blob: 3e9ed424cfaf9ae11bf6aa7c6bb2b970127cdbe1 [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øgsbergfb590842008-11-07 14:27:23 -050028 uint32_t mask;
29
30 wl_display_update_func_t update;
31 void *update_data;
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050032
33 wl_display_event_func_t event_handler;
34 void *event_handler_data;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040035};
36
37struct wl_surface {
38 struct wl_proxy proxy;
39};
40
Kristian Høgsbergfb590842008-11-07 14:27:23 -050041static int
42connection_update(struct wl_connection *connection,
43 uint32_t mask, void *data)
44{
45 struct wl_display *display = data;
46
47 display->mask = mask;
48 if (display->update)
49 return display->update(display->mask,
50 display->update_data);
51
52 return 0;
53}
54
Kristian Høgsbergb7a01922008-11-08 15:39:41 -050055WL_EXPORT struct wl_display *
Kristian Høgsbergfb590842008-11-07 14:27:23 -050056wl_display_create(const char *address)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040057{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040058 struct wl_display *display;
59 struct sockaddr_un name;
60 socklen_t size;
61 char buffer[256];
62 uint32_t id, length;
63
Kristian Høgsberg427524a2008-10-08 13:32:07 -040064 display = malloc(sizeof *display);
65 if (display == NULL)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040066 return NULL;
67
Kristian Høgsberg427524a2008-10-08 13:32:07 -040068 memset(display, 0, sizeof *display);
Kristian Høgsberg427524a2008-10-08 13:32:07 -040069 display->fd = socket(PF_LOCAL, SOCK_STREAM, 0);
70 if (display->fd < 0) {
71 free(display);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040072 return NULL;
73 }
74
75 name.sun_family = AF_LOCAL;
76 memcpy(name.sun_path, address, strlen(address + 1) + 2);
77
78 size = offsetof (struct sockaddr_un, sun_path) + sizeof socket_name;
79
Kristian Høgsberg427524a2008-10-08 13:32:07 -040080 if (connect(display->fd, (struct sockaddr *) &name, size) < 0) {
81 close(display->fd);
82 free(display);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040083 return NULL;
84 }
85
Kristian Høgsbergf9212892008-10-11 18:40:23 -040086 /* FIXME: We'll need a protocol for getting a new range, I
87 * guess... */
88 read(display->fd, &display->id, sizeof display->id);
89
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040090 /* FIXME: actually discover advertised objects here. */
Kristian Høgsberg427524a2008-10-08 13:32:07 -040091 read(display->fd, &id, sizeof id);
92 read(display->fd, &length, sizeof length);
93 read(display->fd, buffer, (length + 3) & ~3);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040094
Kristian Høgsberg427524a2008-10-08 13:32:07 -040095 display->proxy.display = display;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040096 display->proxy.id = id;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040097
Kristian Høgsberg427524a2008-10-08 13:32:07 -040098 display->connection = wl_connection_create(display->fd,
Kristian Høgsbergfb590842008-11-07 14:27:23 -050099 connection_update,
100 display);
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400101
102 return display;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400103}
104
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500105WL_EXPORT void
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400106wl_display_destroy(struct wl_display *display)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400107{
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400108 wl_connection_destroy(display->connection);
109 close(display->fd);
110 free(display);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400111}
112
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500113WL_EXPORT int
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500114wl_display_get_fd(struct wl_display *display,
115 wl_display_update_func_t update, void *data)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400116{
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500117 display->update = update;
118 display->update_data = data;
119
120 display->update(display->mask, display->update_data);
121
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400122 return display->fd;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400123}
124
125static void
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -0500126handle_event(struct wl_display *display, uint32_t opcode, uint32_t size)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400127{
Kristian Høgsbergf9bc7952008-11-02 10:12:29 -0500128 uint32_t p[4];
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400129
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -0500130 wl_connection_copy(display->connection, p, size);
131 if (display->event_handler != NULL)
132 display->event_handler(display, opcode, p[2], p[3],
133 display->event_handler_data);
134 wl_connection_consume(display->connection, size);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400135}
136
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500137WL_EXPORT void
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400138wl_display_iterate(struct wl_display *display, uint32_t mask)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400139{
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400140 uint32_t p[2], opcode, size;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400141 int len;
142
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400143 len = wl_connection_data(display->connection, mask);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400144 while (len > 0) {
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400145 if (len < sizeof p)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400146 break;
147
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400148 wl_connection_copy(display->connection, p, sizeof p);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400149 opcode = p[1] & 0xffff;
150 size = p[1] >> 16;
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400151 if (len < size)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400152 break;
153
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -0500154 handle_event(display, opcode, size);
Kristian Høgsbergf9bc7952008-11-02 10:12:29 -0500155 len -= size;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400156 }
157
158 if (len < 0) {
159 fprintf(stderr, "read error: %m\n");
160 exit(EXIT_FAILURE);
161 }
162}
163
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500164WL_EXPORT void
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -0500165wl_display_set_event_handler(struct wl_display *display,
166 wl_display_event_func_t handler,
167 void *data)
168{
169 /* FIXME: This needs something more generic... */
170 display->event_handler = handler;
171 display->event_handler_data = data;
172}
173
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400174#define WL_DISPLAY_CREATE_SURFACE 0
175
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500176WL_EXPORT struct wl_surface *
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400177wl_display_create_surface(struct wl_display *display)
178{
179 struct wl_surface *surface;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400180 uint32_t request[3];
181
182 surface = malloc(sizeof *surface);
183 if (surface == NULL)
184 return NULL;
185
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400186 surface->proxy.id = display->id++;
187 surface->proxy.display = display;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400188
189 request[0] = display->proxy.id;
190 request[1] = WL_DISPLAY_CREATE_SURFACE | ((sizeof request) << 16);
191 request[2] = surface->proxy.id;
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400192 wl_connection_write(display->connection, request, sizeof request);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400193
194 return surface;
195}
196
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400197#define WL_SURFACE_DESTROY 0
198#define WL_SURFACE_ATTACH 1
199#define WL_SURFACE_MAP 2
Kristian Høgsberg7f77bd82008-11-07 08:39:37 -0500200#define WL_SURFACE_COPY 3
201#define WL_SURFACE_DAMAGE 4
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400202
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500203WL_EXPORT void
204wl_surface_destroy(struct wl_surface *surface)
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400205{
206 uint32_t request[2];
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400207
208 request[0] = surface->proxy.id;
209 request[1] = WL_SURFACE_DESTROY | ((sizeof request) << 16);
210
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400211 wl_connection_write(surface->proxy.display->connection,
212 request, sizeof request);
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400213}
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400214
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500215WL_EXPORT void
216wl_surface_attach(struct wl_surface *surface, uint32_t name,
217 int32_t width, int32_t height, uint32_t stride)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400218{
219 uint32_t request[6];
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400220
221 request[0] = surface->proxy.id;
222 request[1] = WL_SURFACE_ATTACH | ((sizeof request) << 16);
223 request[2] = name;
224 request[3] = width;
225 request[4] = height;
226 request[5] = stride;
227
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400228 wl_connection_write(surface->proxy.display->connection,
229 request, sizeof request);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400230}
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400231
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500232WL_EXPORT void
233wl_surface_map(struct wl_surface *surface,
234 int32_t x, int32_t y, int32_t width, int32_t height)
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400235{
236 uint32_t request[6];
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400237
238 request[0] = surface->proxy.id;
239 request[1] = WL_SURFACE_MAP | ((sizeof request) << 16);
240 request[2] = x;
241 request[3] = y;
242 request[4] = width;
243 request[5] = height;
244
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400245 wl_connection_write(surface->proxy.display->connection,
246 request, sizeof request);
Kristian Høgsberg05eff512008-10-07 10:10:36 -0400247}
Kristian Høgsberg7f77bd82008-11-07 08:39:37 -0500248
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500249WL_EXPORT void
250wl_surface_copy(struct wl_surface *surface, int32_t dst_x, int32_t dst_y,
251 uint32_t name, uint32_t stride,
252 int32_t x, int32_t y, int32_t width, int32_t height)
Kristian Høgsberg7f77bd82008-11-07 08:39:37 -0500253{
254 uint32_t request[10];
255
256 request[0] = surface->proxy.id;
257 request[1] = WL_SURFACE_COPY | ((sizeof request) << 16);
258 request[2] = dst_x;
259 request[3] = dst_y;
260 request[4] = name;
261 request[5] = stride;
262 request[6] = x;
263 request[7] = y;
264 request[8] = width;
265 request[9] = height;
266
267 wl_connection_write(surface->proxy.display->connection,
268 request, sizeof request);
269}
270
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500271WL_EXPORT void
272wl_surface_damage(struct wl_surface *surface,
273 int32_t x, int32_t y, int32_t width, int32_t height)
Kristian Høgsberg7f77bd82008-11-07 08:39:37 -0500274{
275 uint32_t request[6];
276
277 request[0] = surface->proxy.id;
278 request[1] = WL_SURFACE_DAMAGE | ((sizeof request) << 16);
279 request[2] = x;
280 request[3] = y;
281 request[4] = width;
282 request[5] = height;
283
284 wl_connection_write(surface->proxy.display->connection,
285 request, sizeof request);
286}
287