main neuswc / libswc / select.c
  1#include <wayland-server.h>
  2
  3#include "select.h"
  4#include "swc_select-server-protocol.h"
  5
  6#include "internal.h"
  7#include "compositor.h"
  8#include "pointer.h"
  9#include "seat.h"
 10#include "util.h"
 11
 12static struct wl_list select_resources;
 13static int32_t start_x, start_y;
 14static struct pointer_handler select_pointer_handler;
 15
 16enum select_state { STATE_WAIT, STATE_DRAG };
 17static enum select_state select_state;
 18
 19static bool
 20handle_motion(struct pointer_handler *h, uint32_t time, wl_fixed_t fx,
 21              wl_fixed_t fy)
 22{
 23	int32_t x = wl_fixed_to_int(fx);
 24	int32_t y = wl_fixed_to_int(fy);
 25	struct wl_resource *resource;
 26
 27	if (select_state != STATE_DRAG) {
 28		return false;
 29	}
 30
 31	/* TODO: customizable color, maybeee, idk idc */
 32	swc_overlay_set_box(start_x, start_y, x, y, 0xffffffff, 2);
 33
 34	wl_resource_for_each(resource, &select_resources)
 35	    swc_select_send_update(resource, start_x, start_y, x, y);
 36
 37	return true;
 38}
 39
 40static bool
 41handle_button(struct pointer_handler *h, uint32_t time, struct button *button,
 42              uint32_t state)
 43{
 44	int32_t x = wl_fixed_to_int(swc.seat->pointer->x);
 45	int32_t y = wl_fixed_to_int(swc.seat->pointer->y);
 46	struct wl_resource *resource;
 47
 48	if (state == WL_POINTER_BUTTON_STATE_PRESSED &&
 49	    select_state == STATE_WAIT) {
 50		start_x = x;
 51		start_y = y;
 52		select_state = STATE_DRAG;
 53		return true;
 54	}
 55
 56	if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
 57	    select_state == STATE_DRAG) {
 58		swc_overlay_clear();
 59		wl_list_remove(&select_pointer_handler.link);
 60		select_state = STATE_WAIT;
 61		swc_set_cursor(SWC_CURSOR_DEFAULT);
 62
 63		wl_resource_for_each(resource, &select_resources)
 64		    swc_select_send_done(resource, start_x, start_y, x, y);
 65
 66		return true;
 67	}
 68
 69	return false;
 70}
 71
 72static void
 73handle_grab(struct wl_client *client, struct wl_resource *resource)
 74{
 75	select_state = STATE_WAIT;
 76	select_pointer_handler.motion = handle_motion;
 77	select_pointer_handler.button = handle_button;
 78	wl_list_insert(&swc.seat->pointer->handlers, &select_pointer_handler.link);
 79	swc_set_cursor(SWC_CURSOR_CROSS);
 80}
 81
 82static const struct swc_select_interface select_impl = {
 83    .grab = handle_grab,
 84};
 85
 86static void
 87bind_select(struct wl_client *client, void *data, uint32_t version, uint32_t id)
 88{
 89	struct wl_resource *resource;
 90
 91	resource = wl_resource_create(client, &swc_select_interface, 1, id);
 92	if (!resource) {
 93		wl_client_post_no_memory(client);
 94		return;
 95	}
 96
 97	wl_resource_set_implementation(resource, &select_impl, NULL,
 98	                               remove_resource);
 99	wl_list_insert(&select_resources, wl_resource_get_link(resource));
100}
101
102struct wl_global *
103select_manager_create(struct wl_display *display)
104{
105	wl_list_init(&select_resources);
106	select_pointer_handler.motion = handle_motion;
107	select_pointer_handler.button = handle_button;
108	return wl_global_create(display, &swc_select_interface, 1, NULL,
109	                        &bind_select);
110}