From 61e451ea1b36435341d02ae34548bd0ea3abdd57 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 24 Sep 2017 14:12:56 -0400 Subject: Move keyboard logic to wlr_{keyboard,seat} --- examples/compositor.c | 98 +++++++++++++-------------------------------------- 1 file changed, 25 insertions(+), 73 deletions(-) (limited to 'examples/compositor.c') diff --git a/examples/compositor.c b/examples/compositor.c index 53b385b7..f4377f23 100644 --- a/examples/compositor.c +++ b/examples/compositor.c @@ -32,9 +32,6 @@ #include "shared.h" #include -// TODO: move to common header? -int os_create_anonymous_file(off_t size); - struct sample_state; struct example_xdg_surface_v6 { @@ -75,13 +72,9 @@ struct sample_state { struct wlr_xdg_shell_v6 *xdg_shell; struct wlr_data_device_manager *data_device_manager; struct wl_resource *focus; - struct wl_listener keyboard_bound; struct wlr_xwayland *xwayland; struct wlr_gamma_control_manager *gamma_control_manager; bool mod_down; - int keymap_fd; - size_t keymap_size; - uint32_t serial; struct motion_context motion_context; @@ -335,61 +328,11 @@ static void handle_keyboard_key(struct keyboard_state *keyboard, uint32_t keycode, xkb_keysym_t sym, enum wlr_key_state key_state) { struct compositor_state *state = keyboard->compositor; struct sample_state *sample = state->data; - - struct wl_resource *res = NULL; - struct wlr_seat_handle *seat_handle = NULL; - wl_list_for_each(res, &sample->wlr_compositor->surfaces, link) { - break; - } - - if (res) { - seat_handle = wlr_seat_handle_for_client(sample->wl_seat, - wl_resource_get_client(res)); - } - - if (res != sample->focus && seat_handle && seat_handle->keyboard) { - struct wl_array keys; - wl_array_init(&keys); - uint32_t serial = wl_display_next_serial(state->display); - wl_keyboard_send_enter(seat_handle->keyboard, serial, res, &keys); - sample->focus = res; - } - - if (seat_handle && seat_handle->keyboard) { - uint32_t depressed = xkb_state_serialize_mods(keyboard->xkb_state, - XKB_STATE_MODS_DEPRESSED); - uint32_t latched = xkb_state_serialize_mods(keyboard->xkb_state, - XKB_STATE_MODS_LATCHED); - uint32_t locked = xkb_state_serialize_mods(keyboard->xkb_state, - XKB_STATE_MODS_LOCKED); - uint32_t group = xkb_state_serialize_layout(keyboard->xkb_state, - XKB_STATE_LAYOUT_EFFECTIVE); - uint32_t modifiers_serial = wl_display_next_serial(state->display); - uint32_t key_serial = wl_display_next_serial(state->display); - wl_keyboard_send_modifiers(seat_handle->keyboard, modifiers_serial, - depressed, latched, locked, group); - wl_keyboard_send_key(seat_handle->keyboard, key_serial, 0, keycode, - key_state); - } - if (sym == XKB_KEY_Super_L || sym == XKB_KEY_Super_R) { sample->mod_down = key_state == WLR_KEY_PRESSED; } } -static void handle_keyboard_bound(struct wl_listener *listener, void *data) { - struct wlr_seat_handle *handle = data; - struct sample_state *state = - wl_container_of(listener, state, keyboard_bound); - - wl_keyboard_send_keymap(handle->keyboard, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - state->keymap_fd, state->keymap_size); - - if (wl_resource_get_version(handle->keyboard) >= 2) { - wl_keyboard_send_repeat_info(handle->keyboard, 25, 600); - } -} - static struct wlr_xdg_surface_v6 *example_xdg_surface_at( struct sample_state *sample, int lx, int ly) { struct wlr_xdg_surface_v6 *xdg_surface; @@ -550,6 +493,25 @@ static void handle_input_add(struct compositor_state *state, example_config_configure_cursor(sample->config, sample->cursor, sample->compositor); } + + if (device->type == WLR_INPUT_DEVICE_KEYBOARD) { + struct xkb_rule_names rules; + memset(&rules, 0, sizeof(rules)); + rules.rules = getenv("XKB_DEFAULT_RULES"); + rules.model = getenv("XKB_DEFAULT_MODEL"); + rules.layout = getenv("XKB_DEFAULT_LAYOUT"); + rules.variant = getenv("XKB_DEFAULT_VARIANT"); + rules.options = getenv("XKB_DEFAULT_OPTIONS"); + struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (!context) { + wlr_log(L_ERROR, "Failed to create XKB context"); + exit(1); + } + wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names( + context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); + xkb_context_unref(context); + wlr_seat_attach_keyboard(sample->wl_seat, device); + } } static void handle_output_add(struct output_state *ostate) { @@ -669,35 +631,25 @@ int main(int argc, char *argv[]) { state.wl_seat = wlr_seat_create(compositor.display, "seat0"); assert(state.wl_seat); - state.keyboard_bound.notify = handle_keyboard_bound; - wl_signal_add(&state.wl_seat->events.keyboard_bound, &state.keyboard_bound); wlr_seat_set_capabilities(state.wl_seat, WL_SEAT_CAPABILITY_KEYBOARD | WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); - struct keyboard_state *kbstate; - wl_list_for_each(kbstate, &compositor.keyboards, link) { - char *keymap = xkb_keymap_get_as_string(kbstate->keymap, - XKB_KEYMAP_FORMAT_TEXT_V1); - state.keymap_size = strlen(keymap); - state.keymap_fd = os_create_anonymous_file(state.keymap_size); - void *ptr = - mmap(NULL, state.keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, - state.keymap_fd, 0); - strcpy(ptr, keymap); - free(keymap); - break; - } state.xwayland = wlr_xwayland_create(compositor.display, state.wlr_compositor); compositor.keyboard_key_cb = handle_keyboard_key; + if (!wlr_backend_start(compositor.backend)) { + wlr_log(L_ERROR, "Failed to start backend"); + wlr_backend_destroy(compositor.backend); + exit(1); + } + wl_display_run(compositor.display); wl_list_remove(&state.new_xdg_surface_v6.link); wlr_xwayland_destroy(state.xwayland); - close(state.keymap_fd); wlr_seat_destroy(state.wl_seat); wlr_gamma_control_manager_destroy(state.gamma_control_manager); wlr_data_device_manager_destroy(state.data_device_manager); -- cgit v1.2.3 From e6a6634bc50bc65e5813a9ebc336869e6e85e816 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 25 Sep 2017 08:47:00 -0400 Subject: Minor tweaks to (broken) keyboard support --- examples/compositor.c | 5 +- include/wlr/types/wlr_seat.h | 7 +-- types/wlr_keyboard.c | 2 +- types/wlr_seat.c | 117 ++++++++++++------------------------------- 4 files changed, 35 insertions(+), 96 deletions(-) (limited to 'examples/compositor.c') diff --git a/examples/compositor.c b/examples/compositor.c index 8c1f9b09..6f28b193 100644 --- a/examples/compositor.c +++ b/examples/compositor.c @@ -122,10 +122,7 @@ static void example_set_focused_surface(struct sample_state *sample, } if (surface) { - // TODO: send array of currently pressed keys - struct wl_array keys; - wl_array_init(&keys); - wlr_seat_keyboard_enter(sample->wl_seat, surface->surface, keys); + wlr_seat_keyboard_enter(sample->wl_seat, surface->surface); } else { wlr_seat_keyboard_clear_focus(sample->wl_seat); } diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index 86fd36dd..6927cd16 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -29,8 +29,8 @@ struct wlr_seat_pointer_state { struct wlr_seat_handle *focused_handle; struct wlr_surface *focused_surface; - struct wl_listener focus_surface_destroy_listener; - struct wl_listener focus_resource_destroy_listener; + struct wl_listener surface_destroy; + struct wl_listener resource_destroy; }; struct wlr_seat_keyboard { @@ -47,9 +47,6 @@ struct wlr_seat_keyboard_state { struct wlr_seat_handle *focused_handle; struct wlr_surface *focused_surface; - int keymap_fd; - size_t keymap_size; - struct wl_listener surface_destroy; struct wl_listener resource_destroy; }; diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index 08b098d2..f9b26a36 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -66,7 +66,7 @@ void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, } char *keymap_str = xkb_keymap_get_as_string(kb->keymap, XKB_KEYMAP_FORMAT_TEXT_V1); - kb->keymap_size = strlen(keymap_str); + kb->keymap_size = strlen(keymap_str) + 1; kb->keymap_fd = os_create_anonymous_file(kb->keymap_size); void *ptr = mmap(NULL, kb->keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, kb->keymap_fd, 0); diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 8e24886b..4fbe56c2 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -171,14 +171,13 @@ struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) { } wlr_seat->pointer_state.wlr_seat = wlr_seat; - wl_list_init(&wlr_seat->pointer_state.focus_resource_destroy_listener.link); - wl_list_init(&wlr_seat->pointer_state.focus_surface_destroy_listener.link); + wl_list_init(&wlr_seat->pointer_state.surface_destroy.link); + wl_list_init(&wlr_seat->pointer_state.resource_destroy.link); wlr_seat->keyboard_state.wlr_seat = wlr_seat; + wl_list_init(&wlr_seat->keyboard_state.resource_destroy.link); wl_list_init( - &wlr_seat->keyboard_state.focus_resource_destroy_listener.link); - wl_list_init( - &wlr_seat->keyboard_state.focus_surface_destroy_listener.link); + &wlr_seat->keyboard_state.surface_destroy.link); struct wl_global *wl_global = wl_global_create(display, &wl_seat_interface, 6, wlr_seat, wl_seat_bind); @@ -250,20 +249,18 @@ bool wlr_seat_pointer_surface_has_focus(struct wlr_seat *wlr_seat, return surface == wlr_seat->pointer_state.focused_surface; } -static void handle_pointer_focus_surface_destroyed( - struct wl_listener *listener, void *data) { - struct wlr_seat_pointer_state *state = - wl_container_of(listener, state, focus_surface_destroy_listener); - +static void pointer_surface_destroy_notify(struct wl_listener *listener, + void *data) { + struct wlr_seat_pointer_state *state = wl_container_of( + listener, state, surface_destroy); state->focused_surface = NULL; wlr_seat_pointer_clear_focus(state->wlr_seat); } -static void handle_pointer_focus_resource_destroyed( - struct wl_listener *listener, void *data) { - struct wlr_seat_pointer_state *state = - wl_container_of(listener, state, focus_resource_destroy_listener); - +static void pointer_resource_destroy_notify(struct wl_listener *listener, + void *data) { + struct wlr_seat_pointer_state *state = wl_container_of( + listener, state, resource_destroy); state->focused_surface = NULL; wlr_seat_pointer_clear_focus(state->wlr_seat); } @@ -311,21 +308,19 @@ void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat, } // reinitialize the focus destroy events - wl_list_remove( - &wlr_seat->pointer_state.focus_surface_destroy_listener.link); - wl_list_init(&wlr_seat->pointer_state.focus_surface_destroy_listener.link); - wl_list_remove( - &wlr_seat->pointer_state.focus_resource_destroy_listener.link); - wl_list_init(&wlr_seat->pointer_state.focus_resource_destroy_listener.link); + wl_list_remove(&wlr_seat->pointer_state.surface_destroy.link); + wl_list_init(&wlr_seat->pointer_state.surface_destroy.link); + wl_list_remove(&wlr_seat->pointer_state.resource_destroy.link); + wl_list_init(&wlr_seat->pointer_state.resource_destroy.link); if (surface) { wl_signal_add(&surface->signals.destroy, - &wlr_seat->pointer_state.focus_surface_destroy_listener); + &wlr_seat->pointer_state.surface_destroy); wl_resource_add_destroy_listener(surface->resource, - &wlr_seat->pointer_state.focus_resource_destroy_listener); - wlr_seat->pointer_state.focus_resource_destroy_listener.notify = - handle_pointer_focus_resource_destroyed; - wlr_seat->pointer_state.focus_surface_destroy_listener.notify = - handle_pointer_focus_surface_destroyed; + &wlr_seat->pointer_state.resource_destroy); + wlr_seat->pointer_state.resource_destroy.notify = + pointer_resource_destroy_notify; + wlr_seat->pointer_state.surface_destroy.notify = + pointer_surface_destroy_notify; } wlr_seat->pointer_state.focused_handle = handle; @@ -385,7 +380,7 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { struct wlr_seat_keyboard *seat_kb = wl_container_of( listener, seat_kb, key); struct wlr_seat *seat = seat_kb->seat; - struct wlr_seat_handle *handle = seat->pointer_state.focused_handle; + struct wlr_seat_handle *handle = seat->keyboard_state.focused_handle; if (!handle || !handle->keyboard) { return; } @@ -395,7 +390,8 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { if (handle->seat_keyboard != seat_kb) { // TODO: We should probably lift all of the keys set by the other // keyboard - wlr_log(L_DEBUG, "Sending key map"); + wlr_log(L_DEBUG, "Sending key map %d %zd", + seat_kb->keyboard->keymap_fd, seat_kb->keyboard->keymap_size); wl_keyboard_send_keymap(handle->keyboard, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, seat_kb->keyboard->keymap_fd, @@ -451,6 +447,7 @@ void wlr_seat_attach_keyboard(struct wlr_seat *seat, wl_list_init(&seat_kb->keymap.link); seat_kb->keymap.notify = keyboard_keymap_notify; wl_signal_add(&kb->events.keymap, &seat_kb->keymap); + // TODO: update keymap as necessary wl_list_init(&seat_kb->destroy.link); seat_kb->destroy.notify = keyboard_destroy_notify; wl_signal_add(&dev->events.destroy, &seat_kb->destroy); @@ -524,13 +521,10 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, } // reinitialize the focus destroy events - wl_list_remove( - &wlr_seat->keyboard_state.focus_surface_destroy_listener.link); - wl_list_init(&wlr_seat->keyboard_state.focus_surface_destroy_listener.link); - wl_list_remove( - &wlr_seat->keyboard_state.focus_resource_destroy_listener.link); - wl_list_init( - &wlr_seat->keyboard_state.focus_resource_destroy_listener.link); + wl_list_remove(&wlr_seat->keyboard_state.surface_destroy.link); + wl_list_init(&wlr_seat->keyboard_state.surface_destroy.link); + wl_list_remove(&wlr_seat->keyboard_state.resource_destroy.link); + wl_list_init(&wlr_seat->keyboard_state.resource_destroy.link); if (surface) { wl_signal_add(&surface->signals.destroy, &wlr_seat->keyboard_state.surface_destroy); @@ -549,54 +543,5 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, void wlr_seat_keyboard_clear_focus(struct wlr_seat *wlr_seat) { struct wl_array keys; wl_array_init(&keys); - wlr_seat_keyboard_enter(wlr_seat, NULL, keys); -} - -static bool wlr_seat_keyboard_has_focus_resource(struct wlr_seat *wlr_seat) { - return wlr_seat->keyboard_state.focused_handle && - wlr_seat->keyboard_state.focused_handle->keyboard; -} - -/* -void wlr_seat_keyboard_send_modifiers(struct wlr_seat *wlr_seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) { - uint32_t serial = 0; - struct wl_resource *keyboard; - - if (wlr_seat_keyboard_has_focus_resource(wlr_seat)) { - serial = wl_display_next_serial(wlr_seat->display); - keyboard = wlr_seat->keyboard_state.focused_handle->keyboard; - wl_keyboard_send_modifiers(keyboard, serial, mods_depressed, - mods_latched, mods_locked, group); - } - - if (wlr_seat_pointer_has_focus_resource(wlr_seat) && - wlr_seat->pointer_state.focused_handle->keyboard && - wlr_seat->pointer_state.focused_handle != - wlr_seat->keyboard_state.focused_handle) { - if (serial == 0) { - serial = wl_display_next_serial(wlr_seat->display); - } - keyboard = wlr_seat->pointer_state.focused_handle->keyboard; - - wl_keyboard_send_modifiers(keyboard, serial, mods_depressed, - mods_latched, mods_locked, group); - } -} - -void wlr_seat_keyboard_set_keymap(struct wlr_seat *wlr_seat, int keymap_fd, - size_t keymap_size) { - // TODO: we probably should wait to send the keymap if keys are pressed - struct wlr_seat_handle *handle; - wl_list_for_each(handle, &wlr_seat->handles, link) { - if (handle->keyboard) { - wl_keyboard_send_keymap(handle->keyboard, - WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymap_fd, keymap_size); - } - } - - wlr_seat->keyboard_state.keymap_fd = keymap_fd; - wlr_seat->keyboard_state.keymap_size = keymap_size; + wlr_seat_keyboard_enter(wlr_seat, NULL); } -*/ -- cgit v1.2.3 From e001e400221115b0fe41fb48df48e85a2ec4f6ba Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 27 Sep 2017 15:03:35 +0200 Subject: Set view->surface --- examples/compositor.c | 2 +- include/wlr/types/wlr_wl_shell.h | 4 ++-- rootston/wl_shell.c | 2 +- types/wlr_wl_shell.c | 16 ++++++++-------- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'examples/compositor.c') diff --git a/examples/compositor.c b/examples/compositor.c index 6f28b193..14831820 100644 --- a/examples/compositor.c +++ b/examples/compositor.c @@ -290,7 +290,7 @@ static void handle_output_frame(struct output_state *output, struct wlr_wl_shell_surface *wl_shell_surface; wl_list_for_each(wl_shell_surface, &sample->wl_shell->surfaces, link) { output_frame_handle_surface(sample, wlr_output, ts, - wl_shell_surface->surface, 200, 200); + wl_shell_surface->resource, 200, 200); } struct wlr_xdg_surface_v6 *xdg_surface; struct wlr_xdg_client_v6 *xdg_client; diff --git a/include/wlr/types/wlr_wl_shell.h b/include/wlr/types/wlr_wl_shell.h index 614d785b..d5b8a982 100644 --- a/include/wlr/types/wlr_wl_shell.h +++ b/include/wlr/types/wlr_wl_shell.h @@ -19,8 +19,8 @@ struct wlr_wl_shell { struct wlr_wl_shell_surface { struct wlr_wl_shell *shell; struct wl_client *client; - struct wl_resource *surface; - struct wlr_texture *wlr_texture; + struct wl_resource *resource; + struct wlr_surface *surface; struct wl_list link; uint32_t ping_serial; diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 0929a999..67c8f609 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -27,7 +27,7 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { view->x = view->y = 200; view->wl_shell_surface = surface; view->roots_wl_shell_surface = roots_surface; - //view->wlr_surface = surface->surface; + view->wlr_surface = surface->surface; //view->get_input_bounds = get_input_bounds; //view->activate = activate; view->desktop = desktop; diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index 42a906c9..b2a4dc28 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -96,9 +96,9 @@ static int wlr_wl_shell_surface_ping_timeout(void *user_data) { static void wl_shell_get_shell_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id, - struct wl_resource *surface) { - struct wlr_texture *wlr_texture = wl_resource_get_user_data(surface); - struct wlr_wl_shell *wlr_wl_shell = wl_resource_get_user_data(resource); + struct wl_resource *surface_resource) { + struct wlr_surface *surface = wl_resource_get_user_data(surface_resource); + struct wlr_wl_shell *wl_shell = wl_resource_get_user_data(resource); struct wlr_wl_shell_surface *state = calloc(1, sizeof(struct wlr_wl_shell_surface)); if (state == NULL) { @@ -106,9 +106,9 @@ static void wl_shell_get_shell_surface(struct wl_client *client, return; } - state->shell = wlr_wl_shell; + state->shell = wl_shell; state->client = client; - state->wlr_texture = wlr_texture; + state->resource = surface_resource; state->surface = surface; struct wl_resource *shell_surface_resource = wl_resource_create(client, @@ -127,8 +127,8 @@ static void wl_shell_get_shell_surface(struct wl_client *client, wl_client_post_no_memory(client); } - wl_list_insert(&wlr_wl_shell->surfaces, &state->link); - wl_signal_emit(&wlr_wl_shell->events.new_surface, state); + wl_list_insert(&wl_shell->surfaces, &state->link); + wl_signal_emit(&wl_shell->events.new_surface, state); } static struct wl_shell_interface wl_shell_impl = { @@ -200,5 +200,5 @@ void wlr_wl_shell_surface_ping(struct wlr_wl_shell_surface *surface) { wl_display_next_serial(wl_client_get_display(surface->client)); wl_event_source_timer_update(surface->ping_timer, surface->shell->ping_timeout); - wl_shell_surface_send_ping(surface->surface, surface->ping_serial); + wl_shell_surface_send_ping(surface->resource, surface->ping_serial); } -- cgit v1.2.3 From 4e70d36e61dd720e9caadb74b39d3a0cd6c8cad7 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 28 Sep 2017 01:36:23 +0200 Subject: examples/compositor: fix handle_output_frame --- examples/compositor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples/compositor.c') diff --git a/examples/compositor.c b/examples/compositor.c index 14831820..ae21697a 100644 --- a/examples/compositor.c +++ b/examples/compositor.c @@ -290,7 +290,7 @@ static void handle_output_frame(struct output_state *output, struct wlr_wl_shell_surface *wl_shell_surface; wl_list_for_each(wl_shell_surface, &sample->wl_shell->surfaces, link) { output_frame_handle_surface(sample, wlr_output, ts, - wl_shell_surface->resource, 200, 200); + wl_shell_surface->surface->resource, 200, 200); } struct wlr_xdg_surface_v6 *xdg_surface; struct wlr_xdg_client_v6 *xdg_client; -- cgit v1.2.3 From 906a816abf812445ec9e514e6115872632fb3ee1 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 28 Sep 2017 08:54:57 -0400 Subject: Fix rootston keyboard, add Xwayland --- examples/compositor.c | 2 +- include/rootston/desktop.h | 3 +++ include/rootston/input.h | 5 ----- include/rootston/server.h | 1 - include/rootston/view.h | 8 ++++++++ include/wlr/xwayland.h | 14 +++++++++++++- rootston/cursor.c | 1 + rootston/desktop.c | 6 ++++++ rootston/keyboard.c | 40 +++++++--------------------------------- rootston/meson.build | 1 + rootston/xwayland.c | 43 +++++++++++++++++++++++++++++++++++++++++++ types/wlr_keyboard.c | 1 + types/wlr_seat.c | 1 + xwayland/xwayland.c | 1 + xwayland/xwm.c | 6 +++++- 15 files changed, 91 insertions(+), 42 deletions(-) create mode 100644 rootston/xwayland.c (limited to 'examples/compositor.c') diff --git a/examples/compositor.c b/examples/compositor.c index ae21697a..7d6efdb6 100644 --- a/examples/compositor.c +++ b/examples/compositor.c @@ -323,7 +323,7 @@ static void handle_output_frame(struct output_state *output, struct wlr_x11_window *x11_window; wl_list_for_each(x11_window, &sample->xwayland->displayable_windows, link) { output_frame_handle_surface(sample, wlr_output, ts, - x11_window->surface, 200, 200); + x11_window->surface->resource, 200, 200); } wlr_renderer_end(sample->renderer); diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index ef361d87..5e138c11 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -34,11 +34,13 @@ struct roots_desktop { struct wlr_compositor *compositor; struct wlr_wl_shell *wl_shell; struct wlr_xdg_shell_v6 *xdg_shell_v6; + struct wlr_xwayland *xwayland; struct wlr_gamma_control_manager *gamma_control_manager; struct wl_listener output_add; struct wl_listener output_remove; struct wl_listener xdg_shell_v6_surface; + struct wl_listener xwayland_surface; struct wl_listener wl_shell_surface; }; @@ -57,5 +59,6 @@ void output_remove_notify(struct wl_listener *listener, void *data); void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data); void handle_wl_shell_surface(struct wl_listener *listener, void *data); +void handle_xwayland_surface(struct wl_listener *listener, void *data); #endif diff --git a/include/rootston/input.h b/include/rootston/input.h index ec1cd32d..b3ce84d7 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -15,11 +15,6 @@ struct roots_keyboard { struct wlr_input_device *device; struct wl_listener key; struct wl_list link; - struct xkb_keymap *keymap; - struct xkb_state *xkb_state; - xkb_led_index_t leds[WLR_LED_LAST]; - int keymap_fd; - size_t keymap_size; }; struct roots_pointer { diff --git a/include/rootston/server.h b/include/rootston/server.h index d9fa8f9e..15e3a4ee 100644 --- a/include/rootston/server.h +++ b/include/rootston/server.h @@ -23,7 +23,6 @@ struct roots_server { /* WLR tools */ struct wlr_backend *backend; struct wlr_renderer *renderer; - struct wlr_xwayland *xwayland; /* Global resources */ struct wlr_data_device_manager *data_device_manager; diff --git a/include/rootston/view.h b/include/rootston/view.h index 1010566a..8d4d69c5 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -27,6 +27,12 @@ struct roots_xdg_surface_v6 { struct wl_listener request_show_window_menu; }; +struct roots_x11_surface { + struct roots_view *view; + // TODO: Maybe destroy listener should go in roots_view + struct wl_listener destroy; +}; + enum roots_view_type { ROOTS_WL_SHELL_VIEW, ROOTS_XDG_SHELL_V6_VIEW, @@ -42,10 +48,12 @@ struct roots_view { union { struct wlr_wl_shell_surface *wl_shell_surface; struct wlr_xdg_surface_v6 *xdg_surface_v6; + struct wlr_x11_window *x11_window; }; union { struct roots_wl_shell_surface *roots_wl_shell_surface; struct roots_xdg_surface_v6 *roots_xdg_surface_v6; + struct roots_x11_surface *roots_x11_surface; }; struct wlr_surface *wlr_surface; struct wl_list link; diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 41b8042f..e3eadc2d 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -21,6 +21,12 @@ struct wlr_xwayland { struct wl_listener destroy_listener; struct wlr_xwm *xwm; struct wl_list displayable_windows; + + struct { + struct wl_signal new_surface; + } events; + + void *data; }; struct wlr_x11_window { @@ -28,11 +34,17 @@ struct wlr_x11_window { uint32_t surface_id; struct wl_list link; - struct wl_resource *surface; + struct wlr_surface *surface; struct wl_listener surface_destroy_listener; int16_t x, y; uint16_t width, height; bool override_redirect; + + struct { + struct wl_signal destroy; + } events; + + void *data; }; void wlr_xwayland_destroy(struct wlr_xwayland *wlr_xwayland); diff --git a/rootston/cursor.c b/rootston/cursor.c index 0e9bf748..226fe412 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -100,6 +100,7 @@ static void do_cursor_button_press(struct roots_input *input, input->input_events_idx = (i + 1) % (sizeof(input->input_events) / sizeof(input->input_events[0])); set_view_focus(input, desktop, view); + wlr_seat_keyboard_enter(input->wl_seat, view->wlr_surface); break; } } diff --git a/rootston/desktop.c b/rootston/desktop.c index f9af3b8e..0224dd19 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -83,6 +83,12 @@ struct roots_desktop *desktop_create(struct roots_server *server, &desktop->wl_shell_surface); desktop->wl_shell_surface.notify = handle_wl_shell_surface; + desktop->xwayland = wlr_xwayland_create(server->wl_display, + desktop->compositor); + wl_signal_add(&desktop->xwayland->events.new_surface, + &desktop->xwayland_surface); + desktop->xwayland_surface.notify = handle_xwayland_surface; + desktop->gamma_control_manager = wlr_gamma_control_manager_create( server->wl_display); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 54ae3f8f..57e0d14e 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -10,38 +10,19 @@ #include #include "rootston/input.h" -static void keyboard_led_update(struct roots_keyboard *keyboard) { - uint32_t leds = 0; - for (uint32_t i = 0; i < WLR_LED_LAST; ++i) { - if (xkb_state_led_index_is_active( - keyboard->xkb_state, keyboard->leds[i])) { - leds |= (1 << i); - } - } - wlr_keyboard_led_update(keyboard->device->keyboard, leds); -} - static void keyboard_key_notify(struct wl_listener *listener, void *data) { struct wlr_event_keyboard_key *event = data; struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); struct roots_input *input = keyboard->input; struct roots_server *server = input->server; - uint32_t keycode = event->keycode + 8; + enum wlr_key_state key_state = event->state; + uint32_t keycode = event->keycode + 8; const xkb_keysym_t *syms; - int nsyms = xkb_state_key_get_syms(keyboard->xkb_state, keycode, &syms); - xkb_state_update_key(keyboard->xkb_state, keycode, - event->state == WLR_KEY_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP); - keyboard_led_update(keyboard); + int nsyms = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, + keycode, &syms); for (int i = 0; i < nsyms; ++i) { xkb_keysym_t sym = syms[i]; - char name[64]; - int l = xkb_keysym_get_name(sym, name, sizeof(name)); - if (l != -1 && l != sizeof(name)) { - wlr_log(L_DEBUG, "Key event: %s %s", name, - key_state == WLR_KEY_PRESSED ? "pressed" : "released"); - } - // TODO: pass key to clients if (sym == XKB_KEY_Escape) { // TEMPORARY, probably wl_display_terminate(server->wl_display); @@ -77,16 +58,9 @@ void keyboard_add(struct wlr_input_device *device, struct roots_input *input) { rules.options = getenv("XKB_DEFAULT_OPTIONS"); struct xkb_context *context; assert(context = xkb_context_new(XKB_CONTEXT_NO_FLAGS)); - assert(keyboard->keymap = xkb_map_new_from_names(context, &rules, + wlr_keyboard_set_keymap(device->keyboard, + xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); xkb_context_unref(context); - assert(keyboard->xkb_state = xkb_state_new(keyboard->keymap)); - const char *led_names[3] = { - XKB_LED_NAME_NUM, - XKB_LED_NAME_CAPS, - XKB_LED_NAME_SCROLL - }; - for (uint32_t i = 0; i < 3; ++i) { - keyboard->leds[i] = xkb_map_led_get_index(keyboard->keymap, led_names[i]); - } + wlr_seat_attach_keyboard(input->wl_seat, device); } diff --git a/rootston/meson.build b/rootston/meson.build index 6e9e0041..59f73e96 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -10,6 +10,7 @@ executable( 'output.c', 'pointer.c', 'xdg_shell_v6.c', + 'xwayland.c', 'wl_shell.c', ], dependencies: wlroots ) diff --git a/rootston/xwayland.c b/rootston/xwayland.c new file mode 100644 index 00000000..e68af907 --- /dev/null +++ b/rootston/xwayland.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "rootston/desktop.h" +#include "rootston/server.h" + +static void handle_destroy(struct wl_listener *listener, void *data) { + struct roots_wl_shell_surface *roots_surface = + wl_container_of(listener, roots_surface, destroy); + wl_list_remove(&roots_surface->destroy.link); + view_destroy(roots_surface->view); + free(roots_surface); +} + +void handle_xwayland_surface(struct wl_listener *listener, void *data) { + struct roots_desktop *desktop = + wl_container_of(listener, desktop, xwayland_surface); + + struct wlr_x11_window *surface = data; + // TODO: get and log title, class, etc + wlr_log(L_DEBUG, "new xwayland surface"); + + struct roots_x11_surface *roots_surface = + calloc(1, sizeof(struct roots_wl_shell_surface)); + wl_list_init(&roots_surface->destroy.link); + roots_surface->destroy.notify = handle_destroy; + wl_signal_add(&surface->events.destroy, &roots_surface->destroy); + + struct roots_view *view = calloc(1, sizeof(struct roots_view)); + view->type = ROOTS_XWAYLAND_VIEW; + view->x = view->y = 200; + view->x11_window = surface; + view->roots_x11_surface = roots_surface; + view->wlr_surface = surface->surface; + view->desktop = desktop; + roots_surface->view = view; + wl_list_insert(&desktop->views, &view->link); +} diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index 057f4ce3..dd90b38f 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -54,6 +54,7 @@ void wlr_keyboard_led_update(struct wlr_keyboard *kb, uint32_t leds) { void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap) { + wlr_log(L_DEBUG, "Keymap set"); kb->keymap = keymap; assert(kb->xkb_state = xkb_state_new(kb->keymap)); const char *led_names[3] = { diff --git a/types/wlr_seat.c b/types/wlr_seat.c index aaff6005..e473064a 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -377,6 +377,7 @@ void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time, } static void keyboard_key_notify(struct wl_listener *listener, void *data) { + wlr_log(L_DEBUG, "Updating keyboard"); struct wlr_seat_keyboard *seat_kb = wl_container_of( listener, seat_kb, key); struct wlr_seat *seat = seat_kb->seat; diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index bed2e00e..6a521393 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -194,6 +194,7 @@ static bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland, wlr_xwayland->wl_fd[0] = wlr_xwayland->wl_fd[1] = -1; wlr_xwayland->wm_fd[0] = wlr_xwayland->wm_fd[1] = -1; wl_list_init(&wlr_xwayland->displayable_windows); + wl_signal_init(&wlr_xwayland->events.new_surface); wlr_xwayland->display = open_display_sockets(wlr_xwayland->x_fd); if (wlr_xwayland->display < 0) { diff --git a/xwayland/xwm.c b/xwayland/xwm.c index be8fe123..88be0d99 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -16,6 +16,7 @@ static struct wlr_x11_window *lookup_window(struct wl_list *list, xcb_window_t w } return NULL; } + static struct wlr_x11_window *lookup_window_any(struct wlr_xwm *xwm, xcb_window_t window_id) { struct wlr_x11_window *window; if ((window = lookup_window(&xwm->xwayland->displayable_windows, window_id)) || @@ -43,10 +44,12 @@ static struct wlr_x11_window *wlr_x11_window_create(struct wlr_xwm *xwm, window->height = height; window->override_redirect = override_redirect; wl_list_insert(&xwm->new_windows, &window->link); + wl_signal_init(&window->events.destroy); return window; } static void wlr_x11_window_destroy(struct wlr_x11_window *window) { + wl_signal_emit(&window->events.destroy, window); wl_list_remove(&window->link); free(window); } @@ -69,10 +72,11 @@ static bool xcb_call(struct wlr_xwm *xwm, const char *func, uint32_t line, static void map_shell_surface(struct wlr_xwm *xwm, struct wlr_x11_window *window, struct wlr_surface *surface) { // get xcb geometry for depth = alpha channel - window->surface = surface->resource; + window->surface = surface; wl_list_remove(&window->link); wl_list_insert(&xwm->xwayland->displayable_windows, &window->link); + wl_signal_emit(&xwm->xwayland->events.new_surface, window); } /* xcb event handlers */ -- cgit v1.2.3 From e3af7d508fce607c56ca7d2e3afde4dd4eb9587a Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 28 Sep 2017 17:44:07 -0400 Subject: Remove example compositor --- examples/compositor.c | 668 --------------------------------------- examples/meson.build | 7 - examples/wlr-example.ini.example | 57 ---- 3 files changed, 732 deletions(-) delete mode 100644 examples/compositor.c delete mode 100644 examples/wlr-example.ini.example (limited to 'examples/compositor.c') diff --git a/examples/compositor.c b/examples/compositor.c deleted file mode 100644 index 7d6efdb6..00000000 --- a/examples/compositor.c +++ /dev/null @@ -1,668 +0,0 @@ -#define _POSIX_C_SOURCE 199309L -#include -#include -#include -#include -#include -#include -#include -#include -// TODO: BSD et al -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "wlr/types/wlr_compositor.h" -#include -#include -#include -#include -#include -#include "config.h" -#include "shared.h" -#include - -struct sample_state; - -struct example_xdg_surface_v6 { - struct wlr_xdg_surface_v6 *surface; - struct sample_state *sample; - - // position of the wlr_surface in the layout - struct { - int lx; - int ly; - } position; - - struct wl_listener destroy_listener; - struct wl_listener ping_timeout_listener; - struct wl_listener request_minimize_listener; - struct wl_listener request_move_listener; - struct wl_listener request_resize_listener; - struct wl_listener request_show_window_menu_listener; -}; - -struct input_event_cache { - uint32_t serial; - struct wlr_cursor *cursor; - struct wlr_input_device *device; -}; - -struct motion_context { - struct example_xdg_surface_v6 *surface; - int off_x, off_y; -}; - -struct sample_state { - struct wlr_renderer *renderer; - struct compositor_state *compositor; - struct wlr_compositor *wlr_compositor; - struct wlr_wl_shell *wl_shell; - struct wlr_seat *wl_seat; - struct wlr_xdg_shell_v6 *xdg_shell; - struct wlr_data_device_manager *data_device_manager; - struct wl_resource *focus; - struct wlr_xwayland *xwayland; - struct wlr_gamma_control_manager *gamma_control_manager; - bool mod_down; - - struct motion_context motion_context; - - struct example_config *config; - struct wlr_output_layout *layout; - struct wlr_cursor *cursor; - struct wlr_xcursor *xcursor; - - // Ring buffer - int input_cache_idx; - struct input_event_cache input_cache[16]; - - struct wl_listener cursor_motion; - struct wl_listener cursor_motion_absolute; - struct wl_listener cursor_button; - struct wl_listener cursor_axis; - - struct wl_listener tool_axis; - struct wl_listener tool_tip; - struct wl_listener tool_button; - - struct wl_listener new_xdg_surface_v6; - - struct wlr_xdg_surface_v6 *focused_surface; -}; - -static void example_set_focused_surface(struct sample_state *sample, - struct wlr_xdg_surface_v6 *surface) { - if (sample->focused_surface == surface) { - return; - } - - // set activated state of the xdg surfaces - struct wlr_xdg_surface_v6 *xdg_surface; - struct wlr_xdg_client_v6 *xdg_client; - wl_list_for_each(xdg_client, &sample->xdg_shell->clients, link) { - wl_list_for_each(xdg_surface, &xdg_client->surfaces, link) { - if (!xdg_surface->configured || - xdg_surface->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { - continue; - } - wlr_xdg_toplevel_v6_set_activated(xdg_surface, - xdg_surface == surface); - } - } - - if (surface) { - wlr_seat_keyboard_enter(sample->wl_seat, surface->surface); - } else { - wlr_seat_keyboard_clear_focus(sample->wl_seat); - } - - sample->focused_surface = surface; -} - -/* - * Convert timespec to milliseconds - */ -static inline int64_t timespec_to_msec(const struct timespec *a) { - return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; -} - -static void output_frame_handle_surface(struct sample_state *sample, - struct wlr_output *wlr_output, struct timespec *ts, - struct wl_resource *_res, int ox, int oy) { - struct wlr_surface *surface = wl_resource_get_user_data(_res); - float matrix[16]; - float transform[16]; - wlr_surface_flush_damage(surface); - if (surface->texture->valid) { - wlr_matrix_translate(&transform, ox, oy, 0); - wlr_surface_get_matrix(surface, &matrix, - &wlr_output->transform_matrix, &transform); - wlr_render_with_matrix(sample->renderer, surface->texture, &matrix); - - struct wlr_frame_callback *cb, *cnext; - wl_list_for_each_safe(cb, cnext, &surface->frame_callback_list, link) { - wl_callback_send_done(cb->resource, timespec_to_msec(ts)); - wl_resource_destroy(cb->resource); - } - } -} - -static void handle_xdg_surface_v6_ping_timeout(struct wl_listener *listener, - void *data) { - struct wlr_xdg_surface_v6 *surface = data; - wlr_log(L_DEBUG, "got ping timeout for surface: %s", surface->title); -} - -static void handle_xdg_surface_v6_destroy(struct wl_listener *listener, - void *data) { - struct example_xdg_surface_v6 *example_surface = - wl_container_of(listener, example_surface, destroy_listener); - wl_list_remove(&example_surface->destroy_listener.link); - wl_list_remove(&example_surface->ping_timeout_listener.link); - wl_list_remove(&example_surface->request_move_listener.link); - wl_list_remove(&example_surface->request_resize_listener.link); - wl_list_remove(&example_surface->request_show_window_menu_listener.link); - wl_list_remove(&example_surface->request_minimize_listener.link); - free(example_surface); -} - -static void handle_xdg_surface_v6_request_move(struct wl_listener *listener, - void *data) { - struct example_xdg_surface_v6 *esurface = - wl_container_of(listener, esurface, request_move_listener); - struct wlr_xdg_toplevel_v6_move_event *e = data; - struct sample_state *sample = esurface->sample; - struct input_event_cache *event = NULL; - for (size_t i = 0; - i < sizeof(sample->input_cache) / sizeof(sample->input_cache[0]); - ++i) { - if (sample->input_cache[i].cursor - && sample->input_cache[i].serial == e->serial) { - event = &sample->input_cache[i]; - break; - } - } - if (!event || sample->motion_context.surface) { - return; - } - sample->motion_context.surface = esurface; - sample->motion_context.off_x = sample->cursor->x - esurface->position.lx; - sample->motion_context.off_y = sample->cursor->y - esurface->position.ly; - wlr_seat_pointer_clear_focus(sample->wl_seat); -} - -static void handle_xdg_surface_v6_request_resize(struct wl_listener *listener, - void *data) { - struct example_xdg_surface_v6 *example_surface = - wl_container_of(listener, example_surface, request_resize_listener); - struct wlr_xdg_toplevel_v6_resize_event *e = data; - wlr_log(L_DEBUG, "TODO: surface requested resize: %s", e->surface->title); -} - -static void handle_xdg_surface_v6_request_show_window_menu( - struct wl_listener *listener, void *data) { - struct example_xdg_surface_v6 *example_surface = - wl_container_of(listener, example_surface, - request_show_window_menu_listener); - struct wlr_xdg_toplevel_v6_show_window_menu_event *e = data; - wlr_log(L_DEBUG, "TODO: surface requested to show window menu: %s", - e->surface->title); -} - -static void handle_xdg_surface_v6_request_minimize( - struct wl_listener *listener, void *data) { - struct example_xdg_surface_v6 *example_surface = - wl_container_of(listener, example_surface, request_minimize_listener); - wlr_log(L_DEBUG, "TODO: surface requested to be minimized: %s", - example_surface->surface->title); -} - -static void handle_new_xdg_surface_v6(struct wl_listener *listener, - void *data) { - struct sample_state *sample_state = - wl_container_of(listener, sample_state, new_xdg_surface_v6); - struct wlr_xdg_surface_v6 *surface = data; - wlr_log(L_DEBUG, "new xdg surface: title=%s, app_id=%s", - surface->title, surface->app_id); - - wlr_xdg_surface_v6_ping(surface); - - struct example_xdg_surface_v6 *esurface = - calloc(1, sizeof(struct example_xdg_surface_v6)); - if (esurface == NULL) { - return; - } - - esurface->sample = sample_state; - esurface->surface = surface; - // TODO sensible default position - esurface->position.lx = 300; - esurface->position.ly = 300; - surface->data = esurface; - - wl_signal_add(&surface->events.destroy, &esurface->destroy_listener); - esurface->destroy_listener.notify = handle_xdg_surface_v6_destroy; - - wl_signal_add(&surface->events.ping_timeout, - &esurface->ping_timeout_listener); - esurface->ping_timeout_listener.notify = handle_xdg_surface_v6_ping_timeout; - - wl_signal_add(&surface->events.request_move, - &esurface->request_move_listener); - esurface->request_move_listener.notify = handle_xdg_surface_v6_request_move; - - wl_signal_add(&surface->events.request_resize, - &esurface->request_resize_listener); - esurface->request_resize_listener.notify = - handle_xdg_surface_v6_request_resize; - - wl_signal_add(&surface->events.request_show_window_menu, - &esurface->request_show_window_menu_listener); - esurface->request_show_window_menu_listener.notify = - handle_xdg_surface_v6_request_show_window_menu; - - wl_signal_add(&surface->events.request_minimize, - &esurface->request_minimize_listener); - esurface->request_minimize_listener.notify = - handle_xdg_surface_v6_request_minimize; -} - -static void handle_output_frame(struct output_state *output, - struct timespec *ts) { - struct compositor_state *state = output->compositor; - struct sample_state *sample = state->data; - struct wlr_output *wlr_output = output->output; - - wlr_output_make_current(wlr_output); - wlr_renderer_begin(sample->renderer, wlr_output); - - struct wlr_wl_shell_surface *wl_shell_surface; - wl_list_for_each(wl_shell_surface, &sample->wl_shell->surfaces, link) { - output_frame_handle_surface(sample, wlr_output, ts, - wl_shell_surface->surface->resource, 200, 200); - } - struct wlr_xdg_surface_v6 *xdg_surface; - struct wlr_xdg_client_v6 *xdg_client; - wl_list_for_each(xdg_client, &sample->xdg_shell->clients, link) { - wl_list_for_each(xdg_surface, &xdg_client->surfaces, link) { - if (!xdg_surface->configured) { - continue; - } - - struct example_xdg_surface_v6 *esurface = xdg_surface->data; - assert(esurface); - - int width = xdg_surface->surface->current.buffer_width; - int height = xdg_surface->surface->current.buffer_height; - - bool intersects_output = wlr_output_layout_intersects( - sample->layout, wlr_output, - esurface->position.lx, esurface->position.ly, - esurface->position.lx + width, esurface->position.ly + height); - - if (intersects_output) { - double ox = esurface->position.lx, oy = esurface->position.ly; - wlr_output_layout_output_coords(sample->layout, wlr_output, - &ox, &oy); - output_frame_handle_surface(sample, wlr_output, ts, - xdg_surface->surface->resource, ox, oy); - } - } - } - struct wlr_x11_window *x11_window; - wl_list_for_each(x11_window, &sample->xwayland->displayable_windows, link) { - output_frame_handle_surface(sample, wlr_output, ts, - x11_window->surface->resource, 200, 200); - } - - wlr_renderer_end(sample->renderer); - wlr_output_swap_buffers(wlr_output); -} - -static void handle_keyboard_key(struct keyboard_state *keyboard, - uint32_t keycode, xkb_keysym_t sym, enum wlr_key_state key_state, - uint64_t time_usec) { - struct compositor_state *state = keyboard->compositor; - struct sample_state *sample = state->data; - if (sym == XKB_KEY_Super_L || sym == XKB_KEY_Super_R) { - sample->mod_down = key_state == WLR_KEY_PRESSED; - } -} - -static struct wlr_xdg_surface_v6 *example_xdg_surface_at( - struct sample_state *sample, int lx, int ly) { - struct wlr_xdg_surface_v6 *xdg_surface; - struct wlr_xdg_client_v6 *xdg_client; - wl_list_for_each(xdg_client, &sample->xdg_shell->clients, link) { - wl_list_for_each(xdg_surface, &xdg_client->surfaces, link) { - if (!xdg_surface->configured) { - continue; - } - - struct example_xdg_surface_v6 *esurface = xdg_surface->data; - - double window_x = esurface->position.lx + xdg_surface->geometry->x; - double window_y = esurface->position.ly + xdg_surface->geometry->y; - - if (sample->cursor->x >= window_x && - sample->cursor->y >= window_y && - sample->cursor->x <= window_x + - xdg_surface->geometry->width && - sample->cursor->y <= window_y + - xdg_surface->geometry->height) { - return xdg_surface; - } - } - } - - return NULL; -} - -static void update_pointer_position(struct sample_state *sample, uint32_t time) { - if (sample->motion_context.surface) { - struct example_xdg_surface_v6 *surface; - surface = sample->motion_context.surface; - surface->position.lx = sample->cursor->x - sample->motion_context.off_x; - surface->position.ly = sample->cursor->y - sample->motion_context.off_y; - return; - } - - struct wlr_xdg_surface_v6 *surface = example_xdg_surface_at(sample, - sample->cursor->x, sample->cursor->y); - - if (surface) { - struct example_xdg_surface_v6 *esurface = surface->data; - - double sx = sample->cursor->x - esurface->position.lx; - double sy = sample->cursor->y - esurface->position.ly; - - // TODO z-order - wlr_seat_pointer_enter(sample->wl_seat, surface->surface, sx, sy); - wlr_seat_pointer_send_motion(sample->wl_seat, time, sx, sy); - } else { - wlr_seat_pointer_clear_focus(sample->wl_seat); - } -} - -static void handle_cursor_motion(struct wl_listener *listener, void *data) { - struct sample_state *sample = - wl_container_of(listener, sample, cursor_motion); - struct wlr_event_pointer_motion *event = data; - - wlr_cursor_move(sample->cursor, event->device, event->delta_x, - event->delta_y); - - update_pointer_position(sample, (uint32_t)event->time_usec); -} - -static void handle_cursor_motion_absolute(struct wl_listener *listener, - void *data) { - struct sample_state *sample = - wl_container_of(listener, sample, cursor_motion_absolute); - struct wlr_event_pointer_motion_absolute *event = data; - - wlr_cursor_warp_absolute(sample->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); - - update_pointer_position(sample, (uint32_t)event->time_usec); -} - -static void handle_cursor_axis(struct wl_listener *listener, void *data) { - struct sample_state *sample = - wl_container_of(listener, sample, cursor_axis); - struct wlr_event_pointer_axis *event = data; - wlr_seat_pointer_send_axis(sample->wl_seat, event->time_sec, - event->orientation, event->delta); -} - -static void handle_cursor_button(struct wl_listener *listener, void *data) { - struct sample_state *sample = - wl_container_of(listener, sample, cursor_button); - struct wlr_event_pointer_button *event = data; - - struct wlr_xdg_surface_v6 *surface = - example_xdg_surface_at(sample, sample->cursor->x, sample->cursor->y); - - uint32_t serial = wlr_seat_pointer_send_button(sample->wl_seat, - (uint32_t)event->time_usec, event->button, event->state); - - int i; - switch (event->state) { - case WLR_BUTTON_RELEASED: - if (sample->motion_context.surface) { - sample->motion_context.surface = NULL; - } - break; - case WLR_BUTTON_PRESSED: - i = sample->input_cache_idx; - sample->input_cache[i].serial = serial; - sample->input_cache[i].cursor = sample->cursor; - sample->input_cache[i].device = event->device; - sample->input_cache_idx = (i + 1) - % (sizeof(sample->input_cache) / sizeof(sample->input_cache[0])); - example_set_focused_surface(sample, surface); - wlr_log(L_DEBUG, "Stored event %d at %d", serial, i); - if (sample->mod_down && event->button == BTN_LEFT) { - struct example_xdg_surface_v6 *esurface = surface->data; - sample->motion_context.surface = esurface; - sample->motion_context.off_x = sample->cursor->x - esurface->position.lx; - sample->motion_context.off_y = sample->cursor->y - esurface->position.ly; - wlr_seat_pointer_clear_focus(sample->wl_seat); - } - break; - } -} - -static void handle_tool_axis(struct wl_listener *listener, void *data) { - struct sample_state *sample = - wl_container_of(listener, sample, tool_axis); - struct wlr_event_tablet_tool_axis *event = data; - if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && - (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { - wlr_cursor_warp_absolute(sample->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); - update_pointer_position(sample, (uint32_t)event->time_usec); - } -} - -static void handle_tool_tip(struct wl_listener *listener, void *data) { - struct sample_state *sample = - wl_container_of(listener, sample, tool_tip); - struct wlr_event_tablet_tool_tip *event = data; - - struct wlr_xdg_surface_v6 *surface = - example_xdg_surface_at(sample, sample->cursor->x, sample->cursor->y); - example_set_focused_surface(sample, surface); - - wlr_seat_pointer_send_button(sample->wl_seat, (uint32_t)event->time_usec, - BTN_LEFT, event->state); -} - -static void handle_input_add(struct compositor_state *state, - struct wlr_input_device *device) { - struct sample_state *sample = state->data; - - if (device->type == WLR_INPUT_DEVICE_POINTER || - device->type == WLR_INPUT_DEVICE_TOUCH || - device->type == WLR_INPUT_DEVICE_TABLET_TOOL) { - wlr_cursor_attach_input_device(sample->cursor, device); - example_config_configure_cursor(sample->config, sample->cursor, - sample->compositor); - } - - if (device->type == WLR_INPUT_DEVICE_KEYBOARD) { - struct xkb_rule_names rules; - memset(&rules, 0, sizeof(rules)); - rules.rules = getenv("XKB_DEFAULT_RULES"); - rules.model = getenv("XKB_DEFAULT_MODEL"); - rules.layout = getenv("XKB_DEFAULT_LAYOUT"); - rules.variant = getenv("XKB_DEFAULT_VARIANT"); - rules.options = getenv("XKB_DEFAULT_OPTIONS"); - struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - if (!context) { - wlr_log(L_ERROR, "Failed to create XKB context"); - exit(1); - } - wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names( - context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); - xkb_context_unref(context); - wlr_seat_attach_keyboard(sample->wl_seat, device); - } -} - -static void handle_output_add(struct output_state *ostate) { - struct sample_state *sample = ostate->compositor->data; - struct wlr_output *wlr_output = ostate->output; - struct wlr_xcursor_image *image = sample->xcursor->images[0]; - - struct output_config *o_config = - example_config_get_output(sample->config, ostate->output); - - if (o_config) { - wlr_output_transform(ostate->output, o_config->transform); - wlr_output_layout_add(sample->layout, ostate->output, o_config->x, - o_config->y); - } else { - wlr_output_layout_add_auto(sample->layout, ostate->output); - } - - example_config_configure_cursor(sample->config, sample->cursor, - sample->compositor); - - // TODO the cursor must be set depending on which surface it is displayed - // over which should happen in the compositor. - if (!wlr_output_set_cursor(wlr_output, image->buffer, - image->width, image->width, image->height)) { - wlr_log(L_DEBUG, "Failed to set hardware cursor"); - return; - } - - wlr_cursor_warp(sample->cursor, NULL, sample->cursor->x, sample->cursor->y); -} - -static void handle_output_remove(struct output_state *ostate) { - struct sample_state *sample = ostate->compositor->data; - - wlr_output_layout_remove(sample->layout, ostate->output); - - example_config_configure_cursor(sample->config, sample->cursor, - sample->compositor); -} - -int main(int argc, char *argv[]) { - struct sample_state state = { 0 }; - struct compositor_state compositor = { 0, - .data = &state, - .output_frame_cb = handle_output_frame, - }; - - compositor.input_add_cb = handle_input_add; - compositor.output_add_cb = handle_output_add; - compositor.output_remove_cb = handle_output_remove; - - state.compositor = &compositor; - state.config = parse_args(argc, argv); - state.cursor = wlr_cursor_create(); - state.layout = wlr_output_layout_create(); - wlr_cursor_attach_output_layout(state.cursor, state.layout); - wlr_cursor_map_to_region(state.cursor, state.config->cursor.mapped_box); - - struct wlr_xcursor_theme *theme = wlr_xcursor_theme_load("default", 16); - if (!theme) { - wlr_log(L_ERROR, "Failed to load cursor theme"); - return 1; - } - state.xcursor = wlr_xcursor_theme_get_cursor(theme, "left_ptr"); - if (!state.xcursor) { - wlr_log(L_ERROR, "Failed to load left_ptr cursor"); - return 1; - } - - wlr_cursor_set_xcursor(state.cursor, state.xcursor); - - // pointer events - wl_signal_add(&state.cursor->events.motion, &state.cursor_motion); - state.cursor_motion.notify = handle_cursor_motion; - - wl_signal_add(&state.cursor->events.motion_absolute, - &state.cursor_motion_absolute); - state.cursor_motion_absolute.notify = handle_cursor_motion_absolute; - - wl_signal_add(&state.cursor->events.button, &state.cursor_button); - state.cursor_button.notify = handle_cursor_button; - - wl_signal_add(&state.cursor->events.axis, &state.cursor_axis); - state.cursor_axis.notify = handle_cursor_axis; - - wl_signal_add(&state.cursor->events.tablet_tool_axis, &state.tool_axis); - state.tool_axis.notify = handle_tool_axis; - - wl_signal_add(&state.cursor->events.tablet_tool_tip, &state.tool_tip); - state.tool_tip.notify = handle_tool_tip; - - compositor_init(&compositor); - - state.renderer = wlr_gles2_renderer_create(compositor.backend); - if (!state.renderer) { - wlr_log(L_ERROR, "Could not start compositor, OOM"); - exit(EXIT_FAILURE); - } - wl_display_init_shm(compositor.display); - state.wlr_compositor = - wlr_compositor_create(compositor.display, state.renderer); - state.wl_shell = wlr_wl_shell_create(compositor.display); - state.xdg_shell = wlr_xdg_shell_v6_create(compositor.display); - - // shell events - wl_signal_add(&state.xdg_shell->events.new_surface, - &state.new_xdg_surface_v6); - state.new_xdg_surface_v6.notify = handle_new_xdg_surface_v6; - - - state.data_device_manager = - wlr_data_device_manager_create(compositor.display); - - state.gamma_control_manager = - wlr_gamma_control_manager_create(compositor.display); - - state.wl_seat = wlr_seat_create(compositor.display, "seat0"); - assert(state.wl_seat); - wlr_seat_set_capabilities(state.wl_seat, WL_SEAT_CAPABILITY_KEYBOARD - | WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); - - state.xwayland = wlr_xwayland_create(compositor.display, - state.wlr_compositor); - - compositor.keyboard_key_cb = handle_keyboard_key; - - if (!wlr_backend_start(compositor.backend)) { - wlr_log(L_ERROR, "Failed to start backend"); - wlr_backend_destroy(compositor.backend); - exit(1); - } - - wl_display_run(compositor.display); - - wl_list_remove(&state.new_xdg_surface_v6.link); - - wlr_xwayland_destroy(state.xwayland); - wlr_seat_destroy(state.wl_seat); - wlr_gamma_control_manager_destroy(state.gamma_control_manager); - wlr_data_device_manager_destroy(state.data_device_manager); - wlr_xdg_shell_v6_destroy(state.xdg_shell); - wlr_wl_shell_destroy(state.wl_shell); - wlr_compositor_destroy(state.wlr_compositor); - wlr_renderer_destroy(state.renderer); - compositor_fini(&compositor); -} diff --git a/examples/meson.build b/examples/meson.build index 5d3ff52a..6ec40843 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -22,10 +22,3 @@ executable( dependencies: wlroots, link_with: lib_shared, ) - -executable( - 'compositor', - 'compositor.c', - dependencies: wlroots, - link_with: lib_shared, -) diff --git a/examples/wlr-example.ini.example b/examples/wlr-example.ini.example deleted file mode 100644 index 1698e0c6..00000000 --- a/examples/wlr-example.ini.example +++ /dev/null @@ -1,57 +0,0 @@ -# Configuration -# ------------- -# Some examples will read a configuration file. Not all examples will use all of -# the configuration options. The configuration file will be loaded from -# `wlr-example.ini` from the current directory or the path can be specified by the -# `-C` option given on the command line. -# -# Output configuration -# ~~~~~~~~~~~~~~~~~~~~ -# Each output is specified in a section named [output:{NAME}] where NAME is the -# drm name for this output. -# -# Value "x" specifies the x-coordinate in the output layout. -# -# Value "y" specifies the y-coordinate in the output layout. -# -# Value "rotate" specifies output rotation and can be 90, 180, 270, flipped, -# flipped-90, flipped-180, or flipped-270 -[output:HDMI-A-1] -x=3000 -y=0 -rotate=90 - -[output:DP-1] -x=0 -y=0 -rotate=270 - -[output:DVI-D-1] -x=1080 -y=232 - -# Cursor Configuration -# ~~~~~~~~~~~~~~~~~~~~ -# Value "map-to-output" specifies the output to which the cursor is -# constrained. -# -# Value "geometry" specifies the geometry (widthxheight+x+y) to which the cursor -# is constrained. -[cursor] -map-to-output=HDMI-A-1 -geometry=500x700+50+50 - -# Device Configuration -# ~~~~~~~~~~~~~~~~~~~~ -# Each device is specified in a section named [device:{NAME}] where NAME is the -# name given to this device. See a log file for device names. -# -# Value "map-to-output" specifies the output to which the device is constrained. -# -# Value "geometry" specifies the geometry (widthxheight+x+y) to which the device -# is constrained. -[device:Razer Razer DeathAdder 2013] -map-to-output=DP-1 -geometry=500x700+50+50 - -# vim:filetype=dosini -- cgit v1.2.3