commit 96ab570

Michael Forney  ·  2013-06-21 08:25:49 +0000 UTC
parent 967d141
Separate out input focus related stuff to swc_input
8 files changed,  +297, -140
M seat.c
+1, -0
1@@ -13,6 +13,7 @@ libswc_la_SOURCES = \
2 	surface.c surface.h \
3 	region.c region.h \
4 	renderer.c renderer.h \
5+	input.c input.h \
6 	keyboard.c keyboard.h \
7 	pointer.c pointer.h \
8 	seat.c seat.h \
+108, -0
  1@@ -0,0 +1,108 @@
  2+#include "input.h"
  3+#include "surface.h"
  4+
  5+#include <assert.h>
  6+
  7+#include "util.h"
  8+
  9+static inline void focus(struct swc_input * input,
 10+                         struct swc_surface * surface,
 11+                         struct wl_resource * resource)
 12+{
 13+    if (resource)
 14+    {
 15+        input->handler->enter(input->handler, resource, surface);
 16+    }
 17+
 18+    input->focus.surface = surface;
 19+    input->focus.resource = resource;
 20+}
 21+
 22+static inline void unfocus(struct swc_input * input)
 23+{
 24+    if (input->focus.resource)
 25+    {
 26+        input->handler->leave(input->handler, input->focus.resource,
 27+                              input->focus.surface);
 28+    }
 29+}
 30+
 31+bool swc_input_initialize(struct swc_input * input,
 32+                          struct swc_input_handler * handler)
 33+{
 34+    input->focus.resource = NULL;
 35+    input->focus.surface = NULL;
 36+    input->handler = handler;
 37+
 38+    wl_list_init(&input->resources);
 39+
 40+    return true;
 41+}
 42+
 43+void swc_input_finish(struct swc_input * input)
 44+{
 45+    /* XXX: Destroy resources? */
 46+}
 47+
 48+void swc_input_add_resource(struct swc_input * input,
 49+                            struct wl_resource * resource)
 50+{
 51+    /* If this new input resource corresponds to our focus, set it as our
 52+     * focus. */
 53+    if (input->focus.surface)
 54+    {
 55+        struct wl_client * client, * surface_client;
 56+
 57+        client = wl_resource_get_client(resource);
 58+        surface_client = wl_resource_get_client(input->focus.surface->resource);
 59+
 60+        if (client == surface_client)
 61+        {
 62+            unfocus(input);
 63+            focus(input, input->focus.surface, resource);
 64+        }
 65+    }
 66+
 67+    wl_list_insert(&input->resources, wl_resource_get_link(resource));
 68+}
 69+
 70+void swc_input_remove_resource(struct swc_input * input,
 71+                               struct wl_resource * resource)
 72+{
 73+    if (resource == input->focus.resource)
 74+        input->focus.resource = NULL;
 75+
 76+    swc_remove_resource(resource);
 77+}
 78+
 79+void swc_input_set_focus(struct swc_input * input,
 80+                         struct swc_surface * surface)
 81+{
 82+    struct wl_client * client;
 83+    struct wl_display * display;
 84+    struct wl_resource * resource;
 85+    uint32_t serial;
 86+
 87+    if (surface == input->focus.surface)
 88+        return;
 89+
 90+    /* Unfocus previously focused surface. */
 91+    unfocus(input);
 92+
 93+    /* Focus new surface, if given. */
 94+    if (surface)
 95+    {
 96+        client = wl_resource_get_client(surface->resource);
 97+        resource = wl_resource_find_for_client(&input->resources, client);
 98+
 99+        focus(input, surface, resource);
100+    }
101+    else
102+    {
103+        input->focus.surface = NULL;
104+        input->focus.resource = NULL;
105+    }
106+
107+    return;
108+}
109+
+46, -0
 1@@ -0,0 +1,46 @@
 2+#ifndef SWC_INPUT_H
 3+#define SWC_INPUT_H 1
 4+
 5+#include <stdbool.h>
 6+#include <wayland-server.h>
 7+
 8+struct swc_surface;
 9+
10+struct swc_input_handler
11+{
12+    void (* enter)(struct swc_input_handler * handler,
13+                   struct wl_resource * resource,
14+                   struct swc_surface * surface);
15+    void (* leave)(struct swc_input_handler * handler,
16+                   struct wl_resource * resource,
17+                   struct swc_surface * surface);
18+};
19+
20+struct swc_input
21+{
22+    struct
23+    {
24+        struct wl_resource * resource;
25+        struct swc_surface * surface;
26+    } focus;
27+
28+    struct swc_input_handler * handler;
29+    struct wl_list resources;
30+};
31+
32+bool swc_input_initialize(struct swc_input * input,
33+                          struct swc_input_handler * input_handler);
34+
35+void swc_input_finish(struct swc_input * input);
36+
37+void swc_input_add_resource(struct swc_input * input,
38+                            struct wl_resource * resource);
39+
40+void swc_input_remove_resource(struct swc_input * input,
41+                               struct wl_resource * resource);
42+
43+void swc_input_set_focus(struct swc_input * input,
44+                         struct swc_surface * surface);
45+
46+#endif
47+
+49, -50
  1@@ -3,14 +3,45 @@
  2 
  3 #include <stdio.h>
  4 
  5+static void enter(struct swc_input_handler * handler,
  6+                  struct wl_resource * resource, struct swc_surface * surface)
  7+{
  8+    struct swc_keyboard * keyboard;
  9+    struct wl_client * client;
 10+    struct wl_display * display;
 11+    uint32_t serial;
 12+
 13+    keyboard = wl_container_of(handler, keyboard, input_handler);
 14+    client = wl_resource_get_client(resource);
 15+    display = wl_client_get_display(client);
 16+    serial = wl_display_next_serial(display);
 17+
 18+    wl_keyboard_send_enter(resource, serial, surface->resource,
 19+                           &keyboard->keys);
 20+}
 21+
 22+static void leave(struct swc_input_handler * handler,
 23+                  struct wl_resource * resource, struct swc_surface * surface)
 24+{
 25+    struct wl_client * client;
 26+    struct wl_display * display;
 27+    uint32_t serial;
 28+
 29+    client = wl_resource_get_client(resource);
 30+    display = wl_client_get_display(client);
 31+    serial = wl_display_next_serial(display);
 32+
 33+    wl_keyboard_send_leave(resource, serial, surface->resource);
 34+}
 35+
 36 bool swc_keyboard_initialize(struct swc_keyboard * keyboard)
 37 {
 38-    wl_list_init(&keyboard->resources);
 39     wl_array_init(&keyboard->keys);
 40-    //wl_signal_init(&keyboard->focus_signal); // ?
 41 
 42-    keyboard->focus.surface = NULL;
 43-    keyboard->focus.resource = NULL;
 44+    keyboard->input_handler.enter = &enter;
 45+    keyboard->input_handler.leave = &leave;
 46+
 47+    swc_input_initialize(&keyboard->input, &keyboard->input_handler);
 48 
 49     return true;
 50 }
 51@@ -18,53 +49,23 @@ bool swc_keyboard_initialize(struct swc_keyboard * keyboard)
 52 void swc_keyboard_finish(struct swc_keyboard * keyboard)
 53 {
 54     wl_array_release(&keyboard->keys);
 55+    swc_input_finish(&keyboard->input);
 56 }
 57 
 58+/**
 59+ * Sets the focus of the keyboard to the specified surface.
 60+ */
 61 void swc_keyboard_set_focus(struct swc_keyboard * keyboard,
 62                             struct swc_surface * surface)
 63 {
 64-    struct wl_client * client;
 65-    struct wl_display * display;
 66-    struct wl_resource * resource;
 67-    uint32_t serial;
 68+    swc_input_set_focus(&keyboard->input, surface);
 69+}
 70 
 71-    /* Unfocus previously focused surface. */
 72-    if (keyboard->focus.resource && keyboard->focus.surface != surface)
 73-    {
 74-        client = wl_resource_get_client(keyboard->focus.surface->resource);
 75-        display = wl_client_get_display(client);
 76-        serial = wl_display_next_serial(display);
 77-        wl_keyboard_send_leave(keyboard->focus.resource, serial,
 78-                               keyboard->focus.surface->resource);
 79-    }
 80-
 81-    /* Focus new surface, if given. */
 82-    if (surface)
 83-    {
 84-        client = wl_resource_get_client(surface->resource);
 85-        resource = wl_resource_find_for_client(&keyboard->resources, client);
 86-
 87-        printf("keyboard: focusing surface: %p\n", surface);
 88-
 89-        if (resource)
 90-        {
 91-            display = wl_client_get_display(client);
 92-            serial = wl_display_next_serial(display);
 93-            wl_keyboard_send_enter(resource, serial, surface->resource,
 94-                                   &keyboard->keys);
 95-
 96-            keyboard->focus.resource = resource;
 97-        }
 98-        else
 99-            keyboard->focus.resource = NULL;
100-
101-        keyboard->focus.surface = surface;
102-    }
103-    else
104-    {
105-        keyboard->focus.surface = NULL;
106-        keyboard->focus.resource = NULL;
107-    }
108+static void unbind(struct wl_resource * resource)
109+{
110+    struct swc_keyboard * keyboard = wl_resource_get_user_data(resource);
111+
112+    swc_input_remove_resource(&keyboard->input, resource);
113 }
114 
115 struct wl_resource * swc_keyboard_bind(struct swc_keyboard * keyboard,
116@@ -73,11 +74,9 @@ struct wl_resource * swc_keyboard_bind(struct swc_keyboard * keyboard,
117     struct wl_resource * client_resource;
118 
119     client_resource = wl_client_add_object(client, &wl_keyboard_interface,
120-                                           NULL, id, NULL);
121-    wl_resource_set_destructor(client_resource, &swc_remove_resource);
122-    wl_list_insert(&keyboard->resources, wl_resource_get_link(client_resource));
123-
124-    printf("keyboard: adding client %p, resource: %p\n", client, client_resource);
125+                                           NULL, id, keyboard);
126+    wl_resource_set_destructor(client_resource, &unbind);
127+    swc_input_add_resource(&keyboard->input, client_resource);
128 
129     return client_resource;
130 }
+3, -10
 1@@ -2,6 +2,7 @@
 2 #define SWC_KEYBOARD_H 1
 3 
 4 #include "surface.h"
 5+#include "input.h"
 6 
 7 #include <wayland-server.h>
 8 
 9@@ -18,16 +19,8 @@ struct swc_keyboard_handler
10 
11 struct swc_keyboard
12 {
13-    struct wl_list resources;
14-
15-    struct
16-    {
17-        struct swc_surface * surface;
18-        struct wl_resource * resource;
19-    } focus;
20-
21-    //struct wl_listener focus_listener;
22-    //struct wl_signal focus_signal;
23+    struct swc_input input;
24+    struct swc_input_handler input_handler;
25 
26     struct swc_keyboard_handler * handler;
27 
+76, -49
  1@@ -4,73 +4,94 @@
  2 
  3 #include <stdio.h>
  4 
  5+static void enter(struct swc_input_handler * handler,
  6+                  struct wl_resource * resource, struct swc_surface * surface)
  7+{
  8+    struct swc_pointer * pointer;
  9+    struct wl_client * client;
 10+    struct wl_display * display;
 11+    uint32_t serial;
 12+    wl_fixed_t surface_x, surface_y;
 13+
 14+    pointer = wl_container_of(handler, pointer, input_handler);
 15+    client = wl_resource_get_client(resource);
 16+    display = wl_client_get_display(client);
 17+    serial = wl_display_next_serial(display);
 18+
 19+    surface_x = pointer->x - wl_fixed_from_int(surface->geometry.x);
 20+    surface_y = pointer->y - wl_fixed_from_int(surface->geometry.y);
 21+
 22+    printf("-> pointer.enter: %p (%d, %d)\n", resource, surface_x, surface_y);
 23+    wl_pointer_send_enter(resource, serial, surface->resource,
 24+                          surface_x, surface_y);
 25+}
 26+
 27+static void leave(struct swc_input_handler * handler,
 28+                  struct wl_resource * resource, struct swc_surface * surface)
 29+{
 30+    struct wl_client * client;
 31+    struct wl_display * display;
 32+    uint32_t serial;
 33+
 34+    client = wl_resource_get_client(resource);
 35+    display = wl_client_get_display(client);
 36+    serial = wl_display_next_serial(display);
 37+
 38+    printf("-> pointer.leave: %p\n", resource);
 39+    wl_pointer_send_leave(resource, serial, surface->resource);
 40+}
 41+
 42+static void handle_focus_surface_destroy(struct wl_listener * listener,
 43+                                         void * data)
 44+{
 45+    struct swc_pointer * pointer;
 46+
 47+    pointer = wl_container_of(listener, pointer,
 48+                              focus_surface_destroy_listener);
 49+
 50+    pointer->input.focus.surface = NULL;
 51+}
 52+
 53 bool swc_pointer_initialize(struct swc_pointer * pointer)
 54 {
 55-    wl_list_init(&pointer->resources);
 56     wl_signal_init(&pointer->event_signal);
 57 
 58     pointer->x = wl_fixed_from_int(0);
 59     pointer->y = wl_fixed_from_int(0);
 60 
 61-    pointer->focus.surface = NULL;
 62-    pointer->focus.resource = NULL;
 63+    pointer->input_handler.enter = &enter;
 64+    pointer->input_handler.leave = &leave;
 65+
 66+    pointer->focus_surface_destroy_listener.notify
 67+        = &handle_focus_surface_destroy;
 68+
 69+    swc_input_initialize(&pointer->input, &pointer->input_handler);
 70 
 71     return true;
 72 }
 73 
 74 void swc_pointer_finish(struct swc_pointer * pointer)
 75 {
 76+    swc_input_finish(&pointer->input);
 77 }
 78 
 79+/**
 80+ * Sets the focus of the pointer to the specified surface.
 81+ */
 82 void swc_pointer_set_focus(struct swc_pointer * pointer,
 83                            struct swc_surface * surface)
 84 {
 85-    struct wl_client * client;
 86-    struct wl_display * display;
 87-    struct wl_resource * resource;
 88-    uint32_t serial;
 89-
 90-    /* Unfocus previously focused surface. */
 91-    if (pointer->focus.resource && pointer->focus.surface != surface)
 92+    if (surface != pointer->input.focus.surface)
 93     {
 94-        client = wl_resource_get_client(pointer->focus.surface->resource);
 95-        display = wl_client_get_display(client);
 96-        serial = wl_display_next_serial(display);
 97-        wl_pointer_send_leave(pointer->focus.resource, serial,
 98-                               pointer->focus.surface->resource);
 99-    }
100-
101-    /* Focus new surface, if given. */
102-    if (surface)
103-    {
104-        client = wl_resource_get_client(surface->resource);
105-        resource = wl_resource_find_for_client(&pointer->resources, client);
106-
107-        printf("pointer: focusing surface: %p\n", surface);
108-
109-        if (resource)
110-        {
111-            uint32_t surface_x, surface_y;
112+        if (pointer->input.focus.surface)
113+            wl_list_remove(&pointer->focus_surface_destroy_listener.link);
114 
115-            surface_x = wl_fixed_to_int(pointer->x) - surface->geometry.x;
116-            surface_y = wl_fixed_to_int(pointer->y) - surface->geometry.y;
117-
118-            display = wl_client_get_display(client);
119-            serial = wl_display_next_serial(display);
120-            wl_pointer_send_enter(resource, serial, surface->resource,
121-                                  wl_fixed_from_int(surface_x),
122-                                  wl_fixed_from_int(surface_y));
123-
124-            pointer->focus.resource = resource;
125-        }
126-
127-        pointer->focus.surface = surface;
128-    }
129-    else
130-    {
131-        pointer->focus.surface = NULL;
132-        pointer->focus.resource = NULL;
133+        if (surface)
134+            wl_resource_add_destroy_listener
135+                (surface->resource, &pointer->focus_surface_destroy_listener);
136     }
137+
138+    swc_input_set_focus(&pointer->input, surface);
139 }
140 
141 static void set_cursor(struct wl_client * client,
142@@ -98,6 +119,13 @@ struct wl_pointer_interface pointer_implementation = {
143     .set_cursor = &set_cursor
144 };
145 
146+static void unbind(struct wl_resource * resource)
147+{
148+    struct swc_pointer * pointer = wl_resource_get_user_data(resource);
149+
150+    swc_input_remove_resource(&pointer->input, resource);
151+}
152+
153 struct wl_resource * swc_pointer_bind(struct swc_pointer * pointer,
154                                       struct wl_client * client, uint32_t id)
155 {
156@@ -107,9 +135,8 @@ struct wl_resource * swc_pointer_bind(struct swc_pointer * pointer,
157 
158     client_resource = wl_client_add_object(client, &wl_pointer_interface,
159                                            &pointer_implementation, id, pointer);
160-    wl_resource_set_destructor(client_resource, &swc_remove_resource);
161-    wl_list_insert(&pointer->resources,
162-                   wl_resource_get_user_data(client_resource));
163+    wl_resource_set_destructor(client_resource, &unbind);
164+    swc_input_add_resource(&pointer->input, client_resource);
165 
166     return client_resource;
167 }
+4, -9
 1@@ -2,6 +2,7 @@
 2 #define SWC_POINTER_H 1
 3 
 4 #include "surface.h"
 5+#include "input.h"
 6 
 7 #include <wayland-server.h>
 8 
 9@@ -22,16 +23,10 @@ enum swc_pointer_event
10 
11 struct swc_pointer
12 {
13-    struct wl_list resources;
14+    struct swc_input input;
15+    struct swc_input_handler input_handler;
16+    struct wl_listener focus_surface_destroy_listener;
17 
18-    struct
19-    {
20-        struct swc_surface * surface;
21-        struct wl_resource * resource;
22-    } focus;
23-
24-    //uint32_t focus_serial;
25-    //struct wl_signal focus_signal;
26     struct wl_signal event_signal;
27 
28     struct
M seat.c
+10, -22
 1@@ -27,11 +27,11 @@ static void handle_key(struct swc_seat * seat, uint32_t time, uint32_t key,
 2     uint32_t serial;
 3     enum xkb_key_direction direction;
 4 
 5-    if (keyboard->focus.resource)
 6+    if (keyboard->input.focus.resource)
 7     {
 8-        struct wl_client * focus_client
 9-            = wl_resource_get_client(keyboard->focus.resource);
10-        display = wl_client_get_display(focus_client);
11+        struct wl_client * client
12+            = wl_resource_get_client(keyboard->input.focus.resource);
13+        display = wl_client_get_display(client);
14     }
15 
16     /* Update keyboard state state */
17@@ -70,10 +70,11 @@ static void handle_key(struct swc_seat * seat, uint32_t time, uint32_t key,
18     if (!(keyboard->handler && keyboard->handler->key)
19         || !keyboard->handler->key(keyboard, time, key, state))
20     {
21-        if (keyboard->focus.resource)
22+        if (keyboard->input.focus.resource)
23         {
24             serial = wl_display_next_serial(display);
25-            wl_keyboard_send_key(keyboard->focus.resource, serial, time, key, state);
26+            wl_keyboard_send_key(keyboard->input.focus.resource, serial, time,
27+                                 key, state);
28 
29             if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
30                 printf("\t-> sent to client\n");
31@@ -101,11 +102,11 @@ static void handle_key(struct swc_seat * seat, uint32_t time, uint32_t key,
32             || mods_locked != keyboard->modifiers.mods_locked
33             || group != keyboard->modifiers.group)
34         {
35-            if (keyboard->focus.resource)
36+            if (keyboard->input.focus.resource)
37             {
38                 serial = wl_display_next_serial(display);
39-                wl_keyboard_send_modifiers(keyboard->focus.resource, serial,
40-                                           mods_depressed, mods_latched,
41+                wl_keyboard_send_modifiers(keyboard->input.focus.resource,
42+                                           serial, mods_depressed, mods_latched,
43                                            mods_locked, group);
44             }
45         }
46@@ -163,12 +164,6 @@ static void get_pointer(struct wl_client * client, struct wl_resource * resource
47     struct swc_pointer * pointer = &seat->pointer;
48 
49     swc_pointer_bind(pointer, client, id);
50-
51-    if (pointer->focus.surface
52-        && wl_resource_get_client(pointer->focus.surface->resource) == client)
53-    {
54-        swc_pointer_set_focus(pointer, pointer->focus.surface);
55-    }
56 }
57 
58 static void get_keyboard(struct wl_client * client, struct wl_resource * resource,
59@@ -182,13 +177,6 @@ static void get_keyboard(struct wl_client * client, struct wl_resource * resourc
60 
61     wl_keyboard_send_keymap(client_resource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
62                             seat->xkb.keymap.fd, seat->xkb.keymap.size);
63-
64-    if (keyboard->focus.surface
65-        && wl_resource_get_client(keyboard->focus.surface->resource) == client)
66-    {
67-        printf("focusing\n");
68-        swc_keyboard_set_focus(keyboard, keyboard->focus.surface);
69-    }
70 }
71 
72 static void get_touch(struct wl_client * client, struct wl_resource * resource,