bool mapped;
};
-struct tinyds_server _tinyds;
-
-static bool init_server(struct tinyds_server *server, struct wl_display *display);
-static void fini_server(struct tinyds_server *server);
-static void server_handle_new_input(struct wl_listener *listener, void *data);
-static bool init_output(struct tinyds_output *output, struct tinyds_server *server,
- int width, int height);
-static void fini_output(struct tinyds_output *output);
-static void output_handle_destroy(struct wl_listener *listener, void *data);
-static void output_handle_frame(struct wl_listener *listener, void *data);
-static void draw_server(struct tinyds_server *server);
-static void draw_server_with_damage(struct tinyds_server *server);
-static void draw_output(struct tinyds_output *output);
+static bool server_init(struct tinyds_server *server,
+ struct wl_display *display);
+static void server_fini(struct tinyds_server *server);
+static void server_add_view(struct tinyds_server *server,
+ struct ds_xdg_surface *xdg_surface);
+static bool output_init(struct tinyds_output *output,
+ struct tinyds_server *server, int width, int height);
+static void output_fini(struct tinyds_output *output);
+static void output_damage(struct tinyds_output *output);
+static void output_redraw(struct tinyds_output *output);
static void view_destroy(struct tinyds_view *view);
-static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image);
+static void view_composite(struct tinyds_view *view,
+ pixman_image_t *dst_image);
int
main(void)
{
- struct tinyds_server *server = &_tinyds;
+ struct tinyds_server server;
struct wl_display *display;
const char *socket;
display = wl_display_create();
assert(display);
- assert(init_server(server, display) == true);
-
- assert(init_output(&server->output, server,
- OUTPUT_WIDTH, OUTPUT_HEIGHT) == true);
+ assert(server_init(&server, display) == true);
socket = wl_display_add_socket_auto(display);
assert(socket);
- ds_backend_start(server->backend);
+ ds_backend_start(server.backend);
- draw_server(server);
+ output_damage(&server.output);
+ output_redraw(&server.output);
setenv("WAYLAND_DISPLAY", socket, true);
ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
- wl_display_run(server->display);
+ wl_display_run(server.display);
- fini_output(&server->output);
- fini_server(server);
+ server_fini(&server);
wl_display_destroy(display);
return 0;
}
static struct ds_backend *
-tinyds_create_backend_auto(struct wl_display *display)
+create_wl_backend(struct wl_display *display)
{
struct ds_backend *backend = NULL;
char name[512];
}
static void
+keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
+{
+ struct tinyds_keyboard *kbd;
+
+ kbd = wl_container_of(listener, kbd, destroy);
+
+ ds_inf("Keyboard(%p) destroyed", kbd);
+
+ wl_list_remove(&kbd->destroy.link);
+ wl_list_remove(&kbd->key.link);
+
+ free(kbd);
+}
+
+static bool
+server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym)
+{
+ switch (sym) {
+ case XKB_KEY_BackSpace:
+ wl_display_terminate(server->display);
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+static void
+keyboard_handle_key(struct wl_listener *listener, void *data)
+{
+ struct tinyds_keyboard *kbd;
+ struct ds_event_keyboard_key *event = data;
+ struct ds_keyboard *ds_keyboard;
+ struct xkb_state *xkb_state;
+ const xkb_keysym_t *syms;
+ uint32_t modifiers;
+ int nsyms;
+
+ kbd = wl_container_of(listener, kbd, key);
+
+ ds_keyboard = ds_input_device_get_keyboard(kbd->dev);
+
+ modifiers = ds_keyboard_get_modifiers(ds_keyboard);
+ if ((modifiers & DS_MODIFIER_CTRL) &&
+ (modifiers & DS_MODIFIER_ALT) &&
+ (modifiers & DS_MODIFIER_SHIFT) &&
+ event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
+ xkb_state = ds_keyboard_get_xkb_state(ds_keyboard);
+ if (xkb_state) {
+ nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8,
+ &syms);
+ for (int i = 0; i < nsyms; i++) {
+ server_handle_keybinding(kbd->server, syms[i]);
+ }
+ }
+ }
+}
+
+static void
+server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev)
+{
+ struct tinyds_keyboard *kbd;
+
+ kbd = calloc(1, sizeof *kbd);
+ assert(kbd);
+
+ kbd->dev = dev;
+ kbd->server = server;
+
+ kbd->destroy.notify = keyboard_handle_device_destroy;
+ ds_input_device_add_destroy_listener(dev, &kbd->destroy);
+
+ kbd->key.notify = keyboard_handle_key;
+ ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key);
+
+ ds_inf("Keyboard(%p) added", kbd);
+}
+
+static void
+touch_handle_device_destroy(struct wl_listener *listener, void *data)
+{
+ struct tinyds_touch *touch;
+
+ touch = wl_container_of(listener, touch, destroy);
+
+ ds_inf("Touch(%p) destroyed", touch);
+
+ wl_list_remove(&touch->destroy.link);
+ wl_list_remove(&touch->down.link);
+ wl_list_remove(&touch->up.link);
+ wl_list_remove(&touch->motion.link);
+
+ free(touch);
+}
+
+static void
+touch_handle_down(struct wl_listener *listener, void *data)
+{
+ ds_inf("Touch device(%p): down", data);
+}
+
+static void
+touch_handle_up(struct wl_listener *listener, void *data)
+{
+ ds_inf("Touch device(%p): up", data);
+}
+
+static void
+touch_handle_motion(struct wl_listener *listener, void *data)
+{
+ ds_inf("Touch device(%p): motion", data);
+}
+
+static void
+server_add_touch(struct tinyds_server *server, struct ds_input_device *dev)
+{
+ struct tinyds_touch *touch;
+
+ touch = calloc(1, sizeof *touch);
+ assert(touch);
+
+ touch->dev = dev;
+ touch->server = server;
+
+ touch->destroy.notify = touch_handle_device_destroy;
+ ds_input_device_add_destroy_listener(dev, &touch->destroy);
+
+ touch->down.notify = touch_handle_down;
+ ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down);
+
+ touch->up.notify = touch_handle_up;
+ ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up);
+
+ touch->motion.notify = touch_handle_motion;
+ ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion);
+
+ ds_inf("Touch(%p) added", touch);
+}
+
+static void
+server_handle_new_input(struct wl_listener *listener, void *data)
+{
+ struct tinyds_server *server;
+ struct ds_input_device *dev = data;
+ enum ds_input_device_type dev_type;
+
+ server = wl_container_of(listener, server, new_input);
+
+ dev_type = ds_input_device_get_type(dev);
+ switch (dev_type) {
+ case DS_INPUT_DEVICE_KEYBOARD:
+ server_add_keyboard(server, dev);
+ break;
+ case DS_INPUT_DEVICE_TOUCH:
+ server_add_touch(server, dev);
+ break;
+ default:
+ ds_err("Unknown type(%d) of ds_input_device", dev_type);
+ break;
+ }
+}
+
+static void
view_handle_xdg_surface_map(struct wl_listener *listener,
void *data TINYDS_UNUSED)
{
view = wl_container_of(listener, view, xdg_surface_destroy);
- draw_server_with_damage(view->server);
+ output_damage(&view->server->output);
+ output_redraw(&view->server->output);
view_destroy(view);
}
struct tinyds_view *view;
view = wl_container_of(listener, view, surface_commit);
- draw_server_with_damage(view->server);
+
+ output_damage(&view->server->output);
+ output_redraw(&view->server->output);
}
static void
server_new_xdg_surface(struct wl_listener *listener, void *data)
{
struct tinyds_server *server;
- struct tinyds_view *view;
- struct ds_xdg_surface *xdg_surface;
server = wl_container_of(listener, server, new_xdg_surface);
- xdg_surface = data;
-
- ds_inf("New xdg_surface(%p)", (void *)xdg_surface);
-
- view = calloc(1, sizeof *view);
- view->server = server;
- view->xdg_surface = xdg_surface;
-
- view->xdg_surface_map.notify = view_handle_xdg_surface_map;
- ds_xdg_surface_add_map_listener(xdg_surface,
- &view->xdg_surface_map);
-
- view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap;
- ds_xdg_surface_add_unmap_listener(xdg_surface,
- &view->xdg_surface_unmap);
-
- view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy;
- ds_xdg_surface_add_destroy_listener(xdg_surface,
- &view->xdg_surface_destroy);
- view->surface_commit.notify = view_handle_surface_commit;
- ds_surface_add_commit_listener(
- ds_xdg_surface_get_surface(xdg_surface),
- &view->surface_commit);
-
- wl_list_insert(server->views.prev, &view->link);
+ server_add_view(server, (struct ds_xdg_surface *)data);
}
static bool
-init_server(struct tinyds_server *server, struct wl_display *display)
+server_init(struct tinyds_server *server, struct wl_display *display)
{
server->display = display;
if (wl_display_init_shm(display) != 0)
return false;
- server->backend = tinyds_create_backend_auto(display);
+ server->backend = create_wl_backend(display);
if (!server->backend)
return false;
server->new_input.notify = server_handle_new_input;
ds_backend_add_new_input_listener(server->backend, &server->new_input);
+ if (!output_init(&server->output, server, OUTPUT_WIDTH, OUTPUT_HEIGHT))
+ goto err;
+
server->compositor = ds_compositor_create(display);
- if (!server->compositor) {
- ds_backend_destroy(server->backend);
- return false;
- }
+ if (!server->compositor)
+ goto err;
server->xdg_shell = ds_xdg_shell_create(display);
- if (!server->xdg_shell) {
- ds_backend_destroy(server->backend);
- return false;
- }
+ if (!server->xdg_shell)
+ goto err;
server->new_xdg_surface.notify = server_new_xdg_surface;
ds_xdg_shell_add_new_surface_listener(server->xdg_shell,
&server->new_xdg_surface);
return true;
+
+err:
+ ds_backend_destroy(server->backend);
+
+ return false;
}
static void
-fini_server(struct tinyds_server *server)
+server_fini(struct tinyds_server *server)
{
struct tinyds_view *view, *tmp;
wl_list_for_each_safe(view, tmp, &server->views, link)
view_destroy(view);
+ output_fini(&server->output);
+
wl_list_remove(&server->new_xdg_surface.link);
}
wl_container_of(listener, output, output_frame);
output->drawable = true;
- draw_output(output);
+ output_redraw(output);
}
static bool
-init_output(struct tinyds_output *output, struct tinyds_server *server,
+output_init(struct tinyds_output *output, struct tinyds_server *server,
int width, int height)
{
output->server = server;
output->width = width;
output->height = height;
output->drawable = true;
- output->damaged = true;
output->allocator = ds_shm_allocator_create();
if (!output->allocator)
}
static void
-fini_output(struct tinyds_output *output)
+output_fini(struct tinyds_output *output)
{
if (output->ds_output)
ds_output_destroy(output->ds_output);
}
static void
-draw_server(struct tinyds_server *server)
+output_damage(struct tinyds_output *output)
{
- draw_output(&server->output);
-}
-
-static void
-draw_server_with_damage(struct tinyds_server *server)
-{
- struct tinyds_output *output = &server->output;
-
output->damaged = true;
- draw_output(output);
}
-static void view_send_frame_done(struct tinyds_view *view);
-
static void
-draw_output(struct tinyds_output *output)
+output_redraw(struct tinyds_output *output)
{
struct ds_buffer *output_buffer;
pixman_image_t *output_image;
wl_list_for_each(view, &output->server->views, link) {
if (!view->mapped)
continue;
- draw_view(view, output_image);
+ view_composite(view, output_image);
}
pixman_image_unref(output_image);
}
static void
+server_add_view(struct tinyds_server *server, struct ds_xdg_surface *xdg_surface)
+{
+ struct tinyds_view *view;
+
+ view = calloc(1, sizeof *view);
+ view->server = server;
+ view->xdg_surface = xdg_surface;
+
+ view->xdg_surface_map.notify = view_handle_xdg_surface_map;
+ ds_xdg_surface_add_map_listener(xdg_surface,
+ &view->xdg_surface_map);
+
+ view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap;
+ ds_xdg_surface_add_unmap_listener(xdg_surface,
+ &view->xdg_surface_unmap);
+
+ view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy;
+ ds_xdg_surface_add_destroy_listener(xdg_surface,
+ &view->xdg_surface_destroy);
+
+ view->surface_commit.notify = view_handle_surface_commit;
+ ds_surface_add_commit_listener(
+ ds_xdg_surface_get_surface(xdg_surface),
+ &view->surface_commit);
+
+ wl_list_insert(server->views.prev, &view->link);
+
+ ds_inf("View(%p) added", view);
+}
+
+static void
view_destroy(struct tinyds_view *view)
{
ds_inf("View(%p) destroyed", view);
}
static void
-draw_view(struct tinyds_view *view, pixman_image_t *dst_image)
+view_send_frame_done(struct tinyds_view *view)
+{
+ struct timespec now;
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface),
+ &now);
+}
+
+static void
+view_composite(struct tinyds_view *view, pixman_image_t *dst_image)
{
struct ds_buffer *buffer;
pixman_image_t *src_image;
view_send_frame_done(view);
}
-
-static void
-view_send_frame_done(struct tinyds_view *view)
-{
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface),
- &now);
-}
-
-static void
-keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
-{
- struct tinyds_keyboard *kbd;
-
- kbd = wl_container_of(listener, kbd, destroy);
-
- ds_inf("Keyboard(%p) destroyed", kbd);
-
- wl_list_remove(&kbd->destroy.link);
- wl_list_remove(&kbd->key.link);
-
- free(kbd);
-}
-
-static bool
-server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym)
-{
- switch (sym) {
- case XKB_KEY_BackSpace:
- wl_display_terminate(server->display);
- break;
- default:
- return false;
- }
-
- return true;
-}
-
-static void
-keyboard_handle_key(struct wl_listener *listener, void *data)
-{
- struct tinyds_keyboard *kbd;
- struct ds_event_keyboard_key *event = data;
- struct ds_keyboard *ds_keyboard;
- struct xkb_state *xkb_state;
- const xkb_keysym_t *syms;
- uint32_t modifiers;
- int nsyms;
-
- kbd = wl_container_of(listener, kbd, key);
-
- ds_keyboard = ds_input_device_get_keyboard(kbd->dev);
-
- modifiers = ds_keyboard_get_modifiers(ds_keyboard);
- if ((modifiers & DS_MODIFIER_CTRL) &&
- (modifiers & DS_MODIFIER_ALT) &&
- (modifiers & DS_MODIFIER_SHIFT) &&
- event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
- xkb_state = ds_keyboard_get_xkb_state(ds_keyboard);
- if (xkb_state) {
- nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8,
- &syms);
- for (int i = 0; i < nsyms; i++) {
- server_handle_keybinding(kbd->server, syms[i]);
- }
- }
- }
-}
-
-static void
-server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev)
-{
- struct tinyds_keyboard *kbd;
-
- kbd = calloc(1, sizeof *kbd);
- assert(kbd);
-
- kbd->dev = dev;
- kbd->server = server;
-
- kbd->destroy.notify = keyboard_handle_device_destroy;
- ds_input_device_add_destroy_listener(dev, &kbd->destroy);
-
- kbd->key.notify = keyboard_handle_key;
- ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key);
-
- ds_inf("Keyboard(%p) added", kbd);
-}
-
-static void
-touch_handle_device_destroy(struct wl_listener *listener, void *data)
-{
- struct tinyds_touch *touch;
-
- touch = wl_container_of(listener, touch, destroy);
-
- ds_inf("Touch(%p) destroyed", touch);
-
- wl_list_remove(&touch->destroy.link);
- wl_list_remove(&touch->down.link);
- wl_list_remove(&touch->up.link);
- wl_list_remove(&touch->motion.link);
-
- free(touch);
-}
-
-static void
-touch_handle_down(struct wl_listener *listener, void *data)
-{
- ds_inf("Touch device(%p): down", data);
-}
-
-static void
-touch_handle_up(struct wl_listener *listener, void *data)
-{
- ds_inf("Touch device(%p): up", data);
-}
-
-static void
-touch_handle_motion(struct wl_listener *listener, void *data)
-{
- ds_inf("Touch device(%p): motion", data);
-}
-
-static void
-server_add_touch(struct tinyds_server *server, struct ds_input_device *dev)
-{
- struct tinyds_touch *touch;
-
- touch = calloc(1, sizeof *touch);
- assert(touch);
-
- touch->dev = dev;
- touch->server = server;
-
- touch->destroy.notify = touch_handle_device_destroy;
- ds_input_device_add_destroy_listener(dev, &touch->destroy);
-
- touch->down.notify = touch_handle_down;
- ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down);
-
- touch->up.notify = touch_handle_up;
- ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up);
-
- touch->motion.notify = touch_handle_motion;
- ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion);
-
- ds_inf("Touch(%p) added", touch);
-}
-
-static void
-server_handle_new_input(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
- struct ds_input_device *dev = data;
- enum ds_input_device_type dev_type;
-
- server = wl_container_of(listener, server, new_input);
-
- dev_type = ds_input_device_get_type(dev);
- switch (dev_type) {
- case DS_INPUT_DEVICE_KEYBOARD:
- server_add_keyboard(server, dev);
- break;
- case DS_INPUT_DEVICE_TOUCH:
- server_add_touch(server, dev);
- break;
- default:
- ds_err("Unknown type(%d) of ds_input_device", dev_type);
- break;
- }
-}