diff options
Diffstat (limited to 'sway/server.c')
-rw-r--r-- | sway/server.c | 338 |
1 files changed, 292 insertions, 46 deletions
diff --git a/sway/server.c b/sway/server.c index f51fcfe2..180d3a6b 100644 --- a/sway/server.c +++ b/sway/server.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <stdbool.h> | 2 | #include <stdbool.h> |
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
@@ -7,25 +6,45 @@ | |||
7 | #include <wlr/backend.h> | 6 | #include <wlr/backend.h> |
8 | #include <wlr/backend/headless.h> | 7 | #include <wlr/backend/headless.h> |
9 | #include <wlr/backend/multi.h> | 8 | #include <wlr/backend/multi.h> |
10 | #include <wlr/backend/noop.h> | 9 | #include <wlr/config.h> |
11 | #include <wlr/backend/session.h> | 10 | #include <wlr/render/allocator.h> |
12 | #include <wlr/render/wlr_renderer.h> | 11 | #include <wlr/render/wlr_renderer.h> |
13 | #include <wlr/types/wlr_compositor.h> | 12 | #include <wlr/types/wlr_compositor.h> |
13 | #include <wlr/types/wlr_content_type_v1.h> | ||
14 | #include <wlr/types/wlr_cursor_shape_v1.h> | ||
14 | #include <wlr/types/wlr_data_control_v1.h> | 15 | #include <wlr/types/wlr_data_control_v1.h> |
16 | #include <wlr/types/wlr_data_device.h> | ||
17 | #include <wlr/types/wlr_drm.h> | ||
15 | #include <wlr/types/wlr_export_dmabuf_v1.h> | 18 | #include <wlr/types/wlr_export_dmabuf_v1.h> |
19 | #include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h> | ||
20 | #include <wlr/types/wlr_foreign_toplevel_management_v1.h> | ||
21 | #include <wlr/types/wlr_fractional_scale_v1.h> | ||
16 | #include <wlr/types/wlr_gamma_control_v1.h> | 22 | #include <wlr/types/wlr_gamma_control_v1.h> |
17 | #include <wlr/types/wlr_idle.h> | 23 | #include <wlr/types/wlr_idle_notify_v1.h> |
18 | #include <wlr/types/wlr_layer_shell_v1.h> | 24 | #include <wlr/types/wlr_layer_shell_v1.h> |
25 | #include <wlr/types/wlr_linux_dmabuf_v1.h> | ||
26 | #include <wlr/types/wlr_output_management_v1.h> | ||
27 | #include <wlr/types/wlr_output_power_management_v1.h> | ||
19 | #include <wlr/types/wlr_pointer_constraints_v1.h> | 28 | #include <wlr/types/wlr_pointer_constraints_v1.h> |
29 | #include <wlr/types/wlr_presentation_time.h> | ||
20 | #include <wlr/types/wlr_primary_selection_v1.h> | 30 | #include <wlr/types/wlr_primary_selection_v1.h> |
21 | #include <wlr/types/wlr_relative_pointer_v1.h> | 31 | #include <wlr/types/wlr_relative_pointer_v1.h> |
22 | #include <wlr/types/wlr_screencopy_v1.h> | 32 | #include <wlr/types/wlr_screencopy_v1.h> |
33 | #include <wlr/types/wlr_security_context_v1.h> | ||
23 | #include <wlr/types/wlr_server_decoration.h> | 34 | #include <wlr/types/wlr_server_decoration.h> |
35 | #include <wlr/types/wlr_session_lock_v1.h> | ||
36 | #include <wlr/types/wlr_single_pixel_buffer_v1.h> | ||
37 | #include <wlr/types/wlr_subcompositor.h> | ||
24 | #include <wlr/types/wlr_tablet_v2.h> | 38 | #include <wlr/types/wlr_tablet_v2.h> |
25 | #include <wlr/types/wlr_viewporter.h> | 39 | #include <wlr/types/wlr_viewporter.h> |
26 | #include <wlr/types/wlr_xcursor_manager.h> | 40 | #include <wlr/types/wlr_xcursor_manager.h> |
41 | #include <wlr/types/wlr_xdg_activation_v1.h> | ||
27 | #include <wlr/types/wlr_xdg_decoration_v1.h> | 42 | #include <wlr/types/wlr_xdg_decoration_v1.h> |
43 | #include <wlr/types/wlr_xdg_foreign_registry.h> | ||
44 | #include <wlr/types/wlr_xdg_foreign_v1.h> | ||
45 | #include <wlr/types/wlr_xdg_foreign_v2.h> | ||
28 | #include <wlr/types/wlr_xdg_output_v1.h> | 46 | #include <wlr/types/wlr_xdg_output_v1.h> |
47 | #include <xf86drm.h> | ||
29 | #include "config.h" | 48 | #include "config.h" |
30 | #include "list.h" | 49 | #include "list.h" |
31 | #include "log.h" | 50 | #include "log.h" |
@@ -34,41 +53,221 @@ | |||
34 | #include "sway/input/input-manager.h" | 53 | #include "sway/input/input-manager.h" |
35 | #include "sway/output.h" | 54 | #include "sway/output.h" |
36 | #include "sway/server.h" | 55 | #include "sway/server.h" |
56 | #include "sway/input/cursor.h" | ||
37 | #include "sway/tree/root.h" | 57 | #include "sway/tree/root.h" |
58 | |||
38 | #if HAVE_XWAYLAND | 59 | #if HAVE_XWAYLAND |
60 | #include <wlr/xwayland/shell.h> | ||
39 | #include "sway/xwayland.h" | 61 | #include "sway/xwayland.h" |
40 | #endif | 62 | #endif |
41 | 63 | ||
42 | bool server_privileged_prepare(struct sway_server *server) { | 64 | #if WLR_HAS_DRM_BACKEND |
43 | sway_log(SWAY_DEBUG, "Preparing Wayland server initialization"); | 65 | #include <wlr/types/wlr_drm_lease_v1.h> |
66 | #endif | ||
67 | |||
68 | #define SWAY_XDG_SHELL_VERSION 5 | ||
69 | #define SWAY_LAYER_SHELL_VERSION 4 | ||
70 | #define SWAY_FOREIGN_TOPLEVEL_LIST_VERSION 1 | ||
71 | |||
72 | bool allow_unsupported_gpu = false; | ||
73 | |||
74 | #if WLR_HAS_DRM_BACKEND | ||
75 | static void handle_drm_lease_request(struct wl_listener *listener, void *data) { | ||
76 | /* We only offer non-desktop outputs, but in the future we might want to do | ||
77 | * more logic here. */ | ||
78 | |||
79 | struct wlr_drm_lease_request_v1 *req = data; | ||
80 | struct wlr_drm_lease_v1 *lease = wlr_drm_lease_request_v1_grant(req); | ||
81 | if (!lease) { | ||
82 | sway_log(SWAY_ERROR, "Failed to grant lease request"); | ||
83 | wlr_drm_lease_request_v1_reject(req); | ||
84 | } | ||
85 | } | ||
86 | #endif | ||
87 | |||
88 | static bool is_privileged(const struct wl_global *global) { | ||
89 | #if WLR_HAS_DRM_BACKEND | ||
90 | if (server.drm_lease_manager != NULL) { | ||
91 | struct wlr_drm_lease_device_v1 *drm_lease_dev; | ||
92 | wl_list_for_each(drm_lease_dev, &server.drm_lease_manager->devices, link) { | ||
93 | if (drm_lease_dev->global == global) { | ||
94 | return true; | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | #endif | ||
99 | |||
100 | return | ||
101 | global == server.output_manager_v1->global || | ||
102 | global == server.output_power_manager_v1->global || | ||
103 | global == server.input_method->global || | ||
104 | global == server.foreign_toplevel_list->global || | ||
105 | global == server.foreign_toplevel_manager->global || | ||
106 | global == server.data_control_manager_v1->global || | ||
107 | global == server.screencopy_manager_v1->global || | ||
108 | global == server.export_dmabuf_manager_v1->global || | ||
109 | global == server.security_context_manager_v1->global || | ||
110 | global == server.gamma_control_manager_v1->global || | ||
111 | global == server.layer_shell->global || | ||
112 | global == server.session_lock.manager->global || | ||
113 | global == server.input->keyboard_shortcuts_inhibit->global || | ||
114 | global == server.input->virtual_keyboard->global || | ||
115 | global == server.input->virtual_pointer->global || | ||
116 | global == server.input->transient_seat_manager->global; | ||
117 | } | ||
118 | |||
119 | static bool filter_global(const struct wl_client *client, | ||
120 | const struct wl_global *global, void *data) { | ||
121 | #if HAVE_XWAYLAND | ||
122 | struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland; | ||
123 | if (xwayland && global == xwayland->shell_v1->global) { | ||
124 | return xwayland->server != NULL && client == xwayland->server->client; | ||
125 | } | ||
126 | #endif | ||
127 | |||
128 | // Restrict usage of privileged protocols to unsandboxed clients | ||
129 | // TODO: add a way for users to configure an allow-list | ||
130 | const struct wlr_security_context_v1_state *security_context = | ||
131 | wlr_security_context_manager_v1_lookup_client( | ||
132 | server.security_context_manager_v1, (struct wl_client *)client); | ||
133 | if (is_privileged(global)) { | ||
134 | return security_context == NULL; | ||
135 | } | ||
136 | |||
137 | return true; | ||
138 | } | ||
139 | |||
140 | static void detect_proprietary(struct wlr_backend *backend, void *data) { | ||
141 | int drm_fd = wlr_backend_get_drm_fd(backend); | ||
142 | if (drm_fd < 0) { | ||
143 | return; | ||
144 | } | ||
145 | |||
146 | drmVersion *version = drmGetVersion(drm_fd); | ||
147 | if (version == NULL) { | ||
148 | sway_log(SWAY_ERROR, "drmGetVersion() failed"); | ||
149 | return; | ||
150 | } | ||
151 | |||
152 | bool is_unsupported = false; | ||
153 | if (strcmp(version->name, "nvidia-drm") == 0) { | ||
154 | is_unsupported = true; | ||
155 | sway_log(SWAY_ERROR, "!!! Proprietary Nvidia drivers are in use !!!"); | ||
156 | if (!allow_unsupported_gpu) { | ||
157 | sway_log(SWAY_ERROR, "Use Nouveau instead"); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | if (strcmp(version->name, "evdi") == 0) { | ||
162 | is_unsupported = true; | ||
163 | sway_log(SWAY_ERROR, "!!! Proprietary DisplayLink drivers are in use !!!"); | ||
164 | } | ||
165 | |||
166 | if (!allow_unsupported_gpu && is_unsupported) { | ||
167 | sway_log(SWAY_ERROR, | ||
168 | "Proprietary drivers are NOT supported. To launch sway anyway, " | ||
169 | "launch with --unsupported-gpu and DO NOT report issues."); | ||
170 | exit(EXIT_FAILURE); | ||
171 | } | ||
172 | |||
173 | drmFreeVersion(version); | ||
174 | } | ||
175 | |||
176 | static void handle_renderer_lost(struct wl_listener *listener, void *data) { | ||
177 | struct sway_server *server = wl_container_of(listener, server, renderer_lost); | ||
178 | |||
179 | sway_log(SWAY_INFO, "Re-creating renderer after GPU reset"); | ||
180 | |||
181 | struct wlr_renderer *renderer = wlr_renderer_autocreate(server->backend); | ||
182 | if (renderer == NULL) { | ||
183 | sway_log(SWAY_ERROR, "Unable to create renderer"); | ||
184 | return; | ||
185 | } | ||
186 | |||
187 | struct wlr_allocator *allocator = | ||
188 | wlr_allocator_autocreate(server->backend, renderer); | ||
189 | if (allocator == NULL) { | ||
190 | sway_log(SWAY_ERROR, "Unable to create allocator"); | ||
191 | wlr_renderer_destroy(renderer); | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | struct wlr_renderer *old_renderer = server->renderer; | ||
196 | struct wlr_allocator *old_allocator = server->allocator; | ||
197 | server->renderer = renderer; | ||
198 | server->allocator = allocator; | ||
199 | |||
200 | wl_list_remove(&server->renderer_lost.link); | ||
201 | wl_signal_add(&server->renderer->events.lost, &server->renderer_lost); | ||
202 | |||
203 | wlr_compositor_set_renderer(server->compositor, renderer); | ||
204 | |||
205 | for (int i = 0; i < root->outputs->length; ++i) { | ||
206 | struct sway_output *output = root->outputs->items[i]; | ||
207 | wlr_output_init_render(output->wlr_output, | ||
208 | server->allocator, server->renderer); | ||
209 | } | ||
210 | |||
211 | wlr_allocator_destroy(old_allocator); | ||
212 | wlr_renderer_destroy(old_renderer); | ||
213 | } | ||
214 | |||
215 | bool server_init(struct sway_server *server) { | ||
216 | sway_log(SWAY_DEBUG, "Initializing Wayland server"); | ||
44 | server->wl_display = wl_display_create(); | 217 | server->wl_display = wl_display_create(); |
45 | server->wl_event_loop = wl_display_get_event_loop(server->wl_display); | 218 | server->wl_event_loop = wl_display_get_event_loop(server->wl_display); |
46 | server->backend = wlr_backend_autocreate(server->wl_display); | ||
47 | 219 | ||
220 | wl_display_set_global_filter(server->wl_display, filter_global, NULL); | ||
221 | |||
222 | root = root_create(server->wl_display); | ||
223 | |||
224 | server->backend = wlr_backend_autocreate(server->wl_event_loop, &server->session); | ||
48 | if (!server->backend) { | 225 | if (!server->backend) { |
49 | sway_log(SWAY_ERROR, "Unable to create backend"); | 226 | sway_log(SWAY_ERROR, "Unable to create backend"); |
50 | return false; | 227 | return false; |
51 | } | 228 | } |
52 | return true; | ||
53 | } | ||
54 | 229 | ||
55 | bool server_init(struct sway_server *server) { | 230 | wlr_multi_for_each_backend(server->backend, detect_proprietary, NULL); |
56 | sway_log(SWAY_DEBUG, "Initializing Wayland server"); | ||
57 | 231 | ||
58 | struct wlr_renderer *renderer = wlr_backend_get_renderer(server->backend); | 232 | server->renderer = wlr_renderer_autocreate(server->backend); |
59 | assert(renderer); | 233 | if (!server->renderer) { |
234 | sway_log(SWAY_ERROR, "Failed to create renderer"); | ||
235 | return false; | ||
236 | } | ||
60 | 237 | ||
61 | wlr_renderer_init_wl_display(renderer, server->wl_display); | 238 | server->renderer_lost.notify = handle_renderer_lost; |
239 | wl_signal_add(&server->renderer->events.lost, &server->renderer_lost); | ||
62 | 240 | ||
63 | server->compositor = wlr_compositor_create(server->wl_display, renderer); | 241 | wlr_renderer_init_wl_shm(server->renderer, server->wl_display); |
64 | server->compositor_new_surface.notify = handle_compositor_new_surface; | 242 | |
65 | wl_signal_add(&server->compositor->events.new_surface, | 243 | if (wlr_renderer_get_texture_formats(server->renderer, WLR_BUFFER_CAP_DMABUF) != NULL) { |
66 | &server->compositor_new_surface); | 244 | server->linux_dmabuf_v1 = wlr_linux_dmabuf_v1_create_with_renderer( |
245 | server->wl_display, 4, server->renderer); | ||
246 | if (debug.legacy_wl_drm) { | ||
247 | wlr_drm_create(server->wl_display, server->renderer); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | server->allocator = wlr_allocator_autocreate(server->backend, | ||
252 | server->renderer); | ||
253 | if (!server->allocator) { | ||
254 | sway_log(SWAY_ERROR, "Failed to create allocator"); | ||
255 | return false; | ||
256 | } | ||
257 | |||
258 | server->compositor = wlr_compositor_create(server->wl_display, 6, | ||
259 | server->renderer); | ||
260 | |||
261 | wlr_subcompositor_create(server->wl_display); | ||
67 | 262 | ||
68 | server->data_device_manager = | 263 | server->data_device_manager = |
69 | wlr_data_device_manager_create(server->wl_display); | 264 | wlr_data_device_manager_create(server->wl_display); |
70 | 265 | ||
71 | wlr_gamma_control_manager_v1_create(server->wl_display); | 266 | server->gamma_control_manager_v1 = |
267 | wlr_gamma_control_manager_v1_create(server->wl_display); | ||
268 | server->gamma_control_set_gamma.notify = handle_gamma_control_set_gamma; | ||
269 | wl_signal_add(&server->gamma_control_manager_v1->events.set_gamma, | ||
270 | &server->gamma_control_set_gamma); | ||
72 | 271 | ||
73 | server->new_output.notify = handle_new_output; | 272 | server->new_output.notify = handle_new_output; |
74 | wl_signal_add(&server->backend->events.new_output, &server->new_output); | 273 | wl_signal_add(&server->backend->events.new_output, &server->new_output); |
@@ -78,19 +277,20 @@ bool server_init(struct sway_server *server) { | |||
78 | 277 | ||
79 | wlr_xdg_output_manager_v1_create(server->wl_display, root->output_layout); | 278 | wlr_xdg_output_manager_v1_create(server->wl_display, root->output_layout); |
80 | 279 | ||
81 | server->idle = wlr_idle_create(server->wl_display); | 280 | server->idle_notifier_v1 = wlr_idle_notifier_v1_create(server->wl_display); |
82 | server->idle_inhibit_manager_v1 = | 281 | sway_idle_inhibit_manager_v1_init(); |
83 | sway_idle_inhibit_manager_v1_create(server->wl_display, server->idle); | ||
84 | 282 | ||
85 | server->layer_shell = wlr_layer_shell_v1_create(server->wl_display); | 283 | server->layer_shell = wlr_layer_shell_v1_create(server->wl_display, |
284 | SWAY_LAYER_SHELL_VERSION); | ||
86 | wl_signal_add(&server->layer_shell->events.new_surface, | 285 | wl_signal_add(&server->layer_shell->events.new_surface, |
87 | &server->layer_shell_surface); | 286 | &server->layer_shell_surface); |
88 | server->layer_shell_surface.notify = handle_layer_shell_surface; | 287 | server->layer_shell_surface.notify = handle_layer_shell_surface; |
89 | 288 | ||
90 | server->xdg_shell = wlr_xdg_shell_create(server->wl_display); | 289 | server->xdg_shell = wlr_xdg_shell_create(server->wl_display, |
91 | wl_signal_add(&server->xdg_shell->events.new_surface, | 290 | SWAY_XDG_SHELL_VERSION); |
92 | &server->xdg_shell_surface); | 291 | wl_signal_add(&server->xdg_shell->events.new_toplevel, |
93 | server->xdg_shell_surface.notify = handle_xdg_shell_surface; | 292 | &server->xdg_shell_toplevel); |
293 | server->xdg_shell_toplevel.notify = handle_xdg_shell_toplevel; | ||
94 | 294 | ||
95 | server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); | 295 | server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); |
96 | 296 | ||
@@ -121,8 +321,7 @@ bool server_init(struct sway_server *server) { | |||
121 | wl_signal_add(&server->pointer_constraints->events.new_constraint, | 321 | wl_signal_add(&server->pointer_constraints->events.new_constraint, |
122 | &server->pointer_constraint); | 322 | &server->pointer_constraint); |
123 | 323 | ||
124 | server->presentation = | 324 | wlr_presentation_create(server->wl_display, server->backend); |
125 | wlr_presentation_create(server->wl_display, server->backend); | ||
126 | 325 | ||
127 | server->output_manager_v1 = | 326 | server->output_manager_v1 = |
128 | wlr_output_manager_v1_create(server->wl_display); | 327 | wlr_output_manager_v1_create(server->wl_display); |
@@ -141,19 +340,62 @@ bool server_init(struct sway_server *server) { | |||
141 | &server->output_power_manager_set_mode); | 340 | &server->output_power_manager_set_mode); |
142 | server->input_method = wlr_input_method_manager_v2_create(server->wl_display); | 341 | server->input_method = wlr_input_method_manager_v2_create(server->wl_display); |
143 | server->text_input = wlr_text_input_manager_v3_create(server->wl_display); | 342 | server->text_input = wlr_text_input_manager_v3_create(server->wl_display); |
343 | server->foreign_toplevel_list = | ||
344 | wlr_ext_foreign_toplevel_list_v1_create(server->wl_display, SWAY_FOREIGN_TOPLEVEL_LIST_VERSION); | ||
144 | server->foreign_toplevel_manager = | 345 | server->foreign_toplevel_manager = |
145 | wlr_foreign_toplevel_manager_v1_create(server->wl_display); | 346 | wlr_foreign_toplevel_manager_v1_create(server->wl_display); |
146 | 347 | ||
147 | wlr_export_dmabuf_manager_v1_create(server->wl_display); | 348 | sway_session_lock_init(); |
148 | wlr_screencopy_manager_v1_create(server->wl_display); | 349 | |
149 | wlr_data_control_manager_v1_create(server->wl_display); | 350 | #if WLR_HAS_DRM_BACKEND |
150 | wlr_primary_selection_v1_device_manager_create(server->wl_display); | 351 | server->drm_lease_manager= |
352 | wlr_drm_lease_v1_manager_create(server->wl_display, server->backend); | ||
353 | if (server->drm_lease_manager) { | ||
354 | server->drm_lease_request.notify = handle_drm_lease_request; | ||
355 | wl_signal_add(&server->drm_lease_manager->events.request, | ||
356 | &server->drm_lease_request); | ||
357 | } else { | ||
358 | sway_log(SWAY_DEBUG, "Failed to create wlr_drm_lease_device_v1"); | ||
359 | sway_log(SWAY_INFO, "VR will not be available"); | ||
360 | } | ||
361 | #endif | ||
362 | |||
363 | server->export_dmabuf_manager_v1 = wlr_export_dmabuf_manager_v1_create(server->wl_display); | ||
364 | server->screencopy_manager_v1 = wlr_screencopy_manager_v1_create(server->wl_display); | ||
365 | server->data_control_manager_v1 = wlr_data_control_manager_v1_create(server->wl_display); | ||
366 | server->security_context_manager_v1 = wlr_security_context_manager_v1_create(server->wl_display); | ||
151 | wlr_viewporter_create(server->wl_display); | 367 | wlr_viewporter_create(server->wl_display); |
368 | wlr_single_pixel_buffer_manager_v1_create(server->wl_display); | ||
369 | server->content_type_manager_v1 = | ||
370 | wlr_content_type_manager_v1_create(server->wl_display, 1); | ||
371 | wlr_fractional_scale_manager_v1_create(server->wl_display, 1); | ||
372 | |||
373 | struct wlr_xdg_foreign_registry *foreign_registry = | ||
374 | wlr_xdg_foreign_registry_create(server->wl_display); | ||
375 | wlr_xdg_foreign_v1_create(server->wl_display, foreign_registry); | ||
376 | wlr_xdg_foreign_v2_create(server->wl_display, foreign_registry); | ||
377 | |||
378 | server->xdg_activation_v1 = wlr_xdg_activation_v1_create(server->wl_display); | ||
379 | server->xdg_activation_v1_request_activate.notify = | ||
380 | xdg_activation_v1_handle_request_activate; | ||
381 | wl_signal_add(&server->xdg_activation_v1->events.request_activate, | ||
382 | &server->xdg_activation_v1_request_activate); | ||
383 | server->xdg_activation_v1_new_token.notify = | ||
384 | xdg_activation_v1_handle_new_token; | ||
385 | wl_signal_add(&server->xdg_activation_v1->events.new_token, | ||
386 | &server->xdg_activation_v1_new_token); | ||
387 | |||
388 | struct wlr_cursor_shape_manager_v1 *cursor_shape_manager = | ||
389 | wlr_cursor_shape_manager_v1_create(server->wl_display, 1); | ||
390 | server->request_set_cursor_shape.notify = handle_request_set_cursor_shape; | ||
391 | wl_signal_add(&cursor_shape_manager->events.request_set_shape, &server->request_set_cursor_shape); | ||
392 | |||
393 | wl_list_init(&server->pending_launcher_ctxs); | ||
152 | 394 | ||
153 | // Avoid using "wayland-0" as display socket | 395 | // Avoid using "wayland-0" as display socket |
154 | char name_candidate[16]; | 396 | char name_candidate[16]; |
155 | for (int i = 1; i <= 32; ++i) { | 397 | for (unsigned int i = 1; i <= 32; ++i) { |
156 | sprintf(name_candidate, "wayland-%d", i); | 398 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%u", i); |
157 | if (wl_display_add_socket(server->wl_display, name_candidate) >= 0) { | 399 | if (wl_display_add_socket(server->wl_display, name_candidate) >= 0) { |
158 | server->socket = strdup(name_candidate); | 400 | server->socket = strdup(name_candidate); |
159 | break; | 401 | break; |
@@ -166,27 +408,26 @@ bool server_init(struct sway_server *server) { | |||
166 | return false; | 408 | return false; |
167 | } | 409 | } |
168 | 410 | ||
169 | server->noop_backend = wlr_noop_backend_create(server->wl_display); | 411 | server->headless_backend = wlr_headless_backend_create(server->wl_event_loop); |
170 | |||
171 | struct wlr_output *wlr_output = wlr_noop_add_output(server->noop_backend); | ||
172 | root->noop_output = output_create(wlr_output); | ||
173 | |||
174 | server->headless_backend = | ||
175 | wlr_headless_backend_create_with_renderer(server->wl_display, renderer); | ||
176 | if (!server->headless_backend) { | 412 | if (!server->headless_backend) { |
177 | sway_log(SWAY_INFO, "Failed to create secondary headless backend, " | 413 | sway_log(SWAY_ERROR, "Failed to create secondary headless backend"); |
178 | "starting without it"); | 414 | wlr_backend_destroy(server->backend); |
415 | return false; | ||
179 | } else { | 416 | } else { |
180 | wlr_multi_backend_add(server->backend, server->headless_backend); | 417 | wlr_multi_backend_add(server->backend, server->headless_backend); |
181 | } | 418 | } |
182 | 419 | ||
420 | struct wlr_output *wlr_output = | ||
421 | wlr_headless_add_output(server->headless_backend, 800, 600); | ||
422 | wlr_output_set_name(wlr_output, "FALLBACK"); | ||
423 | root->fallback_output = output_create(wlr_output); | ||
424 | |||
183 | // This may have been set already via -Dtxn-timeout | 425 | // This may have been set already via -Dtxn-timeout |
184 | if (!server->txn_timeout_ms) { | 426 | if (!server->txn_timeout_ms) { |
185 | server->txn_timeout_ms = 200; | 427 | server->txn_timeout_ms = 200; |
186 | } | 428 | } |
187 | 429 | ||
188 | server->dirty_nodes = create_list(); | 430 | server->dirty_nodes = create_list(); |
189 | server->transactions = create_list(); | ||
190 | 431 | ||
191 | server->input = input_manager_create(server); | 432 | server->input = input_manager_create(server); |
192 | input_manager_get_default_seat(); // create seat0 | 433 | input_manager_get_default_seat(); // create seat0 |
@@ -200,9 +441,9 @@ void server_fini(struct sway_server *server) { | |||
200 | wlr_xwayland_destroy(server->xwayland.wlr_xwayland); | 441 | wlr_xwayland_destroy(server->xwayland.wlr_xwayland); |
201 | #endif | 442 | #endif |
202 | wl_display_destroy_clients(server->wl_display); | 443 | wl_display_destroy_clients(server->wl_display); |
444 | wlr_backend_destroy(server->backend); | ||
203 | wl_display_destroy(server->wl_display); | 445 | wl_display_destroy(server->wl_display); |
204 | list_free(server->dirty_nodes); | 446 | list_free(server->dirty_nodes); |
205 | list_free(server->transactions); | ||
206 | } | 447 | } |
207 | 448 | ||
208 | bool server_start(struct sway_server *server) { | 449 | bool server_start(struct sway_server *server) { |
@@ -231,6 +472,10 @@ bool server_start(struct sway_server *server) { | |||
231 | } | 472 | } |
232 | #endif | 473 | #endif |
233 | 474 | ||
475 | if (config->primary_selection) { | ||
476 | wlr_primary_selection_v1_device_manager_create(server->wl_display); | ||
477 | } | ||
478 | |||
234 | sway_log(SWAY_INFO, "Starting backend on wayland display '%s'", | 479 | sway_log(SWAY_INFO, "Starting backend on wayland display '%s'", |
235 | server->socket); | 480 | server->socket); |
236 | if (!wlr_backend_start(server->backend)) { | 481 | if (!wlr_backend_start(server->backend)) { |
@@ -238,6 +483,7 @@ bool server_start(struct sway_server *server) { | |||
238 | wlr_backend_destroy(server->backend); | 483 | wlr_backend_destroy(server->backend); |
239 | return false; | 484 | return false; |
240 | } | 485 | } |
486 | |||
241 | return true; | 487 | return true; |
242 | } | 488 | } |
243 | 489 | ||