forked from AuroraMiddleware/gtk
Merge branch 'wip/carlosg/no-x11-core-events' into 'master'
Drop support for X11 core events See merge request GNOME/gtk!846
This commit is contained in:
commit
6a27fe15e3
@ -241,9 +241,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* Define to 1 if XInput 2.0 is available */
|
||||
#mesondefine XINPUT_2
|
||||
|
||||
/* Define to 1 if XInput 2.2 is available */
|
||||
#mesondefine XINPUT_2_2
|
||||
|
||||
|
@ -823,7 +823,6 @@ gdk_x11_lookup_xdisplay
|
||||
gdk_x11_get_server_time
|
||||
gdk_x11_device_get_id
|
||||
gdk_x11_device_manager_lookup
|
||||
gdk_disable_multidevice
|
||||
gdk_x11_display_open
|
||||
gdk_x11_display_set_program_class
|
||||
gdk_x11_display_get_user_time
|
||||
@ -881,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
|
||||
@ -962,8 +949,6 @@ GDK_X11_SURFACE_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
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
|
||||
|
@ -65,15 +65,6 @@ The X11 GDK backend can be influenced with some additional environment variables
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><envar>GDK_CORE_DEVICE_EVENTS</envar></title>
|
||||
|
||||
<para>
|
||||
If set, GDK makes does not use the XInput extension, and only reacts
|
||||
to core X input events.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><envar>GDK_SCALE</envar></title>
|
||||
|
||||
|
@ -1,537 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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 <math.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -1,833 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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 &&
|
||||
#ifdef XINPUT_2
|
||||
mode != XINotifyPassiveGrab &&
|
||||
mode != XINotifyPassiveUngrab &&
|
||||
#endif /* XINPUT_2 */
|
||||
mode != NotifyUngrab)
|
||||
toplevel->has_pointer_focus = (focus_in) ? FALSE : TRUE;
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
case NotifyNonlinear:
|
||||
case NotifyNonlinearVirtual:
|
||||
if (mode != NotifyGrab &&
|
||||
#ifdef XINPUT_2
|
||||
mode != XINotifyPassiveGrab &&
|
||||
mode != XINotifyPassiveUngrab &&
|
||||
#endif /* XINPUT_2 */
|
||||
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 &&
|
||||
#ifdef XINPUT_2
|
||||
mode != XINotifyPassiveGrab &&
|
||||
mode != XINotifyPassiveUngrab &&
|
||||
#endif /* XINPUT_2 */
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -17,11 +17,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkx11devicemanager-core.h"
|
||||
#include "gdkdevicemanagerprivate-core.h"
|
||||
#ifdef XINPUT_2
|
||||
#include "gdkx11devicemanager-xi2.h"
|
||||
#endif
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdkdisplay-x11.h"
|
||||
@ -32,144 +28,74 @@
|
||||
#define VIRTUAL_CORE_POINTER_ID 2
|
||||
#define VIRTUAL_CORE_KEYBOARD_ID 3
|
||||
|
||||
static gboolean _gdk_disable_multidevice = FALSE;
|
||||
|
||||
GdkX11DeviceManagerCore *
|
||||
GdkX11DeviceManagerXI2 *
|
||||
_gdk_x11_device_manager_new (GdkDisplay *display)
|
||||
{
|
||||
if (!g_getenv ("GDK_CORE_DEVICE_EVENTS"))
|
||||
int opcode, firstevent, firsterror;
|
||||
Display *xdisplay;
|
||||
|
||||
xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||
|
||||
if (XQueryExtension (xdisplay, "XInputExtension",
|
||||
&opcode, &firstevent, &firsterror))
|
||||
{
|
||||
#ifdef XINPUT_2
|
||||
int opcode, firstevent, firsterror;
|
||||
Display *xdisplay;
|
||||
int major, minor;
|
||||
|
||||
xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||
major = 2;
|
||||
minor = 3;
|
||||
|
||||
if (XQueryExtension (xdisplay, "XInputExtension",
|
||||
&opcode, &firstevent, &firsterror))
|
||||
if (XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
|
||||
{
|
||||
int major, minor;
|
||||
GdkX11DeviceManagerXI2 *device_manager_xi2;
|
||||
|
||||
major = 2;
|
||||
minor = 3;
|
||||
GDK_DISPLAY_NOTE (display, INPUT, g_message ("Creating XI2 device manager"));
|
||||
|
||||
if (!_gdk_disable_multidevice &&
|
||||
XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
|
||||
{
|
||||
GdkX11DeviceManagerXI2 *device_manager_xi2;
|
||||
device_manager_xi2 = g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_XI2,
|
||||
"display", display,
|
||||
"opcode", opcode,
|
||||
"major", major,
|
||||
"minor", minor,
|
||||
NULL);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, INPUT, g_message ("Creating XI2 device manager"));
|
||||
|
||||
device_manager_xi2 = g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_XI2,
|
||||
"display", display,
|
||||
"opcode", opcode,
|
||||
"major", major,
|
||||
"minor", minor,
|
||||
NULL);
|
||||
|
||||
return GDK_X11_DEVICE_MANAGER_CORE (device_manager_xi2);
|
||||
}
|
||||
return device_manager_xi2;
|
||||
}
|
||||
#endif /* XINPUT_2 */
|
||||
}
|
||||
|
||||
GDK_DISPLAY_NOTE (display, INPUT, g_message ("Creating core device manager"));
|
||||
|
||||
return g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_CORE,
|
||||
"display", display,
|
||||
NULL);
|
||||
g_error ("XInput2 support not found on 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)
|
||||
{
|
||||
GdkDevice *device = NULL;
|
||||
g_return_val_if_fail (GDK_IS_X11_DEVICE_MANAGER_XI2 (device_manager), NULL);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_X11_DEVICE_MANAGER_CORE (device_manager), NULL);
|
||||
|
||||
#ifdef XINPUT_2
|
||||
if (GDK_IS_X11_DEVICE_MANAGER_XI2 (device_manager))
|
||||
device = _gdk_x11_device_manager_xi2_lookup (GDK_X11_DEVICE_MANAGER_XI2 (device_manager),
|
||||
device_id);
|
||||
else
|
||||
#endif /* XINPUT_2 */
|
||||
if (GDK_IS_X11_DEVICE_MANAGER_CORE (device_manager))
|
||||
{
|
||||
/* It is a core/xi1 device manager, we only map
|
||||
* IDs 2 and 3, matching XI2's Virtual Core Pointer
|
||||
* and Keyboard.
|
||||
*/
|
||||
if (device_id == VIRTUAL_CORE_POINTER_ID)
|
||||
device = GDK_X11_DEVICE_MANAGER_CORE (device_manager)->core_pointer;
|
||||
else if (device_id == VIRTUAL_CORE_KEYBOARD_ID)
|
||||
device = GDK_X11_DEVICE_MANAGER_CORE (device_manager)->core_keyboard;
|
||||
}
|
||||
|
||||
return device;
|
||||
return _gdk_x11_device_manager_xi2_lookup (GDK_X11_DEVICE_MANAGER_XI2 (device_manager),
|
||||
device_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_x11_device_get_id:
|
||||
* @device: (type GdkX11DeviceCore): a #GdkDevice
|
||||
* @device: (type GdkX11DeviceXI2): a #GdkDevice
|
||||
*
|
||||
* Returns the device ID as seen by XInput2.
|
||||
*
|
||||
* > If gdk_disable_multidevice() has been called, this function
|
||||
* > will respectively return 2/3 for the core pointer and keyboard,
|
||||
* > (matching the IDs for the Virtual Core Pointer and Keyboard in
|
||||
* > XInput 2), but calling this function on any slave devices (i.e.
|
||||
* > those managed via XInput 1.x), will return 0.
|
||||
*
|
||||
* Returns: the XInput2 device ID.
|
||||
**/
|
||||
gint
|
||||
gdk_x11_device_get_id (GdkDevice *device)
|
||||
{
|
||||
gint device_id = 0;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
|
||||
|
||||
#ifdef XINPUT_2
|
||||
if (GDK_IS_X11_DEVICE_XI2 (device))
|
||||
device_id = _gdk_x11_device_xi2_get_id (GDK_X11_DEVICE_XI2 (device));
|
||||
else
|
||||
#endif /* XINPUT_2 */
|
||||
if (GDK_IS_X11_DEVICE_CORE (device))
|
||||
{
|
||||
if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
|
||||
device_id = VIRTUAL_CORE_KEYBOARD_ID;
|
||||
else
|
||||
device_id = VIRTUAL_CORE_POINTER_ID;
|
||||
}
|
||||
|
||||
return device_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_disable_multidevice:
|
||||
*
|
||||
* Disables multidevice support in GDKs X11 backend. This call must happen prior
|
||||
* to gdk_display_open(), gtk_init() or gtk_init_check() in order to
|
||||
* take effect.
|
||||
*
|
||||
* Most common GTK+ applications won’t ever need to call this. Only
|
||||
* applications that do mixed GDK/Xlib calls could want to disable
|
||||
* multidevice support if such Xlib code deals with input devices in
|
||||
* any way and doesn’t observe the presence of XInput 2.
|
||||
*/
|
||||
void
|
||||
gdk_disable_multidevice (void)
|
||||
{
|
||||
_gdk_disable_multidevice = TRUE;
|
||||
return _gdk_x11_device_xi2_get_id (GDK_X11_DEVICE_XI2 (device));
|
||||
}
|
||||
|
@ -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 <string.h>
|
||||
|
||||
#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;
|
||||
|
@ -44,7 +44,7 @@ struct _GdkX11Display
|
||||
GdkX11Screen *screen;
|
||||
GList *screens;
|
||||
GList *toplevels;
|
||||
GdkX11DeviceManagerCore *device_manager;
|
||||
GdkX11DeviceManagerXI2 *device_manager;
|
||||
|
||||
GSource *event_source;
|
||||
|
||||
|
@ -1925,7 +1925,6 @@ static gboolean
|
||||
drag_grab (GdkDrag *drag)
|
||||
{
|
||||
GdkX11Drag *x11_drag = GDK_X11_DRAG (drag);
|
||||
GdkDevice *device = gdk_drag_get_device (drag);
|
||||
GdkSeatCapabilities capabilities;
|
||||
GdkDisplay *display;
|
||||
Window root;
|
||||
@ -1940,12 +1939,7 @@ drag_grab (GdkDrag *drag)
|
||||
root = GDK_DISPLAY_XROOTWIN (display);
|
||||
seat = gdk_device_get_seat (gdk_drag_get_device (drag));
|
||||
|
||||
#ifdef XINPUT_2
|
||||
if (GDK_IS_X11_DEVICE_XI2 (device))
|
||||
capabilities = GDK_SEAT_CAPABILITY_ALL_POINTING;
|
||||
else
|
||||
#endif
|
||||
capabilities = GDK_SEAT_CAPABILITY_ALL;
|
||||
capabilities = GDK_SEAT_CAPABILITY_ALL_POINTING;
|
||||
|
||||
cursor = gdk_drag_get_cursor (drag, x11_drag->current_action);
|
||||
g_set_object (&x11_drag->cursor, cursor);
|
||||
@ -1961,52 +1955,38 @@ drag_grab (GdkDrag *drag)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (grab_keys); ++i)
|
||||
{
|
||||
gint deviceid = gdk_x11_device_get_id (gdk_seat_get_keyboard (seat));
|
||||
unsigned char mask[XIMaskLen(XI_LASTEVENT)];
|
||||
XIGrabModifiers mods;
|
||||
XIEventMask evmask;
|
||||
gint num_mods;
|
||||
|
||||
keycode = XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (display),
|
||||
grab_keys[i].keysym);
|
||||
if (keycode == NoSymbol)
|
||||
continue;
|
||||
|
||||
#ifdef XINPUT_2
|
||||
if (GDK_IS_X11_DEVICE_XI2 (device))
|
||||
{
|
||||
gint deviceid = gdk_x11_device_get_id (gdk_seat_get_keyboard (seat));
|
||||
unsigned char mask[XIMaskLen(XI_LASTEVENT)];
|
||||
XIGrabModifiers mods;
|
||||
XIEventMask evmask;
|
||||
gint num_mods;
|
||||
memset (mask, 0, sizeof (mask));
|
||||
XISetMask (mask, XI_KeyPress);
|
||||
XISetMask (mask, XI_KeyRelease);
|
||||
|
||||
memset (mask, 0, sizeof (mask));
|
||||
XISetMask (mask, XI_KeyPress);
|
||||
XISetMask (mask, XI_KeyRelease);
|
||||
evmask.deviceid = deviceid;
|
||||
evmask.mask_len = sizeof (mask);
|
||||
evmask.mask = mask;
|
||||
|
||||
evmask.deviceid = deviceid;
|
||||
evmask.mask_len = sizeof (mask);
|
||||
evmask.mask = mask;
|
||||
num_mods = 1;
|
||||
mods.modifiers = grab_keys[i].modifiers;
|
||||
|
||||
num_mods = 1;
|
||||
mods.modifiers = grab_keys[i].modifiers;
|
||||
|
||||
XIGrabKeycode (GDK_DISPLAY_XDISPLAY (display),
|
||||
deviceid,
|
||||
keycode,
|
||||
root,
|
||||
GrabModeAsync,
|
||||
GrabModeAsync,
|
||||
False,
|
||||
&evmask,
|
||||
num_mods,
|
||||
&mods);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
XGrabKey (GDK_DISPLAY_XDISPLAY (display),
|
||||
keycode, grab_keys[i].modifiers,
|
||||
root,
|
||||
FALSE,
|
||||
GrabModeAsync,
|
||||
GrabModeAsync);
|
||||
}
|
||||
XIGrabKeycode (GDK_DISPLAY_XDISPLAY (display),
|
||||
deviceid,
|
||||
keycode,
|
||||
root,
|
||||
GrabModeAsync,
|
||||
GrabModeAsync,
|
||||
False,
|
||||
&evmask,
|
||||
num_mods,
|
||||
&mods);
|
||||
}
|
||||
|
||||
gdk_x11_display_error_trap_pop_ignored (display);
|
||||
@ -2035,34 +2015,23 @@ drag_ungrab (GdkDrag *drag)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (grab_keys); ++i)
|
||||
{
|
||||
XIGrabModifiers mods;
|
||||
gint num_mods;
|
||||
|
||||
keycode = XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (display),
|
||||
grab_keys[i].keysym);
|
||||
if (keycode == NoSymbol)
|
||||
continue;
|
||||
|
||||
#ifdef XINPUT_2
|
||||
if (GDK_IS_X11_DEVICE_XI2 (keyboard))
|
||||
{
|
||||
XIGrabModifiers mods;
|
||||
gint num_mods;
|
||||
num_mods = 1;
|
||||
mods.modifiers = grab_keys[i].modifiers;
|
||||
|
||||
num_mods = 1;
|
||||
mods.modifiers = grab_keys[i].modifiers;
|
||||
|
||||
XIUngrabKeycode (GDK_DISPLAY_XDISPLAY (display),
|
||||
gdk_x11_device_get_id (keyboard),
|
||||
keycode,
|
||||
root,
|
||||
num_mods,
|
||||
&mods);
|
||||
}
|
||||
else
|
||||
#endif /* XINPUT_2 */
|
||||
{
|
||||
XUngrabKey (GDK_DISPLAY_XDISPLAY (display),
|
||||
keycode, grab_keys[i].modifiers,
|
||||
root);
|
||||
}
|
||||
XIUngrabKeycode (GDK_DISPLAY_XDISPLAY (display),
|
||||
gdk_x11_device_get_id (keyboard),
|
||||
keycode,
|
||||
root,
|
||||
num_mods,
|
||||
&mods);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,9 +37,7 @@
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#ifdef XINPUT_2
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
|
||||
#include <cairo-xlib.h>
|
||||
|
||||
@ -132,9 +130,8 @@ 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);
|
||||
|
||||
#ifdef XINPUT_2
|
||||
guchar * _gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager_xi2,
|
||||
GdkEventMask event_mask,
|
||||
gint *len);
|
||||
@ -164,7 +161,6 @@ gdouble gdk_x11_device_xi2_get_last_axis_value (GdkX11DeviceXI2 *device,
|
||||
void gdk_x11_device_xi2_store_axes (GdkX11DeviceXI2 *device,
|
||||
gdouble *axes,
|
||||
gint n_axes);
|
||||
#endif
|
||||
|
||||
GdkAtom _gdk_x11_display_manager_atom_intern (GdkDisplayManager *manager,
|
||||
const gchar *atom_name,
|
||||
|
@ -3690,27 +3690,21 @@ handle_wmspec_button_release (GdkDisplay *display,
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
GdkSurface *surface;
|
||||
|
||||
#if defined (HAVE_XGENERICEVENTS) && defined (XINPUT_2)
|
||||
XIEvent *xiev = (XIEvent *) xevent->xcookie.data;
|
||||
XIDeviceEvent *xidev = (XIDeviceEvent *) xiev;
|
||||
|
||||
if (xevent->xany.type == GenericEvent)
|
||||
surface = gdk_x11_surface_lookup_for_display (display, xidev->event);
|
||||
else
|
||||
#endif
|
||||
surface = gdk_x11_surface_lookup_for_display (display, xevent->xany.window);
|
||||
|
||||
if (display_x11->wm_moveresize_button != 0 && surface != NULL)
|
||||
{
|
||||
if ((xevent->xany.type == ButtonRelease &&
|
||||
xevent->xbutton.button == display_x11->wm_moveresize_button)
|
||||
#if defined (HAVE_XGENERICEVENTS) && defined (XINPUT_2)
|
||||
||
|
||||
xevent->xbutton.button == display_x11->wm_moveresize_button) ||
|
||||
(xevent->xany.type == GenericEvent &&
|
||||
xiev->evtype == XI_ButtonRelease &&
|
||||
xidev->detail == display_x11->wm_moveresize_button)
|
||||
#endif
|
||||
)
|
||||
xidev->detail == display_x11->wm_moveresize_button))
|
||||
{
|
||||
display_x11->wm_moveresize_button = 0;
|
||||
wmspec_send_message (display, surface, 0, 0, _NET_WM_MOVERESIZE_CANCEL, 0);
|
||||
@ -4102,7 +4096,6 @@ _gdk_x11_moveresize_handle_event (const XEvent *event)
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined (HAVE_XGENERICEVENTS) && defined (XINPUT_2)
|
||||
case GenericEvent:
|
||||
{
|
||||
/* we just assume this is an XI2 event */
|
||||
@ -4138,7 +4131,6 @@ _gdk_x11_moveresize_handle_event (const XEvent *event)
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -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)
|
||||
|
@ -34,10 +34,8 @@
|
||||
|
||||
#include <gdk/x11/gdkx11applaunchcontext.h>
|
||||
#include <gdk/x11/gdkx11device.h>
|
||||
#include <gdk/x11/gdkx11device-core.h>
|
||||
#include <gdk/x11/gdkx11device-xi2.h>
|
||||
#include <gdk/x11/gdkx11devicemanager.h>
|
||||
#include <gdk/x11/gdkx11devicemanager-core.h>
|
||||
#include <gdk/x11/gdkx11devicemanager-xi2.h>
|
||||
#include <gdk/x11/gdkx11display.h>
|
||||
#include <gdk/x11/gdkx11dnd.h>
|
||||
|
@ -1,41 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_X11_DEVICE_CORE_H__
|
||||
#define __GDK_X11_DEVICE_CORE_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
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__ */
|
@ -1,42 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_X11_DEVICE_MANAGER_CORE_H__
|
||||
#define __GDK_X11_DEVICE_MANAGER_CORE_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
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__ */
|
@ -1,42 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_X11_DEVICE_MANAGER_XI_H__
|
||||
#define __GDK_X11_DEVICE_MANAGER_XI_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_X11_DEVICE_MANAGER_XI (gdk_x11_device_manager_xi_get_type ())
|
||||
#define GDK_X11_DEVICE_MANAGER_XI(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_X11_DEVICE_MANAGER_XI, GdkX11DeviceManagerXI))
|
||||
#define GDK_X11_DEVICE_MANAGER_XI_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_X11_DEVICE_MANAGER_XI, GdkX11DeviceManagerXIClass))
|
||||
#define GDK_IS_X11_DEVICE_MANAGER_XI(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_X11_DEVICE_MANAGER_XI))
|
||||
#define GDK_IS_X11_DEVICE_MANAGER_XI_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_X11_DEVICE_MANAGER_XI))
|
||||
#define GDK_X11_DEVICE_MANAGER_XI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_X11_DEVICE_MANAGER_XI, GdkX11DeviceManagerXIClass))
|
||||
|
||||
typedef struct _GdkX11DeviceManagerXI GdkX11DeviceManagerXI;
|
||||
typedef struct _GdkX11DeviceManagerXIClass GdkX11DeviceManagerXIClass;
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_x11_device_manager_xi_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_X11_DEVICE_MANAGER_XI_H__ */
|
@ -23,7 +23,7 @@
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/x11/gdkx11devicemanager-core.h>
|
||||
#include <gdk/x11/gdkx11devicemanager-xi2.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
@ -31,11 +31,8 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDevice * gdk_x11_device_manager_lookup (GdkX11DeviceManagerCore *device_manager,
|
||||
gint device_id);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_disable_multidevice (void);
|
||||
|
||||
GdkDevice * gdk_x11_device_manager_lookup (GdkX11DeviceManagerXI2 *device_manager,
|
||||
gint device_id);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -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',
|
||||
|
@ -79,15 +79,6 @@ gtk_test_init (int *argcp,
|
||||
gtk_disable_setlocale();
|
||||
setlocale (LC_ALL, "en_US.UTF-8");
|
||||
|
||||
/* XSendEvent() doesn't work yet on XI2 events.
|
||||
* So at the moment gdk_test_simulate_* can only
|
||||
* send events that GTK+ understands if XI2 is
|
||||
* disabled, bummer.
|
||||
*/
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
gdk_disable_multidevice ();
|
||||
#endif
|
||||
|
||||
gtk_init ();
|
||||
}
|
||||
|
||||
|
25
meson.build
25
meson.build
@ -542,18 +542,19 @@ if x11_enabled
|
||||
cdata.set('HAVE_XGENERICEVENTS', 1)
|
||||
endif
|
||||
|
||||
if xi_dep.found() and cc.has_header('X11/extensions/XInput2.h', dependencies: xi_dep)
|
||||
cdata.set('XINPUT_2', 1)
|
||||
# Note that we also check that the XIScrollClassInfo struct is defined,
|
||||
# because at least Ubuntu Oneiric seems to have XIAllowTouchEvents(),
|
||||
# but not the XIScrollClassInfo struct
|
||||
has_allow_touch_evens = cc.has_function('XIAllowTouchEvents', dependencies: xi_dep)
|
||||
has_scroll_class_info = cc.has_member('XIScrollClassInfo', 'number', dependencies: xi_dep,
|
||||
prefix: '''#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XInput2.h>''')
|
||||
if has_allow_touch_evens and has_scroll_class_info
|
||||
cdata.set('XINPUT_2_2', 1)
|
||||
endif
|
||||
if not xi_dep.found() or not cc.has_header('X11/extensions/XInput2.h', dependencies: xi_dep)
|
||||
error('X11 backend enabled, but XInput2 not found.')
|
||||
endif
|
||||
|
||||
# Note that we also check that the XIScrollClassInfo struct is defined,
|
||||
# because at least Ubuntu Oneiric seems to have XIAllowTouchEvents(),
|
||||
# but not the XIScrollClassInfo struct
|
||||
has_allow_touch_evens = cc.has_function('XIAllowTouchEvents', dependencies: xi_dep)
|
||||
has_scroll_class_info = cc.has_member('XIScrollClassInfo', 'number', dependencies: xi_dep,
|
||||
prefix: '''#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XInput2.h>''')
|
||||
if has_allow_touch_evens and has_scroll_class_info
|
||||
cdata.set('XINPUT_2_2', 1)
|
||||
endif
|
||||
|
||||
enable_xinerama = get_option('xinerama')
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user