commit 5ed87d8

Michael Forney  ·  2014-01-20 23:10:29 +0000 UTC
parent 4834576
launch: Add support for {,de}activate events

- Move launch-related code from util.c to launch.c
- Add a launch event signal for session activation and deactivation
  events.
- Add a serial to launch requests so we can correctly process input from
  the launcher.
12 files changed,  +272, -104
+14, -2
 1@@ -57,6 +57,7 @@ pid_t child_pid = -1;
 2 
 3 static struct
 4 {
 5+    int socket;
 6     int input_fds[128];
 7     unsigned num_input_fds;
 8     int drm_fds[16];
 9@@ -163,14 +164,20 @@ static void handle_chld(int signal)
10 
11 static void handle_usr1(int signal)
12 {
13+    struct swc_launch_event event = { .type = SWC_LAUNCH_EVENT_DEACTIVATE };
14+
15     stop_devices(true);
16     ioctl(launcher.tty_fd, VT_RELDISP, 1);
17+    send(launcher.socket, &event, sizeof event, 0);
18 }
19 
20 static void handle_usr2(int signal)
21 {
22+    struct swc_launch_event event = { .type = SWC_LAUNCH_EVENT_ACTIVATE };
23+
24     start_devices();
25     ioctl(launcher.tty_fd, VT_RELDISP, VT_ACKACQ);
26+    send(launcher.socket, &event, sizeof event, 0);
27 }
28 
29 static void forward_signal(int signal)
30@@ -182,8 +189,8 @@ static void handle_socket_data(int socket)
31 {
32     char buffer[BUFSIZ];
33     struct swc_launch_request * request = (void *) &buffer;
34-    struct swc_launch_response response;
35-    int fd;
36+    struct swc_launch_event response;
37+    int fd = -1;
38     struct stat st;
39     ssize_t size;
40 
41@@ -192,6 +199,9 @@ static void handle_socket_data(int socket)
42     if (size == -1 || size == 0)
43         return;
44 
45+    response.type = SWC_LAUNCH_EVENT_RESPONSE;
46+    response.serial = request->serial;
47+
48     switch (request->type)
49     {
50         case SWC_LAUNCH_REQUEST_OPEN_DEVICE:
51@@ -430,6 +440,8 @@ int main(int argc, char * argv[])
52     if (socketpair(AF_LOCAL, SOCK_SEQPACKET, 0, sockets) == -1)
53         die("Could not create socket pair");
54 
55+    launcher.socket = sockets[0];
56+
57     if (fcntl(sockets[0], F_SETFD, FD_CLOEXEC) == -1)
58         die("Could not set CLOEXEC on socket");
59 
+20, -2
 1@@ -2,6 +2,7 @@
 2 #define SWC_LAUNCH_PROTOCOL_H
 3 
 4 #include <stdbool.h>
 5+#include <stdint.h>
 6 #include <sys/types.h>
 7 
 8 #define SWC_LAUNCH_SOCKET_ENV "SWC_LAUNCH_SOCKET"
 9@@ -14,6 +15,9 @@ struct swc_launch_request
10         SWC_LAUNCH_REQUEST_OPEN_DEVICE,
11         SWC_LAUNCH_REQUEST_ACTIVATE_VT
12     } type;
13+
14+    uint32_t serial;
15+
16     union
17     {
18         struct /* OPEN_DEVICE */
19@@ -28,9 +32,23 @@ struct swc_launch_request
20     };
21 };
22 
23-struct swc_launch_response
24+struct swc_launch_event
25 {
26-    bool success;
27+    enum
28+    {
29+        SWC_LAUNCH_EVENT_RESPONSE,
30+        SWC_LAUNCH_EVENT_ACTIVATE,
31+        SWC_LAUNCH_EVENT_DEACTIVATE,
32+    } type;
33+
34+    union
35+    {
36+        struct /* RESPONSE */
37+        {
38+            uint32_t serial;
39+            bool success;
40+        };
41+    };
42 };
43 
44 ssize_t send_fd(int socket, int fd, const void * buffer, ssize_t buffer_size);
+1, -0
1@@ -4,6 +4,7 @@
2 #include "data_device_manager.h"
3 #include "drm.h"
4 #include "internal.h"
5+#include "launch.h"
6 #include "output.h"
7 #include "pointer.h"
8 #include "region.h"
+1, -0
1@@ -24,6 +24,7 @@
2 #include "drm.h"
3 #include "event.h"
4 #include "internal.h"
5+#include "launch.h"
6 #include "output.h"
7 #include "screen.h"
8 #include "util.h"
+2, -1
 1@@ -1,6 +1,6 @@
 2 /* swc: libswc/evdev_device.c
 3  *
 4- * Copyright (c) 2013 Michael Forney
 5+ * Copyright (c) 2013, 2014 Michael Forney
 6  *
 7  * Based in part upon evdev.c from weston, which is:
 8  *
 9@@ -27,6 +27,7 @@
10 
11 #include "evdev_device.h"
12 #include "event.h"
13+#include "launch.h"
14 #include "seat.h"
15 #include "util.h"
16 
+1, -0
1@@ -34,6 +34,7 @@ struct swc
2 
3     struct udev * udev;
4 
5+    struct swc_launch * const launch;
6     const struct swc_seat_global * const seat;
7     const struct swc_bindings_global * const bindings;
8     struct wl_list screens;
+153, -0
  1@@ -0,0 +1,153 @@
  2+/* swc: libswc/launch.c
  3+ *
  4+ * Copyright (c) 2013, 2014 Michael Forney
  5+ *
  6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
  7+ * of this software and associated documentation files (the "Software"), to deal
  8+ * in the Software without restriction, including without limitation the rights
  9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10+ * copies of the Software, and to permit persons to whom the Software is
 11+ * furnished to do so, subject to the following conditions:
 12+ *
 13+ * The above copyright notice and this permission notice shall be included in
 14+ * all copies or substantial portions of the Software.
 15+ *
 16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 22+ * SOFTWARE.
 23+ */
 24+
 25+#include "launch.h"
 26+#include "event.h"
 27+#include "internal.h"
 28+#include "launch/protocol.h"
 29+#include "util.h"
 30+
 31+#include <unistd.h>
 32+#include <wayland-server.h>
 33+
 34+struct swc_launch swc_launch;
 35+
 36+static struct
 37+{
 38+    int socket;
 39+    struct wl_event_source * source;
 40+    uint32_t next_serial;
 41+} launch;
 42+
 43+static bool handle_event(struct swc_launch_event * event)
 44+{
 45+    switch (event->type)
 46+    {
 47+        case SWC_LAUNCH_EVENT_ACTIVATE:
 48+            swc_send_event(&swc.launch->event_signal,
 49+                           SWC_LAUNCH_EVENT_ACTIVATED, NULL);
 50+            break;
 51+        case SWC_LAUNCH_EVENT_DEACTIVATE:
 52+            swc_send_event(&swc.launch->event_signal,
 53+                           SWC_LAUNCH_EVENT_DEACTIVATED, NULL);
 54+            break;
 55+        default: return false;
 56+    }
 57+
 58+    return true;
 59+}
 60+
 61+static int handle_data(int fd, uint32_t mask, void * data)
 62+{
 63+    struct swc_launch_event event;
 64+
 65+    if (receive_fd(fd, NULL, &event, sizeof event) != -1)
 66+        handle_event(&event);
 67+
 68+    return 1;
 69+}
 70+
 71+bool swc_launch_initialize()
 72+{
 73+    char * socket_string, * end;
 74+
 75+    if (!(socket_string = getenv(SWC_LAUNCH_SOCKET_ENV)))
 76+        return false;
 77+
 78+    launch.socket = strtol(socket_string, &end, 10);
 79+
 80+    if (*end != '\0')
 81+        return false;
 82+
 83+    launch.source = wl_event_loop_add_fd(swc.event_loop, launch.socket,
 84+                                         WL_EVENT_READABLE, &handle_data, NULL);
 85+
 86+    if (!launch.source)
 87+        return false;
 88+
 89+    wl_signal_init(&swc.launch->event_signal);
 90+
 91+    return true;
 92+}
 93+
 94+void swc_launch_finalize()
 95+{
 96+    wl_event_source_remove(launch.source);
 97+    close(launch.socket);
 98+}
 99+
100+static bool send_request(struct swc_launch_request * request, size_t size,
101+                         struct swc_launch_event * event,
102+                         int out_fd, int * in_fd)
103+{
104+    request->serial = ++launch.next_serial;
105+
106+    if (send_fd(launch.socket, out_fd, request, size) == -1)
107+        return false;
108+
109+    while (receive_fd(launch.socket, in_fd, event, sizeof *event) != -1)
110+    {
111+        if (event->type == SWC_LAUNCH_EVENT_RESPONSE
112+            && event->serial == request->serial)
113+        {
114+            return true;
115+        }
116+
117+        handle_event(event);
118+    }
119+
120+    return false;
121+}
122+
123+int swc_launch_open_device(const char * path, int flags)
124+{
125+    size_t path_size = strlen(path);
126+    char buffer[sizeof(struct swc_launch_request) + path_size + 1];
127+    struct swc_launch_request * request = (void *) buffer;
128+    struct swc_launch_event response;
129+    int fd;
130+
131+    request->type = SWC_LAUNCH_REQUEST_OPEN_DEVICE;
132+    request->flags = flags;
133+    strcpy(request->path, path);
134+
135+    if (!send_request(request, sizeof buffer, &response, -1, &fd))
136+        return -1;
137+
138+    return fd;
139+}
140+
141+bool swc_launch_activate_vt(unsigned vt)
142+{
143+    struct swc_launch_request request;
144+    struct swc_launch_event response;
145+
146+    request.type = SWC_LAUNCH_REQUEST_ACTIVATE_VT;
147+    request.vt = vt;
148+
149+    if (!send_request(&request, sizeof request, &response, -1, NULL))
150+        return false;
151+
152+    return response.success;
153+}
154+
+48, -0
 1@@ -0,0 +1,48 @@
 2+/* swc: libswc/launch.h
 3+ *
 4+ * Copyright (c) 2013, 2014 Michael Forney
 5+ *
 6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
 7+ * of this software and associated documentation files (the "Software"), to deal
 8+ * in the Software without restriction, including without limitation the rights
 9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+#ifndef SWC_LAUNCH_H
26+#define SWC_LAUNCH_H
27+
28+#include <stdbool.h>
29+#include <wayland-server.h>
30+
31+enum
32+{
33+    SWC_LAUNCH_EVENT_ACTIVATED,
34+    SWC_LAUNCH_EVENT_DEACTIVATED
35+};
36+
37+struct swc_launch
38+{
39+    struct wl_signal event_signal;
40+};
41+
42+bool swc_launch_initialize();
43+void swc_launch_finalize();
44+
45+int swc_launch_open_device(const char * path, int flags);
46+bool swc_launch_activate_vt(unsigned vt);
47+
48+#endif
49+
+1, -0
1@@ -29,6 +29,7 @@ $(dir)_PACKAGES =   \
2     xkbcommon
3 
4 SWC_SOURCES =                       \
5+    libswc/launch.c                 \
6     libswc/compositor.c             \
7     libswc/view.c                   \
8     libswc/buffer.c                 \
+31, -19
  1@@ -27,6 +27,7 @@
  2 #include "data_device_manager.h"
  3 #include "drm.h"
  4 #include "internal.h"
  5+#include "launch.h"
  6 #include "keyboard.h"
  7 #include "pointer.h"
  8 #include "screen.h"
  9@@ -41,6 +42,7 @@
 10 
 11 #include <libudev.h>
 12 
 13+extern struct swc_launch swc_launch;
 14 extern const struct swc_seat_global seat_global;
 15 extern const struct swc_bindings_global bindings_global;
 16 extern struct swc_drm drm_global;
 17@@ -48,6 +50,7 @@ extern struct swc_shm shm_global;
 18 static struct swc_compositor compositor;
 19 
 20 struct swc swc = {
 21+    .launch = &swc_launch,
 22     .seat = &seat_global,
 23     .bindings = &bindings_global,
 24     .compositor = &compositor,
 25@@ -92,65 +95,71 @@ bool swc_initialize(struct wl_display * display,
 26     swc.manager = manager;
 27     const char * default_seat = "seat0";
 28 
 29+    if (!(swc_launch_initialize()))
 30+    {
 31+        ERROR("Could not connect to launch\n");
 32+        goto error0;
 33+    }
 34+
 35     if (!(swc.udev = udev_new()))
 36     {
 37         ERROR("Could not initialize udev\n");
 38-        goto error0;
 39+        goto error1;
 40     }
 41 
 42     if (!swc_drm_initialize(default_seat))
 43     {
 44         ERROR("Could not initialize DRM\n");
 45-        goto error1;
 46+        goto error2;
 47     }
 48 
 49     if (!swc_shm_initialize())
 50     {
 51         ERROR("Could not initialize SHM\n");
 52-        goto error2;
 53+        goto error3;
 54     }
 55 
 56     if (!swc_screens_initialize())
 57     {
 58         ERROR("Could not initialize screens\n");
 59-        goto error3;
 60+        goto error4;
 61     }
 62 
 63     if (!swc_compositor_initialize(&compositor, display, swc.event_loop))
 64     {
 65         ERROR("Could not initialize compositor\n");
 66-        goto error4;
 67+        goto error5;
 68     }
 69 
 70     if (!swc_data_device_manager_initialize())
 71     {
 72         ERROR("Could not initialize data device manager\n");
 73-        goto error5;
 74+        goto error6;
 75     }
 76 
 77     if (!swc_seat_initialize(default_seat))
 78     {
 79         ERROR("Could not initialize seat\n");
 80-        goto error6;
 81+        goto error7;
 82     }
 83 
 84     if (!swc_bindings_initialize())
 85     {
 86         ERROR("Could not initialize bindings\n");
 87-        goto error7;
 88+        goto error8;
 89     }
 90 
 91     if (!swc_shell_initialize())
 92     {
 93         ERROR("Could not initialize shell\n");
 94-        goto error8;
 95+        goto error9;
 96     }
 97 
 98 #ifdef ENABLE_XWAYLAND
 99     if (!swc_xserver_initialize())
100     {
101         ERROR("Could not initialize xwayland\n");
102-        goto error9;
103+        goto error10;
104     }
105 #endif
106 
107@@ -158,24 +167,26 @@ bool swc_initialize(struct wl_display * display,
108 
109     return true;
110 
111-  error9:
112+  error10:
113     swc_shell_finalize();
114-  error8:
115+  error9:
116     swc_bindings_finalize();
117-  error7:
118+  error8:
119     swc_seat_finalize();
120-  error6:
121+  error7:
122     swc_data_device_manager_finalize();
123-  error5:
124+  error6:
125     swc_compositor_finish(&compositor);
126-  error4:
127+  error5:
128     swc_screens_finalize();
129-  error3:
130+  error4:
131     swc_shm_finalize();
132-  error2:
133+  error3:
134     swc_drm_finalize();
135-  error1:
136+  error2:
137     udev_unref(swc.udev);
138+  error1:
139+    swc_launch_finalize();
140   error0:
141     return false;
142 }
143@@ -195,5 +206,6 @@ void swc_finalize()
144     swc_shm_finalize();
145     swc_drm_finalize();
146     udev_unref(swc.udev);
147+    swc_launch_finalize();
148 }
149 
+0, -76
 1@@ -1,11 +1,5 @@
 2 #include "util.h"
 3-#include "launch/protocol.h"
 4 
 5-#include <stdlib.h>
 6-#include <stdio.h>
 7-#include <string.h>
 8-#include <drm.h>
 9-#include <sys/socket.h>
10 #include <wayland-server.h>
11 
12 pixman_box32_t infinite_extents = {
13@@ -18,73 +12,3 @@ void swc_remove_resource(struct wl_resource * resource)
14     wl_list_remove(wl_resource_get_link(resource));
15 }
16 
17-static int get_launcher_socket()
18-{
19-    static int launcher_socket = -1;
20-
21-    if (launcher_socket == -1)
22-    {
23-        char * launcher_socket_name;
24-
25-        if ((launcher_socket_name = getenv(SWC_LAUNCH_SOCKET_ENV)))
26-        {
27-            char * end;
28-
29-            launcher_socket = strtol(launcher_socket_name, &end, 10);
30-            if (*end != '\0')
31-                launcher_socket = -1;
32-        }
33-    }
34-
35-    return launcher_socket;
36-}
37-
38-static bool send_request(const struct swc_launch_request * request, size_t size,
39-                         struct swc_launch_response * response,
40-                         int out_fd, int * in_fd)
41-{
42-    int socket;
43-
44-    socket = get_launcher_socket();
45-
46-    if (send_fd(socket, out_fd, request, size) == -1)
47-        return false;
48-
49-    if (receive_fd(socket, in_fd, &response, sizeof response) == -1)
50-        return false;
51-
52-    return true;
53-}
54-
55-int swc_launch_open_device(const char * path, int flags)
56-{
57-    size_t path_size = strlen(path);
58-    char buffer[sizeof(struct swc_launch_request) + path_size + 1];
59-    struct swc_launch_request * request = (void *) buffer;
60-    struct swc_launch_response response;
61-    int fd;
62-
63-    request->type = SWC_LAUNCH_REQUEST_OPEN_DEVICE;
64-    request->flags = flags;
65-    strcpy(request->path, path);
66-
67-    if (!send_request(request, sizeof buffer, &response, -1, &fd))
68-        return -1;
69-
70-    return fd;
71-}
72-
73-bool swc_launch_activate_vt(unsigned vt)
74-{
75-    struct swc_launch_request request;
76-    struct swc_launch_response response;
77-
78-    request.type = SWC_LAUNCH_REQUEST_ACTIVATE_VT;
79-    request.vt = vt;
80-
81-    if (!send_request(&request, sizeof request, &response, -1, NULL))
82-        return false;
83-
84-    return response.success;
85-}
86-
+0, -4
 1@@ -85,10 +85,6 @@ static inline void swc_array_remove(struct wl_array * array,
 2     array->size -= size;
 3 }
 4 
 5-/* Launch Utilities */
 6-int swc_launch_open_device(const char * path, int flags);
 7-bool swc_launch_activate_vt(unsigned vt);
 8-
 9 /* Double Buffers */
10 struct swc_double_buffer
11 {