diff options
author | Jørgen Lind <jorgen.lind@nokia.com> | 2011-05-03 12:44:43 +0200 |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2011-05-03 12:59:30 +0200 |
commit | cf8e88b8b1dabb3194702583f08ff025b1f1d5ef (patch) | |
tree | 5ad3ed4d479a71c515d35a755072ee4a6a1e1f32 | |
parent | e6335b7467b6b7d7ba99d4874b6b4731325a2b63 (diff) |
Update 3rd party Wayland
and reapplied 55bc1eeb8627632be81c90c9ab61a8a535eb7e4e
-rw-r--r-- | src/3rdparty/wayland/event-loop.c | 95 | ||||
-rw-r--r-- | src/3rdparty/wayland/server/server.pro | 3 | ||||
-rw-r--r-- | src/3rdparty/wayland/wayland-client-protocol.h | 445 | ||||
-rw-r--r-- | src/3rdparty/wayland/wayland-client.c | 40 | ||||
-rw-r--r-- | src/3rdparty/wayland/wayland-client.h | 24 | ||||
-rw-r--r-- | src/3rdparty/wayland/wayland-egl.h | 22 | ||||
-rw-r--r-- | src/3rdparty/wayland/wayland-protocol.c | 104 | ||||
-rw-r--r-- | src/3rdparty/wayland/wayland-server-protocol.h | 63 | ||||
-rw-r--r-- | src/3rdparty/wayland/wayland-server.c | 39 | ||||
-rw-r--r-- | src/3rdparty/wayland/wayland-server.h | 60 | ||||
-rw-r--r-- | src/3rdparty/wayland/wayland-shm.c | 228 |
11 files changed, 744 insertions, 379 deletions
diff --git a/src/3rdparty/wayland/event-loop.c b/src/3rdparty/wayland/event-loop.c index 8166356f1..0f41034b4 100644 --- a/src/3rdparty/wayland/event-loop.c +++ b/src/3rdparty/wayland/event-loop.c @@ -37,28 +37,29 @@ struct wl_event_loop { int epoll_fd; - struct wl_list idle_list; + struct wl_list check_list; }; struct wl_event_source_interface { - void (*dispatch)(struct wl_event_source *source, - struct epoll_event *ep); + int (*dispatch)(struct wl_event_source *source, + struct epoll_event *ep); int (*remove)(struct wl_event_source *source); }; struct wl_event_source { struct wl_event_source_interface *interface; struct wl_event_loop *loop; + struct wl_list link; + void *data; }; struct wl_event_source_fd { struct wl_event_source base; int fd; wl_event_loop_fd_func_t func; - void *data; }; -static void +static int wl_event_source_fd_dispatch(struct wl_event_source *source, struct epoll_event *ep) { @@ -71,7 +72,7 @@ wl_event_source_fd_dispatch(struct wl_event_source *source, if (ep->events & EPOLLOUT) mask |= WL_EVENT_WRITEABLE; - fd_source->func(fd_source->fd, mask, fd_source->data); + return fd_source->func(fd_source->fd, mask, fd_source->base.data); } static int @@ -108,9 +109,10 @@ wl_event_loop_add_fd(struct wl_event_loop *loop, source->base.interface = &fd_source_interface; source->base.loop = loop; + wl_list_init(&source->base.link); source->fd = fd; source->func = func; - source->data = data; + source->base.data = data; memset(&ep, 0, sizeof ep); if (mask & WL_EVENT_READABLE) @@ -150,10 +152,9 @@ struct wl_event_source_timer { struct wl_event_source base; int fd; wl_event_loop_timer_func_t func; - void *data; }; -static void +static int wl_event_source_timer_dispatch(struct wl_event_source *source, struct epoll_event *ep) { @@ -163,7 +164,7 @@ wl_event_source_timer_dispatch(struct wl_event_source *source, read(timer_source->fd, &expires, sizeof expires); - timer_source->func(timer_source->data); + return timer_source->func(timer_source->base.data); } static int @@ -196,6 +197,7 @@ wl_event_loop_add_timer(struct wl_event_loop *loop, source->base.interface = &timer_source_interface; source->base.loop = loop; + wl_list_init(&source->base.link); source->fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); if (source->fd < 0) { @@ -205,7 +207,7 @@ wl_event_loop_add_timer(struct wl_event_loop *loop, } source->func = func; - source->data = data; + source->base.data = data; memset(&ep, 0, sizeof ep); ep.events = EPOLLIN; @@ -244,10 +246,9 @@ struct wl_event_source_signal { int fd; int signal_number; wl_event_loop_signal_func_t func; - void *data; }; -static void +static int wl_event_source_signal_dispatch(struct wl_event_source *source, struct epoll_event *ep) { @@ -257,7 +258,8 @@ wl_event_source_signal_dispatch(struct wl_event_source *source, read(signal_source->fd, &signal_info, sizeof signal_info); - signal_source->func(signal_source->signal_number, signal_source->data); + return signal_source->func(signal_source->signal_number, + signal_source->base.data); } static int @@ -292,6 +294,7 @@ wl_event_loop_add_signal(struct wl_event_loop *loop, source->base.interface = &signal_source_interface; source->base.loop = loop; + wl_list_init(&source->base.link); source->signal_number = signal_number; sigemptyset(&mask); @@ -305,7 +308,7 @@ wl_event_loop_add_signal(struct wl_event_loop *loop, sigprocmask(SIG_BLOCK, &mask, NULL); source->func = func; - source->data = data; + source->base.data = data; memset(&ep, 0, sizeof ep); ep.events = EPOLLIN; @@ -322,16 +325,20 @@ wl_event_loop_add_signal(struct wl_event_loop *loop, struct wl_event_source_idle { struct wl_event_source base; - struct wl_list link; wl_event_loop_idle_func_t func; - void *data; }; -static void +static int wl_event_source_idle_dispatch(struct wl_event_source *source, struct epoll_event *ep) { - assert(0); + struct wl_event_source_idle *idle_source = + (struct wl_event_source_idle *) source; + + idle_source->func(idle_source->base.data); + wl_event_source_remove(&idle_source->base); + + return 1; } static int @@ -340,7 +347,7 @@ wl_event_source_idle_remove(struct wl_event_source *source) struct wl_event_source_idle *idle_source = (struct wl_event_source_idle *) source; - wl_list_remove(&idle_source->link); + wl_list_remove(&idle_source->base.link); free(source); return 0; @@ -366,15 +373,24 @@ wl_event_loop_add_idle(struct wl_event_loop *loop, source->base.loop = loop; source->func = func; - source->data = data; - wl_list_insert(loop->idle_list.prev, &source->link); + source->base.data = data; + wl_event_source_check(&source->base); return &source->base; } +WL_EXPORT void +wl_event_source_check(struct wl_event_source *source) +{ + wl_list_insert(source->loop->check_list.prev, &source->link); +} + WL_EXPORT int wl_event_source_remove(struct wl_event_source *source) { + if (!wl_list_empty(&source->link)) + wl_list_remove(&source->link); + source->interface->remove(source); return 0; @@ -394,7 +410,7 @@ wl_event_loop_create(void) free(loop); return NULL; } - wl_list_init(&loop->idle_list); + wl_list_init(&loop->check_list); return loop; } @@ -406,31 +422,40 @@ wl_event_loop_destroy(struct wl_event_loop *loop) free(loop); } +static int +post_dispatch_check(struct wl_event_loop *loop) +{ + struct epoll_event ep; + struct wl_event_source *source, *next; + int n; + + ep.events = 0; + n = 0; + wl_list_for_each_safe(source, next, &loop->check_list, link) + n += source->interface->dispatch(source, &ep); + + return n; +} + WL_EXPORT int wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout) { struct epoll_event ep[32]; struct wl_event_source *source; - struct wl_event_source_idle *idle; - int i, count; + int i, count, n; count = epoll_wait(loop->epoll_fd, ep, ARRAY_LENGTH(ep), timeout); if (count < 0) return -1; - + n = 0; for (i = 0; i < count; i++) { source = ep[i].data.ptr; - source->interface->dispatch(source, &ep[i]); - } - - while (!wl_list_empty(&loop->idle_list)) { - idle = container_of(loop->idle_list.next, - struct wl_event_source_idle, link); - wl_list_remove(&idle->link); - idle->func(idle->data); - free(idle); + n += source->interface->dispatch(source, &ep[i]); } + while (n > 0) + n = post_dispatch_check(loop); + return 0; } diff --git a/src/3rdparty/wayland/server/server.pro b/src/3rdparty/wayland/server/server.pro index 0898b443d..9f52b5c00 100644 --- a/src/3rdparty/wayland/server/server.pro +++ b/src/3rdparty/wayland/server/server.pro @@ -12,6 +12,7 @@ SOURCES = ../event-loop.c \ ../wayland-protocol.c \ ../connection.c \ ../wayland-util.c \ - ../wayland-hash.c + ../wayland-hash.c \ + ../wayland-shm.c OBJECTS_DIR = .obj diff --git a/src/3rdparty/wayland/wayland-client-protocol.h b/src/3rdparty/wayland/wayland-client-protocol.h index 4cd842971..564168401 100644 --- a/src/3rdparty/wayland/wayland-client-protocol.h +++ b/src/3rdparty/wayland/wayland-client-protocol.h @@ -48,29 +48,6 @@ struct wl_input_device; struct wl_output; struct wl_visual; -struct wl_proxy; - -extern void -wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...); -extern struct wl_proxy * -wl_proxy_create(struct wl_proxy *factory, - const struct wl_interface *interface); -extern struct wl_proxy * -wl_proxy_create_for_id(struct wl_display *display, - const struct wl_interface *interface, uint32_t id); -extern void -wl_proxy_destroy(struct wl_proxy *proxy); - -extern int -wl_proxy_add_listener(struct wl_proxy *proxy, - void (**implementation)(void), void *data); - -extern void -wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data); - -extern void * -wl_proxy_get_user_data(struct wl_proxy *proxy); - extern const struct wl_interface wl_display_interface; extern const struct wl_interface wl_compositor_interface; extern const struct wl_interface wl_shm_interface; @@ -87,103 +64,113 @@ extern const struct wl_interface wl_visual_interface; struct wl_display_listener { void (*invalid_object)(void *data, - struct wl_display *display, + struct wl_display *wl_display, uint32_t object_id); void (*invalid_method)(void *data, - struct wl_display *display, + struct wl_display *wl_display, uint32_t object_id, uint32_t opcode); void (*no_memory)(void *data, - struct wl_display *display); + struct wl_display *wl_display); void (*global)(void *data, - struct wl_display *display, + struct wl_display *wl_display, uint32_t id, const char *name, uint32_t version); void (*range)(void *data, - struct wl_display *display, + struct wl_display *wl_display, uint32_t base); void (*key)(void *data, - struct wl_display *display, + struct wl_display *wl_display, uint32_t key, uint32_t time); }; static inline int -wl_display_add_listener(struct wl_display *display, - const struct wl_display_listener *listener, void *data) +wl_display_add_listener(struct wl_display *wl_display, + const struct wl_display_listener *listener, void *data) { - return wl_proxy_add_listener((struct wl_proxy *) display, + return wl_proxy_add_listener((struct wl_proxy *) wl_display, (void (**)(void)) listener, data); } -#define WL_DISPLAY_SYNC 0 -#define WL_DISPLAY_FRAME 1 +#define WL_DISPLAY_BIND 0 +#define WL_DISPLAY_SYNC 1 +#define WL_DISPLAY_FRAME 2 static inline void -wl_display_set_user_data(struct wl_display *display, void *user_data) +wl_display_set_user_data(struct wl_display *wl_display, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) display, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_display, user_data); } static inline void * -wl_display_get_user_data(struct wl_display *display) +wl_display_get_user_data(struct wl_display *wl_display) { - return wl_proxy_get_user_data((struct wl_proxy *) display); + return wl_proxy_get_user_data((struct wl_proxy *) wl_display); } static inline void -wl_display_sync(struct wl_display *display, uint32_t key) +wl_display_bind(struct wl_display *wl_display, uint32_t id, const char *interface, uint32_t version) { - wl_proxy_marshal((struct wl_proxy *) display, + wl_proxy_marshal((struct wl_proxy *) wl_display, + WL_DISPLAY_BIND, id, interface, version); +} + +static inline void +wl_display_sync(struct wl_display *wl_display, uint32_t key) +{ + wl_proxy_marshal((struct wl_proxy *) wl_display, WL_DISPLAY_SYNC, key); } static inline void -wl_display_frame(struct wl_display *display, struct wl_surface *surface, uint32_t key) +wl_display_frame(struct wl_display *wl_display, struct wl_surface *surface, uint32_t key) { - wl_proxy_marshal((struct wl_proxy *) display, + wl_proxy_marshal((struct wl_proxy *) wl_display, WL_DISPLAY_FRAME, surface, key); } #define WL_COMPOSITOR_CREATE_SURFACE 0 static inline struct wl_compositor * -wl_compositor_create(struct wl_display *display, uint32_t id) +wl_compositor_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_compositor", version); + return (struct wl_compositor *) wl_proxy_create_for_id(display, &wl_compositor_interface, id); } static inline void -wl_compositor_set_user_data(struct wl_compositor *compositor, void *user_data) +wl_compositor_set_user_data(struct wl_compositor *wl_compositor, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) compositor, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_compositor, user_data); } static inline void * -wl_compositor_get_user_data(struct wl_compositor *compositor) +wl_compositor_get_user_data(struct wl_compositor *wl_compositor) { - return wl_proxy_get_user_data((struct wl_proxy *) compositor); + return wl_proxy_get_user_data((struct wl_proxy *) wl_compositor); } static inline void -wl_compositor_destroy(struct wl_compositor *compositor) +wl_compositor_destroy(struct wl_compositor *wl_compositor) { - wl_proxy_destroy((struct wl_proxy *) compositor); + wl_proxy_destroy((struct wl_proxy *) wl_compositor); } static inline struct wl_surface * -wl_compositor_create_surface(struct wl_compositor *compositor) +wl_compositor_create_surface(struct wl_compositor *wl_compositor) { struct wl_proxy *id; - id = wl_proxy_create((struct wl_proxy *) compositor, + id = wl_proxy_create((struct wl_proxy *) wl_compositor, &wl_surface_interface); if (!id) return NULL; - wl_proxy_marshal((struct wl_proxy *) compositor, + wl_proxy_marshal((struct wl_proxy *) wl_compositor, WL_COMPOSITOR_CREATE_SURFACE, id); return (struct wl_surface *) id; @@ -192,74 +179,86 @@ wl_compositor_create_surface(struct wl_compositor *compositor) #define WL_SHM_CREATE_BUFFER 0 static inline struct wl_shm * -wl_shm_create(struct wl_display *display, uint32_t id) +wl_shm_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_shm", version); + return (struct wl_shm *) wl_proxy_create_for_id(display, &wl_shm_interface, id); } static inline void -wl_shm_set_user_data(struct wl_shm *shm, void *user_data) +wl_shm_set_user_data(struct wl_shm *wl_shm, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) shm, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_shm, user_data); } static inline void * -wl_shm_get_user_data(struct wl_shm *shm) +wl_shm_get_user_data(struct wl_shm *wl_shm) { - return wl_proxy_get_user_data((struct wl_proxy *) shm); + return wl_proxy_get_user_data((struct wl_proxy *) wl_shm); } static inline void -wl_shm_destroy(struct wl_shm *shm) +wl_shm_destroy(struct wl_shm *wl_shm) { - wl_proxy_destroy((struct wl_proxy *) shm); + wl_proxy_destroy((struct wl_proxy *) wl_shm); } static inline struct wl_buffer * -wl_shm_create_buffer(struct wl_shm *shm, int fd, int width, int height, uint32_t stride, struct wl_visual *visual) +wl_shm_create_buffer(struct wl_shm *wl_shm, int fd, int width, int height, uint32_t stride, struct wl_visual *visual) { struct wl_proxy *id; - id = wl_proxy_create((struct wl_proxy *) shm, + id = wl_proxy_create((struct wl_proxy *) wl_shm, &wl_buffer_interface); if (!id) return NULL; - wl_proxy_marshal((struct wl_proxy *) shm, + wl_proxy_marshal((struct wl_proxy *) wl_shm, WL_SHM_CREATE_BUFFER, id, fd, width, height, stride, visual); return (struct wl_buffer *) id; } -#define WL_BUFFER_DESTROY 0 +#define WL_BUFFER_DAMAGE 0 +#define WL_BUFFER_DESTROY 1 static inline struct wl_buffer * -wl_buffer_create(struct wl_display *display, uint32_t id) +wl_buffer_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_buffer", version); + return (struct wl_buffer *) wl_proxy_create_for_id(display, &wl_buffer_interface, id); } static inline void -wl_buffer_set_user_data(struct wl_buffer *buffer, void *user_data) +wl_buffer_set_user_data(struct wl_buffer *wl_buffer, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) buffer, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_buffer, user_data); } static inline void * -wl_buffer_get_user_data(struct wl_buffer *buffer) +wl_buffer_get_user_data(struct wl_buffer *wl_buffer) { - return wl_proxy_get_user_data((struct wl_proxy *) buffer); + return wl_proxy_get_user_data((struct wl_proxy *) wl_buffer); } static inline void -wl_buffer_destroy(struct wl_buffer *buffer) +wl_buffer_damage(struct wl_buffer *wl_buffer, int x, int y, int width, int height) { - wl_proxy_marshal((struct wl_proxy *) buffer, + wl_proxy_marshal((struct wl_proxy *) wl_buffer, + WL_BUFFER_DAMAGE, x, y, width, height); +} + +static inline void +wl_buffer_destroy(struct wl_buffer *wl_buffer) +{ + wl_proxy_marshal((struct wl_proxy *) wl_buffer, WL_BUFFER_DESTROY); - wl_proxy_destroy((struct wl_proxy *) buffer); + wl_proxy_destroy((struct wl_proxy *) wl_buffer); } #ifndef WL_SHELL_RESIZE_ENUM @@ -279,7 +278,7 @@ enum wl_shell_resize { struct wl_shell_listener { void (*configure)(void *data, - struct wl_shell *shell, + struct wl_shell *wl_shell, uint32_t time, uint32_t edges, struct wl_surface *surface, @@ -288,10 +287,10 @@ struct wl_shell_listener { }; static inline int -wl_shell_add_listener(struct wl_shell *shell, - const struct wl_shell_listener *listener, void *data) +wl_shell_add_listener(struct wl_shell *wl_shell, + const struct wl_shell_listener *listener, void *data) { - return wl_proxy_add_listener((struct wl_proxy *) shell, + return wl_proxy_add_listener((struct wl_proxy *) wl_shell, (void (**)(void)) listener, data); } @@ -301,71 +300,73 @@ wl_shell_add_listener(struct wl_shell *shell, #define WL_SHELL_CREATE_SELECTION 3 static inline struct wl_shell * -wl_shell_create(struct wl_display *display, uint32_t id) +wl_shell_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_shell", version); + return (struct wl_shell *) wl_proxy_create_for_id(display, &wl_shell_interface, id); } static inline void -wl_shell_set_user_data(struct wl_shell *shell, void *user_data) +wl_shell_set_user_data(struct wl_shell *wl_shell, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) shell, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_shell, user_data); } static inline void * -wl_shell_get_user_data(struct wl_shell *shell) +wl_shell_get_user_data(struct wl_shell *wl_shell) { - return wl_proxy_get_user_data((struct wl_proxy *) shell); + return wl_proxy_get_user_data((struct wl_proxy *) wl_shell); } static inline void -wl_shell_destroy(struct wl_shell *shell) +wl_shell_destroy(struct wl_shell *wl_shell) { - wl_proxy_destroy((struct wl_proxy *) shell); + wl_proxy_destroy((struct wl_proxy *) wl_shell); } static inline void -wl_shell_move(struct wl_shell *shell, struct wl_surface *surface, struct wl_input_device *input_device, uint32_t time) +wl_shell_move(struct wl_shell *wl_shell, struct wl_surface *surface, struct wl_input_device *input_device, uint32_t time) { - wl_proxy_marshal((struct wl_proxy *) shell, + wl_proxy_marshal((struct wl_proxy *) wl_shell, WL_SHELL_MOVE, surface, input_device, time); } static inline void -wl_shell_resize(struct wl_shell *shell, struct wl_surface *surface, struct wl_input_device *input_device, uint32_t time, uint32_t edges) +wl_shell_resize(struct wl_shell *wl_shell, struct wl_surface *surface, struct wl_input_device *input_device, uint32_t time, uint32_t edges) { - wl_proxy_marshal((struct wl_proxy *) shell, + wl_proxy_marshal((struct wl_proxy *) wl_shell, WL_SHELL_RESIZE, surface, input_device, time, edges); } static inline struct wl_drag * -wl_shell_create_drag(struct wl_shell *shell) +wl_shell_create_drag(struct wl_shell *wl_shell) { struct wl_proxy *id; - id = wl_proxy_create((struct wl_proxy *) shell, + id = wl_proxy_create((struct wl_proxy *) wl_shell, &wl_drag_interface); if (!id) return NULL; - wl_proxy_marshal((struct wl_proxy *) shell, + wl_proxy_marshal((struct wl_proxy *) wl_shell, WL_SHELL_CREATE_DRAG, id); return (struct wl_drag *) id; } static inline struct wl_selection * -wl_shell_create_selection(struct wl_shell *shell) +wl_shell_create_selection(struct wl_shell *wl_shell) { struct wl_proxy *id; - id = wl_proxy_create((struct wl_proxy *) shell, + id = wl_proxy_create((struct wl_proxy *) wl_shell, &wl_selection_interface); if (!id) return NULL; - wl_proxy_marshal((struct wl_proxy *) shell, + wl_proxy_marshal((struct wl_proxy *) wl_shell, WL_SHELL_CREATE_SELECTION, id); return (struct wl_selection *) id; @@ -373,18 +374,18 @@ wl_shell_create_selection(struct wl_shell *shell) struct wl_selection_listener { void (*send)(void *data, - struct wl_selection *selection, + struct wl_selection *wl_selection, const char *mime_type, int fd); void (*cancelled)(void *data, - struct wl_selection *selection); + struct wl_selection *wl_selection); }; static inline int -wl_selection_add_listener(struct wl_selection *selection, - const struct wl_selection_listener *listener, void *data) +wl_selection_add_listener(struct wl_selection *wl_selection, + const struct wl_selection_listener *listener, void *data) { - return wl_proxy_add_listener((struct wl_proxy *) selection, + return wl_proxy_add_listener((struct wl_proxy *) wl_selection, (void (**)(void)) listener, data); } @@ -393,114 +394,118 @@ wl_selection_add_listener(struct wl_selection *selection, #define WL_SELECTION_DESTROY 2 static inline struct wl_selection * -wl_selection_create(struct wl_display *display, uint32_t id) +wl_selection_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_selection", version); + return (struct wl_selection *) wl_proxy_create_for_id(display, &wl_selection_interface, id); } static inline void -wl_selection_set_user_data(struct wl_selection *selection, void *user_data) +wl_selection_set_user_data(struct wl_selection *wl_selection, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) selection, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_selection, user_data); } static inline void * -wl_selection_get_user_data(struct wl_selection *selection) +wl_selection_get_user_data(struct wl_selection *wl_selection) { - return wl_proxy_get_user_data((struct wl_proxy *) selection); + return wl_proxy_get_user_data((struct wl_proxy *) wl_selection); } static inline void -wl_selection_offer(struct wl_selection *selection, const char *type) +wl_selection_offer(struct wl_selection *wl_selection, const char *type) { - wl_proxy_marshal((struct wl_proxy *) selection, + wl_proxy_marshal((struct wl_proxy *) wl_selection, WL_SELECTION_OFFER, type); } static inline void -wl_selection_activate(struct wl_selection *selection, struct wl_input_device *input_device, uint32_t time) +wl_selection_activate(struct wl_selection *wl_selection, struct wl_input_device *input_device, uint32_t time) { - wl_proxy_marshal((struct wl_proxy *) selection, + wl_proxy_marshal((struct wl_proxy *) wl_selection, WL_SELECTION_ACTIVATE, input_device, time); } static inline void -wl_selection_destroy(struct wl_selection *selection) +wl_selection_destroy(struct wl_selection *wl_selection) { - wl_proxy_marshal((struct wl_proxy *) selection, + wl_proxy_marshal((struct wl_proxy *) wl_selection, WL_SELECTION_DESTROY); - wl_proxy_destroy((struct wl_proxy *) selection); + wl_proxy_destroy((struct wl_proxy *) wl_selection); } struct wl_selection_offer_listener { void (*offer)(void *data, - struct wl_selection_offer *selection_offer, + struct wl_selection_offer *wl_selection_offer, const char *type); void (*keyboard_focus)(void *data, - struct wl_selection_offer *selection_offer, + struct wl_selection_offer *wl_selection_offer, struct wl_input_device *input_device); }; static inline int -wl_selection_offer_add_listener(struct wl_selection_offer *selection_offer, - const struct wl_selection_offer_listener *listener, void *data) +wl_selection_offer_add_listener(struct wl_selection_offer *wl_selection_offer, + const struct wl_selection_offer_listener *listener, void *data) { - return wl_proxy_add_listener((struct wl_proxy *) selection_offer, + return wl_proxy_add_listener((struct wl_proxy *) wl_selection_offer, (void (**)(void)) listener, data); } #define WL_SELECTION_OFFER_RECEIVE 0 static inline struct wl_selection_offer * -wl_selection_offer_create(struct wl_display *display, uint32_t id) +wl_selection_offer_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_selection_offer", version); + return (struct wl_selection_offer *) wl_proxy_create_for_id(display, &wl_selection_offer_interface, id); } static inline void -wl_selection_offer_set_user_data(struct wl_selection_offer *selection_offer, void *user_data) +wl_selection_offer_set_user_data(struct wl_selection_offer *wl_selection_offer, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) selection_offer, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_selection_offer, user_data); } static inline void * -wl_selection_offer_get_user_data(struct wl_selection_offer *selection_offer) +wl_selection_offer_get_user_data(struct wl_selection_offer *wl_selection_offer) { - return wl_proxy_get_user_data((struct wl_proxy *) selection_offer); + return wl_proxy_get_user_data((struct wl_proxy *) wl_selection_offer); } static inline void -wl_selection_offer_destroy(struct wl_selection_offer *selection_offer) +wl_selection_offer_destroy(struct wl_selection_offer *wl_selection_offer) { - wl_proxy_destroy((struct wl_proxy *) selection_offer); + wl_proxy_destroy((struct wl_proxy *) wl_selection_offer); } static inline void -wl_selection_offer_receive(struct wl_selection_offer *selection_offer, const char *mime_type, int fd) +wl_selection_offer_receive(struct wl_selection_offer *wl_selection_offer, const char *mime_type, int fd) { - wl_proxy_marshal((struct wl_proxy *) selection_offer, + wl_proxy_marshal((struct wl_proxy *) wl_selection_offer, WL_SELECTION_OFFER_RECEIVE, mime_type, fd); } struct wl_drag_listener { void (*target)(void *data, - struct wl_drag *drag, + struct wl_drag *wl_drag, const char *mime_type); void (*finish)(void *data, - struct wl_drag *drag, + struct wl_drag *wl_drag, int fd); void (*reject)(void *data, - struct wl_drag *drag); + struct wl_drag *wl_drag); }; static inline int -wl_drag_add_listener(struct wl_drag *drag, - const struct wl_drag_listener *listener, void *data) +wl_drag_add_listener(struct wl_drag *wl_drag, + const struct wl_drag_listener *listener, void *data) { - return wl_proxy_add_listener((struct wl_proxy *) drag, + return wl_proxy_add_listener((struct wl_proxy *) wl_drag, (void (**)(void)) listener, data); } @@ -509,53 +514,55 @@ wl_drag_add_listener(struct wl_drag *drag, #define WL_DRAG_DESTROY 2 static inline struct wl_drag * -wl_drag_create(struct wl_display *display, uint32_t id) +wl_drag_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_drag", version); + return (struct wl_drag *) wl_proxy_create_for_id(display, &wl_drag_interface, id); } static inline void -wl_drag_set_user_data(struct wl_drag *drag, void *user_data) +wl_drag_set_user_data(struct wl_drag *wl_drag, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) drag, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_drag, user_data); } static inline void * -wl_drag_get_user_data(struct wl_drag *drag) +wl_drag_get_user_data(struct wl_drag *wl_drag) { - return wl_proxy_get_user_data((struct wl_proxy *) drag); + return wl_proxy_get_user_data((struct wl_proxy *) wl_drag); } static inline void -wl_drag_offer(struct wl_drag *drag, const char *type) +wl_drag_offer(struct wl_drag *wl_drag, const char *type) { - wl_proxy_marshal((struct wl_proxy *) drag, + wl_proxy_marshal((struct wl_proxy *) wl_drag, WL_DRAG_OFFER, type); } static inline void -wl_drag_activate(struct wl_drag *drag, struct wl_surface *surface, struct wl_input_device *input_device, uint32_t time) +wl_drag_activate(struct wl_drag *wl_drag, struct wl_surface *surface, struct wl_input_device *input_device, uint32_t time) { - wl_proxy_marshal((struct wl_proxy *) drag, + wl_proxy_marshal((struct wl_proxy *) wl_drag, WL_DRAG_ACTIVATE, surface, input_device, time); } static inline void -wl_drag_destroy(struct wl_drag *drag) +wl_drag_destroy(struct wl_drag *wl_drag) { - wl_proxy_marshal((struct wl_proxy *) drag, + wl_proxy_marshal((struct wl_proxy *) wl_drag, WL_DRAG_DESTROY); - wl_proxy_destroy((struct wl_proxy *) drag); + wl_proxy_destroy((struct wl_proxy *) wl_drag); } struct wl_drag_offer_listener { void (*offer)(void *data, - struct wl_drag_offer *drag_offer, + struct wl_drag_offer *wl_drag_offer, const char *type); void (*pointer_focus)(void *data, - struct wl_drag_offer *drag_offer, + struct wl_drag_offer *wl_drag_offer, uint32_t time, struct wl_surface *surface, int x, @@ -563,21 +570,21 @@ struct wl_drag_offer_listener { int surface_x, int surface_y); void (*motion)(void *data, - struct wl_drag_offer *drag_offer, + struct wl_drag_offer *wl_drag_offer, uint32_t time, int x, int y, int surface_x, int surface_y); void (*drop)(void *data, - struct wl_drag_offer *drag_offer); + struct wl_drag_offer *wl_drag_offer); }; static inline int -wl_drag_offer_add_listener(struct wl_drag_offer *drag_offer, - const struct wl_drag_offer_listener *listener, void *data) +wl_drag_offer_add_listener(struct wl_drag_offer *wl_drag_offer, + const struct wl_drag_offer_listener *listener, void *data) { - return wl_proxy_add_listener((struct wl_proxy *) drag_offer, + return wl_proxy_add_listener((struct wl_proxy *) wl_drag_offer, (void (**)(void)) listener, data); } @@ -586,48 +593,50 @@ wl_drag_offer_add_listener(struct wl_drag_offer *drag_offer, #define WL_DRAG_OFFER_REJECT 2 static inline struct wl_drag_offer * -wl_drag_offer_create(struct wl_display *display, uint32_t id) +wl_drag_offer_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_drag_offer", version); + return (struct wl_drag_offer *) wl_proxy_create_for_id(display, &wl_drag_offer_interface, id); } static inline void -wl_drag_offer_set_user_data(struct wl_drag_offer *drag_offer, void *user_data) +wl_drag_offer_set_user_data(struct wl_drag_offer *wl_drag_offer, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) drag_offer, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_drag_offer, user_data); } static inline void * -wl_drag_offer_get_user_data(struct wl_drag_offer *drag_offer) +wl_drag_offer_get_user_data(struct wl_drag_offer *wl_drag_offer) { - return wl_proxy_get_user_data((struct wl_proxy *) drag_offer); + return wl_proxy_get_user_data((struct wl_proxy *) wl_drag_offer); } static inline void -wl_drag_offer_destroy(struct wl_drag_offer *drag_offer) +wl_drag_offer_destroy(struct wl_drag_offer *wl_drag_offer) { - wl_proxy_destroy((struct wl_proxy *) drag_offer); + wl_proxy_destroy((struct wl_proxy *) wl_drag_offer); } static inline void -wl_drag_offer_accept(struct wl_drag_offer *drag_offer, uint32_t time, const char *type) +wl_drag_offer_accept(struct wl_drag_offer *wl_drag_offer, uint32_t time, const char *type) { - wl_proxy_marshal((struct wl_proxy *) drag_offer, + wl_proxy_marshal((struct wl_proxy *) wl_drag_offer, WL_DRAG_OFFER_ACCEPT, time, type); } static inline void -wl_drag_offer_receive(struct wl_drag_offer *drag_offer, int fd) +wl_drag_offer_receive(struct wl_drag_offer *wl_drag_offer, int fd) { - wl_proxy_marshal((struct wl_proxy *) drag_offer, + wl_proxy_marshal((struct wl_proxy *) wl_drag_offer, WL_DRAG_OFFER_RECEIVE, fd); } static inline void -wl_drag_offer_reject(struct wl_drag_offer *drag_offer) +wl_drag_offer_reject(struct wl_drag_offer *wl_drag_offer) { - wl_proxy_marshal((struct wl_proxy *) drag_offer, + wl_proxy_marshal((struct wl_proxy *) wl_drag_offer, WL_DRAG_OFFER_REJECT); } @@ -639,88 +648,90 @@ wl_drag_offer_reject(struct wl_drag_offer *drag_offer) #define WL_SURFACE_DAMAGE 5 static inline struct wl_surface * -wl_surface_create(struct wl_display *display, uint32_t id) +wl_surface_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_surface", version); + return (struct wl_surface *) wl_proxy_create_for_id(display, &wl_surface_interface, id); } static inline void -wl_surface_set_user_data(struct wl_surface *surface, void *user_data) +wl_surface_set_user_data(struct wl_surface *wl_surface, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) surface, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_surface, user_data); } static inline void * -wl_surface_get_user_data(struct wl_surface *surface) +wl_surface_get_user_data(struct wl_surface *wl_surface) { - return wl_proxy_get_user_data((struct wl_proxy *) surface); + return wl_proxy_get_user_data((struct wl_proxy *) wl_surface); } static inline void -wl_surface_destroy(struct wl_surface *surface) +wl_surface_destroy(struct wl_surface *wl_surface) { - wl_proxy_marshal((struct wl_proxy *) surface, + wl_proxy_marshal((struct wl_proxy *) wl_surface, WL_SURFACE_DESTROY); - wl_proxy_destroy((struct wl_proxy *) surface); + wl_proxy_destroy((struct wl_proxy *) wl_surface); } static inline void -wl_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer, int x, int y) +wl_surface_attach(struct wl_surface *wl_surface, struct wl_buffer *buffer, int x, int y) { - wl_proxy_marshal((struct wl_proxy *) surface, + wl_proxy_marshal((struct wl_proxy *) wl_surface, WL_SURFACE_ATTACH, buffer, x, y); } static inline void -wl_surface_map_toplevel(struct wl_surface *surface) +wl_surface_map_toplevel(struct wl_surface *wl_surface) { - wl_proxy_marshal((struct wl_proxy *) surface, + wl_proxy_marshal((struct wl_proxy *) wl_surface, WL_SURFACE_MAP_TOPLEVEL); } static inline void -wl_surface_map_transient(struct wl_surface *surface, struct wl_surface *parent, int x, int y, uint32_t flags) +wl_surface_map_transient(struct wl_surface *wl_surface, struct wl_surface *parent, int x, int y, uint32_t flags) { - wl_proxy_marshal((struct wl_proxy *) surface, + wl_proxy_marshal((struct wl_proxy *) wl_surface, WL_SURFACE_MAP_TRANSIENT, parent, x, y, flags); } static inline void -wl_surface_map_fullscreen(struct wl_surface *surface) +wl_surface_map_fullscreen(struct wl_surface *wl_surface) { - wl_proxy_marshal((struct wl_proxy *) surface, + wl_proxy_marshal((struct wl_proxy *) wl_surface, WL_SURFACE_MAP_FULLSCREEN); } static inline void -wl_surface_damage(struct wl_surface *surface, int x, int y, int width, int height) +wl_surface_damage(struct wl_surface *wl_surface, int x, int y, int width, int height) { - wl_proxy_marshal((struct wl_proxy *) surface, + wl_proxy_marshal((struct wl_proxy *) wl_surface, WL_SURFACE_DAMAGE, x, y, width, height); } struct wl_input_device_listener { void (*motion)(void *data, - struct wl_input_device *input_device, + struct wl_input_device *wl_input_device, uint32_t time, int x, int y, int surface_x, int surface_y); void (*button)(void *data, - struct wl_input_device *input_device, + struct wl_input_device *wl_input_device, uint32_t time, uint32_t button, uint32_t state); void (*key)(void *data, - struct wl_input_device *input_device, + struct wl_input_device *wl_input_device, uint32_t time, uint32_t key, uint32_t state); void (*pointer_focus)(void *data, - struct wl_input_device *input_device, + struct wl_input_device *wl_input_device, uint32_t time, struct wl_surface *surface, int x, @@ -728,57 +739,59 @@ struct wl_input_device_listener { int surface_x, int surface_y); void (*keyboard_focus)(void *data, - struct wl_input_device *input_device, + struct wl_input_device *wl_input_device, uint32_t time, struct wl_surface *surface, struct wl_array *keys); }; static inline int -wl_input_device_add_listener(struct wl_input_device *input_device, - const struct wl_input_device_listener *listener, void *data) +wl_input_device_add_listener(struct wl_input_device *wl_input_device, + const struct wl_input_device_listener *listener, void *data) { - return wl_proxy_add_listener((struct wl_proxy *) input_device, + return wl_proxy_add_listener((struct wl_proxy *) wl_input_device, (void (**)(void)) listener, data); } #define WL_INPUT_DEVICE_ATTACH 0 static inline struct wl_input_device * -wl_input_device_create(struct wl_display *display, uint32_t id) +wl_input_device_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_input_device", version); + return (struct wl_input_device *) wl_proxy_create_for_id(display, &wl_input_device_interface, id); } static inline void -wl_input_device_set_user_data(struct wl_input_device *input_device, void *user_data) +wl_input_device_set_user_data(struct wl_input_device *wl_input_device, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) input_device, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_input_device, user_data); } static inline void * -wl_input_device_get_user_data(struct wl_input_device *input_device) +wl_input_device_get_user_data(struct wl_input_device *wl_input_device) { - return wl_proxy_get_user_data((struct wl_proxy *) input_device); + return wl_proxy_get_user_data((struct wl_proxy *) wl_input_device); } static inline void -wl_input_device_destroy(struct wl_input_device *input_device) +wl_input_device_destroy(struct wl_input_device *wl_input_device) { - wl_proxy_destroy((struct wl_proxy *) input_device); + wl_proxy_destroy((struct wl_proxy *) wl_input_device); } static inline void -wl_input_device_attach(struct wl_input_device *input_device, uint32_t time, struct wl_buffer *buffer, int hotspot_x, int hotspot_y) +wl_input_device_attach(struct wl_input_device *wl_input_device, uint32_t time, struct wl_buffer *buffer, int hotspot_x, int hotspot_y) { - wl_proxy_marshal((struct wl_proxy *) input_device, + wl_proxy_marshal((struct wl_proxy *) wl_input_device, WL_INPUT_DEVICE_ATTACH, time, buffer, hotspot_x, hotspot_y); } struct wl_output_listener { void (*geometry)(void *data, - struct wl_output *output, + struct wl_output *wl_output, int x, int y, int width, @@ -786,61 +799,65 @@ struct wl_output_listener { }; static inline int -wl_output_add_listener(struct wl_output *output, - const struct wl_output_listener *listener, void *data) +wl_output_add_listener(struct wl_output *wl_output, + const struct wl_output_listener *listener, void *data) { - return wl_proxy_add_listener((struct wl_proxy *) output, + return wl_proxy_add_listener((struct wl_proxy *) wl_output, (void (**)(void)) listener, data); } static inline struct wl_output * -wl_output_create(struct wl_display *display, uint32_t id) +wl_output_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_output", version); + return (struct wl_output *) wl_proxy_create_for_id(display, &wl_output_interface, id); } static inline void -wl_output_set_user_data(struct wl_output *output, void *user_data) +wl_output_set_user_data(struct wl_output *wl_output, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) output, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_output, user_data); } static inline void * -wl_output_get_user_data(struct wl_output *output) +wl_output_get_user_data(struct wl_output *wl_output) { - return wl_proxy_get_user_data((struct wl_proxy *) output); + return wl_proxy_get_user_data((struct wl_proxy *) wl_output); } static inline void -wl_output_destroy(struct wl_output *output) +wl_output_destroy(struct wl_output *wl_output) { - wl_proxy_destroy((struct wl_proxy *) output); + wl_proxy_destroy((struct wl_proxy *) wl_output); } static inline struct wl_visual * -wl_visual_create(struct wl_display *display, uint32_t id) +wl_visual_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_visual", version); + return (struct wl_visual *) wl_proxy_create_for_id(display, &wl_visual_interface, id); } static inline void -wl_visual_set_user_data(struct wl_visual *visual, void *user_data) +wl_visual_set_user_data(struct wl_visual *wl_visual, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) visual, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_visual, user_data); } static inline void * -wl_visual_get_user_data(struct wl_visual *visual) +wl_visual_get_user_data(struct wl_visual *wl_visual) { - return wl_proxy_get_user_data((struct wl_proxy *) visual); + return wl_proxy_get_user_data((struct wl_proxy *) wl_visual); } static inline void -wl_visual_destroy(struct wl_visual *visual) +wl_visual_destroy(struct wl_visual *wl_visual) { - wl_proxy_destroy((struct wl_proxy *) visual); + wl_proxy_destroy((struct wl_proxy *) wl_visual); } #ifdef __cplusplus diff --git a/src/3rdparty/wayland/wayland-client.c b/src/3rdparty/wayland/wayland-client.c index da89b5bc8..531807dba 100644 --- a/src/3rdparty/wayland/wayland-client.c +++ b/src/3rdparty/wayland/wayland-client.c @@ -34,7 +34,6 @@ #include <fcntl.h> #include <sys/poll.h> -#include "wayland-client-protocol.h" #include "connection.h" #include "wayland-util.h" #include "wayland-client.h" @@ -66,6 +65,13 @@ struct wl_frame_handler { struct wl_list link; }; +struct wl_global { + uint32_t id; + char *interface; + uint32_t version; + struct wl_list link; +}; + struct wl_display { struct wl_proxy proxy; struct wl_connection *connection; @@ -74,6 +80,7 @@ struct wl_display { uint32_t mask; struct wl_hash_table *objects; struct wl_list global_listener_list; + struct wl_list global_list; struct wl_visual *argb_visual; struct wl_visual *premultiplied_argb_visual; @@ -234,6 +241,22 @@ wl_display_get_rgb_visual(struct wl_display *display) return display->rgb_visual; } +/* Can't do this, there may be more than one instance of an + * interface... */ +WL_EXPORT uint32_t +wl_display_get_global(struct wl_display *display, + const char *interface, uint32_t version) +{ + struct wl_global *global; + + wl_list_for_each(global, &display->global_list, link) + if (strcmp(interface, global->interface) == 0 && + version <= global->version) + return global->id; + + return 0; +} + static void display_handle_invalid_object(void *data, struct wl_display *display, uint32_t id) @@ -265,13 +288,20 @@ display_handle_global(void *data, uint32_t id, const char *interface, uint32_t version) { struct wl_global_listener *listener; + struct wl_global *global; - if (strcmp(interface, "display") == 0) + if (strcmp(interface, "wl_display") == 0) wl_hash_table_insert(display->objects, id, &display->proxy.object); - else if (strcmp(interface, "visual") == 0) + else if (strcmp(interface, "wl_visual") == 0) add_visual(display, id); + global = malloc(sizeof *global); + global->id = id; + global->interface = strdup(interface); + global->version = version; + wl_list_insert(display->global_list.prev, &global->link); + wl_list_for_each(listener, &display->global_listener_list, link) (*listener->handler)(display, id, interface, version, listener->data); @@ -403,6 +433,7 @@ wl_display_connect(const char *name) return NULL; } wl_list_init(&display->global_listener_list); + wl_list_init(&display->global_list); display->proxy.object.interface = &wl_display_interface; display->proxy.object.id = 1; @@ -424,6 +455,9 @@ wl_display_connect(const char *name) free(display); return NULL; } + + wl_display_bind(display, 1, "wl_display", 1); + return display; } diff --git a/src/3rdparty/wayland/wayland-client.h b/src/3rdparty/wayland/wayland-client.h index 1064a3a19..f1ac7978c 100644 --- a/src/3rdparty/wayland/wayland-client.h +++ b/src/3rdparty/wayland/wayland-client.h @@ -24,12 +24,28 @@ #define _WAYLAND_CLIENT_H #include "wayland-util.h" -#include "wayland-client-protocol.h" #ifdef __cplusplus extern "C" { #endif +struct wl_proxy; +struct wl_display; + +void wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...); +struct wl_proxy *wl_proxy_create(struct wl_proxy *factory, + const struct wl_interface *interface); +struct wl_proxy *wl_proxy_create_for_id(struct wl_display *display, + const struct wl_interface *interface, + uint32_t id); +void wl_proxy_destroy(struct wl_proxy *proxy); +int wl_proxy_add_listener(struct wl_proxy *proxy, + void (**implementation)(void), void *data); +void wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data); +void *wl_proxy_get_user_data(struct wl_proxy *proxy); + +#include "wayland-client-protocol.h" + #define WL_DISPLAY_READABLE 0x01 #define WL_DISPLAY_WRITABLE 0x02 @@ -59,10 +75,13 @@ typedef void (*wl_display_global_func_t)(struct wl_display *display, void wl_display_remove_global_listener(struct wl_display *display, struct wl_global_listener *listener); - struct wl_global_listener * wl_display_add_global_listener(struct wl_display *display, wl_display_global_func_t handler, void *data); +WL_EXPORT uint32_t +wl_display_get_global(struct wl_display *display, + const char *interface, uint32_t version); + struct wl_visual * wl_display_get_argb_visual(struct wl_display *display); struct wl_visual * @@ -70,6 +89,7 @@ wl_display_get_premultiplied_argb_visual(struct wl_display *display); struct wl_visual * wl_display_get_rgb_visual(struct wl_display *display); + #ifdef __cplusplus } #endif diff --git a/src/3rdparty/wayland/wayland-egl.h b/src/3rdparty/wayland/wayland-egl.h index d3de87c79..85fe73d90 100644 --- a/src/3rdparty/wayland/wayland-egl.h +++ b/src/3rdparty/wayland/wayland-egl.h @@ -32,19 +32,11 @@ extern "C" { #define WL_EGL_PLATFORM 1 -struct wl_egl_display; struct wl_egl_window; struct wl_egl_pixmap; -struct wl_egl_display * -wl_egl_display_create(struct wl_display *egl_display); - -void -wl_egl_display_destroy(struct wl_egl_display *egl_display); - struct wl_egl_window * -wl_egl_window_create(struct wl_egl_display *egl_display, - struct wl_surface *surface, +wl_egl_window_create(struct wl_surface *surface, int width, int height, struct wl_visual *visual); @@ -58,22 +50,16 @@ wl_egl_window_resize(struct wl_egl_window *egl_window, void wl_egl_window_get_attached_size(struct wl_egl_window *egl_window, - int *width, int *height); + int *width, int *height); struct wl_egl_pixmap * -wl_egl_pixmap_create(struct wl_egl_display *egl_display, - int width, int height, +wl_egl_pixmap_create(int width, int height, struct wl_visual *visual, uint32_t flags); void wl_egl_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap); struct wl_buffer * -wl_egl_pixmap_create_buffer(struct wl_egl_display *egl_display, - struct wl_egl_pixmap *egl_pixmap); - -void -wl_egl_pixmap_flush(struct wl_egl_display *egl_display, - struct wl_egl_pixmap *egl_pixmap); +wl_egl_pixmap_create_buffer(struct wl_egl_pixmap *egl_pixmap); #ifdef __cplusplus } diff --git a/src/3rdparty/wayland/wayland-protocol.c b/src/3rdparty/wayland/wayland-protocol.c index 9ae296a4c..afcd2c9d3 100644 --- a/src/3rdparty/wayland/wayland-protocol.c +++ b/src/3rdparty/wayland/wayland-protocol.c @@ -25,12 +25,13 @@ #include <stdint.h> #include "wayland-util.h" -static const struct wl_message display_requests[] = { +static const struct wl_message wl_display_requests[] = { + { "bind", "usu" }, { "sync", "u" }, { "frame", "ou" }, }; -static const struct wl_message display_events[] = { +static const struct wl_message wl_display_events[] = { { "invalid_object", "u" }, { "invalid_method", "uu" }, { "no_memory", "" }, @@ -40,115 +41,116 @@ static const struct wl_message display_events[] = { }; WL_EXPORT const struct wl_interface wl_display_interface = { - "display", 1, - ARRAY_LENGTH(display_requests), display_requests, - ARRAY_LENGTH(display_events), display_events, + "wl_display", 1, + ARRAY_LENGTH(wl_display_requests), wl_display_requests, + ARRAY_LENGTH(wl_display_events), wl_display_events, }; -static const struct wl_message compositor_requests[] = { +static const struct wl_message wl_compositor_requests[] = { { "create_surface", "n" }, }; WL_EXPORT const struct wl_interface wl_compositor_interface = { - "compositor", 1, - ARRAY_LENGTH(compositor_requests), compositor_requests, + "wl_compositor", 1, + ARRAY_LENGTH(wl_compositor_requests), wl_compositor_requests, 0, NULL, }; -static const struct wl_message shm_requests[] = { +static const struct wl_message wl_shm_requests[] = { { "create_buffer", "nhiiuo" }, }; WL_EXPORT const struct wl_interface wl_shm_interface = { - "shm", 1, - ARRAY_LENGTH(shm_requests), shm_requests, + "wl_shm", 1, + ARRAY_LENGTH(wl_shm_requests), wl_shm_requests, 0, NULL, }; -static const struct wl_message buffer_requests[] = { +static const struct wl_message wl_buffer_requests[] = { + { "damage", "iiii" }, { "destroy", "" }, }; WL_EXPORT const struct wl_interface wl_buffer_interface = { - "buffer", 1, - ARRAY_LENGTH(buffer_requests), buffer_requests, + "wl_buffer", 1, + ARRAY_LENGTH(wl_buffer_requests), wl_buffer_requests, 0, NULL, }; -static const struct wl_message shell_requests[] = { +static const struct wl_message wl_shell_requests[] = { { "move", "oou" }, { "resize", "oouu" }, { "create_drag", "n" }, { "create_selection", "n" }, }; -static const struct wl_message shell_events[] = { +static const struct wl_message wl_shell_events[] = { { "configure", "uuoii" }, }; WL_EXPORT const struct wl_interface wl_shell_interface = { - "shell", 1, - ARRAY_LENGTH(shell_requests), shell_requests, - ARRAY_LENGTH(shell_events), shell_events, + "wl_shell", 1, + ARRAY_LENGTH(wl_shell_requests), wl_shell_requests, + ARRAY_LENGTH(wl_shell_events), wl_shell_events, }; -static const struct wl_message selection_requests[] = { +static const struct wl_message wl_selection_requests[] = { { "offer", "s" }, { "activate", "ou" }, { "destroy", "" }, }; -static const struct wl_message selection_events[] = { +static const struct wl_message wl_selection_events[] = { { "send", "sh" }, { "cancelled", "" }, }; WL_EXPORT const struct wl_interface wl_selection_interface = { - "selection", 1, - ARRAY_LENGTH(selection_requests), selection_requests, - ARRAY_LENGTH(selection_events), selection_events, + "wl_selection", 1, + ARRAY_LENGTH(wl_selection_requests), wl_selection_requests, + ARRAY_LENGTH(wl_selection_events), wl_selection_events, }; -static const struct wl_message selection_offer_requests[] = { +static const struct wl_message wl_selection_offer_requests[] = { { "receive", "sh" }, }; -static const struct wl_message selection_offer_events[] = { +static const struct wl_message wl_selection_offer_events[] = { { "offer", "s" }, { "keyboard_focus", "o" }, }; WL_EXPORT const struct wl_interface wl_selection_offer_interface = { - "selection_offer", 1, - ARRAY_LENGTH(selection_offer_requests), selection_offer_requests, - ARRAY_LENGTH(selection_offer_events), selection_offer_events, + "wl_selection_offer", 1, + ARRAY_LENGTH(wl_selection_offer_requests), wl_selection_offer_requests, + ARRAY_LENGTH(wl_selection_offer_events), wl_selection_offer_events, }; -static const struct wl_message drag_requests[] = { +static const struct wl_message wl_drag_requests[] = { { "offer", "s" }, { "activate", "oou" }, { "destroy", "" }, }; -static const struct wl_message drag_events[] = { +static const struct wl_message wl_drag_events[] = { { "target", "s" }, { "finish", "h" }, { "reject", "" }, }; WL_EXPORT const struct wl_interface wl_drag_interface = { - "drag", 1, - ARRAY_LENGTH(drag_requests), drag_requests, - ARRAY_LENGTH(drag_events), drag_events, + "wl_drag", 1, + ARRAY_LENGTH(wl_drag_requests), wl_drag_requests, + ARRAY_LENGTH(wl_drag_events), wl_drag_events, }; -static const struct wl_message drag_offer_requests[] = { +static const struct wl_message wl_drag_offer_requests[] = { { "accept", "us" }, { "receive", "h" }, { "reject", "" }, }; -static const struct wl_message drag_offer_events[] = { +static const struct wl_message wl_drag_offer_events[] = { { "offer", "s" }, { "pointer_focus", "uoiiii" }, { "motion", "uiiii" }, @@ -156,12 +158,12 @@ static const struct wl_message drag_offer_events[] = { }; WL_EXPORT const struct wl_interface wl_drag_offer_interface = { - "drag_offer", 1, - ARRAY_LENGTH(drag_offer_requests), drag_offer_requests, - ARRAY_LENGTH(drag_offer_events), drag_offer_events, + "wl_drag_offer", 1, + ARRAY_LENGTH(wl_drag_offer_requests), wl_drag_offer_requests, + ARRAY_LENGTH(wl_drag_offer_events), wl_drag_offer_events, }; -static const struct wl_message surface_requests[] = { +static const struct wl_message wl_surface_requests[] = { { "destroy", "" }, { "attach", "oii" }, { "map_toplevel", "" }, @@ -171,16 +173,16 @@ static const struct wl_message surface_requests[] = { }; WL_EXPORT const struct wl_interface wl_surface_interface = { - "surface", 1, - ARRAY_LENGTH(surface_requests), surface_requests, + "wl_surface", 1, + ARRAY_LENGTH(wl_surface_requests), wl_surface_requests, 0, NULL, }; -static const struct wl_message input_device_requests[] = { +static const struct wl_message wl_input_device_requests[] = { { "attach", "uoii" }, }; -static const struct wl_message input_device_events[] = { +static const struct wl_message wl_input_device_events[] = { { "motion", "uiiii" }, { "button", "uuu" }, { "key", "uuu" }, @@ -189,23 +191,23 @@ static const struct wl_message input_device_events[] = { }; WL_EXPORT const struct wl_interface wl_input_device_interface = { - "input_device", 1, - ARRAY_LENGTH(input_device_requests), input_device_requests, - ARRAY_LENGTH(input_device_events), input_device_events, + "wl_input_device", 1, + ARRAY_LENGTH(wl_input_device_requests), wl_input_device_requests, + ARRAY_LENGTH(wl_input_device_events), wl_input_device_events, }; -static const struct wl_message output_events[] = { +static const struct wl_message wl_output_events[] = { { "geometry", "iiii" }, }; WL_EXPORT const struct wl_interface wl_output_interface = { - "output", 1, + "wl_output", 1, 0, NULL, - ARRAY_LENGTH(output_events), output_events, + ARRAY_LENGTH(wl_output_events), wl_output_events, }; WL_EXPORT const struct wl_interface wl_visual_interface = { - "visual", 1, + "wl_visual", 1, 0, NULL, 0, NULL, }; diff --git a/src/3rdparty/wayland/wayland-server-protocol.h b/src/3rdparty/wayland/wayland-server-protocol.h index 6529ead04..bd6f91c98 100644 --- a/src/3rdparty/wayland/wayland-server-protocol.h +++ b/src/3rdparty/wayland/wayland-server-protocol.h @@ -63,11 +63,16 @@ extern const struct wl_interface wl_output_interface; extern const struct wl_interface wl_visual_interface; struct wl_display_interface { + void (*bind)(struct wl_client *client, + struct wl_display *wl_display, + uint32_t id, + const char *interface, + uint32_t version); void (*sync)(struct wl_client *client, - struct wl_display *display, + struct wl_display *wl_display, uint32_t key); void (*frame)(struct wl_client *client, - struct wl_display *display, + struct wl_display *wl_display, struct wl_surface *surface, uint32_t key); }; @@ -81,13 +86,13 @@ struct wl_display_interface { struct wl_compositor_interface { void (*create_surface)(struct wl_client *client, - struct wl_compositor *compositor, + struct wl_compositor *wl_compositor, uint32_t id); }; struct wl_shm_interface { void (*create_buffer)(struct wl_client *client, - struct wl_shm *shm, + struct wl_shm *wl_shm, uint32_t id, int fd, int width, @@ -97,8 +102,14 @@ struct wl_shm_interface { }; struct wl_buffer_interface { + void (*damage)(struct wl_client *client, + struct wl_buffer *wl_buffer, + int x, + int y, + int width, + int height); void (*destroy)(struct wl_client *client, - struct wl_buffer *buffer); + struct wl_buffer *wl_buffer); }; #ifndef WL_SHELL_RESIZE_ENUM @@ -118,21 +129,21 @@ enum wl_shell_resize { struct wl_shell_interface { void (*move)(struct wl_client *client, - struct wl_shell *shell, + struct wl_shell *wl_shell, struct wl_surface *surface, struct wl_input_device *input_device, uint32_t time); void (*resize)(struct wl_client *client, - struct wl_shell *shell, + struct wl_shell *wl_shell, struct wl_surface *surface, struct wl_input_device *input_device, uint32_t time, uint32_t edges); void (*create_drag)(struct wl_client *client, - struct wl_shell *shell, + struct wl_shell *wl_shell, uint32_t id); void (*create_selection)(struct wl_client *client, - struct wl_shell *shell, + struct wl_shell *wl_shell, uint32_t id); }; @@ -140,14 +151,14 @@ struct wl_shell_interface { struct wl_selection_interface { void (*offer)(struct wl_client *client, - struct wl_selection *selection, + struct wl_selection *wl_selection, const char *type); void (*activate)(struct wl_client *client, - struct wl_selection *selection, + struct wl_selection *wl_selection, struct wl_input_device *input_device, uint32_t time); void (*destroy)(struct wl_client *client, - struct wl_selection *selection); + struct wl_selection *wl_selection); }; #define WL_SELECTION_SEND 0 @@ -155,7 +166,7 @@ struct wl_selection_interface { struct wl_selection_offer_interface { void (*receive)(struct wl_client *client, - struct wl_selection_offer *selection_offer, + struct wl_selection_offer *wl_selection_offer, const char *mime_type, int fd); }; @@ -165,15 +176,15 @@ struct wl_selection_offer_interface { struct wl_drag_interface { void (*offer)(struct wl_client *client, - struct wl_drag *drag, + struct wl_drag *wl_drag, const char *type); void (*activate)(struct wl_client *client, - struct wl_drag *drag, + struct wl_drag *wl_drag, struct wl_surface *surface, struct wl_input_device *input_device, uint32_t time); void (*destroy)(struct wl_client *client, - struct wl_drag *drag); + struct wl_drag *wl_drag); }; #define WL_DRAG_TARGET 0 @@ -182,14 +193,14 @@ struct wl_drag_interface { struct wl_drag_offer_interface { void (*accept)(struct wl_client *client, - struct wl_drag_offer *drag_offer, + struct wl_drag_offer *wl_drag_offer, uint32_t time, const char *type); void (*receive)(struct wl_client *client, - struct wl_drag_offer *drag_offer, + struct wl_drag_offer *wl_drag_offer, int fd); void (*reject)(struct wl_client *client, - struct wl_drag_offer *drag_offer); + struct wl_drag_offer *wl_drag_offer); }; #define WL_DRAG_OFFER_OFFER 0 @@ -199,24 +210,24 @@ struct wl_drag_offer_interface { struct wl_surface_interface { void (*destroy)(struct wl_client *client, - struct wl_surface *surface); + struct wl_surface *wl_surface); void (*attach)(struct wl_client *client, - struct wl_surface *surface, + struct wl_surface *wl_surface, struct wl_buffer *buffer, int x, int y); void (*map_toplevel)(struct wl_client *client, - struct wl_surface *surface); + struct wl_surface *wl_surface); void (*map_transient)(struct wl_client *client, - struct wl_surface *surface, + struct wl_surface *wl_surface, struct wl_surface *parent, int x, int y, uint32_t flags); void (*map_fullscreen)(struct wl_client *client, - struct wl_surface *surface); + struct wl_surface *wl_surface); void (*damage)(struct wl_client *client, - struct wl_surface *surface, + struct wl_surface *wl_surface, int x, int y, int width, @@ -225,7 +236,7 @@ struct wl_surface_interface { struct wl_input_device_interface { void (*attach)(struct wl_client *client, - struct wl_input_device *input_device, + struct wl_input_device *wl_input_device, uint32_t time, struct wl_buffer *buffer, int hotspot_x, diff --git a/src/3rdparty/wayland/wayland-server.c b/src/3rdparty/wayland/wayland-server.c index 358fa4899..d9f14adf4 100644 --- a/src/3rdparty/wayland/wayland-server.c +++ b/src/3rdparty/wayland/wayland-server.c @@ -84,7 +84,7 @@ struct wl_frame_listener { struct wl_global { struct wl_object *object; - wl_client_connect_func_t func; + wl_global_bind_func_t func; struct wl_list link; }; @@ -113,7 +113,7 @@ wl_client_post_event(struct wl_client *client, struct wl_object *sender, wl_closure_destroy(closure); } -static void +static int wl_client_connection_data(int fd, uint32_t mask, void *data) { struct wl_client *client = data; @@ -133,7 +133,7 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) len = wl_connection_data(connection, cmask); if (len < 0) { wl_client_destroy(client); - return; + return 1; } while (len >= sizeof p) { @@ -185,6 +185,8 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) wl_closure_destroy(closure); } + + return 1; } static int @@ -244,15 +246,7 @@ wl_client_create(struct wl_display *display, int fd) wl_display_post_range(display, client); wl_list_for_each(global, &display->global_list, link) - wl_client_post_event(client, &client->display->object, - WL_DISPLAY_GLOBAL, - global->object, - global->object->interface->name, - global->object->interface->version); - - wl_list_for_each(global, &display->global_list, link) - if (global->func) - global->func(client, global->object); + wl_client_post_global(client, global->object); return client; } @@ -476,6 +470,18 @@ wl_input_device_update_grab(struct wl_input_device *device, } static void +display_bind(struct wl_client *client, + struct wl_display *display, uint32_t id, + const char *interface, uint32_t version) +{ + struct wl_global *global; + + wl_list_for_each(global, &display->global_list, link) + if (global->object->id == id && global->func) + global->func(client, global->object, version); +} + +static void display_sync(struct wl_client *client, struct wl_display *display, uint32_t key) { @@ -518,6 +524,7 @@ display_frame(struct wl_client *client, } struct wl_display_interface display_interface = { + display_bind, display_sync, display_frame }; @@ -598,7 +605,7 @@ wl_display_add_object(struct wl_display *display, struct wl_object *object) WL_EXPORT int wl_display_add_global(struct wl_display *display, - struct wl_object *object, wl_client_connect_func_t func) + struct wl_object *object, wl_global_bind_func_t func) { struct wl_global *global; @@ -610,7 +617,7 @@ wl_display_add_global(struct wl_display *display, global->func = func; wl_list_insert(display->global_list.prev, &global->link); - return 0; + return 0; } WL_EXPORT void @@ -649,7 +656,7 @@ wl_display_run(struct wl_display *display) wl_event_loop_dispatch(display->loop, -1); } -static void +static int socket_data(int fd, uint32_t mask, void *data) { struct wl_display *display = data; @@ -665,6 +672,8 @@ socket_data(int fd, uint32_t mask, void *data) fprintf(stderr, "failed to accept: %m\n"); wl_client_create(display, client_fd); + + return 1; } static int diff --git a/src/3rdparty/wayland/wayland-server.h b/src/3rdparty/wayland/wayland-server.h index 8032866ca..649bb6b0b 100644 --- a/src/3rdparty/wayland/wayland-server.h +++ b/src/3rdparty/wayland/wayland-server.h @@ -38,9 +38,9 @@ enum { struct wl_event_loop; struct wl_event_source; -typedef void (*wl_event_loop_fd_func_t)(int fd, uint32_t mask, void *data); -typedef void (*wl_event_loop_timer_func_t)(void *data); -typedef void (*wl_event_loop_signal_func_t)(int signal_number, void *data); +typedef int (*wl_event_loop_fd_func_t)(int fd, uint32_t mask, void *data); +typedef int (*wl_event_loop_timer_func_t)(void *data); +typedef int (*wl_event_loop_signal_func_t)(int signal_number, void *data); typedef void (*wl_event_loop_idle_func_t)(void *data); struct wl_event_loop *wl_event_loop_create(void); @@ -62,6 +62,7 @@ wl_event_loop_add_signal(struct wl_event_loop *loop, int wl_event_source_timer_update(struct wl_event_source *source, int ms_delay); int wl_event_source_remove(struct wl_event_source *source); +void wl_event_source_check(struct wl_event_source *source); int wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout); @@ -81,11 +82,16 @@ int wl_display_add_socket(struct wl_display *display, const char *name); void wl_display_terminate(struct wl_display *display); void wl_display_run(struct wl_display *display); -void wl_display_add_object(struct wl_display *display, struct wl_object *object); +void wl_display_add_object(struct wl_display *display, + struct wl_object *object); -typedef void (*wl_client_connect_func_t)(struct wl_client *client, struct wl_object *global); +typedef void (*wl_global_bind_func_t)(struct wl_client *client, + struct wl_object *global, + uint32_t version); -int wl_display_add_global(struct wl_display *display, struct wl_object *object, wl_client_connect_func_t func); +int wl_display_add_global(struct wl_display *display, + struct wl_object *object, + wl_global_bind_func_t func); struct wl_client *wl_client_create(struct wl_display *display, int fd); void wl_client_destroy(struct wl_client *client); @@ -96,6 +102,16 @@ struct wl_visual { struct wl_object object; }; +struct wl_shm_callbacks { + void (*buffer_created)(struct wl_buffer *buffer); + + void (*buffer_damaged)(struct wl_buffer *buffer, + int32_t x, int32_t y, + int32_t width, int32_t height); + + void (*buffer_destroyed)(struct wl_buffer *buffer); +}; + struct wl_compositor { struct wl_object object; struct wl_visual argb_visual; @@ -115,10 +131,7 @@ struct wl_buffer { struct wl_compositor *compositor; struct wl_visual *visual; int32_t width, height; - void (*attach)(struct wl_buffer *buffer, struct wl_surface *surface); - void (*damage)(struct wl_buffer *buffer, - struct wl_surface *surface, - int32_t x, int32_t y, int32_t width, int32_t height); + void *user_data; }; struct wl_listener { @@ -133,10 +146,6 @@ struct wl_surface { struct wl_list destroy_listener_list; }; -struct wl_shell { - struct wl_object object; -}; - struct wl_grab; struct wl_grab_interface { void (*motion)(struct wl_grab *grab, @@ -255,6 +264,29 @@ wl_input_device_update_grab(struct wl_input_device *device, struct wl_grab *grab, struct wl_surface *surface, uint32_t time); +struct wl_shm; + +void * +wl_shm_buffer_get_data(struct wl_buffer *buffer); + +int32_t +wl_shm_buffer_get_stride(struct wl_buffer *buffer); + +struct wl_buffer * +wl_shm_buffer_create(struct wl_shm *shm, int width, int height, + int stride, struct wl_visual *visual, + void *data); + +int +wl_buffer_is_shm(struct wl_buffer *buffer); + +struct wl_shm * +wl_shm_init(struct wl_display *display, + const struct wl_shm_callbacks *callbacks); + +void +wl_shm_finish(struct wl_shm *shm); + int wl_compositor_init(struct wl_compositor *compositor, const struct wl_compositor_interface *interface, diff --git a/src/3rdparty/wayland/wayland-shm.c b/src/3rdparty/wayland/wayland-shm.c new file mode 100644 index 000000000..5f46293fc --- /dev/null +++ b/src/3rdparty/wayland/wayland-shm.c @@ -0,0 +1,228 @@ +/* + * Copyright © 2008 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + * + * Authors: + * Kristian Høgsberg <krh@bitplanet.net> + * Benjamin Franzke <benjaminfranzke@googlemail.com> + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <unistd.h> + +#include "wayland-server.h" + +struct wl_shm { + struct wl_object object; + const struct wl_shm_callbacks *callbacks; +}; + +struct wl_shm_buffer { + struct wl_buffer buffer; + struct wl_shm *shm; + int32_t stride; + void *data; +}; + +static void +destroy_buffer(struct wl_resource *resource, struct wl_client *client) +{ + struct wl_shm_buffer *buffer = + container_of(resource, struct wl_shm_buffer, buffer.resource); + + munmap(buffer->data, buffer->stride * buffer->buffer.height); + + buffer->shm->callbacks->buffer_destroyed(&buffer->buffer); + + free(buffer); +} + +static void +shm_buffer_damage(struct wl_client *client, struct wl_buffer *buffer_base, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + struct wl_shm_buffer *buffer = (struct wl_shm_buffer *) buffer_base; + + buffer->shm->callbacks->buffer_damaged(buffer_base, x, y, + width, height); +} + +static void +shm_buffer_destroy(struct wl_client *client, struct wl_buffer *buffer) +{ + wl_resource_destroy(&buffer->resource, client); +} + +const static struct wl_buffer_interface shm_buffer_interface = { + shm_buffer_damage, + shm_buffer_destroy +}; + +static struct wl_shm_buffer * +wl_shm_buffer_init(struct wl_shm *shm, uint32_t id, + int32_t width, int32_t height, + int32_t stride, struct wl_visual *visual, + void *data) +{ + struct wl_shm_buffer *buffer; + + buffer = malloc(sizeof *buffer); + if (buffer == NULL) + return NULL; + + buffer->buffer.width = width; + buffer->buffer.height = height; + buffer->buffer.visual = visual; + buffer->stride = stride; + buffer->data = data; + + buffer->buffer.resource.object.id = id; + buffer->buffer.resource.object.interface = &wl_buffer_interface; + buffer->buffer.resource.object.implementation = (void (**)(void)) + &shm_buffer_interface; + + buffer->buffer.resource.destroy = destroy_buffer; + + buffer->shm = shm; + + buffer->shm->callbacks->buffer_created(&buffer->buffer); + + return buffer; +} + +static void +shm_create_buffer(struct wl_client *client, struct wl_shm *shm, + uint32_t id, int fd, int32_t width, int32_t height, + uint32_t stride, struct wl_visual *visual) +{ + struct wl_shm_buffer *buffer; + struct wl_display *display = wl_client_get_display(client); + + void *data; + + /* FIXME: Define a real exception event instead of abusing the + * display.invalid_object error */ + if (visual->object.interface != &wl_visual_interface) { + wl_client_post_event(client, (struct wl_object *) display, + WL_DISPLAY_INVALID_OBJECT, 0); + fprintf(stderr, "invalid visual in create_buffer\n"); + close(fd); + return; + } + + if (width < 0 || height < 0 || stride < width) { + wl_client_post_event(client, (struct wl_object *) display, + WL_DISPLAY_INVALID_OBJECT, 0); + fprintf(stderr, + "invalid width, height or stride in create_buffer\n"); + close(fd); + return; + } + + data = mmap(NULL, stride * height, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + close(fd); + if (data == MAP_FAILED) { + /* FIXME: Define a real exception event instead of + * abusing this one */ + wl_client_post_event(client, (struct wl_object *) display, + WL_DISPLAY_INVALID_OBJECT, 0); + fprintf(stderr, "failed to create image for fd %d\n", fd); + return; + } + + buffer = wl_shm_buffer_init(shm, id, + width, height, stride, visual, + data); + if (buffer == NULL) { + munmap(data, stride * height); + wl_client_post_no_memory(client); + return; + } + + wl_client_add_resource(client, &buffer->buffer.resource); +} + +const static struct wl_shm_interface shm_interface = { + shm_create_buffer +}; + + +WL_EXPORT struct wl_shm * +wl_shm_init(struct wl_display *display, + const struct wl_shm_callbacks *callbacks) +{ + struct wl_shm *shm; + + shm = malloc(sizeof *shm); + if (!shm) + return NULL; + + shm->object.interface = &wl_shm_interface; + shm->object.implementation = (void (**)(void)) &shm_interface; + wl_display_add_object(display, &shm->object); + wl_display_add_global(display, &shm->object, NULL); + + shm->callbacks = callbacks; + + return shm; +} + +WL_EXPORT void +wl_shm_finish(struct wl_shm *shm) +{ + /* FIXME: add wl_display_del_{object,global} */ + + free(shm); +} + +WL_EXPORT int +wl_buffer_is_shm(struct wl_buffer *buffer) +{ + return buffer->resource.object.implementation == + (void (**)(void)) &shm_buffer_interface; +} + +WL_EXPORT int32_t +wl_shm_buffer_get_stride(struct wl_buffer *buffer_base) +{ + struct wl_shm_buffer *buffer = (struct wl_shm_buffer *) buffer_base; + + if (!wl_buffer_is_shm(buffer_base)) + return 0; + + return buffer->stride; +} + +WL_EXPORT void * +wl_shm_buffer_get_data(struct wl_buffer *buffer_base) +{ + struct wl_shm_buffer *buffer = (struct wl_shm_buffer *) buffer_base; + + if (!wl_buffer_is_shm(buffer_base)) + return NULL; + + return buffer->data; +} |