| File: | cdk/x11/cdkdevice-core-x11.c |
| Warning: | line 554, column 40 The left operand of '/' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* CDK - The GIMP Drawing Kit | |||
| 2 | * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org> | |||
| 3 | * | |||
| 4 | * This library is free software; you can redistribute it and/or | |||
| 5 | * modify it under the terms of the GNU Lesser General Public | |||
| 6 | * License as published by the Free Software Foundation; either | |||
| 7 | * version 2 of the License, or (at your option) any later version. | |||
| 8 | * | |||
| 9 | * This library is distributed in the hope that it will be useful, | |||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 12 | * Lesser General Public License for more details. | |||
| 13 | * | |||
| 14 | * You should have received a copy of the GNU Lesser General Public | |||
| 15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | |||
| 16 | */ | |||
| 17 | ||||
| 18 | #include "config.h" | |||
| 19 | ||||
| 20 | ||||
| 21 | #include "cdkx11device-core.h" | |||
| 22 | #include "cdkdeviceprivate.h" | |||
| 23 | ||||
| 24 | #include "cdkinternals.h" | |||
| 25 | #include "cdkwindow.h" | |||
| 26 | #include "cdkprivate-x11.h" | |||
| 27 | #include "cdkasync.h" | |||
| 28 | ||||
| 29 | #include <math.h> | |||
| 30 | ||||
| 31 | /* for the use of round() */ | |||
| 32 | #include "fallback-c89.c" | |||
| 33 | ||||
| 34 | struct _CdkX11DeviceCore | |||
| 35 | { | |||
| 36 | CdkDevice parent_instance; | |||
| 37 | }; | |||
| 38 | ||||
| 39 | struct _CdkX11DeviceCoreClass | |||
| 40 | { | |||
| 41 | CdkDeviceClass parent_class; | |||
| 42 | }; | |||
| 43 | ||||
| 44 | static gboolean cdk_x11_device_core_get_history (CdkDevice *device, | |||
| 45 | CdkWindow *window, | |||
| 46 | guint32 start, | |||
| 47 | guint32 stop, | |||
| 48 | CdkTimeCoord ***events, | |||
| 49 | gint *n_events); | |||
| 50 | static void cdk_x11_device_core_get_state (CdkDevice *device, | |||
| 51 | CdkWindow *window, | |||
| 52 | gdouble *axes, | |||
| 53 | CdkModifierType *mask); | |||
| 54 | static void cdk_x11_device_core_set_window_cursor (CdkDevice *device, | |||
| 55 | CdkWindow *window, | |||
| 56 | CdkCursor *cursor); | |||
| 57 | static void cdk_x11_device_core_warp (CdkDevice *device, | |||
| 58 | CdkScreen *screen, | |||
| 59 | gdouble x, | |||
| 60 | gdouble y); | |||
| 61 | static void cdk_x11_device_core_query_state (CdkDevice *device, | |||
| 62 | CdkWindow *window, | |||
| 63 | CdkWindow **root_window, | |||
| 64 | CdkWindow **child_window, | |||
| 65 | gdouble *root_x, | |||
| 66 | gdouble *root_y, | |||
| 67 | gdouble *win_x, | |||
| 68 | gdouble *win_y, | |||
| 69 | CdkModifierType *mask); | |||
| 70 | static CdkGrabStatus cdk_x11_device_core_grab (CdkDevice *device, | |||
| 71 | CdkWindow *window, | |||
| 72 | gboolean owner_events, | |||
| 73 | CdkEventMask event_mask, | |||
| 74 | CdkWindow *confine_to, | |||
| 75 | CdkCursor *cursor, | |||
| 76 | guint32 time_); | |||
| 77 | static void cdk_x11_device_core_ungrab (CdkDevice *device, | |||
| 78 | guint32 time_); | |||
| 79 | static CdkWindow * cdk_x11_device_core_window_at_position (CdkDevice *device, | |||
| 80 | gdouble *win_x, | |||
| 81 | gdouble *win_y, | |||
| 82 | CdkModifierType *mask, | |||
| 83 | gboolean get_toplevel); | |||
| 84 | static void cdk_x11_device_core_select_window_events (CdkDevice *device, | |||
| 85 | CdkWindow *window, | |||
| 86 | CdkEventMask event_mask); | |||
| 87 | ||||
| 88 | G_DEFINE_TYPE (CdkX11DeviceCore, cdk_x11_device_core, CDK_TYPE_DEVICE)static void cdk_x11_device_core_init (CdkX11DeviceCore *self) ; static void cdk_x11_device_core_class_init (CdkX11DeviceCoreClass *klass); static GType cdk_x11_device_core_get_type_once (void ); static gpointer cdk_x11_device_core_parent_class = ((void* )0); static gint CdkX11DeviceCore_private_offset; static void cdk_x11_device_core_class_intern_init (gpointer klass) { cdk_x11_device_core_parent_class = g_type_class_peek_parent (klass); if (CdkX11DeviceCore_private_offset != 0) g_type_class_adjust_private_offset (klass, &CdkX11DeviceCore_private_offset ); cdk_x11_device_core_class_init ((CdkX11DeviceCoreClass*) klass ); } __attribute__ ((__unused__)) static inline gpointer cdk_x11_device_core_get_instance_private (CdkX11DeviceCore *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CdkX11DeviceCore_private_offset)))); } GType cdk_x11_device_core_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = cdk_x11_device_core_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType cdk_x11_device_core_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple ((cdk_device_get_type ()), g_intern_static_string ("CdkX11DeviceCore" ), sizeof (CdkX11DeviceCoreClass), (GClassInitFunc)(void (*)( void)) cdk_x11_device_core_class_intern_init, sizeof (CdkX11DeviceCore ), (GInstanceInitFunc)(void (*)(void)) cdk_x11_device_core_init , (GTypeFlags) 0); { {{};} } return g_define_type_id; } | |||
| 89 | ||||
| 90 | static void | |||
| 91 | cdk_x11_device_core_class_init (CdkX11DeviceCoreClass *klass) | |||
| 92 | { | |||
| 93 | CdkDeviceClass *device_class = CDK_DEVICE_CLASS (klass)((((CdkDeviceClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), ((cdk_device_get_type ())))))); | |||
| 94 | ||||
| 95 | device_class->get_history = cdk_x11_device_core_get_history; | |||
| 96 | device_class->get_state = cdk_x11_device_core_get_state; | |||
| 97 | device_class->set_window_cursor = cdk_x11_device_core_set_window_cursor; | |||
| 98 | device_class->warp = cdk_x11_device_core_warp; | |||
| 99 | device_class->query_state = cdk_x11_device_core_query_state; | |||
| 100 | device_class->grab = cdk_x11_device_core_grab; | |||
| 101 | device_class->ungrab = cdk_x11_device_core_ungrab; | |||
| 102 | device_class->window_at_position = cdk_x11_device_core_window_at_position; | |||
| 103 | device_class->select_window_events = cdk_x11_device_core_select_window_events; | |||
| 104 | } | |||
| 105 | ||||
| 106 | static void | |||
| 107 | cdk_x11_device_core_init (CdkX11DeviceCore *device_core) | |||
| 108 | { | |||
| 109 | CdkDevice *device; | |||
| 110 | ||||
| 111 | device = CDK_DEVICE (device_core)((((CdkDevice*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((device_core)), ((cdk_device_get_type ())))))); | |||
| 112 | ||||
| 113 | _cdk_device_add_axis (device, CDK_NONE((CdkAtom)((gpointer) (gulong) (0))), CDK_AXIS_X, 0, 0, 1); | |||
| 114 | _cdk_device_add_axis (device, CDK_NONE((CdkAtom)((gpointer) (gulong) (0))), CDK_AXIS_Y, 0, 0, 1); | |||
| 115 | } | |||
| 116 | ||||
| 117 | static gboolean | |||
| 118 | impl_coord_in_window (CdkWindow *window, | |||
| 119 | int impl_x, | |||
| 120 | int impl_y) | |||
| 121 | { | |||
| 122 | if (impl_x < window->abs_x || | |||
| 123 | impl_x >= window->abs_x + window->width) | |||
| 124 | return FALSE(0); | |||
| 125 | ||||
| 126 | if (impl_y < window->abs_y || | |||
| 127 | impl_y >= window->abs_y + window->height) | |||
| 128 | return FALSE(0); | |||
| 129 | ||||
| 130 | return TRUE(!(0)); | |||
| 131 | } | |||
| 132 | ||||
| 133 | static gboolean | |||
| 134 | cdk_x11_device_core_get_history (CdkDevice *device, | |||
| 135 | CdkWindow *window, | |||
| 136 | guint32 start, | |||
| 137 | guint32 stop, | |||
| 138 | CdkTimeCoord ***events, | |||
| 139 | gint *n_events) | |||
| 140 | { | |||
| 141 | XTimeCoord *xcoords; | |||
| 142 | CdkTimeCoord **coords; | |||
| 143 | CdkWindow *impl_window; | |||
| 144 | CdkWindowImplX11 *impl; | |||
| 145 | int tmp_n_events; | |||
| 146 | int i, j; | |||
| 147 | ||||
| 148 | impl_window = _cdk_window_get_impl_window (window); | |||
| 149 | impl = CDK_WINDOW_IMPL_X11 (impl_window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((impl_window->impl)), ((cdk_window_impl_x11_get_type ())))))); | |||
| 150 | xcoords = XGetMotionEvents (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance *) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type ()))))))->xdisplay), | |||
| 151 | CDK_WINDOW_XID (impl_window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((impl_window)), ((cdk_window_get_type ()) )))))->impl)), ((cdk_window_impl_x11_get_type ()))))))-> xid), | |||
| 152 | start, stop, &tmp_n_events); | |||
| 153 | if (!xcoords) | |||
| 154 | return FALSE(0); | |||
| 155 | ||||
| 156 | coords = _cdk_device_allocate_history (device, tmp_n_events); | |||
| 157 | ||||
| 158 | for (i = 0, j = 0; i < tmp_n_events; i++) | |||
| 159 | { | |||
| 160 | if (impl_coord_in_window (window, | |||
| 161 | xcoords[i].x / impl->window_scale, | |||
| 162 | xcoords[i].y / impl->window_scale)) | |||
| 163 | { | |||
| 164 | coords[j]->time = xcoords[i].time; | |||
| 165 | coords[j]->axes[0] = (double)xcoords[i].x / impl->window_scale - window->abs_x; | |||
| 166 | coords[j]->axes[1] = (double)xcoords[i].y / impl->window_scale - window->abs_y; | |||
| 167 | j++; | |||
| 168 | } | |||
| 169 | } | |||
| 170 | ||||
| 171 | XFree (xcoords); | |||
| 172 | ||||
| 173 | /* free the events we allocated too much */ | |||
| 174 | for (i = j; i < tmp_n_events; i++) | |||
| 175 | { | |||
| 176 | g_free (coords[i]); | |||
| 177 | coords[i] = NULL((void*)0); | |||
| 178 | } | |||
| 179 | ||||
| 180 | tmp_n_events = j; | |||
| 181 | ||||
| 182 | if (tmp_n_events == 0) | |||
| 183 | { | |||
| 184 | cdk_device_free_history (coords, tmp_n_events); | |||
| 185 | return FALSE(0); | |||
| 186 | } | |||
| 187 | ||||
| 188 | if (n_events) | |||
| 189 | *n_events = tmp_n_events; | |||
| 190 | ||||
| 191 | if (events) | |||
| 192 | *events = coords; | |||
| 193 | else if (coords) | |||
| 194 | cdk_device_free_history (coords, tmp_n_events); | |||
| 195 | ||||
| 196 | return TRUE(!(0)); | |||
| 197 | } | |||
| 198 | ||||
| 199 | static void | |||
| 200 | cdk_x11_device_core_get_state (CdkDevice *device, | |||
| 201 | CdkWindow *window, | |||
| 202 | gdouble *axes, | |||
| 203 | CdkModifierType *mask) | |||
| 204 | { | |||
| 205 | gdouble x, y; | |||
| 206 | ||||
| 207 | cdk_window_get_device_position_double (window, device, &x, &y, mask); | |||
| 208 | ||||
| 209 | if (axes) | |||
| 210 | { | |||
| 211 | axes[0] = x; | |||
| 212 | axes[1] = y; | |||
| 213 | } | |||
| 214 | } | |||
| 215 | ||||
| 216 | static void | |||
| 217 | cdk_x11_device_core_set_window_cursor (CdkDevice *device G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
| 218 | CdkWindow *window, | |||
| 219 | CdkCursor *cursor) | |||
| 220 | { | |||
| 221 | Cursor xcursor; | |||
| 222 | ||||
| 223 | if (!cursor) | |||
| 224 | xcursor = None0L; | |||
| 225 | else | |||
| 226 | xcursor = cdk_x11_cursor_get_xcursor (cursor); | |||
| 227 | ||||
| 228 | XDefineCursor (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance *) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type ()))))))->xdisplay), | |||
| 229 | CDK_WINDOW_XID (window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((window)), ((cdk_window_get_type ())))))) ->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid), | |||
| 230 | xcursor); | |||
| 231 | } | |||
| 232 | ||||
| 233 | static void | |||
| 234 | cdk_x11_device_core_warp (CdkDevice *device, | |||
| 235 | CdkScreen *screen, | |||
| 236 | gdouble x, | |||
| 237 | gdouble y) | |||
| 238 | { | |||
| 239 | Display *xdisplay; | |||
| 240 | Window dest; | |||
| 241 | ||||
| 242 | xdisplay = CDK_DISPLAY_XDISPLAY (cdk_device_get_display (device))(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cdk_device_get_display (device))), ((cdk_x11_display_get_type ()))))))->xdisplay); | |||
| 243 | dest = CDK_WINDOW_XID (cdk_screen_get_root_window (screen))(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((cdk_screen_get_root_window (screen))), ( (cdk_window_get_type ()))))))->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid); | |||
| 244 | ||||
| 245 | XWarpPointer (xdisplay, None0L, dest, 0, 0, 0, 0, | |||
| 246 | round (x * CDK_X11_SCREEN (screen)((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), ((cdk_x11_screen_get_type ()))))))->window_scale), | |||
| 247 | round (y * CDK_X11_SCREEN (screen)((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), ((cdk_x11_screen_get_type ()))))))->window_scale)); | |||
| 248 | } | |||
| 249 | ||||
| 250 | static void | |||
| 251 | cdk_x11_device_core_query_state (CdkDevice *device G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
| 252 | CdkWindow *window, | |||
| 253 | CdkWindow **root_window, | |||
| 254 | CdkWindow **child_window, | |||
| 255 | gdouble *root_x, | |||
| 256 | gdouble *root_y, | |||
| 257 | gdouble *win_x, | |||
| 258 | gdouble *win_y, | |||
| 259 | CdkModifierType *mask) | |||
| 260 | { | |||
| 261 | CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type ())))))); | |||
| 262 | CdkDisplay *display; | |||
| 263 | CdkScreen *default_screen; | |||
| 264 | Window xroot_window, xchild_window; | |||
| 265 | int xroot_x, xroot_y, xwin_x, xwin_y; | |||
| 266 | unsigned int xmask; | |||
| 267 | ||||
| 268 | display = cdk_window_get_display (window); | |||
| 269 | default_screen = cdk_display_get_default_screen (display); | |||
| 270 | ||||
| 271 | if (!CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((display)), ((cdk_x11_display_get_type()))))))->trusted_client || | |||
| 272 | !XQueryPointer (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance *) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type ()))))))->xdisplay), | |||
| 273 | CDK_WINDOW_XID (window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((window)), ((cdk_window_get_type ())))))) ->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid), | |||
| 274 | &xroot_window, | |||
| 275 | &xchild_window, | |||
| 276 | &xroot_x, &xroot_y, | |||
| 277 | &xwin_x, &xwin_y, | |||
| 278 | &xmask)) | |||
| 279 | { | |||
| 280 | XSetWindowAttributes attributes; | |||
| 281 | Display *xdisplay; | |||
| 282 | Window xwindow, w; | |||
| 283 | ||||
| 284 | /* FIXME: untrusted clients not multidevice-safe */ | |||
| 285 | xdisplay = CDK_SCREEN_XDISPLAY (default_screen)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((default_screen)), ((cdk_x11_screen_get_type ()))))))-> xdisplay); | |||
| 286 | xwindow = CDK_SCREEN_XROOTWIN (default_screen)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((default_screen)), ((cdk_x11_screen_get_type ()))))))-> xroot_window); | |||
| 287 | ||||
| 288 | w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0, | |||
| 289 | CopyFromParent0L, InputOnly2, CopyFromParent0L, | |||
| 290 | 0, &attributes); | |||
| 291 | XQueryPointer (xdisplay, w, | |||
| 292 | &xroot_window, | |||
| 293 | &xchild_window, | |||
| 294 | &xroot_x, &xroot_y, | |||
| 295 | &xwin_x, &xwin_y, | |||
| 296 | &xmask); | |||
| 297 | XDestroyWindow (xdisplay, w); | |||
| 298 | } | |||
| 299 | ||||
| 300 | if (root_window) | |||
| 301 | *root_window = cdk_x11_window_lookup_for_display (display, xroot_window); | |||
| 302 | ||||
| 303 | if (child_window) | |||
| 304 | *child_window = cdk_x11_window_lookup_for_display (display, xchild_window); | |||
| 305 | ||||
| 306 | if (root_x) | |||
| 307 | *root_x = (double)xroot_x / impl->window_scale; | |||
| 308 | ||||
| 309 | if (root_y) | |||
| 310 | *root_y = (double)xroot_y / impl->window_scale; | |||
| 311 | ||||
| 312 | if (win_x) | |||
| 313 | *win_x = (double)xwin_x / impl->window_scale; | |||
| 314 | ||||
| 315 | if (win_y) | |||
| 316 | *win_y = (double)xwin_y / impl->window_scale; | |||
| 317 | ||||
| 318 | if (mask) | |||
| 319 | *mask = xmask; | |||
| 320 | } | |||
| 321 | ||||
| 322 | static CdkGrabStatus | |||
| 323 | cdk_x11_device_core_grab (CdkDevice *device, | |||
| 324 | CdkWindow *window, | |||
| 325 | gboolean owner_events, | |||
| 326 | CdkEventMask event_mask, | |||
| 327 | CdkWindow *confine_to, | |||
| 328 | CdkCursor *cursor, | |||
| 329 | guint32 time_) | |||
| 330 | { | |||
| 331 | CdkDisplay *display; | |||
| 332 | Window xwindow, xconfine_to; | |||
| 333 | gint status; | |||
| 334 | ||||
| 335 | display = cdk_device_get_display (device); | |||
| 336 | ||||
| 337 | xwindow = CDK_WINDOW_XID (window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((window)), ((cdk_window_get_type ())))))) ->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid); | |||
| 338 | ||||
| 339 | if (confine_to) | |||
| 340 | confine_to = _cdk_window_get_impl_window (confine_to); | |||
| 341 | ||||
| 342 | if (!confine_to || CDK_WINDOW_DESTROYED (confine_to)(((CdkWindow *)(confine_to))->destroyed)) | |||
| 343 | xconfine_to = None0L; | |||
| 344 | else | |||
| 345 | xconfine_to = CDK_WINDOW_XID (confine_to)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((confine_to)), ((cdk_window_get_type ())) ))))->impl)), ((cdk_window_impl_x11_get_type ()))))))-> xid); | |||
| 346 | ||||
| 347 | #ifdef G_ENABLE_DEBUG1 | |||
| 348 | if (CDK_DEBUG_CHECK (NOGRABS)(_cdk_debug_flags & CDK_DEBUG_NOGRABS)) | |||
| 349 | status = GrabSuccess0; | |||
| 350 | else | |||
| 351 | #endif | |||
| 352 | if (cdk_device_get_source (device) == CDK_SOURCE_KEYBOARD) | |||
| 353 | { | |||
| 354 | /* Device is a keyboard */ | |||
| 355 | status = XGrabKeyboard (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay ), | |||
| 356 | xwindow, | |||
| 357 | owner_events, | |||
| 358 | GrabModeAsync1, GrabModeAsync1, | |||
| 359 | time_); | |||
| 360 | } | |||
| 361 | else | |||
| 362 | { | |||
| 363 | Cursor xcursor; | |||
| 364 | guint xevent_mask; | |||
| 365 | gint i; | |||
| 366 | ||||
| 367 | /* Device is a pointer */ | |||
| 368 | if (!cursor) | |||
| 369 | xcursor = None0L; | |||
| 370 | else | |||
| 371 | { | |||
| 372 | _cdk_x11_cursor_update_theme (cursor); | |||
| 373 | xcursor = cdk_x11_cursor_get_xcursor (cursor); | |||
| 374 | } | |||
| 375 | ||||
| 376 | xevent_mask = 0; | |||
| 377 | ||||
| 378 | for (i = 0; i < _cdk_x11_event_mask_table_size; i++) | |||
| 379 | { | |||
| 380 | if (event_mask & (1 << (i + 1))) | |||
| 381 | xevent_mask |= _cdk_x11_event_mask_table[i]; | |||
| 382 | } | |||
| 383 | ||||
| 384 | /* We don't want to set a native motion hint mask, as we're emulating motion | |||
| 385 | * hints. If we set a native one we just wouldn't get any events. | |||
| 386 | */ | |||
| 387 | xevent_mask &= ~PointerMotionHintMask(1L<<7); | |||
| 388 | ||||
| 389 | status = XGrabPointer (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay ), | |||
| 390 | xwindow, | |||
| 391 | owner_events, | |||
| 392 | xevent_mask, | |||
| 393 | GrabModeAsync1, GrabModeAsync1, | |||
| 394 | xconfine_to, | |||
| 395 | xcursor, | |||
| 396 | time_); | |||
| 397 | } | |||
| 398 | ||||
| 399 | _cdk_x11_display_update_grab_info (display, device, status); | |||
| 400 | ||||
| 401 | return _cdk_x11_convert_grab_status (status); | |||
| 402 | } | |||
| 403 | ||||
| 404 | static void | |||
| 405 | cdk_x11_device_core_ungrab (CdkDevice *device, | |||
| 406 | guint32 time_) | |||
| 407 | { | |||
| 408 | CdkDisplay *display; | |||
| 409 | gulong serial; | |||
| 410 | ||||
| 411 | display = cdk_device_get_display (device); | |||
| 412 | serial = NextRequest (CDK_DISPLAY_XDISPLAY (display))(((_XPrivDisplay)((((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display)), ((cdk_x11_display_get_type()) )))))->xdisplay)))->request + 1); | |||
| 413 | ||||
| 414 | if (cdk_device_get_source (device) == CDK_SOURCE_KEYBOARD) | |||
| 415 | XUngrabKeyboard (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay ), time_); | |||
| 416 | else | |||
| 417 | XUngrabPointer (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay ), time_); | |||
| 418 | ||||
| 419 | _cdk_x11_display_update_grab_info_ungrab (display, device, time_, serial); | |||
| 420 | } | |||
| 421 | ||||
| 422 | static CdkWindow * | |||
| 423 | cdk_x11_device_core_window_at_position (CdkDevice *device, | |||
| 424 | gdouble *win_x, | |||
| 425 | gdouble *win_y, | |||
| 426 | CdkModifierType *mask, | |||
| 427 | gboolean get_toplevel) | |||
| 428 | { | |||
| 429 | CdkWindowImplX11 *impl; | |||
| 430 | CdkDisplay *display; | |||
| 431 | CdkScreen *screen; | |||
| 432 | Display *xdisplay; | |||
| 433 | CdkWindow *window; | |||
| 434 | Window xwindow, root, child, last; | |||
| 435 | int xroot_x, xroot_y, xwin_x, xwin_y; | |||
| ||||
| 436 | unsigned int xmask; | |||
| 437 | ||||
| 438 | last = None0L; | |||
| 439 | display = cdk_device_get_display (device); | |||
| 440 | screen = cdk_display_get_default_screen (display); | |||
| 441 | ||||
| 442 | /* This function really only works if the mouse pointer is held still | |||
| 443 | * during its operation. If it moves from one leaf window to another | |||
| 444 | * than we'll end up with inaccurate values for win_x, win_y | |||
| 445 | * and the result. | |||
| 446 | */ | |||
| 447 | cdk_x11_display_grab (display); | |||
| 448 | ||||
| 449 | xdisplay = CDK_SCREEN_XDISPLAY (screen)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), ((cdk_x11_screen_get_type ()))))))->xdisplay ); | |||
| 450 | xwindow = CDK_SCREEN_XROOTWIN (screen)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), ((cdk_x11_screen_get_type ()))))))->xroot_window ); | |||
| 451 | ||||
| 452 | if (G_LIKELY (CDK_X11_DISPLAY (display)->trusted_client)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((display)), ((cdk_x11_display_get_type()))))))->trusted_client )) | |||
| 453 | { | |||
| 454 | XQueryPointer (xdisplay, xwindow, | |||
| 455 | &root, &child, | |||
| 456 | &xroot_x, &xroot_y, | |||
| 457 | &xwin_x, &xwin_y, | |||
| 458 | &xmask); | |||
| 459 | ||||
| 460 | if (root == xwindow) | |||
| 461 | xwindow = child; | |||
| 462 | else | |||
| 463 | xwindow = root; | |||
| 464 | } | |||
| 465 | else | |||
| 466 | { | |||
| 467 | gint width, height; | |||
| 468 | GList *toplevels, *list; | |||
| 469 | Window pointer_window; | |||
| 470 | int rootx = -1, rooty = -1; | |||
| 471 | int winx, winy; | |||
| 472 | ||||
| 473 | /* FIXME: untrusted clients case not multidevice-safe */ | |||
| 474 | pointer_window = None0L; | |||
| 475 | screen = cdk_display_get_default_screen (display); | |||
| 476 | toplevels = cdk_screen_get_toplevel_windows (screen); | |||
| 477 | for (list = toplevels; list != NULL((void*)0); list = list->next) | |||
| 478 | { | |||
| 479 | window = CDK_WINDOW (list->data)((((CdkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((list->data)), ((cdk_window_get_type ())))))); | |||
| 480 | impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type ())))))); | |||
| 481 | xwindow = CDK_WINDOW_XID (window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((window)), ((cdk_window_get_type ())))))) ->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid); | |||
| 482 | cdk_x11_display_error_trap_push (display); | |||
| 483 | XQueryPointer (xdisplay, xwindow, | |||
| 484 | &root, &child, | |||
| 485 | &rootx, &rooty, | |||
| 486 | &winx, &winy, | |||
| 487 | &xmask); | |||
| 488 | if (cdk_x11_display_error_trap_pop (display)) | |||
| 489 | continue; | |||
| 490 | if (child != None0L) | |||
| 491 | { | |||
| 492 | pointer_window = child; | |||
| 493 | break; | |||
| 494 | } | |||
| 495 | cdk_window_get_geometry (window, NULL((void*)0), NULL((void*)0), &width, &height); | |||
| 496 | if (winx >= 0 && winy >= 0 && winx < width * impl->window_scale && winy < height * impl->window_scale) | |||
| 497 | { | |||
| 498 | /* A childless toplevel, or below another window? */ | |||
| 499 | XSetWindowAttributes attributes; | |||
| 500 | Window w; | |||
| 501 | ||||
| 502 | w = XCreateWindow (xdisplay, xwindow, winx, winy, 1, 1, 0, | |||
| 503 | CopyFromParent0L, InputOnly2, CopyFromParent0L, | |||
| 504 | 0, &attributes); | |||
| 505 | XMapWindow (xdisplay, w); | |||
| 506 | XQueryPointer (xdisplay, xwindow, | |||
| 507 | &root, &child, | |||
| 508 | &rootx, &rooty, | |||
| 509 | &winx, &winy, | |||
| 510 | &xmask); | |||
| 511 | XDestroyWindow (xdisplay, w); | |||
| 512 | if (child == w) | |||
| 513 | { | |||
| 514 | pointer_window = xwindow; | |||
| 515 | break; | |||
| 516 | } | |||
| 517 | } | |||
| 518 | } | |||
| 519 | ||||
| 520 | g_list_free (toplevels); | |||
| 521 | ||||
| 522 | xwindow = pointer_window; | |||
| 523 | } | |||
| 524 | ||||
| 525 | while (xwindow) | |||
| 526 | { | |||
| 527 | last = xwindow; | |||
| 528 | cdk_x11_display_error_trap_push (display); | |||
| 529 | XQueryPointer (xdisplay, xwindow, | |||
| 530 | &root, &xwindow, | |||
| 531 | &xroot_x, &xroot_y, | |||
| 532 | &xwin_x, &xwin_y, | |||
| 533 | &xmask); | |||
| 534 | if (cdk_x11_display_error_trap_pop (display)) | |||
| 535 | break; | |||
| 536 | ||||
| 537 | if (get_toplevel && last != root && | |||
| 538 | (window = cdk_x11_window_lookup_for_display (display, last)) != NULL((void*)0) && | |||
| 539 | window->window_type != CDK_WINDOW_FOREIGN) | |||
| 540 | { | |||
| 541 | xwindow = last; | |||
| 542 | break; | |||
| 543 | } | |||
| 544 | } | |||
| 545 | ||||
| 546 | cdk_x11_display_ungrab (display); | |||
| 547 | ||||
| 548 | window = cdk_x11_window_lookup_for_display (display, last); | |||
| 549 | impl = NULL((void*)0); | |||
| 550 | if (window) | |||
| 551 | impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type ())))))); | |||
| 552 | ||||
| 553 | if (win_x) | |||
| 554 | *win_x = (window
| |||
| ||||
| 555 | ||||
| 556 | if (win_y) | |||
| 557 | *win_y = (window) ? (double)xwin_y / impl->window_scale : -1; | |||
| 558 | ||||
| 559 | if (mask) | |||
| 560 | *mask = xmask; | |||
| 561 | ||||
| 562 | return window; | |||
| 563 | } | |||
| 564 | ||||
| 565 | static void | |||
| 566 | cdk_x11_device_core_select_window_events (CdkDevice *device G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
| 567 | CdkWindow *window, | |||
| 568 | CdkEventMask event_mask) | |||
| 569 | { | |||
| 570 | CdkEventMask filter_mask, window_mask; | |||
| 571 | guint xmask = 0; | |||
| 572 | gint i; | |||
| 573 | ||||
| 574 | window_mask = cdk_window_get_events (window); | |||
| 575 | filter_mask = CDK_POINTER_MOTION_MASK | |||
| 576 | | CDK_POINTER_MOTION_HINT_MASK | |||
| 577 | | CDK_BUTTON_MOTION_MASK | |||
| 578 | | CDK_BUTTON1_MOTION_MASK | |||
| 579 | | CDK_BUTTON2_MOTION_MASK | |||
| 580 | | CDK_BUTTON3_MOTION_MASK | |||
| 581 | | CDK_BUTTON_PRESS_MASK | |||
| 582 | | CDK_BUTTON_RELEASE_MASK | |||
| 583 | | CDK_KEY_PRESS_MASK | |||
| 584 | | CDK_KEY_RELEASE_MASK | |||
| 585 | | CDK_ENTER_NOTIFY_MASK | |||
| 586 | | CDK_LEAVE_NOTIFY_MASK | |||
| 587 | | CDK_FOCUS_CHANGE_MASK | |||
| 588 | | CDK_PROXIMITY_IN_MASK | |||
| 589 | | CDK_PROXIMITY_OUT_MASK | |||
| 590 | | CDK_SCROLL_MASK; | |||
| 591 | ||||
| 592 | /* Filter out non-device events */ | |||
| 593 | event_mask &= filter_mask; | |||
| 594 | ||||
| 595 | /* Unset device events on window mask */ | |||
| 596 | window_mask &= ~filter_mask; | |||
| 597 | ||||
| 598 | /* Combine masks */ | |||
| 599 | event_mask |= window_mask; | |||
| 600 | ||||
| 601 | for (i = 0; i < _cdk_x11_event_mask_table_size; i++) | |||
| 602 | { | |||
| 603 | if (event_mask & (1 << (i + 1))) | |||
| 604 | xmask |= _cdk_x11_event_mask_table[i]; | |||
| 605 | } | |||
| 606 | ||||
| 607 | if (CDK_WINDOW_XID (window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((window)), ((cdk_window_get_type ())))))) ->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid) != CDK_WINDOW_XROOTWIN (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance *) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type ()))))))->xroot_window)) | |||
| 608 | xmask |= StructureNotifyMask(1L<<17) | PropertyChangeMask(1L<<22); | |||
| 609 | ||||
| 610 | XSelectInput (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance *) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type ()))))))->xdisplay), | |||
| 611 | CDK_WINDOW_XID (window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((window)), ((cdk_window_get_type ())))))) ->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid), | |||
| 612 | xmask); | |||
| 613 | } |