mirror of
https://github.com/brl/mutter.git
synced 2024-11-24 00:50:42 -05:00
1dea1813b1
For each device that can be mapped (touchscreens, tablets), the output will be fetched from settings and matched with the currently connected ones. If a match is found, the device matrix will be found out from the output configuration and set on the device. This is also updated both individually for newly connected devices, and collectively on output configuration changes. https://bugzilla.gnome.org/show_bug.cgi?id=739397
839 lines
27 KiB
C
839 lines
27 KiB
C
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
|
/*
|
|
* Copyright 2014 Red Hat, Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Author: Carlos Garnacho <carlosg@gnome.org>
|
|
*/
|
|
|
|
/**
|
|
* SECTION:input-settings
|
|
* @title: MetaInputSettings
|
|
* @short_description: Mutter input device configuration
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "meta-backend-private.h"
|
|
#include "meta-input-settings-private.h"
|
|
#include "x11/meta-input-settings-x11.h"
|
|
|
|
#ifdef HAVE_NATIVE_BACKEND
|
|
#include "native/meta-backend-native.h"
|
|
#include "native/meta-input-settings-native.h"
|
|
#endif
|
|
|
|
#include <meta/util.h>
|
|
|
|
typedef struct _MetaInputSettingsPrivate MetaInputSettingsPrivate;
|
|
typedef struct _DeviceMappingInfo DeviceMappingInfo;
|
|
|
|
struct _DeviceMappingInfo
|
|
{
|
|
MetaInputSettings *input_settings;
|
|
ClutterInputDevice *device;
|
|
GSettings *settings;
|
|
};
|
|
|
|
struct _MetaInputSettingsPrivate
|
|
{
|
|
ClutterDeviceManager *device_manager;
|
|
MetaMonitorManager *monitor_manager;
|
|
guint monitors_changed_id;
|
|
|
|
GSettings *mouse_settings;
|
|
GSettings *touchpad_settings;
|
|
GSettings *trackball_settings;
|
|
GSettings *keyboard_settings;
|
|
|
|
GHashTable *mappable_devices;
|
|
};
|
|
|
|
typedef void (*ConfigBoolFunc) (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device,
|
|
gboolean setting);
|
|
typedef void (*ConfigDoubleFunc) (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device,
|
|
gdouble value);
|
|
typedef void (*ConfigUintFunc) (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device,
|
|
guint value);
|
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettings, meta_input_settings, G_TYPE_OBJECT)
|
|
|
|
static GSList *
|
|
meta_input_settings_get_devices (MetaInputSettings *settings,
|
|
ClutterInputDeviceType type)
|
|
{
|
|
MetaInputSettingsPrivate *priv;
|
|
const GSList *devices;
|
|
GSList *list = NULL;
|
|
|
|
priv = meta_input_settings_get_instance_private (settings);
|
|
devices = clutter_device_manager_peek_devices (priv->device_manager);
|
|
|
|
while (devices)
|
|
{
|
|
ClutterInputDevice *device = devices->data;
|
|
|
|
if (clutter_input_device_get_device_type (device) == type &&
|
|
clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER)
|
|
list = g_slist_prepend (list, device);
|
|
|
|
devices = devices->next;
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
static void
|
|
meta_input_settings_dispose (GObject *object)
|
|
{
|
|
MetaInputSettings *settings = META_INPUT_SETTINGS (object);
|
|
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (settings);
|
|
|
|
g_clear_object (&priv->mouse_settings);
|
|
g_clear_object (&priv->touchpad_settings);
|
|
g_clear_object (&priv->trackball_settings);
|
|
g_clear_object (&priv->keyboard_settings);
|
|
g_clear_pointer (&priv->mappable_devices, g_hash_table_unref);
|
|
|
|
if (priv->monitors_changed_id && priv->monitor_manager)
|
|
{
|
|
g_signal_handler_disconnect (priv->monitor_manager,
|
|
priv->monitors_changed_id);
|
|
priv->monitors_changed_id = 0;
|
|
}
|
|
|
|
g_clear_object (&priv->monitor_manager);
|
|
|
|
G_OBJECT_CLASS (meta_input_settings_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
settings_device_set_bool_setting (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device,
|
|
ConfigBoolFunc func,
|
|
gboolean enabled)
|
|
{
|
|
func (input_settings, device, enabled);
|
|
}
|
|
|
|
static void
|
|
settings_set_bool_setting (MetaInputSettings *input_settings,
|
|
ClutterInputDeviceType type,
|
|
ConfigBoolFunc func,
|
|
gboolean enabled)
|
|
{
|
|
GSList *devices, *d;
|
|
|
|
devices = meta_input_settings_get_devices (input_settings, type);
|
|
|
|
for (d = devices; d; d = d->next)
|
|
settings_device_set_bool_setting (input_settings, d->data, func, enabled);
|
|
|
|
g_slist_free (devices);
|
|
}
|
|
|
|
static void
|
|
settings_device_set_double_setting (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device,
|
|
ConfigDoubleFunc func,
|
|
gdouble value)
|
|
{
|
|
func (input_settings, device, value);
|
|
}
|
|
|
|
static void
|
|
settings_set_double_setting (MetaInputSettings *input_settings,
|
|
ClutterInputDeviceType type,
|
|
ConfigDoubleFunc func,
|
|
gdouble value)
|
|
{
|
|
GSList *devices, *d;
|
|
|
|
devices = meta_input_settings_get_devices (input_settings, type);
|
|
|
|
for (d = devices; d; d = d->next)
|
|
settings_device_set_double_setting (input_settings, d->data, func, value);
|
|
|
|
g_slist_free (devices);
|
|
}
|
|
|
|
static void
|
|
settings_device_set_uint_setting (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device,
|
|
ConfigUintFunc func,
|
|
guint value)
|
|
{
|
|
(func) (input_settings, device, value);
|
|
}
|
|
|
|
static void
|
|
settings_set_uint_setting (MetaInputSettings *input_settings,
|
|
ClutterInputDeviceType type,
|
|
ConfigUintFunc func,
|
|
guint value)
|
|
{
|
|
GSList *devices, *d;
|
|
|
|
devices = meta_input_settings_get_devices (input_settings, type);
|
|
|
|
for (d = devices; d; d = d->next)
|
|
settings_device_set_uint_setting (input_settings, d->data, func, value);
|
|
|
|
g_slist_free (devices);
|
|
}
|
|
|
|
static void
|
|
update_touchpad_left_handed (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device)
|
|
{
|
|
MetaInputSettingsClass *input_settings_class;
|
|
GDesktopTouchpadHandedness handedness;
|
|
MetaInputSettingsPrivate *priv;
|
|
gboolean enabled = FALSE;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
|
handedness = g_settings_get_enum (priv->touchpad_settings, "left-handed");
|
|
|
|
switch (handedness)
|
|
{
|
|
case G_DESKTOP_TOUCHPAD_HANDEDNESS_RIGHT:
|
|
enabled = FALSE;
|
|
break;
|
|
case G_DESKTOP_TOUCHPAD_HANDEDNESS_LEFT:
|
|
enabled = TRUE;
|
|
break;
|
|
case G_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE:
|
|
enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed");
|
|
break;
|
|
default:
|
|
g_assert_not_reached ();
|
|
}
|
|
|
|
if (device)
|
|
{
|
|
g_assert (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHPAD_DEVICE);
|
|
settings_device_set_bool_setting (input_settings, device,
|
|
input_settings_class->set_left_handed,
|
|
enabled);
|
|
}
|
|
else
|
|
{
|
|
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
|
input_settings_class->set_left_handed,
|
|
enabled);
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_mouse_left_handed (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device)
|
|
{
|
|
MetaInputSettingsClass *input_settings_class;
|
|
MetaInputSettingsPrivate *priv;
|
|
gboolean enabled;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
|
enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed");
|
|
|
|
if (device)
|
|
{
|
|
g_assert (clutter_input_device_get_device_type (device) == CLUTTER_POINTER_DEVICE);
|
|
settings_device_set_bool_setting (input_settings, device,
|
|
input_settings_class->set_left_handed,
|
|
enabled);
|
|
}
|
|
else
|
|
{
|
|
GDesktopTouchpadHandedness touchpad_handedness;
|
|
|
|
settings_set_bool_setting (input_settings, CLUTTER_POINTER_DEVICE,
|
|
input_settings_class->set_left_handed,
|
|
enabled);
|
|
|
|
touchpad_handedness = g_settings_get_enum (priv->touchpad_settings,
|
|
"left-handed");
|
|
|
|
/* Also update touchpads if they're following mouse settings */
|
|
if (touchpad_handedness == G_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE)
|
|
update_touchpad_left_handed (input_settings, NULL);
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_device_speed (MetaInputSettings *input_settings,
|
|
GSettings *settings,
|
|
ClutterInputDevice *device,
|
|
ClutterInputDeviceType type)
|
|
{
|
|
MetaInputSettingsClass *input_settings_class;
|
|
gdouble speed;
|
|
|
|
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
|
speed = g_settings_get_double (settings, "speed");
|
|
|
|
if (device)
|
|
settings_device_set_double_setting (input_settings, device,
|
|
input_settings_class->set_speed,
|
|
speed);
|
|
else
|
|
settings_set_double_setting (input_settings, type,
|
|
input_settings_class->set_speed,
|
|
speed);
|
|
}
|
|
|
|
static void
|
|
update_device_natural_scroll (MetaInputSettings *input_settings,
|
|
GSettings *settings,
|
|
ClutterInputDevice *device,
|
|
ClutterInputDeviceType type)
|
|
{
|
|
MetaInputSettingsClass *input_settings_class;
|
|
gboolean enabled;
|
|
|
|
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
|
enabled = g_settings_get_boolean (settings, "natural-scroll");
|
|
|
|
if (device)
|
|
{
|
|
settings_device_set_bool_setting (input_settings, device,
|
|
input_settings_class->set_invert_scroll,
|
|
enabled);
|
|
}
|
|
else
|
|
{
|
|
settings_set_bool_setting (input_settings, type,
|
|
input_settings_class->set_invert_scroll,
|
|
enabled);
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_touchpad_tap_enabled (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device)
|
|
{
|
|
MetaInputSettingsClass *input_settings_class;
|
|
MetaInputSettingsPrivate *priv;
|
|
gboolean enabled;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
|
enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
|
|
|
|
if (device)
|
|
{
|
|
settings_device_set_bool_setting (input_settings, device,
|
|
input_settings_class->set_tap_enabled,
|
|
enabled);
|
|
}
|
|
else
|
|
{
|
|
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
|
input_settings_class->set_tap_enabled,
|
|
enabled);
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_touchpad_scroll_method (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device)
|
|
{
|
|
MetaInputSettingsClass *input_settings_class;
|
|
GDesktopTouchpadScrollMethod method;
|
|
MetaInputSettingsPrivate *priv;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
|
method = g_settings_get_enum (priv->touchpad_settings, "scroll-method");
|
|
|
|
if (device)
|
|
{
|
|
settings_device_set_uint_setting (input_settings, device,
|
|
input_settings_class->set_scroll_method,
|
|
method);
|
|
}
|
|
else
|
|
{
|
|
settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
|
(ConfigUintFunc) input_settings_class->set_scroll_method,
|
|
method);
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_touchpad_send_events (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device)
|
|
{
|
|
MetaInputSettingsClass *input_settings_class;
|
|
MetaInputSettingsPrivate *priv;
|
|
GDesktopDeviceSendEvents mode;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
|
mode = g_settings_get_enum (priv->touchpad_settings, "send-events");
|
|
|
|
if (device)
|
|
{
|
|
settings_device_set_uint_setting (input_settings, device,
|
|
input_settings_class->set_send_events,
|
|
mode);
|
|
}
|
|
else
|
|
{
|
|
settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
|
input_settings_class->set_send_events,
|
|
mode);
|
|
}
|
|
}
|
|
|
|
static gboolean
|
|
device_is_trackball (ClutterInputDevice *device)
|
|
{
|
|
gboolean is_trackball;
|
|
char *name;
|
|
|
|
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
|
return FALSE;
|
|
|
|
name = g_ascii_strdown (clutter_input_device_get_device_name (device), -1);
|
|
is_trackball = strstr (name, "trackball") != NULL;
|
|
g_free (name);
|
|
|
|
return is_trackball;
|
|
}
|
|
|
|
static void
|
|
update_trackball_scroll_button (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device)
|
|
{
|
|
MetaInputSettingsClass *input_settings_class;
|
|
MetaInputSettingsPrivate *priv;
|
|
guint button;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
|
button = g_settings_get_uint (priv->trackball_settings, "scroll-wheel-emulation-button");
|
|
|
|
if (device && device_is_trackball (device))
|
|
{
|
|
input_settings_class->set_scroll_button (input_settings, device, button);
|
|
}
|
|
else if (!device)
|
|
{
|
|
MetaInputSettingsPrivate *priv;
|
|
const GSList *devices;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
devices = clutter_device_manager_peek_devices (priv->device_manager);
|
|
|
|
while (devices)
|
|
{
|
|
ClutterInputDevice *device = devices->data;
|
|
|
|
if (device_is_trackball (device))
|
|
input_settings_class->set_scroll_button (input_settings, device, button);
|
|
|
|
devices = devices->next;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_keyboard_repeat (MetaInputSettings *input_settings)
|
|
{
|
|
MetaInputSettingsClass *input_settings_class;
|
|
MetaInputSettingsPrivate *priv;
|
|
guint delay, interval;
|
|
gboolean repeat;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
repeat = g_settings_get_boolean (priv->keyboard_settings, "repeat");
|
|
delay = g_settings_get_uint (priv->keyboard_settings, "delay");
|
|
interval = g_settings_get_uint (priv->keyboard_settings, "repeat-interval");
|
|
|
|
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
|
input_settings_class->set_keyboard_repeat (input_settings,
|
|
repeat, delay, interval);
|
|
}
|
|
|
|
static MetaOutput *
|
|
meta_input_settings_find_output (MetaInputSettings *input_settings,
|
|
GSettings *settings,
|
|
ClutterInputDevice *device)
|
|
{
|
|
MetaInputSettingsPrivate *priv;
|
|
guint n_values, n_outputs, i;
|
|
MetaOutput *outputs;
|
|
gchar **edid;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
edid = g_settings_get_strv (settings, "display");
|
|
n_values = g_strv_length (edid);
|
|
|
|
if (n_values != 3)
|
|
{
|
|
g_warning ("EDID configuration for device '%s' "
|
|
"is incorrect, must have 3 values",
|
|
clutter_input_device_get_device_name (device));
|
|
return NULL;
|
|
}
|
|
|
|
if (!*edid[0] && !*edid[1] && !*edid[2])
|
|
return NULL;
|
|
|
|
outputs = meta_monitor_manager_get_outputs (priv->monitor_manager,
|
|
&n_outputs);
|
|
for (i = 0; i < n_outputs; i++)
|
|
{
|
|
if (g_strcmp0 (outputs[i].vendor, edid[0]) == 0 &&
|
|
g_strcmp0 (outputs[i].product, edid[1]) == 0 &&
|
|
g_strcmp0 (outputs[i].serial, edid[2]) == 0)
|
|
return &outputs[i];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
update_device_display (MetaInputSettings *input_settings,
|
|
GSettings *settings,
|
|
ClutterInputDevice *device)
|
|
{
|
|
MetaInputSettingsClass *input_settings_class;
|
|
MetaInputSettingsPrivate *priv;
|
|
gfloat matrix[6] = { 1, 0, 0, 0, 1, 0 };
|
|
MetaOutput *output;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
|
output = meta_input_settings_find_output (input_settings, settings, device);
|
|
|
|
if (output)
|
|
meta_monitor_manager_get_monitor_matrix (priv->monitor_manager,
|
|
output, matrix);
|
|
|
|
input_settings_class->set_matrix (input_settings, device, matrix);
|
|
}
|
|
|
|
static void
|
|
meta_input_settings_changed_cb (GSettings *settings,
|
|
const char *key,
|
|
gpointer user_data)
|
|
{
|
|
MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data);
|
|
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
|
|
|
|
if (settings == priv->mouse_settings)
|
|
{
|
|
if (strcmp (key, "left-handed") == 0)
|
|
update_mouse_left_handed (input_settings, NULL);
|
|
else if (strcmp (key, "speed") == 0)
|
|
update_device_speed (input_settings, settings, NULL,
|
|
CLUTTER_POINTER_DEVICE);
|
|
else if (strcmp (key, "natural-scroll") == 0)
|
|
update_device_natural_scroll (input_settings, settings,
|
|
NULL, CLUTTER_POINTER_DEVICE);
|
|
}
|
|
else if (settings == priv->touchpad_settings)
|
|
{
|
|
if (strcmp (key, "left-handed") == 0)
|
|
update_touchpad_left_handed (input_settings, NULL);
|
|
else if (strcmp (key, "speed") == 0)
|
|
update_device_speed (input_settings, settings, NULL,
|
|
CLUTTER_TOUCHPAD_DEVICE);
|
|
else if (strcmp (key, "natural-scroll") == 0)
|
|
update_device_natural_scroll (input_settings, settings,
|
|
NULL, CLUTTER_TOUCHPAD_DEVICE);
|
|
else if (strcmp (key, "tap-to-click") == 0)
|
|
update_touchpad_tap_enabled (input_settings, NULL);
|
|
else if (strcmp (key, "send-events") == 0)
|
|
update_touchpad_send_events (input_settings, NULL);
|
|
else if (strcmp (key, "scroll-method") == 0)
|
|
update_touchpad_scroll_method (input_settings, NULL);
|
|
}
|
|
else if (settings == priv->trackball_settings)
|
|
{
|
|
if (strcmp (key, "scroll-wheel-emulation-button") == 0)
|
|
update_trackball_scroll_button (input_settings, NULL);
|
|
}
|
|
else if (settings == priv->keyboard_settings)
|
|
{
|
|
if (strcmp (key, "repeat") == 0 ||
|
|
strcmp (key, "repeat-interval") == 0 ||
|
|
strcmp (key, "delay") == 0)
|
|
update_keyboard_repeat (input_settings);
|
|
}
|
|
}
|
|
|
|
static void
|
|
mapped_device_changed_cb (GSettings *settings,
|
|
const gchar *key,
|
|
DeviceMappingInfo *info)
|
|
{
|
|
if (strcmp (key, "display") == 0)
|
|
update_device_display (info->input_settings, settings, info->device);
|
|
}
|
|
|
|
static GSettings *
|
|
lookup_device_settings (ClutterInputDevice *device)
|
|
{
|
|
const gchar *group, *schema, *vendor, *product;
|
|
ClutterInputDeviceType type;
|
|
GSettings *settings;
|
|
gchar *path;
|
|
|
|
type = clutter_input_device_get_device_type (device);
|
|
|
|
if (type == CLUTTER_TOUCHSCREEN_DEVICE)
|
|
{
|
|
group = "touchscreens";
|
|
schema = "org.gnome.desktop.peripherals.touchscreen";
|
|
}
|
|
else if (type == CLUTTER_TABLET_DEVICE ||
|
|
type == CLUTTER_PEN_DEVICE ||
|
|
type == CLUTTER_ERASER_DEVICE ||
|
|
type == CLUTTER_CURSOR_DEVICE)
|
|
{
|
|
group = "tablets";
|
|
schema = "org.gnome.desktop.peripherals.tablet";
|
|
}
|
|
else
|
|
return NULL;
|
|
|
|
vendor = clutter_input_device_get_vendor_id (device);
|
|
product = clutter_input_device_get_product_id (device);
|
|
path = g_strdup_printf ("/org/gnome/desktop/peripherals/%s/%s:%s/",
|
|
group, vendor, product);
|
|
|
|
settings = g_settings_new_with_path (schema, path);
|
|
g_free (path);
|
|
|
|
return settings;
|
|
}
|
|
|
|
static void
|
|
monitors_changed_cb (MetaMonitorManager *monitor_manager,
|
|
MetaInputSettings *input_settings)
|
|
{
|
|
MetaInputSettingsPrivate *priv;
|
|
ClutterInputDevice *device;
|
|
GSettings *settings;
|
|
GHashTableIter iter;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
g_hash_table_iter_init (&iter, priv->mappable_devices);
|
|
|
|
while (g_hash_table_iter_next (&iter, (gpointer *) &device,
|
|
(gpointer *) &settings))
|
|
update_device_display (input_settings, settings, device);
|
|
}
|
|
|
|
static gboolean
|
|
check_add_mappable_device (MetaInputSettings *input_settings,
|
|
ClutterInputDevice *device)
|
|
{
|
|
MetaInputSettingsPrivate *priv;
|
|
DeviceMappingInfo *info;
|
|
GSettings *settings;
|
|
|
|
settings = lookup_device_settings (device);
|
|
|
|
if (!settings)
|
|
return FALSE;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
|
|
info = g_new0 (DeviceMappingInfo, 1);
|
|
info->input_settings = input_settings;
|
|
info->device = device;
|
|
info->settings = settings;
|
|
|
|
g_signal_connect_data (settings, "changed",
|
|
G_CALLBACK (mapped_device_changed_cb),
|
|
info, (GClosureNotify) g_free, 0);
|
|
|
|
g_hash_table_insert (priv->mappable_devices, device, settings);
|
|
|
|
update_device_display (input_settings, settings, device);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
meta_input_settings_device_added (ClutterDeviceManager *device_manager,
|
|
ClutterInputDevice *device,
|
|
MetaInputSettings *input_settings)
|
|
{
|
|
ClutterInputDeviceType type;
|
|
MetaInputSettingsPrivate *priv;
|
|
|
|
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
|
return;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
type = clutter_input_device_get_device_type (device);
|
|
|
|
if (type == CLUTTER_POINTER_DEVICE)
|
|
{
|
|
update_mouse_left_handed (input_settings, device);
|
|
update_device_speed (input_settings, priv->mouse_settings, device, type);
|
|
|
|
if (device_is_trackball (device))
|
|
update_trackball_scroll_button (input_settings, device);
|
|
}
|
|
else if (type == CLUTTER_TOUCHPAD_DEVICE)
|
|
{
|
|
update_touchpad_left_handed (input_settings, device);
|
|
update_touchpad_tap_enabled (input_settings, device);
|
|
update_touchpad_scroll_method (input_settings, device);
|
|
update_touchpad_send_events (input_settings, device);
|
|
|
|
update_device_speed (input_settings, priv->touchpad_settings,
|
|
device, type);
|
|
update_device_natural_scroll (input_settings, priv->touchpad_settings,
|
|
device, type);
|
|
}
|
|
else
|
|
{
|
|
check_add_mappable_device (input_settings, device);
|
|
}
|
|
}
|
|
|
|
static void
|
|
meta_input_settings_device_removed (ClutterDeviceManager *device_manager,
|
|
ClutterInputDevice *device,
|
|
MetaInputSettings *input_settings)
|
|
{
|
|
MetaInputSettingsPrivate *priv;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
g_hash_table_remove (priv->mappable_devices, device);
|
|
}
|
|
|
|
static void
|
|
check_mappable_devices (MetaInputSettings *input_settings)
|
|
{
|
|
MetaInputSettingsPrivate *priv;
|
|
const GSList *devices, *l;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
devices = clutter_device_manager_peek_devices (priv->device_manager);
|
|
|
|
for (l = devices; l; l = l->next)
|
|
{
|
|
ClutterInputDevice *device = l->data;
|
|
|
|
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
|
continue;
|
|
|
|
check_add_mappable_device (input_settings, device);
|
|
}
|
|
}
|
|
|
|
static void
|
|
meta_input_settings_constructed (GObject *object)
|
|
{
|
|
MetaInputSettings *input_settings = META_INPUT_SETTINGS (object);
|
|
MetaInputSettingsPrivate *priv;
|
|
|
|
priv = meta_input_settings_get_instance_private (input_settings);
|
|
|
|
update_mouse_left_handed (input_settings, NULL);
|
|
|
|
update_touchpad_left_handed (input_settings, NULL);
|
|
update_touchpad_tap_enabled (input_settings, NULL);
|
|
update_touchpad_send_events (input_settings, NULL);
|
|
|
|
update_device_natural_scroll (input_settings, priv->touchpad_settings,
|
|
NULL, CLUTTER_TOUCHPAD_DEVICE);
|
|
update_device_speed (input_settings, priv->touchpad_settings, NULL,
|
|
CLUTTER_TOUCHPAD_DEVICE);
|
|
update_device_speed (input_settings, priv->mouse_settings, NULL,
|
|
CLUTTER_POINTER_DEVICE);
|
|
|
|
update_keyboard_repeat (input_settings);
|
|
|
|
check_mappable_devices (input_settings);
|
|
}
|
|
|
|
static void
|
|
meta_input_settings_class_init (MetaInputSettingsClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
object_class->dispose = meta_input_settings_dispose;
|
|
object_class->constructed = meta_input_settings_constructed;
|
|
}
|
|
|
|
static void
|
|
meta_input_settings_init (MetaInputSettings *settings)
|
|
{
|
|
MetaInputSettingsPrivate *priv;
|
|
|
|
priv = meta_input_settings_get_instance_private (settings);
|
|
priv->device_manager = clutter_device_manager_get_default ();
|
|
g_signal_connect (priv->device_manager, "device-added",
|
|
G_CALLBACK (meta_input_settings_device_added), settings);
|
|
g_signal_connect (priv->device_manager, "device-removed",
|
|
G_CALLBACK (meta_input_settings_device_removed), settings);
|
|
|
|
priv->mouse_settings = g_settings_new ("org.gnome.desktop.peripherals.mouse");
|
|
g_signal_connect (priv->mouse_settings, "changed",
|
|
G_CALLBACK (meta_input_settings_changed_cb), settings);
|
|
|
|
priv->touchpad_settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
|
|
g_signal_connect (priv->touchpad_settings, "changed",
|
|
G_CALLBACK (meta_input_settings_changed_cb), settings);
|
|
|
|
priv->trackball_settings = g_settings_new ("org.gnome.desktop.peripherals.trackball");
|
|
g_signal_connect (priv->trackball_settings, "changed",
|
|
G_CALLBACK (meta_input_settings_changed_cb), settings);
|
|
|
|
priv->keyboard_settings = g_settings_new ("org.gnome.desktop.peripherals.keyboard");
|
|
g_signal_connect (priv->keyboard_settings, "changed",
|
|
G_CALLBACK (meta_input_settings_changed_cb), settings);
|
|
|
|
priv->mappable_devices =
|
|
g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref);
|
|
|
|
priv->monitor_manager = g_object_ref (meta_monitor_manager_get ());
|
|
g_signal_connect (priv->monitor_manager, "monitors-changed",
|
|
G_CALLBACK (monitors_changed_cb), settings);
|
|
}
|
|
|
|
MetaInputSettings *
|
|
meta_input_settings_create (void)
|
|
{
|
|
#ifdef HAVE_NATIVE_BACKEND
|
|
MetaBackend *backend;
|
|
|
|
backend = meta_get_backend ();
|
|
|
|
if (META_IS_BACKEND_NATIVE (backend))
|
|
return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL);
|
|
#endif
|
|
if (!meta_is_wayland_compositor ())
|
|
return g_object_new (META_TYPE_INPUT_SETTINGS_X11, NULL);
|
|
|
|
return NULL;
|
|
}
|