swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit 5ed87d81348e1512cffa24df3543275a3b078d3e
parent 483457622a0b31c0e4a59e4426594db0bb159d49
Author: Michael Forney <mforney@mforney.org>
Date:   Mon, 20 Jan 2014 15:10:29 -0800

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.

Diffstat:
Mlaunch/launch.c | 16++++++++++++++--
Mlaunch/protocol.h | 22++++++++++++++++++++--
Mlibswc/compositor.c | 1+
Mlibswc/drm.c | 1+
Mlibswc/evdev_device.c | 3++-
Mlibswc/internal.h | 1+
Alibswc/launch.c | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibswc/launch.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Mlibswc/local.mk | 1+
Mlibswc/swc.c | 50+++++++++++++++++++++++++++++++-------------------
Mlibswc/util.c | 76----------------------------------------------------------------------------
Mlibswc/util.h | 4----
12 files changed, 272 insertions(+), 104 deletions(-)

diff --git a/launch/launch.c b/launch/launch.c @@ -57,6 +57,7 @@ pid_t child_pid = -1; static struct { + int socket; int input_fds[128]; unsigned num_input_fds; int drm_fds[16]; @@ -163,14 +164,20 @@ static void handle_chld(int signal) static void handle_usr1(int signal) { + struct swc_launch_event event = { .type = SWC_LAUNCH_EVENT_DEACTIVATE }; + stop_devices(true); ioctl(launcher.tty_fd, VT_RELDISP, 1); + send(launcher.socket, &event, sizeof event, 0); } static void handle_usr2(int signal) { + struct swc_launch_event event = { .type = SWC_LAUNCH_EVENT_ACTIVATE }; + start_devices(); ioctl(launcher.tty_fd, VT_RELDISP, VT_ACKACQ); + send(launcher.socket, &event, sizeof event, 0); } static void forward_signal(int signal) @@ -182,8 +189,8 @@ static void handle_socket_data(int socket) { char buffer[BUFSIZ]; struct swc_launch_request * request = (void *) &buffer; - struct swc_launch_response response; - int fd; + struct swc_launch_event response; + int fd = -1; struct stat st; ssize_t size; @@ -192,6 +199,9 @@ static void handle_socket_data(int socket) if (size == -1 || size == 0) return; + response.type = SWC_LAUNCH_EVENT_RESPONSE; + response.serial = request->serial; + switch (request->type) { case SWC_LAUNCH_REQUEST_OPEN_DEVICE: @@ -430,6 +440,8 @@ int main(int argc, char * argv[]) if (socketpair(AF_LOCAL, SOCK_SEQPACKET, 0, sockets) == -1) die("Could not create socket pair"); + launcher.socket = sockets[0]; + if (fcntl(sockets[0], F_SETFD, FD_CLOEXEC) == -1) die("Could not set CLOEXEC on socket"); diff --git a/launch/protocol.h b/launch/protocol.h @@ -2,6 +2,7 @@ #define SWC_LAUNCH_PROTOCOL_H #include <stdbool.h> +#include <stdint.h> #include <sys/types.h> #define SWC_LAUNCH_SOCKET_ENV "SWC_LAUNCH_SOCKET" @@ -14,6 +15,9 @@ struct swc_launch_request SWC_LAUNCH_REQUEST_OPEN_DEVICE, SWC_LAUNCH_REQUEST_ACTIVATE_VT } type; + + uint32_t serial; + union { struct /* OPEN_DEVICE */ @@ -28,9 +32,23 @@ struct swc_launch_request }; }; -struct swc_launch_response +struct swc_launch_event { - bool success; + enum + { + SWC_LAUNCH_EVENT_RESPONSE, + SWC_LAUNCH_EVENT_ACTIVATE, + SWC_LAUNCH_EVENT_DEACTIVATE, + } type; + + union + { + struct /* RESPONSE */ + { + uint32_t serial; + bool success; + }; + }; }; ssize_t send_fd(int socket, int fd, const void * buffer, ssize_t buffer_size); diff --git a/libswc/compositor.c b/libswc/compositor.c @@ -4,6 +4,7 @@ #include "data_device_manager.h" #include "drm.h" #include "internal.h" +#include "launch.h" #include "output.h" #include "pointer.h" #include "region.h" diff --git a/libswc/drm.c b/libswc/drm.c @@ -24,6 +24,7 @@ #include "drm.h" #include "event.h" #include "internal.h" +#include "launch.h" #include "output.h" #include "screen.h" #include "util.h" diff --git a/libswc/evdev_device.c b/libswc/evdev_device.c @@ -1,6 +1,6 @@ /* swc: libswc/evdev_device.c * - * Copyright (c) 2013 Michael Forney + * Copyright (c) 2013, 2014 Michael Forney * * Based in part upon evdev.c from weston, which is: * @@ -27,6 +27,7 @@ #include "evdev_device.h" #include "event.h" +#include "launch.h" #include "seat.h" #include "util.h" diff --git a/libswc/internal.h b/libswc/internal.h @@ -34,6 +34,7 @@ struct swc struct udev * udev; + struct swc_launch * const launch; const struct swc_seat_global * const seat; const struct swc_bindings_global * const bindings; struct wl_list screens; diff --git a/libswc/launch.c b/libswc/launch.c @@ -0,0 +1,153 @@ +/* swc: libswc/launch.c + * + * Copyright (c) 2013, 2014 Michael Forney + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "launch.h" +#include "event.h" +#include "internal.h" +#include "launch/protocol.h" +#include "util.h" + +#include <unistd.h> +#include <wayland-server.h> + +struct swc_launch swc_launch; + +static struct +{ + int socket; + struct wl_event_source * source; + uint32_t next_serial; +} launch; + +static bool handle_event(struct swc_launch_event * event) +{ + switch (event->type) + { + case SWC_LAUNCH_EVENT_ACTIVATE: + swc_send_event(&swc.launch->event_signal, + SWC_LAUNCH_EVENT_ACTIVATED, NULL); + break; + case SWC_LAUNCH_EVENT_DEACTIVATE: + swc_send_event(&swc.launch->event_signal, + SWC_LAUNCH_EVENT_DEACTIVATED, NULL); + break; + default: return false; + } + + return true; +} + +static int handle_data(int fd, uint32_t mask, void * data) +{ + struct swc_launch_event event; + + if (receive_fd(fd, NULL, &event, sizeof event) != -1) + handle_event(&event); + + return 1; +} + +bool swc_launch_initialize() +{ + char * socket_string, * end; + + if (!(socket_string = getenv(SWC_LAUNCH_SOCKET_ENV))) + return false; + + launch.socket = strtol(socket_string, &end, 10); + + if (*end != '\0') + return false; + + launch.source = wl_event_loop_add_fd(swc.event_loop, launch.socket, + WL_EVENT_READABLE, &handle_data, NULL); + + if (!launch.source) + return false; + + wl_signal_init(&swc.launch->event_signal); + + return true; +} + +void swc_launch_finalize() +{ + wl_event_source_remove(launch.source); + close(launch.socket); +} + +static bool send_request(struct swc_launch_request * request, size_t size, + struct swc_launch_event * event, + int out_fd, int * in_fd) +{ + request->serial = ++launch.next_serial; + + if (send_fd(launch.socket, out_fd, request, size) == -1) + return false; + + while (receive_fd(launch.socket, in_fd, event, sizeof *event) != -1) + { + if (event->type == SWC_LAUNCH_EVENT_RESPONSE + && event->serial == request->serial) + { + return true; + } + + handle_event(event); + } + + return false; +} + +int swc_launch_open_device(const char * path, int flags) +{ + size_t path_size = strlen(path); + char buffer[sizeof(struct swc_launch_request) + path_size + 1]; + struct swc_launch_request * request = (void *) buffer; + struct swc_launch_event response; + int fd; + + request->type = SWC_LAUNCH_REQUEST_OPEN_DEVICE; + request->flags = flags; + strcpy(request->path, path); + + if (!send_request(request, sizeof buffer, &response, -1, &fd)) + return -1; + + return fd; +} + +bool swc_launch_activate_vt(unsigned vt) +{ + struct swc_launch_request request; + struct swc_launch_event response; + + request.type = SWC_LAUNCH_REQUEST_ACTIVATE_VT; + request.vt = vt; + + if (!send_request(&request, sizeof request, &response, -1, NULL)) + return false; + + return response.success; +} + diff --git a/libswc/launch.h b/libswc/launch.h @@ -0,0 +1,48 @@ +/* swc: libswc/launch.h + * + * Copyright (c) 2013, 2014 Michael Forney + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef SWC_LAUNCH_H +#define SWC_LAUNCH_H + +#include <stdbool.h> +#include <wayland-server.h> + +enum +{ + SWC_LAUNCH_EVENT_ACTIVATED, + SWC_LAUNCH_EVENT_DEACTIVATED +}; + +struct swc_launch +{ + struct wl_signal event_signal; +}; + +bool swc_launch_initialize(); +void swc_launch_finalize(); + +int swc_launch_open_device(const char * path, int flags); +bool swc_launch_activate_vt(unsigned vt); + +#endif + diff --git a/libswc/local.mk b/libswc/local.mk @@ -29,6 +29,7 @@ $(dir)_PACKAGES = \ xkbcommon SWC_SOURCES = \ + libswc/launch.c \ libswc/compositor.c \ libswc/view.c \ libswc/buffer.c \ diff --git a/libswc/swc.c b/libswc/swc.c @@ -27,6 +27,7 @@ #include "data_device_manager.h" #include "drm.h" #include "internal.h" +#include "launch.h" #include "keyboard.h" #include "pointer.h" #include "screen.h" @@ -41,6 +42,7 @@ #include <libudev.h> +extern struct swc_launch swc_launch; extern const struct swc_seat_global seat_global; extern const struct swc_bindings_global bindings_global; extern struct swc_drm drm_global; @@ -48,6 +50,7 @@ extern struct swc_shm shm_global; static struct swc_compositor compositor; struct swc swc = { + .launch = &swc_launch, .seat = &seat_global, .bindings = &bindings_global, .compositor = &compositor, @@ -92,65 +95,71 @@ bool swc_initialize(struct wl_display * display, swc.manager = manager; const char * default_seat = "seat0"; + if (!(swc_launch_initialize())) + { + ERROR("Could not connect to launch\n"); + goto error0; + } + if (!(swc.udev = udev_new())) { ERROR("Could not initialize udev\n"); - goto error0; + goto error1; } if (!swc_drm_initialize(default_seat)) { ERROR("Could not initialize DRM\n"); - goto error1; + goto error2; } if (!swc_shm_initialize()) { ERROR("Could not initialize SHM\n"); - goto error2; + goto error3; } if (!swc_screens_initialize()) { ERROR("Could not initialize screens\n"); - goto error3; + goto error4; } if (!swc_compositor_initialize(&compositor, display, swc.event_loop)) { ERROR("Could not initialize compositor\n"); - goto error4; + goto error5; } if (!swc_data_device_manager_initialize()) { ERROR("Could not initialize data device manager\n"); - goto error5; + goto error6; } if (!swc_seat_initialize(default_seat)) { ERROR("Could not initialize seat\n"); - goto error6; + goto error7; } if (!swc_bindings_initialize()) { ERROR("Could not initialize bindings\n"); - goto error7; + goto error8; } if (!swc_shell_initialize()) { ERROR("Could not initialize shell\n"); - goto error8; + goto error9; } #ifdef ENABLE_XWAYLAND if (!swc_xserver_initialize()) { ERROR("Could not initialize xwayland\n"); - goto error9; + goto error10; } #endif @@ -158,24 +167,26 @@ bool swc_initialize(struct wl_display * display, return true; - error9: + error10: swc_shell_finalize(); - error8: + error9: swc_bindings_finalize(); - error7: + error8: swc_seat_finalize(); - error6: + error7: swc_data_device_manager_finalize(); - error5: + error6: swc_compositor_finish(&compositor); - error4: + error5: swc_screens_finalize(); - error3: + error4: swc_shm_finalize(); - error2: + error3: swc_drm_finalize(); - error1: + error2: udev_unref(swc.udev); + error1: + swc_launch_finalize(); error0: return false; } @@ -195,5 +206,6 @@ void swc_finalize() swc_shm_finalize(); swc_drm_finalize(); udev_unref(swc.udev); + swc_launch_finalize(); } diff --git a/libswc/util.c b/libswc/util.c @@ -1,11 +1,5 @@ #include "util.h" -#include "launch/protocol.h" -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <drm.h> -#include <sys/socket.h> #include <wayland-server.h> pixman_box32_t infinite_extents = { @@ -18,73 +12,3 @@ void swc_remove_resource(struct wl_resource * resource) wl_list_remove(wl_resource_get_link(resource)); } -static int get_launcher_socket() -{ - static int launcher_socket = -1; - - if (launcher_socket == -1) - { - char * launcher_socket_name; - - if ((launcher_socket_name = getenv(SWC_LAUNCH_SOCKET_ENV))) - { - char * end; - - launcher_socket = strtol(launcher_socket_name, &end, 10); - if (*end != '\0') - launcher_socket = -1; - } - } - - return launcher_socket; -} - -static bool send_request(const struct swc_launch_request * request, size_t size, - struct swc_launch_response * response, - int out_fd, int * in_fd) -{ - int socket; - - socket = get_launcher_socket(); - - if (send_fd(socket, out_fd, request, size) == -1) - return false; - - if (receive_fd(socket, in_fd, &response, sizeof response) == -1) - return false; - - return true; -} - -int swc_launch_open_device(const char * path, int flags) -{ - size_t path_size = strlen(path); - char buffer[sizeof(struct swc_launch_request) + path_size + 1]; - struct swc_launch_request * request = (void *) buffer; - struct swc_launch_response response; - int fd; - - request->type = SWC_LAUNCH_REQUEST_OPEN_DEVICE; - request->flags = flags; - strcpy(request->path, path); - - if (!send_request(request, sizeof buffer, &response, -1, &fd)) - return -1; - - return fd; -} - -bool swc_launch_activate_vt(unsigned vt) -{ - struct swc_launch_request request; - struct swc_launch_response response; - - request.type = SWC_LAUNCH_REQUEST_ACTIVATE_VT; - request.vt = vt; - - if (!send_request(&request, sizeof request, &response, -1, NULL)) - return false; - - return response.success; -} - diff --git a/libswc/util.h b/libswc/util.h @@ -85,10 +85,6 @@ static inline void swc_array_remove(struct wl_array * array, array->size -= size; } -/* Launch Utilities */ -int swc_launch_open_device(const char * path, int flags); -bool swc_launch_activate_vt(unsigned vt); - /* Double Buffers */ struct swc_double_buffer {