Merge branch 'issue1549' into 'gtk-3-24'

Handle Wintab cursors that are recognized after GDK app init

See merge request GNOME/gtk!2458
This commit is contained in:
Matthias Clasen
2021-03-05 18:53:42 +00:00

View File

@ -70,6 +70,10 @@ static gboolean default_display_opened = FALSE;
G_DEFINE_TYPE (GdkDeviceManagerWin32, gdk_device_manager_win32, GDK_TYPE_DEVICE_MANAGER)
static GdkDeviceWintab *gdk_device_manager_find_wintab_device (GdkDeviceManagerWin32 *, HCTX, UINT);
UINT _wintab_recognize_new_cursors (GdkDeviceManagerWin32 *, HCTX);
int _gdk_find_wintab_device_index (HCTX);
static GdkDevice *
create_pointer (GdkDeviceManager *device_manager,
GType g_type,
@ -355,18 +359,15 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
GdkDisplay *display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
GdkWindow *root = gdk_screen_get_root_window (gdk_display_get_default_screen (display));
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];
UINT devix, cursorix;
int i, num_axes = 0;
wchar_t devname[100], csrname[100];
gchar *devname_utf8, *csrname_utf8, *device_name;
UINT ndevices, ncursors;
UINT devix;
AXIS axis_x, axis_y;
int i;
wchar_t devname[100];
gchar *devname_utf8;
BOOL defcontext_done;
HMODULE wintab32;
char *wintab32_dll_path;
@ -465,13 +466,8 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
#ifdef DEBUG_WINTAB
GDK_NOTE (INPUT, (g_print("Device %u: %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)
@ -544,31 +540,80 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
}
if (!i)
GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n"));
/* Get the cursors that Wintab is currently aware of */
_wintab_recognize_new_cursors(device_manager, *hctx);
}
}
UINT
_wintab_recognize_new_cursors (GdkDeviceManagerWin32 *device_manager,
HCTX hctx)
{
GdkDisplay *display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
int devix;
wchar_t devname[100], csrname[100];
gchar *devname_utf8, *csrname_utf8, *device_name;
UINT ncsrtypes, firstcsr, cursorix;
BOOL active;
DWORD physid;
AXIS axis_x, axis_y, axis_npressure, axis_or[3];
GdkDeviceWintab *device;
LOGCONTEXT lc;
int num_axes;
UINT num_new_cursors = 0;
devix = _gdk_find_wintab_device_index(hctx);
if (devix == -1)
return num_new_cursors;
(*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("Finding cursors for device %u: %s\n", devix, devname_utf8)));
#endif
(*p_WTInfoA) (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
(*p_WTInfoA) (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
{
#ifdef DEBUG_WINTAB
GDK_NOTE (INPUT, (g_print("Cursor %u:\n", cursorix), print_cursor (cursorix)));
#endif
/* Skip cursors that are already known to us */
if (gdk_device_manager_find_wintab_device(device_manager, hctx, cursorix) != NULL)
continue;
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.
/* Wacom tablets iterate through all possible cursors,
* even if the cursor's presence has not been recognized.
* Unrecognized cursors have a physid of zero and are ignored.
* Recognized cursors have a non-zero physid and we create a
* Wintab device object for each of them.
*/
(*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
if (wcscmp (devname, L"WACOM Tablet") == 0 && physid == 0)
continue;
if (!(*p_WTGetA) (hctx, &lc))
{
g_warning ("wintab_recognize_new_cursors: Failed to retrieve device LOGCONTEXT");
continue;
}
/* Create a Wintab device for this cursor */
(*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);
(*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);
g_free (csrname_utf8);
device = g_object_new (GDK_TYPE_DEVICE_WINTAB,
"name", device_name,
@ -587,11 +632,10 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
_gdk_device_add_slave (device_manager->core_pointer, GDK_DEVICE (device));
}
g_free (csrname_utf8);
device->hctx = *hctx;
device->hctx = hctx;
device->cursor = cursorix;
(*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &device->pktdata);
num_axes = 0;
if (device->pktdata & PK_X)
{
@ -615,7 +659,6 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
num_axes++;
}
if (device->pktdata & PK_NORMAL_PRESSURE)
{
_gdk_device_add_axis (GDK_DEVICE (device),
@ -669,12 +712,11 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
device_manager->wintab_devices = g_list_append (device_manager->wintab_devices,
device);
num_new_cursors++;
g_free (device_name);
}
g_free (devname_utf8);
}
return num_new_cursors;
}
/* Only initialize Wintab after the default display is set for
@ -918,6 +960,31 @@ get_modifier_key_state (void)
return state;
}
int
_gdk_find_wintab_device_index (HCTX hctx)
{
GList *tmp_list;
int devix;
/* Find the index of the Wintab driver's input device (probably zero) */
if (!wintab_contexts)
return -1; /* No tablet devices found or Wintab not initialized yet */
tmp_list = wintab_contexts;
devix = 0;
while (tmp_list)
{
if ((*(HCTX *) (tmp_list->data)) == hctx)
return devix;
else
{
devix++;
tmp_list = tmp_list->next;
}
}
return -1;
}
static GdkDeviceWintab *
gdk_device_manager_find_wintab_device (GdkDeviceManagerWin32 *device_manager,
HCTX hctx,
@ -1223,10 +1290,21 @@ G_GNUC_END_IGNORE_DEPRECATIONS;
if (device_manager->dev_entered_proximity > 0)
device_manager->dev_entered_proximity -= 1;
if ((source_device = gdk_device_manager_find_wintab_device (device_manager,
if ((source_device =
gdk_device_manager_find_wintab_device (device_manager,
(HCTX) msg->lParam,
packet.pkCursor)) == NULL)
{
/* Check for new cursors and try again */
if (_wintab_recognize_new_cursors(device_manager,
(HCTX) msg->lParam) == 0)
return FALSE;
if ((source_device =
gdk_device_manager_find_wintab_device (device_manager,
(HCTX) msg->lParam,
packet.pkCursor)) == NULL)
return FALSE;
}
if (source_device->sends_core &&
gdk_device_get_mode (GDK_DEVICE (source_device)) != GDK_MODE_DISABLED)
@ -1235,7 +1313,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS;
GDK_DEVICE (source_device));
_gdk_input_ignore_core += 1;
}
return FALSE;
case WT_PROXIMITY: