window.c: Move window items to window.c
diff --git a/clients/window.c b/clients/window.c
index e7a61ef..9e92adb 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -125,11 +125,22 @@
window_motion_handler_t motion_handler;
window_enter_handler_t enter_handler;
window_leave_handler_t leave_handler;
+ window_item_focus_handler_t item_focus_handler;
+
+ struct wl_list item_list;
+ struct item *focus_item;
+ uint32_t item_grab_button;
void *user_data;
struct wl_list link;
};
+struct item {
+ struct wl_list link;
+ struct rectangle allocation;
+ void *user_data;
+};
+
struct input {
struct display *display;
struct wl_input_device *input_device;
@@ -949,6 +960,73 @@
free(window);
}
+static struct item *
+window_find_item(struct window *window, int32_t x, int32_t y)
+{
+ struct item *item;
+
+ wl_list_for_each(item, &window->item_list, link) {
+ if (item->allocation.x <= x &&
+ x < item->allocation.x + item->allocation.width &&
+ item->allocation.y <= y &&
+ y < item->allocation.y + item->allocation.height) {
+ return item;
+ }
+ }
+
+ return NULL;
+}
+
+struct item *
+window_add_item(struct window *window, void *data)
+{
+ struct item *item;
+
+ item = malloc(sizeof *item);
+ memset(item, 0, sizeof *item);
+ item->user_data = data;
+ wl_list_insert(window->item_list.prev, &item->link);
+
+ return item;
+}
+
+void
+window_for_each_item(struct window *window, item_func_t func, void *data)
+{
+ struct item *item;
+
+ wl_list_for_each(item, &window->item_list, link)
+ func(item, data);
+}
+
+struct item *
+window_get_focus_item(struct window *window)
+{
+ return window->focus_item;
+}
+
+void
+item_get_allocation(struct item *item, struct rectangle *allocation)
+{
+ *allocation = item->allocation;
+}
+
+void
+item_set_allocation(struct item *item,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ item->allocation.x = x;
+ item->allocation.y = y;
+ item->allocation.width = width;
+ item->allocation.height = height;
+}
+
+void *
+item_get_user_data(struct item *item)
+{
+ return item->user_data;
+}
+
void
display_flush_cairo_device(struct display *display)
{
@@ -1079,12 +1157,27 @@
}
static void
+window_set_focus_item(struct window *window, struct item *focus)
+{
+ void *data;
+
+ if (focus == window->focus_item)
+ return;
+
+ window->focus_item = focus;
+ data = focus ? focus->user_data : NULL;
+ if (window->item_focus_handler)
+ window->item_focus_handler(window, focus, data);
+}
+
+static void
window_handle_motion(void *data, struct wl_input_device *input_device,
uint32_t time,
int32_t x, int32_t y, int32_t sx, int32_t sy)
{
struct input *input = data;
struct window *window = input->pointer_focus;
+ struct item *item;
int pointer = POINTER_LEFT_PTR;
input->x = x;
@@ -1092,6 +1185,11 @@
input->sx = sx;
input->sy = sy;
+ if (!window->focus_item || !window->item_grab_button) {
+ item = window_find_item(window, sx, sy);
+ window_set_focus_item(window, item);
+ }
+
if (window->motion_handler)
pointer = (*window->motion_handler)(window, input, time,
x, y, sx, sy,
@@ -1107,8 +1205,12 @@
{
struct input *input = data;
struct window *window = input->pointer_focus;
+ struct item *item;
int location;
+ if (window->focus_item && window->item_grab_button == 0 && state)
+ window->item_grab_button = button;
+
location = get_pointer_location(window, input->sx, input->sy);
if (button == BTN_LEFT && state == 1) {
@@ -1144,6 +1246,13 @@
button, state,
window->user_data);
}
+
+ if (window->focus_item &&
+ window->item_grab_button == button && !state) {
+ window->item_grab_button = 0;
+ item = window_find_item(window, input->sx, input->sy);
+ window_set_focus_item(window, item);
+ }
}
static void
@@ -1184,10 +1293,13 @@
{
struct input *input = data;
struct window *window;
+ struct item *item;
int pointer;
window = input->pointer_focus;
if (window && window->surface != surface) {
+ window_set_focus_item(window, NULL);
+
if (window->leave_handler)
window->leave_handler(window, input,
time, window->user_data);
@@ -1210,8 +1322,10 @@
time, sx, sy,
window->user_data);
- set_pointer_image(input, time, pointer);
+ item = window_find_item(window, x, y);
+ window_set_focus_item(window, item);
+ set_pointer_image(input, time, pointer);
}
}
@@ -1504,6 +1618,13 @@
}
void
+window_set_item_focus_handler(struct window *window,
+ window_item_focus_handler_t handler)
+{
+ window->item_focus_handler = handler;
+}
+
+void
window_set_transparent(struct window *window, int transparent)
{
window->transparent = transparent;
@@ -1562,6 +1683,7 @@
window->margin = 16;
window->decoration = 1;
window->transparent = 1;
+ wl_list_init(&window->item_list);
if (display->dpy)
#ifdef HAVE_CAIRO_EGL