Compare commits
28 Commits
add-mutter
...
wip/waylan
Author | SHA1 | Date | |
---|---|---|---|
|
f71c85b163 | ||
|
fbc5a8c772 | ||
|
3061589507 | ||
|
8cb68a1f3d | ||
|
0414fe5251 | ||
|
604125e991 | ||
|
25b0318505 | ||
|
ab11dcc94a | ||
|
cc7901077f | ||
|
d9acfd5e6a | ||
|
0eaf32a27d | ||
|
b1d63e509c | ||
|
9e5a430ac1 | ||
|
b00b99511a | ||
|
55563a1a96 | ||
|
c1b585214e | ||
|
45ed5478e4 | ||
|
e0c29664c8 | ||
|
b963df69a6 | ||
|
436bf19e9d | ||
|
50d02d752f | ||
|
44b23556a4 | ||
|
b712ad53ff | ||
|
f7e76c5332 | ||
|
13e408278f | ||
|
b94d09999d | ||
|
9a4ca1784c | ||
|
30c4abd63d |
@@ -24,14 +24,15 @@
|
||||
|
||||
typedef struct {
|
||||
GdkDevice *last_source;
|
||||
GHashTable *axes; /* axis label atom -> value */
|
||||
GdkDeviceTool *last_tool;
|
||||
gdouble *axes;
|
||||
GdkRGBA color;
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
} AxesInfo;
|
||||
|
||||
typedef struct {
|
||||
AxesInfo *pointer_info;
|
||||
GHashTable *pointer_info; /* GdkDevice -> AxesInfo */
|
||||
GHashTable *touch_info; /* GdkEventSequence -> AxesInfo */
|
||||
} EventData;
|
||||
|
||||
@@ -59,8 +60,6 @@ axes_info_new (void)
|
||||
|
||||
info = g_new0 (AxesInfo, 1);
|
||||
gdk_rgba_parse (&info->color, colors[cur_color]);
|
||||
info->axes = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
|
||||
cur_color = (cur_color + 1) % G_N_ELEMENTS (colors);
|
||||
|
||||
@@ -70,38 +69,17 @@ axes_info_new (void)
|
||||
static void
|
||||
axes_info_free (AxesInfo *info)
|
||||
{
|
||||
g_hash_table_destroy (info->axes);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
axes_info_lookup (AxesInfo *info,
|
||||
const gchar *axis_label,
|
||||
gdouble *value)
|
||||
{
|
||||
gdouble *val;
|
||||
GdkAtom atom;
|
||||
|
||||
atom = gdk_atom_intern (axis_label, FALSE);
|
||||
|
||||
if (atom == GDK_NONE)
|
||||
return FALSE;
|
||||
|
||||
val = g_hash_table_lookup (info->axes, GDK_ATOM_TO_POINTER (atom));
|
||||
|
||||
if (!val)
|
||||
return FALSE;
|
||||
|
||||
*value = *val;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static EventData *
|
||||
event_data_new (void)
|
||||
{
|
||||
EventData *data;
|
||||
|
||||
data = g_new0 (EventData, 1);
|
||||
data->pointer_info = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) axes_info_free);
|
||||
data->touch_info = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) axes_info_free);
|
||||
|
||||
@@ -111,8 +89,7 @@ event_data_new (void)
|
||||
static void
|
||||
event_data_free (EventData *data)
|
||||
{
|
||||
if (data->pointer_info)
|
||||
axes_info_free (data->pointer_info);
|
||||
g_hash_table_destroy (data->pointer_info);
|
||||
g_hash_table_destroy (data->touch_info);
|
||||
g_free (data);
|
||||
}
|
||||
@@ -123,13 +100,14 @@ update_axes_from_event (GdkEvent *event,
|
||||
{
|
||||
GdkDevice *device, *source_device;
|
||||
GdkEventSequence *sequence;
|
||||
gdouble x, y, value;
|
||||
GList *l, *axes;
|
||||
GdkDeviceTool *tool;
|
||||
gdouble x, y;
|
||||
AxesInfo *info;
|
||||
|
||||
device = gdk_event_get_device (event);
|
||||
source_device = gdk_event_get_source_device (event);
|
||||
sequence = gdk_event_get_event_sequence (event);
|
||||
tool = gdk_event_get_device_tool (event);
|
||||
|
||||
if (event->type == GDK_TOUCH_END ||
|
||||
event->type == GDK_TOUCH_CANCEL)
|
||||
@@ -139,17 +117,19 @@ update_axes_from_event (GdkEvent *event,
|
||||
}
|
||||
else if (event->type == GDK_LEAVE_NOTIFY)
|
||||
{
|
||||
if (data->pointer_info)
|
||||
axes_info_free (data->pointer_info);
|
||||
data->pointer_info = NULL;
|
||||
g_hash_table_remove (data->pointer_info, device);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sequence)
|
||||
{
|
||||
if (!data->pointer_info)
|
||||
data->pointer_info = axes_info_new ();
|
||||
info = data->pointer_info;
|
||||
info = g_hash_table_lookup (data->pointer_info, device);
|
||||
|
||||
if (!info)
|
||||
{
|
||||
info = axes_info_new ();
|
||||
g_hash_table_insert (data->pointer_info, device, info);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -163,10 +143,10 @@ update_axes_from_event (GdkEvent *event,
|
||||
}
|
||||
|
||||
if (info->last_source != source_device)
|
||||
{
|
||||
g_hash_table_remove_all (info->axes);
|
||||
info->last_source = source_device;
|
||||
}
|
||||
info->last_source = source_device;
|
||||
|
||||
if (info->last_tool != tool)
|
||||
info->last_tool = tool;
|
||||
|
||||
if (event->type == GDK_TOUCH_BEGIN ||
|
||||
event->type == GDK_TOUCH_UPDATE ||
|
||||
@@ -174,30 +154,15 @@ update_axes_from_event (GdkEvent *event,
|
||||
event->type == GDK_BUTTON_PRESS ||
|
||||
event->type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
axes = gdk_device_list_axes (device);
|
||||
|
||||
if (sequence && event->touch.emulating_pointer)
|
||||
{
|
||||
if (data->pointer_info)
|
||||
axes_info_free (data->pointer_info);
|
||||
data->pointer_info = NULL;
|
||||
}
|
||||
g_hash_table_remove (data->pointer_info, device);
|
||||
|
||||
for (l = axes; l; l = l->next)
|
||||
{
|
||||
gdouble *ptr;
|
||||
if (info->axes)
|
||||
g_free (info->axes);
|
||||
|
||||
/* All those event types are compatible wrt axes position in the struct */
|
||||
if (!gdk_device_get_axis_value (device, event->motion.axes,
|
||||
l->data, &value))
|
||||
continue;
|
||||
|
||||
ptr = g_new0 (gdouble, 1);
|
||||
*ptr = value;
|
||||
g_hash_table_insert (info->axes, GDK_ATOM_TO_POINTER (l->data), ptr);
|
||||
}
|
||||
|
||||
g_list_free (axes);
|
||||
info->axes =
|
||||
g_memdup (event->motion.axes,
|
||||
sizeof(gdouble) * gdk_device_get_n_axes (source_device));
|
||||
}
|
||||
|
||||
if (gdk_event_get_coords (event, &x, &y))
|
||||
@@ -242,7 +207,8 @@ draw_axes_info (cairo_t *cr,
|
||||
AxesInfo *info,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
gdouble pressure, tilt_x, tilt_y, wheel;
|
||||
gdouble pressure, tilt_x, tilt_y, distance, wheel;
|
||||
GdkAxisFlags axes = gdk_device_get_axes (info->last_source);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
@@ -257,10 +223,13 @@ draw_axes_info (cairo_t *cr,
|
||||
|
||||
cairo_translate (cr, info->x, info->y);
|
||||
|
||||
if (axes_info_lookup (info, "Abs Pressure", &pressure))
|
||||
if (axes & GDK_AXIS_FLAG_PRESSURE)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_PRESSURE,
|
||||
&pressure);
|
||||
|
||||
pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, 100);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, pressure, 1, 0, 0, pressure);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 1, 0);
|
||||
@@ -273,12 +242,49 @@ draw_axes_info (cairo_t *cr,
|
||||
cairo_pattern_destroy (pattern);
|
||||
}
|
||||
|
||||
if (axes_info_lookup (info, "Abs Tilt X", &tilt_x) &&
|
||||
axes_info_lookup (info, "Abs Tilt Y", &tilt_y))
|
||||
render_arrow (cr, tilt_x * 100, tilt_y * 100, "Tilt");
|
||||
|
||||
if (axes_info_lookup (info, "Abs Wheel", &wheel))
|
||||
if (axes & GDK_AXIS_FLAG_XTILT &&
|
||||
axes & GDK_AXIS_FLAG_YTILT)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_XTILT,
|
||||
&tilt_x);
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_YTILT,
|
||||
&tilt_y);
|
||||
|
||||
render_arrow (cr, tilt_x * 100, tilt_y * 100, "Tilt");
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_DISTANCE)
|
||||
{
|
||||
double dashes[] = { 5.0, 5.0 };
|
||||
cairo_text_extents_t extents;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_DISTANCE,
|
||||
&distance);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_move_to (cr, distance * 100, 0);
|
||||
|
||||
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
|
||||
cairo_set_dash (cr, dashes, 2, 0.0);
|
||||
cairo_arc (cr, 0, 0, distance * 100, 0, 2 * G_PI);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_move_to (cr, 0, -distance * 100);
|
||||
cairo_text_extents (cr, "Distance", &extents);
|
||||
cairo_rel_move_to (cr, -extents.width / 2, 0);
|
||||
cairo_show_text (cr, "Distance");
|
||||
|
||||
cairo_move_to (cr, 0, 0);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_WHEEL)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_WHEEL,
|
||||
&wheel);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_set_line_width (cr, 10);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
|
||||
@@ -292,6 +298,31 @@ draw_axes_info (cairo_t *cr,
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
tool_type_to_string (GdkDeviceToolType tool_type)
|
||||
{
|
||||
switch (tool_type)
|
||||
{
|
||||
case GDK_DEVICE_TOOL_TYPE_PEN:
|
||||
return "Pen";
|
||||
case GDK_DEVICE_TOOL_TYPE_ERASER:
|
||||
return "Eraser";
|
||||
case GDK_DEVICE_TOOL_TYPE_BRUSH:
|
||||
return "Brush";
|
||||
case GDK_DEVICE_TOOL_TYPE_PENCIL:
|
||||
return "Pencil";
|
||||
case GDK_DEVICE_TOOL_TYPE_AIRBRUSH:
|
||||
return "Airbrush";
|
||||
case GDK_DEVICE_TOOL_TYPE_MOUSE:
|
||||
return "Mouse";
|
||||
case GDK_DEVICE_TOOL_TYPE_LENS:
|
||||
return "Lens cursor";
|
||||
case GDK_DEVICE_TOOL_TYPE_UNKNOWN:
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_device_info (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
@@ -313,6 +344,19 @@ draw_device_info (GtkWidget *widget,
|
||||
g_string_append_printf (string, "\nSequence: %d",
|
||||
GPOINTER_TO_UINT (sequence));
|
||||
|
||||
if (info->last_tool)
|
||||
{
|
||||
const gchar *tool_type;
|
||||
guint64 serial;
|
||||
|
||||
tool_type = tool_type_to_string (gdk_device_tool_get_tool_type (info->last_tool));
|
||||
serial = gdk_device_tool_get_serial (info->last_tool);
|
||||
g_string_append_printf (string, "\nTool: %s", tool_type);
|
||||
|
||||
if (serial != 0)
|
||||
g_string_append_printf (string, ", Serial: %lx", serial);
|
||||
}
|
||||
|
||||
cairo_move_to (cr, 10, *y);
|
||||
layout = gtk_widget_create_pango_layout (widget, string->str);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
@@ -341,7 +385,7 @@ draw_cb (GtkWidget *widget,
|
||||
{
|
||||
EventData *data = user_data;
|
||||
GtkAllocation allocation;
|
||||
AxesInfo *touch_info;
|
||||
AxesInfo *info;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
gint y = 0;
|
||||
@@ -349,27 +393,37 @@ draw_cb (GtkWidget *widget,
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
/* Draw Abs info */
|
||||
if (data->pointer_info)
|
||||
draw_axes_info (cr, data->pointer_info, &allocation);
|
||||
g_hash_table_iter_init (&iter, data->pointer_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_axes_info (cr, info, &allocation);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, data->touch_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
touch_info = value;
|
||||
draw_axes_info (cr, touch_info, &allocation);
|
||||
info = value;
|
||||
draw_axes_info (cr, info, &allocation);
|
||||
}
|
||||
|
||||
/* Draw name, color legend and misc data */
|
||||
if (data->pointer_info)
|
||||
draw_device_info (widget, cr, NULL, &y, data->pointer_info);
|
||||
g_hash_table_iter_init (&iter, data->pointer_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_device_info (widget, cr, NULL, &y, info);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, data->touch_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
touch_info = value;
|
||||
draw_device_info (widget, cr, key, &y, touch_info);
|
||||
info = value;
|
||||
draw_device_info (widget, cr, key, &y, info);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@@ -393,11 +447,14 @@ do_event_axes (GtkWidget *toplevel)
|
||||
|
||||
box = gtk_event_box_new ();
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
gtk_widget_set_support_multidevice (box, TRUE);
|
||||
gtk_widget_add_events (box,
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_BUTTON_PRESS_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_SMOOTH_SCROLL_MASK |
|
||||
GDK_ENTER_NOTIFY_MASK |
|
||||
GDK_LEAVE_NOTIFY_MASK |
|
||||
GDK_TOUCH_MASK);
|
||||
|
||||
event_data = event_data_new ();
|
||||
|
@@ -715,6 +715,8 @@ GdkDevice
|
||||
GdkInputSource
|
||||
GdkInputMode
|
||||
GdkAxisUse
|
||||
GdkAxisFlags
|
||||
GdkDeviceToolType
|
||||
GdkDeviceType
|
||||
GdkGrabOwnership
|
||||
|
||||
@@ -736,6 +738,7 @@ gdk_device_get_display
|
||||
gdk_device_get_has_cursor
|
||||
gdk_device_get_n_axes
|
||||
gdk_device_get_n_keys
|
||||
gdk_device_get_axes
|
||||
gdk_device_warp
|
||||
gdk_device_get_seat
|
||||
|
||||
@@ -757,6 +760,10 @@ gdk_device_list_axes
|
||||
gdk_device_get_axis_value
|
||||
gdk_device_get_last_event_window
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_device_tool_get_serial
|
||||
gdk_device_tool_get_tool_type
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GDK_TYPE_AXIS_USE
|
||||
GDK_TYPE_EXTENSION_MODE
|
||||
@@ -883,6 +890,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
|
||||
|
219
gdk/gdkdevice.c
219
gdk/gdkdevice.c
@@ -57,6 +57,7 @@ struct _GdkAxisInfo
|
||||
|
||||
enum {
|
||||
CHANGED,
|
||||
TOOL_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -92,6 +93,7 @@ enum {
|
||||
PROP_PRODUCT_ID,
|
||||
PROP_SEAT,
|
||||
PROP_NUM_TOUCHES,
|
||||
PROP_AXES,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
@@ -305,6 +307,19 @@ gdk_device_class_init (GdkDeviceClass *klass)
|
||||
0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
/**
|
||||
* GdkDevice:axes:
|
||||
*
|
||||
* The axes currently available for this device.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
device_props[PROP_AXES] =
|
||||
g_param_spec_flags ("axes",
|
||||
P_("Axes"),
|
||||
P_("Axes"),
|
||||
GDK_TYPE_AXIS_FLAGS, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, device_props);
|
||||
|
||||
@@ -327,6 +342,24 @@ gdk_device_class_init (GdkDeviceClass *klass)
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GdkDevice::tool-changed:
|
||||
* @device: the #GdkDevice that changed.
|
||||
* @tool: The new current tool
|
||||
*
|
||||
* The ::tool-changed signal is emitted on pen/eraser
|
||||
* #GdkDevice<!-- -->s whenever tools enter or leave proximity.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
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
|
||||
@@ -374,6 +407,8 @@ gdk_device_dispose (GObject *object)
|
||||
g_object_unref (associated);
|
||||
}
|
||||
|
||||
g_clear_object (&device->last_tool);
|
||||
|
||||
G_OBJECT_CLASS (gdk_device_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -477,6 +512,9 @@ gdk_device_get_property (GObject *object,
|
||||
case PROP_NUM_TOUCHES:
|
||||
g_value_set_uint (value, device->num_touches);
|
||||
break;
|
||||
case PROP_AXES:
|
||||
g_value_set_flags (value, device->axis_flags);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -1515,7 +1553,10 @@ _gdk_device_reset_axes (GdkDevice *device)
|
||||
for (i = device->axes->len - 1; i >= 0; i--)
|
||||
g_array_remove_index (device->axes, i);
|
||||
|
||||
device->axis_flags = 0;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (device), device_props[PROP_N_AXES]);
|
||||
g_object_notify_by_pspec (G_OBJECT (device), device_props[PROP_AXES]);
|
||||
}
|
||||
|
||||
guint
|
||||
@@ -1556,7 +1597,10 @@ _gdk_device_add_axis (GdkDevice *device,
|
||||
device->axes = g_array_append_val (device->axes, axis_info);
|
||||
pos = device->axes->len - 1;
|
||||
|
||||
device->axis_flags |= (1 << use);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (device), device_props[PROP_N_AXES]);
|
||||
g_object_notify_by_pspec (G_OBJECT (device), device_props[PROP_AXES]);
|
||||
|
||||
return pos;
|
||||
}
|
||||
@@ -1964,3 +2008,178 @@ gdk_device_get_seat (GdkDevice *device)
|
||||
|
||||
return device->seat;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_device_get_axes:
|
||||
* @device: a #GdkDevice
|
||||
*
|
||||
* Returns the axes currently available on the device.
|
||||
*
|
||||
* Since: 3.22
|
||||
**/
|
||||
GdkAxisFlags
|
||||
gdk_device_get_axes (GdkDevice *device)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
|
||||
|
||||
return device->axis_flags;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (GdkDeviceTool, gdk_device_tool, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
TOOL_PROP_0,
|
||||
TOOL_PROP_SERIAL,
|
||||
TOOL_PROP_TOOL_TYPE,
|
||||
TOOL_PROP_AXES,
|
||||
N_TOOL_PROPS
|
||||
};
|
||||
|
||||
GParamSpec *tool_props[N_TOOL_PROPS] = { 0 };
|
||||
|
||||
static void
|
||||
gdk_device_tool_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDeviceTool *tool = GDK_DEVICE_TOOL (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case TOOL_PROP_SERIAL:
|
||||
tool->serial = g_value_get_uint64 (value);
|
||||
break;
|
||||
case TOOL_PROP_TOOL_TYPE:
|
||||
tool->type = g_value_get_enum (value);
|
||||
break;
|
||||
case TOOL_PROP_AXES:
|
||||
tool->tool_axes = g_value_get_flags (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_tool_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDeviceTool *tool = GDK_DEVICE_TOOL (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case TOOL_PROP_SERIAL:
|
||||
g_value_set_uint64 (value, tool->serial);
|
||||
break;
|
||||
case TOOL_PROP_TOOL_TYPE:
|
||||
g_value_set_enum (value, tool->type);
|
||||
break;
|
||||
case TOOL_PROP_AXES:
|
||||
g_value_set_flags (value, tool->tool_axes);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_tool_class_init (GdkDeviceToolClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = gdk_device_tool_set_property;
|
||||
object_class->get_property = gdk_device_tool_get_property;
|
||||
|
||||
tool_props[TOOL_PROP_SERIAL] = g_param_spec_uint64 ("serial",
|
||||
"Serial",
|
||||
"Serial number",
|
||||
0, G_MAXUINT64, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
tool_props[TOOL_PROP_TOOL_TYPE] = g_param_spec_enum ("tool-type",
|
||||
"Tool type",
|
||||
"Tool type",
|
||||
GDK_TYPE_DEVICE_TOOL_TYPE,
|
||||
GDK_DEVICE_TOOL_TYPE_UNKNOWN,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
tool_props[TOOL_PROP_AXES] = g_param_spec_flags ("axes",
|
||||
"Axes",
|
||||
"Tool axes",
|
||||
GDK_TYPE_AXIS_FLAGS, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_TOOL_PROPS, tool_props);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_tool_init (GdkDeviceTool *tool)
|
||||
{
|
||||
}
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_device_tool_new (guint64 serial,
|
||||
GdkDeviceToolType type,
|
||||
GdkAxisFlags tool_axes)
|
||||
{
|
||||
return g_object_new (GDK_TYPE_DEVICE_TOOL,
|
||||
"serial", serial,
|
||||
"tool-type", type,
|
||||
"axes", tool_axes,
|
||||
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);
|
||||
|
||||
if (g_set_object (&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.22
|
||||
**/
|
||||
guint
|
||||
gdk_device_tool_get_serial (GdkDeviceTool *tool)
|
||||
{
|
||||
g_return_val_if_fail (tool != NULL, 0);
|
||||
|
||||
return tool->serial;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_device_tool_get_tool_type:
|
||||
* @tool: a #GdkDeviceTool
|
||||
*
|
||||
* Gets the #GdkDeviceToolType of the tool.
|
||||
*
|
||||
* Returns: The physical type for this tool. This can be used to figure out what
|
||||
* sort of pen is being used, such as an airbrush or a pencil.
|
||||
*
|
||||
* Since: 3.22
|
||||
**/
|
||||
GdkDeviceToolType
|
||||
gdk_device_tool_get_tool_type (GdkDeviceTool *tool)
|
||||
{
|
||||
g_return_val_if_fail (tool != NULL, GDK_DEVICE_TOOL_TYPE_UNKNOWN);
|
||||
|
||||
return tool->type;
|
||||
}
|
||||
|
@@ -32,7 +32,12 @@ 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 ())
|
||||
#define GDK_DEVICE_TOOL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_TOOL, GdkDeviceTool))
|
||||
#define GDK_IS_DEVICE_TOOL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_TOOL))
|
||||
|
||||
typedef struct _GdkTimeCoord GdkTimeCoord;
|
||||
typedef struct _GdkDeviceTool GdkDeviceTool;
|
||||
|
||||
/**
|
||||
* GdkInputSource:
|
||||
@@ -89,6 +94,9 @@ typedef enum
|
||||
* @GDK_AXIS_XTILT: the axis is used for x tilt information.
|
||||
* @GDK_AXIS_YTILT: the axis is used for y tilt information.
|
||||
* @GDK_AXIS_WHEEL: the axis is used for wheel information.
|
||||
* @GDK_AXIS_DISTANCE: the axis is used for pen/tablet distance information. (Since: 3.22)
|
||||
* @GDK_AXIS_ROTATION: the axis is used for pen rotation information. (Since: 3.22)
|
||||
* @GDK_AXIS_SLIDER: the axis is used for pen slider information. (Since: 3.22)
|
||||
* @GDK_AXIS_LAST: a constant equal to the numerically highest axis value.
|
||||
*
|
||||
* An enumeration describing the way in which a device
|
||||
@@ -104,9 +112,41 @@ typedef enum
|
||||
GDK_AXIS_XTILT,
|
||||
GDK_AXIS_YTILT,
|
||||
GDK_AXIS_WHEEL,
|
||||
GDK_AXIS_DISTANCE,
|
||||
GDK_AXIS_ROTATION,
|
||||
GDK_AXIS_SLIDER,
|
||||
GDK_AXIS_LAST
|
||||
} GdkAxisUse;
|
||||
|
||||
/**
|
||||
* GdkAxisFlags:
|
||||
* @GDK_AXIS_FLAG_X: X axis is present
|
||||
* @GDK_AXIS_FLAG_Y: Y axis is present
|
||||
* @GDK_AXIS_FLAG_PRESSURE: Pressure axis is present
|
||||
* @GDK_AXIS_FLAG_XTILT: X tilt axis is present
|
||||
* @GDK_AXIS_FLAG_YTILT: Y tilt axis is present
|
||||
* @GDK_AXIS_FLAG_WHEEL: Wheel axis is present
|
||||
* @GDK_AXIS_FLAG_DISTANCE: Distance axis is present
|
||||
* @GDK_AXIS_FLAG_ROTATION: Z-axis rotation is present
|
||||
* @GDK_AXIS_FLAG_SLIDER: Slider axis is present
|
||||
*
|
||||
* Flags describing the current capabilities of a device/tool.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GDK_AXIS_FLAG_X = 1 << GDK_AXIS_X,
|
||||
GDK_AXIS_FLAG_Y = 1 << GDK_AXIS_Y,
|
||||
GDK_AXIS_FLAG_PRESSURE = 1 << GDK_AXIS_PRESSURE,
|
||||
GDK_AXIS_FLAG_XTILT = 1 << GDK_AXIS_XTILT,
|
||||
GDK_AXIS_FLAG_YTILT = 1 << GDK_AXIS_YTILT,
|
||||
GDK_AXIS_FLAG_WHEEL = 1 << GDK_AXIS_WHEEL,
|
||||
GDK_AXIS_FLAG_DISTANCE = 1 << GDK_AXIS_DISTANCE,
|
||||
GDK_AXIS_FLAG_ROTATION = 1 << GDK_AXIS_ROTATION,
|
||||
GDK_AXIS_FLAG_SLIDER = 1 << GDK_AXIS_SLIDER,
|
||||
} GdkAxisFlags;
|
||||
|
||||
/**
|
||||
* GdkDeviceType:
|
||||
* @GDK_DEVICE_TYPE_MASTER: Device is a master (or virtual) device. There will
|
||||
@@ -124,6 +164,33 @@ typedef enum {
|
||||
GDK_DEVICE_TYPE_FLOATING
|
||||
} GdkDeviceType;
|
||||
|
||||
/**
|
||||
* GdkDeviceToolType:
|
||||
* @GDK_DEVICE_TOOL_TYPE_UNKNOWN: Tool is of an unknown type.
|
||||
* @GDK_DEVICE_TOOL_TYPE_PEN: Tool is a standard tablet stylus.
|
||||
* @GDK_DEVICE_TOOL_TYPE_ERASER: Tool is standard tablet eraser.
|
||||
* @GDK_DEVICE_TOOL_TYPE_BRUSH: Tool is a brush stylus.
|
||||
* @GDK_DEVICE_TOOL_TYPE_PENCIL: Tool is a pencil stylus.
|
||||
* @GDK_DEVICE_TOOL_TYPE_AIRBRUSH: Tool is an airbrush stylus.
|
||||
* @GDK_DEVICE_TOOL_TYPE_MOUSE: Tool is a mouse.
|
||||
* @GDK_DEVICE_TOOL_TYPE_LENS: Tool is a lens cursor.
|
||||
*
|
||||
* Indicates the specific type of tool being used being a tablet. Such as an
|
||||
* airbrush, pencil, etc.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_DEVICE_TOOL_TYPE_UNKNOWN,
|
||||
GDK_DEVICE_TOOL_TYPE_PEN,
|
||||
GDK_DEVICE_TOOL_TYPE_ERASER,
|
||||
GDK_DEVICE_TOOL_TYPE_BRUSH,
|
||||
GDK_DEVICE_TOOL_TYPE_PENCIL,
|
||||
GDK_DEVICE_TOOL_TYPE_AIRBRUSH,
|
||||
GDK_DEVICE_TOOL_TYPE_MOUSE,
|
||||
GDK_DEVICE_TOOL_TYPE_LENS,
|
||||
} GdkDeviceToolType;
|
||||
|
||||
/* We don't allocate each coordinate this big, but we use it to
|
||||
* be ANSI compliant and avoid accessing past the defined limits.
|
||||
*/
|
||||
@@ -282,6 +349,18 @@ const gchar *gdk_device_get_product_id (GdkDevice *device);
|
||||
GDK_AVAILABLE_IN_3_20
|
||||
GdkSeat *gdk_device_get_seat (GdkDevice *device);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GdkAxisFlags gdk_device_get_axes (GdkDevice *device);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GType gdk_device_tool_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
guint gdk_device_tool_get_serial (GdkDeviceTool *tool);
|
||||
|
||||
GDK_AVAILABLE_IN_3_22
|
||||
GdkDeviceToolType gdk_device_tool_get_tool_type (GdkDeviceTool *tool);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_H__ */
|
||||
|
@@ -30,8 +30,22 @@ G_BEGIN_DECLS
|
||||
#define GDK_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE, GdkDeviceClass))
|
||||
|
||||
typedef struct _GdkDeviceClass GdkDeviceClass;
|
||||
typedef struct _GdkDeviceToolClass GdkDeviceToolClass;
|
||||
typedef struct _GdkDeviceKey GdkDeviceKey;
|
||||
|
||||
struct _GdkDeviceTool
|
||||
{
|
||||
GObject parent_instance;
|
||||
guint64 serial;
|
||||
GdkDeviceToolType type;
|
||||
GdkAxisFlags tool_axes;
|
||||
};
|
||||
|
||||
struct _GdkDeviceToolClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
struct _GdkDeviceKey
|
||||
{
|
||||
guint keyval;
|
||||
@@ -47,6 +61,7 @@ struct _GdkDevice
|
||||
GdkInputMode mode;
|
||||
gboolean has_cursor;
|
||||
gint num_keys;
|
||||
GdkAxisFlags axis_flags;
|
||||
GdkDeviceKey *keys;
|
||||
GdkDeviceManager *manager;
|
||||
GdkDisplay *display;
|
||||
@@ -63,6 +78,7 @@ struct _GdkDevice
|
||||
gchar *product_id;
|
||||
|
||||
GdkSeat *seat;
|
||||
GdkDeviceTool *last_tool;
|
||||
};
|
||||
|
||||
struct _GdkDeviceClass
|
||||
@@ -183,6 +199,13 @@ GdkWindow * _gdk_device_window_at_position (GdkDevice *device,
|
||||
void gdk_device_set_seat (GdkDevice *device,
|
||||
GdkSeat *seat);
|
||||
|
||||
/* Device tools */
|
||||
GdkDeviceTool *gdk_device_tool_new (guint64 serial,
|
||||
GdkDeviceToolType type,
|
||||
GdkAxisFlags tool_axes);
|
||||
void gdk_device_update_tool (GdkDevice *device,
|
||||
GdkDeviceTool *tool);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_PRIVATE_H__ */
|
||||
|
@@ -650,6 +650,7 @@ gdk_event_copy (const GdkEvent *event)
|
||||
new_private->device = private->device ? g_object_ref (private->device) : NULL;
|
||||
new_private->source_device = private->source_device ? g_object_ref (private->source_device) : NULL;
|
||||
new_private->seat = private->seat;
|
||||
new_private->tool = private->tool;
|
||||
}
|
||||
|
||||
switch (event->any.type)
|
||||
@@ -2412,3 +2413,54 @@ gdk_event_set_seat (GdkEvent *event,
|
||||
priv->seat = seat;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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: (transfer none): The current device tool, or %NULL
|
||||
*
|
||||
* Since: 3.22
|
||||
**/
|
||||
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.22
|
||||
**/
|
||||
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;
|
||||
}
|
||||
|
@@ -1443,6 +1443,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__ */
|
||||
|
@@ -189,6 +189,7 @@ struct _GdkEventPrivate
|
||||
GdkDevice *device;
|
||||
GdkDevice *source_device;
|
||||
GdkSeat *seat;
|
||||
GdkDeviceTool *tool;
|
||||
};
|
||||
|
||||
typedef struct _GdkWindowPaint GdkWindowPaint;
|
||||
|
@@ -46,6 +46,8 @@ struct _GdkSeatPrivate
|
||||
enum {
|
||||
DEVICE_ADDED,
|
||||
DEVICE_REMOVED,
|
||||
TOOL_ADDED,
|
||||
TOOL_REMOVED,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
@@ -146,6 +148,48 @@ gdk_seat_class_init (GdkSeatClass *klass)
|
||||
G_TYPE_NONE, 1,
|
||||
GDK_TYPE_DEVICE);
|
||||
|
||||
/**
|
||||
* GdkSeat::tool-added:
|
||||
* @seat: the object on which the signal is emitted
|
||||
* @tool: the new #GdkDeviceTool known to the seat
|
||||
*
|
||||
* The ::tool-added signal is emitted whenever a new tool
|
||||
* is made known to the seat. The tool may later be assigned
|
||||
* to a device (i.e. on proximity with a tablet). The device
|
||||
* will emit the #GdkDevice::tool-changed signal accordingly.
|
||||
*
|
||||
* A same tool may be used by several devices.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
signals [TOOL_ADDED] =
|
||||
g_signal_new (g_intern_static_string ("tool-added"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__BOXED,
|
||||
G_TYPE_NONE, 1,
|
||||
GDK_TYPE_DEVICE_TOOL);
|
||||
|
||||
/**
|
||||
* GdkSeat::tool-removed:
|
||||
* @seat: the object on which the signal is emitted
|
||||
* @tool: the just removed #GdkDeviceTool
|
||||
*
|
||||
* This signal is emitted whenever a tool is no longer known
|
||||
* to this @seat.
|
||||
*
|
||||
* Since: 3.22
|
||||
*/
|
||||
signals [TOOL_REMOVED] =
|
||||
g_signal_new (g_intern_static_string ("tool-removed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__BOXED,
|
||||
G_TYPE_NONE, 1,
|
||||
GDK_TYPE_DEVICE_TOOL);
|
||||
|
||||
/**
|
||||
* GdkSeat:display:
|
||||
*
|
||||
@@ -388,3 +432,29 @@ gdk_seat_get_display (GdkSeat *seat)
|
||||
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_seat_tool_added (GdkSeat *seat,
|
||||
GdkDeviceTool *tool)
|
||||
{
|
||||
g_signal_emit (seat, signals[TOOL_ADDED], 0, tool);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_seat_tool_removed (GdkSeat *seat,
|
||||
GdkDeviceTool *tool)
|
||||
{
|
||||
g_signal_emit (seat, signals[TOOL_REMOVED], 0, tool);
|
||||
}
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial)
|
||||
{
|
||||
GdkSeatClass *seat_class;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SEAT (seat), NULL);
|
||||
|
||||
seat_class = GDK_SEAT_GET_CLASS (seat);
|
||||
return seat_class->get_tool (seat, serial);
|
||||
}
|
||||
|
@@ -29,6 +29,8 @@ struct _GdkSeatDefaultPrivate
|
||||
GList *slave_pointers;
|
||||
GList *slave_keyboards;
|
||||
GdkSeatCapabilities capabilities;
|
||||
|
||||
GPtrArray *tools;
|
||||
};
|
||||
|
||||
#define KEYBOARD_EVENTS (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | \
|
||||
@@ -76,6 +78,12 @@ gdk_seat_dispose (GObject *object)
|
||||
g_object_unref (l->data);
|
||||
}
|
||||
|
||||
if (priv->tools)
|
||||
{
|
||||
g_ptr_array_unref (priv->tools);
|
||||
priv->tools = NULL;
|
||||
}
|
||||
|
||||
g_list_free (priv->slave_pointers);
|
||||
g_list_free (priv->slave_keyboards);
|
||||
priv->slave_pointers = NULL;
|
||||
@@ -248,6 +256,30 @@ gdk_seat_default_get_slaves (GdkSeat *seat,
|
||||
return devices;
|
||||
}
|
||||
|
||||
static GdkDeviceTool *
|
||||
gdk_seat_default_get_tool (GdkSeat *seat,
|
||||
guint64 serial)
|
||||
{
|
||||
GdkSeatDefaultPrivate *priv;
|
||||
GdkDeviceTool *tool;
|
||||
guint i;
|
||||
|
||||
priv = gdk_seat_default_get_instance_private (GDK_SEAT_DEFAULT (seat));
|
||||
|
||||
if (!priv->tools)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < priv->tools->len; i++)
|
||||
{
|
||||
tool = g_ptr_array_index (priv->tools, i);
|
||||
|
||||
if (tool->serial == serial)
|
||||
return tool;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_seat_default_class_init (GdkSeatDefaultClass *klass)
|
||||
{
|
||||
@@ -263,6 +295,8 @@ gdk_seat_default_class_init (GdkSeatDefaultClass *klass)
|
||||
|
||||
seat_class->get_master = gdk_seat_default_get_master;
|
||||
seat_class->get_slaves = gdk_seat_default_get_slaves;
|
||||
|
||||
seat_class->get_tool = gdk_seat_default_get_tool;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -355,3 +389,40 @@ gdk_seat_default_remove_slave (GdkSeatDefault *seat,
|
||||
gdk_seat_device_removed (GDK_SEAT (seat), device);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gdk_seat_default_add_tool (GdkSeatDefault *seat,
|
||||
GdkDeviceTool *tool)
|
||||
{
|
||||
GdkSeatDefaultPrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_SEAT_DEFAULT (seat));
|
||||
g_return_if_fail (tool != NULL);
|
||||
|
||||
priv = gdk_seat_default_get_instance_private (seat);
|
||||
|
||||
if (!priv->tools)
|
||||
priv->tools = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
|
||||
g_ptr_array_add (priv->tools, g_object_ref (tool));
|
||||
g_signal_emit_by_name (seat, "tool-added", tool);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_seat_default_remove_tool (GdkSeatDefault *seat,
|
||||
GdkDeviceTool *tool)
|
||||
{
|
||||
GdkSeatDefaultPrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_SEAT_DEFAULT (seat));
|
||||
g_return_if_fail (tool != NULL);
|
||||
|
||||
priv = gdk_seat_default_get_instance_private (seat);
|
||||
|
||||
if (tool != gdk_seat_get_tool (GDK_SEAT (seat),
|
||||
gdk_device_tool_get_serial (tool)))
|
||||
return;
|
||||
|
||||
g_signal_emit_by_name (seat, "tool-removed", tool);
|
||||
g_ptr_array_remove (priv->tools, tool);
|
||||
}
|
||||
|
@@ -52,5 +52,9 @@ void gdk_seat_default_add_slave (GdkSeatDefault *seat,
|
||||
GdkDevice *device);
|
||||
void gdk_seat_default_remove_slave (GdkSeatDefault *seat,
|
||||
GdkDevice *device);
|
||||
void gdk_seat_default_add_tool (GdkSeatDefault *seat,
|
||||
GdkDeviceTool *tool);
|
||||
void gdk_seat_default_remove_tool (GdkSeatDefault *seat,
|
||||
GdkDeviceTool *tool);
|
||||
|
||||
#endif /* __GDK_SEAT_DEFAULT_PRIVATE_H__ */
|
||||
|
@@ -55,6 +55,9 @@ struct _GdkSeatClass
|
||||
GdkSeatCapabilities capability);
|
||||
GList * (* get_slaves) (GdkSeat *seat,
|
||||
GdkSeatCapabilities capabilities);
|
||||
|
||||
GdkDeviceTool * (* get_tool) (GdkSeat *seat,
|
||||
guint64 serial);
|
||||
};
|
||||
|
||||
void gdk_seat_device_added (GdkSeat *seat,
|
||||
@@ -62,4 +65,13 @@ void gdk_seat_device_added (GdkSeat *seat,
|
||||
void gdk_seat_device_removed (GdkSeat *seat,
|
||||
GdkDevice *device);
|
||||
|
||||
void gdk_seat_tool_added (GdkSeat *seat,
|
||||
GdkDeviceTool *tool);
|
||||
void gdk_seat_tool_removed (GdkSeat *seat,
|
||||
GdkDeviceTool *tool);
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial);
|
||||
|
||||
#endif /* __GDK_SEAT_PRIVATE_H__ */
|
||||
|
@@ -9039,6 +9039,7 @@ proxy_pointer_event (GdkDisplay *display,
|
||||
gdk_event_set_device (event, gdk_event_get_device (source_event));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
||||
gdk_event_set_device_tool (event, gdk_event_get_device_tool (source_event));
|
||||
|
||||
if (event_type == GDK_TOUCH_UPDATE)
|
||||
{
|
||||
@@ -9280,6 +9281,7 @@ proxy_button_event (GdkEvent *source_event,
|
||||
gdk_event_set_device (event, gdk_event_get_device (source_event));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
||||
gdk_event_set_device_tool (event, gdk_event_get_device_tool (source_event));
|
||||
|
||||
if (is_touch_type (source_event->type))
|
||||
{
|
||||
|
@@ -26,6 +26,8 @@ BUILT_SOURCES = \
|
||||
xdg-shell-unstable-v5-protocol.c \
|
||||
gtk-primary-selection-client-protocol.h \
|
||||
gtk-primary-selection-protocol.c \
|
||||
tablet-unstable-v1-client-protocol.h \
|
||||
tablet-unstable-v1-protocol.c \
|
||||
gtk-shell-client-protocol.h \
|
||||
gtk-shell-protocol.c
|
||||
|
||||
|
@@ -216,7 +216,7 @@ _gdk_wayland_cursor_get_buffer (GdkCursor *cursor,
|
||||
int *hotspot_y,
|
||||
int *w,
|
||||
int *h,
|
||||
int *scale)
|
||||
int *scale)
|
||||
{
|
||||
GdkWaylandCursor *wayland_cursor = GDK_WAYLAND_CURSOR (cursor);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -38,6 +38,7 @@
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkglcontext-wayland.h"
|
||||
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
||||
#include "tablet-unstable-v1-client-protocol.h"
|
||||
|
||||
/**
|
||||
* SECTION:wayland_interaction
|
||||
@@ -418,6 +419,12 @@ gdk_registry_handle_global (void *data,
|
||||
wl_registry_bind(display_wayland->wl_registry, id,
|
||||
>k_primary_selection_device_manager_interface, 1);
|
||||
}
|
||||
else if (strcmp (interface, "zwp_tablet_manager_v1") == 0)
|
||||
{
|
||||
display_wayland->tablet_manager =
|
||||
wl_registry_bind(display_wayland->wl_registry, id,
|
||||
&zwp_tablet_manager_v1_interface, 1);
|
||||
}
|
||||
else
|
||||
handled = FALSE;
|
||||
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-cursor.h>
|
||||
#include <wayland-egl.h>
|
||||
#include <gdk/wayland/tablet-unstable-v1-client-protocol.h>
|
||||
#include <gdk/wayland/gtk-shell-client-protocol.h>
|
||||
#include <gdk/wayland/xdg-shell-unstable-v5-client-protocol.h>
|
||||
|
||||
@@ -72,6 +73,7 @@ struct _GdkWaylandDisplay
|
||||
struct wl_subcompositor *subcompositor;
|
||||
struct zwp_pointer_gestures_v1 *pointer_gestures;
|
||||
struct gtk_primary_selection_device_manager *primary_selection_manager;
|
||||
struct zwp_tablet_manager_v1 *tablet_manager;
|
||||
|
||||
GList *async_roundtrips;
|
||||
|
||||
|
@@ -345,13 +345,17 @@ get_device_ids (GdkDisplay *display,
|
||||
gulong nitems, bytes_after;
|
||||
guint32 *data;
|
||||
int rc, format;
|
||||
Atom type;
|
||||
Atom prop, type;
|
||||
|
||||
gdk_x11_display_error_trap_push (display);
|
||||
|
||||
prop = XInternAtom (GDK_DISPLAY_XDISPLAY (display), "Device Product ID", True);
|
||||
|
||||
if (prop == None)
|
||||
return 0;
|
||||
|
||||
rc = XIGetProperty (GDK_DISPLAY_XDISPLAY (display),
|
||||
info->deviceid,
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "Device Product ID"),
|
||||
info->deviceid, prop,
|
||||
0, 2, False, XA_INTEGER, &type, &format, &nitems, &bytes_after,
|
||||
(guchar **) &data);
|
||||
gdk_x11_display_error_trap_pop_ignored (display);
|
||||
@@ -726,6 +730,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);
|
||||
@@ -966,6 +971,111 @@ 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
|
||||
translate_proximity (GdkDevice *device,
|
||||
GdkDeviceTool *tool,
|
||||
GdkEvent *event,
|
||||
XIPropertyEvent *ev)
|
||||
{
|
||||
GdkDevice *master = NULL;
|
||||
GdkWindow *window;
|
||||
|
||||
if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
|
||||
master = gdk_device_get_associated_device (device);
|
||||
|
||||
if (!master)
|
||||
master = device;
|
||||
|
||||
window = gdk_device_get_window_at_position (master, NULL, NULL);
|
||||
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
event->proximity.type = tool ? GDK_PROXIMITY_IN : GDK_PROXIMITY_OUT;
|
||||
event->proximity.window = window;
|
||||
event->proximity.time = ev->time;
|
||||
event->proximity.send_event = FALSE;
|
||||
gdk_event_set_device (event, master);
|
||||
gdk_event_set_source_device (event, device);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_property_change (GdkX11DeviceManagerXI2 *device_manager,
|
||||
XIPropertyEvent *ev,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkDevice *device;
|
||||
Atom wacom_serial_prop;
|
||||
|
||||
device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (ev->deviceid));
|
||||
|
||||
display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
|
||||
wacom_serial_prop = XInternAtom (GDK_DISPLAY_XDISPLAY (display),
|
||||
"Wacom Serial IDs", True);
|
||||
|
||||
if (wacom_serial_prop != None && ev->property == wacom_serial_prop)
|
||||
{
|
||||
GdkDeviceTool *tool = NULL;
|
||||
guint serial_id;
|
||||
GdkSeat *seat;
|
||||
|
||||
if (ev->what != XIPropertyDeleted)
|
||||
{
|
||||
serial_id = device_get_tool_serial (device);
|
||||
seat = gdk_device_get_seat (device);
|
||||
tool = gdk_seat_get_tool (seat, serial_id);
|
||||
|
||||
if (!tool && serial_id > 0)
|
||||
{
|
||||
tool = gdk_device_tool_new (serial_id,
|
||||
GDK_DEVICE_TOOL_TYPE_UNKNOWN, 0);
|
||||
gdk_seat_default_add_tool (GDK_SEAT_DEFAULT (seat), tool);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_device_update_tool (device, tool);
|
||||
|
||||
translate_proximity (device, tool, event, ev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GdkCrossingMode
|
||||
translate_crossing_mode (gint mode)
|
||||
{
|
||||
@@ -1366,6 +1476,12 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
(XIDeviceChangedEvent *) ev);
|
||||
return_val = FALSE;
|
||||
break;
|
||||
case XI_PropertyEvent:
|
||||
if (!handle_property_change (device_manager,
|
||||
(XIPropertyEvent *) ev,
|
||||
event))
|
||||
return_val = FALSE;
|
||||
break;
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
{
|
||||
@@ -1508,6 +1624,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
||||
gdk_event_set_device_tool (event, source_device->last_tool);
|
||||
|
||||
event->button.axes = translate_axes (event->button.device,
|
||||
event->button.x,
|
||||
@@ -1616,6 +1733,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_seat (event, gdk_device_get_seat (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