]> Pileus Git - ~andy/gtk/blob - gdk/wayland/gdkdevicemanager-wayland.c
5c9a3b348ec9e66c577e3fd6303ccb43c4541291
[~andy/gtk] / gdk / wayland / gdkdevicemanager-wayland.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "config.h"
21
22 #include <string.h>
23 #include <gdk/gdktypes.h>
24 #include <gdk/gdkdevicemanager.h>
25 #include "gdkdevicemanager-wayland.h"
26 #include "gdkdevice-wayland.h"
27 #include "gdkkeysyms.h"
28 #include "gdkprivate-wayland.h"
29
30 #include <X11/extensions/XKBcommon.h>
31 #include <X11/keysym.h>
32
33 static void    gdk_device_manager_core_finalize    (GObject *object);
34
35 static GList * gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager,
36                                                      GdkDeviceType     type);
37 static GdkDevice * gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager);
38
39 G_DEFINE_TYPE (GdkDeviceManagerCore, gdk_device_manager_core, GDK_TYPE_DEVICE_MANAGER)
40
41 static void
42 gdk_device_manager_core_class_init (GdkDeviceManagerCoreClass *klass)
43 {
44   GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
45   GObjectClass *object_class = G_OBJECT_CLASS (klass);
46
47   object_class->finalize = gdk_device_manager_core_finalize;
48   device_manager_class->list_devices = gdk_device_manager_core_list_devices;
49   device_manager_class->get_client_pointer = gdk_device_manager_core_get_client_pointer;
50 }
51
52 static void
53 input_handle_motion(void *data, struct wl_input_device *input_device,
54                     uint32_t time,
55                     int32_t x, int32_t y, int32_t sx, int32_t sy)
56 {
57   GdkWaylandDevice *device = data;
58   GdkEvent *event;
59
60   event = gdk_event_new (GDK_NOTHING);
61
62   device->time = time;
63   device->x = x;
64   device->y = y;
65   device->surface_x = sx;
66   device->surface_y = sy;
67
68   event->motion.type = GDK_MOTION_NOTIFY;
69   event->motion.window = g_object_ref (device->pointer_focus);
70   gdk_event_set_device (event, device->pointer);
71   event->motion.time = time;
72   event->motion.x = (gdouble) sx;
73   event->motion.y = (gdouble) sy;
74   event->motion.x_root = (gdouble) x;
75   event->motion.y_root = (gdouble) y;
76   event->motion.axes = NULL;
77   event->motion.state = device->modifiers;
78   event->motion.is_hint = 0;
79
80   _gdk_wayland_display_deliver_event (device->display, event);
81 }
82
83 static void
84 input_handle_button(void *data, struct wl_input_device *input_device,
85                      uint32_t time, uint32_t button, uint32_t state)
86 {
87   GdkWaylandDevice *device = data;
88   GdkEvent *event;
89   uint32_t modifier;
90
91   fprintf (stderr, "button event %d, state %d\n", button, state);
92
93   device->time = time;
94   event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
95   event->button.window = g_object_ref (device->pointer_focus);
96   gdk_event_set_device (event, device->pointer);
97   event->button.time = time;
98   event->button.x = (gdouble) device->surface_x;
99   event->button.y = (gdouble) device->surface_y;
100   event->button.x_root = (gdouble) device->x;
101   event->button.y_root = (gdouble) device->y;
102   event->button.axes = NULL;
103   event->button.state = device->modifiers;
104   event->button.button = button - 271;
105
106   modifier = 1 << (8 + button - 272);
107   if (state)
108     device->modifiers |= modifier;
109   else
110     device->modifiers &= ~modifier;
111
112   _gdk_wayland_display_deliver_event (device->display, event);
113 }
114
115 static void
116 input_handle_key(void *data, struct wl_input_device *input_device,
117                  uint32_t time, uint32_t key, uint32_t state)
118 {
119   GdkWaylandDevice *device = data;
120   GdkEvent *event;
121   uint32_t code, modifier, level;
122   struct xkb_desc *xkb;
123   GdkKeymap *keymap;
124
125   device->time = time;
126   event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
127   event->key.window = g_object_ref (device->keyboard_focus);
128   gdk_event_set_device (event, device->keyboard);
129   event->button.time = time;
130   event->key.state = device->modifiers;
131   event->key.group = 0;
132   event->key.hardware_keycode = key;
133
134   keymap = gdk_keymap_get_for_display (device->display);
135   xkb = _gdk_wayland_keymap_get_xkb_desc (keymap);
136
137   code = key + xkb->min_key_code;
138
139   level = 0;
140   if (device->modifiers & XKB_COMMON_SHIFT_MASK &&
141       XkbKeyGroupWidth(xkb, code, 0) > 1)
142     level = 1;
143
144   event->key.keyval = XkbKeySymEntry(xkb, code, level, 0);
145
146   modifier = xkb->map->modmap[code];
147   if (state)
148     device->modifiers |= modifier;
149   else
150     device->modifiers &= ~modifier;
151
152   event->key.is_modifier = modifier > 0;
153
154   if (event->key.keyval == GDK_KEY_Escape)
155     {
156       event->key.length = 1;
157       event->key.string = g_strdup ("\033");
158     }
159   else if (event->key.keyval == GDK_KEY_Return ||
160            event->key.keyval == GDK_KEY_KP_Enter)
161     {
162       event->key.length = 1;
163       event->key.string = g_strdup ("\r");
164     }
165   else if (event->key.state & GDK_CONTROL_MASK)
166     {
167       gsize bytes_written;
168       gint len;
169       gchar buf[7];
170       int c = event->key.keyval;
171
172       /* Apply the control key - Taken from Xlib */
173       if ((c >= XK_at && c < '\177') || c == ' ')
174         c &= 0x1F;
175       else if (c == XK_2)
176         {
177           event->key.string = g_memdup ("\0\0", 2);
178           event->key.length = 1;
179           buf[0] = '\0';
180           goto out;
181         }
182       else if (c >= XK_3 && c <= XK_7)
183         c -= (XK_3 - '\033');
184       else if (c == XK_8)
185         c = '\177';
186       else if (c == XK_slash)
187         c = '_' & 0x1F;
188
189       len = g_unichar_to_utf8 (c, buf);
190       buf[len] = '\0';
191
192       event->key.string = g_locale_from_utf8 (buf, len,
193                                               NULL, &bytes_written,
194                                               NULL);
195       if (event->key.string)
196         event->key.length = bytes_written;
197     }
198   else
199     {
200       char buffer[128];
201       xkb_keysym_to_string(event->key.keyval, buffer, sizeof buffer);
202       event->key.string = g_strdup (buffer);
203       event->key.length = strlen(event->key.string);
204     }
205
206  out:
207   _gdk_wayland_display_deliver_event (device->display, event);
208
209   fprintf (stderr, "keyboard event, code %d, sym %d, string %s, mods 0x%x\n",
210            code, event->key.keyval, event->key.string, event->key.state);
211 }
212
213 static void
214 input_handle_pointer_focus(void *data,
215                            struct wl_input_device *input_device,
216                            uint32_t time, struct wl_surface *surface,
217                            int32_t x, int32_t y, int32_t sx, int32_t sy)
218 {
219   GdkWaylandDevice *device = data;
220   GdkEvent *event;
221
222   device->time = time;
223   if (device->pointer_focus)
224     {
225       event = gdk_event_new (GDK_LEAVE_NOTIFY);
226       event->crossing.window = g_object_ref (device->pointer_focus);
227       gdk_event_set_device (event, device->pointer);
228       event->crossing.subwindow = NULL;
229       event->crossing.time = time;
230       event->crossing.x = (gdouble) device->surface_x;
231       event->crossing.y = (gdouble) device->surface_y;
232       event->crossing.x_root = (gdouble) device->x;
233       event->crossing.y_root = (gdouble) device->y;
234
235       event->crossing.mode = GDK_CROSSING_NORMAL;
236       event->crossing.detail = GDK_NOTIFY_ANCESTOR;
237       event->crossing.focus = TRUE;
238       event->crossing.state = 0;
239
240       _gdk_wayland_display_deliver_event (device->display, event);
241
242       g_object_unref(device->pointer_focus);
243       device->pointer_focus = NULL;
244     }
245
246   if (surface)
247     {
248       device->pointer_focus = wl_surface_get_user_data(surface);
249       g_object_ref(device->pointer_focus);
250
251       event = gdk_event_new (GDK_ENTER_NOTIFY);
252       event->crossing.window = g_object_ref (device->pointer_focus);
253       gdk_event_set_device (event, device->pointer);
254       event->crossing.subwindow = NULL;
255       event->crossing.time = time;
256       event->crossing.x = (gdouble) sx;
257       event->crossing.y = (gdouble) sy;
258       event->crossing.x_root = (gdouble) x;
259       event->crossing.y_root = (gdouble) y;
260
261       event->crossing.mode = GDK_CROSSING_NORMAL;
262       event->crossing.detail = GDK_NOTIFY_ANCESTOR;
263       event->crossing.focus = TRUE;
264       event->crossing.state = 0;
265
266       device->surface_x = sx;
267       device->surface_y = sy;
268       device->x = x;
269       device->y = y;
270
271       _gdk_wayland_display_deliver_event (device->display, event);
272     }
273
274   fprintf (stderr, "pointer focus surface %p, window %p\n",
275            surface, device->pointer_focus);
276 }
277
278 static void
279 update_modifiers(GdkWaylandDevice *device, struct wl_array *keys)
280 {
281   uint32_t *k, *end;
282   GdkKeymap *keymap;
283   struct xkb_desc *xkb;
284
285   keymap = gdk_keymap_get_for_display (device->display);
286   xkb = _gdk_wayland_keymap_get_xkb_desc (keymap);
287
288   end = keys->data + keys->size;
289   for (k = keys->data; k < end; k++)
290     device->modifiers |= xkb->map->modmap[*k];
291
292   fprintf (stderr, "modifiers: 0x%x\n", device->modifiers);
293 }
294
295 static void
296 input_handle_keyboard_focus(void *data,
297                             struct wl_input_device *input_device,
298                             uint32_t time,
299                             struct wl_surface *surface,
300                             struct wl_array *keys)
301 {
302   GdkWaylandDevice *device = data;
303   GdkEvent *event;
304
305   fprintf (stderr, "keyboard focus surface %p\n", surface);
306
307   device->time = time;
308   if (device->keyboard_focus)
309     {
310       event = gdk_event_new (GDK_FOCUS_CHANGE);
311       event->focus_change.window = g_object_ref (device->keyboard_focus);
312       event->focus_change.send_event = FALSE;
313       event->focus_change.in = FALSE;
314       gdk_event_set_device (event, device->keyboard);
315
316       g_object_unref(device->pointer_focus);
317       device->keyboard_focus = NULL;
318
319       _gdk_wayland_display_deliver_event (device->display, event);
320     }
321
322   if (surface)
323     {
324       device->keyboard_focus = wl_surface_get_user_data(surface);
325       g_object_ref(device->keyboard_focus);
326
327       event = gdk_event_new (GDK_FOCUS_CHANGE);
328       event->focus_change.window = g_object_ref (device->keyboard_focus);
329       event->focus_change.send_event = FALSE;
330       event->focus_change.in = TRUE;
331       gdk_event_set_device (event, device->keyboard);
332
333       update_modifiers (device, keys);
334
335       _gdk_wayland_display_deliver_event (device->display, event);
336     }
337 }
338
339 static const struct wl_input_device_listener input_device_listener = {
340         input_handle_motion,
341         input_handle_button,
342         input_handle_key,
343         input_handle_pointer_focus,
344         input_handle_keyboard_focus,
345 };
346
347 void
348 gdk_device_manager_core_add_device (GdkDeviceManager *device_manager,
349                                     struct wl_input_device *wl_device)
350 {
351   GdkDisplay *display;
352   GdkDeviceManagerCore *device_manager_core =
353     GDK_DEVICE_MANAGER_CORE(device_manager);
354   GdkWaylandDevice *device;
355
356   device = g_new0 (GdkWaylandDevice, 1);
357   display = gdk_device_manager_get_display (device_manager);
358
359   device->display = display;
360   device->pointer = g_object_new (GDK_TYPE_DEVICE_CORE,
361                                   "name", "Core Pointer",
362                                   "type", GDK_DEVICE_TYPE_MASTER,
363                                   "input-source", GDK_SOURCE_MOUSE,
364                                   "input-mode", GDK_MODE_SCREEN,
365                                   "has-cursor", TRUE,
366                                   "display", display,
367                                   "device-manager", device_manager,
368                                   NULL);
369
370   device->keyboard = g_object_new (GDK_TYPE_DEVICE_CORE,
371                                    "name", "Core Keyboard",
372                                    "type", GDK_DEVICE_TYPE_MASTER,
373                                    "input-source", GDK_SOURCE_KEYBOARD,
374                                    "input-mode", GDK_MODE_SCREEN,
375                                    "has-cursor", FALSE,
376                                    "display", display,
377                                    "device-manager", device_manager,
378                                    NULL);
379
380   GDK_DEVICE_CORE (device->pointer)->device = device;
381   GDK_DEVICE_CORE (device->keyboard)->device = device;
382   device->device = wl_device;
383
384   wl_input_device_add_listener(device->device,
385                                &input_device_listener, device);
386
387   device_manager_core->devices =
388     g_list_prepend (device_manager_core->devices, device->keyboard);
389   device_manager_core->devices =
390     g_list_prepend (device_manager_core->devices, device->pointer);
391
392   _gdk_device_set_associated_device (device->pointer, device->keyboard);
393   _gdk_device_set_associated_device (device->keyboard, device->pointer);
394 }
395
396 static void
397 gdk_device_manager_core_init (GdkDeviceManagerCore *device_manager)
398 {
399 }
400
401 static void
402 free_device (void *data, void *user_data)
403 {
404   g_object_unref (data);
405 }
406
407 static void
408 gdk_device_manager_core_finalize (GObject *object)
409 {
410   GdkDeviceManagerCore *device_manager_core;
411
412   device_manager_core = GDK_DEVICE_MANAGER_CORE (object);
413
414   g_list_foreach (device_manager_core->devices, free_device, NULL);
415   g_list_free (device_manager_core->devices);
416
417   G_OBJECT_CLASS (gdk_device_manager_core_parent_class)->finalize (object);
418 }
419
420 static GList *
421 gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager,
422                                       GdkDeviceType     type)
423 {
424   GdkDeviceManagerCore *device_manager_core;
425   GList *devices = NULL;
426
427   if (type == GDK_DEVICE_TYPE_MASTER)
428     {
429       device_manager_core = (GdkDeviceManagerCore *) device_manager;
430       devices = g_list_copy(device_manager_core->devices);
431     }
432
433   return devices;
434 }
435
436 static GdkDevice *
437 gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager)
438 {
439   GdkDeviceManagerCore *device_manager_core;
440
441   device_manager_core = (GdkDeviceManagerCore *) device_manager;
442   return device_manager_core->devices->data;
443 }
444
445 GdkDeviceManager *
446 _gdk_device_manager_new (GdkDisplay *display)
447 {
448   return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE,
449                        "display", display,
450                        NULL);
451 }