input-settings: Use logical monitors instead of outputs

A MetaOutput is a connector, not exactly a monitor or a region on the
stage; for example tiled monitors are split up into multiple outputs,
and for what is used in input settings, that makes no sense. Change
this to use logical monitors instead of outputs.

https://bugzilla.gnome.org/show_bug.cgi?id=779745
This commit is contained in:
Jonas Ådahl 2017-03-07 12:20:14 +08:00
parent a48c9d6cd9
commit cdedd017d6
6 changed files with 141 additions and 96 deletions

View File

@ -92,7 +92,7 @@ struct _MetaInputSettingsClass
GDesktopTabletMapping mapping); GDesktopTabletMapping mapping);
void (* set_tablet_keep_aspect) (MetaInputSettings *settings, void (* set_tablet_keep_aspect) (MetaInputSettings *settings,
ClutterInputDevice *device, ClutterInputDevice *device,
MetaOutput *output, MetaLogicalMonitor *logical_monitor,
gboolean keep_aspect); gboolean keep_aspect);
void (* set_tablet_area) (MetaInputSettings *settings, void (* set_tablet_area) (MetaInputSettings *settings,
ClutterInputDevice *device, ClutterInputDevice *device,

View File

@ -31,6 +31,8 @@
#include "meta-backend-private.h" #include "meta-backend-private.h"
#include "meta-input-settings-private.h" #include "meta-input-settings-private.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor.h"
#include "x11/meta-input-settings-x11.h" #include "x11/meta-input-settings-x11.h"
#ifdef HAVE_NATIVE_BACKEND #ifdef HAVE_NATIVE_BACKEND
@ -686,14 +688,40 @@ update_keyboard_repeat (MetaInputSettings *input_settings)
repeat, delay, interval); repeat, delay, interval);
} }
static MetaOutput * static gboolean
meta_input_settings_find_output (MetaInputSettings *input_settings, logical_monitor_has_monitor (MetaMonitorManager *monitor_manager,
GSettings *settings, MetaLogicalMonitor *logical_monitor,
ClutterInputDevice *device) const char *vendor,
const char *product,
const char *serial)
{
GList *monitors;
GList *l;
monitors = meta_monitor_manager_get_monitors (monitor_manager);
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 TRUE;
}
return FALSE;
}
static MetaLogicalMonitor *
meta_input_settings_find_logical_monitor (MetaInputSettings *input_settings,
GSettings *settings,
ClutterInputDevice *device)
{ {
MetaInputSettingsPrivate *priv; MetaInputSettingsPrivate *priv;
guint n_values, n_outputs, i; MetaMonitorManager *monitor_manager;
MetaOutput *outputs; guint n_values;
GList *logical_monitors;
GList *l;
gchar **edid; gchar **edid;
priv = meta_input_settings_get_instance_private (input_settings); priv = meta_input_settings_get_instance_private (input_settings);
@ -711,14 +739,19 @@ meta_input_settings_find_output (MetaInputSettings *input_settings,
if (!*edid[0] && !*edid[1] && !*edid[2]) if (!*edid[0] && !*edid[1] && !*edid[2])
return NULL; return NULL;
outputs = meta_monitor_manager_get_outputs (priv->monitor_manager, monitor_manager = priv->monitor_manager;
&n_outputs); logical_monitors =
for (i = 0; i < n_outputs; i++) meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{ {
if (g_strcmp0 (outputs[i].vendor, edid[0]) == 0 && MetaLogicalMonitor *logical_monitor = l->data;
g_strcmp0 (outputs[i].product, edid[1]) == 0 &&
g_strcmp0 (outputs[i].serial, edid[2]) == 0) if (logical_monitor_has_monitor (monitor_manager,
return &outputs[i]; logical_monitor,
edid[0],
edid[1],
edid[2]))
return logical_monitor;
} }
return NULL; return NULL;
@ -730,7 +763,7 @@ update_tablet_keep_aspect (MetaInputSettings *input_settings,
ClutterInputDevice *device) ClutterInputDevice *device)
{ {
MetaInputSettingsClass *input_settings_class; MetaInputSettingsClass *input_settings_class;
MetaOutput *output = NULL; MetaLogicalMonitor *logical_monitor = NULL;
gboolean keep_aspect; gboolean keep_aspect;
if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE && if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE &&
@ -757,7 +790,9 @@ update_tablet_keep_aspect (MetaInputSettings *input_settings,
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE) CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE)
{ {
keep_aspect = g_settings_get_boolean (settings, "keep-aspect"); keep_aspect = g_settings_get_boolean (settings, "keep-aspect");
output = meta_input_settings_find_output (input_settings, settings, device); logical_monitor = meta_input_settings_find_logical_monitor (input_settings,
settings,
device);
} }
else else
{ {
@ -765,7 +800,7 @@ update_tablet_keep_aspect (MetaInputSettings *input_settings,
} }
input_settings_class->set_tablet_keep_aspect (input_settings, device, input_settings_class->set_tablet_keep_aspect (input_settings, device,
output, keep_aspect); logical_monitor, keep_aspect);
} }
static void static void
@ -776,7 +811,7 @@ update_device_display (MetaInputSettings *input_settings,
MetaInputSettingsClass *input_settings_class; MetaInputSettingsClass *input_settings_class;
MetaInputSettingsPrivate *priv; MetaInputSettingsPrivate *priv;
gfloat matrix[6] = { 1, 0, 0, 0, 1, 0 }; gfloat matrix[6] = { 1, 0, 0, 0, 1, 0 };
MetaOutput *output; MetaLogicalMonitor *logical_monitor;
if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE && 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_PEN_DEVICE &&
@ -791,13 +826,15 @@ update_device_display (MetaInputSettings *input_settings,
if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE || if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE ||
clutter_input_device_get_mapping_mode (device) == clutter_input_device_get_mapping_mode (device) ==
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE) CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE)
output = meta_input_settings_find_output (input_settings, settings, device); logical_monitor = meta_input_settings_find_logical_monitor (input_settings,
settings,
device);
else else
output = NULL; logical_monitor = NULL;
if (output) if (logical_monitor)
meta_monitor_manager_get_monitor_matrix (priv->monitor_manager, meta_monitor_manager_get_monitor_matrix (priv->monitor_manager,
output, matrix); logical_monitor, matrix);
input_settings_class->set_matrix (input_settings, device, matrix); input_settings_class->set_matrix (input_settings, device, matrix);
@ -1472,7 +1509,6 @@ meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings,
{ {
MetaInputSettingsPrivate *priv; MetaInputSettingsPrivate *priv;
DeviceMappingInfo *info; DeviceMappingInfo *info;
MetaOutput *output;
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);
@ -1482,12 +1518,9 @@ meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings,
if (!info) if (!info)
return NULL; return NULL;
output = meta_input_settings_find_output (settings, info->settings, device); return meta_input_settings_find_logical_monitor (settings,
info->settings,
if (output && output->crtc) device);
return output->crtc->logical_monitor;
return NULL;
} }
GDesktopTabletMapping GDesktopTabletMapping
@ -1549,47 +1582,38 @@ meta_input_settings_get_tablet_wacom_device (MetaInputSettings *settings,
#endif /* HAVE_LIBWACOM */ #endif /* HAVE_LIBWACOM */
static gboolean static gboolean
cycle_outputs (MetaInputSettings *settings, cycle_logical_monitors (MetaInputSettings *settings,
MetaOutput *current_output, MetaLogicalMonitor *current_logical_monitor,
MetaOutput **next_output) MetaLogicalMonitor **next_logical_monitor)
{ {
MetaInputSettingsPrivate *priv; MetaInputSettingsPrivate *priv =
MetaOutput *next, *outputs; meta_input_settings_get_instance_private (settings);
guint n_outputs, current, i; MetaMonitorManager *monitor_manager = priv->monitor_manager;
GList *logical_monitors;
priv = meta_input_settings_get_instance_private (settings);
outputs = meta_monitor_manager_get_outputs (priv->monitor_manager,
&n_outputs);
if (n_outputs <= 1)
return FALSE;
/* We cycle between: /* We cycle between:
* - the span of all monitors (current_output = NULL) * - the span of all monitors (current_output = NULL)
* - each monitor individually. * - each monitor individually.
*/ */
if (!current_output)
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
if (!current_logical_monitor)
{ {
next = &outputs[0]; *next_logical_monitor = logical_monitors->data;
} }
else else
{ {
for (i = 0; i < n_outputs; i++) GList *l;
{
if (current_output != &outputs[i])
continue;
current = i;
break;
}
g_assert (i < n_outputs); l = g_list_find (logical_monitors, current_logical_monitor);
if (l->next)
if (current == n_outputs - 1) *next_logical_monitor = l->next->data;
next = NULL;
else else
next = &outputs[current + 1]; *next_logical_monitor = logical_monitors->data;
} }
*next_output = next;
return TRUE; return TRUE;
} }
@ -1599,7 +1623,7 @@ meta_input_settings_cycle_tablet_output (MetaInputSettings *input_settings,
{ {
MetaInputSettingsPrivate *priv; MetaInputSettingsPrivate *priv;
DeviceMappingInfo *info; DeviceMappingInfo *info;
MetaOutput *output; MetaLogicalMonitor *logical_monitor;
const gchar *edid[4] = { 0 }, *pretty_name = NULL; const gchar *edid[4] = { 0 }, *pretty_name = NULL;
g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings)); g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings));
@ -1622,14 +1646,30 @@ meta_input_settings_cycle_tablet_output (MetaInputSettings *input_settings,
} }
#endif #endif
output = meta_input_settings_find_output (input_settings, logical_monitor = meta_input_settings_find_logical_monitor (input_settings,
info->settings, device); info->settings,
if (!cycle_outputs (input_settings, output, &output)) device);
if (!cycle_logical_monitors (input_settings,
logical_monitor,
&logical_monitor))
return; return;
edid[0] = output ? output->vendor : ""; if (logical_monitor)
edid[1] = output ? output->product : ""; {
edid[2] = output ? output->serial : ""; MetaMonitor *monitor;
/* Pick an arbitrary monitor in the logical monitor to represent it. */
monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
edid[0] = meta_monitor_get_vendor (monitor);
edid[1] = meta_monitor_get_product (monitor);
edid[2] = meta_monitor_get_serial (monitor);
}
else
{
edid[0] = "";
edid[1] = "";
edid[2] = "";
}
g_settings_set_strv (info->settings, "display", edid); g_settings_set_strv (info->settings, "display", edid);
meta_display_show_tablet_mapping_notification (meta_get_display (), meta_display_show_tablet_mapping_notification (meta_get_display (),

View File

@ -423,7 +423,7 @@ void meta_monitor_manager_read_current_state (MetaMonitorManager *
void meta_monitor_manager_on_hotplug (MetaMonitorManager *manager); void meta_monitor_manager_on_hotplug (MetaMonitorManager *manager);
gboolean meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager, gboolean meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
MetaOutput *output, MetaLogicalMonitor *logical_monitor,
gfloat matrix[6]); gfloat matrix[6]);
void meta_monitor_manager_tiled_monitor_added (MetaMonitorManager *manager, void meta_monitor_manager_tiled_monitor_added (MetaMonitorManager *manager,

View File

@ -1980,18 +1980,15 @@ meta_monitor_manager_on_hotplug (MetaMonitorManager *manager)
static gboolean static gboolean
calculate_viewport_matrix (MetaMonitorManager *manager, calculate_viewport_matrix (MetaMonitorManager *manager,
MetaOutput *output, MetaLogicalMonitor *logical_monitor,
gfloat viewport[6]) gfloat viewport[6])
{ {
gfloat x, y, width, height; gfloat x, y, width, height;
if (!output->crtc) x = (float) logical_monitor->rect.x / manager->screen_width;
return FALSE; y = (float) logical_monitor->rect.y / manager->screen_height;
width = (float) logical_monitor->rect.width / manager->screen_width;
x = (float) output->crtc->rect.x / manager->screen_width; height = (float) logical_monitor->rect.height / manager->screen_height;
y = (float) output->crtc->rect.y / manager->screen_height;
width = (float) output->crtc->rect.width / manager->screen_width;
height = (float) output->crtc->rect.height / manager->screen_height;
viewport[0] = width; viewport[0] = width;
viewport[1] = 0.0f; viewport[1] = 0.0f;
@ -2018,15 +2015,21 @@ multiply_matrix (float a[6],
gboolean gboolean
meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager, meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
MetaOutput *output, MetaLogicalMonitor *logical_monitor,
gfloat matrix[6]) gfloat matrix[6])
{ {
MetaMonitor *main_monitor;
MetaOutput *main_output;
MetaMonitorTransform transform;
gfloat viewport[9]; gfloat viewport[9];
if (!calculate_viewport_matrix (manager, output, viewport)) if (!calculate_viewport_matrix (manager, logical_monitor, viewport))
return FALSE; return FALSE;
multiply_matrix (viewport, transform_matrices[output->crtc->transform], main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
main_output = meta_monitor_get_main_output (main_monitor);
transform = main_output->crtc->transform;
multiply_matrix (viewport, transform_matrices[transform],
matrix); matrix);
return TRUE; return TRUE;
} }

View File

@ -29,6 +29,7 @@
#include "meta-backend-native.h" #include "meta-backend-native.h"
#include "meta-input-settings-native.h" #include "meta-input-settings-native.h"
#include "backends/meta-logical-monitor.h"
G_DEFINE_TYPE (MetaInputSettingsNative, meta_input_settings_native, META_TYPE_INPUT_SETTINGS) G_DEFINE_TYPE (MetaInputSettingsNative, meta_input_settings_native, META_TYPE_INPUT_SETTINGS)
@ -390,19 +391,19 @@ meta_input_settings_native_set_tablet_mapping (MetaInputSettings *settings,
static void static void
meta_input_settings_native_set_tablet_keep_aspect (MetaInputSettings *settings, meta_input_settings_native_set_tablet_keep_aspect (MetaInputSettings *settings,
ClutterInputDevice *device, ClutterInputDevice *device,
MetaOutput *output, MetaLogicalMonitor *logical_monitor,
gboolean keep_aspect) gboolean keep_aspect)
{ {
gdouble output_aspect = 0; double aspect_ratio = 0;
if (keep_aspect) if (keep_aspect)
{ {
gint output_width, output_height; int width, height;
if (output && output->crtc) if (logical_monitor)
{ {
output_width = output->crtc->rect.width; width = logical_monitor->rect.width;
output_height = output->crtc->rect.height; height = logical_monitor->rect.height;
} }
else else
{ {
@ -412,14 +413,14 @@ meta_input_settings_native_set_tablet_keep_aspect (MetaInputSettings *settings,
backend = meta_get_backend (); backend = meta_get_backend ();
monitor_manager = meta_backend_get_monitor_manager (backend); monitor_manager = meta_backend_get_monitor_manager (backend);
meta_monitor_manager_get_screen_size (monitor_manager, meta_monitor_manager_get_screen_size (monitor_manager,
&output_width, &width,
&output_height); &height);
} }
output_aspect = (gdouble) output_width / output_height; aspect_ratio = (double) width / height;
} }
g_object_set (device, "output-aspect-ratio", output_aspect, NULL); g_object_set (device, "output-aspect-ratio", aspect_ratio, NULL);
} }
static void static void

View File

@ -36,6 +36,7 @@
#endif #endif
#include <meta/errors.h> #include <meta/errors.h>
#include "backends/meta-logical-monitor.h"
typedef struct _MetaInputSettingsX11Private typedef struct _MetaInputSettingsX11Private
{ {
@ -604,7 +605,7 @@ meta_input_settings_x11_set_tablet_area (MetaInputSettings *settings,
static void static void
meta_input_settings_x11_set_tablet_keep_aspect (MetaInputSettings *settings, meta_input_settings_x11_set_tablet_keep_aspect (MetaInputSettings *settings,
ClutterInputDevice *device, ClutterInputDevice *device,
MetaOutput *output, MetaLogicalMonitor *logical_monitor,
gboolean keep_aspect) gboolean keep_aspect)
{ {
gint32 width, height, dev_width, dev_height, area[4] = { 0 }; gint32 width, height, dev_width, dev_height, area[4] = { 0 };
@ -614,12 +615,12 @@ meta_input_settings_x11_set_tablet_keep_aspect (MetaInputSettings *settings,
if (keep_aspect) if (keep_aspect)
{ {
gdouble output_aspect, dev_aspect; double aspect_ratio, dev_aspect;
if (output && output->crtc) if (logical_monitor)
{ {
width = output->crtc->rect.width; width = logical_monitor->rect.width;
height = output->crtc->rect.height; height = logical_monitor->rect.height;
} }
else else
{ {
@ -632,13 +633,13 @@ meta_input_settings_x11_set_tablet_keep_aspect (MetaInputSettings *settings,
&width, &height); &width, &height);
} }
output_aspect = (gdouble) width / height; aspect_ratio = (double) width / height;
dev_aspect = (gdouble) dev_width / dev_height; dev_aspect = (double) dev_width / dev_height;
if (dev_aspect > output_aspect) if (dev_aspect > aspect_ratio)
dev_width = dev_height * output_aspect; dev_width = dev_height * aspect_ratio;
else if (dev_aspect < output_aspect) else if (dev_aspect < aspect_ratio)
dev_height = dev_width / output_aspect; dev_height = dev_width / aspect_ratio;
} }
area[2] = dev_width; area[2] = dev_width;