diff options
Diffstat (limited to 'examples/support/shared.c')
-rw-r--r-- | examples/support/shared.c | 274 |
1 files changed, 112 insertions, 162 deletions
diff --git a/examples/support/shared.c b/examples/support/shared.c index 6cfaa6aa..c4f9288d 100644 --- a/examples/support/shared.c +++ b/examples/support/shared.c @@ -56,10 +56,24 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { } } +static void keyboard_destroy_notify(struct wl_listener *listener, void *data) { + struct keyboard_state *kbstate = wl_container_of(listener, kbstate, destroy); + struct compositor_state *state = kbstate->compositor; + if (state->input_remove_cb) { + state->input_remove_cb(state, kbstate->device); + } + wl_list_remove(&kbstate->link); + wl_list_remove(&kbstate->destroy.link); + wl_list_remove(&kbstate->key.link); + free(kbstate); +} + static void keyboard_add(struct wlr_input_device *device, struct compositor_state *state) { struct keyboard_state *kbstate = calloc(sizeof(struct keyboard_state), 1); kbstate->device = device; kbstate->compositor = state; + kbstate->destroy.notify = keyboard_destroy_notify; + wl_signal_add(&device->events.destroy, &kbstate->destroy); kbstate->key.notify = keyboard_key_notify; wl_signal_add(&device->keyboard->events.key, &kbstate->key); wl_list_insert(&state->keyboards, &kbstate->link); @@ -117,17 +131,34 @@ static void pointer_axis_notify(struct wl_listener *listener, void *data) { } } +static void pointer_destroy_notify(struct wl_listener *listener, void *data) { + struct pointer_state *pstate = wl_container_of(listener, pstate, destroy); + struct compositor_state *state = pstate->compositor; + if (state->input_remove_cb) { + state->input_remove_cb(state, pstate->device); + } + wl_list_remove(&pstate->link); + wl_list_remove(&pstate->destroy.link); + wl_list_remove(&pstate->motion.link); + wl_list_remove(&pstate->motion_absolute.link); + wl_list_remove(&pstate->button.link); + wl_list_remove(&pstate->axis.link); + free(pstate); +} + static void pointer_add(struct wlr_input_device *device, struct compositor_state *state) { struct pointer_state *pstate = calloc(sizeof(struct pointer_state), 1); pstate->device = device; pstate->compositor = state; + pstate->destroy.notify = pointer_destroy_notify; + wl_signal_add(&device->events.destroy, &pstate->destroy); pstate->motion.notify = pointer_motion_notify; - pstate->motion_absolute.notify = pointer_motion_absolute_notify; - pstate->button.notify = pointer_button_notify; - pstate->axis.notify = pointer_axis_notify; wl_signal_add(&device->pointer->events.motion, &pstate->motion); + pstate->motion_absolute.notify = pointer_motion_absolute_notify; wl_signal_add(&device->pointer->events.motion_absolute, &pstate->motion_absolute); + pstate->button.notify = pointer_button_notify; wl_signal_add(&device->pointer->events.button, &pstate->button); + pstate->axis.notify = pointer_axis_notify; wl_signal_add(&device->pointer->events.axis, &pstate->axis); wl_list_insert(&state->pointers, &pstate->link); } @@ -166,17 +197,34 @@ static void touch_cancel_notify(struct wl_listener *listener, void *data) { } } +static void touch_destroy_notify(struct wl_listener *listener, void *data) { + struct touch_state *tstate = wl_container_of(listener, tstate, destroy); + struct compositor_state *state = tstate->compositor; + if (state->input_remove_cb) { + state->input_remove_cb(state, tstate->device); + } + wl_list_remove(&tstate->link); + wl_list_remove(&tstate->destroy.link); + wl_list_remove(&tstate->down.link); + wl_list_remove(&tstate->motion.link); + wl_list_remove(&tstate->up.link); + wl_list_remove(&tstate->cancel.link); + free(tstate); +} + static void touch_add(struct wlr_input_device *device, struct compositor_state *state) { struct touch_state *tstate = calloc(sizeof(struct touch_state), 1); tstate->device = device; tstate->compositor = state; + tstate->destroy.notify = touch_destroy_notify; + wl_signal_add(&device->events.destroy, &tstate->destroy); tstate->down.notify = touch_down_notify; - tstate->motion.notify = touch_motion_notify; - tstate->up.notify = touch_up_notify; - tstate->cancel.notify = touch_cancel_notify; wl_signal_add(&device->touch->events.down, &tstate->down); + tstate->motion.notify = touch_motion_notify; wl_signal_add(&device->touch->events.motion, &tstate->motion); + tstate->up.notify = touch_up_notify; wl_signal_add(&device->touch->events.up, &tstate->up); + tstate->cancel.notify = touch_cancel_notify; wl_signal_add(&device->touch->events.cancel, &tstate->cancel); wl_list_insert(&state->touch, &tstate->link); } @@ -205,18 +253,35 @@ static void tablet_tool_button_notify(struct wl_listener *listener, void *data) } } +static void tablet_tool_destroy_notify(struct wl_listener *listener, void *data) { + struct tablet_tool_state *tstate = wl_container_of(listener, tstate, destroy); + struct compositor_state *state = tstate->compositor; + if (state->input_remove_cb) { + state->input_remove_cb(state, tstate->device); + } + wl_list_remove(&tstate->link); + wl_list_remove(&tstate->destroy.link); + wl_list_remove(&tstate->axis.link); + wl_list_remove(&tstate->proximity.link); + //wl_list_remove(&tstate->tip.link); + wl_list_remove(&tstate->button.link); + free(tstate); +} + static void tablet_tool_add(struct wlr_input_device *device, struct compositor_state *state) { struct tablet_tool_state *tstate = calloc(sizeof(struct tablet_tool_state), 1); tstate->device = device; tstate->compositor = state; + tstate->destroy.notify = tablet_tool_destroy_notify; + wl_signal_add(&device->events.destroy, &tstate->destroy); tstate->axis.notify = tablet_tool_axis_notify; - tstate->proximity.notify = tablet_tool_proximity_notify; - //tstate->tip.notify = tablet_tool_tip_notify; - tstate->button.notify = tablet_tool_button_notify; wl_signal_add(&device->tablet_tool->events.axis, &tstate->axis); + tstate->proximity.notify = tablet_tool_proximity_notify; wl_signal_add(&device->tablet_tool->events.proximity, &tstate->proximity); + //tstate->tip.notify = tablet_tool_tip_notify; //wl_signal_add(&device->tablet_tool->events.tip, &tstate->tip); + tstate->button.notify = tablet_tool_button_notify; wl_signal_add(&device->tablet_tool->events.button, &tstate->button); wl_list_insert(&state->tablet_tools, &tstate->link); } @@ -229,19 +294,33 @@ static void tablet_pad_button_notify(struct wl_listener *listener, void *data) { } } +static void tablet_pad_destroy_notify(struct wl_listener *listener, void *data) { + struct tablet_pad_state *pstate = wl_container_of(listener, pstate, destroy); + struct compositor_state *state = pstate->compositor; + if (state->input_remove_cb) { + state->input_remove_cb(state, pstate->device); + } + wl_list_remove(&pstate->link); + wl_list_remove(&pstate->destroy.link); + wl_list_remove(&pstate->button.link); + free(pstate); +} + static void tablet_pad_add(struct wlr_input_device *device, struct compositor_state *state) { struct tablet_pad_state *pstate = calloc(sizeof(struct tablet_pad_state), 1); pstate->device = device; pstate->compositor = state; + pstate->destroy.notify = tablet_pad_destroy_notify; + wl_signal_add(&device->events.destroy, &pstate->destroy); pstate->button.notify = tablet_pad_button_notify; wl_signal_add(&device->tablet_pad->events.button, &pstate->button); wl_list_insert(&state->tablet_pads, &pstate->link); } -static void input_add_notify(struct wl_listener *listener, void *data) { +static void new_input_notify(struct wl_listener *listener, void *data) { struct wlr_input_device *device = data; - struct compositor_state *state = wl_container_of(listener, state, input_add); + struct compositor_state *state = wl_container_of(listener, state, new_input); switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: keyboard_add(device, state); @@ -267,123 +346,6 @@ static void input_add_notify(struct wl_listener *listener, void *data) { } } -static void keyboard_remove(struct wlr_input_device *device, struct compositor_state *state) { - struct keyboard_state *kbstate = NULL, *_kbstate; - wl_list_for_each(_kbstate, &state->keyboards, link) { - if (_kbstate->device == device) { - kbstate = _kbstate; - break; - } - } - if (!kbstate) { - return; - } - wl_list_remove(&kbstate->link); - wl_list_remove(&kbstate->key.link); - free(kbstate); -} - -static void pointer_remove(struct wlr_input_device *device, struct compositor_state *state) { - struct pointer_state *pstate = NULL, *_pstate; - wl_list_for_each(_pstate, &state->pointers, link) { - if (_pstate->device == device) { - pstate = _pstate; - break; - } - } - if (!pstate) { - return; - } - wl_list_remove(&pstate->link); - wl_list_remove(&pstate->motion.link); - wl_list_remove(&pstate->motion_absolute.link); - wl_list_remove(&pstate->button.link); - wl_list_remove(&pstate->axis.link); - free(pstate); -} - -static void touch_remove(struct wlr_input_device *device, struct compositor_state *state) { - struct touch_state *tstate = NULL, *_tstate; - wl_list_for_each(_tstate, &state->touch, link) { - if (_tstate->device == device) { - tstate = _tstate; - break; - } - } - if (!tstate) { - return; - } - wl_list_remove(&tstate->link); - wl_list_remove(&tstate->down.link); - wl_list_remove(&tstate->motion.link); - wl_list_remove(&tstate->up.link); - wl_list_remove(&tstate->cancel.link); - free(tstate); -} - -static void tablet_tool_remove(struct wlr_input_device *device, struct compositor_state *state) { - struct tablet_tool_state *tstate = NULL, *_tstate; - wl_list_for_each(_tstate, &state->tablet_tools, link) { - if (_tstate->device == device) { - tstate = _tstate; - break; - } - } - if (!tstate) { - return; - } - wl_list_remove(&tstate->link); - wl_list_remove(&tstate->axis.link); - wl_list_remove(&tstate->proximity.link); - //wl_list_remove(&tstate->tip.link); - wl_list_remove(&tstate->button.link); - free(tstate); -} - -static void tablet_pad_remove(struct wlr_input_device *device, struct compositor_state *state) { - struct tablet_pad_state *pstate = NULL, *_pstate; - wl_list_for_each(_pstate, &state->tablet_pads, link) { - if (_pstate->device ==device) { - pstate = _pstate; - break; - } - } - if (!pstate) { - return; - } - wl_list_remove(&pstate->button.link); - free(pstate); -} - -static void input_remove_notify(struct wl_listener *listener, void *data) { - struct wlr_input_device *device = data; - struct compositor_state *state = wl_container_of(listener, state, input_remove); - - if (state->input_remove_cb) { - state->input_remove_cb(state, device); - } - - switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: - keyboard_remove(device, state); - break; - case WLR_INPUT_DEVICE_POINTER: - pointer_remove(device, state); - break; - case WLR_INPUT_DEVICE_TOUCH: - touch_remove(device, state); - break; - case WLR_INPUT_DEVICE_TABLET_TOOL: - tablet_tool_remove(device, state); - break; - case WLR_INPUT_DEVICE_TABLET_PAD: - tablet_pad_remove(device, state); - break; - default: - break; - } -} - static void output_frame_notify(struct wl_listener *listener, void *data) { struct output_state *output = wl_container_of(listener, output, frame); struct compositor_state *compositor = output->compositor; @@ -407,9 +369,21 @@ static void output_resolution_notify(struct wl_listener *listener, void *data) { } } -static void output_add_notify(struct wl_listener *listener, void *data) { +static void output_destroy_notify(struct wl_listener *listener, void *data) { + struct output_state *ostate = wl_container_of(listener, ostate, destroy); + struct compositor_state *state = ostate->compositor; + if (state->output_remove_cb) { + state->output_remove_cb(ostate); + } + wl_list_remove(&ostate->link); + wl_list_remove(&ostate->frame.link); + wl_list_remove(&ostate->resolution.link); + free(ostate); +} + +static void new_output_notify(struct wl_listener *listener, void *data) { struct wlr_output *output = data; - struct compositor_state *state = wl_container_of(listener, state, output_add); + struct compositor_state *state = wl_container_of(listener, state, new_output); wlr_log(L_DEBUG, "Output '%s' added", output->name); wlr_log(L_DEBUG, "%s %s %"PRId32"mm x %"PRId32"mm", output->make, output->model, output->phys_width, output->phys_height); @@ -422,9 +396,11 @@ static void output_add_notify(struct wl_listener *listener, void *data) { clock_gettime(CLOCK_MONOTONIC, &ostate->last_frame); ostate->output = output; ostate->compositor = state; + ostate->destroy.notify = output_destroy_notify; + wl_signal_add(&output->events.destroy, &ostate->destroy); ostate->frame.notify = output_frame_notify; - ostate->resolution.notify = output_resolution_notify; wl_signal_add(&output->events.frame, &ostate->frame); + ostate->resolution.notify = output_resolution_notify; wl_signal_add(&output->events.mode, &ostate->resolution); wl_list_insert(&state->outputs, &ostate->link); if (state->output_add_cb) { @@ -432,28 +408,6 @@ static void output_add_notify(struct wl_listener *listener, void *data) { } } -static void output_remove_notify(struct wl_listener *listener, void *data) { - struct wlr_output *output = data; - struct compositor_state *state = wl_container_of(listener, state, output_remove); - struct output_state *ostate = NULL, *_ostate; - wl_list_for_each(_ostate, &state->outputs, link) { - if (_ostate->output == output) { - ostate = _ostate; - break; - } - } - if (!ostate) { - return; // We are unfamiliar with this output - } - if (state->output_remove_cb) { - state->output_remove_cb(ostate); - } - wl_list_remove(&ostate->link); - wl_list_remove(&ostate->frame.link); - wl_list_remove(&ostate->resolution.link); - free(ostate); -} - void compositor_init(struct compositor_state *state) { state->display = wl_display_create(); state->event_loop = wl_display_get_event_loop(state->display); @@ -463,23 +417,19 @@ void compositor_init(struct compositor_state *state) { wl_list_init(&state->touch); wl_list_init(&state->tablet_tools); wl_list_init(&state->tablet_pads); - state->input_add.notify = input_add_notify; - state->input_remove.notify = input_remove_notify; - wl_list_init(&state->outputs); - state->output_add.notify = output_add_notify; - state->output_remove.notify = output_remove_notify; struct wlr_backend *wlr = wlr_backend_autocreate(state->display); if (!wlr) { exit(1); } - wl_signal_add(&wlr->events.input_add, &state->input_add); - wl_signal_add(&wlr->events.input_remove, &state->input_remove); - wl_signal_add(&wlr->events.output_add, &state->output_add); - wl_signal_add(&wlr->events.output_remove, &state->output_remove); state->backend = wlr; + wl_signal_add(&wlr->events.new_input, &state->new_input); + state->new_input.notify = new_input_notify; + wl_signal_add(&wlr->events.new_output, &state->new_output); + state->new_output.notify = new_output_notify; + clock_gettime(CLOCK_MONOTONIC, &state->last_frame); const char *socket = wl_display_add_socket_auto(state->display); |