static void get_pointer_position_gdk (int *x, int *y, int *mods) { GdkDeviceManager *gmanager; GdkDevice *gdevice; GdkScreen *gscreen; gmanager = gdk_display_get_device_manager (gdk_display_get_default ()); gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID); gdk_device_get_position (gdevice, &gscreen, x, y); if (mods) gdk_device_get_state (gdevice, gdk_screen_get_root_window (gscreen), NULL, (GdkModifierType*)mods); }
GList * get_disabled_devices (GdkDeviceManager *manager) { XDeviceInfo *device_info; gint n_devices; guint i; GList *ret; ret = NULL; device_info = XListInputDevices (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &n_devices); if (device_info == NULL) return ret; for (i = 0; i < n_devices; i++) { GdkDevice *device; /* Ignore core devices */ if (device_info[i].use == IsXKeyboard || device_info[i].use == IsXPointer) continue; /* Check whether the device is actually available */ device = gdk_x11_device_manager_lookup (manager, device_info[i].id); if (device != NULL) continue; ret = g_list_prepend (ret, GINT_TO_POINTER (device_info[i].id)); } XFreeDeviceList (device_info); return ret; }
static gboolean maybe_redirect_mouse_event (XEvent *xevent) { GdkDisplay *gdisplay; GdkDeviceManager *gmanager; GdkDevice *gdevice; MetaUI *ui; GdkEvent *gevent; GdkWindow *gdk_window; Window window; XIEvent *xev; XIDeviceEvent *xev_d = NULL; XIEnterEvent *xev_e = NULL; if (!is_input_event (xevent)) return FALSE; xev = (XIEvent *) xevent->xcookie.data; switch (xev->evtype) { case XI_TouchBegin: case XI_ButtonPress: case XI_ButtonRelease: case XI_Motion: xev_d = (XIDeviceEvent *) xev; window = xev_d->event; break; case XI_Enter: case XI_Leave: xev_e = (XIEnterEvent *) xev; window = xev_e->event; break; default: return FALSE; } gdisplay = gdk_x11_lookup_xdisplay (xev->display); ui = g_object_get_data (G_OBJECT (gdisplay), "meta-ui"); if (!ui) return FALSE; gdk_window = gdk_x11_window_lookup_for_display (gdisplay, window); if (gdk_window == NULL) return FALSE; gmanager = gdk_display_get_device_manager (gdisplay); gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID); /* If GDK already thinks it has a grab, we better let it see events; this * is the menu-navigation case and events need to get sent to the appropriate * (client-side) subwindow for individual menu items. */ if (gdk_display_device_is_grabbed (gdisplay, gdevice)) return FALSE; switch (xev->evtype) { case XI_TouchBegin: case XI_ButtonPress: case XI_ButtonRelease: if (xev_d->evtype == XI_ButtonPress || xev_d->evtype == XI_TouchBegin) { GtkSettings *settings = gtk_settings_get_default (); int double_click_time; int double_click_distance; int button; g_object_get (settings, "gtk-double-click-time", &double_click_time, "gtk-double-click-distance", &double_click_distance, NULL); if (xev->evtype == XI_TouchBegin) button = 1; else button = xev_d->detail; if (button == ui->button_click_number && xev_d->event == ui->button_click_window && xev_d->time < ui->button_click_time + double_click_time && ABS (xev_d->event_x - ui->button_click_x) <= double_click_distance && ABS (xev_d->event_y - ui->button_click_y) <= double_click_distance) { gevent = gdk_event_new (GDK_2BUTTON_PRESS); ui->button_click_number = 0; } else { gevent = gdk_event_new (GDK_BUTTON_PRESS); ui->button_click_number = button; ui->button_click_window = xev_d->event; ui->button_click_time = xev_d->time; ui->button_click_x = xev_d->event_x; ui->button_click_y = xev_d->event_y; } gevent->button.button = button; } else { gevent = gdk_event_new (GDK_BUTTON_RELEASE); gevent->button.button = xev_d->detail; } gevent->button.window = g_object_ref (gdk_window); gevent->button.time = xev_d->time; gevent->button.x = xev_d->event_x; gevent->button.y = xev_d->event_y; gevent->button.x_root = xev_d->root_x; gevent->button.y_root = xev_d->root_y; break; case XI_Motion: gevent = gdk_event_new (GDK_MOTION_NOTIFY); gevent->motion.type = GDK_MOTION_NOTIFY; gevent->motion.window = g_object_ref (gdk_window); break; case XI_Enter: case XI_Leave: gevent = gdk_event_new (xev_e->evtype == XI_Enter ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY); gevent->crossing.window = g_object_ref (gdk_window); gevent->crossing.x = xev_e->event_x; gevent->crossing.y = xev_e->event_y; break; default: g_assert_not_reached (); break; } /* If we've gotten here, we've created the gdk_event and should send it on */ gdk_event_set_device (gevent, gdevice); gtk_main_do_event (gevent); gdk_event_free (gevent); return TRUE; }