swc

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

commit 96ab570aa427013949bc6946c5640846d25336fb
parent 967d141663ca99d6f0cc3f88828e5006223da05e
Author: Michael Forney <mforney@mforney.org>
Date:   Fri, 21 Jun 2013 01:25:49 -0700

Separate out input focus related stuff to swc_input

Diffstat:
MMakefile.am | 1+
Ainput.c | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainput.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Mkeyboard.c | 99+++++++++++++++++++++++++++++++++++++++----------------------------------------
Mkeyboard.h | 13+++----------
Mpointer.c | 125++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mpointer.h | 13++++---------
Mseat.c | 32++++++++++----------------------
8 files changed, 297 insertions(+), 140 deletions(-)

diff --git a/Makefile.am b/Makefile.am @@ -13,6 +13,7 @@ libswc_la_SOURCES = \ surface.c surface.h \ region.c region.h \ renderer.c renderer.h \ + input.c input.h \ keyboard.c keyboard.h \ pointer.c pointer.h \ seat.c seat.h \ diff --git a/input.c b/input.c @@ -0,0 +1,108 @@ +#include "input.h" +#include "surface.h" + +#include <assert.h> + +#include "util.h" + +static inline void focus(struct swc_input * input, + struct swc_surface * surface, + struct wl_resource * resource) +{ + if (resource) + { + input->handler->enter(input->handler, resource, surface); + } + + input->focus.surface = surface; + input->focus.resource = resource; +} + +static inline void unfocus(struct swc_input * input) +{ + if (input->focus.resource) + { + input->handler->leave(input->handler, input->focus.resource, + input->focus.surface); + } +} + +bool swc_input_initialize(struct swc_input * input, + struct swc_input_handler * handler) +{ + input->focus.resource = NULL; + input->focus.surface = NULL; + input->handler = handler; + + wl_list_init(&input->resources); + + return true; +} + +void swc_input_finish(struct swc_input * input) +{ + /* XXX: Destroy resources? */ +} + +void swc_input_add_resource(struct swc_input * input, + struct wl_resource * resource) +{ + /* If this new input resource corresponds to our focus, set it as our + * focus. */ + if (input->focus.surface) + { + struct wl_client * client, * surface_client; + + client = wl_resource_get_client(resource); + surface_client = wl_resource_get_client(input->focus.surface->resource); + + if (client == surface_client) + { + unfocus(input); + focus(input, input->focus.surface, resource); + } + } + + wl_list_insert(&input->resources, wl_resource_get_link(resource)); +} + +void swc_input_remove_resource(struct swc_input * input, + struct wl_resource * resource) +{ + if (resource == input->focus.resource) + input->focus.resource = NULL; + + swc_remove_resource(resource); +} + +void swc_input_set_focus(struct swc_input * input, + struct swc_surface * surface) +{ + struct wl_client * client; + struct wl_display * display; + struct wl_resource * resource; + uint32_t serial; + + if (surface == input->focus.surface) + return; + + /* Unfocus previously focused surface. */ + unfocus(input); + + /* Focus new surface, if given. */ + if (surface) + { + client = wl_resource_get_client(surface->resource); + resource = wl_resource_find_for_client(&input->resources, client); + + focus(input, surface, resource); + } + else + { + input->focus.surface = NULL; + input->focus.resource = NULL; + } + + return; +} + diff --git a/input.h b/input.h @@ -0,0 +1,46 @@ +#ifndef SWC_INPUT_H +#define SWC_INPUT_H 1 + +#include <stdbool.h> +#include <wayland-server.h> + +struct swc_surface; + +struct swc_input_handler +{ + void (* enter)(struct swc_input_handler * handler, + struct wl_resource * resource, + struct swc_surface * surface); + void (* leave)(struct swc_input_handler * handler, + struct wl_resource * resource, + struct swc_surface * surface); +}; + +struct swc_input +{ + struct + { + struct wl_resource * resource; + struct swc_surface * surface; + } focus; + + struct swc_input_handler * handler; + struct wl_list resources; +}; + +bool swc_input_initialize(struct swc_input * input, + struct swc_input_handler * input_handler); + +void swc_input_finish(struct swc_input * input); + +void swc_input_add_resource(struct swc_input * input, + struct wl_resource * resource); + +void swc_input_remove_resource(struct swc_input * input, + struct wl_resource * resource); + +void swc_input_set_focus(struct swc_input * input, + struct swc_surface * surface); + +#endif + diff --git a/keyboard.c b/keyboard.c @@ -3,14 +3,45 @@ #include <stdio.h> +static void enter(struct swc_input_handler * handler, + struct wl_resource * resource, struct swc_surface * surface) +{ + struct swc_keyboard * keyboard; + struct wl_client * client; + struct wl_display * display; + uint32_t serial; + + keyboard = wl_container_of(handler, keyboard, input_handler); + client = wl_resource_get_client(resource); + display = wl_client_get_display(client); + serial = wl_display_next_serial(display); + + wl_keyboard_send_enter(resource, serial, surface->resource, + &keyboard->keys); +} + +static void leave(struct swc_input_handler * handler, + struct wl_resource * resource, struct swc_surface * surface) +{ + struct wl_client * client; + struct wl_display * display; + uint32_t serial; + + client = wl_resource_get_client(resource); + display = wl_client_get_display(client); + serial = wl_display_next_serial(display); + + wl_keyboard_send_leave(resource, serial, surface->resource); +} + bool swc_keyboard_initialize(struct swc_keyboard * keyboard) { - wl_list_init(&keyboard->resources); wl_array_init(&keyboard->keys); - //wl_signal_init(&keyboard->focus_signal); // ? - keyboard->focus.surface = NULL; - keyboard->focus.resource = NULL; + keyboard->input_handler.enter = &enter; + keyboard->input_handler.leave = &leave; + + swc_input_initialize(&keyboard->input, &keyboard->input_handler); return true; } @@ -18,53 +49,23 @@ bool swc_keyboard_initialize(struct swc_keyboard * keyboard) void swc_keyboard_finish(struct swc_keyboard * keyboard) { wl_array_release(&keyboard->keys); + swc_input_finish(&keyboard->input); } +/** + * Sets the focus of the keyboard to the specified surface. + */ void swc_keyboard_set_focus(struct swc_keyboard * keyboard, struct swc_surface * surface) { - struct wl_client * client; - struct wl_display * display; - struct wl_resource * resource; - uint32_t serial; + swc_input_set_focus(&keyboard->input, surface); +} - /* Unfocus previously focused surface. */ - if (keyboard->focus.resource && keyboard->focus.surface != surface) - { - client = wl_resource_get_client(keyboard->focus.surface->resource); - display = wl_client_get_display(client); - serial = wl_display_next_serial(display); - wl_keyboard_send_leave(keyboard->focus.resource, serial, - keyboard->focus.surface->resource); - } - - /* Focus new surface, if given. */ - if (surface) - { - client = wl_resource_get_client(surface->resource); - resource = wl_resource_find_for_client(&keyboard->resources, client); - - printf("keyboard: focusing surface: %p\n", surface); - - if (resource) - { - display = wl_client_get_display(client); - serial = wl_display_next_serial(display); - wl_keyboard_send_enter(resource, serial, surface->resource, - &keyboard->keys); - - keyboard->focus.resource = resource; - } - else - keyboard->focus.resource = NULL; - - keyboard->focus.surface = surface; - } - else - { - keyboard->focus.surface = NULL; - keyboard->focus.resource = NULL; - } +static void unbind(struct wl_resource * resource) +{ + struct swc_keyboard * keyboard = wl_resource_get_user_data(resource); + + swc_input_remove_resource(&keyboard->input, resource); } struct wl_resource * swc_keyboard_bind(struct swc_keyboard * keyboard, @@ -73,11 +74,9 @@ struct wl_resource * swc_keyboard_bind(struct swc_keyboard * keyboard, struct wl_resource * client_resource; client_resource = wl_client_add_object(client, &wl_keyboard_interface, - NULL, id, NULL); - wl_resource_set_destructor(client_resource, &swc_remove_resource); - wl_list_insert(&keyboard->resources, wl_resource_get_link(client_resource)); - - printf("keyboard: adding client %p, resource: %p\n", client, client_resource); + NULL, id, keyboard); + wl_resource_set_destructor(client_resource, &unbind); + swc_input_add_resource(&keyboard->input, client_resource); return client_resource; } diff --git a/keyboard.h b/keyboard.h @@ -2,6 +2,7 @@ #define SWC_KEYBOARD_H 1 #include "surface.h" +#include "input.h" #include <wayland-server.h> @@ -18,16 +19,8 @@ struct swc_keyboard_handler struct swc_keyboard { - struct wl_list resources; - - struct - { - struct swc_surface * surface; - struct wl_resource * resource; - } focus; - - //struct wl_listener focus_listener; - //struct wl_signal focus_signal; + struct swc_input input; + struct swc_input_handler input_handler; struct swc_keyboard_handler * handler; diff --git a/pointer.c b/pointer.c @@ -4,73 +4,94 @@ #include <stdio.h> +static void enter(struct swc_input_handler * handler, + struct wl_resource * resource, struct swc_surface * surface) +{ + struct swc_pointer * pointer; + struct wl_client * client; + struct wl_display * display; + uint32_t serial; + wl_fixed_t surface_x, surface_y; + + pointer = wl_container_of(handler, pointer, input_handler); + client = wl_resource_get_client(resource); + display = wl_client_get_display(client); + serial = wl_display_next_serial(display); + + surface_x = pointer->x - wl_fixed_from_int(surface->geometry.x); + surface_y = pointer->y - wl_fixed_from_int(surface->geometry.y); + + printf("-> pointer.enter: %p (%d, %d)\n", resource, surface_x, surface_y); + wl_pointer_send_enter(resource, serial, surface->resource, + surface_x, surface_y); +} + +static void leave(struct swc_input_handler * handler, + struct wl_resource * resource, struct swc_surface * surface) +{ + struct wl_client * client; + struct wl_display * display; + uint32_t serial; + + client = wl_resource_get_client(resource); + display = wl_client_get_display(client); + serial = wl_display_next_serial(display); + + printf("-> pointer.leave: %p\n", resource); + wl_pointer_send_leave(resource, serial, surface->resource); +} + +static void handle_focus_surface_destroy(struct wl_listener * listener, + void * data) +{ + struct swc_pointer * pointer; + + pointer = wl_container_of(listener, pointer, + focus_surface_destroy_listener); + + pointer->input.focus.surface = NULL; +} + bool swc_pointer_initialize(struct swc_pointer * pointer) { - wl_list_init(&pointer->resources); wl_signal_init(&pointer->event_signal); pointer->x = wl_fixed_from_int(0); pointer->y = wl_fixed_from_int(0); - pointer->focus.surface = NULL; - pointer->focus.resource = NULL; + pointer->input_handler.enter = &enter; + pointer->input_handler.leave = &leave; + + pointer->focus_surface_destroy_listener.notify + = &handle_focus_surface_destroy; + + swc_input_initialize(&pointer->input, &pointer->input_handler); return true; } void swc_pointer_finish(struct swc_pointer * pointer) { + swc_input_finish(&pointer->input); } +/** + * Sets the focus of the pointer to the specified surface. + */ void swc_pointer_set_focus(struct swc_pointer * pointer, struct swc_surface * surface) { - struct wl_client * client; - struct wl_display * display; - struct wl_resource * resource; - uint32_t serial; - - /* Unfocus previously focused surface. */ - if (pointer->focus.resource && pointer->focus.surface != surface) + if (surface != pointer->input.focus.surface) { - client = wl_resource_get_client(pointer->focus.surface->resource); - display = wl_client_get_display(client); - serial = wl_display_next_serial(display); - wl_pointer_send_leave(pointer->focus.resource, serial, - pointer->focus.surface->resource); - } - - /* Focus new surface, if given. */ - if (surface) - { - client = wl_resource_get_client(surface->resource); - resource = wl_resource_find_for_client(&pointer->resources, client); - - printf("pointer: focusing surface: %p\n", surface); - - if (resource) - { - uint32_t surface_x, surface_y; + if (pointer->input.focus.surface) + wl_list_remove(&pointer->focus_surface_destroy_listener.link); - surface_x = wl_fixed_to_int(pointer->x) - surface->geometry.x; - surface_y = wl_fixed_to_int(pointer->y) - surface->geometry.y; - - display = wl_client_get_display(client); - serial = wl_display_next_serial(display); - wl_pointer_send_enter(resource, serial, surface->resource, - wl_fixed_from_int(surface_x), - wl_fixed_from_int(surface_y)); - - pointer->focus.resource = resource; - } - - pointer->focus.surface = surface; - } - else - { - pointer->focus.surface = NULL; - pointer->focus.resource = NULL; + if (surface) + wl_resource_add_destroy_listener + (surface->resource, &pointer->focus_surface_destroy_listener); } + + swc_input_set_focus(&pointer->input, surface); } static void set_cursor(struct wl_client * client, @@ -98,6 +119,13 @@ struct wl_pointer_interface pointer_implementation = { .set_cursor = &set_cursor }; +static void unbind(struct wl_resource * resource) +{ + struct swc_pointer * pointer = wl_resource_get_user_data(resource); + + swc_input_remove_resource(&pointer->input, resource); +} + struct wl_resource * swc_pointer_bind(struct swc_pointer * pointer, struct wl_client * client, uint32_t id) { @@ -107,9 +135,8 @@ struct wl_resource * swc_pointer_bind(struct swc_pointer * pointer, client_resource = wl_client_add_object(client, &wl_pointer_interface, &pointer_implementation, id, pointer); - wl_resource_set_destructor(client_resource, &swc_remove_resource); - wl_list_insert(&pointer->resources, - wl_resource_get_user_data(client_resource)); + wl_resource_set_destructor(client_resource, &unbind); + swc_input_add_resource(&pointer->input, client_resource); return client_resource; } diff --git a/pointer.h b/pointer.h @@ -2,6 +2,7 @@ #define SWC_POINTER_H 1 #include "surface.h" +#include "input.h" #include <wayland-server.h> @@ -22,16 +23,10 @@ enum swc_pointer_event struct swc_pointer { - struct wl_list resources; + struct swc_input input; + struct swc_input_handler input_handler; + struct wl_listener focus_surface_destroy_listener; - struct - { - struct swc_surface * surface; - struct wl_resource * resource; - } focus; - - //uint32_t focus_serial; - //struct wl_signal focus_signal; struct wl_signal event_signal; struct diff --git a/seat.c b/seat.c @@ -27,11 +27,11 @@ static void handle_key(struct swc_seat * seat, uint32_t time, uint32_t key, uint32_t serial; enum xkb_key_direction direction; - if (keyboard->focus.resource) + if (keyboard->input.focus.resource) { - struct wl_client * focus_client - = wl_resource_get_client(keyboard->focus.resource); - display = wl_client_get_display(focus_client); + struct wl_client * client + = wl_resource_get_client(keyboard->input.focus.resource); + display = wl_client_get_display(client); } /* Update keyboard state state */ @@ -70,10 +70,11 @@ static void handle_key(struct swc_seat * seat, uint32_t time, uint32_t key, if (!(keyboard->handler && keyboard->handler->key) || !keyboard->handler->key(keyboard, time, key, state)) { - if (keyboard->focus.resource) + if (keyboard->input.focus.resource) { serial = wl_display_next_serial(display); - wl_keyboard_send_key(keyboard->focus.resource, serial, time, key, state); + wl_keyboard_send_key(keyboard->input.focus.resource, serial, time, + key, state); if (state == WL_KEYBOARD_KEY_STATE_PRESSED) printf("\t-> sent to client\n"); @@ -101,11 +102,11 @@ static void handle_key(struct swc_seat * seat, uint32_t time, uint32_t key, || mods_locked != keyboard->modifiers.mods_locked || group != keyboard->modifiers.group) { - if (keyboard->focus.resource) + if (keyboard->input.focus.resource) { serial = wl_display_next_serial(display); - wl_keyboard_send_modifiers(keyboard->focus.resource, serial, - mods_depressed, mods_latched, + wl_keyboard_send_modifiers(keyboard->input.focus.resource, + serial, mods_depressed, mods_latched, mods_locked, group); } } @@ -163,12 +164,6 @@ static void get_pointer(struct wl_client * client, struct wl_resource * resource struct swc_pointer * pointer = &seat->pointer; swc_pointer_bind(pointer, client, id); - - if (pointer->focus.surface - && wl_resource_get_client(pointer->focus.surface->resource) == client) - { - swc_pointer_set_focus(pointer, pointer->focus.surface); - } } static void get_keyboard(struct wl_client * client, struct wl_resource * resource, @@ -182,13 +177,6 @@ static void get_keyboard(struct wl_client * client, struct wl_resource * resourc wl_keyboard_send_keymap(client_resource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, seat->xkb.keymap.fd, seat->xkb.keymap.size); - - if (keyboard->focus.surface - && wl_resource_get_client(keyboard->focus.surface->resource) == client) - { - printf("focusing\n"); - swc_keyboard_set_focus(keyboard, keyboard->focus.surface); - } } static void get_touch(struct wl_client * client, struct wl_resource * resource,