commit 680957d

Michael Forney  ·  2014-02-17 00:06:06 +0000 UTC
parent 77ec52d
pointer: Add more flexible handler system
3 files changed,  +115, -28
+108, -26
  1@@ -33,6 +33,12 @@
  2 #include <assert.h>
  3 #include <wld/wld.h>
  4 
  5+struct button_press
  6+{
  7+    uint32_t value;
  8+    struct swc_pointer_handler * handler;
  9+};
 10+
 11 static void enter(struct swc_input_focus_handler * handler,
 12                   struct wl_resource * resource, struct swc_surface * surface)
 13 {
 14@@ -189,6 +195,54 @@ void swc_pointer_set_cursor(struct swc_pointer * pointer, uint32_t id)
 15     swc_view_attach(&pointer->cursor.view, pointer->cursor.internal_buffer);
 16 }
 17 
 18+static bool client_handle_button(struct swc_pointer_handler * handler,
 19+                                 uint32_t time, uint32_t button, uint32_t state)
 20+{
 21+    struct swc_pointer * pointer
 22+        = CONTAINER_OF(handler, typeof(*pointer), client_handler);
 23+    uint32_t serial;
 24+
 25+    if (!pointer->focus.resource)
 26+        return false;
 27+
 28+    serial = wl_display_get_serial(swc.display);
 29+    wl_pointer_send_button(pointer->focus.resource, serial, time,
 30+                           button, state);
 31+
 32+    return true;
 33+}
 34+
 35+static bool client_handle_axis(struct swc_pointer_handler * handler,
 36+                               uint32_t time, uint32_t axis, wl_fixed_t amount)
 37+{
 38+    struct swc_pointer * pointer
 39+        = CONTAINER_OF(handler, typeof(*pointer), client_handler);
 40+
 41+    if (!pointer->focus.resource)
 42+        return false;
 43+
 44+    wl_pointer_send_axis(pointer->focus.resource, time, axis, amount);
 45+
 46+    return true;
 47+}
 48+
 49+static bool client_handle_motion(struct swc_pointer_handler * handler,
 50+                                 uint32_t time, wl_fixed_t x, wl_fixed_t y)
 51+{
 52+    struct swc_pointer * pointer
 53+        = CONTAINER_OF(handler, typeof(*pointer), client_handler);
 54+
 55+    if (!pointer->focus.resource)
 56+        return false;
 57+
 58+    wl_pointer_send_motion
 59+        (pointer->focus.resource, time,
 60+         x - wl_fixed_from_int(pointer->focus.surface->view->geometry.x),
 61+         y - wl_fixed_from_int(pointer->focus.surface->view->geometry.y));
 62+
 63+    return true;
 64+}
 65+
 66 bool swc_pointer_initialize(struct swc_pointer * pointer)
 67 {
 68     struct screen * screen;
 69@@ -202,6 +256,12 @@ bool swc_pointer_initialize(struct swc_pointer * pointer)
 70 
 71     pointer->focus_handler.enter = &enter;
 72     pointer->focus_handler.leave = &leave;
 73+    pointer->client_handler.button = &client_handle_button;
 74+    pointer->client_handler.axis = &client_handle_axis;
 75+    pointer->client_handler.motion = &client_handle_motion;
 76+    wl_list_init(&pointer->handlers);
 77+    wl_list_insert(&pointer->handlers, &pointer->client_handler.link);
 78+    wl_array_init(&pointer->buttons);
 79 
 80     swc_view_initialize(&pointer->cursor.view, &view_impl);
 81     pointer->cursor.view_listener.notify = &handle_view_event;
 82@@ -322,51 +382,73 @@ struct wl_resource * swc_pointer_bind(struct swc_pointer * pointer,
 83 }
 84 
 85 void swc_pointer_handle_button(struct swc_pointer * pointer, uint32_t time,
 86-                               uint32_t button, uint32_t state)
 87+                               uint32_t value, uint32_t state)
 88 {
 89-    if ((!pointer->handler || !pointer->handler->button
 90-         || !pointer->handler->button(pointer->handler, time, button, state))
 91-        && pointer->focus.resource)
 92+    struct swc_pointer_handler * handler;
 93+    struct button_press * button;
 94+    uint32_t serial;
 95+
 96+    serial = wl_display_next_serial(swc.display);
 97+
 98+    if (state == WL_POINTER_BUTTON_STATE_RELEASED)
 99     {
100-        struct wl_client * client
101-            = wl_resource_get_client(pointer->focus.resource);
102-        struct wl_display * display = wl_client_get_display(client);
103-        uint32_t serial = wl_display_next_serial(display);
104+        wl_array_for_each(button, &pointer->buttons)
105+        {
106+            if (button->value == value)
107+            {
108+                swc_array_remove(&pointer->buttons, button, sizeof *button);
109 
110-        wl_pointer_send_button(pointer->focus.resource, serial, time,
111-                               button, state);
112+                if (button->handler->button)
113+                {
114+                    button->handler->button(button->handler, time,
115+                                            value, state);
116+                }
117+
118+                break;
119+            }
120+        }
121+    }
122+    else
123+    {
124+        wl_list_for_each(handler, &pointer->handlers, link)
125+        {
126+            if (handler->button && handler->button(handler, time, value, state))
127+            {
128+                button = wl_array_add(&pointer->buttons, sizeof *button);
129+                button->value = value;
130+                button->handler = handler;
131+                break;
132+            }
133+        }
134     }
135 }
136 
137 void swc_pointer_handle_axis(struct swc_pointer * pointer, uint32_t time,
138                              uint32_t axis, wl_fixed_t amount)
139 {
140-    if ((!pointer->handler || !pointer->handler->axis
141-         || !pointer->handler->axis(pointer->handler, time, axis, amount))
142-        && pointer->focus.resource)
143+    struct swc_pointer_handler * handler;
144+
145+    wl_list_for_each(handler, &pointer->handlers, link)
146     {
147-        wl_pointer_send_axis(pointer->focus.resource, time, axis, amount);
148+        if (handler->axis && handler->axis(handler, time, axis, amount))
149+            break;
150     }
151 }
152 
153 void swc_pointer_handle_relative_motion
154     (struct swc_pointer * pointer, uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
155 {
156+    struct swc_pointer_handler * handler;
157+
158     clip_position(pointer, pointer->x + dx, pointer->y + dy);
159 
160-    if ((!pointer->handler || !pointer->handler->motion
161-         || !pointer->handler->motion(pointer->handler, time,
162-                                      pointer->x, pointer->y))
163-        && pointer->focus.resource)
164+    wl_list_for_each(handler, &pointer->handlers, link)
165     {
166-        wl_fixed_t surface_x, surface_y;
167-        surface_x = pointer->x
168-            - wl_fixed_from_int(pointer->focus.surface->view->geometry.x);
169-        surface_y = pointer->y
170-            - wl_fixed_from_int(pointer->focus.surface->view->geometry.y);
171-
172-        wl_pointer_send_motion(pointer->focus.resource, time,
173-                               surface_x, surface_y);
174+        if (handler->motion && handler->motion(handler, time,
175+                                               pointer->x, pointer->y))
176+        {
177+            break;
178+        }
179     }
180 
181     update_cursor(pointer);
+5, -1
 1@@ -41,6 +41,8 @@ struct swc_pointer_handler
 2                     uint32_t button, uint32_t state);
 3     bool (* axis)(struct swc_pointer_handler * handler, uint32_t time,
 4                   enum wl_pointer_axis axis, wl_fixed_t amount);
 5+
 6+    struct wl_list link;
 7 };
 8 
 9 struct swc_pointer
10@@ -65,7 +67,9 @@ struct swc_pointer
11         } hotspot;
12     } cursor;
13 
14-    struct swc_pointer_handler * handler;
15+    struct wl_array buttons;
16+    struct wl_list handlers;
17+    struct swc_pointer_handler client_handler;
18 
19     wl_fixed_t x, y;
20     pixman_region32_t region;
+2, -1
 1@@ -65,7 +65,8 @@ static void setup_compositor()
 2 
 3     wl_list_insert(&swc.seat->keyboard->handlers,
 4                    &swc.bindings->keyboard_handler->link);
 5-    swc.seat->pointer->handler = swc.compositor->pointer_handler;
 6+    wl_list_insert(&swc.seat->pointer->handlers,
 7+                   &swc.compositor->pointer_handler->link);
 8     wl_signal_add(&swc.seat->pointer->focus.event_signal,
 9                   &window_enter_listener);
10