Merge lp:~albertomilone/unity-settings-daemon/non-blocking-touch-mapping-trusty into lp:unity-settings-daemon/14.04

Proposed by Alberto Milone
Status: Merged
Approved by: Iain Lane
Approved revision: 4045
Merged at revision: 4044
Proposed branch: lp:~albertomilone/unity-settings-daemon/non-blocking-touch-mapping-trusty
Merge into: lp:unity-settings-daemon/14.04
Diff against target: 231 lines (+156/-18)
1 file modified
plugins/xrandr/gsd-xrandr-manager.c (+156/-18)
To merge this branch: bzr merge lp:~albertomilone/unity-settings-daemon/non-blocking-touch-mapping-trusty
Reviewer Review Type Date Requested Status
Iain Lane Approve
Canonical Desktop Team Pending
Review via email: mp+266249@code.launchpad.net

Commit message

Make touchscreen mapping non-blocking, and kill it if it takes more than 3 seconds; finally, in case of failure, try again after a few seconds. This helps on resume from S3 (LP: #1471708).

Description of the change

Make touchscreen mapping non-blocking, and kill it if it takes more than 3 seconds; finally, in case of failure, try again after a few seconds. This helps on resume from S3 (LP: #1471708).

To post a comment you must log in.
4044. By Alberto Milone

Keep track of processes and retries dinamically

4045. By Alberto Milone

Add whitespaces and remove duplicate message

Revision history for this message
Iain Lane (laney) wrote :

Cool

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/xrandr/gsd-xrandr-manager.c'
2--- plugins/xrandr/gsd-xrandr-manager.c 2014-06-05 11:56:15 +0000
3+++ plugins/xrandr/gsd-xrandr-manager.c 2015-08-25 08:21:03 +0000
4@@ -132,6 +132,13 @@
5 gchar *main_touchscreen_name;
6 };
7
8+typedef struct {
9+ int mapping_pid;
10+ guint mapping_kill_id;
11+ guint mapping_retry_id;
12+ gboolean mapping_killed;
13+} TouchMappingPrivate;
14+
15 static const GnomeRRRotation possible_rotations[] = {
16 GNOME_RR_ROTATION_0,
17 GNOME_RR_ROTATION_90,
18@@ -160,9 +167,14 @@
19
20 static FILE *log_file;
21
22+/* Wait before retrying */
23+static const int RETRY_TIMEOUT = 5;
24+/* Wait before timing out */
25+static const int MAPPING_TIMEOUT = 3;
26+
27 static GnomeRROutput * input_info_find_size_match (GsdXrandrManager *manager, GnomeRRScreen *rr_screen);
28-static int map_touch_to_output (GnomeRRScreen *screen, int device_id, GnomeRROutputInfo *output);
29-static void do_touchscreen_mapping (GsdXrandrManager *manager);
30+static int map_touch_to_output (GsdXrandrManager *manager, GnomeRROutputInfo *output);
31+static gboolean do_touchscreen_mapping (GsdXrandrManager *manager);
32
33 static void
34 log_open (void)
35@@ -2182,37 +2194,163 @@
36 XFreeDeviceList (device_info);
37 }
38
39+/* Kill a mapping process */
40+static gboolean
41+cb_mapping_child_kill (gpointer data)
42+{
43+ int kill_status;
44+
45+ gchar *message = NULL;
46+ TouchMappingPrivate *mapping_data = (TouchMappingPrivate*) data;
47+
48+ message = g_strdup_printf ("Killing touchscreen mapping process %d after %d second(s) timeout...",
49+ mapping_data->mapping_pid, MAPPING_TIMEOUT);
50+
51+ if (!message) {
52+ g_error ("Failed to allocate memory to log the killing of the mapping process");
53+ goto out;
54+ }
55+
56+ g_warning ("%s", message);
57+
58+ g_free (message);
59+
60+ kill_status = kill (mapping_data->mapping_pid, SIGTERM);
61+
62+ /* Mark as killed */
63+ mapping_data->mapping_killed = TRUE;
64+
65+ g_debug ("Kill status %d...", kill_status);
66+
67+ if (kill_status != 0)
68+ g_error ("Failed to kill mapping process: %s", strerror (errno));
69+
70+out:
71+ return G_SOURCE_REMOVE;
72+}
73+
74+/* Clean up spawned processes when they are done */
75+static void
76+cb_mapping_child_watch (GPid pid,
77+ gint status,
78+ gpointer data)
79+{
80+ TouchMappingPrivate *mapping_data = (TouchMappingPrivate*) data;
81+
82+ g_debug ("Cleaning up spawned mapping");
83+
84+ /* Close pid */
85+ g_spawn_close_pid (pid);
86+
87+ /* No need to kill a process that ended */
88+ if (mapping_data->mapping_kill_id > 0) {
89+ g_debug ("Cancelling killing of process that ended");
90+ g_source_remove (mapping_data->mapping_kill_id);
91+ }
92+
93+ /* No need to retry if it succeeded */
94+ if (!mapping_data->mapping_killed) {
95+ g_debug ("Cancelling retry id %d", mapping_data->mapping_retry_id);
96+ g_source_remove (mapping_data->mapping_retry_id);
97+ }
98+
99+ /* Free mapping data */
100+ g_slice_free (TouchMappingPrivate, mapping_data);
101+ mapping_data = NULL;
102+}
103+
104 static int
105-map_touch_to_output (GnomeRRScreen *screen, int device_id,
106- GnomeRROutputInfo *output)
107+map_touch_to_output (GsdXrandrManager *manager, GnomeRROutputInfo *output)
108 {
109- int status = 0;
110- char command[100];
111+ TouchMappingPrivate *mapping_data = NULL;
112+ gchar *command_str = NULL;
113+ GError **error = NULL;
114+ gboolean success = FALSE;
115+ gchar **command = NULL;
116+
117+ GsdXrandrManagerPrivate *priv = manager->priv;
118 gchar *name = gnome_rr_output_info_get_name (output);
119
120 if (!name) {
121 g_debug ("Failure to map screen with missing name");
122- status = 1;
123 goto out;
124 }
125
126- if (gnome_rr_output_info_is_active(output)) {
127+ if (gnome_rr_output_info_is_active (output)) {
128 g_debug ("Mapping touchscreen %d onto output %s",
129- device_id, name);
130- sprintf (command, "xinput --map-to-output %d %s",
131- device_id, name);
132- status = system (command);
133+ priv->main_touchscreen_id, name);
134+
135+ command_str = g_strdup_printf ("/usr/bin/xinput --map-to-output %d %s",
136+ priv->main_touchscreen_id, name);
137+
138+ if (!command_str)
139+ goto out;
140+
141+ if (!g_shell_parse_argv (command_str, NULL, &command, NULL))
142+ goto out;
143+
144+ /* Each spawned process gets its own mapping data */
145+ mapping_data = g_slice_new (TouchMappingPrivate);
146+ if (!mapping_data) {
147+ g_error ("Touchscreen mapping resource allocation failed");
148+ goto out;
149+ }
150+ /* Initialise mapping data */
151+ mapping_data->mapping_pid = -1;
152+ mapping_data->mapping_kill_id = 0;
153+ mapping_data->mapping_retry_id = 0;
154+ mapping_data->mapping_killed = FALSE;
155+
156+ success = g_spawn_async (NULL,
157+ command,
158+ NULL,
159+ G_SPAWN_DO_NOT_REAP_CHILD,
160+ NULL,
161+ NULL,
162+ &(mapping_data->mapping_pid),
163+ error);
164+ g_strfreev (command);
165+
166+ if (success) {
167+ g_debug ("Touchscreen mapping spawn succeeded");
168+
169+ /* Clean up after child is done */
170+ g_child_watch_add (mapping_data->mapping_pid, (GChildWatchFunc) cb_mapping_child_watch,
171+ mapping_data);
172+ /* Kill the child after n seconds */
173+ mapping_data->mapping_kill_id = g_timeout_add_seconds (MAPPING_TIMEOUT,
174+ (GSourceFunc) cb_mapping_child_kill,
175+ mapping_data);
176+ /* Set potential retry */
177+ g_debug ("Retrying in %d second(s)", RETRY_TIMEOUT+MAPPING_TIMEOUT);
178+ mapping_data->mapping_retry_id = g_timeout_add_seconds (RETRY_TIMEOUT+MAPPING_TIMEOUT,
179+ (GSourceFunc) do_touchscreen_mapping,
180+ manager);
181+ g_debug ("Retry id: %d", mapping_data->mapping_retry_id);
182+ }
183+ else {
184+ g_error ("Touchscreen mapping failed");
185+ if (error != NULL)
186+ g_error ("%s", (*error)->message);
187+ g_clear_error (error);
188+
189+ /* Free mapping data */
190+ g_slice_free(TouchMappingPrivate, mapping_data);
191+ mapping_data = NULL;
192+ }
193 }
194 else {
195 g_debug ("No need to map %d onto output %s. The output is off",
196- device_id, name);
197+ priv->main_touchscreen_id, name);
198 }
199
200 out:
201- return (status == 0);
202+ g_free (command_str);
203+
204+ return success;
205 }
206
207-static void
208+static gboolean
209 do_touchscreen_mapping (GsdXrandrManager *manager)
210 {
211 GsdXrandrManagerPrivate *priv = manager->priv;
212@@ -2234,9 +2372,7 @@
213 if (priv->main_touchscreen_id != -1) {
214 /* Set initial mapping */
215 g_debug ("Setting initial touchscreen mapping");
216- map_touch_to_output (screen,
217- priv->main_touchscreen_id,
218- laptop_output);
219+ map_touch_to_output (manager, laptop_output);
220 }
221 else {
222 g_debug ("No main touchscreen detected");
223@@ -2244,6 +2380,8 @@
224
225 out:
226 g_object_unref (current);
227+
228+ return G_SOURCE_REMOVE;
229 }
230
231 gboolean

Subscribers

People subscribed via source and target branches