swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit 2a378d5c71866432aef636d04fda4663f3679a75
parent 33ee03b33880d44ff6830da7a1a8f5330cb1582c
Author: Michael Forney <mforney@mforney.org>
Date:   Fri, 13 Sep 2013 19:36:27 -0700

Move key handling stuff to keyboard.c and mouse handling stuff to pointer.c

Diffstat:
Mlibswc/compositor.c | 16++++++++--------
Mlibswc/keyboard.c | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlibswc/keyboard.h | 4++++
Mlibswc/pointer.c | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlibswc/pointer.h | 12++++++++++--
Mlibswc/seat.c | 197++-----------------------------------------------------------------------------
Mlibswc/seat.h | 6------
7 files changed, 235 insertions(+), 208 deletions(-)

diff --git a/libswc/compositor.c b/libswc/compositor.c @@ -159,7 +159,7 @@ static bool handle_key(struct swc_keyboard * keyboard, uint32_t time, { xkb_keysym_t keysym; - keysym = xkb_state_key_get_one_sym(seat->xkb.state, key + 8); + keysym = xkb_state_key_get_one_sym(keyboard->xkb.state, key + 8); wl_array_for_each(binding, &compositor->key_bindings) { @@ -167,18 +167,18 @@ static bool handle_key(struct swc_keyboard * keyboard, uint32_t time, { xkb_mod_mask_t mod_mask; uint32_t modifiers = 0; - mod_mask = xkb_state_serialize_mods(seat->xkb.state, + mod_mask = xkb_state_serialize_mods(keyboard->xkb.state, XKB_STATE_MODS_EFFECTIVE); - mod_mask = xkb_state_mod_mask_remove_consumed(seat->xkb.state, key + 8, + mod_mask = xkb_state_mod_mask_remove_consumed(keyboard->xkb.state, key + 8, mod_mask); - if (mod_mask & (1 << seat->xkb.indices.ctrl)) + if (mod_mask & (1 << keyboard->xkb.indices.ctrl)) modifiers |= SWC_MOD_CTRL; - if (mod_mask & (1 << seat->xkb.indices.alt)) + if (mod_mask & (1 << keyboard->xkb.indices.alt)) modifiers |= SWC_MOD_ALT; - if (mod_mask & (1 << seat->xkb.indices.super)) + if (mod_mask & (1 << keyboard->xkb.indices.super)) modifiers |= SWC_MOD_LOGO; - if (mod_mask & (1 << seat->xkb.indices.shift)) + if (mod_mask & (1 << keyboard->xkb.indices.shift)) modifiers |= SWC_MOD_SHIFT; if (binding->modifiers == SWC_MOD_ANY @@ -483,7 +483,7 @@ bool swc_compositor_initialize(struct swc_compositor * compositor, output->geometry.height); } - swc_seat_set_pointer_region(&compositor->seat, &pointer_region); + swc_pointer_set_region(&compositor->seat.pointer, &pointer_region); pixman_region32_fini(&pointer_region); pixman_region32_init(&compositor->damage); diff --git a/libswc/keyboard.c b/libswc/keyboard.c @@ -2,6 +2,7 @@ #include "util.h" #include <stdio.h> +#include <string.h> static void enter(struct swc_input_focus_handler * handler, struct wl_resource * resource, struct swc_surface * surface) @@ -36,6 +37,15 @@ static void leave(struct swc_input_focus_handler * handler, bool swc_keyboard_initialize(struct swc_keyboard * keyboard) { + if (!swc_xkb_initialize(&keyboard->xkb)) + { + printf("could not initialize XKB\n"); + goto error0; + } + + if (!swc_input_focus_initialize(&keyboard->focus, &keyboard->focus_handler)) + goto error1; + wl_array_init(&keyboard->keys); keyboard->focus_handler.enter = &enter; @@ -44,12 +54,18 @@ bool swc_keyboard_initialize(struct swc_keyboard * keyboard) swc_input_focus_initialize(&keyboard->focus, &keyboard->focus_handler); return true; + + error1: + swc_xkb_finish(&keyboard->xkb); + error0: + return false; } void swc_keyboard_finish(struct swc_keyboard * keyboard) { wl_array_release(&keyboard->keys); swc_input_focus_finish(&keyboard->focus); + swc_xkb_finish(&keyboard->xkb); } /** @@ -77,6 +93,100 @@ struct wl_resource * swc_keyboard_bind(struct swc_keyboard * keyboard, wl_resource_set_implementation(client_resource, NULL, keyboard, &unbind); swc_input_focus_add_resource(&keyboard->focus, client_resource); + /* Subtract one to remove terminating NULL character. */ + wl_keyboard_send_keymap(client_resource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, + keyboard->xkb.keymap.fd, + keyboard->xkb.keymap.size - 1); + return client_resource; } +void swc_keyboard_handle_key(struct swc_keyboard * keyboard, uint32_t time, + uint32_t key, uint32_t state) +{ + uint32_t * pressed_key; + uint32_t mods_depressed, mods_latched, mods_locked, mods_active, group; + struct wl_display * display; + uint32_t serial; + enum xkb_key_direction direction; + struct swc_xkb * xkb = &keyboard->xkb; + + if (keyboard->focus.resource) + { + struct wl_client * client + = wl_resource_get_client(keyboard->focus.resource); + display = wl_client_get_display(client); + } + + /* Update keyboard state state */ + wl_array_for_each(pressed_key, &keyboard->keys) + { + if (*pressed_key == key) + { + /* Ignore repeat events. */ + if (state == WL_KEYBOARD_KEY_STATE_PRESSED) + return; + else + { + /* Remove the key from the array */ + uint32_t bytes_to_copy = keyboard->keys.size + 1 + - (((void *) pressed_key) - keyboard->keys.data); + + if (bytes_to_copy > 0) + memmove(pressed_key, pressed_key + 1, bytes_to_copy); + + keyboard->keys.size -= sizeof key; + + break; + } + } + } + + if (state == WL_KEYBOARD_KEY_STATE_PRESSED) + { + pressed_key = wl_array_add(&keyboard->keys, sizeof key); + *pressed_key = key; + } + + /* Check if the key event is handled by the keyboard handler. */ + if ((!keyboard->handler || !keyboard->handler->key + || !keyboard->handler->key(keyboard, time, key, state)) + && keyboard->focus.resource) + { + serial = wl_display_next_serial(display); + wl_keyboard_send_key(keyboard->focus.resource, serial, time, + key, state); + } + + /* Update XKB state. Apparently the keycodes are offset by 8 in XKB. */ + direction = state == WL_KEYBOARD_KEY_STATE_PRESSED ? XKB_KEY_DOWN + : XKB_KEY_UP; + xkb_state_update_key(xkb->state, key + 8, direction); + + mods_depressed = xkb_state_serialize_mods(xkb->state, XKB_STATE_DEPRESSED); + mods_latched = xkb_state_serialize_mods(xkb->state, XKB_STATE_LATCHED); + mods_locked = xkb_state_serialize_mods(xkb->state, XKB_STATE_LOCKED); + mods_active = mods_depressed | mods_latched; + + group = xkb_state_serialize_layout(xkb->state, XKB_STATE_LAYOUT_EFFECTIVE); + + if (mods_depressed != keyboard->modifiers.mods_depressed + || mods_latched != keyboard->modifiers.mods_latched + || mods_locked != keyboard->modifiers.mods_locked + || group != keyboard->modifiers.group) + { + if (keyboard->focus.resource) + { + serial = wl_display_next_serial(display); + wl_keyboard_send_modifiers(keyboard->focus.resource, + serial, mods_depressed, mods_latched, + mods_locked, group); + } + } + + keyboard->modifiers.mods_depressed = mods_depressed; + keyboard->modifiers.mods_latched = mods_latched; + keyboard->modifiers.mods_locked = mods_locked; + keyboard->modifiers.group = group; +} + diff --git a/libswc/keyboard.h b/libswc/keyboard.h @@ -3,6 +3,7 @@ #include "surface.h" #include "input_focus.h" +#include "xkb.h" #include <wayland-server.h> @@ -24,6 +25,7 @@ struct swc_keyboard struct swc_keyboard_handler * handler; + struct swc_xkb xkb; struct wl_array keys; struct @@ -41,6 +43,8 @@ void swc_keyboard_set_focus(struct swc_keyboard * keyboard, struct swc_surface * surface); struct wl_resource * swc_keyboard_bind(struct swc_keyboard * keyboard, struct wl_client * client, uint32_t id); +void swc_keyboard_handle_key(struct swc_keyboard * keyboard, uint32_t time, + uint32_t key, uint32_t state); #endif diff --git a/libswc/pointer.c b/libswc/pointer.c @@ -3,6 +3,7 @@ #include "event.h" #include <stdio.h> +#include <assert.h> static void enter(struct swc_input_focus_handler * handler, struct wl_resource * resource, struct swc_surface * surface) @@ -63,6 +64,7 @@ bool swc_pointer_initialize(struct swc_pointer * pointer) pointer->cursor.destroy_listener.notify = &handle_cursor_surface_destroy; swc_input_focus_initialize(&pointer->focus, &pointer->focus_handler); + pixman_region32_init(&pointer->region); return true; } @@ -70,6 +72,7 @@ bool swc_pointer_initialize(struct swc_pointer * pointer) void swc_pointer_finish(struct swc_pointer * pointer) { swc_input_focus_finish(&pointer->focus); + pixman_region32_fini(&pointer->region); } /** @@ -81,6 +84,38 @@ void swc_pointer_set_focus(struct swc_pointer * pointer, swc_input_focus_set(&pointer->focus, surface); } +static void clip_position(struct swc_pointer * pointer, + wl_fixed_t fx, wl_fixed_t fy) +{ + int32_t x, y, last_x, last_y; + pixman_box32_t box; + + x = wl_fixed_to_int(fx); + y = wl_fixed_to_int(fy); + last_x = wl_fixed_to_int(pointer->x); + last_y = wl_fixed_to_int(pointer->y); + + if (!pixman_region32_contains_point(&pointer->region, x, y, NULL)) + { + assert(pixman_region32_contains_point(&pointer->region, + last_x, last_y, &box)); + + /* Do some clipping. */ + x = MAX(MIN(x, box.x2 - 1), box.x1); + y = MAX(MIN(y, box.y2 - 1), box.y1); + } + + pointer->x = wl_fixed_from_int(x); + pointer->y = wl_fixed_from_int(y); +} + +void swc_pointer_set_region(struct swc_pointer * pointer, + pixman_region32_t * region) +{ + pixman_region32_copy(&pointer->region, region); + clip_position(pointer, pointer->x, pointer->y); +} + static void set_cursor(struct wl_client * client, struct wl_resource * resource, uint32_t serial, struct wl_resource * surface_resource, @@ -141,3 +176,66 @@ struct wl_resource * swc_pointer_bind(struct swc_pointer * pointer, return client_resource; } +void swc_pointer_handle_button(struct swc_pointer * pointer, uint32_t time, + uint32_t button, uint32_t state) +{ + if ((!pointer->handler || !pointer->handler->button + || !pointer->handler->button(pointer, time, button, state)) + && pointer->focus.resource) + { + struct wl_client * client + = wl_resource_get_client(pointer->focus.resource); + struct wl_display * display = wl_client_get_display(client); + uint32_t serial = wl_display_next_serial(display); + + wl_pointer_send_button(pointer->focus.resource, serial, time, + button, state); + } +} + +void swc_pointer_handle_axis(struct swc_pointer * pointer, uint32_t time, + uint32_t axis, wl_fixed_t amount) +{ + if ((!pointer->handler || !pointer->handler->axis + || !pointer->handler->axis(pointer, time, axis, amount)) + && pointer->focus.resource) + { + struct wl_client * client + = wl_resource_get_client(pointer->focus.resource); + struct wl_display * display = wl_client_get_display(client); + + wl_pointer_send_axis(pointer->focus.resource, time, axis, amount); + } +} + +void swc_pointer_handle_relative_motion + (struct swc_pointer * pointer, uint32_t time, wl_fixed_t dx, wl_fixed_t dy) +{ + clip_position(pointer, pointer->x + dx, pointer->y + dy); + + if (pointer->handler && pointer->handler->focus) + pointer->handler->focus(pointer); + + if ((!pointer->handler || !pointer->handler->motion + || !pointer->handler->motion(pointer, time)) + && pointer->focus.resource) + { + wl_fixed_t surface_x, surface_y; + surface_x = pointer->x + - wl_fixed_from_int(pointer->focus.surface->geometry.x); + surface_y = pointer->y + - wl_fixed_from_int(pointer->focus.surface->geometry.y); + + wl_pointer_send_motion(pointer->focus.resource, time, + surface_x, surface_y); + + if (pointer->cursor.surface) + { + swc_surface_move + (pointer->cursor.surface, + wl_fixed_to_int(pointer->x) - pointer->cursor.hotspot_x, + wl_fixed_to_int(pointer->y) - pointer->cursor.hotspot_y); + } + } +} + diff --git a/libswc/pointer.h b/libswc/pointer.h @@ -5,6 +5,7 @@ #include "input_focus.h" #include <wayland-server.h> +#include <pixman.h> struct swc_pointer; @@ -45,16 +46,23 @@ struct swc_pointer struct swc_pointer_handler * handler; wl_fixed_t x, y; - - uint32_t button_count; + pixman_region32_t region; }; bool swc_pointer_initialize(struct swc_pointer * pointer); void swc_pointer_finish(struct swc_pointer * pointer); void swc_pointer_set_focus(struct swc_pointer * pointer, struct swc_surface * surface); +void swc_pointer_set_region(struct swc_pointer * pointer, + pixman_region32_t * region); struct wl_resource * swc_pointer_bind(struct swc_pointer * pointer, struct wl_client * client, uint32_t id); +void swc_pointer_handle_button(struct swc_pointer * pointer, uint32_t time, + uint32_t button, uint32_t state); +void swc_pointer_handle_axis(struct swc_pointer * pointer, uint32_t time, + uint32_t axis, wl_fixed_t amount); +void swc_pointer_handle_relative_motion + (struct swc_pointer * pointer, uint32_t time, wl_fixed_t dx, wl_fixed_t dy); #endif diff --git a/libswc/seat.c b/libswc/seat.c @@ -8,7 +8,6 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <assert.h> struct evdev_device_entry { @@ -18,193 +17,28 @@ struct evdev_device_entry struct wl_list link; }; -static void clip_position(struct swc_seat * seat, wl_fixed_t fx, wl_fixed_t fy) -{ - int32_t x, y, last_x, last_y; - pixman_box32_t box; - - x = wl_fixed_to_int(fx); - y = wl_fixed_to_int(fy); - last_x = wl_fixed_to_int(seat->pointer.x); - last_y = wl_fixed_to_int(seat->pointer.y); - - if (!pixman_region32_contains_point(&seat->pointer_region, x, y, NULL)) - { - assert(pixman_region32_contains_point(&seat->pointer_region, - last_x, last_y, &box)); - - /* Do some clipping. */ - x = MAX(MIN(x, box.x2 - 1), box.x1); - y = MAX(MIN(y, box.y2 - 1), box.y1); - } - - seat->pointer.x = wl_fixed_from_int(x); - seat->pointer.y = wl_fixed_from_int(y); -} - static void handle_key(struct swc_seat * seat, uint32_t time, uint32_t key, uint32_t state) { - uint32_t * pressed_key; - struct swc_keyboard * keyboard = &seat->keyboard; - struct swc_xkb * xkb = &seat->xkb; - struct wl_display * display; - uint32_t serial; - enum xkb_key_direction direction; - - if (keyboard->focus.resource) - { - struct wl_client * client - = wl_resource_get_client(keyboard->focus.resource); - display = wl_client_get_display(client); - } - - /* Update keyboard state state */ - wl_array_for_each(pressed_key, &keyboard->keys) - { - if (*pressed_key == key) - { - /* Ignore repeat evdev events. */ - if (state == WL_KEYBOARD_KEY_STATE_PRESSED) - return; - else - { - /* Remove the key from the array */ - uint32_t bytes_to_copy = keyboard->keys.size + 1 - - (((void *) pressed_key) - keyboard->keys.data); - - if (bytes_to_copy > 0) - memmove(pressed_key, pressed_key + 1, bytes_to_copy); - - keyboard->keys.size -= sizeof key; - - break; - } - } - } - - if (state == WL_KEYBOARD_KEY_STATE_PRESSED) - { - //keyboard->grab_key = key; - //keyboard->grab_time = time; - pressed_key = wl_array_add(&keyboard->keys, sizeof key); - *pressed_key = key; - } - - /* See if the key press is not handled by the compositor */ - if ((!keyboard->handler || !keyboard->handler->key - || !keyboard->handler->key(keyboard, time, key, state)) - && keyboard->focus.resource) - { - serial = wl_display_next_serial(display); - wl_keyboard_send_key(keyboard->focus.resource, serial, time, - key, state); - } - - /* Update XKB state. Apparently the keycodes are offset by 8 in XKB. */ - direction = state == WL_KEYBOARD_KEY_STATE_PRESSED ? XKB_KEY_DOWN - : XKB_KEY_UP; - xkb_state_update_key(xkb->state, key + 8, direction); - - { - uint32_t mods_depressed, mods_latched, mods_locked, mods_active; - uint32_t group; - - mods_depressed = xkb_state_serialize_mods(xkb->state, XKB_STATE_DEPRESSED); - mods_latched = xkb_state_serialize_mods(xkb->state, XKB_STATE_LATCHED); - mods_locked = xkb_state_serialize_mods(xkb->state, XKB_STATE_LOCKED); - mods_active = mods_depressed | mods_latched; - - group = xkb_state_serialize_layout(xkb->state, XKB_STATE_LAYOUT_EFFECTIVE); - - if (mods_depressed != keyboard->modifiers.mods_depressed - || mods_latched != keyboard->modifiers.mods_latched - || mods_locked != keyboard->modifiers.mods_locked - || group != keyboard->modifiers.group) - { - if (keyboard->focus.resource) - { - serial = wl_display_next_serial(display); - wl_keyboard_send_modifiers(keyboard->focus.resource, - serial, mods_depressed, mods_latched, - mods_locked, group); - } - } - - keyboard->modifiers.mods_depressed = mods_depressed; - keyboard->modifiers.mods_latched = mods_latched; - keyboard->modifiers.mods_locked = mods_locked; - keyboard->modifiers.group = group; - } + swc_keyboard_handle_key(&seat->keyboard, time, key, state); } static void handle_button(struct swc_seat * seat, uint32_t time, uint32_t button, uint32_t state) { - struct swc_pointer * pointer = &seat->pointer; - - if ((!pointer->handler || !pointer->handler->button - || !pointer->handler->button(pointer, time, button, state)) - && pointer->focus.resource) - { - struct wl_client * client - = wl_resource_get_client(pointer->focus.resource); - struct wl_display * display = wl_client_get_display(client); - uint32_t serial = wl_display_next_serial(display); - - wl_pointer_send_button(pointer->focus.resource, serial, time, - button, state); - } + swc_pointer_handle_button(&seat->pointer, time, button, state); } static void handle_relative_motion(struct swc_seat * seat, uint32_t time, wl_fixed_t dx, wl_fixed_t dy) { - struct swc_pointer * pointer = &seat->pointer; - - clip_position(seat, pointer->x + dx, pointer->y + dy); - - if (pointer->handler && pointer->handler->focus) - pointer->handler->focus(pointer); - - if ((!pointer->handler || !pointer->handler->motion - || !pointer->handler->motion(pointer, time)) - && pointer->focus.resource) - { - wl_fixed_t surface_x, surface_y; - surface_x = pointer->x - - wl_fixed_from_int(pointer->focus.surface->geometry.x); - surface_y = pointer->y - - wl_fixed_from_int(pointer->focus.surface->geometry.y); - - wl_pointer_send_motion(pointer->focus.resource, time, - surface_x, surface_y); - - if (pointer->cursor.surface) - { - swc_surface_move - (pointer->cursor.surface, - wl_fixed_to_int(pointer->x) - pointer->cursor.hotspot_x, - wl_fixed_to_int(pointer->y) - pointer->cursor.hotspot_y); - } - } + swc_pointer_handle_relative_motion(&seat->pointer, time, dx, dy); } static void handle_axis_motion(struct swc_seat * seat, uint32_t time, enum wl_pointer_axis axis, wl_fixed_t amount) { - struct swc_pointer * pointer = &seat->pointer; - - if ((!pointer->handler || !pointer->handler->axis - || !pointer->handler->axis(pointer, time, axis, amount)) - && pointer->focus.resource) - { - struct wl_client * client - = wl_resource_get_client(pointer->focus.resource); - struct wl_display * display = wl_client_get_display(client); - - wl_pointer_send_axis(pointer->focus.resource, time, axis, amount); - } + swc_pointer_handle_axis(&seat->pointer, time, axis, amount); } static void handle_evdev_event(struct wl_listener * listener, void * data) @@ -300,10 +134,6 @@ static void get_keyboard(struct wl_client * client, struct wl_resource * resourc struct swc_keyboard * keyboard = &seat->keyboard; client_resource = swc_keyboard_bind(keyboard, client, id); - - /* Subtract one to remove terminating NULL character. */ - wl_keyboard_send_keymap(client_resource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - seat->xkb.keymap.fd, seat->xkb.keymap.size - 1); } static void get_touch(struct wl_client * client, struct wl_resource * resource, @@ -396,16 +226,10 @@ bool swc_seat_initialize(struct swc_seat * seat, struct udev * udev, seat->keyboard_focus_listener.notify = &handle_keyboard_focus_event; seat->data_device_listener.notify = &handle_data_device_event; - if (!swc_xkb_initialize(&seat->xkb)) - { - printf("could not initialize XKB\n"); - goto error_name; - } - if (!swc_data_device_initialize(&seat->data_device)) { printf("could not initialize data device\n"); - goto error_xkb; + goto error_name; } if (!swc_keyboard_initialize(&seat->keyboard)) @@ -427,7 +251,6 @@ bool swc_seat_initialize(struct swc_seat * seat, struct udev * udev, wl_list_init(&seat->resources); wl_signal_init(&seat->destroy_signal); - pixman_region32_init(&seat->pointer_region); wl_list_init(&seat->devices); swc_seat_add_devices(seat, udev); @@ -437,8 +260,6 @@ bool swc_seat_initialize(struct swc_seat * seat, struct udev * udev, swc_keyboard_finish(&seat->keyboard); error_data_device: swc_data_device_finish(&seat->data_device); - error_xkb: - swc_xkb_finish(&seat->xkb); error_name: free(seat->name); error_base: @@ -453,7 +274,6 @@ void swc_seat_finish(struct swc_seat * seat) swc_pointer_finish(&seat->pointer); swc_keyboard_finish(&seat->keyboard); - swc_xkb_finish(&seat->xkb); free(seat->name); @@ -504,10 +324,3 @@ void swc_seat_add_devices(struct swc_seat * seat, struct udev * udev) udev_enumerate_unref(enumerate); } -void swc_seat_set_pointer_region(struct swc_seat * seat, - pixman_region32_t * region) -{ - pixman_region32_copy(&seat->pointer_region, region); - clip_position(seat, seat->pointer.x, seat->pointer.y); -} - diff --git a/libswc/seat.h b/libswc/seat.h @@ -10,15 +10,12 @@ #include <stdbool.h> #include <libudev.h> #include <wayland-server.h> -#include <pixman.h> struct swc_seat { char * name; uint32_t capabilities; - struct swc_xkb xkb; - struct wl_list resources; struct wl_signal destroy_signal; @@ -29,7 +26,6 @@ struct swc_seat struct wl_listener keyboard_focus_listener; struct swc_pointer pointer; - pixman_region32_t pointer_region; struct wl_list devices; }; @@ -46,8 +42,6 @@ void swc_seat_add_event_sources(struct swc_seat * seat, void swc_seat_add_devices(struct swc_seat * seat, struct udev * udev); -void swc_seat_set_pointer_region(struct swc_seat * seat, - pixman_region32_t * region); #endif