diff --git a/gdk/wayland/Makefile.am b/gdk/wayland/Makefile.am index e39bcb003c..3466311853 100644 --- a/gdk/wayland/Makefile.am +++ b/gdk/wayland/Makefile.am @@ -20,10 +20,7 @@ noinst_LTLIBRARIES = \ libgdk_wayland_la_SOURCES = \ gdkapplaunchcontext-wayland.c \ gdkcursor-wayland.c \ - gdkdevice-wayland.h \ gdkdevice-wayland.c \ - gdkdevicemanager-wayland.h \ - gdkdevicemanager-wayland.c \ gdkdisplay-wayland.c \ gdkdisplay-wayland.h \ gdkdisplaymanager-wayland.c \ diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index c46ca1c29a..a2bc8e520b 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -19,84 +19,81 @@ #include "config.h" +#include #include -#include "gdkdevice-wayland.h" +#include #include "gdkprivate-wayland.h" #include "gdkwayland.h" +#include "gdkkeysyms.h" +#include "gdkdeviceprivate.h" +#include "gdkdevicemanagerprivate.h" +#include "gdkprivate-wayland.h" -static gboolean gdk_device_core_get_history (GdkDevice *device, - GdkWindow *window, - guint32 start, - guint32 stop, - GdkTimeCoord ***events, - gint *n_events); -static void gdk_device_core_get_state (GdkDevice *device, - GdkWindow *window, - gdouble *axes, - GdkModifierType *mask); -static void gdk_device_core_set_window_cursor (GdkDevice *device, - GdkWindow *window, - GdkCursor *cursor); -static void gdk_device_core_warp (GdkDevice *device, - GdkScreen *screen, - gint x, - gint y); -static gboolean gdk_device_core_query_state (GdkDevice *device, - GdkWindow *window, - GdkWindow **root_window, - GdkWindow **child_window, - gint *root_x, - gint *root_y, - gint *win_x, - gint *win_y, - GdkModifierType *mask); -static GdkGrabStatus gdk_device_core_grab (GdkDevice *device, - GdkWindow *window, - gboolean owner_events, - GdkEventMask event_mask, - GdkWindow *confine_to, - GdkCursor *cursor, - guint32 time_); -static void gdk_device_core_ungrab (GdkDevice *device, - guint32 time_); -static GdkWindow * gdk_device_core_window_at_position (GdkDevice *device, - gint *win_x, - gint *win_y, - GdkModifierType *mask, - gboolean get_toplevel); -static void gdk_device_core_select_window_events (GdkDevice *device, - GdkWindow *window, - GdkEventMask event_mask); +#include +#include +#define GDK_TYPE_DEVICE_CORE (gdk_device_core_get_type ()) +#define GDK_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCore)) +#define GDK_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass)) +#define GDK_IS_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_CORE)) +#define GDK_IS_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_CORE)) +#define GDK_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass)) + +typedef struct _GdkDeviceCore GdkDeviceCore; +typedef struct _GdkDeviceCoreClass GdkDeviceCoreClass; +typedef struct _GdkWaylandDevice GdkWaylandDevice; + +struct _GdkWaylandDevice +{ + GdkDisplay *display; + GdkDevice *pointer; + GdkDevice *keyboard; + GdkModifierType modifiers; + GdkWindow *pointer_focus; + GdkWindow *keyboard_focus; + struct wl_input_device *device; + int32_t x, y, surface_x, surface_y; + uint32_t time; +}; + +struct _GdkDeviceCore +{ + GdkDevice parent_instance; + GdkWaylandDevice *device; +}; + +struct _GdkDeviceCoreClass +{ + GdkDeviceClass parent_class; +}; G_DEFINE_TYPE (GdkDeviceCore, gdk_device_core, GDK_TYPE_DEVICE) -static void -gdk_device_core_class_init (GdkDeviceCoreClass *klass) +#define GDK_TYPE_DEVICE_MANAGER_CORE (gdk_device_manager_core_get_type ()) +#define GDK_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCore)) +#define GDK_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass)) +#define GDK_IS_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER_CORE)) +#define GDK_IS_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER_CORE)) +#define GDK_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass)) + +typedef struct _GdkDeviceManagerCore GdkDeviceManagerCore; +typedef struct _GdkDeviceManagerCoreClass GdkDeviceManagerCoreClass; + +struct _GdkDeviceManagerCore { - GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass); + GdkDeviceManager parent_object; + GdkDevice *core_pointer; + GdkDevice *core_keyboard; + GList *devices; +}; - device_class->get_history = gdk_device_core_get_history; - device_class->get_state = gdk_device_core_get_state; - device_class->set_window_cursor = gdk_device_core_set_window_cursor; - device_class->warp = gdk_device_core_warp; - device_class->query_state = gdk_device_core_query_state; - device_class->grab = gdk_device_core_grab; - device_class->ungrab = gdk_device_core_ungrab; - device_class->window_at_position = gdk_device_core_window_at_position; - device_class->select_window_events = gdk_device_core_select_window_events; -} - -static void -gdk_device_core_init (GdkDeviceCore *device_core) +struct _GdkDeviceManagerCoreClass { - GdkDevice *device; + GdkDeviceManagerClass parent_class; +}; - device = GDK_DEVICE (device_core); - - _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1); - _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1); -} +G_DEFINE_TYPE (GdkDeviceManagerCore, + gdk_device_manager_core, GDK_TYPE_DEVICE_MANAGER) static gboolean gdk_device_core_get_history (GdkDevice *device, @@ -227,3 +224,448 @@ gdk_device_core_select_window_events (GdkDevice *device, GdkEventMask event_mask) { } + +static void +gdk_device_core_class_init (GdkDeviceCoreClass *klass) +{ + GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass); + + device_class->get_history = gdk_device_core_get_history; + device_class->get_state = gdk_device_core_get_state; + device_class->set_window_cursor = gdk_device_core_set_window_cursor; + device_class->warp = gdk_device_core_warp; + device_class->query_state = gdk_device_core_query_state; + device_class->grab = gdk_device_core_grab; + device_class->ungrab = gdk_device_core_ungrab; + device_class->window_at_position = gdk_device_core_window_at_position; + device_class->select_window_events = gdk_device_core_select_window_events; +} + +static void +gdk_device_core_init (GdkDeviceCore *device_core) +{ + GdkDevice *device; + + device = GDK_DEVICE (device_core); + + _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1); + _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1); +} + +struct wl_input_device * +_gdk_wayland_device_get_device (GdkDevice *device) +{ + GDK_DEVICE_CORE (device)->device->device; +} + +static void +input_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) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + + event = gdk_event_new (GDK_NOTHING); + + device->time = time; + device->x = x; + device->y = y; + device->surface_x = sx; + device->surface_y = sy; + + event->motion.type = GDK_MOTION_NOTIFY; + event->motion.window = g_object_ref (device->pointer_focus); + gdk_event_set_device (event, device->pointer); + event->motion.time = time; + event->motion.x = (gdouble) sx; + event->motion.y = (gdouble) sy; + event->motion.x_root = (gdouble) x; + event->motion.y_root = (gdouble) y; + event->motion.axes = NULL; + event->motion.state = device->modifiers; + event->motion.is_hint = 0; + + _gdk_wayland_display_deliver_event (device->display, event); +} + +static void +input_handle_button(void *data, struct wl_input_device *input_device, + uint32_t time, uint32_t button, uint32_t state) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + uint32_t modifier; + + fprintf (stderr, "button event %d, state %d\n", button, state); + + device->time = time; + event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE); + event->button.window = g_object_ref (device->pointer_focus); + gdk_event_set_device (event, device->pointer); + event->button.time = time; + event->button.x = (gdouble) device->surface_x; + event->button.y = (gdouble) device->surface_y; + event->button.x_root = (gdouble) device->x; + event->button.y_root = (gdouble) device->y; + event->button.axes = NULL; + event->button.state = device->modifiers; + event->button.button = button - 271; + + modifier = 1 << (8 + button - 272); + if (state) + device->modifiers |= modifier; + else + device->modifiers &= ~modifier; + + _gdk_wayland_display_deliver_event (device->display, event); +} + +static void +input_handle_key(void *data, struct wl_input_device *input_device, + uint32_t time, uint32_t key, uint32_t state) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + uint32_t code, modifier, level; + struct xkb_desc *xkb; + GdkKeymap *keymap; + + device->time = time; + event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE); + event->key.window = g_object_ref (device->keyboard_focus); + gdk_event_set_device (event, device->keyboard); + event->button.time = time; + event->key.state = device->modifiers; + event->key.group = 0; + event->key.hardware_keycode = key; + + keymap = gdk_keymap_get_for_display (device->display); + xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); + + code = key + xkb->min_key_code; + + level = 0; + if (device->modifiers & XKB_COMMON_SHIFT_MASK && + XkbKeyGroupWidth(xkb, code, 0) > 1) + level = 1; + + event->key.keyval = XkbKeySymEntry(xkb, code, level, 0); + + modifier = xkb->map->modmap[code]; + if (state) + device->modifiers |= modifier; + else + device->modifiers &= ~modifier; + + event->key.is_modifier = modifier > 0; + + if (event->key.keyval == GDK_KEY_Escape) + { + event->key.length = 1; + event->key.string = g_strdup ("\033"); + } + else if (event->key.keyval == GDK_KEY_Return || + event->key.keyval == GDK_KEY_KP_Enter) + { + event->key.length = 1; + event->key.string = g_strdup ("\r"); + } + else if (event->key.state & GDK_CONTROL_MASK) + { + gsize bytes_written; + gint len; + gchar buf[7]; + int c = event->key.keyval; + + /* Apply the control key - Taken from Xlib */ + if ((c >= XK_at && c < '\177') || c == ' ') + c &= 0x1F; + else if (c == XK_2) + { + event->key.string = g_memdup ("\0\0", 2); + event->key.length = 1; + buf[0] = '\0'; + goto out; + } + else if (c >= XK_3 && c <= XK_7) + c -= (XK_3 - '\033'); + else if (c == XK_8) + c = '\177'; + else if (c == XK_slash) + c = '_' & 0x1F; + + len = g_unichar_to_utf8 (c, buf); + buf[len] = '\0'; + + event->key.string = g_locale_from_utf8 (buf, len, + NULL, &bytes_written, + NULL); + if (event->key.string) + event->key.length = bytes_written; + } + else + { + char buffer[128]; + xkb_keysym_to_string(event->key.keyval, buffer, sizeof buffer); + event->key.string = g_strdup (buffer); + event->key.length = strlen(event->key.string); + } + + out: + _gdk_wayland_display_deliver_event (device->display, event); + + fprintf (stderr, "keyboard event, code %d, sym %d, string %s, mods 0x%x\n", + code, event->key.keyval, event->key.string, event->key.state); +} + +static void +input_handle_pointer_focus(void *data, + struct wl_input_device *input_device, + uint32_t time, struct wl_surface *surface, + int32_t x, int32_t y, int32_t sx, int32_t sy) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + + device->time = time; + if (device->pointer_focus) + { + event = gdk_event_new (GDK_LEAVE_NOTIFY); + event->crossing.window = g_object_ref (device->pointer_focus); + gdk_event_set_device (event, device->pointer); + event->crossing.subwindow = NULL; + event->crossing.time = time; + event->crossing.x = (gdouble) device->surface_x; + event->crossing.y = (gdouble) device->surface_y; + event->crossing.x_root = (gdouble) device->x; + event->crossing.y_root = (gdouble) device->y; + + event->crossing.mode = GDK_CROSSING_NORMAL; + event->crossing.detail = GDK_NOTIFY_ANCESTOR; + event->crossing.focus = TRUE; + event->crossing.state = 0; + + _gdk_wayland_display_deliver_event (device->display, event); + + g_object_unref(device->pointer_focus); + device->pointer_focus = NULL; + } + + if (surface) + { + device->pointer_focus = wl_surface_get_user_data(surface); + g_object_ref(device->pointer_focus); + + event = gdk_event_new (GDK_ENTER_NOTIFY); + event->crossing.window = g_object_ref (device->pointer_focus); + gdk_event_set_device (event, device->pointer); + event->crossing.subwindow = NULL; + event->crossing.time = time; + event->crossing.x = (gdouble) sx; + event->crossing.y = (gdouble) sy; + event->crossing.x_root = (gdouble) x; + event->crossing.y_root = (gdouble) y; + + event->crossing.mode = GDK_CROSSING_NORMAL; + event->crossing.detail = GDK_NOTIFY_ANCESTOR; + event->crossing.focus = TRUE; + event->crossing.state = 0; + + device->surface_x = sx; + device->surface_y = sy; + device->x = x; + device->y = y; + + _gdk_wayland_display_deliver_event (device->display, event); + } + + fprintf (stderr, "pointer focus surface %p, window %p\n", + surface, device->pointer_focus); +} + +static void +update_modifiers(GdkWaylandDevice *device, struct wl_array *keys) +{ + uint32_t *k, *end; + GdkKeymap *keymap; + struct xkb_desc *xkb; + + keymap = gdk_keymap_get_for_display (device->display); + xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); + + end = keys->data + keys->size; + for (k = keys->data; k < end; k++) + device->modifiers |= xkb->map->modmap[*k]; + + fprintf (stderr, "modifiers: 0x%x\n", device->modifiers); +} + +static void +input_handle_keyboard_focus(void *data, + struct wl_input_device *input_device, + uint32_t time, + struct wl_surface *surface, + struct wl_array *keys) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + + fprintf (stderr, "keyboard focus surface %p\n", surface); + + device->time = time; + if (device->keyboard_focus) + { + event = gdk_event_new (GDK_FOCUS_CHANGE); + event->focus_change.window = g_object_ref (device->keyboard_focus); + event->focus_change.send_event = FALSE; + event->focus_change.in = FALSE; + gdk_event_set_device (event, device->keyboard); + + g_object_unref(device->pointer_focus); + device->keyboard_focus = NULL; + + _gdk_wayland_display_deliver_event (device->display, event); + } + + if (surface) + { + device->keyboard_focus = wl_surface_get_user_data(surface); + g_object_ref(device->keyboard_focus); + + event = gdk_event_new (GDK_FOCUS_CHANGE); + event->focus_change.window = g_object_ref (device->keyboard_focus); + event->focus_change.send_event = FALSE; + event->focus_change.in = TRUE; + gdk_event_set_device (event, device->keyboard); + + update_modifiers (device, keys); + + _gdk_wayland_display_deliver_event (device->display, event); + } +} + +static const struct wl_input_device_listener input_device_listener = { + input_handle_motion, + input_handle_button, + input_handle_key, + input_handle_pointer_focus, + input_handle_keyboard_focus, +}; + +void +_gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager, + struct wl_input_device *wl_device) +{ + GdkDisplay *display; + GdkDeviceManagerCore *device_manager_core = + GDK_DEVICE_MANAGER_CORE(device_manager); + GdkWaylandDevice *device; + + device = g_new0 (GdkWaylandDevice, 1); + display = gdk_device_manager_get_display (device_manager); + + device->display = display; + device->pointer = g_object_new (GDK_TYPE_DEVICE_CORE, + "name", "Core Pointer", + "type", GDK_DEVICE_TYPE_MASTER, + "input-source", GDK_SOURCE_MOUSE, + "input-mode", GDK_MODE_SCREEN, + "has-cursor", TRUE, + "display", display, + "device-manager", device_manager, + NULL); + + device->keyboard = g_object_new (GDK_TYPE_DEVICE_CORE, + "name", "Core Keyboard", + "type", GDK_DEVICE_TYPE_MASTER, + "input-source", GDK_SOURCE_KEYBOARD, + "input-mode", GDK_MODE_SCREEN, + "has-cursor", FALSE, + "display", display, + "device-manager", device_manager, + NULL); + + GDK_DEVICE_CORE (device->pointer)->device = device; + GDK_DEVICE_CORE (device->keyboard)->device = device; + device->device = wl_device; + + wl_input_device_add_listener(device->device, + &input_device_listener, device); + + device_manager_core->devices = + g_list_prepend (device_manager_core->devices, device->keyboard); + device_manager_core->devices = + g_list_prepend (device_manager_core->devices, device->pointer); + + _gdk_device_set_associated_device (device->pointer, device->keyboard); + _gdk_device_set_associated_device (device->keyboard, device->pointer); +} + +static void +free_device (void *data, void *user_data) +{ + g_object_unref (data); +} + +static void +gdk_device_manager_core_finalize (GObject *object) +{ + GdkDeviceManagerCore *device_manager_core; + + device_manager_core = GDK_DEVICE_MANAGER_CORE (object); + + g_list_foreach (device_manager_core->devices, free_device, NULL); + g_list_free (device_manager_core->devices); + + G_OBJECT_CLASS (gdk_device_manager_core_parent_class)->finalize (object); +} + +static GList * +gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager, + GdkDeviceType type) +{ + GdkDeviceManagerCore *device_manager_core; + GList *devices = NULL; + + if (type == GDK_DEVICE_TYPE_MASTER) + { + device_manager_core = (GdkDeviceManagerCore *) device_manager; + devices = g_list_copy(device_manager_core->devices); + } + + return devices; +} + +static GdkDevice * +gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager) +{ + GdkDeviceManagerCore *device_manager_core; + + device_manager_core = (GdkDeviceManagerCore *) device_manager; + return device_manager_core->devices->data; +} + +static void +gdk_device_manager_core_class_init (GdkDeviceManagerCoreClass *klass) +{ + GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gdk_device_manager_core_finalize; + device_manager_class->list_devices = gdk_device_manager_core_list_devices; + device_manager_class->get_client_pointer = gdk_device_manager_core_get_client_pointer; +} + +static void +gdk_device_manager_core_init (GdkDeviceManagerCore *device_manager) +{ +} + +GdkDeviceManager * +_gdk_wayland_device_manager_new (GdkDisplay *display) +{ + return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE, + "display", display, + NULL); +} diff --git a/gdk/wayland/gdkdevice-wayland.h b/gdk/wayland/gdkdevice-wayland.h deleted file mode 100644 index ce631c062d..0000000000 --- a/gdk/wayland/gdkdevice-wayland.h +++ /dev/null @@ -1,68 +0,0 @@ -/* GDK - The GIMP Drawing Kit - * Copyright (C) 2009 Carlos Garnacho - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GDK_DEVICE_CORE_H__ -#define __GDK_DEVICE_CORE_H__ - -#include -#include - -G_BEGIN_DECLS - -#define GDK_TYPE_DEVICE_CORE (gdk_device_core_get_type ()) -#define GDK_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCore)) -#define GDK_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass)) -#define GDK_IS_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_CORE)) -#define GDK_IS_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_CORE)) -#define GDK_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass)) - -typedef struct _GdkDeviceCore GdkDeviceCore; -typedef struct _GdkDeviceCoreClass GdkDeviceCoreClass; -typedef struct _GdkWaylandDevice GdkWaylandDevice; - -struct _GdkWaylandDevice -{ - GdkDisplay *display; - GdkDevice *pointer; - GdkDevice *keyboard; - GdkModifierType modifiers; - GdkWindow *pointer_focus; - GdkWindow *keyboard_focus; - struct wl_input_device *device; - int32_t x, y, surface_x, surface_y; - uint32_t time; -}; - -struct _GdkDeviceCore -{ - GdkDevice parent_instance; - GdkWaylandDevice *device; -}; - -struct _GdkDeviceCoreClass -{ - GdkDeviceClass parent_class; -}; - -G_GNUC_INTERNAL -GType gdk_device_core_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __GDK_DEVICE_CORE_H__ */ diff --git a/gdk/wayland/gdkdevicemanager-wayland.c b/gdk/wayland/gdkdevicemanager-wayland.c deleted file mode 100644 index 5c9a3b348e..0000000000 --- a/gdk/wayland/gdkdevicemanager-wayland.c +++ /dev/null @@ -1,451 +0,0 @@ -/* GDK - The GIMP Drawing Kit - * Copyright (C) 2009 Carlos Garnacho - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include -#include "gdkdevicemanager-wayland.h" -#include "gdkdevice-wayland.h" -#include "gdkkeysyms.h" -#include "gdkprivate-wayland.h" - -#include -#include - -static void gdk_device_manager_core_finalize (GObject *object); - -static GList * gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager, - GdkDeviceType type); -static GdkDevice * gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager); - -G_DEFINE_TYPE (GdkDeviceManagerCore, gdk_device_manager_core, GDK_TYPE_DEVICE_MANAGER) - -static void -gdk_device_manager_core_class_init (GdkDeviceManagerCoreClass *klass) -{ - GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass); - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = gdk_device_manager_core_finalize; - device_manager_class->list_devices = gdk_device_manager_core_list_devices; - device_manager_class->get_client_pointer = gdk_device_manager_core_get_client_pointer; -} - -static void -input_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) -{ - GdkWaylandDevice *device = data; - GdkEvent *event; - - event = gdk_event_new (GDK_NOTHING); - - device->time = time; - device->x = x; - device->y = y; - device->surface_x = sx; - device->surface_y = sy; - - event->motion.type = GDK_MOTION_NOTIFY; - event->motion.window = g_object_ref (device->pointer_focus); - gdk_event_set_device (event, device->pointer); - event->motion.time = time; - event->motion.x = (gdouble) sx; - event->motion.y = (gdouble) sy; - event->motion.x_root = (gdouble) x; - event->motion.y_root = (gdouble) y; - event->motion.axes = NULL; - event->motion.state = device->modifiers; - event->motion.is_hint = 0; - - _gdk_wayland_display_deliver_event (device->display, event); -} - -static void -input_handle_button(void *data, struct wl_input_device *input_device, - uint32_t time, uint32_t button, uint32_t state) -{ - GdkWaylandDevice *device = data; - GdkEvent *event; - uint32_t modifier; - - fprintf (stderr, "button event %d, state %d\n", button, state); - - device->time = time; - event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE); - event->button.window = g_object_ref (device->pointer_focus); - gdk_event_set_device (event, device->pointer); - event->button.time = time; - event->button.x = (gdouble) device->surface_x; - event->button.y = (gdouble) device->surface_y; - event->button.x_root = (gdouble) device->x; - event->button.y_root = (gdouble) device->y; - event->button.axes = NULL; - event->button.state = device->modifiers; - event->button.button = button - 271; - - modifier = 1 << (8 + button - 272); - if (state) - device->modifiers |= modifier; - else - device->modifiers &= ~modifier; - - _gdk_wayland_display_deliver_event (device->display, event); -} - -static void -input_handle_key(void *data, struct wl_input_device *input_device, - uint32_t time, uint32_t key, uint32_t state) -{ - GdkWaylandDevice *device = data; - GdkEvent *event; - uint32_t code, modifier, level; - struct xkb_desc *xkb; - GdkKeymap *keymap; - - device->time = time; - event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE); - event->key.window = g_object_ref (device->keyboard_focus); - gdk_event_set_device (event, device->keyboard); - event->button.time = time; - event->key.state = device->modifiers; - event->key.group = 0; - event->key.hardware_keycode = key; - - keymap = gdk_keymap_get_for_display (device->display); - xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); - - code = key + xkb->min_key_code; - - level = 0; - if (device->modifiers & XKB_COMMON_SHIFT_MASK && - XkbKeyGroupWidth(xkb, code, 0) > 1) - level = 1; - - event->key.keyval = XkbKeySymEntry(xkb, code, level, 0); - - modifier = xkb->map->modmap[code]; - if (state) - device->modifiers |= modifier; - else - device->modifiers &= ~modifier; - - event->key.is_modifier = modifier > 0; - - if (event->key.keyval == GDK_KEY_Escape) - { - event->key.length = 1; - event->key.string = g_strdup ("\033"); - } - else if (event->key.keyval == GDK_KEY_Return || - event->key.keyval == GDK_KEY_KP_Enter) - { - event->key.length = 1; - event->key.string = g_strdup ("\r"); - } - else if (event->key.state & GDK_CONTROL_MASK) - { - gsize bytes_written; - gint len; - gchar buf[7]; - int c = event->key.keyval; - - /* Apply the control key - Taken from Xlib */ - if ((c >= XK_at && c < '\177') || c == ' ') - c &= 0x1F; - else if (c == XK_2) - { - event->key.string = g_memdup ("\0\0", 2); - event->key.length = 1; - buf[0] = '\0'; - goto out; - } - else if (c >= XK_3 && c <= XK_7) - c -= (XK_3 - '\033'); - else if (c == XK_8) - c = '\177'; - else if (c == XK_slash) - c = '_' & 0x1F; - - len = g_unichar_to_utf8 (c, buf); - buf[len] = '\0'; - - event->key.string = g_locale_from_utf8 (buf, len, - NULL, &bytes_written, - NULL); - if (event->key.string) - event->key.length = bytes_written; - } - else - { - char buffer[128]; - xkb_keysym_to_string(event->key.keyval, buffer, sizeof buffer); - event->key.string = g_strdup (buffer); - event->key.length = strlen(event->key.string); - } - - out: - _gdk_wayland_display_deliver_event (device->display, event); - - fprintf (stderr, "keyboard event, code %d, sym %d, string %s, mods 0x%x\n", - code, event->key.keyval, event->key.string, event->key.state); -} - -static void -input_handle_pointer_focus(void *data, - struct wl_input_device *input_device, - uint32_t time, struct wl_surface *surface, - int32_t x, int32_t y, int32_t sx, int32_t sy) -{ - GdkWaylandDevice *device = data; - GdkEvent *event; - - device->time = time; - if (device->pointer_focus) - { - event = gdk_event_new (GDK_LEAVE_NOTIFY); - event->crossing.window = g_object_ref (device->pointer_focus); - gdk_event_set_device (event, device->pointer); - event->crossing.subwindow = NULL; - event->crossing.time = time; - event->crossing.x = (gdouble) device->surface_x; - event->crossing.y = (gdouble) device->surface_y; - event->crossing.x_root = (gdouble) device->x; - event->crossing.y_root = (gdouble) device->y; - - event->crossing.mode = GDK_CROSSING_NORMAL; - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - event->crossing.focus = TRUE; - event->crossing.state = 0; - - _gdk_wayland_display_deliver_event (device->display, event); - - g_object_unref(device->pointer_focus); - device->pointer_focus = NULL; - } - - if (surface) - { - device->pointer_focus = wl_surface_get_user_data(surface); - g_object_ref(device->pointer_focus); - - event = gdk_event_new (GDK_ENTER_NOTIFY); - event->crossing.window = g_object_ref (device->pointer_focus); - gdk_event_set_device (event, device->pointer); - event->crossing.subwindow = NULL; - event->crossing.time = time; - event->crossing.x = (gdouble) sx; - event->crossing.y = (gdouble) sy; - event->crossing.x_root = (gdouble) x; - event->crossing.y_root = (gdouble) y; - - event->crossing.mode = GDK_CROSSING_NORMAL; - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - event->crossing.focus = TRUE; - event->crossing.state = 0; - - device->surface_x = sx; - device->surface_y = sy; - device->x = x; - device->y = y; - - _gdk_wayland_display_deliver_event (device->display, event); - } - - fprintf (stderr, "pointer focus surface %p, window %p\n", - surface, device->pointer_focus); -} - -static void -update_modifiers(GdkWaylandDevice *device, struct wl_array *keys) -{ - uint32_t *k, *end; - GdkKeymap *keymap; - struct xkb_desc *xkb; - - keymap = gdk_keymap_get_for_display (device->display); - xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); - - end = keys->data + keys->size; - for (k = keys->data; k < end; k++) - device->modifiers |= xkb->map->modmap[*k]; - - fprintf (stderr, "modifiers: 0x%x\n", device->modifiers); -} - -static void -input_handle_keyboard_focus(void *data, - struct wl_input_device *input_device, - uint32_t time, - struct wl_surface *surface, - struct wl_array *keys) -{ - GdkWaylandDevice *device = data; - GdkEvent *event; - - fprintf (stderr, "keyboard focus surface %p\n", surface); - - device->time = time; - if (device->keyboard_focus) - { - event = gdk_event_new (GDK_FOCUS_CHANGE); - event->focus_change.window = g_object_ref (device->keyboard_focus); - event->focus_change.send_event = FALSE; - event->focus_change.in = FALSE; - gdk_event_set_device (event, device->keyboard); - - g_object_unref(device->pointer_focus); - device->keyboard_focus = NULL; - - _gdk_wayland_display_deliver_event (device->display, event); - } - - if (surface) - { - device->keyboard_focus = wl_surface_get_user_data(surface); - g_object_ref(device->keyboard_focus); - - event = gdk_event_new (GDK_FOCUS_CHANGE); - event->focus_change.window = g_object_ref (device->keyboard_focus); - event->focus_change.send_event = FALSE; - event->focus_change.in = TRUE; - gdk_event_set_device (event, device->keyboard); - - update_modifiers (device, keys); - - _gdk_wayland_display_deliver_event (device->display, event); - } -} - -static const struct wl_input_device_listener input_device_listener = { - input_handle_motion, - input_handle_button, - input_handle_key, - input_handle_pointer_focus, - input_handle_keyboard_focus, -}; - -void -gdk_device_manager_core_add_device (GdkDeviceManager *device_manager, - struct wl_input_device *wl_device) -{ - GdkDisplay *display; - GdkDeviceManagerCore *device_manager_core = - GDK_DEVICE_MANAGER_CORE(device_manager); - GdkWaylandDevice *device; - - device = g_new0 (GdkWaylandDevice, 1); - display = gdk_device_manager_get_display (device_manager); - - device->display = display; - device->pointer = g_object_new (GDK_TYPE_DEVICE_CORE, - "name", "Core Pointer", - "type", GDK_DEVICE_TYPE_MASTER, - "input-source", GDK_SOURCE_MOUSE, - "input-mode", GDK_MODE_SCREEN, - "has-cursor", TRUE, - "display", display, - "device-manager", device_manager, - NULL); - - device->keyboard = g_object_new (GDK_TYPE_DEVICE_CORE, - "name", "Core Keyboard", - "type", GDK_DEVICE_TYPE_MASTER, - "input-source", GDK_SOURCE_KEYBOARD, - "input-mode", GDK_MODE_SCREEN, - "has-cursor", FALSE, - "display", display, - "device-manager", device_manager, - NULL); - - GDK_DEVICE_CORE (device->pointer)->device = device; - GDK_DEVICE_CORE (device->keyboard)->device = device; - device->device = wl_device; - - wl_input_device_add_listener(device->device, - &input_device_listener, device); - - device_manager_core->devices = - g_list_prepend (device_manager_core->devices, device->keyboard); - device_manager_core->devices = - g_list_prepend (device_manager_core->devices, device->pointer); - - _gdk_device_set_associated_device (device->pointer, device->keyboard); - _gdk_device_set_associated_device (device->keyboard, device->pointer); -} - -static void -gdk_device_manager_core_init (GdkDeviceManagerCore *device_manager) -{ -} - -static void -free_device (void *data, void *user_data) -{ - g_object_unref (data); -} - -static void -gdk_device_manager_core_finalize (GObject *object) -{ - GdkDeviceManagerCore *device_manager_core; - - device_manager_core = GDK_DEVICE_MANAGER_CORE (object); - - g_list_foreach (device_manager_core->devices, free_device, NULL); - g_list_free (device_manager_core->devices); - - G_OBJECT_CLASS (gdk_device_manager_core_parent_class)->finalize (object); -} - -static GList * -gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager, - GdkDeviceType type) -{ - GdkDeviceManagerCore *device_manager_core; - GList *devices = NULL; - - if (type == GDK_DEVICE_TYPE_MASTER) - { - device_manager_core = (GdkDeviceManagerCore *) device_manager; - devices = g_list_copy(device_manager_core->devices); - } - - return devices; -} - -static GdkDevice * -gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager) -{ - GdkDeviceManagerCore *device_manager_core; - - device_manager_core = (GdkDeviceManagerCore *) device_manager; - return device_manager_core->devices->data; -} - -GdkDeviceManager * -_gdk_device_manager_new (GdkDisplay *display) -{ - return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE, - "display", display, - NULL); -} diff --git a/gdk/wayland/gdkdevicemanager-wayland.h b/gdk/wayland/gdkdevicemanager-wayland.h deleted file mode 100644 index 83c76e9983..0000000000 --- a/gdk/wayland/gdkdevicemanager-wayland.h +++ /dev/null @@ -1,59 +0,0 @@ -/* GDK - The GIMP Drawing Kit - * Copyright (C) 2009 Carlos Garnacho - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GDK_DEVICE_MANAGER_CORE_H__ -#define __GDK_DEVICE_MANAGER_CORE_H__ - -#include -#include - -G_BEGIN_DECLS - -#define GDK_TYPE_DEVICE_MANAGER_CORE (gdk_device_manager_core_get_type ()) -#define GDK_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCore)) -#define GDK_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass)) -#define GDK_IS_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER_CORE)) -#define GDK_IS_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER_CORE)) -#define GDK_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass)) - -typedef struct _GdkDeviceManagerCore GdkDeviceManagerCore; -typedef struct _GdkDeviceManagerCoreClass GdkDeviceManagerCoreClass; - -struct _GdkDeviceManagerCore -{ - GdkDeviceManager parent_object; - GdkDevice *core_pointer; - GdkDevice *core_keyboard; - GList *devices; -}; - -struct _GdkDeviceManagerCoreClass -{ - GdkDeviceManagerClass parent_class; -}; - -GType gdk_device_manager_core_get_type (void) G_GNUC_CONST; - -void -gdk_device_manager_core_add_device (GdkDeviceManager *device_manager, - struct wl_input_device *device); - -G_END_DECLS - -#endif /* __GDK_DEVICE_MANAGER_CORE_H__ */ diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 45184b0f00..0e68b7e572 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -36,7 +36,6 @@ #include "gdkinternals.h" #include "gdkdeviceprivate.h" #include "gdkdevicemanager.h" -#include "gdkdevicemanager-wayland.h" #include "gdkkeysprivate.h" typedef struct _GdkEventTypeWayland GdkEventTypeWayland; @@ -192,7 +191,8 @@ gdk_display_handle_global(struct wl_display *display, uint32_t id, &output_listener, display_wayland); } else if (strcmp(interface, "input_device") == 0) { input = wl_input_device_create(display, id); - gdk_device_manager_core_add_device (gdk_display->device_manager, input); + _gdk_wayland_device_manager_add_device (gdk_display->device_manager, + input); } } @@ -286,7 +286,7 @@ _gdk_wayland_display_open (const gchar *display_name) /*set the default screen */ display_wayland->default_screen = display_wayland->screens[0]; - display->device_manager = _gdk_device_manager_new (display); + display->device_manager = _gdk_wayland_device_manager_new (display); /* Set up listener so we'll catch all events. */ wl_display_add_global_listener(display_wayland->wl_display, diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index da215a121d..a9256831b0 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -121,7 +121,10 @@ gint _gdk_wayland_display_text_property_to_utf8_list (GdkDisplay *disp gchar * _gdk_wayland_display_utf8_to_string_target (GdkDisplay *display, const gchar *str); -GdkDeviceManager *_gdk_device_manager_new (GdkDisplay *display); +GdkDeviceManager *_gdk_wayland_device_manager_new (GdkDisplay *display); +void _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager, + struct wl_input_device *device); +struct wl_input_device *_gdk_wayland_device_get_device (GdkDevice *device); void _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event); GSource *_gdk_wayland_display_event_source_new (GdkDisplay *display); diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index d0cd39e954..934b7b5940 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -33,7 +33,6 @@ #include "gdkinternals.h" #include "gdkwindow-wayland.h" #include "gdkdeviceprivate.h" -#include "gdkdevice-wayland.h" #include #include @@ -1148,7 +1147,7 @@ gdk_wayland_window_begin_resize_drag (GdkWindow *window, device = gdk_device_manager_get_client_pointer (dm); wl_shell_resize(GDK_DISPLAY_WAYLAND (display)->shell, impl->surface, - GDK_DEVICE_CORE (device)->device->device, + _gdk_wayland_device_get_device (device), timestamp, grab_type); } @@ -1174,7 +1173,7 @@ gdk_wayland_window_begin_move_drag (GdkWindow *window, device = gdk_device_manager_get_client_pointer (dm); wl_shell_move(GDK_DISPLAY_WAYLAND (display)->shell, impl->surface, - GDK_DEVICE_CORE (device)->device->device, timestamp); + _gdk_wayland_device_get_device (device), timestamp); } static void