blob: a12e36b8082a37c060c7f7723230c6e6f33b3858 [file] [log] [blame]
Kristian Høgsberga67a71a2008-10-07 10:10:36 -04001#include <stdlib.h>
2#include <stdint.h>
3#include <stddef.h>
4#include <stdio.h>
5#include <errno.h>
6#include <string.h>
7#include <unistd.h>
8#include <sys/socket.h>
9#include <sys/un.h>
10#include <ctype.h>
11#include <sys/poll.h>
12
Kristian Høgsberg427524a2008-10-08 13:32:07 -040013#include "connection.h"
14#include "wayland-client.h"
15
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040016static const char socket_name[] = "\0wayland";
17
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040018struct wl_proxy {
Kristian Høgsberg427524a2008-10-08 13:32:07 -040019 struct wl_display *display;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040020 uint32_t id;
21};
22
23struct wl_display {
24 struct wl_proxy proxy;
Kristian Høgsberg427524a2008-10-08 13:32:07 -040025 struct wl_connection *connection;
26 int fd;
27 uint32_t id;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040028};
29
30struct wl_surface {
31 struct wl_proxy proxy;
32};
33
Kristian Høgsberg427524a2008-10-08 13:32:07 -040034struct wl_display *
35wl_display_create(const char *address,
36 wl_connection_update_func_t update, void *data)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040037{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040038 struct wl_display *display;
39 struct sockaddr_un name;
40 socklen_t size;
41 char buffer[256];
42 uint32_t id, length;
43
Kristian Høgsberg427524a2008-10-08 13:32:07 -040044 display = malloc(sizeof *display);
45 if (display == NULL)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040046 return NULL;
47
Kristian Høgsberg427524a2008-10-08 13:32:07 -040048 memset(display, 0, sizeof *display);
Kristian Høgsberg427524a2008-10-08 13:32:07 -040049 display->fd = socket(PF_LOCAL, SOCK_STREAM, 0);
50 if (display->fd < 0) {
51 free(display);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040052 return NULL;
53 }
54
55 name.sun_family = AF_LOCAL;
56 memcpy(name.sun_path, address, strlen(address + 1) + 2);
57
58 size = offsetof (struct sockaddr_un, sun_path) + sizeof socket_name;
59
Kristian Høgsberg427524a2008-10-08 13:32:07 -040060 if (connect(display->fd, (struct sockaddr *) &name, size) < 0) {
61 close(display->fd);
62 free(display);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040063 return NULL;
64 }
65
Kristian Høgsbergf9212892008-10-11 18:40:23 -040066 /* FIXME: We'll need a protocol for getting a new range, I
67 * guess... */
68 read(display->fd, &display->id, sizeof display->id);
69
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040070 /* FIXME: actually discover advertised objects here. */
Kristian Høgsberg427524a2008-10-08 13:32:07 -040071 read(display->fd, &id, sizeof id);
72 read(display->fd, &length, sizeof length);
73 read(display->fd, buffer, (length + 3) & ~3);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040074
Kristian Høgsberg427524a2008-10-08 13:32:07 -040075 display->proxy.display = display;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040076 display->proxy.id = id;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040077
Kristian Høgsberg427524a2008-10-08 13:32:07 -040078 display->connection = wl_connection_create(display->fd,
79 update, data);
80
81 return display;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040082}
83
84void
Kristian Høgsberg427524a2008-10-08 13:32:07 -040085wl_display_destroy(struct wl_display *display)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040086{
Kristian Høgsberg427524a2008-10-08 13:32:07 -040087 wl_connection_destroy(display->connection);
88 close(display->fd);
89 free(display);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040090}
91
92int
Kristian Høgsberg427524a2008-10-08 13:32:07 -040093wl_display_get_fd(struct wl_display *display)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040094{
Kristian Høgsberg427524a2008-10-08 13:32:07 -040095 return display->fd;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040096}
97
98static void
Kristian Høgsbergf9bc7952008-11-02 10:12:29 -050099handle_event(struct wl_connection *connection, uint32_t opcode, uint32_t size)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400100{
Kristian Høgsbergf9bc7952008-11-02 10:12:29 -0500101 uint32_t p[4];
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400102
Kristian Høgsbergf9bc7952008-11-02 10:12:29 -0500103 wl_connection_copy(connection, p, size);
104 printf("signal from object %d, opcode %d, size %d, args: %d, %d\n",
105 p[0], opcode, size, p[2], p[3]);
106 wl_connection_consume(connection, size);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400107}
108
109void
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400110wl_display_iterate(struct wl_display *display, uint32_t mask)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400111{
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400112 uint32_t p[2], opcode, size;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400113 int len;
114
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400115 len = wl_connection_data(display->connection, mask);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400116 while (len > 0) {
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400117 if (len < sizeof p)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400118 break;
119
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400120 wl_connection_copy(display->connection, p, sizeof p);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400121 opcode = p[1] & 0xffff;
122 size = p[1] >> 16;
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400123 if (len < size)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400124 break;
125
Kristian Høgsbergf9bc7952008-11-02 10:12:29 -0500126 handle_event(display->connection, opcode, size);
127 len -= size;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400128 }
129
130 if (len < 0) {
131 fprintf(stderr, "read error: %m\n");
132 exit(EXIT_FAILURE);
133 }
134}
135
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400136#define WL_DISPLAY_CREATE_SURFACE 0
137
138struct wl_surface *
139wl_display_create_surface(struct wl_display *display)
140{
141 struct wl_surface *surface;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400142 uint32_t request[3];
143
144 surface = malloc(sizeof *surface);
145 if (surface == NULL)
146 return NULL;
147
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400148 surface->proxy.id = display->id++;
149 surface->proxy.display = display;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400150
151 request[0] = display->proxy.id;
152 request[1] = WL_DISPLAY_CREATE_SURFACE | ((sizeof request) << 16);
153 request[2] = surface->proxy.id;
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400154 wl_connection_write(display->connection, request, sizeof request);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400155
156 return surface;
157}
158
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400159#define WL_SURFACE_DESTROY 0
160#define WL_SURFACE_ATTACH 1
161#define WL_SURFACE_MAP 2
162
163void wl_surface_destroy(struct wl_surface *surface)
164{
165 uint32_t request[2];
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400166
167 request[0] = surface->proxy.id;
168 request[1] = WL_SURFACE_DESTROY | ((sizeof request) << 16);
169
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400170 wl_connection_write(surface->proxy.display->connection,
171 request, sizeof request);
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400172}
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400173
174void wl_surface_attach(struct wl_surface *surface,
175 uint32_t name, int width, int height, int stride)
176{
177 uint32_t request[6];
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400178
179 request[0] = surface->proxy.id;
180 request[1] = WL_SURFACE_ATTACH | ((sizeof request) << 16);
181 request[2] = name;
182 request[3] = width;
183 request[4] = height;
184 request[5] = stride;
185
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400186 wl_connection_write(surface->proxy.display->connection,
187 request, sizeof request);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400188}
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400189
190
191void wl_surface_map(struct wl_surface *surface,
192 int32_t x, int32_t y, int32_t width, int32_t height)
193{
194 uint32_t request[6];
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400195
196 request[0] = surface->proxy.id;
197 request[1] = WL_SURFACE_MAP | ((sizeof request) << 16);
198 request[2] = x;
199 request[3] = y;
200 request[4] = width;
201 request[5] = height;
202
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400203 wl_connection_write(surface->proxy.display->connection,
204 request, sizeof request);
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400205}