static void grab_devices(GtkWidget *window) { GdkGrabStatus status; GdkDevice *device; /* Grab the current event device */ device = gtk_get_current_event_device(); if (device == NULL) { WARN("Couldn't get current device"); return; } /* Grab every seat capabilities */ status = gdk_seat_grab(gdk_device_get_seat(device), gtk_widget_get_window(window), GDK_SEAT_CAPABILITY_ALL, TRUE, NULL, NULL, NULL, NULL); if (status != GDK_GRAB_SUCCESS) WARN("Could not grab %s", gdk_device_get_name(device)); }
static gboolean on_widget_button_release (GtkWidget *widget, GdkEventButton *event, char *item_id) { GdkDevice *device = gdk_event_get_device ((GdkEvent*) event); g_print ("%s received 'button-release' signal\n", item_id); if (device && strstr (item_id, "explicit")) { #if GTK_CHECK_VERSION(3,20,0) gdk_seat_ungrab (gdk_device_get_seat (device)); #else gdk_device_ungrab (device, event->time); #endif g_print ("released pointer grab\n"); } return TRUE; }
static gboolean on_widget_button_press (GtkWidget *widget, GdkEventButton *event, char *item_id) { GdkDevice *device = gdk_event_get_device ((GdkEvent*) event); g_print ("%s received 'button-press' signal\n", item_id); if (device && strstr (item_id, "explicit")) { GdkGrabStatus status; #if GTK_CHECK_VERSION(3,20,0) status = gdk_seat_grab (gdk_device_get_seat (device), gtk_widget_get_window (widget), GDK_SEAT_CAPABILITY_ALL_POINTING, FALSE, NULL, (GdkEvent*) event, NULL, NULL); #else GdkEventMask mask = GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK; status = gdk_device_grab (device, gtk_widget_get_window (widget), GDK_OWNERSHIP_NONE, FALSE, mask, NULL, event->time); #endif if (status == GDK_GRAB_SUCCESS) g_print ("grabbed pointer\n"); else g_print ("pointer grab failed\n"); } return TRUE; }
static void gtk_button_finish_activate (GtkButton *button, gboolean do_it) { GtkWidget *widget = GTK_WIDGET (button); GtkButtonPrivate *priv = button->priv; g_source_remove (priv->activate_timeout); priv->activate_timeout = 0; if (priv->grab_keyboard) { gdk_seat_ungrab (gdk_device_get_seat (priv->grab_keyboard)); gtk_device_grab_remove (widget, priv->grab_keyboard); priv->grab_keyboard = NULL; } priv->button_down = FALSE; gtk_button_update_state (button); if (do_it) gtk_button_clicked (button); }
static void gtk_real_button_activate (GtkButton *button) { GtkWidget *widget = GTK_WIDGET (button); GtkButtonPrivate *priv = button->priv; GdkDevice *device; device = gtk_get_current_event_device (); if (device && gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD) device = gdk_device_get_associated_device (device); if (gtk_widget_get_realized (widget) && !priv->activate_timeout) { /* bgo#626336 - Only grab if we have a device (from an event), not if we * were activated programmatically when no event is available. */ if (device && gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) { if (gdk_seat_grab (gdk_device_get_seat (device), priv->event_window, GDK_SEAT_CAPABILITY_KEYBOARD, TRUE, NULL, NULL, NULL, NULL) == GDK_GRAB_SUCCESS) { gtk_device_grab_add (widget, device, TRUE); priv->grab_keyboard = device; } } priv->activate_timeout = gdk_threads_add_timeout (ACTIVATE_TIMEOUT, button_activate_timeout, button); g_source_set_name_by_id (priv->activate_timeout, "[gtk+] button_activate_timeout"); priv->button_down = TRUE; gtk_button_update_state (button); } }
static void grab_window_toggled (GtkToggleButton *button, GtkWidget *widget) { GdkDevice *device = gtk_get_current_event_device (); GdkSeat *seat = gdk_device_get_seat (device); if (gtk_toggle_button_get_active (button)) { int status; status = gdk_seat_grab (seat, gtk_widget_get_window (widget), GDK_SEAT_CAPABILITY_KEYBOARD, FALSE, NULL, NULL, NULL, NULL); if (status != GDK_GRAB_SUCCESS) g_warning ("Could not grab keyboard! (%s)", grab_string (status)); } else { gdk_seat_ungrab (seat); } }
gboolean gdk_input_other_event (GdkDisplay *display, GdkEvent *event, MSG *msg, GdkWindow *window) { GdkDeviceManagerWin32 *device_manager; GdkDeviceWintab *source_device = NULL; GdkDeviceGrabInfo *last_grab; GdkEventMask masktest; guint key_state; POINT pt; PACKET packet; gint root_x, root_y; gint num_axes; gint x, y; guint translated_buttons, button_diff, button_mask; /* Translation from tablet button state to GDK button state for * buttons 1-3 - swap button 2 and 3. */ static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7}; if (event->any.window != wintab_window) { g_warning ("gdk_input_other_event: not wintab_window?"); return FALSE; } G_GNUC_BEGIN_IGNORE_DEPRECATIONS; device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (display)); G_GNUC_END_IGNORE_DEPRECATIONS; window = gdk_device_get_window_at_position (device_manager->core_pointer, &x, &y); if (window == NULL) window = gdk_get_default_root_window (); g_object_ref (window); GDK_NOTE (EVENTS_OR_INPUT, g_print ("gdk_input_other_event: window=%p %+d%+d\n", GDK_WINDOW_HWND (window), x, y)); if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE) { if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet)) return FALSE; } switch (msg->message) { case WT_PACKET: /* Don't produce any button or motion events while a window is being * moved or resized, see bug #151090. */ if (_modal_operation_in_progress) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n")); return FALSE; } if ((source_device = gdk_device_manager_find_wintab_device (device_manager, (HCTX) msg->lParam, packet.pkCursor)) == NULL) return FALSE; if (gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED) return FALSE; last_grab = _gdk_display_get_last_device_grab (display, GDK_DEVICE (source_device)); if (last_grab && last_grab->window) { g_object_unref (window); window = g_object_ref (last_grab->window); } if (window == gdk_get_default_root_window ()) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n")); return FALSE; } num_axes = 0; if (source_device->pktdata & PK_X) source_device->last_axis_data[num_axes++] = packet.pkX; if (source_device->pktdata & PK_Y) source_device->last_axis_data[num_axes++] = packet.pkY; if (source_device->pktdata & PK_NORMAL_PRESSURE) source_device->last_axis_data[num_axes++] = packet.pkNormalPressure; if (source_device->pktdata & PK_ORIENTATION) { decode_tilt (source_device->last_axis_data + num_axes, source_device->orientation_axes, &packet); num_axes += 2; } translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07); if (translated_buttons != source_device->button_state) { /* At least one button has changed state so produce a button event * If more than one button has changed state (unlikely), * just care about the first and act on the next the next time * we get a packet */ button_diff = translated_buttons ^ source_device->button_state; /* Gdk buttons are numbered 1.. */ event->button.button = 1; for (button_mask = 1; button_mask != 0x80000000; button_mask <<= 1, event->button.button++) { if (button_diff & button_mask) { /* Found a button that has changed state */ break; } } if (!(translated_buttons & button_mask)) { event->any.type = GDK_BUTTON_RELEASE; masktest = GDK_BUTTON_RELEASE_MASK; } else { event->any.type = GDK_BUTTON_PRESS; masktest = GDK_BUTTON_PRESS_MASK; } source_device->button_state ^= button_mask; } else { event->any.type = GDK_MOTION_NOTIFY; masktest = GDK_POINTER_MOTION_MASK; if (source_device->button_state & (1 << 0)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK; if (source_device->button_state & (1 << 1)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK; if (source_device->button_state & (1 << 2)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK; } /* Now we can check if the window wants the event, and * propagate if necessary. */ while ((gdk_window_get_device_events (window, GDK_DEVICE (source_device)) & masktest) == 0 && (gdk_device_get_device_type (GDK_DEVICE (source_device)) == GDK_DEVICE_TYPE_SLAVE && (gdk_window_get_events (window) & masktest) == 0)) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n")); if (window->parent == gdk_get_default_root_window () || window->parent == NULL) return FALSE; pt.x = x; pt.y = y; ClientToScreen (GDK_WINDOW_HWND (window), &pt); g_object_unref (window); window = window->parent; g_object_ref (window); ScreenToClient (GDK_WINDOW_HWND (window), &pt); x = pt.x; y = pt.y; GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n", GDK_WINDOW_HWND (window), x, y)); } event->any.window = window; key_state = get_modifier_key_state (); if (event->any.type == GDK_BUTTON_PRESS || event->any.type == GDK_BUTTON_RELEASE) { event->button.time = _gdk_win32_get_next_tick (msg->time); if (source_device->sends_core) gdk_event_set_device (event, device_manager->core_pointer); gdk_event_set_source_device (event, GDK_DEVICE (source_device)); gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer)); event->button.axes = g_new (gdouble, num_axes); gdk_window_get_origin (window, &root_x, &root_y); _gdk_device_wintab_translate_axes (source_device, window, event->button.axes, &event->button.x, &event->button.y); event->button.x_root = event->button.x + root_x; event->button.y_root = event->button.y + root_y; event->button.state = key_state | ((source_device->button_state << 8) & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)); GDK_NOTE (EVENTS_OR_INPUT, g_print ("WINTAB button %s:%d %g,%g\n", (event->button.type == GDK_BUTTON_PRESS ? "press" : "release"), event->button.button, event->button.x, event->button.y)); } else { event->motion.time = _gdk_win32_get_next_tick (msg->time); event->motion.is_hint = FALSE; gdk_event_set_device (event, device_manager->core_pointer); gdk_event_set_source_device (event, GDK_DEVICE (source_device)); gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer)); event->motion.axes = g_new (gdouble, num_axes); gdk_window_get_origin (window, &root_x, &root_y); _gdk_device_wintab_translate_axes (source_device, window, event->motion.axes, &event->motion.x, &event->motion.y); event->motion.x_root = event->motion.x + root_x; event->motion.y_root = event->motion.y + root_y; event->motion.state = key_state | ((source_device->button_state << 8) & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)); GDK_NOTE (EVENTS_OR_INPUT, g_print ("WINTAB motion: %g,%g\n", event->motion.x, event->motion.y)); } return TRUE; case WT_CSRCHANGE: if ((source_device = gdk_device_manager_find_wintab_device (device_manager, (HCTX) msg->lParam, packet.pkCursor)) == NULL) return FALSE; if (gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED) return FALSE; if (source_device->sends_core) { _gdk_device_virtual_set_active (device_manager->core_pointer, GDK_DEVICE (source_device)); _gdk_input_ignore_core = TRUE; } return FALSE; case WT_PROXIMITY: if (LOWORD (msg->lParam) == 0) { _gdk_input_ignore_core = FALSE; _gdk_device_virtual_set_active (device_manager->core_pointer, device_manager->system_pointer); } return FALSE; } return FALSE; }
static gboolean gstyle_eyedropper_key_pressed_cb (GstyleEyedropper *self, GdkEventKey *event, GtkWindow *window) { GdkSeat *seat; GdkDevice *pointer; GdkDevice *keyboard; gint x, y; gint dx = 0; gint dy = 0; gint state; g_assert (GSTYLE_IS_EYEDROPPER (self)); g_assert (event != NULL); g_assert (GTK_IS_WINDOW (window)); state = (event->state & gtk_accelerator_get_default_mod_mask () & GDK_MOD1_MASK); switch (event->keyval) { case GDK_KEY_Escape: release_grab (self); return GDK_EVENT_STOP; break; case GDK_KEY_Up: case GDK_KEY_KP_Up: dy = (state == GDK_MOD1_MASK) ? -CURSOR_ALT_STEP : -1; break; case GDK_KEY_Down: case GDK_KEY_KP_Down: dy = (state == GDK_MOD1_MASK) ? CURSOR_ALT_STEP : 1; break; case GDK_KEY_Left: case GDK_KEY_KP_Left: dx = (state == GDK_MOD1_MASK) ? -CURSOR_ALT_STEP : -1; break; case GDK_KEY_Right: case GDK_KEY_KP_Right: dx = (state == GDK_MOD1_MASK) ? CURSOR_ALT_STEP : 1; break; case GDK_KEY_Page_Up: case GDK_KEY_KP_Page_Up: increase_zoom_factor (self); break; case GDK_KEY_Page_Down: case GDK_KEY_KP_Page_Down: decrease_zoom_factor (self); break; default: return GDK_EVENT_PROPAGATE; } keyboard = gdk_event_get_device ((GdkEvent *)event); seat = gdk_device_get_seat (keyboard); pointer = gdk_seat_get_pointer (seat); gdk_device_get_position (pointer, NULL, &x, &y); gdk_device_warp (pointer, self->screen, x + dx, y + dy); return GDK_EVENT_STOP; }