[mutter] backends/x11: Implement tablet settings based on the Wacom driver
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] backends/x11: Implement tablet settings based on the Wacom driver
- Date: Fri, 4 Nov 2016 20:38:59 +0000 (UTC)
commit ff9753688fcba7eacc49ba2420bf42c0af22dc59
Author: Carlos Garnacho <carlosg gnome org>
Date: Mon Oct 31 18:01:25 2016 +0100
backends/x11: Implement tablet settings based on the Wacom driver
This is a stopgap solution until libinput is the fallback driver
handling tablets and pads.
https://bugzilla.gnome.org/show_bug.cgi?id=773779
src/backends/x11/meta-input-settings-x11.c | 214 +++++++++++++++++++++++++++-
1 files changed, 207 insertions(+), 7 deletions(-)
---
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
index 332997b..d7d468d 100644
--- a/src/backends/x11/meta-input-settings-x11.c
+++ b/src/backends/x11/meta-input-settings-x11.c
@@ -188,10 +188,20 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled)
{
- guchar value = (enabled) ? 1 : 0;
+ guchar value;
- change_property (device, "libinput Left Handed Enabled",
- XA_INTEGER, 8, &value, 1);
+ if (clutter_input_device_get_device_type (device) == CLUTTER_TABLET_DEVICE)
+ {
+ value = enabled ? 3 : 0;
+ change_property (device, "Wacom Rotation",
+ XA_INTEGER, 8, &value, 1);
+ }
+ else
+ {
+ value = enabled ? 1 : 0;
+ change_property (device, "libinput Left Handed Enabled",
+ XA_INTEGER, 8, &value, 1);
+ }
}
static void
@@ -467,14 +477,76 @@ meta_input_settings_x11_set_tablet_mapping (MetaInputSettings *settings,
ClutterInputDevice *device,
GDesktopTabletMapping mapping)
{
+ MetaDisplay *display = meta_get_display ();
+ MetaBackend *backend = meta_get_backend ();
+ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
+ int device_id = clutter_input_device_get_device_id (device);
+ XDevice *xdev;
+
+ if (!display)
+ return;
+
+ /* Grab the puke bucket! */
+ meta_error_trap_push (display);
+ xdev = XOpenDevice (xdisplay, device_id);
+ if (xdev)
+ {
+ XSetDeviceMode (xdisplay, xdev,
+ mapping == G_DESKTOP_TABLET_MAPPING_ABSOLUTE ?
+ Absolute : Relative);
+ XCloseDevice (xdisplay, xdev);
+ }
+
+ if (meta_error_trap_pop_with_return (display))
+ {
+ g_warning ("Could not set tablet mapping for %s",
+ clutter_input_device_get_device_name (device));
+ }
+}
+
+static gboolean
+device_query_area (ClutterInputDevice *device,
+ gint *width,
+ gint *height)
+{
+ MetaBackend *backend = meta_get_backend ();
+ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
+ gint device_id, n_devices, i;
+ XIDeviceInfo *info;
+ Atom abs_x, abs_y;
+
+ *width = *height = 0;
+ device_id = clutter_input_device_get_device_id (device);
+ info = XIQueryDevice (xdisplay, device_id, &n_devices);
+ if (n_devices == 0)
+ return FALSE;
+
+ abs_x = XInternAtom (xdisplay, "Abs X", True);
+ abs_y = XInternAtom (xdisplay, "Abs Y", True);
+
+ for (i = 0; i < info->num_classes; i++)
+ {
+ XIValuatorClassInfo *valuator = (XIValuatorClassInfo *) info->classes[i];
+
+ if (valuator->type != XIValuatorClass)
+ continue;
+ if (valuator->label == abs_x)
+ *width = valuator->max - valuator->min;
+ else if (valuator->label == abs_y)
+ *height = valuator->max - valuator->min;
+ }
+
+ XIFreeDeviceInfo (info);
+ return TRUE;
}
static void
-meta_input_settings_x11_set_tablet_keep_aspect (MetaInputSettings *settings,
- ClutterInputDevice *device,
- MetaOutput *output,
- gboolean keep_aspect)
+update_tablet_area (MetaInputSettings *settings,
+ ClutterInputDevice *device,
+ gint32 *area)
{
+ change_property (device, "Wacom Tablet Area",
+ XA_INTEGER, 32, area, 4);
}
static void
@@ -485,6 +557,61 @@ meta_input_settings_x11_set_tablet_area (MetaInputSettings *settings,
gdouble padding_top,
gdouble padding_bottom)
{
+ gint32 width, height, area[4] = { 0 };
+
+ if (!device_query_area (device, &width, &height))
+ return;
+
+ area[0] = width * padding_left;
+ area[1] = height * padding_top;
+ area[2] = width - (width * padding_right);
+ area[2] = height - (height * padding_bottom);
+ update_tablet_area (settings, device, area);
+}
+
+static void
+meta_input_settings_x11_set_tablet_keep_aspect (MetaInputSettings *settings,
+ ClutterInputDevice *device,
+ MetaOutput *output,
+ gboolean keep_aspect)
+{
+ gint32 width, height, dev_width, dev_height, area[4] = { 0 };
+
+ if (!device_query_area (device, &dev_width, &dev_height))
+ return;
+
+ if (keep_aspect)
+ {
+ gdouble output_aspect, dev_aspect;
+
+ if (output && output->crtc)
+ {
+ width = output->crtc->rect.width;
+ height = output->crtc->rect.height;
+ }
+ else
+ {
+ MetaMonitorManager *monitor_manager;
+ MetaBackend *backend;
+
+ backend = meta_get_backend ();
+ monitor_manager = meta_backend_get_monitor_manager (backend);
+ meta_monitor_manager_get_screen_limits (monitor_manager,
+ &width, &height);
+ }
+
+ output_aspect = (gdouble) width / height;
+ dev_aspect = (gdouble) dev_width / dev_height;
+
+ if (dev_aspect > output_aspect)
+ dev_width = dev_height * output_aspect;
+ else if (dev_aspect < output_aspect)
+ dev_height = dev_width / output_aspect;
+ }
+
+ area[2] = dev_width;
+ area[3] = dev_height;
+ update_tablet_area (settings, device, area);
}
static void
@@ -501,6 +628,76 @@ meta_input_settings_x11_dispose (GObject *object)
G_OBJECT_CLASS (meta_input_settings_x11_parent_class)->dispose (object);
}
+static guint
+action_to_button (GDesktopStylusButtonAction action,
+ guint button)
+{
+ switch (action)
+ {
+ case G_DESKTOP_STYLUS_BUTTON_ACTION_MIDDLE:
+ return CLUTTER_BUTTON_MIDDLE;
+ case G_DESKTOP_STYLUS_BUTTON_ACTION_RIGHT:
+ return CLUTTER_BUTTON_SECONDARY;
+ case G_DESKTOP_STYLUS_BUTTON_ACTION_BACK:
+ return 8;
+ case G_DESKTOP_STYLUS_BUTTON_ACTION_FORWARD:
+ return 9;
+ case G_DESKTOP_STYLUS_BUTTON_ACTION_DEFAULT:
+ default:
+ return button;
+ }
+}
+
+static void
+meta_input_settings_x11_set_stylus_button_map (MetaInputSettings *settings,
+ ClutterInputDevice *device,
+ ClutterInputDeviceTool *tool,
+ GDesktopStylusButtonAction primary,
+ GDesktopStylusButtonAction secondary)
+{
+ MetaDisplay *display = meta_get_display ();
+ MetaBackend *backend = meta_get_backend ();
+ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
+ int device_id = clutter_input_device_get_device_id (device);
+ XDevice *xdev;
+
+ if (!display)
+ return;
+
+ /* Grab the puke bucket! */
+ meta_error_trap_push (display);
+ xdev = XOpenDevice (xdisplay, device_id);
+ if (xdev)
+ {
+ guchar map[3] = {
+ CLUTTER_BUTTON_PRIMARY,
+ action_to_button (primary, CLUTTER_BUTTON_MIDDLE),
+ action_to_button (secondary, CLUTTER_BUTTON_SECONDARY),
+ };
+
+ XSetDeviceButtonMapping (xdisplay, xdev, map, G_N_ELEMENTS (map));
+ XCloseDevice (xdisplay, xdev);
+ }
+
+ if (meta_error_trap_pop_with_return (display))
+ {
+ g_warning ("Could not set stylus button map for %s",
+ clutter_input_device_get_device_name (device));
+ }
+}
+
+static void
+meta_input_settings_x11_set_stylus_pressure (MetaInputSettings *settings,
+ ClutterInputDevice *device,
+ ClutterInputDeviceTool *tool,
+ const gint32 pressure[4])
+{
+ guchar values[4] = { pressure[0], pressure[1], pressure[2], pressure[3] };
+
+ change_property (device, "Wacom Pressurecurve", XA_INTEGER, 8,
+ &values, G_N_ELEMENTS (values));
+}
+
static void
meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
{
@@ -527,6 +724,9 @@ meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
input_settings_class->set_mouse_accel_profile = meta_input_settings_x11_set_mouse_accel_profile;
input_settings_class->set_trackball_accel_profile = meta_input_settings_x11_set_trackball_accel_profile;
+
+ input_settings_class->set_stylus_pressure = meta_input_settings_x11_set_stylus_pressure;
+ input_settings_class->set_stylus_button_map = meta_input_settings_x11_set_stylus_button_map;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]