[gnome-settings-daemon] common: Implement size matching on screen-integrated devices
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] common: Implement size matching on screen-integrated devices
- Date: Wed, 28 May 2014 14:25:46 +0000 (UTC)
commit bc996ff6d7d9929fd17cfb98ea0f318194e4af96
Author: Carlos Garnacho <carlosg gnome org>
Date: Mon May 26 20:36:25 2014 +0200
common: Implement size matching on screen-integrated devices
On these devices, attempt to find a match based on device WxH calculations
and output size information from EDID. Allow for a certain error threshold
as sizes don't exactly match.
https://bugzilla.gnome.org/show_bug.cgi?id=730583
plugins/common/gsd-device-mapper.c | 66 ++++++++++++++++++++++++++++++++++-
plugins/common/gsd-input-helper.c | 49 ++++++++++++++++++++++++++
plugins/common/gsd-input-helper.h | 4 ++
3 files changed, 117 insertions(+), 2 deletions(-)
---
diff --git a/plugins/common/gsd-device-mapper.c b/plugins/common/gsd-device-mapper.c
index 8fdad66..43d726a 100644
--- a/plugins/common/gsd-device-mapper.c
+++ b/plugins/common/gsd-device-mapper.c
@@ -51,6 +51,7 @@ typedef enum {
typedef enum {
GSD_PRIO_BUILTIN, /* Output is builtin, applies mainly to system-integrated devices */
+ GSD_PRIO_MATCH_SIZE, /* Size from input device and output match */
GSD_PRIO_EDID_MATCH_FULL, /* Full EDID model match, eg. "Cintiq 12WX" */
GSD_PRIO_EDID_MATCH_PARTIAL, /* Partial EDID model match, eg. "Cintiq" */
GSD_PRIO_EDID_MATCH_VENDOR, /* EDID vendor match, eg. "WAC" for Wacom */
@@ -120,6 +121,9 @@ enum {
N_SIGNALS
};
+static GnomeRROutput * input_info_find_size_match (GsdInputInfo *input,
+ GnomeRRScreen *rr_screen);
+
static guint signals[N_SIGNALS] = { 0 };
G_DEFINE_TYPE (GsdDeviceMapper, gsd_device_mapper, G_TYPE_OBJECT)
@@ -359,6 +363,10 @@ input_info_guess_candidates (GsdInputInfo *input,
if (found)
return;
+ if (input->capabilities & GSD_INPUT_IS_SCREEN_INTEGRATED) {
+ outputs[GSD_PRIO_MATCH_SIZE] = input_info_find_size_match (input, input->mapper->rr_screen);
+ }
+
split = g_strsplit (name, " ", -1);
/* On Wacom devices that are integrated on a not-in-system screen (eg. Cintiqs),
@@ -377,10 +385,10 @@ input_info_guess_candidates (GsdInputInfo *input,
for (i = 0; i < G_N_ELEMENTS (edids); i++) {
/* i + 1 matches the desired priority, we skip GSD_PRIO_BUILTIN here */
- outputs[i + 1] =
+ outputs[i + GSD_PRIO_EDID_MATCH_FULL] =
find_output_by_edid (input->mapper->rr_screen,
edids[i]);
- found |= outputs[i + 1] != NULL;
+ found |= outputs[i + GSD_PRIO_EDID_MATCH_FULL] != NULL;
}
g_free (product);
@@ -616,6 +624,60 @@ monitor_for_output (GnomeRROutput *output)
return gdk_screen_get_monitor_at_point (screen, x, y);
}
+static gboolean
+output_get_dimensions (GnomeRROutput *output,
+ guint *width,
+ guint *height)
+{
+ GdkScreen *screen = gdk_screen_get_default ();
+ gint monitor_num;
+
+ monitor_num = monitor_for_output (output);
+
+ if (monitor_num < 0)
+ return FALSE;
+
+ *width = gdk_screen_get_monitor_width_mm (screen, monitor_num);
+ *height = gdk_screen_get_monitor_height_mm (screen, monitor_num);
+ return TRUE;
+}
+
+static GnomeRROutput *
+input_info_find_size_match (GsdInputInfo *input,
+ GnomeRRScreen *rr_screen)
+{
+ guint i, input_width, input_height, output_width, output_height;
+ GnomeRROutput **outputs;
+
+ g_return_val_if_fail (rr_screen != NULL, NULL);
+
+ if (!xdevice_get_dimensions (gdk_x11_device_get_id (input->device),
+ &input_width, &input_height))
+ return NULL;
+
+ g_debug ("Input device '%s' has %dx%d mm",
+ gdk_device_get_name (input->device), input_width, input_height);
+
+ outputs = gnome_rr_screen_list_outputs (rr_screen);
+
+ for (i = 0; outputs[i] != NULL; i++) {
+ if (!output_get_dimensions (outputs[i], &output_width, &output_height))
+ continue;
+
+#define MAX_DIFF 0.05
+ if (ABS (1 - ((gdouble) output_width / input_width)) < MAX_DIFF &&
+ ABS (1 - ((gdouble) output_height / input_height)) < MAX_DIFF) {
+ g_debug ("Output device '%s' is considered a match with %dx%d mm",
+ gnome_rr_output_get_name (outputs[i]),
+ output_width, output_height);
+ return outputs[i];
+ }
+#undef MAX_DIFF
+ }
+
+ return NULL;
+}
+
static void
input_info_get_matrix (GsdInputInfo *input,
float matrix[NUM_ELEMS_MATRIX])
diff --git a/plugins/common/gsd-input-helper.c b/plugins/common/gsd-input-helper.c
index 625d361..4872506 100644
--- a/plugins/common/gsd-input-helper.c
+++ b/plugins/common/gsd-input-helper.c
@@ -33,6 +33,11 @@
#define INPUT_DEVICES_SCHEMA "org.gnome.settings-daemon.peripherals.input-devices"
#define KEY_HOTPLUG_COMMAND "hotplug-command"
+#define ABS_MT_X "Abs MT Position X"
+#define ABS_MT_Y "Abs MT Position Y"
+#define ABS_X "Abs X"
+#define ABS_Y "Abs Y"
+
typedef gboolean (* InfoIdentifyFunc) (XDeviceInfo *device_info);
typedef gboolean (* DeviceIdentifyFunc) (XDevice *xdevice);
@@ -626,3 +631,47 @@ xdevice_close (XDevice *xdevice)
XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
gdk_error_trap_pop_ignored();
}
+
+gboolean
+xdevice_get_dimensions (int deviceid,
+ guint *width,
+ guint *height)
+{
+ GdkDisplay *display = gdk_display_get_default ();
+ XIDeviceInfo *info;
+ guint *value, w, h;
+ int i, n_info;
+
+ info = XIQueryDevice (GDK_DISPLAY_XDISPLAY (display), deviceid, &n_info);
+ *width = *height = w = h = 0;
+
+ if (!info)
+ return FALSE;
+
+ for (i = 0; i < info->num_classes; i++) {
+ XIValuatorClassInfo *valuator_info;
+
+ if (info->classes[i]->type != XIValuatorClass)
+ continue;
+
+ valuator_info = (XIValuatorClassInfo *) info->classes[i];
+
+ if (valuator_info->label == gdk_x11_get_xatom_by_name_for_display (display, ABS_X) ||
+ valuator_info->label == gdk_x11_get_xatom_by_name_for_display (display, ABS_MT_X))
+ value = &w;
+ else if (valuator_info->label == gdk_x11_get_xatom_by_name_for_display (display, ABS_Y) ||
+ valuator_info->label == gdk_x11_get_xatom_by_name_for_display (display, ABS_MT_Y))
+ value = &h;
+ else
+ continue;
+
+ *value = (valuator_info->max - valuator_info->min) * 1000 / valuator_info->resolution;
+ }
+
+ *width = w;
+ *height = h;
+
+ XIFreeDeviceInfo (info);
+
+ return (w != 0 && h != 0);
+}
diff --git a/plugins/common/gsd-input-helper.h b/plugins/common/gsd-input-helper.h
index 702a15a..ce07f7c 100644
--- a/plugins/common/gsd-input-helper.h
+++ b/plugins/common/gsd-input-helper.h
@@ -80,10 +80,14 @@ gboolean run_custom_command (GdkDevice *device,
GList * get_disabled_devices (GdkDeviceManager *manager);
char * xdevice_get_device_node (int deviceid);
int xdevice_get_last_tool_id (int deviceid);
+gboolean xdevice_get_dimensions (int deviceid,
+ guint *width,
+ guint *height);
void xdevice_close (XDevice *xdevice);
const char * xdevice_get_wacom_tool_type (int deviceid);
+
G_END_DECLS
#endif /* __GSD_INPUT_HELPER_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]