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 {