From f9552bb9c0e32d252f3341ff513bccc7bbc6f118 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 22 Jun 2016 15:58:33 +0200 Subject: [PATCH] backends: Add function to apply pressure sensitivity to tablet tools A bezier curve is created out of the 2 control points in settings, so the pressure is made to follow the stablished curve between 0 and 1. --- src/backends/meta-input-settings-private.h | 5 ++ src/backends/meta-input-settings.c | 84 ++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h index 45ce92f53..a9d448e43 100644 --- a/src/backends/meta-input-settings-private.h +++ b/src/backends/meta-input-settings-private.h @@ -110,6 +110,11 @@ GDesktopStylusButtonAction meta_input_settings_get_stylus_button_action (MetaInp ClutterInputDeviceTool *tool, ClutterInputDevice *current_device, guint button); +gdouble meta_input_settings_translate_tablet_tool_pressure (MetaInputSettings *input_settings, + ClutterInputDeviceTool *tool, + ClutterInputDevice *current_tablet, + gdouble pressure); + #ifdef HAVE_LIBWACOM WacomDevice * meta_input_settings_get_tablet_wacom_device (MetaInputSettings *settings, ClutterInputDevice *device); diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 4ae12dbc0..30a391d2d 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -62,6 +62,7 @@ struct _ToolSettings ClutterInputDeviceTool *tool; GDesktopStylusButtonAction button_action; GDesktopStylusButtonAction secondary_button_action; + gdouble curve[4]; }; struct _MetaInputSettingsPrivate @@ -921,6 +922,36 @@ lookup_device_settings (ClutterInputDevice *device) return settings; } +static void +tool_settings_cache_pressure_curve (ToolSettings *tool_settings) +{ + GVariant *variant; + const gint32 *curve; + gsize n_elems; + + if (clutter_input_device_tool_get_tool_type (tool_settings->tool) == + CLUTTER_INPUT_DEVICE_TOOL_ERASER) + variant = g_settings_get_value (tool_settings->settings, "eraser-pressure-curve"); + else + variant = g_settings_get_value (tool_settings->settings, "pressure-curve"); + + curve = g_variant_get_fixed_array (variant, &n_elems, sizeof (gint32)); + if (n_elems == 4) + { + tool_settings->curve[0] = (gdouble) curve[0] / 100; + tool_settings->curve[1] = (gdouble) curve[1] / 100; + tool_settings->curve[2] = (gdouble) curve[2] / 100; + tool_settings->curve[3] = (gdouble) curve[3] / 100; + } + else + { + tool_settings->curve[0] = tool_settings->curve[1] = 0; + tool_settings->curve[2] = tool_settings->curve[3] = 1; + } + + g_variant_unref (variant); +} + static void tool_settings_changed_cb (GSettings *settings, const gchar *key, @@ -930,6 +961,14 @@ tool_settings_changed_cb (GSettings *settings, tool_settings->button_action = g_settings_get_enum (settings, "button-action"); else if (strcmp (key, "secondary-button-action") == 0) tool_settings->secondary_button_action = g_settings_get_enum (settings, "secondary-button-action"); + else if (strcmp (key, "pressure-curve") == 0 && + clutter_input_device_tool_get_tool_type (tool_settings->tool) != + CLUTTER_INPUT_DEVICE_TOOL_ERASER) + tool_settings_cache_pressure_curve (tool_settings); + else if (strcmp (key, "eraser-pressure-curve") == 0 && + clutter_input_device_tool_get_tool_type (tool_settings->tool) == + CLUTTER_INPUT_DEVICE_TOOL_ERASER) + tool_settings_cache_pressure_curve (tool_settings); } static ToolSettings * @@ -952,6 +991,7 @@ tool_settings_new (ClutterInputDeviceTool *tool, g_settings_get_enum (tool_settings->settings, "button-action"); tool_settings->secondary_button_action = g_settings_get_enum (tool_settings->settings, "secondary-button-action"); + tool_settings_cache_pressure_curve (tool_settings); return tool_settings; } @@ -1278,3 +1318,47 @@ meta_input_settings_get_tablet_wacom_device (MetaInputSettings *settings, return info->wacom_device; } #endif /* HAVE_LIBWACOM */ + +static gdouble +calculate_bezier_position (gdouble pos, + gdouble x1, + gdouble y1, + gdouble x2, + gdouble y2) +{ + gdouble int1_y, int2_y; + + pos = CLAMP (pos, 0, 1); + + /* Intersection between 0,0 and x1,y1 */ + int1_y = pos * y1; + + /* Intersection between x2,y2 and 1,1 */ + int2_y = (pos * (1 - y2)) + y2; + + /* Find the new position in the line traced by the previous points */ + return (pos * (int2_y - int1_y)) + int1_y; +} + +gdouble +meta_input_settings_translate_tablet_tool_pressure (MetaInputSettings *input_settings, + ClutterInputDeviceTool *tool, + ClutterInputDevice *current_tablet, + gdouble pressure) +{ + ToolSettings *tool_settings; + + pressure = CLAMP (pressure, 0, 1); + + g_return_val_if_fail (META_IS_INPUT_SETTINGS (input_settings), pressure); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL (tool), pressure); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (current_tablet), pressure); + + tool_settings = lookup_tool_settings (tool, current_tablet); + pressure = calculate_bezier_position (pressure, + tool_settings->curve[0], + tool_settings->curve[1], + tool_settings->curve[2], + tool_settings->curve[3]); + return pressure; +}