diff options
Diffstat (limited to 'sway/server.c')
-rw-r--r-- | sway/server.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/sway/server.c b/sway/server.c new file mode 100644 index 00000000..c1125f14 --- /dev/null +++ b/sway/server.c | |||
@@ -0,0 +1,141 @@ | |||
1 | #define _POSIX_C_SOURCE 200112L | ||
2 | #include <assert.h> | ||
3 | #include <stdbool.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <wayland-server.h> | ||
6 | #include <wlr/backend.h> | ||
7 | #include <wlr/backend/session.h> | ||
8 | #include <wlr/render/wlr_renderer.h> | ||
9 | #include <wlr/types/wlr_compositor.h> | ||
10 | #include <wlr/types/wlr_gamma_control.h> | ||
11 | #include <wlr/types/wlr_linux_dmabuf.h> | ||
12 | #include <wlr/types/wlr_layer_shell.h> | ||
13 | #include <wlr/types/wlr_primary_selection.h> | ||
14 | #include <wlr/types/wlr_screenshooter.h> | ||
15 | #include <wlr/types/wlr_server_decoration.h> | ||
16 | #include <wlr/types/wlr_xcursor_manager.h> | ||
17 | #include <wlr/types/wlr_xdg_output.h> | ||
18 | #include <wlr/types/wlr_wl_shell.h> | ||
19 | #include <wlr/util/log.h> | ||
20 | // TODO WLR: make Xwayland optional | ||
21 | #include <wlr/xwayland.h> | ||
22 | #include "sway/commands.h" | ||
23 | #include "sway/config.h" | ||
24 | #include "sway/input/input-manager.h" | ||
25 | #include "sway/server.h" | ||
26 | #include "sway/tree/layout.h" | ||
27 | |||
28 | static void server_ready(struct wl_listener *listener, void *data) { | ||
29 | wlr_log(L_DEBUG, "Compositor is ready, executing cmds in queue"); | ||
30 | // Execute commands until there are none left | ||
31 | config->active = true; | ||
32 | while (config->cmd_queue->length) { | ||
33 | char *line = config->cmd_queue->items[0]; | ||
34 | struct cmd_results *res = execute_command(line, NULL); | ||
35 | if (res->status != CMD_SUCCESS) { | ||
36 | wlr_log(L_ERROR, "Error on line '%s': %s", line, res->error); | ||
37 | } | ||
38 | free_cmd_results(res); | ||
39 | free(line); | ||
40 | list_del(config->cmd_queue, 0); | ||
41 | } | ||
42 | } | ||
43 | |||
44 | bool server_init(struct sway_server *server) { | ||
45 | wlr_log(L_DEBUG, "Initializing Wayland server"); | ||
46 | |||
47 | server->wl_display = wl_display_create(); | ||
48 | server->wl_event_loop = wl_display_get_event_loop(server->wl_display); | ||
49 | server->backend = wlr_backend_autocreate(server->wl_display); | ||
50 | |||
51 | struct wlr_renderer *renderer = wlr_backend_get_renderer(server->backend); | ||
52 | assert(renderer); | ||
53 | |||
54 | wl_display_init_shm(server->wl_display); | ||
55 | |||
56 | server->compositor = wlr_compositor_create(server->wl_display, renderer); | ||
57 | server->data_device_manager = | ||
58 | wlr_data_device_manager_create(server->wl_display); | ||
59 | |||
60 | wlr_screenshooter_create(server->wl_display); | ||
61 | wlr_gamma_control_manager_create(server->wl_display); | ||
62 | wlr_primary_selection_device_manager_create(server->wl_display); | ||
63 | |||
64 | server->new_output.notify = handle_new_output; | ||
65 | wl_signal_add(&server->backend->events.new_output, &server->new_output); | ||
66 | |||
67 | wlr_xdg_output_manager_create(server->wl_display, | ||
68 | root_container.sway_root->output_layout); | ||
69 | |||
70 | server->layer_shell = wlr_layer_shell_create(server->wl_display); | ||
71 | wl_signal_add(&server->layer_shell->events.new_surface, | ||
72 | &server->layer_shell_surface); | ||
73 | server->layer_shell_surface.notify = handle_layer_shell_surface; | ||
74 | |||
75 | server->xdg_shell_v6 = wlr_xdg_shell_v6_create(server->wl_display); | ||
76 | wl_signal_add(&server->xdg_shell_v6->events.new_surface, | ||
77 | &server->xdg_shell_v6_surface); | ||
78 | server->xdg_shell_v6_surface.notify = handle_xdg_shell_v6_surface; | ||
79 | |||
80 | server->wl_shell = wlr_wl_shell_create(server->wl_display); | ||
81 | wl_signal_add(&server->wl_shell->events.new_surface, | ||
82 | &server->wl_shell_surface); | ||
83 | server->wl_shell_surface.notify = handle_wl_shell_surface; | ||
84 | |||
85 | // TODO make xwayland optional | ||
86 | server->xwayland = | ||
87 | wlr_xwayland_create(server->wl_display, server->compositor); | ||
88 | wl_signal_add(&server->xwayland->events.new_surface, | ||
89 | &server->xwayland_surface); | ||
90 | server->xwayland_surface.notify = handle_xwayland_surface; | ||
91 | wl_signal_add(&server->xwayland->events.ready, | ||
92 | &server->xwayland_ready); | ||
93 | // TODO: call server_ready now if xwayland is not enabled | ||
94 | server->xwayland_ready.notify = server_ready; | ||
95 | |||
96 | // TODO: configurable cursor theme and size | ||
97 | server->xcursor_manager = wlr_xcursor_manager_create(NULL, 24); | ||
98 | wlr_xcursor_manager_load(server->xcursor_manager, 1); | ||
99 | struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( | ||
100 | server->xcursor_manager, "left_ptr", 1); | ||
101 | if (xcursor != NULL) { | ||
102 | struct wlr_xcursor_image *image = xcursor->images[0]; | ||
103 | wlr_xwayland_set_cursor(server->xwayland, image->buffer, | ||
104 | image->width * 4, image->width, image->height, image->hotspot_x, | ||
105 | image->hotspot_y); | ||
106 | } | ||
107 | |||
108 | // TODO: Integration with sway borders | ||
109 | struct wlr_server_decoration_manager *deco_manager = | ||
110 | wlr_server_decoration_manager_create(server->wl_display); | ||
111 | wlr_server_decoration_manager_set_default_mode( | ||
112 | deco_manager, WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); | ||
113 | |||
114 | wlr_linux_dmabuf_create(server->wl_display, renderer); | ||
115 | |||
116 | server->socket = wl_display_add_socket_auto(server->wl_display); | ||
117 | if (!server->socket) { | ||
118 | wlr_log(L_ERROR, "Unable to open wayland socket"); | ||
119 | wlr_backend_destroy(server->backend); | ||
120 | return false; | ||
121 | } | ||
122 | |||
123 | input_manager = input_manager_create(server); | ||
124 | return true; | ||
125 | } | ||
126 | |||
127 | void server_fini(struct sway_server *server) { | ||
128 | // TODO | ||
129 | } | ||
130 | |||
131 | void server_run(struct sway_server *server) { | ||
132 | wlr_log(L_INFO, "Running compositor on wayland display '%s'", | ||
133 | server->socket); | ||
134 | setenv("WAYLAND_DISPLAY", server->socket, true); | ||
135 | if (!wlr_backend_start(server->backend)) { | ||
136 | wlr_log(L_ERROR, "Failed to start backend"); | ||
137 | wlr_backend_destroy(server->backend); | ||
138 | return; | ||
139 | } | ||
140 | wl_display_run(server->wl_display); | ||
141 | } | ||