Merge lp:~albertomilone/unity-settings-daemon/lp1287341-14.10 into lp:unity-settings-daemon/14.04

Proposed by Sebastien Bacher
Status: Merged
Approved by: Sebastien Bacher
Approved revision: 4047
Merged at revision: 4041
Proposed branch: lp:~albertomilone/unity-settings-daemon/lp1287341-14.10
Merge into: lp:unity-settings-daemon/14.04
Diff against target: 381 lines (+295/-0)
4 files modified
debian/changelog (+19/-0)
plugins/common/gsd-input-helper.c (+49/-0)
plugins/common/gsd-input-helper.h (+3/-0)
plugins/xrandr/gsd-xrandr-manager.c (+224/-0)
To merge this branch: bzr merge lp:~albertomilone/unity-settings-daemon/lp1287341-14.10
Reviewer Review Type Date Requested Status
Sebastien Bacher Approve
Review via email: mp+222071@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Sebastien Bacher (seb128) wrote :

let's sru that one

review: Approve
4048. By Alberto Milone

gsd-xrandr-manager.c: do not try to map an invalid touch device on initialisation

Fixes LP: #1326636

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/changelog'
--- debian/changelog 2014-04-14 10:13:11 +0000
+++ debian/changelog 2014-06-05 11:56:47 +0000
@@ -1,3 +1,22 @@
1unity-settings-daemon (14.04.0+14.04.20140414-0ubuntu2) UNRELEASED; urgency=medium
2
3 [ Alberto Milone ]
4 * gsd-xrandr-manager.c:
5 - Add support for mapping the main touchscreen onto the laptop
6 display (LP: #1287341).
7 This makes sure that the input device knows exactly the area
8 that represents the display when the screen configuration
9 changes. Note: this doesn't cover the tablet use case.
10 - Add support for matching displays with touch input devices
11 according to the reported size. This is particularly
12 useful on systems that don't use embedded display connectors
13 i.e. all-in-one systems such as the Dell Optiplex 9030 AIO.
14 - This work is a partial backport of the upstream work on
15 touchscreens. When we finally sync with the upstream code
16 we can drop this.
17
18 -- Alberto Milone <alberto.milone@canonical.com> Fri, 23 May 2014 12:01:11 +0200
19
1unity-settings-daemon (14.04.0+14.04.20140414-0ubuntu1) trusty; urgency=low20unity-settings-daemon (14.04.0+14.04.20140414-0ubuntu1) trusty; urgency=low
221
3 [ Dmitry Shachnev ]22 [ Dmitry Shachnev ]
423
=== modified file 'plugins/common/gsd-input-helper.c'
--- plugins/common/gsd-input-helper.c 2013-02-07 04:14:22 +0000
+++ plugins/common/gsd-input-helper.c 2014-06-05 11:56:47 +0000
@@ -34,6 +34,11 @@
34#define INPUT_DEVICES_SCHEMA "org.gnome.settings-daemon.peripherals.input-devices"34#define INPUT_DEVICES_SCHEMA "org.gnome.settings-daemon.peripherals.input-devices"
35#define KEY_HOTPLUG_COMMAND "hotplug-command"35#define KEY_HOTPLUG_COMMAND "hotplug-command"
3636
37#define ABS_MT_X "Abs MT Position X"
38#define ABS_MT_Y "Abs MT Position Y"
39#define ABS_X "Abs X"
40#define ABS_Y "Abs Y"
41
37typedef gboolean (* InfoIdentifyFunc) (XDeviceInfo *device_info);42typedef gboolean (* InfoIdentifyFunc) (XDeviceInfo *device_info);
38typedef gboolean (* DeviceIdentifyFunc) (XDevice *xdevice);43typedef gboolean (* DeviceIdentifyFunc) (XDevice *xdevice);
3944
@@ -571,3 +576,47 @@
571576
572 return ret;577 return ret;
573}578}
579
580gboolean
581xdevice_get_dimensions (int deviceid,
582 guint *width,
583 guint *height)
584{
585 GdkDisplay *display = gdk_display_get_default ();
586 XIDeviceInfo *info;
587 guint *value, w, h;
588 int i, n_info;
589
590 info = XIQueryDevice (GDK_DISPLAY_XDISPLAY (display), deviceid, &n_info);
591 *width = *height = w = h = 0;
592
593 if (!info)
594 return FALSE;
595
596 for (i = 0; i < info->num_classes; i++) {
597 XIValuatorClassInfo *valuator_info;
598
599 if (info->classes[i]->type != XIValuatorClass)
600 continue;
601
602 valuator_info = (XIValuatorClassInfo *) info->classes[i];
603
604 if (valuator_info->label == gdk_x11_get_xatom_by_name_for_display (display, ABS_X) ||
605 valuator_info->label == gdk_x11_get_xatom_by_name_for_display (display, ABS_MT_X))
606 value = &w;
607 else if (valuator_info->label == gdk_x11_get_xatom_by_name_for_display (display, ABS_Y) ||
608 valuator_info->label == gdk_x11_get_xatom_by_name_for_display (display, ABS_MT_Y))
609 value = &h;
610 else
611 continue;
612
613 *value = (valuator_info->max - valuator_info->min) * 1000 / valuator_info->resolution;
614 }
615
616 *width = w;
617 *height = h;
618
619 XIFreeDeviceInfo (info);
620
621 return (w != 0 && h != 0);
622}
574623
=== modified file 'plugins/common/gsd-input-helper.h'
--- plugins/common/gsd-input-helper.h 2013-01-21 17:01:42 +0000
+++ plugins/common/gsd-input-helper.h 2014-06-05 11:56:47 +0000
@@ -81,6 +81,9 @@
81GList * get_disabled_devices (GdkDeviceManager *manager);81GList * get_disabled_devices (GdkDeviceManager *manager);
82char * xdevice_get_device_node (int deviceid);82char * xdevice_get_device_node (int deviceid);
83int xdevice_get_last_tool_id (int deviceid);83int xdevice_get_last_tool_id (int deviceid);
84gboolean xdevice_get_dimensions (int deviceid,
85 guint *width,
86 guint *height);
8487
85G_END_DECLS88G_END_DECLS
8689
8790
=== modified file 'plugins/xrandr/gsd-xrandr-manager.c'
--- plugins/xrandr/gsd-xrandr-manager.c 2013-12-04 23:55:26 +0000
+++ plugins/xrandr/gsd-xrandr-manager.c 2014-06-05 11:56:47 +0000
@@ -127,6 +127,9 @@
127#ifdef HAVE_WACOM127#ifdef HAVE_WACOM
128 WacomDeviceDatabase *wacom_db;128 WacomDeviceDatabase *wacom_db;
129#endif /* HAVE_WACOM */129#endif /* HAVE_WACOM */
130
131 int main_touchscreen_id;
132 gchar *main_touchscreen_name;
130};133};
131134
132static const GnomeRRRotation possible_rotations[] = {135static const GnomeRRRotation possible_rotations[] = {
@@ -157,6 +160,10 @@
157160
158static FILE *log_file;161static FILE *log_file;
159162
163static GnomeRROutput * input_info_find_size_match (GsdXrandrManager *manager, GnomeRRScreen *rr_screen);
164static int map_touch_to_output (GnomeRRScreen *screen, int device_id, GnomeRROutputInfo *output);
165static void do_touchscreen_mapping (GsdXrandrManager *manager);
166
160static void167static void
161log_open (void)168log_open (void)
162{169{
@@ -1818,6 +1825,12 @@
1818 use_stored_configuration_or_auto_configure_outputs (manager, config_timestamp);1825 use_stored_configuration_or_auto_configure_outputs (manager, config_timestamp);
1819 }1826 }
18201827
1828 if (priv->main_touchscreen_id != -1) {
1829 /* Set mapping of input devices onto displays */
1830 log_msg ("\nSetting touchscreen mapping on RandR event\n");
1831 do_touchscreen_mapping (manager);
1832 }
1833
1821 log_close ();1834 log_close ();
1822}1835}
18231836
@@ -2033,6 +2046,206 @@
2033 }2046 }
2034}2047}
20352048
2049static gboolean
2050matches_name (GnomeRROutputInfo *output, GnomeRROutput *to_match)
2051{
2052 return (g_strcmp0 (gnome_rr_output_info_get_name (output),
2053 gnome_rr_output_get_name (to_match) ) == 0);
2054}
2055
2056static gint
2057monitor_for_output (GnomeRROutput *output)
2058{
2059 GdkScreen *screen = gdk_screen_get_default ();
2060 GnomeRRCrtc *crtc = gnome_rr_output_get_crtc (output);
2061 gint x, y;
2062
2063 if (!crtc)
2064 return -1;
2065
2066 gnome_rr_crtc_get_position (crtc, &x, &y);
2067
2068 return gdk_screen_get_monitor_at_point (screen, x, y);
2069}
2070
2071static gboolean
2072output_get_dimensions (GnomeRROutput *output,
2073 guint *width,
2074 guint *height)
2075{
2076 GdkScreen *screen = gdk_screen_get_default ();
2077 gint monitor_num;
2078
2079 monitor_num = monitor_for_output (output);
2080
2081 if (monitor_num < 0)
2082 return FALSE;
2083
2084 *width = gdk_screen_get_monitor_width_mm (screen, monitor_num);
2085 *height = gdk_screen_get_monitor_height_mm (screen, monitor_num);
2086 return TRUE;
2087}
2088
2089static GnomeRROutput *
2090input_info_find_size_match (GsdXrandrManager *manager, GnomeRRScreen *rr_screen)
2091{
2092 guint i, input_width, input_height, output_width, output_height;
2093 gdouble min_width_diff, min_height_diff;
2094 GnomeRROutput **outputs, *match = NULL;
2095 GsdXrandrManagerPrivate *priv = manager->priv;
2096
2097 g_return_val_if_fail (rr_screen != NULL, NULL);
2098
2099 if (!xdevice_get_dimensions (priv->main_touchscreen_id,
2100 &input_width, &input_height))
2101 return NULL;
2102
2103 /* Restrict the matches to be below a narrow percentage */
2104 min_width_diff = min_height_diff = 0.05;
2105
2106 g_debug ("Input device '%s' has %dx%d mm",
2107 priv->main_touchscreen_name, input_width, input_height);
2108
2109 outputs = gnome_rr_screen_list_outputs (rr_screen);
2110
2111 for (i = 0; outputs[i] != NULL; i++) {
2112 gdouble width_diff, height_diff;
2113 if (!output_get_dimensions (outputs[i], &output_width, &output_height))
2114 continue;
2115
2116 width_diff = ABS (1 - ((gdouble) output_width / input_width));
2117 height_diff = ABS (1 - ((gdouble) output_height / input_height));
2118
2119 g_debug ("Output '%s' has size %dx%d mm, deviation from "
2120 "input device size: %.2f width, %.2f height ",
2121 gnome_rr_output_get_name (outputs[i]),
2122 output_width, output_height, width_diff, height_diff);
2123
2124 if (width_diff <= min_width_diff && height_diff <= min_height_diff) {
2125 match = outputs[i];
2126 min_width_diff = width_diff;
2127 min_height_diff = height_diff;
2128 }
2129 }
2130
2131 if (match) {
2132 g_debug ("Output '%s' is considered a best size match (%.2f / %.2f)",
2133 gnome_rr_output_get_name (match),
2134 min_width_diff, min_height_diff);
2135 } else {
2136 g_debug ("No input/output size match was found\n");
2137 }
2138
2139 return match;
2140}
2141
2142static GnomeRROutputInfo *
2143get_mappable_output_info (GsdXrandrManager *manager, GnomeRRScreen *screen, GnomeRRConfig *config)
2144{
2145 int i;
2146 GnomeRROutputInfo **outputs = gnome_rr_config_get_outputs (config);
2147
2148 GnomeRROutput *size_match = NULL;
2149
2150 size_match = input_info_find_size_match (manager, screen);
2151
2152 for (i = 0; outputs[i] != NULL; i++) {
2153 if (is_laptop (screen, outputs[i]) || (size_match && matches_name (outputs[i], size_match)))
2154 return outputs[i];
2155 }
2156
2157 return NULL;
2158}
2159
2160static void
2161set_touchscreen_id (GsdXrandrManager *manager)
2162{
2163 GsdXrandrManagerPrivate *priv = manager->priv;
2164 XDeviceInfo *device_info;
2165 int n_devices;
2166 int i;
2167
2168 device_info = XListInputDevices (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
2169 &n_devices);
2170 if (device_info == NULL)
2171 return;
2172
2173 for (i = 0; i < n_devices; i++) {
2174 if (device_info_is_touchscreen (&device_info[i])) {
2175 /* Let's deal only with the 1st touchscreen */
2176 priv->main_touchscreen_id = (int)device_info[i].id;
2177 priv->main_touchscreen_name = g_strdup (device_info[i].name);
2178 break;
2179 }
2180 }
2181
2182 XFreeDeviceList (device_info);
2183}
2184
2185static int
2186map_touch_to_output (GnomeRRScreen *screen, int device_id,
2187 GnomeRROutputInfo *output)
2188{
2189 int status = 0;
2190 char command[100];
2191 gchar *name = gnome_rr_output_info_get_name (output);
2192
2193 if (!name) {
2194 g_debug ("Failure to map screen with missing name");
2195 status = 1;
2196 goto out;
2197 }
2198
2199 if (gnome_rr_output_info_is_active(output)) {
2200 g_debug ("Mapping touchscreen %d onto output %s",
2201 device_id, name);
2202 sprintf (command, "xinput --map-to-output %d %s",
2203 device_id, name);
2204 status = system (command);
2205 }
2206 else {
2207 g_debug ("No need to map %d onto output %s. The output is off",
2208 device_id, name);
2209 }
2210
2211out:
2212 return (status == 0);
2213}
2214
2215static void
2216do_touchscreen_mapping (GsdXrandrManager *manager)
2217{
2218 GsdXrandrManagerPrivate *priv = manager->priv;
2219 GnomeRRScreen *screen = priv->rw_screen;
2220 GnomeRRConfig *current;
2221 GnomeRROutputInfo *laptop_output;
2222
2223 if (!supports_xinput_devices ())
2224 return;
2225
2226 current = gnome_rr_config_new_current (screen, NULL);
2227 laptop_output = get_mappable_output_info (manager, screen, current);
2228
2229 if (laptop_output == NULL) {
2230 g_debug ("No laptop screen detected");
2231 goto out;
2232 }
2233
2234 if (priv->main_touchscreen_id != -1) {
2235 /* Set initial mapping */
2236 g_debug ("Setting initial touchscreen mapping");
2237 map_touch_to_output (screen,
2238 priv->main_touchscreen_id,
2239 laptop_output);
2240 }
2241 else {
2242 g_debug ("No main touchscreen detected");
2243 }
2244
2245out:
2246 g_object_unref (current);
2247}
2248
2036gboolean2249gboolean
2037gsd_xrandr_manager_start (GsdXrandrManager *manager,2250gsd_xrandr_manager_start (GsdXrandrManager *manager,
2038 GError **error)2251 GError **error)
@@ -2071,6 +2284,11 @@
2071 if (!apply_default_configuration_from_file (manager, GDK_CURRENT_TIME))2284 if (!apply_default_configuration_from_file (manager, GDK_CURRENT_TIME))
2072 apply_default_boot_configuration (manager, GDK_CURRENT_TIME);2285 apply_default_boot_configuration (manager, GDK_CURRENT_TIME);
20732286
2287 /* Initialise touchscreen mapping */
2288 set_touchscreen_id (manager);
2289 if (manager->priv->main_touchscreen_id != -1)
2290 do_touchscreen_mapping (manager);
2291
2074 log_msg ("State of screen after initial configuration:\n");2292 log_msg ("State of screen after initial configuration:\n");
2075 log_screen (manager->priv->rw_screen);2293 log_screen (manager->priv->rw_screen);
20762294
@@ -2127,6 +2345,8 @@
2127 }2345 }
2128#endif /* HAVE_WACOM */2346#endif /* HAVE_WACOM */
21292347
2348 g_free (manager->priv->main_touchscreen_name);
2349
2130 log_open ();2350 log_open ();
2131 log_msg ("STOPPING XRANDR PLUGIN\n------------------------------------------------------------\n");2351 log_msg ("STOPPING XRANDR PLUGIN\n------------------------------------------------------------\n");
2132 log_close ();2352 log_close ();
@@ -2149,6 +2369,10 @@
21492369
2150 manager->priv->current_fn_f7_config = -1;2370 manager->priv->current_fn_f7_config = -1;
2151 manager->priv->fn_f7_configs = NULL;2371 manager->priv->fn_f7_configs = NULL;
2372
2373 /* For touchscreen mapping */
2374 manager->priv->main_touchscreen_id = -1;
2375 manager->priv->main_touchscreen_name = NULL;
2152}2376}
21532377
2154static void2378static void

Subscribers

People subscribed via source and target branches