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
=== modified file 'plugins/xrandr/gsd-xrandr-manager.c'
--- plugins/xrandr/gsd-xrandr-manager.c 2014-06-05 11:56:15 +0000
+++ plugins/xrandr/gsd-xrandr-manager.c 2015-08-25 08:21:03 +0000
@@ -132,6 +132,13 @@
132 gchar *main_touchscreen_name;132 gchar *main_touchscreen_name;
133};133};
134134
135typedef struct {
136 int mapping_pid;
137 guint mapping_kill_id;
138 guint mapping_retry_id;
139 gboolean mapping_killed;
140} TouchMappingPrivate;
141
135static const GnomeRRRotation possible_rotations[] = {142static const GnomeRRRotation possible_rotations[] = {
136 GNOME_RR_ROTATION_0,143 GNOME_RR_ROTATION_0,
137 GNOME_RR_ROTATION_90,144 GNOME_RR_ROTATION_90,
@@ -160,9 +167,14 @@
160167
161static FILE *log_file;168static FILE *log_file;
162169
170/* Wait before retrying */
171static const int RETRY_TIMEOUT = 5;
172/* Wait before timing out */
173static const int MAPPING_TIMEOUT = 3;
174
163static GnomeRROutput * input_info_find_size_match (GsdXrandrManager *manager, GnomeRRScreen *rr_screen);175static GnomeRROutput * input_info_find_size_match (GsdXrandrManager *manager, GnomeRRScreen *rr_screen);
164static int map_touch_to_output (GnomeRRScreen *screen, int device_id, GnomeRROutputInfo *output);176static int map_touch_to_output (GsdXrandrManager *manager, GnomeRROutputInfo *output);
165static void do_touchscreen_mapping (GsdXrandrManager *manager);177static gboolean do_touchscreen_mapping (GsdXrandrManager *manager);
166178
167static void179static void
168log_open (void)180log_open (void)
@@ -2182,37 +2194,163 @@
2182 XFreeDeviceList (device_info);2194 XFreeDeviceList (device_info);
2183}2195}
21842196
2197/* Kill a mapping process */
2198static gboolean
2199cb_mapping_child_kill (gpointer data)
2200{
2201 int kill_status;
2202
2203 gchar *message = NULL;
2204 TouchMappingPrivate *mapping_data = (TouchMappingPrivate*) data;
2205
2206 message = g_strdup_printf ("Killing touchscreen mapping process %d after %d second(s) timeout...",
2207 mapping_data->mapping_pid, MAPPING_TIMEOUT);
2208
2209 if (!message) {
2210 g_error ("Failed to allocate memory to log the killing of the mapping process");
2211 goto out;
2212 }
2213
2214 g_warning ("%s", message);
2215
2216 g_free (message);
2217
2218 kill_status = kill (mapping_data->mapping_pid, SIGTERM);
2219
2220 /* Mark as killed */
2221 mapping_data->mapping_killed = TRUE;
2222
2223 g_debug ("Kill status %d...", kill_status);
2224
2225 if (kill_status != 0)
2226 g_error ("Failed to kill mapping process: %s", strerror (errno));
2227
2228out:
2229 return G_SOURCE_REMOVE;
2230}
2231
2232/* Clean up spawned processes when they are done */
2233static void
2234cb_mapping_child_watch (GPid pid,
2235 gint status,
2236 gpointer data)
2237{
2238 TouchMappingPrivate *mapping_data = (TouchMappingPrivate*) data;
2239
2240 g_debug ("Cleaning up spawned mapping");
2241
2242 /* Close pid */
2243 g_spawn_close_pid (pid);
2244
2245 /* No need to kill a process that ended */
2246 if (mapping_data->mapping_kill_id > 0) {
2247 g_debug ("Cancelling killing of process that ended");
2248 g_source_remove (mapping_data->mapping_kill_id);
2249 }
2250
2251 /* No need to retry if it succeeded */
2252 if (!mapping_data->mapping_killed) {
2253 g_debug ("Cancelling retry id %d", mapping_data->mapping_retry_id);
2254 g_source_remove (mapping_data->mapping_retry_id);
2255 }
2256
2257 /* Free mapping data */
2258 g_slice_free (TouchMappingPrivate, mapping_data);
2259 mapping_data = NULL;
2260}
2261
2185static int2262static int
2186map_touch_to_output (GnomeRRScreen *screen, int device_id,2263map_touch_to_output (GsdXrandrManager *manager, GnomeRROutputInfo *output)
2187 GnomeRROutputInfo *output)
2188{2264{
2189 int status = 0;2265 TouchMappingPrivate *mapping_data = NULL;
2190 char command[100];2266 gchar *command_str = NULL;
2267 GError **error = NULL;
2268 gboolean success = FALSE;
2269 gchar **command = NULL;
2270
2271 GsdXrandrManagerPrivate *priv = manager->priv;
2191 gchar *name = gnome_rr_output_info_get_name (output);2272 gchar *name = gnome_rr_output_info_get_name (output);
21922273
2193 if (!name) {2274 if (!name) {
2194 g_debug ("Failure to map screen with missing name");2275 g_debug ("Failure to map screen with missing name");
2195 status = 1;
2196 goto out;2276 goto out;
2197 }2277 }
21982278
2199 if (gnome_rr_output_info_is_active(output)) {2279 if (gnome_rr_output_info_is_active (output)) {
2200 g_debug ("Mapping touchscreen %d onto output %s",2280 g_debug ("Mapping touchscreen %d onto output %s",
2201 device_id, name);2281 priv->main_touchscreen_id, name);
2202 sprintf (command, "xinput --map-to-output %d %s",2282
2203 device_id, name);2283 command_str = g_strdup_printf ("/usr/bin/xinput --map-to-output %d %s",
2204 status = system (command);2284 priv->main_touchscreen_id, name);
2285
2286 if (!command_str)
2287 goto out;
2288
2289 if (!g_shell_parse_argv (command_str, NULL, &command, NULL))
2290 goto out;
2291
2292 /* Each spawned process gets its own mapping data */
2293 mapping_data = g_slice_new (TouchMappingPrivate);
2294 if (!mapping_data) {
2295 g_error ("Touchscreen mapping resource allocation failed");
2296 goto out;
2297 }
2298 /* Initialise mapping data */
2299 mapping_data->mapping_pid = -1;
2300 mapping_data->mapping_kill_id = 0;
2301 mapping_data->mapping_retry_id = 0;
2302 mapping_data->mapping_killed = FALSE;
2303
2304 success = g_spawn_async (NULL,
2305 command,
2306 NULL,
2307 G_SPAWN_DO_NOT_REAP_CHILD,
2308 NULL,
2309 NULL,
2310 &(mapping_data->mapping_pid),
2311 error);
2312 g_strfreev (command);
2313
2314 if (success) {
2315 g_debug ("Touchscreen mapping spawn succeeded");
2316
2317 /* Clean up after child is done */
2318 g_child_watch_add (mapping_data->mapping_pid, (GChildWatchFunc) cb_mapping_child_watch,
2319 mapping_data);
2320 /* Kill the child after n seconds */
2321 mapping_data->mapping_kill_id = g_timeout_add_seconds (MAPPING_TIMEOUT,
2322 (GSourceFunc) cb_mapping_child_kill,
2323 mapping_data);
2324 /* Set potential retry */
2325 g_debug ("Retrying in %d second(s)", RETRY_TIMEOUT+MAPPING_TIMEOUT);
2326 mapping_data->mapping_retry_id = g_timeout_add_seconds (RETRY_TIMEOUT+MAPPING_TIMEOUT,
2327 (GSourceFunc) do_touchscreen_mapping,
2328 manager);
2329 g_debug ("Retry id: %d", mapping_data->mapping_retry_id);
2330 }
2331 else {
2332 g_error ("Touchscreen mapping failed");
2333 if (error != NULL)
2334 g_error ("%s", (*error)->message);
2335 g_clear_error (error);
2336
2337 /* Free mapping data */
2338 g_slice_free(TouchMappingPrivate, mapping_data);
2339 mapping_data = NULL;
2340 }
2205 }2341 }
2206 else {2342 else {
2207 g_debug ("No need to map %d onto output %s. The output is off",2343 g_debug ("No need to map %d onto output %s. The output is off",
2208 device_id, name);2344 priv->main_touchscreen_id, name);
2209 }2345 }
22102346
2211out:2347out:
2212 return (status == 0);2348 g_free (command_str);
2349
2350 return success;
2213}2351}
22142352
2215static void2353static gboolean
2216do_touchscreen_mapping (GsdXrandrManager *manager)2354do_touchscreen_mapping (GsdXrandrManager *manager)
2217{2355{
2218 GsdXrandrManagerPrivate *priv = manager->priv;2356 GsdXrandrManagerPrivate *priv = manager->priv;
@@ -2234,9 +2372,7 @@
2234 if (priv->main_touchscreen_id != -1) {2372 if (priv->main_touchscreen_id != -1) {
2235 /* Set initial mapping */2373 /* Set initial mapping */
2236 g_debug ("Setting initial touchscreen mapping");2374 g_debug ("Setting initial touchscreen mapping");
2237 map_touch_to_output (screen,2375 map_touch_to_output (manager, laptop_output);
2238 priv->main_touchscreen_id,
2239 laptop_output);
2240 }2376 }
2241 else {2377 else {
2242 g_debug ("No main touchscreen detected");2378 g_debug ("No main touchscreen detected");
@@ -2244,6 +2380,8 @@
22442380
2245out:2381out:
2246 g_object_unref (current);2382 g_object_unref (current);
2383
2384 return G_SOURCE_REMOVE;
2247}2385}
22482386
2249gboolean2387gboolean

Subscribers

People subscribed via source and target branches