gboolean XInputUtils::onMouseLeaveNotifyEvent(GtkWidget* widget, GdkEventCrossing* event) { if(!XInputUtils::enableLeafEnterWorkaround) { return FALSE; } INPUTDBG("leave notify (mode=%d, details=%d)\n", event->mode, event->detail); /* emergency disable XInput to avoid segfaults (GTK+ 2.17) or interface non-responsiveness (GTK+ 2.18) */ if (!gtk_check_version(2, 17, 0)) { gdk_flush(); gdk_error_trap_push(); for (GList* dev_list = gdk_devices_list(); dev_list != NULL; dev_list = dev_list->next) { GdkDevice* dev = GDK_DEVICE(dev_list->data); gdk_device_set_mode(dev, GDK_MODE_DISABLED); } gdk_flush(); gdk_error_trap_pop(); } return FALSE; }
gboolean XInputUtils::onMouseEnterNotifyEvent(GtkWidget* widget, GdkEventCrossing* event) { if(!XInputUtils::enableLeafEnterWorkaround) { return FALSE; } INPUTDBG("enter notify\n"); /* re-enable input devices after they've been emergency-disabled by leave_notify */ if (!gtk_check_version(2, 17, 0)) { gdk_flush(); gdk_error_trap_push(); for (GList* dev_list = gdk_devices_list(); dev_list != NULL; dev_list = dev_list->next) { GdkDevice* dev = GDK_DEVICE(dev_list->data); gdk_device_set_mode(dev, GDK_MODE_SCREEN); } gdk_flush(); gdk_error_trap_pop(); } return FALSE; }
static void gdk_device_virtual_init (GdkDeviceVirtual *device_virtual) { GdkDevice *device; device = GDK_DEVICE (device_virtual); }
static void gdk_device_win32_init (GdkDeviceWin32 *device_win32) { GdkDevice *device; device = GDK_DEVICE (device_win32); _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1); _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1); }
static void gdk_broadway_device_init (GdkBroadwayDevice *device_core) { GdkDevice *device; device = GDK_DEVICE (device_core); _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1); _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1); }
USER_OBJECT_ S_GdkDeviceGetNumKeys (USER_OBJECT_ s_obj) { USER_OBJECT_ _result = NULL_USER_OBJECT; GdkDevice *obj; gint val; obj = GDK_DEVICE(getPtrValue(s_obj)) ; val = obj->num_keys; _result = asRInteger(val); return(_result); }
USER_OBJECT_ S_GdkDeviceGetAxes (USER_OBJECT_ s_obj) { USER_OBJECT_ _result = NULL_USER_OBJECT; GdkDevice *obj; GdkDeviceAxis* val; obj = GDK_DEVICE(getPtrValue(s_obj)) ; val = obj->axes; _result = toRPointer(val, "GdkDeviceAxis"); return(_result); }
USER_OBJECT_ S_GdkDeviceGetHasCursor (USER_OBJECT_ s_obj) { USER_OBJECT_ _result = NULL_USER_OBJECT; GdkDevice *obj; gboolean val; obj = GDK_DEVICE(getPtrValue(s_obj)) ; val = obj->has_cursor; _result = asRLogical(val); return(_result); }
USER_OBJECT_ S_GdkDeviceGetMode (USER_OBJECT_ s_obj) { USER_OBJECT_ _result = NULL_USER_OBJECT; GdkDevice *obj; GdkInputMode val; obj = GDK_DEVICE(getPtrValue(s_obj)) ; val = obj->mode; _result = asREnum(val, GDK_TYPE_INPUT_MODE); return(_result); }
USER_OBJECT_ S_GdkDeviceGetName (USER_OBJECT_ s_obj) { USER_OBJECT_ _result = NULL_USER_OBJECT; GdkDevice *obj; gchar* val; obj = GDK_DEVICE(getPtrValue(s_obj)) ; val = obj->name; _result = asRString(val); return(_result); }
JS_EXPORT_API void guide_disable_keyboard() { // gdk_keyboard_grab(gtk_widget_get_window(get_container()), FALSE, GDK_CURRENT_TIME); GdkWindow* window = gtk_widget_get_window(get_container()); GdkDisplay* display = gdk_window_get_display(window); GdkDeviceManager* manager = gdk_display_get_device_manager(display); GList* devices = gdk_device_manager_list_devices(manager, GDK_DEVICE_TYPE_MASTER); GdkDevice* device = NULL; for (GList* dev = devices; dev != NULL; dev = dev->next) { device = GDK_DEVICE(dev->data); if (gdk_device_get_source(device) != GDK_SOURCE_KEYBOARD) { continue; } GdkGrabStatus res = gdk_device_grab(device, window, GDK_OWNERSHIP_NONE, FALSE, GDK_KEY_PRESS_MASK|GDK_KEY_RELEASE_MASK, NULL, GDK_CURRENT_TIME ); switch (res) { case GDK_GRAB_ALREADY_GRABBED: g_warning("Grab falied, device %s is already grabbed.", gdk_device_get_name(device)); break; case GDK_GRAB_INVALID_TIME: g_warning("Grab failed, the resource is grabbed more recently than the specified time."); break; case GDK_GRAB_NOT_VIEWABLE: g_warning("Grab falied, the window is not viewable."); break; case GDK_GRAB_FROZEN: g_warning("Grab falied, the resources is frozen."); break; case GDK_GRAB_SUCCESS: break; } } g_list_free(devices); }
JS_EXPORT_API void guide_enable_keyboard() { // gdk_keyboard_ungrab(GDK_CURRENT_TIME); GdkWindow* window = gtk_widget_get_window(get_container()); GdkDisplay* display = gdk_window_get_display(window); GdkDeviceManager* manager = gdk_display_get_device_manager(display); GList* devices = gdk_device_manager_list_devices(manager, GDK_DEVICE_TYPE_MASTER); GdkDevice* device = NULL; for (GList* dev = devices; dev != NULL; dev = dev->next) { device = GDK_DEVICE(dev->data); if (gdk_device_get_source(device) != GDK_SOURCE_KEYBOARD) { continue; } gdk_device_ungrab(device, GDK_CURRENT_TIME); } g_list_free(devices); }
gboolean _gdk_input_other_event (GdkEvent *event, MSG *msg, GdkWindow *window) { GdkDisplay *display; GdkDeviceWintab *device = NULL; GdkDeviceGrabInfo *last_grab; GdkEventMask masktest; guint key_state; POINT pt; PACKET packet; gdouble 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; } window = gdk_window_at_pointer (&x, &y); if (window == NULL) window = _gdk_root; g_object_ref (window); display = gdk_window_get_display (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) { 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 ((device = _gdk_device_manager_find_wintab_device ((HCTX) msg->lParam, packet.pkCursor)) == NULL) return FALSE; if (gdk_device_get_mode (GDK_DEVICE (device)) == GDK_MODE_DISABLED) return FALSE; last_grab = _gdk_display_get_last_device_grab (_gdk_display, GDK_DEVICE (device)); if (last_grab && last_grab->window) { g_object_unref (window); window = g_object_ref (last_grab->window); } if (window == _gdk_root) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n")); return FALSE; } num_axes = 0; if (device->pktdata & PK_X) device->last_axis_data[num_axes++] = packet.pkX; if (device->pktdata & PK_Y) device->last_axis_data[num_axes++] = packet.pkY; if (device->pktdata & PK_NORMAL_PRESSURE) device->last_axis_data[num_axes++] = packet.pkNormalPressure; if (device->pktdata & PK_ORIENTATION) { decode_tilt (device->last_axis_data + num_axes, device->orientation_axes, &packet); num_axes += 2; } translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07); if (translated_buttons != 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 ^ 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; } device->button_state ^= button_mask; } else { event->any.type = GDK_MOTION_NOTIFY; masktest = GDK_POINTER_MOTION_MASK; if (device->button_state & (1 << 0)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK; if (device->button_state & (1 << 1)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK; if (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 (device)) == 0) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n")); if (window->parent == GDK_WINDOW (_gdk_root)) return FALSE; /* It is not good to propagate the extended events up to the parent * if this window wants normal (not extended) motion/button events */ if (window->event_mask & masktest) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... wants ordinary event, ignoring this\n")); 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)); } if (gdk_window_get_device_events (window, GDK_DEVICE (device)) == 0) return FALSE; 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); gdk_event_set_device (event, GDK_DEVICE (device)); event->button.axes = g_new (gdouble, num_axes); _gdk_device_wintab_get_window_coords (window, &root_x, &root_y); _gdk_device_wintab_translate_axes (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 | ((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, GDK_DEVICE (device)); event->motion.axes = g_new (gdouble, num_axes); _gdk_device_wintab_get_window_coords (window, &root_x, &root_y); _gdk_device_wintab_translate_axes (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 | ((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_PROXIMITY: if (LOWORD (msg->lParam) == 0) { event->proximity.type = GDK_PROXIMITY_OUT; set_ignore_core (FALSE); } else { event->proximity.type = GDK_PROXIMITY_IN; set_ignore_core (TRUE); } event->proximity.time = _gdk_win32_get_next_tick (msg->time); gdk_event_set_device (event, GDK_DEVICE (device)); GDK_NOTE (EVENTS_OR_INPUT, g_print ("WINTAB proximity %s\n", (event->proximity.type == GDK_PROXIMITY_IN ? "in" : "out"))); return TRUE; } return FALSE; }
static void _gdk_input_wintab_init_check (GdkDeviceManagerWin32 *device_manager) { static gboolean wintab_initialized = FALSE; GdkDeviceWintab *device; GdkWindowAttr wa; WORD specversion; HCTX *hctx; UINT ndevices, ncursors, ncsrtypes, firstcsr, hardware; BOOL active; DWORD physid; AXIS axis_x, axis_y, axis_npressure, axis_or[3]; int i, devix, cursorix, num_axes = 0; wchar_t devname[100], csrname[100]; gchar *devname_utf8, *csrname_utf8, *device_name; BOOL defcontext_done; HMODULE wintab32; char *wintab32_dll_path; char dummy; int n, k; if (wintab_initialized) return; wintab_initialized = TRUE; wintab_contexts = NULL; if (_gdk_input_ignore_wintab) return; n = GetSystemDirectory (&dummy, 0); if (n <= 0) return; wintab32_dll_path = g_malloc (n + 1 + strlen (WINTAB32_DLL)); k = GetSystemDirectory (wintab32_dll_path, n); if (k == 0 || k > n) { g_free (wintab32_dll_path); return; } if (!G_IS_DIR_SEPARATOR (wintab32_dll_path[strlen (wintab32_dll_path) -1])) strcat (wintab32_dll_path, G_DIR_SEPARATOR_S); strcat (wintab32_dll_path, WINTAB32_DLL); if ((wintab32 = LoadLibrary (wintab32_dll_path)) == NULL) return; if ((p_WTInfoA = (t_WTInfoA) GetProcAddress (wintab32, "WTInfoA")) == NULL) return; if ((p_WTInfoW = (t_WTInfoW) GetProcAddress (wintab32, "WTInfoW")) == NULL) return; if ((p_WTEnable = (t_WTEnable) GetProcAddress (wintab32, "WTEnable")) == NULL) return; if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL) return; if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL) return; if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL) return; if ((p_WTQueueSizeSet = (t_WTQueueSizeSet) GetProcAddress (wintab32, "WTQueueSizeSet")) == NULL) return; if (!(*p_WTInfoA) (0, 0, NULL)) return; (*p_WTInfoA) (WTI_INTERFACE, IFC_SPECVERSION, &specversion); GDK_NOTE (INPUT, g_print ("Wintab interface version %d.%d\n", HIBYTE (specversion), LOBYTE (specversion))); (*p_WTInfoA) (WTI_INTERFACE, IFC_NDEVICES, &ndevices); (*p_WTInfoA) (WTI_INTERFACE, IFC_NCURSORS, &ncursors); #if DEBUG_WINTAB GDK_NOTE (INPUT, g_print ("NDEVICES: %d, NCURSORS: %d\n", ndevices, ncursors)); #endif /* Create a dummy window to receive wintab events */ wa.wclass = GDK_INPUT_OUTPUT; wa.event_mask = GDK_ALL_EVENTS_MASK; wa.width = 2; wa.height = 2; wa.x = -100; wa.y = -100; wa.window_type = GDK_WINDOW_TOPLEVEL; if ((wintab_window = gdk_window_new (NULL, &wa, GDK_WA_X|GDK_WA_Y)) == NULL) { g_warning ("gdk_input_wintab_init: gdk_window_new failed"); return; } g_object_ref (wintab_window); for (devix = 0; devix < ndevices; devix++) { LOGCONTEXT lc; /* We open the Wintab device (hmm, what if there are several, or * can there even be several, probably not?) as a system * pointing device, i.e. it controls the normal Windows * cursor. This seems much more natural. */ (*p_WTInfoW) (WTI_DEVICES + devix, DVC_NAME, devname); devname_utf8 = g_utf16_to_utf8 (devname, -1, NULL, NULL, NULL); #ifdef DEBUG_WINTAB GDK_NOTE (INPUT, (g_print("Device %d: %s\n", devix, devname_utf8))); #endif (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes); (*p_WTInfoA) (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr); (*p_WTInfoA) (WTI_DEVICES + devix, DVC_HARDWARE, &hardware); (*p_WTInfoA) (WTI_DEVICES + devix, DVC_X, &axis_x); (*p_WTInfoA) (WTI_DEVICES + devix, DVC_Y, &axis_y); (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure); (*p_WTInfoA) (WTI_DEVICES + devix, DVC_ORIENTATION, axis_or); defcontext_done = FALSE; if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1) { /* Try to get device-specific default context */ /* Some drivers, e.g. Aiptek, don't provide this info */ if ((*p_WTInfoA) (WTI_DSCTXS + devix, 0, &lc) > 0) defcontext_done = TRUE; #if DEBUG_WINTAB if (defcontext_done) GDK_NOTE (INPUT, (g_print("Using device-specific default context\n"))); else GDK_NOTE (INPUT, (g_print("Note: Driver did not provide device specific default context info despite claiming to support version 1.1\n"))); #endif } if (!defcontext_done) (*p_WTInfoA) (WTI_DEFSYSCTX, 0, &lc); #if DEBUG_WINTAB GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc))); #endif lc.lcOptions |= CXO_MESSAGES; lc.lcStatus = 0; lc.lcMsgBase = WT_DEFBASE; lc.lcPktRate = 0; lc.lcPktData = PACKETDATA; lc.lcPktMode = PACKETMODE; lc.lcMoveMask = PACKETDATA; lc.lcBtnUpMask = lc.lcBtnDnMask = ~0; lc.lcOutOrgX = axis_x.axMin; lc.lcOutOrgY = axis_y.axMin; lc.lcOutExtX = axis_x.axMax - axis_x.axMin; lc.lcOutExtY = axis_y.axMax - axis_y.axMin; lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */ #if DEBUG_WINTAB GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix), print_lc(&lc))); #endif hctx = g_new (HCTX, 1); if ((*hctx = (*p_WTOpenA) (GDK_WINDOW_HWND (wintab_window), &lc, TRUE)) == NULL) { g_warning ("gdk_input_wintab_init: WTOpen failed"); return; } GDK_NOTE (INPUT, g_print ("opened Wintab device %d %p\n", devix, *hctx)); wintab_contexts = g_list_append (wintab_contexts, hctx); #if 0 (*p_WTEnable) (*hctx, TRUE); #endif (*p_WTOverlap) (*hctx, TRUE); #if DEBUG_WINTAB GDK_NOTE (INPUT, (g_print("context for device %d after WTOpen:\n", devix), print_lc(&lc))); #endif /* Increase packet queue size to reduce the risk of lost packets. * According to the specs, if the function fails we must try again * with a smaller queue size. */ GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n")); for (i = 32; i >= 1; i >>= 1) { if ((*p_WTQueueSizeSet) (*hctx, i)) { GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i)); break; } } if (!i) GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n")); for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++) { #ifdef DEBUG_WINTAB GDK_NOTE (INPUT, (g_print("Cursor %d:\n", cursorix), print_cursor (cursorix))); #endif active = FALSE; (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_ACTIVE, &active); if (!active) continue; /* Wacom tablets seem to report cursors corresponding to * nonexistent pens or pucks. At least my ArtPad II reports * six cursors: a puck, pressure stylus and eraser stylus, * and then the same three again. I only have a * pressure-sensitive pen. The puck instances, and the * second instances of the styluses report physid zero. So * at least for Wacom, skip cursors with physid zero. */ (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid); if (wcscmp (devname, L"WACOM Tablet") == 0 && physid == 0) continue; (*p_WTInfoW) (WTI_CURSORS + cursorix, CSR_NAME, csrname); csrname_utf8 = g_utf16_to_utf8 (csrname, -1, NULL, NULL, NULL); device_name = g_strconcat (devname_utf8, " ", csrname_utf8, NULL); device = g_object_new (GDK_TYPE_DEVICE_WINTAB, "name", device_name, "type", GDK_DEVICE_TYPE_SLAVE, "source", GDK_SOURCE_PEN, "mode", GDK_MODE_SCREEN, "has-cursor", FALSE, "display", _gdk_display, "device-manager", device_manager, NULL); g_free (csrname_utf8); device->hctx = *hctx; device->cursor = cursorix; (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &device->pktdata); if (device->pktdata & PK_X) { _gdk_device_add_axis (GDK_DEVICE (device), GDK_NONE, GDK_AXIS_X, axis_x.axMin, axis_x.axMax, axis_x.axResolution / 65535); num_axes++; } if (device->pktdata & PK_Y) { _gdk_device_add_axis (GDK_DEVICE (device), GDK_NONE, GDK_AXIS_Y, axis_y.axMin, axis_y.axMax, axis_y.axResolution / 65535); num_axes++; } if (device->pktdata & PK_NORMAL_PRESSURE) { _gdk_device_add_axis (GDK_DEVICE (device), GDK_NONE, GDK_AXIS_PRESSURE, axis_npressure.axMin, axis_npressure.axMax, axis_npressure.axResolution / 65535); num_axes++; } /* The wintab driver for the Wacom ArtPad II reports * PK_ORIENTATION in CSR_PKTDATA, but the tablet doesn't * actually sense tilt. Catch this by noticing that the * orientation axis's azimuth resolution is zero. */ if ((device->pktdata & PK_ORIENTATION) && axis_or[0].axResolution == 0) { device->orientation_axes[0] = axis_or[0]; device->orientation_axes[1] = axis_or[1]; /* Wintab gives us aximuth and altitude, which * we convert to x and y tilt in the -1000..1000 range */ _gdk_device_add_axis (GDK_DEVICE (device), GDK_NONE, GDK_AXIS_XTILT, -1000, 1000, 1000); _gdk_device_add_axis (GDK_DEVICE (device), GDK_NONE, GDK_AXIS_YTILT, -1000, 1000, 1000); num_axes += 2; } device->last_axis_data = g_new (gint, num_axes); GDK_NOTE (INPUT, g_print ("device: (%d) %s axes: %d\n", cursorix, device_name, num_axes)); #if 0 for (i = 0; i < gdkdev->info.num_axes; i++) GDK_NOTE (INPUT, g_print ("... axis %d: %d--%d@%d\n", i, gdkdev->axes[i].min_value, gdkdev->axes[i].max_value, gdkdev->axes[i].resolution)); #endif device_manager->wintab_devices = g_list_append (device_manager->wintab_devices, device); g_free (device_name); } g_free (devname_utf8); } }
void _gdk_device_wintab_translate_axes (GdkDeviceWintab *device_wintab, GdkSurface *window, gdouble *axes, gdouble *x, gdouble *y) { GdkDevice *device; GdkSurface *impl_surface; gint root_x, root_y; gdouble temp_x, temp_y; gint i; device = GDK_DEVICE (device_wintab); impl_surface = _gdk_surface_get_impl_surface (window); temp_x = temp_y = 0; gdk_surface_get_origin (impl_surface, &root_x, &root_y); for (i = 0; i < gdk_device_get_n_axes (device); i++) { GdkAxisUse use; use = gdk_device_get_axis_use (device, i); switch (use) { case GDK_AXIS_X: case GDK_AXIS_Y: if (gdk_device_get_mode (device) == GDK_MODE_SURFACE) _gdk_device_translate_surface_coord (device, window, i, device_wintab->last_axis_data[i], &axes[i]); else { HMONITOR hmonitor; MONITORINFO minfo = {sizeof (MONITORINFO),}; hmonitor = MonitorFromWindow (GDK_SURFACE_HWND (window), MONITOR_DEFAULTTONEAREST); GetMonitorInfo (hmonitor, &minfo); /* XXX: the dimensions from minfo may need to be scaled for HiDPI usage */ _gdk_device_translate_screen_coord (device, window, root_x, root_y, minfo.rcWork.right - minfo.rcWork.left, minfo.rcWork.bottom - minfo.rcWork.top, i, device_wintab->last_axis_data[i], &axes[i]); } if (use == GDK_AXIS_X) temp_x = axes[i]; else if (use == GDK_AXIS_Y) temp_y = axes[i]; break; default: _gdk_device_translate_axis (device, i, device_wintab->last_axis_data[i], &axes[i]); break; } } if (x) *x = temp_x; if (y) *y = temp_y; }