8 #include <drm_fourcc.h>
10 #include <wayland-server.h>
11 #include <libds/log.h>
12 #include <libds/backend.h>
13 #include <libds/output.h>
14 #include <libds/compositor.h>
15 #include <libds/xdg_shell.h>
16 #include <libds-tizen/allocator/tbm.h>
17 #include <libds-tizen/backend/tdm.h>
18 #include <libds/backend/libinput.h>
19 #include <libds-tizen/tbm_server.h>
21 #include <libds/input_device.h>
22 #include <libds/keyboard.h>
23 #include <libds/touch.h>
24 #include <libds/pointer.h>
25 #include <libds/seat.h>
27 #define USE_TDM_BUFFER_QUEUE
29 #ifdef USE_TDM_BUFFER_QUEUE
30 #include "pixman-tbm-helper.h"
31 #include "tinyds-tdm-renderer.h"
33 #include <libds/swapchain.h>
36 #include "pixman-helper.h"
38 #define TINYDS_UNUSED __attribute__((unused))
42 struct tinyds_server *server;
43 struct ds_output *ds_output;
44 struct ds_allocator *allocator;
45 #ifdef USE_TDM_BUFFER_QUEUE
46 struct tinyds_renderer renderer;
47 struct ds_tdm_buffer_queue *buffer_queue;
48 struct wl_listener buffer_queue_acquirable;
50 struct ds_swapchain *swapchain;
52 struct ds_buffer *front_buffer;
54 struct wl_listener output_destroy;
55 struct wl_listener output_frame;
65 struct ds_tbm_server *tbm_server;
67 struct wl_display *display;
69 struct ds_backend *backend;
70 struct ds_backend *input_backend;
71 struct ds_compositor *compositor;
72 struct ds_xdg_shell *xdg_shell;
75 double output_x, output_y;
77 struct tinyds_output *output;
78 struct wl_event_source *stdin_source;
82 struct wl_listener new_output;
83 struct wl_listener new_input;
84 struct wl_listener new_xdg_surface;
89 struct tinyds_server *server;
91 struct tinyds_texture *texture;
92 struct ds_xdg_surface *xdg_surface;
94 struct wl_listener xdg_surface_map;
95 struct wl_listener xdg_surface_unmap;
96 struct wl_listener xdg_surface_destroy;
97 struct wl_listener surface_commit;
98 struct wl_list link; // tinyds_server::views
104 struct tinyds_pointer
106 struct ds_input_device *dev;
107 struct tinyds_server *server;
109 struct tinyds_view *focused_view;
111 struct wl_listener destroy;
112 struct wl_listener motion; //relative
113 struct wl_listener button;
114 struct wl_listener frame;
117 struct tinyds_keyboard
119 struct ds_input_device *dev;
120 struct tinyds_server *server;
122 struct wl_listener destroy;
123 struct wl_listener key;
128 struct ds_input_device *dev;
129 struct tinyds_server *server;
131 struct wl_listener destroy;
132 struct wl_listener down;
133 struct wl_listener up;
134 struct wl_listener motion;
137 struct tinyds_server tinyds;
139 static bool init_server(struct tinyds_server *server, struct wl_display *display);
140 static int server_dispatch_stdin(int fd, uint32_t mask, void *data);
141 static void output_handle_destroy(struct wl_listener *listener, void *data);
142 static void output_handle_frame(struct wl_listener *listener, void *data);
143 static void draw_server_with_damage(struct tinyds_server *server);
144 static void draw_output(struct tinyds_output *output);
145 static void output_swap_buffer(struct tinyds_output *output,
146 struct ds_buffer *buffer);
147 static void view_send_frame_done(struct tinyds_view *view);
148 #ifdef USE_TDM_BUFFER_QUEUE
149 static void output_buffer_queue_init(struct tinyds_output *output);
150 static void output_renderer_init(struct tinyds_output *output);
151 static void output_draw_with_renderer(struct tinyds_output *output);
153 static void output_swapchain_init(struct tinyds_output *output,
154 int width, int height, uint32_t format);
155 static void output_draw_with_swapchain(struct tinyds_output *output);
156 static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image);
158 static void server_add_keyboard(struct tinyds_server *server,
159 struct ds_input_device *dev);
160 static void server_add_pointer(struct tinyds_server *server,
161 struct ds_input_device *dev);
162 static void server_add_touch(struct tinyds_server *server,
163 struct ds_input_device *dev);
168 struct tinyds_server *server = &tinyds;
169 struct wl_display *display;
170 struct wl_event_loop *loop;
174 ds_log_init(DS_INF, NULL);
176 display = wl_display_create();
179 res = init_server(server, display);
182 socket = wl_display_add_socket_auto(display);
185 ds_backend_start(server->backend);
186 ds_backend_start(server->input_backend);
188 setenv("WAYLAND_DISPLAY", socket, true);
190 ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
192 loop = wl_display_get_event_loop(display);
193 server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO,
194 WL_EVENT_READABLE, server_dispatch_stdin, server);
196 wl_display_run(display);
198 wl_display_destroy_clients(display);
199 wl_display_destroy(display);
205 view_handle_xdg_surface_map(struct wl_listener *listener,
206 void *data TINYDS_UNUSED)
208 struct tinyds_view *view;
210 view = wl_container_of(listener, view, xdg_surface_map);
215 view_handle_xdg_surface_unmap(struct wl_listener *listener,
216 void *data TINYDS_UNUSED)
218 struct tinyds_view *view;
220 view = wl_container_of(listener, view, xdg_surface_unmap);
221 view->mapped = false;
225 view_handle_xdg_surface_destroy(struct wl_listener *listener,
226 void *data TINYDS_UNUSED)
228 struct tinyds_view *view;
229 struct tinyds_server *server;
231 view = wl_container_of(listener, view, xdg_surface_destroy);
232 server = view->server;
234 wl_list_remove(&view->xdg_surface_destroy.link);
235 wl_list_remove(&view->xdg_surface_map.link);
236 wl_list_remove(&view->xdg_surface_unmap.link);
237 wl_list_remove(&view->surface_commit.link);
238 wl_list_remove(&view->link);
241 draw_server_with_damage(server);
245 view_handle_surface_commit(struct wl_listener *listener,
246 void *data TINYDS_UNUSED)
248 struct tinyds_view *view;
250 view = wl_container_of(listener, view, surface_commit);
251 draw_server_with_damage(view->server);
255 server_new_xdg_surface(struct wl_listener *listener, void *data)
257 struct tinyds_server *server;
258 struct tinyds_view *view;
259 struct ds_xdg_surface *xdg_surface;
261 server = wl_container_of(listener, server, new_xdg_surface);
264 ds_inf("New xdg_surface(%p)", (void *)xdg_surface);
266 view = calloc(1, sizeof *view);
269 view->server = server;
270 view->xdg_surface = xdg_surface;
272 view->xdg_surface_map.notify = view_handle_xdg_surface_map;
273 ds_xdg_surface_add_map_listener(xdg_surface,
274 &view->xdg_surface_map);
276 view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap;
277 ds_xdg_surface_add_unmap_listener(xdg_surface,
278 &view->xdg_surface_unmap);
280 view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy;
281 ds_xdg_surface_add_destroy_listener(xdg_surface,
282 &view->xdg_surface_destroy);
284 view->surface_commit.notify = view_handle_surface_commit;
285 ds_surface_add_commit_listener(
286 ds_xdg_surface_get_surface(xdg_surface),
287 &view->surface_commit);
289 wl_list_insert(server->views.prev, &view->link);
291 view->x = rand() % 1000;
292 view->y = rand() % 500;
296 backend_handle_new_output(struct wl_listener *listener, void *data)
298 struct tinyds_server *server;
299 struct tinyds_output *output;
300 struct ds_output *ds_output;
301 const struct ds_output_mode *mode;
303 server = wl_container_of(listener, server, new_output);
306 ds_inf("New output(%p)", ds_output);
311 mode = ds_output_get_preferred_mode(ds_output);
312 ds_output_set_mode(ds_output, mode);
314 output = calloc(1, sizeof *output);
318 output->server = server;
319 output->ds_output = ds_output;
320 output->width = mode->width;
321 output->height = mode->height;
322 output->drawable = true;
323 output->damaged = true;
325 #ifdef USE_TDM_BUFFER_QUEUE
326 output_buffer_queue_init(output);
327 output_renderer_init(output);
329 output_swapchain_init(output, mode->width, mode->height,
330 DRM_FORMAT_XRGB8888);
333 output->output_destroy.notify = output_handle_destroy;
334 ds_output_add_destroy_listener(ds_output, &output->output_destroy);
336 output->output_frame.notify = output_handle_frame;
337 ds_output_add_frame_listener(ds_output, &output->output_frame);
339 server->output = output;
345 backend_handle_new_input(struct wl_listener *listener, void *data)
347 struct tinyds_server *server;
348 struct ds_input_device *dev = data;
349 enum ds_input_device_type dev_type;
351 server = wl_container_of(listener, server, new_input);
353 dev_type = ds_input_device_get_type(dev);
356 case DS_INPUT_DEVICE_KEYBOARD:
357 server_add_keyboard(server, dev);
358 server->seat_caps |= WL_SEAT_CAPABILITY_KEYBOARD;
360 case DS_INPUT_DEVICE_TOUCH:
361 server_add_touch(server, dev);
362 server->seat_caps |= WL_SEAT_CAPABILITY_TOUCH;
364 case DS_INPUT_DEVICE_POINTER:
365 server_add_pointer(server, dev);
366 server->seat_caps |= WL_SEAT_CAPABILITY_POINTER;
369 ds_err("Unknown type(%d) of ds_input_device", dev_type);
373 ds_seat_set_capabilities(server->seat, server->seat_caps);
377 init_server(struct tinyds_server *server, struct wl_display *display)
379 server->display = display;
381 wl_list_init(&server->views);
383 if (wl_display_init_shm(display) != 0)
386 server->backend = ds_tdm_backend_create(display);
387 if (!server->backend)
390 server->input_backend = ds_libinput_backend_create(display);
391 if (!server->input_backend)
394 server->new_output.notify = backend_handle_new_output;
395 ds_backend_add_new_output_listener(server->backend,
396 &server->new_output);
398 server->new_input.notify = backend_handle_new_input;
399 ds_backend_add_new_input_listener(server->input_backend, &server->new_input);
401 server->compositor = ds_compositor_create(display);
402 if (!server->compositor)
405 server->tbm_server = ds_tbm_server_create(display);
406 if (!server->tbm_server)
409 server->xdg_shell = ds_xdg_shell_create(display);
410 if (!server->xdg_shell)
413 server->new_xdg_surface.notify = server_new_xdg_surface;
414 ds_xdg_shell_add_new_surface_listener(server->xdg_shell,
415 &server->new_xdg_surface);
417 server->seat = ds_seat_create(display, "seat0" /* arbitrary name */);
420 server->seat_caps = 0;
425 ds_backend_destroy(server->backend);
426 ds_backend_destroy(server->input_backend);
432 output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
434 struct tinyds_output *output =
435 wl_container_of(listener, output, output_destroy);
437 wl_list_remove(&output->output_destroy.link);
438 wl_list_remove(&output->output_frame.link);
440 if (output->front_buffer)
441 ds_buffer_unlock(output->front_buffer);
443 #ifdef USE_TDM_BUFFER_QUEUE
444 fini_renderer(&output->renderer);
446 if (output->swapchain)
447 ds_swapchain_destroy(output->swapchain);
449 if (output->allocator)
450 ds_allocator_destroy(output->allocator);
453 wl_display_terminate(output->server->display);
455 output->server->output = NULL;
461 output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED)
463 struct tinyds_output *output =
464 wl_container_of(listener, output, output_frame);
466 output->drawable = true;
471 draw_server_with_damage(struct tinyds_server *server)
473 server->output->damaged = true;
474 draw_output(server->output);
477 #ifdef USE_TDM_BUFFER_QUEUE
479 output_handle_buffer_queue_acquirable(struct wl_listener *listener,
480 void *data TINYDS_UNUSED)
482 struct tinyds_output *output;
483 struct ds_buffer *buffer;
485 output = wl_container_of(listener, output, buffer_queue_acquirable);
487 buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue);
490 output_swap_buffer(output, buffer);
494 output_buffer_queue_init(struct tinyds_output *output)
496 struct ds_tdm_output *tdm_output;
498 tdm_output = ds_tdm_output_from_output(output->ds_output);
501 output->buffer_queue = ds_tdm_output_get_buffer_queue(tdm_output);
502 assert(output->buffer_queue);
504 output->buffer_queue_acquirable.notify =
505 output_handle_buffer_queue_acquirable;
506 ds_tdm_buffer_queue_add_acquirable_listener(output->buffer_queue,
507 &output->buffer_queue_acquirable);
511 output_renderer_init(struct tinyds_output *output)
513 init_renderer(&output->renderer);
515 renderer_set_surface_queue(&output->renderer,
516 ds_tdm_buffer_queue_get_native_queue(output->buffer_queue));
518 renderer_set_bg_color(&output->renderer, 80, 80, 80);
522 output_draw_with_renderer(struct tinyds_output *output)
524 struct tinyds_view *view;
526 ds_dbg(">> BEGIN UPDATE TEXTURES");
528 wl_list_for_each(view, &output->server->views, link) {
529 struct ds_buffer *ds_buffer;
530 struct ds_tbm_client_buffer *tbm_buffer;
531 tbm_surface_h surface;
536 ds_buffer = ds_surface_get_buffer(
537 ds_xdg_surface_get_surface(view->xdg_surface));
540 tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer);
543 surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer);
545 renderer_add_texture(&output->renderer, surface, view->x, view->y);
547 view_send_frame_done(view);
550 ds_dbg("<< END UPDATE TEXTURES");
552 renderer_draw(&output->renderer);
557 output_swapchain_init(struct tinyds_output *output,
558 int width, int height, uint32_t format);
561 output->allocator = ds_tbm_allocator_create();
562 assert(output->allocator);
564 output->swapchain = ds_swapchain_create(output->allocator,
565 width, height, format);
566 assert(output->swapchain);
570 output_draw_with_swapchain(struct tinyds_output *output)
572 struct tinyds_view *view;
573 struct ds_buffer *output_buffer;
574 pixman_image_t *output_image;
576 output_buffer = ds_swapchain_acquire(output->swapchain, NULL);
580 output_image = pixman_image_from_buffer(output_buffer,
581 DS_BUFFER_DATA_PTR_ACCESS_WRITE);
583 ds_buffer_unlock(output_buffer);
587 pixman_image_fill_color(output_image, 80, 80, 80);
589 wl_list_for_each(view, &output->server->views, link) {
592 draw_view(view, output_image);
594 pixman_image_unref(output_image);
596 output_swap_buffer(output, output_buffer);
600 draw_view(struct tinyds_view *view, pixman_image_t *dst_image)
602 struct ds_buffer *buffer;
603 pixman_image_t *src_image;
605 buffer = ds_surface_get_buffer(
606 ds_xdg_surface_get_surface(view->xdg_surface));
610 src_image = pixman_image_from_buffer(buffer,
611 DS_BUFFER_DATA_PTR_ACCESS_READ);
612 pixman_image_composite32(PIXMAN_OP_OVER,
618 pixman_image_get_width(src_image),
619 pixman_image_get_height(src_image));
620 pixman_image_unref(src_image);
622 view_send_frame_done(view);
627 draw_output(struct tinyds_output *output)
630 if (!output->drawable || !output->damaged)
633 #ifdef USE_TDM_BUFFER_QUEUE
634 output_draw_with_renderer(output);
636 output_draw_with_swapchain(output);
639 output->drawable = false;
640 output->damaged = false;
644 output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer)
646 ds_output_attach_buffer(output->ds_output, buffer);
647 ds_output_commit(output->ds_output);
649 if (output->front_buffer)
650 ds_buffer_unlock(output->front_buffer);
651 output->front_buffer = buffer;
655 view_send_frame_done(struct tinyds_view *view)
658 clock_gettime(CLOCK_MONOTONIC, &now);
659 ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface),
664 server_dispatch_stdin(int fd, uint32_t mask, void *data)
666 struct tinyds_server *server = data;
668 wl_display_terminate(server->display);
675 keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
677 struct tinyds_keyboard *kbd;
679 kbd = wl_container_of(listener, kbd, destroy);
681 ds_inf("Keyboard(%p) destroyed", kbd);
683 wl_list_remove(&kbd->destroy.link);
684 wl_list_remove(&kbd->key.link);
690 keyboard_handle_key(struct wl_listener *listener, void *data)
692 struct tinyds_keyboard *kbd;
693 struct ds_event_keyboard_key *event = data;
695 kbd = wl_container_of(listener, kbd, key);
697 ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), "
698 "update_state(%d)", kbd->dev,
699 event->keycode, event->state, event->time_msec,
700 event->update_state);
702 //ds_seat_keyboard_notify_key()
706 server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev)
708 struct tinyds_keyboard *kbd;
710 kbd = calloc(1, sizeof *kbd);
714 kbd->server = server;
716 kbd->destroy.notify = keyboard_handle_device_destroy;
717 ds_input_device_add_destroy_listener(dev, &kbd->destroy);
719 kbd->key.notify = keyboard_handle_key;
720 ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key);
722 ds_inf("Keyboard(%p) added", kbd);
725 static struct tinyds_view *
726 server_view_at(struct tinyds_server *server, double lx, double ly,
727 double *sx, double *sy)
729 struct tinyds_view *view;
730 struct ds_surface *surface;
731 struct ds_buffer *buffer;
732 int x, y, w = 0, h = 0;
734 wl_list_for_each(view, &server->views, link) {
735 surface = ds_xdg_surface_get_surface(view->xdg_surface);
736 buffer = ds_surface_get_buffer(surface);
737 ds_buffer_get_size(buffer, &w, &h);
742 if (lx >= x && lx <= x + w && ly >= y && ly <= y + h) {
754 touch_handle_device_destroy(struct wl_listener *listener, void *data)
756 struct tinyds_touch *touch;
758 touch = wl_container_of(listener, touch, destroy);
760 ds_inf("Touch(%p) destroyed", touch);
762 wl_list_remove(&touch->destroy.link);
763 wl_list_remove(&touch->down.link);
764 wl_list_remove(&touch->up.link);
765 wl_list_remove(&touch->motion.link);
771 touch_handle_down(struct wl_listener *listener, void *data)
773 struct ds_event_touch_down *event = data;
774 struct tinyds_touch *touch;
775 struct tinyds_view *view;
776 struct tinyds_server *server;
777 double sx = 0.f, sy = 0.f;
779 touch = wl_container_of(listener, touch, down);
781 server = touch->server;
782 server->output_x = event->x * server->output->width;
783 server->output_y = event->y * server->output->height;
785 ds_inf("Touch(%p) event down: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
786 touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
788 view = server_view_at(server, server->output_x, server->output_y, &sx, &sy);
791 ds_seat_touch_notify_down(touch->server->seat, ds_xdg_surface_get_surface(view->xdg_surface),
792 event->time_msec, event->id, sx, sy);
797 touch_handle_up(struct wl_listener *listener, void *data)
799 struct ds_event_touch_up *event = data;
800 struct tinyds_touch *touch;
802 touch = wl_container_of(listener, touch, up);
804 ds_inf("Touch(%p) event up: id(%d) time_msec(%d)",
805 touch->dev, event->id, event->time_msec);
807 ds_seat_touch_notify_up(touch->server->seat, event->time_msec, event->id);
811 touch_handle_motion(struct wl_listener *listener, void *data)
813 struct ds_event_touch_motion *event = data;
814 struct tinyds_touch *touch;
815 struct tinyds_view *view;
816 struct tinyds_server *server;
817 double sx = 0.f, sy = 0.f;
819 touch = wl_container_of(listener, touch, motion);
821 server = touch->server;
822 server->output_x = event->x * server->output->width;
823 server->output_y = event->y * server->output->height;
825 ds_inf("Touch(%p) event motion: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
826 touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
828 view = server_view_at(server, server->output_x, server->output_y, &sx, &sy);
831 ds_seat_touch_notify_motion(server->seat, event->time_msec,
837 server_add_touch(struct tinyds_server *server, struct ds_input_device *dev)
839 struct tinyds_touch *touch;
841 touch = calloc(1, sizeof *touch);
845 touch->server = server;
847 touch->destroy.notify = touch_handle_device_destroy;
848 ds_input_device_add_destroy_listener(dev, &touch->destroy);
850 touch->down.notify = touch_handle_down;
851 ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down);
853 touch->up.notify = touch_handle_up;
854 ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up);
856 touch->motion.notify = touch_handle_motion;
857 ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion);
859 ds_inf("Touch(%p) added", touch);
863 pointer_handle_device_destroy(struct wl_listener *listener, void *data)
865 struct tinyds_pointer *pointer;
867 pointer = wl_container_of(listener, pointer, destroy);
869 ds_inf("Pointer(%p) destroyed", pointer);
871 wl_list_remove(&pointer->destroy.link);
872 wl_list_remove(&pointer->motion.link);
873 wl_list_remove(&pointer->button.link);
874 wl_list_remove(&pointer->frame.link);
880 pointer_handle_motion(struct wl_listener *listener, void *data)
882 struct tinyds_pointer *pointer;
883 struct ds_event_pointer_motion *event = data;
884 struct tinyds_view *view;
885 struct tinyds_server *server;
889 pointer = wl_container_of(listener, pointer, motion);
891 server = pointer->server;
892 if (server->output) {
893 ow = server->output->width;
894 oh = server->output->height;
897 if (server->output_x + event->delta_x >= ow)
898 server->output_x = ow;
899 else if(server->output_x + event->delta_x <= 0.f)
900 server->output_x = 0.f;
902 server->output_x = server->output_x + event->delta_x ;
903 if (server->output_y + event->delta_y >= oh)
904 server->output_y = oh;
905 else if(server->output_y + event->delta_y <= 0.f)
906 server->output_y = 0.f;
908 server->output_y = server->output_y + event->delta_y ;
910 ds_inf("Pointer(%p) motion: (delta_x %.1f delta_y %.1f) output_x %.1f output_y %.1f",
911 pointer, event->delta_x, event->delta_y, server->output_x, server->output_y);
913 view = server_view_at(pointer->server, server->output_x, server->output_y, &sx, &sy);
915 if (pointer->focused_view != view) {
916 if (pointer->focused_view) {
917 ds_inf("Clear pointer focus from view(%p)", pointer->focused_view);
918 ds_seat_pointer_notify_clear_focus(pointer->server->seat);
919 pointer->focused_view = NULL;
923 ds_inf("Set pointer focus to view(%p)", view);
924 ds_seat_pointer_notify_enter(pointer->server->seat,
925 ds_xdg_surface_get_surface(view->xdg_surface), sx, sy);
926 pointer->focused_view = view;
931 ds_seat_pointer_notify_motion(pointer->server->seat,
932 event->time_msec, sx, sy);
937 pointer_handle_button(struct wl_listener *listener, void *data)
939 struct tinyds_pointer *pointer;
940 struct ds_event_pointer_button *event = data;
942 pointer = wl_container_of(listener, pointer, button);
944 ds_inf("Pointer(%p) button(%d): state(%s) time(%d)",
945 pointer, event->button,
946 (event->state == DS_BUTTON_PRESSED) ? "Pressed" : "Released",
949 ds_seat_pointer_notify_button(pointer->server->seat, event->time_msec, event->button, event->state);
953 pointer_handle_frame(struct wl_listener *listener, void *data)
955 struct tinyds_pointer *pointer;
957 pointer = wl_container_of(listener, pointer, frame);
959 ds_inf("Pointer(%p) frame", pointer);
960 ds_seat_pointer_notify_frame(pointer->server->seat);
964 server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev)
966 struct tinyds_pointer *pointer;
968 pointer = calloc(1, sizeof *pointer);
972 pointer->server = server;
973 server->output_x = 200;
974 server->output_y = 200;
976 pointer->destroy.notify = pointer_handle_device_destroy;
977 ds_input_device_add_destroy_listener(dev, &pointer->destroy);
979 pointer->motion.notify = pointer_handle_motion;
980 ds_pointer_add_motion_listener(ds_input_device_get_pointer(dev),
983 pointer->button.notify = pointer_handle_button;
984 ds_pointer_add_button_listener(ds_input_device_get_pointer(dev),
987 pointer->frame.notify = pointer_handle_frame;
988 ds_pointer_add_frame_listener(ds_input_device_get_pointer(dev),
991 ds_inf("Pointer(%p) added", pointer);