backends: Move all output management to MetaInputMapper

Delegate on the MetaInputMapper all matching of inputs and outputs,
including configuration. Other secondary aspects, like output
aspect ratio for tablet letterbox mode, or toggling attached devices
with power saving changes, are also moved here.

This makes MetaInputSettings independent of MetaMonitorManager,
all interaction with it happens indirectly via public API entrypoints.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403
This commit is contained in:
Carlos Garnacho 2020-08-04 13:33:37 +02:00
parent 91f6b3b5bc
commit c678cdab5a
4 changed files with 412 additions and 348 deletions

View File

@ -33,8 +33,7 @@ G_DECLARE_FINAL_TYPE (MetaInputMapper, meta_input_mapper,
MetaInputMapper * meta_input_mapper_new (void); MetaInputMapper * meta_input_mapper_new (void);
void meta_input_mapper_add_device (MetaInputMapper *mapper, void meta_input_mapper_add_device (MetaInputMapper *mapper,
ClutterInputDevice *device, ClutterInputDevice *device);
gboolean builtin);
void meta_input_mapper_remove_device (MetaInputMapper *mapper, void meta_input_mapper_remove_device (MetaInputMapper *mapper,
ClutterInputDevice *device); ClutterInputDevice *device);
@ -46,4 +45,7 @@ MetaLogicalMonitor *
meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper, meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
ClutterInputDevice *device); ClutterInputDevice *device);
GSettings * meta_input_mapper_get_tablet_settings (MetaInputMapper *mapper,
ClutterInputDevice *device);
#endif /* META_INPUT_MAPPER_H */ #endif /* META_INPUT_MAPPER_H */

View File

@ -24,6 +24,7 @@
#include <gudev/gudev.h> #include <gudev/gudev.h>
#endif #endif
#include "backends/meta-input-device-private.h"
#include "meta-input-mapper-private.h" #include "meta-input-mapper-private.h"
#include "meta-monitor-manager-private.h" #include "meta-monitor-manager-private.h"
#include "meta-logical-monitor.h" #include "meta-logical-monitor.h"
@ -59,6 +60,7 @@ typedef enum
typedef enum typedef enum
{ {
META_MATCH_CONFIG, /* Specified by config */
META_MATCH_IS_BUILTIN, /* Output is builtin, applies mainly to system-integrated devices */ META_MATCH_IS_BUILTIN, /* Output is builtin, applies mainly to system-integrated devices */
META_MATCH_SIZE, /* Size from input device and output match */ META_MATCH_SIZE, /* Size from input device and output match */
META_MATCH_EDID_FULL, /* Full EDID model match, eg. "Cintiq 12WX" */ META_MATCH_EDID_FULL, /* Full EDID model match, eg. "Cintiq 12WX" */
@ -72,6 +74,7 @@ struct _MetaMapperInputInfo
ClutterInputDevice *device; ClutterInputDevice *device;
MetaInputMapper *mapper; MetaInputMapper *mapper;
MetaMapperOutputInfo *output; MetaMapperOutputInfo *output;
GSettings *settings;
guint builtin : 1; guint builtin : 1;
}; };
@ -99,24 +102,149 @@ struct _DeviceCandidates
enum enum
{ {
DEVICE_MAPPED, DEVICE_MAPPED,
DEVICE_ENABLED,
DEVICE_ASPECT_RATIO,
N_SIGNALS N_SIGNALS
}; };
static guint signals[N_SIGNALS] = { 0, }; static guint signals[N_SIGNALS] = { 0, };
static void mapper_recalculate_input (MetaInputMapper *mapper,
MetaMapperInputInfo *input);
G_DEFINE_TYPE (MetaInputMapper, meta_input_mapper, G_TYPE_OBJECT) G_DEFINE_TYPE (MetaInputMapper, meta_input_mapper, G_TYPE_OBJECT)
static GSettings *
get_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 ||
type == CLUTTER_PAD_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 MetaMonitor *
logical_monitor_find_monitor (MetaLogicalMonitor *logical_monitor,
const char *vendor,
const char *product,
const char *serial)
{
GList *monitors;
GList *l;
monitors = meta_logical_monitor_get_monitors (logical_monitor);
for (l = monitors; l; l = l->next)
{
MetaMonitor *monitor = l->data;
if (g_strcmp0 (meta_monitor_get_vendor (monitor), vendor) == 0 &&
g_strcmp0 (meta_monitor_get_product (monitor), product) == 0 &&
g_strcmp0 (meta_monitor_get_serial (monitor), serial) == 0)
return monitor;
}
return NULL;
}
static void
find_settings_monitor (MetaInputMapper *mapper,
GSettings *settings,
ClutterInputDevice *device,
MetaMonitor **out_monitor,
MetaLogicalMonitor **out_logical_monitor)
{
MetaMonitor *monitor;
guint n_values;
GList *logical_monitors;
GList *l;
gchar **edid;
edid = g_settings_get_strv (settings, "output");
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));
goto out;
}
if (!*edid[0] && !*edid[1] && !*edid[2])
goto out;
logical_monitors =
meta_monitor_manager_get_logical_monitors (mapper->monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
monitor = logical_monitor_find_monitor (logical_monitor,
edid[0], edid[1], edid[2]);
if (monitor)
{
if (out_monitor)
*out_monitor = monitor;
if (out_logical_monitor)
*out_logical_monitor = logical_monitor;
break;
}
}
out:
g_strfreev (edid);
}
static void
settings_output_changed_cb (GSettings *settings,
const gchar *key,
MetaMapperInputInfo *info)
{
mapper_recalculate_input (info->mapper, info);
}
static MetaMapperInputInfo * static MetaMapperInputInfo *
mapper_input_info_new (ClutterInputDevice *device, mapper_input_info_new (ClutterInputDevice *device,
MetaInputMapper *mapper, MetaInputMapper *mapper)
gboolean builtin)
{ {
MetaMapperInputInfo *info; MetaMapperInputInfo *info;
info = g_new0 (MetaMapperInputInfo, 1); info = g_new0 (MetaMapperInputInfo, 1);
info->mapper = mapper; info->mapper = mapper;
info->device = device; info->device = device;
info->builtin = builtin; info->settings = get_device_settings (device);
g_signal_connect (info->settings, "changed::output",
G_CALLBACK (settings_output_changed_cb), info);
return info; return info;
} }
@ -124,6 +252,7 @@ mapper_input_info_new (ClutterInputDevice *device,
static void static void
mapper_input_info_free (MetaMapperInputInfo *info) mapper_input_info_free (MetaMapperInputInfo *info)
{ {
g_object_unref (info->settings);
g_free (info); g_free (info);
} }
@ -174,13 +303,36 @@ mapper_input_info_set_output (MetaMapperInputInfo *input,
MetaMapperOutputInfo *output, MetaMapperOutputInfo *output,
MetaMonitor *monitor) MetaMonitor *monitor)
{ {
MetaInputMapper *mapper = input->mapper;
float matrix[6] = { 1, 0, 0, 0, 1, 0 };
double aspect_ratio;
int width, height;
if (input->output == output) if (input->output == output)
return; return;
input->output = output; input->output = output;
if (output && monitor)
{
meta_monitor_manager_get_monitor_matrix (mapper->monitor_manager,
monitor,
output->logical_monitor,
matrix);
meta_monitor_get_current_resolution (monitor, &width, &height);
}
else
{
meta_monitor_manager_get_screen_size (mapper->monitor_manager,
&width, &height);
}
aspect_ratio = (double) width / height;
g_signal_emit (input->mapper, signals[DEVICE_MAPPED], 0, g_signal_emit (input->mapper, signals[DEVICE_MAPPED], 0,
input->device, input->device, matrix);
output ? output->logical_monitor : NULL, monitor); g_signal_emit (input->mapper, signals[DEVICE_ASPECT_RATIO], 0,
input->device, aspect_ratio);
} }
static void static void
@ -361,6 +513,32 @@ guess_candidates (MetaInputMapper *mapper,
MetaOutputMatchType best = N_OUTPUT_MATCHES; MetaOutputMatchType best = N_OUTPUT_MATCHES;
GList *monitors, *l; GList *monitors, *l;
MetaMonitor *matched_monitor = NULL; MetaMonitor *matched_monitor = NULL;
gboolean builtin = FALSE;
gboolean integrated = TRUE;
#ifdef HAVE_LIBWACOM
if (clutter_input_device_get_device_type (input->device) != CLUTTER_TOUCHSCREEN_DEVICE)
{
WacomDevice *wacom_device;
WacomIntegrationFlags flags = 0;
wacom_device =
meta_input_device_get_wacom_device (META_INPUT_DEVICE (input->device));
if (wacom_device)
{
flags = libwacom_get_integration_flags (wacom_device);
if ((flags & (WACOM_DEVICE_INTEGRATED_SYSTEM |
WACOM_DEVICE_INTEGRATED_DISPLAY)) == 0)
return;
integrated = (flags & (WACOM_DEVICE_INTEGRATED_SYSTEM |
WACOM_DEVICE_INTEGRATED_DISPLAY)) != 0;
builtin = (flags & WACOM_DEVICE_INTEGRATED_SYSTEM) != 0;
}
}
#endif
monitors = meta_monitor_manager_get_monitors (mapper->monitor_manager); monitors = meta_monitor_manager_get_monitors (mapper->monitor_manager);
@ -375,18 +553,23 @@ guess_candidates (MetaInputMapper *mapper,
} }
} }
if (find_size_match (input, monitors, &matched_monitor)) if (integrated && find_size_match (input, monitors, &matched_monitor))
{ {
best = MIN (best, META_MATCH_SIZE); best = MIN (best, META_MATCH_SIZE);
info->candidates[META_MATCH_SIZE] = matched_monitor; info->candidates[META_MATCH_SIZE] = matched_monitor;
} }
if (input->builtin || best == N_OUTPUT_MATCHES) if (builtin || best == N_OUTPUT_MATCHES)
{ {
best = MIN (best, META_MATCH_IS_BUILTIN); best = MIN (best, META_MATCH_IS_BUILTIN);
find_builtin_output (mapper, &info->candidates[META_MATCH_IS_BUILTIN]); find_builtin_output (mapper, &info->candidates[META_MATCH_IS_BUILTIN]);
} }
find_settings_monitor (mapper, input->settings, input->device,
&info->candidates[META_MATCH_CONFIG], NULL);
if (info->candidates[META_MATCH_CONFIG])
best = MIN (best, META_MATCH_CONFIG);
info->best = best; info->best = best;
} }
@ -524,6 +707,37 @@ input_mapper_monitors_changed_cb (MetaMonitorManager *monitor_manager,
mapper_update_outputs (mapper); mapper_update_outputs (mapper);
} }
static void
input_mapper_power_save_mode_changed_cb (MetaMonitorManager *monitor_manager,
MetaInputMapper *mapper)
{
ClutterInputDevice *device;
MetaLogicalMonitor *logical_monitor;
MetaMonitor *builtin;
MetaPowerSave power_save_mode;
gboolean on;
power_save_mode =
meta_monitor_manager_get_power_save_mode (mapper->monitor_manager);
on = power_save_mode == META_POWER_SAVE_ON;
if (!find_builtin_output (mapper, &builtin))
return;
logical_monitor = meta_monitor_get_logical_monitor (builtin);
if (!logical_monitor)
return;
device =
meta_input_mapper_get_logical_monitor_device (mapper,
logical_monitor,
CLUTTER_TOUCHSCREEN_DEVICE);
if (!device)
return;
g_signal_emit (mapper, signals[DEVICE_ENABLED], 0, device, on);
}
static void static void
input_mapper_device_removed_cb (ClutterSeat *seat, input_mapper_device_removed_cb (ClutterSeat *seat,
ClutterInputDevice *device, ClutterInputDevice *device,
@ -576,6 +790,9 @@ meta_input_mapper_constructed (GObject *object)
mapper->monitor_manager = meta_backend_get_monitor_manager (backend); mapper->monitor_manager = meta_backend_get_monitor_manager (backend);
g_signal_connect (mapper->monitor_manager, "monitors-changed-internal", g_signal_connect (mapper->monitor_manager, "monitors-changed-internal",
G_CALLBACK (input_mapper_monitors_changed_cb), mapper); G_CALLBACK (input_mapper_monitors_changed_cb), mapper);
g_signal_connect (mapper->monitor_manager, "power-save-mode-changed",
G_CALLBACK (input_mapper_power_save_mode_changed_cb),
mapper);
mapper_update_outputs (mapper); mapper_update_outputs (mapper);
} }
@ -594,9 +811,27 @@ meta_input_mapper_class_init (MetaInputMapperClass *klass)
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
0, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
G_TYPE_NONE, 3, G_TYPE_NONE, 2,
CLUTTER_TYPE_INPUT_DEVICE, CLUTTER_TYPE_INPUT_DEVICE,
G_TYPE_POINTER, G_TYPE_POINTER); G_TYPE_POINTER);
signals[DEVICE_ENABLED] =
g_signal_new ("device-enabled",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 2,
CLUTTER_TYPE_INPUT_DEVICE,
G_TYPE_BOOLEAN);
signals[DEVICE_ASPECT_RATIO] =
g_signal_new ("device-aspect-ratio",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 2,
CLUTTER_TYPE_INPUT_DEVICE,
G_TYPE_DOUBLE);
} }
static void static void
@ -618,8 +853,7 @@ meta_input_mapper_new (void)
void void
meta_input_mapper_add_device (MetaInputMapper *mapper, meta_input_mapper_add_device (MetaInputMapper *mapper,
ClutterInputDevice *device, ClutterInputDevice *device)
gboolean builtin)
{ {
MetaMapperInputInfo *info; MetaMapperInputInfo *info;
@ -629,7 +863,7 @@ meta_input_mapper_add_device (MetaInputMapper *mapper,
if (g_hash_table_contains (mapper->input_devices, device)) if (g_hash_table_contains (mapper->input_devices, device))
return; return;
info = mapper_input_info_new (device, mapper, builtin); info = mapper_input_info_new (device, mapper);
g_hash_table_insert (mapper->input_devices, device, info); g_hash_table_insert (mapper->input_devices, device, info);
mapper_recalculate_input (mapper, info); mapper_recalculate_input (mapper, info);
} }
@ -676,6 +910,43 @@ meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper,
return NULL; return NULL;
} }
static ClutterInputDevice *
find_grouped_pen (ClutterInputDevice *device)
{
GList *l, *devices;
ClutterInputDeviceType device_type;
ClutterInputDevice *pen = NULL;
ClutterSeat *seat;
device_type = clutter_input_device_get_device_type (device);
if (device_type == CLUTTER_TABLET_DEVICE ||
device_type == CLUTTER_PEN_DEVICE)
return device;
seat = clutter_input_device_get_seat (device);
devices = clutter_seat_list_devices (seat);
for (l = devices; l; l = l->next)
{
ClutterInputDevice *other_device = l->data;
device_type = clutter_input_device_get_device_type (other_device);
if ((device_type == CLUTTER_TABLET_DEVICE ||
device_type == CLUTTER_PEN_DEVICE) &&
clutter_input_device_is_grouped (device, other_device))
{
pen = other_device;
break;
}
}
g_list_free (devices);
return pen;
}
MetaLogicalMonitor * MetaLogicalMonitor *
meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper, meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
ClutterInputDevice *device) ClutterInputDevice *device)
@ -685,6 +956,13 @@ meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
GHashTableIter iter; GHashTableIter iter;
GList *l; GList *l;
if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE)
{
device = find_grouped_pen (device);
if (!device)
return NULL;
}
g_hash_table_iter_init (&iter, mapper->output_devices); g_hash_table_iter_init (&iter, mapper->output_devices);
while (g_hash_table_iter_next (&iter, (gpointer *) &logical_monitor, while (g_hash_table_iter_next (&iter, (gpointer *) &logical_monitor,
@ -701,3 +979,19 @@ meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
return NULL; return NULL;
} }
GSettings *
meta_input_mapper_get_tablet_settings (MetaInputMapper *mapper,
ClutterInputDevice *device)
{
MetaMapperInputInfo *input;
g_return_val_if_fail (META_IS_INPUT_MAPPER (mapper), NULL);
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
input = g_hash_table_lookup (mapper->input_devices, device);
if (!input)
return NULL;
return input->settings;
}

View File

@ -144,4 +144,14 @@ MetaLogicalMonitor * meta_input_settings_get_tablet_logical_monitor (MetaInputS
void meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings); void meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings);
void meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings); void meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings);
void meta_input_settings_set_device_matrix (MetaInputSettings *input_settings,
ClutterInputDevice *device,
float matrix[6]);
void meta_input_settings_set_device_enabled (MetaInputSettings *input_settings,
ClutterInputDevice *device,
gboolean enabled);
void meta_input_settings_set_device_aspect_ratio (MetaInputSettings *input_settings,
ClutterInputDevice *device,
double aspect_ratio);
#endif /* META_INPUT_SETTINGS_PRIVATE_H */ #endif /* META_INPUT_SETTINGS_PRIVATE_H */

View File

@ -61,12 +61,12 @@ struct _DeviceMappingInfo
GSettings *settings; GSettings *settings;
gulong changed_id; gulong changed_id;
guint *group_modes; guint *group_modes;
double aspect_ratio;
}; };
struct _MetaInputSettingsPrivate struct _MetaInputSettingsPrivate
{ {
ClutterSeat *seat; ClutterSeat *seat;
MetaMonitorManager *monitor_manager;
gulong monitors_changed_id; gulong monitors_changed_id;
GSettings *mouse_settings; GSettings *mouse_settings;
@ -145,11 +145,6 @@ meta_input_settings_dispose (GObject *object)
g_clear_pointer (&priv->mappable_devices, g_hash_table_unref); g_clear_pointer (&priv->mappable_devices, g_hash_table_unref);
g_clear_pointer (&priv->current_tools, g_hash_table_unref); g_clear_pointer (&priv->current_tools, g_hash_table_unref);
if (priv->monitor_manager)
g_clear_signal_handler (&priv->monitors_changed_id, priv->monitor_manager);
g_clear_object (&priv->monitor_manager);
g_clear_pointer (&priv->two_finger_devices, g_hash_table_destroy); g_clear_pointer (&priv->two_finger_devices, g_hash_table_destroy);
G_OBJECT_CLASS (meta_input_settings_parent_class)->dispose (object); G_OBJECT_CLASS (meta_input_settings_parent_class)->dispose (object);
@ -889,124 +884,14 @@ update_keyboard_repeat (MetaInputSettings *input_settings)
repeat, delay, interval); repeat, delay, interval);
} }
static MetaMonitor *
logical_monitor_find_monitor (MetaLogicalMonitor *logical_monitor,
const char *vendor,
const char *product,
const char *serial)
{
GList *monitors;
GList *l;
monitors = meta_logical_monitor_get_monitors (logical_monitor);
for (l = monitors; l; l = l->next)
{
MetaMonitor *monitor = l->data;
if (g_strcmp0 (meta_monitor_get_vendor (monitor), vendor) == 0 &&
g_strcmp0 (meta_monitor_get_product (monitor), product) == 0 &&
g_strcmp0 (meta_monitor_get_serial (monitor), serial) == 0)
return monitor;
}
return NULL;
}
static void
meta_input_settings_find_monitor (MetaInputSettings *input_settings,
GSettings *settings,
ClutterInputDevice *device,
MetaMonitor **out_monitor,
MetaLogicalMonitor **out_logical_monitor)
{
MetaInputSettingsPrivate *priv;
MetaMonitorManager *monitor_manager;
MetaMonitor *monitor;
guint n_values;
GList *logical_monitors;
GList *l;
gchar **edid;
priv = meta_input_settings_get_instance_private (input_settings);
edid = g_settings_get_strv (settings, "output");
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));
goto out;
}
if (!*edid[0] && !*edid[1] && !*edid[2])
goto out;
monitor_manager = priv->monitor_manager;
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
monitor = logical_monitor_find_monitor (logical_monitor,
edid[0], edid[1], edid[2]);
if (monitor)
{
if (out_monitor)
*out_monitor = monitor;
if (out_logical_monitor)
*out_logical_monitor = logical_monitor;
break;
}
}
out:
g_strfreev (edid);
}
static gboolean
meta_input_settings_delegate_on_mapper (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsPrivate *priv;
gboolean builtin = FALSE;
priv = meta_input_settings_get_instance_private (input_settings);
#ifdef HAVE_LIBWACOM
if (clutter_input_device_get_device_type (device) != CLUTTER_TOUCHSCREEN_DEVICE)
{
WacomDevice *wacom_device;
WacomIntegrationFlags flags = 0;
wacom_device =
meta_input_device_get_wacom_device (META_INPUT_DEVICE (device));
if (wacom_device)
{
flags = libwacom_get_integration_flags (wacom_device);
if ((flags & (WACOM_DEVICE_INTEGRATED_SYSTEM |
WACOM_DEVICE_INTEGRATED_DISPLAY)) == 0)
return FALSE;
builtin = (flags & WACOM_DEVICE_INTEGRATED_SYSTEM) != 0;
}
}
#endif
meta_input_mapper_add_device (priv->input_mapper, device, builtin);
return TRUE;
}
static void static void
update_tablet_keep_aspect (MetaInputSettings *input_settings, update_tablet_keep_aspect (MetaInputSettings *input_settings,
GSettings *settings, GSettings *settings,
ClutterInputDevice *device) ClutterInputDevice *device)
{ {
MetaInputSettingsPrivate *priv;
MetaInputSettingsClass *input_settings_class; MetaInputSettingsClass *input_settings_class;
MetaLogicalMonitor *logical_monitor = NULL; DeviceMappingInfo *info;
gboolean keep_aspect; gboolean keep_aspect;
double aspect_ratio; double aspect_ratio;
@ -1015,6 +900,12 @@ update_tablet_keep_aspect (MetaInputSettings *input_settings,
clutter_input_device_get_device_type (device) != CLUTTER_ERASER_DEVICE) clutter_input_device_get_device_type (device) != CLUTTER_ERASER_DEVICE)
return; return;
priv = meta_input_settings_get_instance_private (input_settings);
info = g_hash_table_lookup (priv->mappable_devices, device);
if (!info)
return;
#ifdef HAVE_LIBWACOM #ifdef HAVE_LIBWACOM
{ {
WacomDevice *wacom_device; WacomDevice *wacom_device;
@ -1028,81 +919,15 @@ update_tablet_keep_aspect (MetaInputSettings *input_settings,
} }
#endif #endif
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
keep_aspect = g_settings_get_boolean (settings, "keep-aspect"); keep_aspect = g_settings_get_boolean (settings, "keep-aspect");
meta_input_settings_find_monitor (input_settings, settings, device,
NULL, &logical_monitor);
if (keep_aspect) if (keep_aspect)
{ aspect_ratio = info->aspect_ratio;
int width, height;
if (logical_monitor)
{
width = logical_monitor->rect.width;
height = logical_monitor->rect.height;
}
else else
{
MetaMonitorManager *monitor_manager;
MetaBackend *backend;
backend = meta_get_backend ();
monitor_manager = meta_backend_get_monitor_manager (backend);
meta_monitor_manager_get_screen_size (monitor_manager,
&width, &height);
}
aspect_ratio = (double) width / height;
}
else
{
aspect_ratio = 0; aspect_ratio = 0;
}
input_settings_class->set_tablet_aspect_ratio (input_settings, device, aspect_ratio);
}
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 };
MetaMonitor *monitor = NULL;
MetaLogicalMonitor *logical_monitor = NULL;
if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE &&
clutter_input_device_get_device_type (device) != CLUTTER_PEN_DEVICE &&
clutter_input_device_get_device_type (device) != CLUTTER_ERASER_DEVICE &&
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHSCREEN_DEVICE)
return;
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
input_settings_class->set_tablet_aspect_ratio (input_settings, device, aspect_ratio);
meta_input_settings_find_monitor (input_settings, settings, device,
&monitor, &logical_monitor);
if (monitor)
{
meta_input_mapper_remove_device (priv->input_mapper, device);
meta_monitor_manager_get_monitor_matrix (priv->monitor_manager,
monitor, logical_monitor,
matrix);
}
else
{
if (meta_input_settings_delegate_on_mapper (input_settings, device))
return;
}
input_settings_class->set_matrix (input_settings, device, matrix);
/* Ensure the keep-aspect mapping is updated */
update_tablet_keep_aspect (input_settings, settings, device);
} }
static void static void
@ -1137,10 +962,6 @@ update_tablet_mapping (MetaInputSettings *input_settings,
settings_device_set_uint_setting (input_settings, device, settings_device_set_uint_setting (input_settings, device,
input_settings_class->set_tablet_mapping, input_settings_class->set_tablet_mapping,
mapping); mapping);
/* Relative mapping disables keep-aspect/display */
update_tablet_keep_aspect (input_settings, settings, device);
update_device_display (input_settings, settings, device);
} }
static void static void
@ -1296,9 +1117,7 @@ mapped_device_changed_cb (GSettings *settings,
const gchar *key, const gchar *key,
DeviceMappingInfo *info) DeviceMappingInfo *info)
{ {
if (strcmp (key, "output") == 0) if (strcmp (key, "mapping") == 0)
update_device_display (info->input_settings, settings, info->device);
else if (strcmp (key, "mapping") == 0)
update_tablet_mapping (info->input_settings, settings, info->device); update_tablet_mapping (info->input_settings, settings, info->device);
else if (strcmp (key, "area") == 0) else if (strcmp (key, "area") == 0)
update_tablet_area (info->input_settings, settings, info->device); update_tablet_area (info->input_settings, settings, info->device);
@ -1314,7 +1133,6 @@ apply_mappable_device_settings (MetaInputSettings *input_settings,
{ {
ClutterInputDeviceType device_type; ClutterInputDeviceType device_type;
update_device_display (input_settings, info->settings, info->device);
device_type = clutter_input_device_get_device_type (info->device); device_type = clutter_input_device_get_device_type (info->device);
if (device_type == CLUTTER_TABLET_DEVICE || if (device_type == CLUTTER_TABLET_DEVICE ||
@ -1589,43 +1407,30 @@ lookup_tool_settings (ClutterInputDeviceTool *tool,
} }
static void static void
monitors_changed_cb (MetaMonitorManager *monitor_manager, input_mapper_device_mapped_cb (MetaInputMapper *mapper,
ClutterInputDevice *device,
float matrix[6],
MetaInputSettings *input_settings) MetaInputSettings *input_settings)
{ {
MetaInputSettingsPrivate *priv; meta_input_settings_set_device_matrix (input_settings, device, matrix);
ClutterInputDevice *device;
DeviceMappingInfo *info;
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 *) &info))
update_device_display (input_settings, info->settings, device);
} }
static void static void
input_mapper_device_mapped_cb (MetaInputMapper *mapper, input_mapper_device_enabled_cb (MetaInputMapper *mapper,
ClutterInputDevice *device, ClutterInputDevice *device,
MetaLogicalMonitor *logical_monitor, gboolean enabled,
MetaMonitor *monitor,
MetaInputSettings *input_settings) MetaInputSettings *input_settings)
{ {
MetaInputSettingsPrivate *priv; meta_input_settings_set_device_enabled (input_settings, device, enabled);
float matrix[6] = { 1, 0, 0, 0, 1, 0 };
priv = meta_input_settings_get_instance_private (input_settings);
if (monitor && logical_monitor)
{
meta_monitor_manager_get_monitor_matrix (priv->monitor_manager,
monitor, logical_monitor,
matrix);
} }
META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_matrix (input_settings, static void
device, matrix); input_mapper_device_aspect_ratio_cb (MetaInputMapper *mapper,
ClutterInputDevice *device,
double aspect_ratio,
MetaInputSettings *input_settings)
{
meta_input_settings_set_device_aspect_ratio (input_settings, device, aspect_ratio);
} }
static void static void
@ -1660,6 +1465,8 @@ check_add_mappable_device (MetaInputSettings *input_settings,
if (!settings) if (!settings)
return FALSE; return FALSE;
meta_input_mapper_add_device (priv->input_mapper, device);
priv = meta_input_settings_get_instance_private (input_settings); priv = meta_input_settings_get_instance_private (input_settings);
info = g_slice_new0 (DeviceMappingInfo); info = g_slice_new0 (DeviceMappingInfo);
@ -1924,47 +1731,6 @@ check_mappable_devices (MetaInputSettings *input_settings)
g_list_free (devices); g_list_free (devices);
} }
static void
power_save_mode_changed_cb (MetaMonitorManager *manager,
gpointer user_data)
{
MetaInputSettings *input_settings = user_data;
MetaInputSettingsPrivate *priv;
ClutterInputDevice *device;
MetaLogicalMonitor *logical_monitor;
MetaMonitor *builtin;
MetaPowerSave power_save_mode;
GDesktopDeviceSendEvents send_events;
gboolean on;
power_save_mode = meta_monitor_manager_get_power_save_mode (manager);
on = power_save_mode == META_POWER_SAVE_ON;
priv = meta_input_settings_get_instance_private (input_settings);
builtin = meta_monitor_manager_get_laptop_panel (manager);
if (!builtin)
return;
logical_monitor = meta_monitor_get_logical_monitor (builtin);
if (!logical_monitor)
return;
device =
meta_input_mapper_get_logical_monitor_device (priv->input_mapper,
logical_monitor,
CLUTTER_TOUCHSCREEN_DEVICE);
if (!device)
return;
send_events = on ?
G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED :
G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED;
META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_send_events (input_settings,
device,
send_events);
}
static void static void
meta_input_settings_constructed (GObject *object) meta_input_settings_constructed (GObject *object)
{ {
@ -2046,17 +1812,15 @@ meta_input_settings_init (MetaInputSettings *settings)
priv->current_tools = priv->current_tools =
g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) current_tool_info_free); g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) current_tool_info_free);
priv->monitor_manager = g_object_ref (meta_monitor_manager_get ());
g_signal_connect (priv->monitor_manager, "monitors-changed-internal",
G_CALLBACK (monitors_changed_cb), settings);
g_signal_connect (priv->monitor_manager, "power-save-mode-changed",
G_CALLBACK (power_save_mode_changed_cb), settings);
priv->two_finger_devices = g_hash_table_new (NULL, NULL); priv->two_finger_devices = g_hash_table_new (NULL, NULL);
priv->input_mapper = meta_input_mapper_new (); priv->input_mapper = meta_input_mapper_new ();
g_signal_connect (priv->input_mapper, "device-mapped", g_signal_connect (priv->input_mapper, "device-mapped",
G_CALLBACK (input_mapper_device_mapped_cb), settings); G_CALLBACK (input_mapper_device_mapped_cb), settings);
g_signal_connect (priv->input_mapper, "device-enabled",
G_CALLBACK (input_mapper_device_enabled_cb), settings);
g_signal_connect (priv->input_mapper, "device-aspect-ratio",
G_CALLBACK (input_mapper_device_aspect_ratio_cb), settings);
} }
GSettings * GSettings *
@ -2075,77 +1839,18 @@ meta_input_settings_get_tablet_settings (MetaInputSettings *settings,
return info ? g_object_ref (info->settings) : NULL; return info ? g_object_ref (info->settings) : NULL;
} }
static ClutterInputDevice *
find_grouped_pen (MetaInputSettings *settings,
ClutterInputDevice *device)
{
MetaInputSettingsPrivate *priv;
GList *l, *devices;
ClutterInputDeviceType device_type;
ClutterInputDevice *pen = NULL;
device_type = clutter_input_device_get_device_type (device);
if (device_type == CLUTTER_TABLET_DEVICE ||
device_type == CLUTTER_PEN_DEVICE)
return device;
priv = meta_input_settings_get_instance_private (settings);
devices = clutter_seat_list_devices (priv->seat);
for (l = devices; l; l = l->next)
{
ClutterInputDevice *other_device = l->data;
device_type = clutter_input_device_get_device_type (other_device);
if ((device_type == CLUTTER_TABLET_DEVICE ||
device_type == CLUTTER_PEN_DEVICE) &&
clutter_input_device_is_grouped (device, other_device))
{
pen = other_device;
break;
}
}
g_list_free (devices);
return pen;
}
MetaLogicalMonitor * MetaLogicalMonitor *
meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings, meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings,
ClutterInputDevice *device) ClutterInputDevice *device)
{ {
MetaLogicalMonitor *logical_monitor = NULL;
MetaInputSettingsPrivate *priv; MetaInputSettingsPrivate *priv;
DeviceMappingInfo *info;
g_return_val_if_fail (META_IS_INPUT_SETTINGS (settings), NULL); g_return_val_if_fail (META_IS_INPUT_SETTINGS (settings), NULL);
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE)
{
device = find_grouped_pen (settings, device);
if (!device)
return NULL;
}
priv = meta_input_settings_get_instance_private (settings); priv = meta_input_settings_get_instance_private (settings);
info = g_hash_table_lookup (priv->mappable_devices, device);
if (!info)
return NULL;
logical_monitor = return meta_input_mapper_get_device_logical_monitor (priv->input_mapper, device);
meta_input_mapper_get_device_logical_monitor (priv->input_mapper, device);
if (!logical_monitor)
{
meta_input_settings_find_monitor (settings, info->settings, device,
NULL, &logical_monitor);
}
return logical_monitor;
} }
void void
@ -2185,3 +1890,56 @@ meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settin
numlock_state = g_settings_get_boolean (priv->keyboard_settings, "numlock-state"); numlock_state = g_settings_get_boolean (priv->keyboard_settings, "numlock-state");
meta_backend_set_numlock (meta_get_backend (), numlock_state); meta_backend_set_numlock (meta_get_backend (), numlock_state);
} }
void
meta_input_settings_set_device_matrix (MetaInputSettings *input_settings,
ClutterInputDevice *device,
float matrix[6])
{
g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings));
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_matrix (input_settings,
device,
matrix);
}
void
meta_input_settings_set_device_enabled (MetaInputSettings *input_settings,
ClutterInputDevice *device,
gboolean enabled)
{
GDesktopDeviceSendEvents mode;
g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings));
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
mode = enabled ?
G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED :
G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED;
META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_send_events (input_settings,
device,
mode);
}
void
meta_input_settings_set_device_aspect_ratio (MetaInputSettings *input_settings,
ClutterInputDevice *device,
double aspect_ratio)
{
MetaInputSettingsPrivate *priv;
DeviceMappingInfo *info;
g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings));
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
priv = meta_input_settings_get_instance_private (input_settings);
info = g_hash_table_lookup (priv->mappable_devices, device);
if (!info)
return;
info->aspect_ratio = aspect_ratio;
update_tablet_keep_aspect (input_settings, info->settings, device);
}