diff --git a/docs/reference/gdk/gdk4-sections.txt b/docs/reference/gdk/gdk4-sections.txt index 902b724ba3..32a212e44e 100644 --- a/docs/reference/gdk/gdk4-sections.txt +++ b/docs/reference/gdk/gdk4-sections.txt @@ -880,18 +880,6 @@ GDK_X11_APP_LAUNCH_CONTEXT_CLASS GDK_IS_X11_APP_LAUNCH_CONTEXT GDK_IS_X11_APP_LAUNCH_CONTEXT_CLASS GDK_X11_APP_LAUNCH_CONTEXT_GET_CLASS -GDK_TYPE_X11_DEVICE_CORE -GDK_X11_DEVICE_CORE -GDK_X11_DEVICE_CORE_CLASS -GDK_IS_X11_DEVICE_CORE -GDK_IS_X11_DEVICE_CORE_CLASS -GDK_X11_DEVICE_CORE_GET_CLASS -GDK_TYPE_X11_DEVICE_MANAGER_CORE -GDK_X11_DEVICE_MANAGER_CORE -GDK_X11_DEVICE_MANAGER_CORE_CLASS -GDK_IS_X11_DEVICE_MANAGER_CORE -GDK_IS_X11_DEVICE_MANAGER_CORE_CLASS -GDK_X11_DEVICE_MANAGER_CORE_GET_CLASS GDK_TYPE_X11_DEVICE_MANAGER_XI2 GDK_X11_DEVICE_MANAGER_XI2 GDK_X11_DEVICE_MANAGER_XI2_CLASS @@ -961,8 +949,6 @@ GDK_X11_SURFACE_GET_CLASS gdk_x11_app_launch_context_get_type gdk_x11_cursor_get_type -gdk_x11_device_core_get_type -gdk_x11_device_manager_core_get_type gdk_x11_device_manager_xi2_get_type gdk_x11_device_manager_xi_get_type gdk_x11_device_xi2_get_type diff --git a/gdk/x11/gdkdevice-core-x11.c b/gdk/x11/gdkdevice-core-x11.c deleted file mode 100644 index d23c01a1bc..0000000000 --- a/gdk/x11/gdkdevice-core-x11.c +++ /dev/null @@ -1,537 +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, see . - */ - -#include "config.h" - - -#include "gdkx11device-core.h" -#include "gdkdeviceprivate.h" - -#include "gdkinternals.h" -#include "gdksurface.h" -#include "gdkprivate-x11.h" -#include "gdkdisplay-x11.h" -#include "gdkasync.h" - -#include - -struct _GdkX11DeviceCore -{ - GdkDevice parent_instance; -}; - -struct _GdkX11DeviceCoreClass -{ - GdkDeviceClass parent_class; -}; - -static gboolean gdk_x11_device_core_get_history (GdkDevice *device, - GdkSurface *surface, - guint32 start, - guint32 stop, - GdkTimeCoord ***events, - gint *n_events); -static void gdk_x11_device_core_get_state (GdkDevice *device, - GdkSurface *surface, - gdouble *axes, - GdkModifierType *mask); -static void gdk_x11_device_core_set_surface_cursor (GdkDevice *device, - GdkSurface *surface, - GdkCursor *cursor); -static void gdk_x11_device_core_query_state (GdkDevice *device, - GdkSurface *surface, - GdkSurface **child_surface, - gdouble *root_x, - gdouble *root_y, - gdouble *win_x, - gdouble *win_y, - GdkModifierType *mask); -static GdkGrabStatus gdk_x11_device_core_grab (GdkDevice *device, - GdkSurface *surface, - gboolean owner_events, - GdkEventMask event_mask, - GdkSurface *confine_to, - GdkCursor *cursor, - guint32 time_); -static void gdk_x11_device_core_ungrab (GdkDevice *device, - guint32 time_); -static GdkSurface * gdk_x11_device_core_surface_at_position (GdkDevice *device, - gdouble *win_x, - gdouble *win_y, - GdkModifierType *mask, - gboolean get_toplevel); - -G_DEFINE_TYPE (GdkX11DeviceCore, gdk_x11_device_core, GDK_TYPE_DEVICE) - -static void -gdk_x11_device_core_class_init (GdkX11DeviceCoreClass *klass) -{ - GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass); - - device_class->get_history = gdk_x11_device_core_get_history; - device_class->get_state = gdk_x11_device_core_get_state; - device_class->set_surface_cursor = gdk_x11_device_core_set_surface_cursor; - device_class->query_state = gdk_x11_device_core_query_state; - device_class->grab = gdk_x11_device_core_grab; - device_class->ungrab = gdk_x11_device_core_ungrab; - device_class->surface_at_position = gdk_x11_device_core_surface_at_position; -} - -static void -gdk_x11_device_core_init (GdkX11DeviceCore *device_core) -{ - GdkDevice *device; - - device = GDK_DEVICE (device_core); - - _gdk_device_add_axis (device, NULL, GDK_AXIS_X, 0, 0, 1); - _gdk_device_add_axis (device, NULL, GDK_AXIS_Y, 0, 0, 1); -} - -static gboolean -impl_coord_in_surface (GdkSurface *surface, - int impl_x, - int impl_y) -{ - if (impl_x < surface->abs_x || - impl_x >= surface->abs_x + surface->width) - return FALSE; - - if (impl_y < surface->abs_y || - impl_y >= surface->abs_y + surface->height) - return FALSE; - - return TRUE; -} - -static gboolean -gdk_x11_device_core_get_history (GdkDevice *device, - GdkSurface *surface, - guint32 start, - guint32 stop, - GdkTimeCoord ***events, - gint *n_events) -{ - XTimeCoord *xcoords; - GdkTimeCoord **coords; - GdkSurface *impl_surface; - GdkSurfaceImplX11 *impl; - int tmp_n_events; - int i, j; - - impl_surface = _gdk_surface_get_impl_surface (surface); - impl = GDK_SURFACE_IMPL_X11 (impl_surface->impl); - xcoords = XGetMotionEvents (GDK_SURFACE_XDISPLAY (surface), - GDK_SURFACE_XID (impl_surface), - start, stop, &tmp_n_events); - if (!xcoords) - return FALSE; - - coords = _gdk_device_allocate_history (device, tmp_n_events); - - for (i = 0, j = 0; i < tmp_n_events; i++) - { - if (impl_coord_in_surface (surface, - xcoords[i].x / impl->surface_scale, - xcoords[i].y / impl->surface_scale)) - { - coords[j]->time = xcoords[i].time; - coords[j]->axes[0] = (double)xcoords[i].x / impl->surface_scale - surface->abs_x; - coords[j]->axes[1] = (double)xcoords[i].y / impl->surface_scale - surface->abs_y; - j++; - } - } - - XFree (xcoords); - - /* free the events we allocated too much */ - for (i = j; i < tmp_n_events; i++) - { - g_free (coords[i]); - coords[i] = NULL; - } - - tmp_n_events = j; - - if (tmp_n_events == 0) - { - gdk_device_free_history (coords, tmp_n_events); - return FALSE; - } - - if (n_events) - *n_events = tmp_n_events; - - if (events) - *events = coords; - else if (coords) - gdk_device_free_history (coords, tmp_n_events); - - return TRUE; -} - -static void -gdk_x11_device_core_get_state (GdkDevice *device, - GdkSurface *surface, - gdouble *axes, - GdkModifierType *mask) -{ - gdouble x, y; - - gdk_surface_get_device_position (surface, device, &x, &y, mask); - - if (axes) - { - axes[0] = x; - axes[1] = y; - } -} - -static void -gdk_x11_device_core_set_surface_cursor (GdkDevice *device, - GdkSurface *surface, - GdkCursor *cursor) -{ - GdkDisplay *display = gdk_device_get_display (device); - Cursor xcursor; - - if (!cursor) - xcursor = None; - else - xcursor = gdk_x11_display_get_xcursor (display, cursor); - - XDefineCursor (GDK_DISPLAY_XDISPLAY (display), - GDK_SURFACE_XID (surface), - xcursor); -} - -static void -gdk_x11_device_core_query_state (GdkDevice *device, - GdkSurface *surface, - GdkSurface **child_surface, - gdouble *root_x, - gdouble *root_y, - gdouble *win_x, - gdouble *win_y, - GdkModifierType *mask) -{ - GdkDisplay *display; - GdkX11Screen *screen; - Window xwindow, w; - Window xroot_window, xchild_window; - int xroot_x, xroot_y, xwin_x, xwin_y; - unsigned int xmask; - int scale; - - display = gdk_device_get_display (device); - screen = GDK_X11_DISPLAY (display)->screen; - if (surface == NULL) - { - xwindow = GDK_SCREEN_XROOTWIN (screen); - scale = screen->surface_scale; - } - else - { - xwindow = GDK_SURFACE_XID (surface); - scale = GDK_SURFACE_IMPL_X11 (surface->impl)->surface_scale; - } - - if (!GDK_X11_DISPLAY (display)->trusted_client || - !XQueryPointer (GDK_SURFACE_XDISPLAY (surface), - xwindow, - &xroot_window, - &xchild_window, - &xroot_x, &xroot_y, - &xwin_x, &xwin_y, - &xmask)) - { - XSetWindowAttributes attributes; - Display *xdisplay; - - /* FIXME: untrusted clients not multidevice-safe */ - xdisplay = GDK_SCREEN_XDISPLAY (screen); - xwindow = GDK_SCREEN_XROOTWIN (screen); - - w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0, - CopyFromParent, InputOnly, CopyFromParent, - 0, &attributes); - XQueryPointer (xdisplay, w, - &xroot_window, - &xchild_window, - &xroot_x, &xroot_y, - &xwin_x, &xwin_y, - &xmask); - XDestroyWindow (xdisplay, w); - } - - if (child_surface) - *child_surface = gdk_x11_surface_lookup_for_display (display, xchild_window); - - if (root_x) - *root_x = (double)xroot_x / scale; - - if (root_y) - *root_y = (double)xroot_y / scale; - - if (win_x) - *win_x = (double)xwin_x / scale; - - if (win_y) - *win_y = (double)xwin_y / scale; - - if (mask) - *mask = xmask; -} - -static GdkGrabStatus -gdk_x11_device_core_grab (GdkDevice *device, - GdkSurface *surface, - gboolean owner_events, - GdkEventMask event_mask, - GdkSurface *confine_to, - GdkCursor *cursor, - guint32 time_) -{ - GdkDisplay *display; - Window xwindow, xconfine_to; - gint status; - - display = gdk_device_get_display (device); - - xwindow = GDK_SURFACE_XID (surface); - - if (confine_to) - confine_to = _gdk_surface_get_impl_surface (confine_to); - - if (!confine_to || GDK_SURFACE_DESTROYED (confine_to)) - xconfine_to = None; - else - xconfine_to = GDK_SURFACE_XID (confine_to); - -#ifdef G_ENABLE_DEBUG - if (GDK_DISPLAY_DEBUG_CHECK (display, NOGRABS)) - status = GrabSuccess; - else -#endif - if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) - { - /* Device is a keyboard */ - status = XGrabKeyboard (GDK_DISPLAY_XDISPLAY (display), - xwindow, - owner_events, - GrabModeAsync, GrabModeAsync, - time_); - } - else - { - Cursor xcursor; - guint xevent_mask; - gint i; - - /* Device is a pointer */ - if (!cursor) - xcursor = None; - else - { - xcursor = gdk_x11_display_get_xcursor (display, cursor); - } - - xevent_mask = 0; - - for (i = 0; i < _gdk_x11_event_mask_table_size; i++) - { - if (event_mask & (1 << (i + 1))) - xevent_mask |= _gdk_x11_event_mask_table[i]; - } - - /* We don't want to set a native motion hint mask, as we're emulating motion - * hints. If we set a native one we just wouldn't get any events. - */ - xevent_mask &= ~PointerMotionHintMask; - - status = XGrabPointer (GDK_DISPLAY_XDISPLAY (display), - xwindow, - owner_events, - xevent_mask, - GrabModeAsync, GrabModeAsync, - xconfine_to, - xcursor, - time_); - } - - _gdk_x11_display_update_grab_info (display, device, status); - - return _gdk_x11_convert_grab_status (status); -} - -static void -gdk_x11_device_core_ungrab (GdkDevice *device, - guint32 time_) -{ - GdkDisplay *display; - gulong serial; - - display = gdk_device_get_display (device); - serial = NextRequest (GDK_DISPLAY_XDISPLAY (display)); - - if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) - XUngrabKeyboard (GDK_DISPLAY_XDISPLAY (display), time_); - else - XUngrabPointer (GDK_DISPLAY_XDISPLAY (display), time_); - - _gdk_x11_display_update_grab_info_ungrab (display, device, time_, serial); -} - -static GdkSurface * -gdk_x11_device_core_surface_at_position (GdkDevice *device, - gdouble *win_x, - gdouble *win_y, - GdkModifierType *mask, - gboolean get_toplevel) -{ - GdkSurfaceImplX11 *impl; - GdkDisplay *display; - Display *xdisplay; - GdkSurface *surface; - GdkX11Screen *screen; - Window xwindow, root, child, last; - int xroot_x, xroot_y, xwin_x, xwin_y; - unsigned int xmask; - - last = None; - display = gdk_device_get_display (device); - screen = GDK_X11_DISPLAY (display)->screen; - - /* This function really only works if the mouse pointer is held still - * during its operation. If it moves from one leaf window to another - * than we'll end up with inaccurate values for win_x, win_y - * and the result. - */ - gdk_x11_display_grab (display); - - xdisplay = GDK_SCREEN_XDISPLAY (screen); - xwindow = GDK_SCREEN_XROOTWIN (screen); - - if (G_LIKELY (GDK_X11_DISPLAY (display)->trusted_client)) - { - XQueryPointer (xdisplay, xwindow, - &root, &child, - &xroot_x, &xroot_y, - &xwin_x, &xwin_y, - &xmask); - - if (root == xwindow) - xwindow = child; - else - xwindow = root; - } - else - { - gint width, height; - GList *toplevels, *list; - Window pointer_window; - int rootx = -1, rooty = -1; - int winx, winy; - - /* FIXME: untrusted clients case not multidevice-safe */ - pointer_window = None; - toplevels = gdk_x11_display_get_toplevel_windows (display); - for (list = toplevels; list != NULL; list = list->next) - { - surface = GDK_SURFACE (list->data); - impl = GDK_SURFACE_IMPL_X11 (surface->impl); - xwindow = GDK_SURFACE_XID (surface); - gdk_x11_display_error_trap_push (display); - XQueryPointer (xdisplay, xwindow, - &root, &child, - &rootx, &rooty, - &winx, &winy, - &xmask); - if (gdk_x11_display_error_trap_pop (display)) - continue; - if (child != None) - { - pointer_window = child; - break; - } - gdk_surface_get_geometry (surface, NULL, NULL, &width, &height); - if (winx >= 0 && winy >= 0 && winx < width * impl->surface_scale && winy < height * impl->surface_scale) - { - /* A childless toplevel, or below another window? */ - XSetWindowAttributes attributes; - Window w; - - w = XCreateWindow (xdisplay, xwindow, winx, winy, 1, 1, 0, - CopyFromParent, InputOnly, CopyFromParent, - 0, &attributes); - XMapWindow (xdisplay, w); - XQueryPointer (xdisplay, xwindow, - &root, &child, - &rootx, &rooty, - &winx, &winy, - &xmask); - XDestroyWindow (xdisplay, w); - if (child == w) - { - pointer_window = xwindow; - break; - } - } - } - - xwindow = pointer_window; - } - - while (xwindow) - { - last = xwindow; - gdk_x11_display_error_trap_push (display); - XQueryPointer (xdisplay, xwindow, - &root, &xwindow, - &xroot_x, &xroot_y, - &xwin_x, &xwin_y, - &xmask); - if (gdk_x11_display_error_trap_pop (display)) - break; - - if (get_toplevel && last != root && - (surface = gdk_x11_surface_lookup_for_display (display, last)) != NULL) - { - xwindow = last; - break; - } - } - - gdk_x11_display_ungrab (display); - - surface = gdk_x11_surface_lookup_for_display (display, last); - impl = NULL; - if (surface) - impl = GDK_SURFACE_IMPL_X11 (surface->impl); - - if (win_x) - *win_x = (surface) ? (double)xwin_x / impl->surface_scale : -1; - - if (win_y) - *win_y = (surface) ? (double)xwin_y / impl->surface_scale : -1; - - if (mask) - *mask = xmask; - - return surface; -} - diff --git a/gdk/x11/gdkdevicemanager-core-x11.c b/gdk/x11/gdkdevicemanager-core-x11.c deleted file mode 100644 index fb740286b5..0000000000 --- a/gdk/x11/gdkdevicemanager-core-x11.c +++ /dev/null @@ -1,827 +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, see . - */ - -#include "config.h" - -#include "gdkx11devicemanager-core.h" -#include "gdkdevicemanagerprivate-core.h" -#include "gdkx11device-core.h" - -#include "gdkdeviceprivate.h" -#include "gdkseatdefaultprivate.h" -#include "gdkdisplayprivate.h" -#include "gdkeventtranslator.h" -#include "gdkprivate-x11.h" -#include "gdkdisplay-x11.h" -#include "gdkkeysyms.h" - - - -#define HAS_FOCUS(toplevel) \ - ((toplevel)->has_focus || (toplevel)->has_pointer_focus) - -static void gdk_x11_device_manager_core_finalize (GObject *object); -static void gdk_x11_device_manager_core_constructed (GObject *object); - -static void gdk_x11_device_manager_event_translator_init (GdkEventTranslatorIface *iface); - -static gboolean gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator, - GdkDisplay *display, - GdkEvent *event, - const XEvent *xevent); - - -G_DEFINE_TYPE_WITH_CODE (GdkX11DeviceManagerCore, gdk_x11_device_manager_core, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR, - gdk_x11_device_manager_event_translator_init)) - -enum { - PROP_0, - PROP_DISPLAY -}; - -static void -gdk_device_manager_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) - { - case PROP_DISPLAY: - GDK_X11_DEVICE_MANAGER_CORE (object)->display = g_value_get_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdk_device_manager_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - - switch (prop_id) - { - case PROP_DISPLAY: - g_value_set_object (value, GDK_X11_DEVICE_MANAGER_CORE (object)->display); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdk_x11_device_manager_core_class_init (GdkX11DeviceManagerCoreClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = gdk_x11_device_manager_core_finalize; - object_class->constructed = gdk_x11_device_manager_core_constructed; - object_class->set_property = gdk_device_manager_set_property; - object_class->get_property = gdk_device_manager_get_property; - - g_object_class_install_property (object_class, - PROP_DISPLAY, - g_param_spec_object ("display", - "Display", - "Display for the device manager", - GDK_TYPE_DISPLAY, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); -} - -static void -gdk_x11_device_manager_event_translator_init (GdkEventTranslatorIface *iface) -{ - iface->translate_event = gdk_x11_device_manager_core_translate_event; -} - -static GdkDevice * -create_core_pointer (GdkX11DeviceManagerCore *device_manager, - GdkDisplay *display) -{ - return g_object_new (GDK_TYPE_X11_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, - NULL); -} - -static GdkDevice * -create_core_keyboard (GdkX11DeviceManagerCore *device_manager, - GdkDisplay *display) -{ - return g_object_new (GDK_TYPE_X11_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, - NULL); -} - -static void -gdk_x11_device_manager_core_init (GdkX11DeviceManagerCore *device_manager) -{ -} - -static void -gdk_x11_device_manager_core_finalize (GObject *object) -{ - GdkX11DeviceManagerCore *device_manager_core; - - device_manager_core = GDK_X11_DEVICE_MANAGER_CORE (object); - - g_object_unref (device_manager_core->core_pointer); - g_object_unref (device_manager_core->core_keyboard); - - G_OBJECT_CLASS (gdk_x11_device_manager_core_parent_class)->finalize (object); -} - -static void -gdk_x11_device_manager_core_constructed (GObject *object) -{ - GdkX11DeviceManagerCore *device_manager; - GdkDisplay *display; - - device_manager = GDK_X11_DEVICE_MANAGER_CORE (object); - display = device_manager->display; - device_manager->core_pointer = create_core_pointer (device_manager, display); - device_manager->core_keyboard = create_core_keyboard (device_manager, display); - - _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard); - _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer); - - /* We expect subclasses to handle their own seats */ - if (G_OBJECT_TYPE (object) == GDK_TYPE_X11_DEVICE_MANAGER_CORE) - { - GdkSeat *seat; - - seat = gdk_seat_default_new_for_master_pair (device_manager->core_pointer, - device_manager->core_keyboard); - - gdk_display_add_seat (display, seat); - g_object_unref (seat); - } -} - -static void -translate_key_event (GdkDisplay *display, - GdkX11DeviceManagerCore *device_manager, - GdkEvent *event, - const XEvent *xevent) -{ - GdkKeymap *keymap = gdk_display_get_keymap (display); - GdkModifierType consumed, state; - - event->any.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE; - event->key.time = xevent->xkey.time; - gdk_event_set_device (event, device_manager->core_keyboard); - - event->key.state = (GdkModifierType) xevent->xkey.state; - event->key.group = gdk_x11_keymap_get_group_for_state (keymap, xevent->xkey.state); - event->key.hardware_keycode = xevent->xkey.keycode; - gdk_event_set_scancode (event, xevent->xkey.keycode); - - event->key.keyval = GDK_KEY_VoidSymbol; - - gdk_keymap_translate_keyboard_state (keymap, - event->key.hardware_keycode, - event->key.state, - event->key.group, - &event->key.keyval, - NULL, NULL, &consumed); - - state = event->key.state & ~consumed; - _gdk_x11_keymap_add_virt_mods (keymap, &state); - event->key.state |= state; - - event->key.is_modifier = gdk_x11_keymap_key_is_modifier (keymap, event->key.hardware_keycode); - -#ifdef G_ENABLE_DEBUG - if (GDK_DISPLAY_DEBUG_CHECK (display, EVENTS)) - { - g_message ("%s:\t\twindow: %ld key: %12s %d", - event->any.type == GDK_KEY_PRESS ? "key press " : "key release", - xevent->xkey.window, - event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)", - event->key.keyval); - } -#endif /* G_ENABLE_DEBUG */ - return; -} - -#ifdef G_ENABLE_DEBUG -static const char notify_modes[][19] = { - "NotifyNormal", - "NotifyGrab", - "NotifyUngrab", - "NotifyWhileGrabbed" -}; - -static const char notify_details[][23] = { - "NotifyAncestor", - "NotifyVirtual", - "NotifyInferior", - "NotifyNonlinear", - "NotifyNonlinearVirtual", - "NotifyPointer", - "NotifyPointerRoot", - "NotifyDetailNone" -}; -#endif - -static void -set_user_time (GdkSurface *surface, - GdkEvent *event) -{ - g_return_if_fail (event != NULL); - - surface = gdk_surface_get_toplevel (event->any.surface); - g_return_if_fail (GDK_IS_SURFACE (surface)); - - /* If an event doesn't have a valid timestamp, we shouldn't use it - * to update the latest user interaction time. - */ - if (gdk_event_get_time (event) != GDK_CURRENT_TIME) - gdk_x11_surface_set_user_time (gdk_surface_get_toplevel (surface), - gdk_event_get_time (event)); -} - -static GdkCrossingMode -translate_crossing_mode (int mode) -{ - switch (mode) - { - case NotifyNormal: - return GDK_CROSSING_NORMAL; - case NotifyGrab: - return GDK_CROSSING_GRAB; - case NotifyUngrab: - return GDK_CROSSING_UNGRAB; - default: - g_assert_not_reached (); - return GDK_CROSSING_NORMAL; - } -} - -static GdkNotifyType -translate_notify_type (int detail) -{ - switch (detail) - { - case NotifyInferior: - return GDK_NOTIFY_INFERIOR; - case NotifyAncestor: - return GDK_NOTIFY_ANCESTOR; - case NotifyVirtual: - return GDK_NOTIFY_VIRTUAL; - case NotifyNonlinear: - return GDK_NOTIFY_NONLINEAR; - case NotifyNonlinearVirtual: - return GDK_NOTIFY_NONLINEAR_VIRTUAL; - default: - g_assert_not_reached (); - return GDK_NOTIFY_UNKNOWN; - } -} - -static gboolean -is_parent_of (GdkSurface *parent, - GdkSurface *child) -{ - GdkSurface *w; - - w = child; - while (w != NULL) - { - if (w == parent) - return TRUE; - - w = gdk_surface_get_parent (w); - } - - return FALSE; -} - -static GdkSurface * -get_event_surface (GdkEventTranslator *translator, - const XEvent *xevent) -{ - GdkDisplay *display; - GdkSurface *surface; - - display = GDK_X11_DEVICE_MANAGER_CORE (translator)->display; - surface = gdk_x11_surface_lookup_for_display (display, xevent->xany.window); - - /* Apply keyboard grabs to non-native windows */ - if (xevent->type == KeyPress || xevent->type == KeyRelease) - { - GdkDeviceGrabInfo *info; - gulong serial; - - serial = _gdk_display_get_next_serial (display); - info = _gdk_display_has_device_grab (display, - GDK_X11_DEVICE_MANAGER_CORE (translator)->core_keyboard, - serial); - if (info && - (!is_parent_of (info->surface, surface) || - !info->owner_events)) - { - /* Report key event against grab surface */ - surface = info->surface; - } - } - - return surface; -} - -static gboolean -gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator, - GdkDisplay *display, - GdkEvent *event, - const XEvent *xevent) -{ - GdkSurfaceImplX11 *impl; - GdkX11DeviceManagerCore *device_manager; - GdkSurface *surface; - gboolean return_val; - int scale; - GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); - - device_manager = GDK_X11_DEVICE_MANAGER_CORE (translator); - - surface = get_event_surface (translator, xevent); - - scale = 1; - if (surface) - { - if (GDK_SURFACE_DESTROYED (surface) || !GDK_IS_SURFACE (surface)) - return FALSE; - - g_object_ref (surface); - impl = GDK_SURFACE_IMPL_X11 (surface->impl); - scale = impl->surface_scale; - } - - event->any.surface = surface; - event->any.send_event = xevent->xany.send_event ? TRUE : FALSE; - - if (surface && GDK_SURFACE_DESTROYED (surface)) - { - if (xevent->type != DestroyNotify) - { - return_val = FALSE; - goto done; - } - } - - if (surface && - (xevent->type == MotionNotify || - xevent->type == ButtonRelease)) - { - if (_gdk_x11_moveresize_handle_event (xevent)) - { - return_val = FALSE; - goto done; - } - } - - /* We do a "manual" conversion of the XEvent to a - * GdkEvent. The structures are mostly the same so - * the conversion is fairly straightforward. We also - * optionally print debugging info regarding events - * received. - */ - - return_val = TRUE; - - switch (xevent->type) - { - case KeyPress: - if (surface == NULL) - { - return_val = FALSE; - break; - } - translate_key_event (display, device_manager, event, xevent); - set_user_time (surface, event); - break; - - case KeyRelease: - if (surface == NULL) - { - return_val = FALSE; - break; - } - - /* Emulate detectable auto-repeat by checking to see - * if the next event is a key press with the same - * keycode and timestamp, and if so, ignoring the event. - */ - - if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display)) - { - XEvent next_event; - - XPeekEvent (xevent->xkey.display, &next_event); - - if (next_event.type == KeyPress && - next_event.xkey.keycode == xevent->xkey.keycode && - next_event.xkey.time == xevent->xkey.time) - { - return_val = FALSE; - break; - } - } - - translate_key_event (display, device_manager, event, xevent); - break; - - case ButtonPress: - GDK_DISPLAY_NOTE (display, EVENTS, - g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d", - xevent->xbutton.window, - xevent->xbutton.x, xevent->xbutton.y, - xevent->xbutton.button)); - - if (surface == NULL) - { - return_val = FALSE; - break; - } - - /* If we get a ButtonPress event where the button is 4 or 5, - it's a Scroll event */ - switch (xevent->xbutton.button) - { - case 4: /* up */ - case 5: /* down */ - case 6: /* left */ - case 7: /* right */ - event->any.type = GDK_SCROLL; - - if (xevent->xbutton.button == 4) - event->scroll.direction = GDK_SCROLL_UP; - else if (xevent->xbutton.button == 5) - event->scroll.direction = GDK_SCROLL_DOWN; - else if (xevent->xbutton.button == 6) - event->scroll.direction = GDK_SCROLL_LEFT; - else - event->scroll.direction = GDK_SCROLL_RIGHT; - - event->any.surface = surface; - event->scroll.time = xevent->xbutton.time; - event->scroll.x = (gdouble) xevent->xbutton.x / scale; - event->scroll.y = (gdouble) xevent->xbutton.y / scale; - event->scroll.x_root = (gdouble) xevent->xbutton.x_root / scale; - event->scroll.y_root = (gdouble) xevent->xbutton.y_root / scale; - event->scroll.state = (GdkModifierType) xevent->xbutton.state; - gdk_event_set_device (event, device_manager->core_pointer); - - event->scroll.delta_x = 0; - event->scroll.delta_y = 0; - - gdk_event_set_display (event, display); - - break; - - default: - event->any.type = GDK_BUTTON_PRESS; - event->any.surface = surface; - event->button.time = xevent->xbutton.time; - event->button.x = (gdouble) xevent->xbutton.x / scale; - event->button.y = (gdouble) xevent->xbutton.y / scale; - event->button.x_root = (gdouble) xevent->xbutton.x_root / scale; - event->button.y_root = (gdouble) xevent->xbutton.y_root / scale; - event->button.axes = NULL; - event->button.state = (GdkModifierType) xevent->xbutton.state; - event->button.button = xevent->xbutton.button; - gdk_event_set_device (event, device_manager->core_pointer); - - gdk_event_set_display (event, display); - - break; - } - - set_user_time (surface, event); - - break; - - case ButtonRelease: - GDK_DISPLAY_NOTE (display, EVENTS, - g_message ("button release:\twindow: %ld x,y: %d %d button: %d", - xevent->xbutton.window, - xevent->xbutton.x, xevent->xbutton.y, - xevent->xbutton.button)); - - if (surface == NULL) - { - return_val = FALSE; - break; - } - - /* We treat button presses as scroll wheel events, so ignore the release */ - if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 || - xevent->xbutton.button == 6 || xevent->xbutton.button == 7) - { - return_val = FALSE; - break; - } - - event->any.type = GDK_BUTTON_RELEASE; - event->any.surface = surface; - event->button.time = xevent->xbutton.time; - event->button.x = (gdouble) xevent->xbutton.x / scale; - event->button.y = (gdouble) xevent->xbutton.y / scale; - event->button.x_root = (gdouble) xevent->xbutton.x_root / scale; - event->button.y_root = (gdouble) xevent->xbutton.y_root / scale; - event->button.axes = NULL; - event->button.state = (GdkModifierType) xevent->xbutton.state; - event->button.button = xevent->xbutton.button; - gdk_event_set_device (event, device_manager->core_pointer); - - gdk_event_set_display (event, display); - - break; - - case MotionNotify: - GDK_DISPLAY_NOTE (display, EVENTS, - g_message ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s", - xevent->xmotion.window, - xevent->xmotion.x, xevent->xmotion.y, - (xevent->xmotion.is_hint) ? "true" : "false")); - - if (surface == NULL) - { - return_val = FALSE; - break; - } - - event->any.type = GDK_MOTION_NOTIFY; - event->any.surface = surface; - event->motion.time = xevent->xmotion.time; - event->motion.x = (gdouble) xevent->xmotion.x / scale; - event->motion.y = (gdouble) xevent->xmotion.y / scale; - event->motion.x_root = (gdouble) xevent->xmotion.x_root / scale; - event->motion.y_root = (gdouble) xevent->xmotion.y_root / scale; - event->motion.axes = NULL; - event->motion.state = (GdkModifierType) xevent->xmotion.state; - gdk_event_set_device (event, device_manager->core_pointer); - - gdk_event_set_display (event, display); - - break; - - case EnterNotify: - GDK_DISPLAY_NOTE (display, EVENTS, - g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld", - xevent->xcrossing.window, - xevent->xcrossing.detail, - xevent->xcrossing.subwindow)); - - if (surface == NULL) - { - return_val = FALSE; - break; - } - - gdk_event_set_display (event, display); - - event->any.type = GDK_ENTER_NOTIFY; - event->any.surface = surface; - gdk_event_set_device (event, device_manager->core_pointer); - - /* If the subwindow field of the XEvent is non-NULL, then - * lookup the corresponding GdkSurface. - */ - if (xevent->xcrossing.subwindow != None) - event->crossing.child_surface = gdk_x11_surface_lookup_for_display (display, xevent->xcrossing.subwindow); - else - event->crossing.child_surface = NULL; - - event->crossing.time = xevent->xcrossing.time; - event->crossing.x = (gdouble) xevent->xcrossing.x / scale; - event->crossing.y = (gdouble) xevent->xcrossing.y / scale; - event->crossing.x_root = (gdouble) xevent->xcrossing.x_root / scale; - event->crossing.y_root = (gdouble) xevent->xcrossing.y_root / scale; - - event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode); - event->crossing.detail = translate_notify_type (xevent->xcrossing.detail); - - event->crossing.focus = xevent->xcrossing.focus; - event->crossing.state = xevent->xcrossing.state; - - break; - - case LeaveNotify: - GDK_DISPLAY_NOTE (display, EVENTS, - g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld", - xevent->xcrossing.window, - xevent->xcrossing.detail, xevent->xcrossing.subwindow)); - - if (surface == NULL) - { - return_val = FALSE; - break; - } - - gdk_event_set_display (event, display); - - event->any.type = GDK_LEAVE_NOTIFY; - event->any.surface = surface; - gdk_event_set_device (event, device_manager->core_pointer); - - /* If the subwindow field of the XEvent is non-NULL, then - * lookup the corresponding GdkSurface. - */ - if (xevent->xcrossing.subwindow != None) - event->crossing.child_surface = gdk_x11_surface_lookup_for_display (display, xevent->xcrossing.subwindow); - else - event->crossing.child_surface = NULL; - - event->crossing.time = xevent->xcrossing.time; - event->crossing.x = (gdouble) xevent->xcrossing.x / scale; - event->crossing.y = (gdouble) xevent->xcrossing.y / scale; - event->crossing.x_root = (gdouble) xevent->xcrossing.x_root / scale; - event->crossing.y_root = (gdouble) xevent->xcrossing.y_root / scale; - - event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode); - event->crossing.detail = translate_notify_type (xevent->xcrossing.detail); - - event->crossing.focus = xevent->xcrossing.focus; - event->crossing.state = xevent->xcrossing.state; - - break; - - case FocusIn: - case FocusOut: - if (surface) - _gdk_device_manager_core_handle_focus (surface, - xevent->xfocus.window, - device_manager->core_keyboard, - NULL, - xevent->type == FocusIn, - xevent->xfocus.detail, - xevent->xfocus.mode); - return_val = FALSE; - break; - - default: - return_val = FALSE; - } - - done: - if (return_val) - { - if (event->any.surface) - g_object_ref (event->any.surface); - - if (((event->any.type == GDK_ENTER_NOTIFY) || - (event->any.type == GDK_LEAVE_NOTIFY)) && - (event->crossing.child_surface != NULL)) - g_object_ref (event->crossing.child_surface); - } - else - { - /* Mark this event as having no resources to be freed */ - event->any.surface = NULL; - event->any.type = GDK_NOTHING; - } - - if (surface) - g_object_unref (surface); - - return return_val; -} - -/* We only care about focus events that indicate that _this_ - * surface (not a ancestor or child) got or lost the focus - */ -void -_gdk_device_manager_core_handle_focus (GdkSurface *surface, - Window original, - GdkDevice *device, - GdkDevice *source_device, - gboolean focus_in, - int detail, - int mode) -{ - GdkToplevelX11 *toplevel; - GdkX11Screen *x11_screen; - gboolean had_focus; - - g_return_if_fail (GDK_IS_SURFACE (surface)); - g_return_if_fail (GDK_IS_DEVICE (device)); - g_return_if_fail (source_device == NULL || GDK_IS_DEVICE (source_device)); - - GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, - g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s", - GDK_SURFACE_XID (surface), - notify_details[detail], - notify_modes[mode])); - - toplevel = _gdk_x11_surface_get_toplevel (surface); - - if (!toplevel) - return; - - if (toplevel->focus_window == original) - return; - - had_focus = HAS_FOCUS (toplevel); - x11_screen = GDK_X11_SCREEN (GDK_SURFACE_SCREEN (surface)); - - switch (detail) - { - case NotifyAncestor: - case NotifyVirtual: - /* When the focus moves from an ancestor of the window to - * the window or a descendent of the window, *and* the - * pointer is inside the window, then we were previously - * receiving keystroke events in the has_pointer_focus - * case and are now receiving them in the - * has_focus_window case. - */ - if (toplevel->has_pointer && - !x11_screen->wmspec_check_window && - mode != NotifyGrab && - mode != XINotifyPassiveGrab && - mode != XINotifyPassiveUngrab && - mode != NotifyUngrab) - toplevel->has_pointer_focus = (focus_in) ? FALSE : TRUE; - G_GNUC_FALLTHROUGH; - - case NotifyNonlinear: - case NotifyNonlinearVirtual: - if (mode != NotifyGrab && - mode != XINotifyPassiveGrab && - mode != XINotifyPassiveUngrab && - mode != NotifyUngrab) - toplevel->has_focus_window = (focus_in) ? TRUE : FALSE; - /* We pretend that the focus moves to the grab - * window, so we pay attention to NotifyGrab - * NotifyUngrab, and ignore NotifyWhileGrabbed - */ - if (mode != NotifyWhileGrabbed) - toplevel->has_focus = (focus_in) ? TRUE : FALSE; - break; - case NotifyPointer: - /* The X server sends NotifyPointer/NotifyGrab, - * but the pointer focus is ignored while a - * grab is in effect - */ - if (!x11_screen->wmspec_check_window && - mode != NotifyGrab && - mode != XINotifyPassiveGrab && - mode != XINotifyPassiveUngrab && - mode != NotifyUngrab) - toplevel->has_pointer_focus = (focus_in) ? TRUE : FALSE; - break; - case NotifyInferior: - case NotifyPointerRoot: - case NotifyDetailNone: - default: - break; - } - - if (HAS_FOCUS (toplevel) != had_focus) - { - GdkEvent *event; - - event = gdk_event_new (GDK_FOCUS_CHANGE); - event->any.surface = g_object_ref (surface); - event->any.send_event = FALSE; - event->focus_change.in = focus_in; - gdk_event_set_device (event, device); - if (source_device) - gdk_event_set_source_device (event, source_device); - - gdk_display_put_event (gdk_surface_get_display (surface), event); - g_object_unref (event); - } -} - diff --git a/gdk/x11/gdkdevicemanager-x11.c b/gdk/x11/gdkdevicemanager-x11.c index dd62f27d08..1478b9242a 100644 --- a/gdk/x11/gdkdevicemanager-x11.c +++ b/gdk/x11/gdkdevicemanager-x11.c @@ -17,8 +17,6 @@ #include "config.h" -#include "gdkx11devicemanager-core.h" -#include "gdkdevicemanagerprivate-core.h" #include "gdkx11devicemanager-xi2.h" #include "gdkinternals.h" #include "gdkprivate-x11.h" @@ -30,7 +28,7 @@ #define VIRTUAL_CORE_POINTER_ID 2 #define VIRTUAL_CORE_KEYBOARD_ID 3 -GdkX11DeviceManagerCore * +GdkX11DeviceManagerXI2 * _gdk_x11_device_manager_new (GdkDisplay *display) { int opcode, firstevent, firsterror; @@ -59,7 +57,7 @@ _gdk_x11_device_manager_new (GdkDisplay *display) "minor", minor, NULL); - return GDK_X11_DEVICE_MANAGER_CORE (device_manager_xi2); + return device_manager_xi2; } } @@ -68,17 +66,17 @@ _gdk_x11_device_manager_new (GdkDisplay *display) /** * gdk_x11_device_manager_lookup: - * @device_manager: (type GdkX11DeviceManagerCore): a #GdkDeviceManager + * @device_manager: (type GdkX11DeviceManagerXI2): a #GdkDeviceManager * @device_id: a device ID, as understood by the XInput2 protocol * * Returns the #GdkDevice that wraps the given device ID. * - * Returns: (transfer none) (allow-none) (type GdkX11DeviceCore): The #GdkDevice wrapping the device ID, + * Returns: (transfer none) (allow-none) (type GdkX11DeviceXI2): The #GdkDevice wrapping the device ID, * or %NULL if the given ID doesn’t currently represent a device. **/ GdkDevice * -gdk_x11_device_manager_lookup (GdkX11DeviceManagerCore *device_manager, - gint device_id) +gdk_x11_device_manager_lookup (GdkX11DeviceManagerXI2 *device_manager, + gint device_id) { g_return_val_if_fail (GDK_IS_X11_DEVICE_MANAGER_XI2 (device_manager), NULL); @@ -88,7 +86,7 @@ gdk_x11_device_manager_lookup (GdkX11DeviceManagerCore *device_manager, /** * gdk_x11_device_get_id: - * @device: (type GdkX11DeviceCore): a #GdkDevice + * @device: (type GdkX11DeviceXI2): a #GdkDevice * * Returns the device ID as seen by XInput2. * diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c index 01d51d3d3a..3cc4af03ea 100644 --- a/gdk/x11/gdkdevicemanager-xi2.c +++ b/gdk/x11/gdkdevicemanager-xi2.c @@ -20,8 +20,6 @@ #include "gdkx11devicemanager-xi2.h" #include "gdkx11device-xi2.h" -#include "gdkx11devicemanager-core.h" -#include "gdkdevicemanagerprivate-core.h" #include "gdkdeviceprivate.h" #include "gdkdevicetoolprivate.h" #include "gdkdisplayprivate.h" @@ -40,6 +38,29 @@ #include +#ifdef G_ENABLE_DEBUG +static const char notify_modes[][19] = { + "NotifyNormal", + "NotifyGrab", + "NotifyUngrab", + "NotifyWhileGrabbed" +}; + +static const char notify_details[][23] = { + "NotifyAncestor", + "NotifyVirtual", + "NotifyInferior", + "NotifyNonlinear", + "NotifyNonlinearVirtual", + "NotifyPointer", + "NotifyPointerRoot", + "NotifyDetailNone" +}; +#endif + +#define HAS_FOCUS(toplevel) \ + ((toplevel)->has_focus || (toplevel)->has_pointer_focus) + static const char *wacom_type_atoms[] = { "STYLUS", "CURSOR", @@ -59,8 +80,9 @@ enum { struct _GdkX11DeviceManagerXI2 { - GdkX11DeviceManagerCore parent_object; + GObject parent_object; + GdkDisplay *display; GHashTable *id_table; GList *devices; @@ -72,12 +94,12 @@ struct _GdkX11DeviceManagerXI2 struct _GdkX11DeviceManagerXI2Class { - GdkX11DeviceManagerCoreClass parent_class; + GObjectClass parent_class; }; static void gdk_x11_device_manager_xi2_event_translator_init (GdkEventTranslatorIface *iface); -G_DEFINE_TYPE_WITH_CODE (GdkX11DeviceManagerXI2, gdk_x11_device_manager_xi2, GDK_TYPE_X11_DEVICE_MANAGER_CORE, +G_DEFINE_TYPE_WITH_CODE (GdkX11DeviceManagerXI2, gdk_x11_device_manager_xi2, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR, gdk_x11_device_manager_xi2_event_translator_init)) @@ -92,8 +114,6 @@ static void gdk_x11_device_manager_xi2_get_property (GObject *object, GValue *value, GParamSpec *pspec); -static GdkDevice * gdk_x11_device_manager_xi2_get_client_pointer (GdkX11DeviceManagerXI2 *device_manager); - static gboolean gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, GdkDisplay *display, GdkEvent *event, @@ -107,6 +127,7 @@ static GdkSurface * gdk_x11_device_manager_xi2_get_surface (GdkEventTra enum { PROP_0, + PROP_DISPLAY, PROP_OPCODE, PROP_MAJOR, PROP_MINOR @@ -122,6 +143,14 @@ gdk_x11_device_manager_xi2_class_init (GdkX11DeviceManagerXI2Class *klass) object_class->set_property = gdk_x11_device_manager_xi2_set_property; object_class->get_property = gdk_x11_device_manager_xi2_get_property; + g_object_class_install_property (object_class, + PROP_DISPLAY, + g_param_spec_object ("display", + "Display", + "Display for the device manager", + GDK_TYPE_DISPLAY, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_OPCODE, g_param_spec_int ("opcode", @@ -165,7 +194,7 @@ _gdk_x11_device_manager_xi2_select_events (GdkX11DeviceManagerXI2 *device_manage GdkDisplay *display; Display *xdisplay; - display = GDK_X11_DEVICE_MANAGER_CORE (device_manager)->display; + display = device_manager->display; xdisplay = GDK_DISPLAY_XDISPLAY (display); XISelectEvents (xdisplay, xwindow, event_mask, 1); @@ -553,7 +582,7 @@ ensure_seat_for_device_pair (GdkX11DeviceManagerXI2 *device_manager, GdkDisplay *display; GdkSeat *seat; - display = GDK_X11_DEVICE_MANAGER_CORE (device_manager)->display; + display = device_manager->display; seat = gdk_device_get_seat (device1); if (!seat) @@ -583,7 +612,7 @@ add_device (GdkX11DeviceManagerXI2 *device_manager, GdkDisplay *display; GdkDevice *device; - display = GDK_X11_DEVICE_MANAGER_CORE (device_manager)->display; + display = device_manager->display; device = create_device (device_manager, display, dev); g_hash_table_replace (device_manager->id_table, @@ -717,7 +746,7 @@ gdk_x11_device_manager_xi2_constructed (GObject *object) G_OBJECT_CLASS (gdk_x11_device_manager_xi2_parent_class)->constructed (object); device_manager = GDK_X11_DEVICE_MANAGER_XI2 (object); - display = GDK_X11_DEVICE_MANAGER_CORE (device_manager)->display; + display = device_manager->display; xdisplay = GDK_DISPLAY_XDISPLAY (display); g_assert (device_manager->major == 2); @@ -795,21 +824,6 @@ gdk_x11_device_manager_xi2_dispose (GObject *object) G_OBJECT_CLASS (gdk_x11_device_manager_xi2_parent_class)->dispose (object); } -static GdkDevice * -gdk_x11_device_manager_xi2_get_client_pointer (GdkX11DeviceManagerXI2 *device_manager) -{ - GdkDisplay *display; - int device_id; - - display = GDK_X11_DEVICE_MANAGER_CORE (device_manager)->display; - - XIGetClientPointer (GDK_DISPLAY_XDISPLAY (display), - None, &device_id); - - return g_hash_table_lookup (device_manager->id_table, - GINT_TO_POINTER (device_id)); -} - static void gdk_x11_device_manager_xi2_set_property (GObject *object, guint prop_id, @@ -822,6 +836,9 @@ gdk_x11_device_manager_xi2_set_property (GObject *object, switch (prop_id) { + case PROP_DISPLAY: + device_manager->display = g_value_get_object (value); + break; case PROP_OPCODE: device_manager->opcode = g_value_get_int (value); break; @@ -849,6 +866,9 @@ gdk_x11_device_manager_xi2_get_property (GObject *object, switch (prop_id) { + case PROP_DISPLAY: + g_value_set_object (value, device_manager->display); + break; case PROP_OPCODE: g_value_set_int (value, device_manager->opcode); break; @@ -883,7 +903,7 @@ handle_hierarchy_changed (GdkX11DeviceManagerXI2 *device_manager, int ndevices; gint i; - display = GDK_X11_DEVICE_MANAGER_CORE (device_manager)->display; + display = device_manager->display; xdisplay = GDK_DISPLAY_XDISPLAY (display); for (i = 0; i < ev->num_info; i++) @@ -958,7 +978,7 @@ handle_device_changed (GdkX11DeviceManagerXI2 *device_manager, GdkDisplay *display; GdkDevice *device, *source_device; - display = GDK_X11_DEVICE_MANAGER_CORE (device_manager)->display; + display = device_manager->display; device = g_hash_table_lookup (device_manager->id_table, GUINT_TO_POINTER (ev->deviceid)); source_device = g_hash_table_lookup (device_manager->id_table, @@ -1256,7 +1276,7 @@ get_event_surface (GdkEventTranslator *translator, GdkSurface *surface = NULL; gboolean should_have_window = TRUE; - display = GDK_X11_DEVICE_MANAGER_CORE (translator)->display; + display = GDK_X11_DEVICE_MANAGER_XI2 (translator)->display; switch (ev->evtype) { @@ -1321,81 +1341,6 @@ get_event_surface (GdkEventTranslator *translator, return TRUE; } -static gboolean -gdk_x11_device_manager_xi2_translate_core_event (GdkEventTranslator *translator, - GdkDisplay *display, - GdkEvent *event, - const XEvent *xevent) -{ - GdkEventTranslatorIface *parent_iface; - gboolean keyboard = FALSE; - GdkDevice *device; - - if ((xevent->type == KeyPress || xevent->type == KeyRelease) && - (xevent->xkey.keycode == 0 || xevent->xkey.serial == 0)) - { - /* The X input methods (when triggered via XFilterEvent) - * generate a core key press event with keycode 0 to signal the - * end of a key sequence. We use the core translate_event - * implementation to translate this event. - * - * Other less educated IM modules like to filter every keypress, - * only to have these replaced by their own homegrown events, - * these events oddly have serial=0, so we try to catch these. - * - * This is just a bandaid fix to keep xim working with a single - * keyboard until XFilterEvent learns about XI2. - */ - keyboard = TRUE; - } - else if (xevent->xany.send_event) - { - /* If another process sends us core events, process them; we - * assume that it won't send us redundant core and XI2 events. - * (At the moment, it's not possible to send XI2 events anyway. - * In the future, an app that was trying to decide whether to - * send core or XI2 events could look at the event mask on the - * surface to see which kind we are listening to.) - */ - switch (xevent->type) - { - case KeyPress: - case KeyRelease: - case FocusIn: - case FocusOut: - keyboard = TRUE; - break; - - case ButtonPress: - case ButtonRelease: - case MotionNotify: - case EnterNotify: - case LeaveNotify: - break; - - default: - return FALSE; - } - } - else - return FALSE; - - parent_iface = g_type_interface_peek_parent (GDK_EVENT_TRANSLATOR_GET_IFACE (translator)); - if (!parent_iface->translate_event (translator, display, event, xevent)) - return FALSE; - - /* The core device manager sets a core device on the event. - * We need to override that with an XI2 device, since we are - * using XI2. - */ - device = gdk_x11_device_manager_xi2_get_client_pointer ((GdkX11DeviceManagerXI2 *)translator); - if (keyboard) - device = gdk_device_get_associated_device (device); - gdk_event_set_device (event, device); - - return TRUE; -} - static gboolean scroll_valuators_changed (GdkX11DeviceXI2 *device, XIValuatorState *valuators, @@ -1437,6 +1382,113 @@ scroll_valuators_changed (GdkX11DeviceXI2 *device, return has_scroll_valuators; } +/* We only care about focus events that indicate that _this_ + * surface (not a ancestor or child) got or lost the focus + */ +static void +_gdk_device_manager_xi2_handle_focus (GdkSurface *surface, + Window original, + GdkDevice *device, + GdkDevice *source_device, + gboolean focus_in, + int detail, + int mode) +{ + GdkToplevelX11 *toplevel; + GdkX11Screen *x11_screen; + gboolean had_focus; + + g_return_if_fail (GDK_IS_SURFACE (surface)); + g_return_if_fail (GDK_IS_DEVICE (device)); + g_return_if_fail (source_device == NULL || GDK_IS_DEVICE (source_device)); + + GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, + g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s", + GDK_SURFACE_XID (surface), + notify_details[detail], + notify_modes[mode])); + + toplevel = _gdk_x11_surface_get_toplevel (surface); + + if (!toplevel) + return; + + if (toplevel->focus_window == original) + return; + + had_focus = HAS_FOCUS (toplevel); + x11_screen = GDK_X11_SCREEN (GDK_SURFACE_SCREEN (surface)); + + switch (detail) + { + case NotifyAncestor: + case NotifyVirtual: + /* When the focus moves from an ancestor of the window to + * the window or a descendent of the window, *and* the + * pointer is inside the window, then we were previously + * receiving keystroke events in the has_pointer_focus + * case and are now receiving them in the + * has_focus_window case. + */ + if (toplevel->has_pointer && + !x11_screen->wmspec_check_window && + mode != NotifyGrab && + mode != XINotifyPassiveGrab && + mode != XINotifyPassiveUngrab && + mode != NotifyUngrab) + toplevel->has_pointer_focus = (focus_in) ? FALSE : TRUE; + G_GNUC_FALLTHROUGH; + + case NotifyNonlinear: + case NotifyNonlinearVirtual: + if (mode != NotifyGrab && + mode != XINotifyPassiveGrab && + mode != XINotifyPassiveUngrab && + mode != NotifyUngrab) + toplevel->has_focus_window = (focus_in) ? TRUE : FALSE; + /* We pretend that the focus moves to the grab + * window, so we pay attention to NotifyGrab + * NotifyUngrab, and ignore NotifyWhileGrabbed + */ + if (mode != NotifyWhileGrabbed) + toplevel->has_focus = (focus_in) ? TRUE : FALSE; + break; + case NotifyPointer: + /* The X server sends NotifyPointer/NotifyGrab, + * but the pointer focus is ignored while a + * grab is in effect + */ + if (!x11_screen->wmspec_check_window && + mode != NotifyGrab && + mode != XINotifyPassiveGrab && + mode != XINotifyPassiveUngrab && + mode != NotifyUngrab) + toplevel->has_pointer_focus = (focus_in) ? TRUE : FALSE; + break; + case NotifyInferior: + case NotifyPointerRoot: + case NotifyDetailNone: + default: + break; + } + + if (HAS_FOCUS (toplevel) != had_focus) + { + GdkEvent *event; + + event = gdk_event_new (GDK_FOCUS_CHANGE); + event->any.surface = g_object_ref (surface); + event->any.send_event = FALSE; + event->focus_change.in = focus_in; + gdk_event_set_device (event, device); + if (source_device) + gdk_event_set_source_device (event, source_device); + + gdk_display_put_event (gdk_surface_get_display (surface), event); + g_object_unref (event); + } +} + static gboolean gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, GdkDisplay *display, @@ -1455,9 +1507,8 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, device_manager = (GdkX11DeviceManagerXI2 *) translator; cookie = &xevent->xcookie; - if (xevent->type != GenericEvent) - return gdk_x11_device_manager_xi2_translate_core_event (translator, display, event, xevent); - else if (cookie->extension != device_manager->opcode) + if (xevent->type != GenericEvent || + cookie->extension != device_manager->opcode) return FALSE; ev = (XIEvent *) cookie->data; @@ -1948,13 +1999,13 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, source_device = g_hash_table_lookup (device_manager->id_table, GUINT_TO_POINTER (xev->sourceid)); - _gdk_device_manager_core_handle_focus (surface, - xev->event, - device, - source_device, - (ev->evtype == XI_FocusIn) ? TRUE : FALSE, - xev->detail, - xev->mode); + _gdk_device_manager_xi2_handle_focus (surface, + xev->event, + device, + source_device, + (ev->evtype == XI_FocusIn) ? TRUE : FALSE, + xev->detail, + xev->mode); } return_val = FALSE; diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h index 4859c01422..c326b6a23e 100644 --- a/gdk/x11/gdkdisplay-x11.h +++ b/gdk/x11/gdkdisplay-x11.h @@ -44,7 +44,7 @@ struct _GdkX11Display GdkX11Screen *screen; GList *screens; GList *toplevels; - GdkX11DeviceManagerCore *device_manager; + GdkX11DeviceManagerXI2 *device_manager; GSource *event_source; diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h index 2700dcbe56..658a2d9b5a 100644 --- a/gdk/x11/gdkprivate-x11.h +++ b/gdk/x11/gdkprivate-x11.h @@ -130,7 +130,7 @@ gchar * _gdk_x11_display_utf8_to_string_target (GdkDisplay *display void _gdk_x11_device_check_extension_events (GdkDevice *device); -GdkX11DeviceManagerCore *_gdk_x11_device_manager_new (GdkDisplay *display); +GdkX11DeviceManagerXI2 *_gdk_x11_device_manager_new (GdkDisplay *display); guchar * _gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager_xi2, GdkEventMask event_mask, diff --git a/gdk/x11/gdkx-autocleanups.h b/gdk/x11/gdkx-autocleanups.h index a6e6e1c024..e615a14efd 100644 --- a/gdk/x11/gdkx-autocleanups.h +++ b/gdk/x11/gdkx-autocleanups.h @@ -22,8 +22,6 @@ #ifndef __GI_SCANNER__ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkX11AppLaunchContext, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkX11DeviceCore, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkX11DeviceManagerCore, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkX11DeviceManagerXI2, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkX11DeviceXI2, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkX11Display, g_object_unref) diff --git a/gdk/x11/gdkx.h b/gdk/x11/gdkx.h index 9fa9cb0711..2705305964 100644 --- a/gdk/x11/gdkx.h +++ b/gdk/x11/gdkx.h @@ -34,10 +34,8 @@ #include #include -#include #include #include -#include #include #include #include diff --git a/gdk/x11/gdkx11device-core.h b/gdk/x11/gdkx11device-core.h deleted file mode 100644 index a3cfa96a48..0000000000 --- a/gdk/x11/gdkx11device-core.h +++ /dev/null @@ -1,41 +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, see . - */ - -#ifndef __GDK_X11_DEVICE_CORE_H__ -#define __GDK_X11_DEVICE_CORE_H__ - -#include - -G_BEGIN_DECLS - -#define GDK_TYPE_X11_DEVICE_CORE (gdk_x11_device_core_get_type ()) -#define GDK_X11_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_X11_DEVICE_CORE, GdkX11DeviceCore)) -#define GDK_X11_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_X11_DEVICE_CORE, GdkX11DeviceCoreClass)) -#define GDK_IS_X11_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_X11_DEVICE_CORE)) -#define GDK_IS_X11_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_X11_DEVICE_CORE)) -#define GDK_X11_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_X11_DEVICE_CORE, GdkX11DeviceCoreClass)) - -typedef struct _GdkX11DeviceCore GdkX11DeviceCore; -typedef struct _GdkX11DeviceCoreClass GdkX11DeviceCoreClass; - - -GDK_AVAILABLE_IN_ALL -GType gdk_x11_device_core_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __GDK_X11_DEVICE_CORE_H__ */ diff --git a/gdk/x11/gdkx11devicemanager-core.h b/gdk/x11/gdkx11devicemanager-core.h deleted file mode 100644 index d1ea0b2b20..0000000000 --- a/gdk/x11/gdkx11devicemanager-core.h +++ /dev/null @@ -1,42 +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, see . - */ - -#ifndef __GDK_X11_DEVICE_MANAGER_CORE_H__ -#define __GDK_X11_DEVICE_MANAGER_CORE_H__ - -#include - -G_BEGIN_DECLS - -#define GDK_TYPE_X11_DEVICE_MANAGER_CORE (gdk_x11_device_manager_core_get_type ()) -#define GDK_X11_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_X11_DEVICE_MANAGER_CORE, GdkX11DeviceManagerCore)) -#define GDK_X11_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_X11_DEVICE_MANAGER_CORE, GdkX11DeviceManagerCoreClass)) -#define GDK_IS_X11_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_X11_DEVICE_MANAGER_CORE)) -#define GDK_IS_X11_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_X11_DEVICE_MANAGER_CORE)) -#define GDK_X11_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_X11_DEVICE_MANAGER_CORE, GdkX11DeviceManagerCoreClass)) - -typedef struct _GdkX11DeviceManagerCore GdkX11DeviceManagerCore; -typedef struct _GdkX11DeviceManagerCoreClass GdkX11DeviceManagerCoreClass; - - -GDK_AVAILABLE_IN_ALL -GType gdk_x11_device_manager_core_get_type (void) G_GNUC_CONST; - - -G_END_DECLS - -#endif /* __GDK_X11_DEVICE_MANAGER_CORE_H__ */ diff --git a/gdk/x11/gdkx11devicemanager.h b/gdk/x11/gdkx11devicemanager.h index b0cd50b423..e99806c6b2 100644 --- a/gdk/x11/gdkx11devicemanager.h +++ b/gdk/x11/gdkx11devicemanager.h @@ -23,7 +23,7 @@ #endif #include -#include +#include #include #include @@ -31,8 +31,8 @@ G_BEGIN_DECLS GDK_AVAILABLE_IN_ALL -GdkDevice * gdk_x11_device_manager_lookup (GdkX11DeviceManagerCore *device_manager, - gint device_id); +GdkDevice * gdk_x11_device_manager_lookup (GdkX11DeviceManagerXI2 *device_manager, + gint device_id); G_END_DECLS diff --git a/gdk/x11/meson.build b/gdk/x11/meson.build index 06d6d8b497..fce1a92079 100644 --- a/gdk/x11/meson.build +++ b/gdk/x11/meson.build @@ -5,9 +5,7 @@ gdk_x11_sources = files([ 'gdkcairocontext-x11.c', 'gdkclipboard-x11.c', 'gdkcursor-x11.c', - 'gdkdevice-core-x11.c', 'gdkdevice-xi2.c', - 'gdkdevicemanager-core-x11.c', 'gdkdevicemanager-x11.c', 'gdkdevicemanager-xi2.c', 'gdkdisplay-x11.c', @@ -36,10 +34,8 @@ gdk_x11_sources = files([ gdk_x11_public_headers = files([ 'gdkx-autocleanups.h', 'gdkx11applaunchcontext.h', - 'gdkx11device-core.h', 'gdkx11device-xi2.h', 'gdkx11device.h', - 'gdkx11devicemanager-core.h', 'gdkx11devicemanager-xi2.h', 'gdkx11devicemanager.h', 'gdkx11display.h', diff --git a/testsuite/gtk/objects-finalize.c b/testsuite/gtk/objects-finalize.c index b43ab812ee..bb7e51371d 100644 --- a/testsuite/gtk/objects-finalize.c +++ b/testsuite/gtk/objects-finalize.c @@ -132,7 +132,6 @@ main (int argc, char **argv) all_types[i] != GDK_TYPE_X11_SURFACE && all_types[i] != GDK_TYPE_X11_SCREEN && all_types[i] != GDK_TYPE_X11_DISPLAY && - all_types[i] != GDK_TYPE_X11_DEVICE_MANAGER_CORE && all_types[i] != GDK_TYPE_X11_DEVICE_MANAGER_XI2 && all_types[i] != GDK_TYPE_X11_GL_CONTEXT && #endif