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); }
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_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); } }