diff options
-rw-r--r-- | examples/config.c | 79 | ||||
-rw-r--r-- | examples/config.h | 16 | ||||
-rw-r--r-- | examples/pointer.c | 75 | ||||
-rw-r--r-- | types/wlr_cursor.c | 150 |
4 files changed, 189 insertions, 131 deletions
diff --git a/examples/config.c b/examples/config.c index 6796ea66..f04f92d2 100644 --- a/examples/config.c +++ b/examples/config.c @@ -266,3 +266,82 @@ struct output_config *example_config_get_output(struct example_config *config, return NULL; } + +struct device_config *example_config_get_device(struct example_config *config, + struct wlr_input_device *device) { + struct device_config *d_config; + wl_list_for_each(d_config, &config->devices, link) { + if (strcmp(d_config->name, device->name) == 0) { + return d_config; + } + } + + return NULL; +} + +/** + * Set device output mappings to NULL and configure region mappings. + */ +static void reset_device_mappings(struct example_config *config, + struct wlr_cursor *cursor, struct wlr_input_device *device) { + struct device_config *d_config; + wlr_cursor_map_input_to_output(cursor, device, NULL); + d_config = example_config_get_device(config, device); + if (d_config) { + wlr_cursor_map_input_to_region(cursor, device, + d_config->mapped_box); + } +} + +static void set_device_output_mappings(struct example_config *config, + struct wlr_cursor *cursor, struct wlr_output *output, + struct wlr_input_device *device) { + struct device_config *d_config; + d_config = example_config_get_device(config, device); + if (d_config && + d_config->mapped_output && + strcmp(d_config->mapped_output, output->name) == 0) { + wlr_cursor_map_input_to_output(cursor, device, output); + } +} + +void example_config_configure_cursor(struct example_config *config, + struct wlr_cursor *cursor, struct compositor_state *compositor) { + struct pointer_state *p_state; + struct tablet_tool_state *tt_state; + struct touch_state *tch_state; + struct output_state *o_state; + + // reset mappings + wlr_cursor_map_to_output(cursor, NULL); + wl_list_for_each(p_state, &compositor->pointers, link) { + reset_device_mappings(config, cursor, p_state->device); + } + wl_list_for_each(tt_state, &compositor->tablet_tools, link) { + reset_device_mappings(config, cursor, tt_state->device); + } + wl_list_for_each(tch_state, &compositor->touch, link) { + reset_device_mappings(config, cursor, tch_state->device); + } + + // configure device to output mappings + char *mapped_output = config->cursor.mapped_output; + wl_list_for_each(o_state, &compositor->outputs, link) { + if (mapped_output && strcmp(mapped_output, o_state->output->name) == 0) { + wlr_cursor_map_to_output(cursor, o_state->output); + } + + wl_list_for_each(p_state, &compositor->pointers, link) { + set_device_output_mappings(config, cursor, o_state->output, + p_state->device); + } + wl_list_for_each(tt_state, &compositor->tablet_tools, link) { + set_device_output_mappings(config, cursor, o_state->output, + tt_state->device); + } + wl_list_for_each(tch_state, &compositor->touch, link) { + set_device_output_mappings(config, cursor, o_state->output, + tch_state->device); + } + } +} diff --git a/examples/config.h b/examples/config.h index bc2e101b..e26531c2 100644 --- a/examples/config.h +++ b/examples/config.h @@ -4,6 +4,9 @@ #define _POSIX_C_SOURCE 200112L #endif #include <wlr/types/wlr_output_layout.h> +#include <wlr/types/wlr_input_device.h> +#include <wlr/types/wlr_cursor.h> +#include "shared.h" struct output_config { char *name; @@ -41,4 +44,17 @@ void example_config_destroy(struct example_config *config); struct output_config *example_config_get_output(struct example_config *config, struct wlr_output *output); +/** + * Get configuration for the device. If the device is not configured, returns + * NULL. + */ +struct device_config *example_config_get_device(struct example_config *config, + struct wlr_input_device *device); + +/** + * Configure cursor device mappings. + */ +void example_config_configure_cursor(struct example_config *config, + struct wlr_cursor *cursor, struct compositor_state *state); + #endif diff --git a/examples/pointer.c b/examples/pointer.c index 56f9e60a..2b937540 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -25,11 +25,6 @@ #include "config.h" #include "cat.h" -struct sample_input_device { - struct wlr_input_device *device; - struct wl_list link; -}; - struct sample_state { struct compositor_state *compositor; struct example_config *config; @@ -95,38 +90,6 @@ static void handle_output_frame(struct output_state *output, wlr_output_swap_buffers(wlr_output); } -static void configure_devices(struct sample_state *sample) { - struct sample_input_device *dev; - struct device_config *dc; - - // reset device mappings - wl_list_for_each(dev, &sample->devices, link) { - wlr_cursor_map_input_to_output(sample->cursor, dev->device, NULL); - wl_list_for_each(dc, &sample->config->devices, link) { - if (strcmp(dev->device->name, dc->name) == 0) { - wlr_cursor_map_input_to_region(sample->cursor, dev->device, - dc->mapped_box); - } - } - } - - struct output_state *ostate; - wl_list_for_each(ostate, &sample->compositor->outputs, link) { - wl_list_for_each(dc, &sample->config->devices, link) { - // configure device to output mappings - if (dc->mapped_output && - strcmp(dc->mapped_output, ostate->output->name) == 0) { - wl_list_for_each(dev, &sample->devices, link) { - if (strcmp(dev->device->name, dc->name) == 0) { - wlr_cursor_map_input_to_output(sample->cursor, - dev->device, ostate->output); - } - } - } - } - } -} - static void handle_output_add(struct output_state *ostate) { struct sample_state *sample = ostate->compositor->data; struct wlr_output *wlr_output = ostate->output; @@ -143,13 +106,8 @@ static void handle_output_add(struct output_state *ostate) { wlr_output_layout_add_auto(sample->layout, ostate->output); } - // cursor configuration - char *mapped_output = sample->config->cursor.mapped_output; - if (mapped_output && strcmp(mapped_output, wlr_output->name) == 0) { - wlr_cursor_map_to_output(sample->cursor, wlr_output); - } - - configure_devices(sample); + 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. @@ -167,12 +125,8 @@ static void handle_output_remove(struct output_state *ostate) { wlr_output_layout_remove(sample->layout, ostate->output); - configure_devices(sample); - - char *mapped_output = sample->config->cursor.mapped_output; - if (mapped_output && strcmp(mapped_output, ostate->output->name) == 0) { - wlr_cursor_map_to_output(sample->cursor, NULL); - } + example_config_configure_cursor(sample->config, sample->cursor, + sample->compositor); } static void handle_input_add(struct compositor_state *state, @@ -182,25 +136,9 @@ static void handle_input_add(struct compositor_state *state, if (device->type == WLR_INPUT_DEVICE_POINTER || device->type == WLR_INPUT_DEVICE_TOUCH || device->type == WLR_INPUT_DEVICE_TABLET_TOOL) { - struct sample_input_device *s_device; - s_device = calloc(1, sizeof(struct sample_input_device)); - s_device->device = device; - - wl_list_insert(&sample->devices, &s_device->link); wlr_cursor_attach_input_device(sample->cursor, device); - configure_devices(sample); - } -} - -static void handle_input_remove(struct compositor_state *state, - struct wlr_input_device *device) { - struct sample_state *sample = state->data; - struct sample_input_device *s_device, *tmp = NULL; - wl_list_for_each_safe(s_device, tmp, &sample->devices, link) { - if (s_device->device == device) { - wl_list_remove(&s_device->link); - free(s_device); - } + example_config_configure_cursor(sample->config, sample->cursor, + sample->compositor); } } @@ -378,7 +316,6 @@ int main(int argc, char *argv[]) { compositor.output_remove_cb = handle_output_remove; compositor.output_frame_cb = handle_output_frame; compositor.input_add_cb = handle_input_add; - compositor.input_remove_cb = handle_input_remove; state.compositor = &compositor; diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 8751e5c3..79972745 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -354,6 +354,70 @@ static void handle_device_destroy(struct wl_listener *listener, void *data) { wlr_cursor_detach_input_device(c_device->cursor, c_device->device); } +static struct wlr_cursor_device *wlr_cursor_device_create( + struct wlr_cursor *cursor, struct wlr_input_device *device) { + struct wlr_cursor_device *c_device = + calloc(1, sizeof(struct wlr_cursor_device)); + if (!c_device) { + wlr_log(L_ERROR, "Failed to allocate wlr_cursor_device"); + return NULL; + } + + c_device->cursor = cursor; + c_device->device = device; + + // listen to events + wl_signal_add(&device->events.destroy, &c_device->destroy); + c_device->destroy.notify = handle_device_destroy; + + if (device->type == WLR_INPUT_DEVICE_POINTER) { + wl_signal_add(&device->pointer->events.motion, &c_device->motion); + c_device->motion.notify = handle_pointer_motion; + + wl_signal_add(&device->pointer->events.motion_absolute, + &c_device->motion_absolute); + c_device->motion_absolute.notify = handle_pointer_motion_absolute; + + wl_signal_add(&device->pointer->events.button, &c_device->button); + c_device->button.notify = handle_pointer_button; + + wl_signal_add(&device->pointer->events.axis, &c_device->axis); + c_device->axis.notify = handle_pointer_axis; + } else if (device->type == WLR_INPUT_DEVICE_TOUCH) { + wl_signal_add(&device->touch->events.motion, &c_device->touch_motion); + c_device->touch_motion.notify = handle_touch_motion; + + wl_signal_add(&device->touch->events.down, &c_device->touch_down); + c_device->touch_down.notify = handle_touch_down; + + wl_signal_add(&device->touch->events.up, &c_device->touch_up); + c_device->touch_up.notify = handle_touch_up; + + wl_signal_add(&device->touch->events.cancel, &c_device->touch_cancel); + c_device->touch_cancel.notify = handle_touch_cancel; + } else if (device->type == WLR_INPUT_DEVICE_TABLET_TOOL) { + wl_signal_add(&device->tablet_tool->events.tip, + &c_device->tablet_tool_tip); + c_device->tablet_tool_tip.notify = handle_tablet_tool_tip; + + wl_signal_add(&device->tablet_tool->events.proximity, + &c_device->tablet_tool_proximity); + c_device->tablet_tool_proximity.notify = handle_tablet_tool_proximity; + + wl_signal_add(&device->tablet_tool->events.axis, + &c_device->tablet_tool_axis); + c_device->tablet_tool_axis.notify = handle_tablet_tool_axis; + + wl_signal_add(&device->tablet_tool->events.button, + &c_device->tablet_tool_button); + c_device->tablet_tool_button.notify = handle_tablet_tool_button; + } + + wl_list_insert(&cursor->state->devices, &c_device->link); + + return c_device; +} + void wlr_cursor_attach_input_device(struct wlr_cursor *cur, struct wlr_input_device *dev) { if (dev->type != WLR_INPUT_DEVICE_POINTER && @@ -372,80 +436,42 @@ void wlr_cursor_attach_input_device(struct wlr_cursor *cur, } } - struct wlr_cursor_device *device; - device = calloc(1, sizeof(struct wlr_cursor_device)); - if (!device) { - wlr_log(L_ERROR, "Failed to allocate wlr_cursor_device"); - return; - } - - device->cursor = cur; - device->device = dev; - - // listen to events - - wl_signal_add(&dev->events.destroy, &device->destroy); - device->destroy.notify = handle_device_destroy; + wlr_cursor_device_create(cur, dev); +} +static void wlr_cursor_device_destroy(struct wlr_cursor_device *c_device) { + struct wlr_input_device *dev = c_device->device; if (dev->type == WLR_INPUT_DEVICE_POINTER) { - wl_signal_add(&dev->pointer->events.motion, &device->motion); - device->motion.notify = handle_pointer_motion; - - wl_signal_add(&dev->pointer->events.motion_absolute, - &device->motion_absolute); - device->motion_absolute.notify = handle_pointer_motion_absolute; - - wl_signal_add(&dev->pointer->events.button, &device->button); - device->button.notify = handle_pointer_button; - - wl_signal_add(&dev->pointer->events.axis, &device->axis); - device->axis.notify = handle_pointer_axis; + wl_list_remove(&c_device->motion.link); + wl_list_remove(&c_device->motion_absolute.link); + wl_list_remove(&c_device->button.link); + wl_list_remove(&c_device->axis.link); } else if (dev->type == WLR_INPUT_DEVICE_TOUCH) { - wl_signal_add(&dev->touch->events.motion, &device->touch_motion); - device->touch_motion.notify = handle_touch_motion; - - wl_signal_add(&dev->touch->events.down, &device->touch_down); - device->touch_down.notify = handle_touch_down; - - wl_signal_add(&dev->touch->events.up, &device->touch_up); - device->touch_up.notify = handle_touch_up; - - wl_signal_add(&dev->touch->events.cancel, &device->touch_cancel); - device->touch_cancel.notify = handle_touch_cancel; + wl_list_remove(&c_device->touch_down.link); + wl_list_remove(&c_device->touch_up.link); + wl_list_remove(&c_device->touch_motion.link); + wl_list_remove(&c_device->touch_cancel.link); } else if (dev->type == WLR_INPUT_DEVICE_TABLET_TOOL) { - wl_signal_add(&dev->tablet_tool->events.tip, &device->tablet_tool_tip); - device->tablet_tool_tip.notify = handle_tablet_tool_tip; - - wl_signal_add(&dev->tablet_tool->events.proximity, - &device->tablet_tool_proximity); - device->tablet_tool_proximity.notify = handle_tablet_tool_proximity; - - wl_signal_add(&dev->tablet_tool->events.axis, - &device->tablet_tool_axis); - device->tablet_tool_axis.notify = handle_tablet_tool_axis; - - wl_signal_add(&dev->tablet_tool->events.button, - &device->tablet_tool_button); - device->tablet_tool_button.notify = handle_tablet_tool_button; + wl_list_remove(&c_device->tablet_tool_axis.link); + wl_list_remove(&c_device->tablet_tool_proximity.link); + wl_list_remove(&c_device->tablet_tool_tip.link); + wl_list_remove(&c_device->tablet_tool_button.link); } - wl_list_insert(&cur->state->devices, &device->link); + wl_list_remove(&c_device->link); + wl_list_remove(&c_device->destroy.link); + free(c_device); + } void wlr_cursor_detach_input_device(struct wlr_cursor *cur, struct wlr_input_device *dev) { - struct wlr_cursor_device *target_device = NULL, *_device = NULL; - wl_list_for_each(_device, &cur->state->devices, link) { - if (_device->device == dev) { - target_device = _device; - break; + struct wlr_cursor_device *c_device, *tmp = NULL; + wl_list_for_each_safe(c_device, tmp, &cur->state->devices, link) { + if (c_device->device == dev) { + wlr_cursor_device_destroy(c_device); } } - - if (target_device) { - wl_list_remove(&target_device->link); - free(target_device); - } } static void handle_layout_destroy(struct wl_listener *listener, void *data) { |