Compare commits
5 Commits
matthiasc/
...
wip/tablet
Author | SHA1 | Date | |
---|---|---|---|
|
08f4e5f091 | ||
|
8999ce720a | ||
|
3666cd4cef | ||
|
a34d9203ee | ||
|
6315284d6f |
@@ -747,6 +747,9 @@ gdk_device_list_axes
|
||||
gdk_device_get_axis_value
|
||||
gdk_device_get_last_event_window
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_device_tool_get_serial
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GDK_TYPE_AXIS_USE
|
||||
GDK_TYPE_EXTENSION_MODE
|
||||
@@ -846,6 +849,8 @@ gdk_event_get_device
|
||||
gdk_event_set_device
|
||||
gdk_event_get_source_device
|
||||
gdk_event_set_source_device
|
||||
gdk_event_get_device_tool
|
||||
gdk_event_set_device_tool
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_setting_get
|
||||
|
118
gdk/gdkdevice.c
118
gdk/gdkdevice.c
@@ -43,6 +43,11 @@
|
||||
|
||||
typedef struct _GdkAxisInfo GdkAxisInfo;
|
||||
|
||||
struct _GdkDeviceTool
|
||||
{
|
||||
guint serial;
|
||||
};
|
||||
|
||||
struct _GdkAxisInfo
|
||||
{
|
||||
GdkAtom label;
|
||||
@@ -57,6 +62,7 @@ struct _GdkAxisInfo
|
||||
|
||||
enum {
|
||||
CHANGED,
|
||||
TOOL_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -256,6 +262,14 @@ gdk_device_class_init (GdkDeviceClass *klass)
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
signals[TOOL_CHANGED] =
|
||||
g_signal_new (g_intern_static_string ("tool-changed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__BOXED,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_DEVICE_TOOL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -287,6 +301,12 @@ gdk_device_dispose (GObject *object)
|
||||
device->axes = NULL;
|
||||
}
|
||||
|
||||
if (device->tools)
|
||||
{
|
||||
g_ptr_array_free (device->tools, TRUE);
|
||||
device->tools = NULL;
|
||||
}
|
||||
|
||||
g_free (device->name);
|
||||
g_free (device->keys);
|
||||
|
||||
@@ -1757,3 +1777,101 @@ gdk_device_get_last_event_window (GdkDevice *device)
|
||||
|
||||
return info->window_under_pointer;
|
||||
}
|
||||
|
||||
static GdkDeviceTool *
|
||||
gdk_device_tool_copy (GdkDeviceTool *tool)
|
||||
{
|
||||
return tool;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_tool_free (GdkDeviceTool *tool)
|
||||
{
|
||||
/* Nothing to free here, memory is owned by GdkDevice */
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GdkDeviceTool, gdk_device_tool,
|
||||
gdk_device_tool_copy, gdk_device_tool_free);
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_device_tool_new (guint serial)
|
||||
{
|
||||
GdkDeviceTool *tool;
|
||||
|
||||
tool = g_new0 (GdkDeviceTool, 1);
|
||||
tool->serial = serial;
|
||||
|
||||
return tool;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_device_add_tool (GdkDevice *device,
|
||||
GdkDeviceTool *tool)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DEVICE (device));
|
||||
g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER);
|
||||
g_return_if_fail (tool != NULL);
|
||||
|
||||
if (!device->tools)
|
||||
device->tools = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
|
||||
|
||||
g_ptr_array_add (device->tools, tool);
|
||||
}
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_device_lookup_tool (GdkDevice *device,
|
||||
guint serial)
|
||||
{
|
||||
GdkDeviceTool *tool;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
|
||||
g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER, NULL);
|
||||
|
||||
if (!device->tools)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < device->tools->len; i++)
|
||||
{
|
||||
tool = g_ptr_array_index (device->tools, i);
|
||||
|
||||
if (tool->serial == serial)
|
||||
return tool;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_device_update_tool (GdkDevice *device,
|
||||
GdkDeviceTool *tool)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DEVICE (device));
|
||||
g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER);
|
||||
g_return_if_fail (!tool || gdk_device_lookup_tool (device, gdk_device_tool_get_serial (tool)) != NULL);
|
||||
|
||||
if (device->last_tool == tool)
|
||||
return;
|
||||
|
||||
device->last_tool = tool;
|
||||
g_signal_emit (device, signals[TOOL_CHANGED], 0, tool);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_device_tool_get_serial:
|
||||
* @tool: a #GdkDeviceTool
|
||||
*
|
||||
* Gets the serial of this tool, this value can be used to identify a
|
||||
* physical tool (eg. a tablet pen) across program executions.
|
||||
*
|
||||
* Returns: The serial ID for this tool
|
||||
*
|
||||
* Since: 3.16
|
||||
**/
|
||||
guint
|
||||
gdk_device_tool_get_serial (GdkDeviceTool *tool)
|
||||
{
|
||||
g_return_val_if_fail (tool != NULL, 0);
|
||||
|
||||
return tool->serial;
|
||||
}
|
||||
|
@@ -32,7 +32,10 @@ G_BEGIN_DECLS
|
||||
#define GDK_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE, GdkDevice))
|
||||
#define GDK_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE))
|
||||
|
||||
#define GDK_TYPE_DEVICE_TOOL (gdk_device_tool_get_type ())
|
||||
|
||||
typedef struct _GdkTimeCoord GdkTimeCoord;
|
||||
typedef struct _GdkDeviceTool GdkDeviceTool;
|
||||
|
||||
/**
|
||||
* GdkInputSource:
|
||||
@@ -274,6 +277,12 @@ gboolean gdk_device_grab_info_libgtk_only (GdkDisplay *display,
|
||||
GDK_AVAILABLE_IN_3_12
|
||||
GdkWindow *gdk_device_get_last_event_window (GdkDevice *device);
|
||||
|
||||
GDK_AVAILABLE_IN_3_16
|
||||
GType gdk_device_tool_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_16
|
||||
guint gdk_device_tool_get_serial (GdkDeviceTool *tool);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_H__ */
|
||||
|
@@ -56,6 +56,9 @@ struct _GdkDevice
|
||||
GList *slaves;
|
||||
GdkDeviceType type;
|
||||
GArray *axes;
|
||||
|
||||
GPtrArray *tools;
|
||||
GdkDeviceTool *last_tool;
|
||||
};
|
||||
|
||||
struct _GdkDeviceClass
|
||||
@@ -173,6 +176,15 @@ GdkWindow * _gdk_device_window_at_position (GdkDevice *device,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
|
||||
/* Device tools */
|
||||
GdkDeviceTool *gdk_device_tool_new (guint serial);
|
||||
GdkDeviceTool *gdk_device_lookup_tool (GdkDevice *device,
|
||||
guint serial);
|
||||
void gdk_device_add_tool (GdkDevice *device,
|
||||
GdkDeviceTool *tool);
|
||||
void gdk_device_update_tool (GdkDevice *device,
|
||||
GdkDeviceTool *tool);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_PRIVATE_H__ */
|
||||
|
@@ -642,6 +642,7 @@ gdk_event_copy (const GdkEvent *event)
|
||||
new_private->screen = private->screen;
|
||||
new_private->device = private->device;
|
||||
new_private->source_device = private->source_device;
|
||||
new_private->tool = private->tool;
|
||||
}
|
||||
|
||||
switch (event->any.type)
|
||||
@@ -2262,3 +2263,54 @@ gdk_event_get_event_type (const GdkEvent *event)
|
||||
|
||||
return event->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_event_get_device_tool:
|
||||
* @event: a #GdkEvent
|
||||
*
|
||||
* If the event was generated by a device that supports
|
||||
* different tools (eg. a tablet), this function will
|
||||
* return a #GdkDeviceTool representing the tool that
|
||||
* caused the event. Otherwise, %NULL will be returned.
|
||||
*
|
||||
* Note: the #GdkDeviceTool<!-- -->s will be constant during
|
||||
* the application lifetime, if settings must be stored
|
||||
* persistently across runs, see gdk_device_tool_get_serial()
|
||||
*
|
||||
* Returns: The current device tool, or %NULL
|
||||
*
|
||||
* Since: 3.16
|
||||
**/
|
||||
GdkDeviceTool *
|
||||
gdk_event_get_device_tool (const GdkEvent *event)
|
||||
{
|
||||
GdkEventPrivate *private;
|
||||
|
||||
if (!gdk_event_is_allocated (event))
|
||||
return NULL;
|
||||
|
||||
private = (GdkEventPrivate *) event;
|
||||
return private->tool;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_event_set_device_tool:
|
||||
* @event: a #GdkEvent
|
||||
* @tool: (nullable): tool to set on the event, or %NULL
|
||||
*
|
||||
* Sets the device tool for this event, should be rarely used.
|
||||
*
|
||||
* Since: 3.16
|
||||
**/
|
||||
void
|
||||
gdk_event_set_device_tool (GdkEvent *event,
|
||||
GdkDeviceTool *tool)
|
||||
{
|
||||
GdkEventPrivate *private;
|
||||
|
||||
if (!gdk_event_is_allocated (event))
|
||||
return;
|
||||
|
||||
private = (GdkEventPrivate *) event;
|
||||
private->tool = tool;
|
||||
}
|
||||
|
@@ -1309,6 +1309,13 @@ GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_setting_get (const gchar *name,
|
||||
GValue *value);
|
||||
|
||||
GDK_AVAILABLE_IN_3_16
|
||||
GdkDeviceTool *gdk_event_get_device_tool (const GdkEvent *event);
|
||||
|
||||
GDK_AVAILABLE_IN_3_16
|
||||
void gdk_event_set_device_tool (GdkEvent *event,
|
||||
GdkDeviceTool *tool);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_EVENTS_H__ */
|
||||
|
@@ -184,6 +184,7 @@ struct _GdkEventPrivate
|
||||
gpointer windowing_data;
|
||||
GdkDevice *device;
|
||||
GdkDevice *source_device;
|
||||
GdkDeviceTool *tool;
|
||||
};
|
||||
|
||||
typedef struct _GdkWindowPaint GdkWindowPaint;
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -543,6 +544,7 @@ gdk_x11_device_manager_xi2_constructed (GObject *object)
|
||||
screen = gdk_display_get_default_screen (display);
|
||||
XISetMask (mask, XI_HierarchyChanged);
|
||||
XISetMask (mask, XI_DeviceChanged);
|
||||
XISetMask (mask, XI_PropertyEvent);
|
||||
|
||||
event_mask.deviceid = XIAllDevices;
|
||||
event_mask.mask_len = sizeof (mask);
|
||||
@@ -775,6 +777,68 @@ handle_device_changed (GdkX11DeviceManagerXI2 *device_manager,
|
||||
_gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (source_device));
|
||||
}
|
||||
|
||||
static guint
|
||||
device_get_tool_serial (GdkDevice *device)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
gulong nitems, bytes_after;
|
||||
guint serial_id = 0;
|
||||
guint32 *data;
|
||||
int rc, format;
|
||||
Atom type;
|
||||
|
||||
display = gdk_device_get_display (device);
|
||||
|
||||
gdk_x11_display_error_trap_push (display);
|
||||
|
||||
rc = XIGetProperty (GDK_DISPLAY_XDISPLAY (display),
|
||||
gdk_x11_device_get_id (device),
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "Wacom Serial IDs"),
|
||||
0, 4, False, XA_INTEGER, &type, &format, &nitems, &bytes_after,
|
||||
(guchar **) &data);
|
||||
gdk_x11_display_error_trap_pop_ignored (display);
|
||||
|
||||
if (rc != Success)
|
||||
return 0;
|
||||
|
||||
if (type == XA_INTEGER && format == 32 && nitems >= 4)
|
||||
serial_id = data[3];
|
||||
|
||||
XFree (data);
|
||||
|
||||
return serial_id;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_property_change (GdkX11DeviceManagerXI2 *device_manager,
|
||||
XIPropertyEvent *ev)
|
||||
{
|
||||
GdkDevice *device;
|
||||
|
||||
device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (ev->deviceid));
|
||||
|
||||
if (ev->property == gdk_x11_get_xatom_by_name ("Wacom Serial IDs"))
|
||||
{
|
||||
GdkDeviceTool *tool = NULL;
|
||||
guint serial_id;
|
||||
|
||||
if (ev->what != XIPropertyDeleted)
|
||||
{
|
||||
serial_id = device_get_tool_serial (device);
|
||||
tool = gdk_device_lookup_tool (device, serial_id);
|
||||
|
||||
if (!tool && serial_id > 0)
|
||||
{
|
||||
tool = gdk_device_tool_new (serial_id);
|
||||
gdk_device_add_tool (device, tool);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_device_update_tool (device, tool);
|
||||
}
|
||||
}
|
||||
|
||||
static GdkCrossingMode
|
||||
translate_crossing_mode (gint mode)
|
||||
{
|
||||
@@ -1169,6 +1233,11 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
(XIDeviceChangedEvent *) ev);
|
||||
return_val = FALSE;
|
||||
break;
|
||||
case XI_PropertyEvent:
|
||||
handle_property_change (device_manager,
|
||||
(XIPropertyEvent *) ev);
|
||||
return_val = FALSE;
|
||||
break;
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
{
|
||||
@@ -1308,6 +1377,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
gdk_event_set_device_tool (event, source_device->last_tool);
|
||||
|
||||
event->button.axes = translate_axes (event->button.device,
|
||||
event->button.x,
|
||||
@@ -1412,6 +1482,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
event->motion.device = device;
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
gdk_event_set_device_tool (event, source_device->last_tool);
|
||||
|
||||
event->motion.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
|
||||
|
Reference in New Issue
Block a user