Switch to use safe_strtoint instead of strtol
[platform/upstream/weston.git] / compositor / main.c
1 /*
2  * Copyright © 2010-2011 Intel Corporation
3  * Copyright © 2008-2011 Kristian Høgsberg
4  * Copyright © 2012-2015 Collabora, Ltd.
5  * Copyright © 2010-2011 Benjamin Franzke
6  * Copyright © 2013 Jason Ekstrand
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining
9  * a copy of this software and associated documentation files (the
10  * "Software"), to deal in the Software without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Software, and to
13  * permit persons to whom the Software is furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice and this permission notice (including the
17  * next paragraph) shall be included in all copies or substantial
18  * portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  * SOFTWARE.
28  */
29
30 #include "config.h"
31
32 #include <unistd.h>
33 #include <signal.h>
34 #include <errno.h>
35 #include <dlfcn.h>
36 #include <stdint.h>
37 #include <string.h>
38 #include <sys/utsname.h>
39 #include <sys/stat.h>
40 #include <sys/wait.h>
41 #include <sys/socket.h>
42 #include <libinput.h>
43 #include <sys/time.h>
44 #include <linux/limits.h>
45
46 #ifdef HAVE_LIBUNWIND
47 #define UNW_LOCAL_ONLY
48 #include <libunwind.h>
49 #endif
50
51 #include "weston.h"
52 #include "compositor.h"
53 #include "../shared/os-compatibility.h"
54 #include "../shared/helpers.h"
55 #include "../shared/string-helpers.h"
56 #include "git-version.h"
57 #include "version.h"
58 #include "weston.h"
59
60 #include "compositor-drm.h"
61 #include "compositor-headless.h"
62 #include "compositor-rdp.h"
63 #include "compositor-fbdev.h"
64 #include "compositor-x11.h"
65 #include "compositor-wayland.h"
66
67 #define WINDOW_TITLE "Weston Compositor"
68
69 struct wet_compositor {
70         struct weston_config *config;
71 };
72
73 static FILE *weston_logfile = NULL;
74
75 static int cached_tm_mday = -1;
76
77 static int weston_log_timestamp(void)
78 {
79         struct timeval tv;
80         struct tm *brokendown_time;
81         char string[128];
82
83         gettimeofday(&tv, NULL);
84
85         brokendown_time = localtime(&tv.tv_sec);
86         if (brokendown_time == NULL)
87                 return fprintf(weston_logfile, "[(NULL)localtime] ");
88
89         if (brokendown_time->tm_mday != cached_tm_mday) {
90                 strftime(string, sizeof string, "%Y-%m-%d %Z", brokendown_time);
91                 fprintf(weston_logfile, "Date: %s\n", string);
92
93                 cached_tm_mday = brokendown_time->tm_mday;
94         }
95
96         strftime(string, sizeof string, "%H:%M:%S", brokendown_time);
97
98         return fprintf(weston_logfile, "[%s.%03li] ", string, tv.tv_usec/1000);
99 }
100
101 static void
102 custom_handler(const char *fmt, va_list arg)
103 {
104         weston_log_timestamp();
105         fprintf(weston_logfile, "libwayland: ");
106         vfprintf(weston_logfile, fmt, arg);
107 }
108
109 static void
110 weston_log_file_open(const char *filename)
111 {
112         wl_log_set_handler_server(custom_handler);
113
114         if (filename != NULL) {
115                 weston_logfile = fopen(filename, "a");
116                 if (weston_logfile)
117                         os_fd_set_cloexec(fileno(weston_logfile));
118         }
119
120         if (weston_logfile == NULL)
121                 weston_logfile = stderr;
122         else
123                 setvbuf(weston_logfile, NULL, _IOLBF, 256);
124 }
125
126 static void
127 weston_log_file_close(void)
128 {
129         if ((weston_logfile != stderr) && (weston_logfile != NULL))
130                 fclose(weston_logfile);
131         weston_logfile = stderr;
132 }
133
134 static int
135 vlog(const char *fmt, va_list ap)
136 {
137         int l;
138
139         l = weston_log_timestamp();
140         l += vfprintf(weston_logfile, fmt, ap);
141
142         return l;
143 }
144
145 static int
146 vlog_continue(const char *fmt, va_list argp)
147 {
148         return vfprintf(weston_logfile, fmt, argp);
149 }
150
151 static struct wl_list child_process_list;
152 static struct weston_compositor *segv_compositor;
153
154 static int
155 sigchld_handler(int signal_number, void *data)
156 {
157         struct weston_process *p;
158         int status;
159         pid_t pid;
160
161         while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
162                 wl_list_for_each(p, &child_process_list, link) {
163                         if (p->pid == pid)
164                                 break;
165                 }
166
167                 if (&p->link == &child_process_list) {
168                         weston_log("unknown child process exited\n");
169                         continue;
170                 }
171
172                 wl_list_remove(&p->link);
173                 p->cleanup(p, status);
174         }
175
176         if (pid < 0 && errno != ECHILD)
177                 weston_log("waitpid error %m\n");
178
179         return 1;
180 }
181
182 #ifdef HAVE_LIBUNWIND
183
184 static void
185 print_backtrace(void)
186 {
187         unw_cursor_t cursor;
188         unw_context_t context;
189         unw_word_t off;
190         unw_proc_info_t pip;
191         int ret, i = 0;
192         char procname[256];
193         const char *filename;
194         Dl_info dlinfo;
195
196         pip.unwind_info = NULL;
197         ret = unw_getcontext(&context);
198         if (ret) {
199                 weston_log("unw_getcontext: %d\n", ret);
200                 return;
201         }
202
203         ret = unw_init_local(&cursor, &context);
204         if (ret) {
205                 weston_log("unw_init_local: %d\n", ret);
206                 return;
207         }
208
209         ret = unw_step(&cursor);
210         while (ret > 0) {
211                 ret = unw_get_proc_info(&cursor, &pip);
212                 if (ret) {
213                         weston_log("unw_get_proc_info: %d\n", ret);
214                         break;
215                 }
216
217                 ret = unw_get_proc_name(&cursor, procname, 256, &off);
218                 if (ret && ret != -UNW_ENOMEM) {
219                         if (ret != -UNW_EUNSPEC)
220                                 weston_log("unw_get_proc_name: %d\n", ret);
221                         procname[0] = '?';
222                         procname[1] = 0;
223                 }
224
225                 if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&
226                     *dlinfo.dli_fname)
227                         filename = dlinfo.dli_fname;
228                 else
229                         filename = "?";
230
231                 weston_log("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
232                            ret == -UNW_ENOMEM ? "..." : "", (int)off, (void *)(pip.start_ip + off));
233
234                 ret = unw_step(&cursor);
235                 if (ret < 0)
236                         weston_log("unw_step: %d\n", ret);
237         }
238 }
239
240 #else
241
242 static void
243 print_backtrace(void)
244 {
245         void *buffer[32];
246         int i, count;
247         Dl_info info;
248
249         count = backtrace(buffer, ARRAY_LENGTH(buffer));
250         for (i = 0; i < count; i++) {
251                 dladdr(buffer[i], &info);
252                 weston_log("  [%016lx]  %s  (%s)\n",
253                         (long) buffer[i],
254                         info.dli_sname ? info.dli_sname : "--",
255                         info.dli_fname);
256         }
257 }
258
259 #endif
260
261 static void
262 child_client_exec(int sockfd, const char *path)
263 {
264         int clientfd;
265         char s[32];
266         sigset_t allsigs;
267
268         /* do not give our signal mask to the new process */
269         sigfillset(&allsigs);
270         sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
271
272         /* Launch clients as the user. Do not lauch clients with wrong euid.*/
273         if (seteuid(getuid()) == -1) {
274                 weston_log("compositor: failed seteuid\n");
275                 return;
276         }
277
278         /* SOCK_CLOEXEC closes both ends, so we dup the fd to get a
279          * non-CLOEXEC fd to pass through exec. */
280         clientfd = dup(sockfd);
281         if (clientfd == -1) {
282                 weston_log("compositor: dup failed: %m\n");
283                 return;
284         }
285
286         snprintf(s, sizeof s, "%d", clientfd);
287         setenv("WAYLAND_SOCKET", s, 1);
288
289         if (execl(path, path, NULL) < 0)
290                 weston_log("compositor: executing '%s' failed: %m\n",
291                         path);
292 }
293
294 WL_EXPORT struct wl_client *
295 weston_client_launch(struct weston_compositor *compositor,
296                      struct weston_process *proc,
297                      const char *path,
298                      weston_process_cleanup_func_t cleanup)
299 {
300         int sv[2];
301         pid_t pid;
302         struct wl_client *client;
303
304         weston_log("launching '%s'\n", path);
305
306         if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
307                 weston_log("weston_client_launch: "
308                         "socketpair failed while launching '%s': %m\n",
309                         path);
310                 return NULL;
311         }
312
313         pid = fork();
314         if (pid == -1) {
315                 close(sv[0]);
316                 close(sv[1]);
317                 weston_log("weston_client_launch: "
318                         "fork failed while launching '%s': %m\n", path);
319                 return NULL;
320         }
321
322         if (pid == 0) {
323                 child_client_exec(sv[1], path);
324                 _exit(-1);
325         }
326
327         close(sv[1]);
328
329         client = wl_client_create(compositor->wl_display, sv[0]);
330         if (!client) {
331                 close(sv[0]);
332                 weston_log("weston_client_launch: "
333                         "wl_client_create failed while launching '%s'.\n",
334                         path);
335                 return NULL;
336         }
337
338         proc->pid = pid;
339         proc->cleanup = cleanup;
340         weston_watch_process(proc);
341
342         return client;
343 }
344
345 WL_EXPORT void
346 weston_watch_process(struct weston_process *process)
347 {
348         wl_list_insert(&child_process_list, &process->link);
349 }
350
351 struct process_info {
352         struct weston_process proc;
353         char *path;
354 };
355
356 static void
357 process_handle_sigchld(struct weston_process *process, int status)
358 {
359         struct process_info *pinfo =
360                 container_of(process, struct process_info, proc);
361
362         /*
363          * There are no guarantees whether this runs before or after
364          * the wl_client destructor.
365          */
366
367         if (WIFEXITED(status)) {
368                 weston_log("%s exited with status %d\n", pinfo->path,
369                            WEXITSTATUS(status));
370         } else if (WIFSIGNALED(status)) {
371                 weston_log("%s died on signal %d\n", pinfo->path,
372                            WTERMSIG(status));
373         } else {
374                 weston_log("%s disappeared\n", pinfo->path);
375         }
376
377         free(pinfo->path);
378         free(pinfo);
379 }
380
381 WL_EXPORT struct wl_client *
382 weston_client_start(struct weston_compositor *compositor, const char *path)
383 {
384         struct process_info *pinfo;
385         struct wl_client *client;
386
387         pinfo = zalloc(sizeof *pinfo);
388         if (!pinfo)
389                 return NULL;
390
391         pinfo->path = strdup(path);
392         if (!pinfo->path)
393                 goto out_free;
394
395         client = weston_client_launch(compositor, &pinfo->proc, path,
396                                       process_handle_sigchld);
397         if (!client)
398                 goto out_str;
399
400         return client;
401
402 out_str:
403         free(pinfo->path);
404
405 out_free:
406         free(pinfo);
407
408         return NULL;
409 }
410
411 static void
412 log_uname(void)
413 {
414         struct utsname usys;
415
416         uname(&usys);
417
418         weston_log("OS: %s, %s, %s, %s\n", usys.sysname, usys.release,
419                                                 usys.version, usys.machine);
420 }
421
422 static struct wet_compositor *
423 to_wet_compositor(struct weston_compositor *compositor)
424 {
425         return weston_compositor_get_user_data(compositor);
426 }
427
428 WL_EXPORT struct weston_config *
429 wet_get_config(struct weston_compositor *ec)
430 {
431         struct wet_compositor *compositor = to_wet_compositor(ec);
432
433         return compositor->config;
434 }
435
436 static const char xdg_error_message[] =
437         "fatal: environment variable XDG_RUNTIME_DIR is not set.\n";
438
439 static const char xdg_wrong_message[] =
440         "fatal: environment variable XDG_RUNTIME_DIR\n"
441         "is set to \"%s\", which is not a directory.\n";
442
443 static const char xdg_wrong_mode_message[] =
444         "warning: XDG_RUNTIME_DIR \"%s\" is not configured\n"
445         "correctly.  Unix access mode must be 0700 (current mode is %o),\n"
446         "and must be owned by the user (current owner is UID %d).\n";
447
448 static const char xdg_detail_message[] =
449         "Refer to your distribution on how to get it, or\n"
450         "http://www.freedesktop.org/wiki/Specifications/basedir-spec\n"
451         "on how to implement it.\n";
452
453 static void
454 verify_xdg_runtime_dir(void)
455 {
456         char *dir = getenv("XDG_RUNTIME_DIR");
457         struct stat s;
458
459         if (!dir) {
460                 weston_log(xdg_error_message);
461                 weston_log_continue(xdg_detail_message);
462                 exit(EXIT_FAILURE);
463         }
464
465         if (stat(dir, &s) || !S_ISDIR(s.st_mode)) {
466                 weston_log(xdg_wrong_message, dir);
467                 weston_log_continue(xdg_detail_message);
468                 exit(EXIT_FAILURE);
469         }
470
471         if ((s.st_mode & 0777) != 0700 || s.st_uid != getuid()) {
472                 weston_log(xdg_wrong_mode_message,
473                            dir, s.st_mode & 0777, s.st_uid);
474                 weston_log_continue(xdg_detail_message);
475         }
476 }
477
478 static int
479 usage(int error_code)
480 {
481         fprintf(stderr,
482                 "Usage: weston [OPTIONS]\n\n"
483                 "This is weston version " VERSION ", the Wayland reference compositor.\n"
484                 "Weston supports multiple backends, and depending on which backend is in use\n"
485                 "different options will be accepted.\n\n"
486
487
488                 "Core options:\n\n"
489                 "  --version\t\tPrint weston version\n"
490                 "  -B, --backend=MODULE\tBackend module, one of\n"
491 #if defined(BUILD_DRM_COMPOSITOR)
492                         "\t\t\t\tdrm-backend.so\n"
493 #endif
494 #if defined(BUILD_FBDEV_COMPOSITOR)
495                         "\t\t\t\tfbdev-backend.so\n"
496 #endif
497 #if defined(BUILD_HEADLESS_COMPOSITOR)
498                         "\t\t\t\theadless-backend.so\n"
499 #endif
500 #if defined(BUILD_RDP_COMPOSITOR)
501                         "\t\t\t\trdp-backend.so\n"
502 #endif
503 #if defined(BUILD_WAYLAND_COMPOSITOR)
504                         "\t\t\t\twayland-backend.so\n"
505 #endif
506 #if defined(BUILD_X11_COMPOSITOR)
507                         "\t\t\t\tx11-backend.so\n"
508 #endif
509                 "  --shell=MODULE\tShell module, defaults to desktop-shell.so\n"
510                 "  -S, --socket=NAME\tName of socket to listen on\n"
511                 "  -i, --idle-time=SECS\tIdle time in seconds\n"
512                 "  --modules\t\tLoad the comma-separated list of modules\n"
513                 "  --log=FILE\t\tLog to the given file\n"
514                 "  -c, --config=FILE\tConfig file to load, defaults to weston.ini\n"
515                 "  --no-config\t\tDo not read weston.ini\n"
516                 "  -h, --help\t\tThis help message\n\n");
517
518 #if defined(BUILD_DRM_COMPOSITOR)
519         fprintf(stderr,
520                 "Options for drm-backend.so:\n\n"
521                 "  --connector=ID\tBring up only this connector\n"
522                 "  --seat=SEAT\t\tThe seat that weston should run on\n"
523                 "  --tty=TTY\t\tThe tty to use\n"
524                 "  --use-pixman\t\tUse the pixman (CPU) renderer\n"
525                 "  --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n");
526 #endif
527
528 #if defined(BUILD_FBDEV_COMPOSITOR)
529         fprintf(stderr,
530                 "Options for fbdev-backend.so:\n\n"
531                 "  --tty=TTY\t\tThe tty to use\n"
532                 "  --device=DEVICE\tThe framebuffer device to use\n"
533                 "\n");
534 #endif
535
536 #if defined(BUILD_HEADLESS_COMPOSITOR)
537         fprintf(stderr,
538                 "Options for headless-backend.so:\n\n"
539                 "  --width=WIDTH\t\tWidth of memory surface\n"
540                 "  --height=HEIGHT\tHeight of memory surface\n"
541                 "  --transform=TR\tThe output transformation, TR is one of:\n"
542                 "\tnormal 90 180 270 flipped flipped-90 flipped-180 flipped-270\n"
543                 "  --use-pixman\t\tUse the pixman (CPU) renderer (default: no rendering)\n"
544                 "  --no-outputs\t\tDo not create any virtual outputs\n"
545                 "\n");
546 #endif
547
548 #if defined(BUILD_RDP_COMPOSITOR)
549         fprintf(stderr,
550                 "Options for rdp-backend.so:\n\n"
551                 "  --width=WIDTH\t\tWidth of desktop\n"
552                 "  --height=HEIGHT\tHeight of desktop\n"
553                 "  --env-socket\t\tUse socket defined in RDP_FD env variable as peer connection\n"
554                 "  --address=ADDR\tThe address to bind\n"
555                 "  --port=PORT\t\tThe port to listen on\n"
556                 "  --no-clients-resize\tThe RDP peers will be forced to the size of the desktop\n"
557                 "  --rdp4-key=FILE\tThe file containing the key for RDP4 encryption\n"
558                 "  --rdp-tls-cert=FILE\tThe file containing the certificate for TLS encryption\n"
559                 "  --rdp-tls-key=FILE\tThe file containing the private key for TLS encryption\n"
560                 "\n");
561 #endif
562
563 #if defined(BUILD_WAYLAND_COMPOSITOR)
564         fprintf(stderr,
565                 "Options for wayland-backend.so:\n\n"
566                 "  --width=WIDTH\t\tWidth of Wayland surface\n"
567                 "  --height=HEIGHT\tHeight of Wayland surface\n"
568                 "  --scale=SCALE\t\tScale factor of output\n"
569                 "  --fullscreen\t\tRun in fullscreen mode\n"
570                 "  --use-pixman\t\tUse the pixman (CPU) renderer\n"
571                 "  --output-count=COUNT\tCreate multiple outputs\n"
572                 "  --sprawl\t\tCreate one fullscreen output for every parent output\n"
573                 "  --display=DISPLAY\tWayland display to connect to\n\n");
574 #endif
575
576 #if defined(BUILD_X11_COMPOSITOR)
577         fprintf(stderr,
578                 "Options for x11-backend.so:\n\n"
579                 "  --width=WIDTH\t\tWidth of X window\n"
580                 "  --height=HEIGHT\tHeight of X window\n"
581                 "  --scale=SCALE\t\tScale factor of output\n"
582                 "  --fullscreen\t\tRun in fullscreen mode\n"
583                 "  --use-pixman\t\tUse the pixman (CPU) renderer\n"
584                 "  --output-count=COUNT\tCreate multiple outputs\n"
585                 "  --no-input\t\tDont create input devices\n\n");
586 #endif
587
588         exit(error_code);
589 }
590
591 static int on_term_signal(int signal_number, void *data)
592 {
593         struct wl_display *display = data;
594
595         weston_log("caught signal %d\n", signal_number);
596         wl_display_terminate(display);
597
598         return 1;
599 }
600
601 static void
602 on_caught_signal(int s, siginfo_t *siginfo, void *context)
603 {
604         /* This signal handler will do a best-effort backtrace, and
605          * then call the backend restore function, which will switch
606          * back to the vt we launched from or ungrab X etc and then
607          * raise SIGTRAP.  If we run weston under gdb from X or a
608          * different vt, and tell gdb "handle *s* nostop", this
609          * will allow weston to switch back to gdb on crash and then
610          * gdb will catch the crash with SIGTRAP.*/
611
612         weston_log("caught signal: %d\n", s);
613
614         print_backtrace();
615
616         segv_compositor->backend->restore(segv_compositor);
617
618         raise(SIGTRAP);
619 }
620
621 static void
622 catch_signals(void)
623 {
624         struct sigaction action;
625
626         action.sa_flags = SA_SIGINFO | SA_RESETHAND;
627         action.sa_sigaction = on_caught_signal;
628         sigemptyset(&action.sa_mask);
629         sigaction(SIGSEGV, &action, NULL);
630         sigaction(SIGABRT, &action, NULL);
631 }
632
633 static const char *
634 clock_name(clockid_t clk_id)
635 {
636         static const char *names[] = {
637                 [CLOCK_REALTIME] =              "CLOCK_REALTIME",
638                 [CLOCK_MONOTONIC] =             "CLOCK_MONOTONIC",
639                 [CLOCK_MONOTONIC_RAW] =         "CLOCK_MONOTONIC_RAW",
640                 [CLOCK_REALTIME_COARSE] =       "CLOCK_REALTIME_COARSE",
641                 [CLOCK_MONOTONIC_COARSE] =      "CLOCK_MONOTONIC_COARSE",
642 #ifdef CLOCK_BOOTTIME
643                 [CLOCK_BOOTTIME] =              "CLOCK_BOOTTIME",
644 #endif
645         };
646
647         if (clk_id < 0 || (unsigned)clk_id >= ARRAY_LENGTH(names))
648                 return "unknown";
649
650         return names[clk_id];
651 }
652
653 static const struct {
654         uint32_t bit; /* enum weston_capability */
655         const char *desc;
656 } capability_strings[] = {
657         { WESTON_CAP_ROTATION_ANY, "arbitrary surface rotation:" },
658         { WESTON_CAP_CAPTURE_YFLIP, "screen capture uses y-flip:" },
659 };
660
661 static void
662 weston_compositor_log_capabilities(struct weston_compositor *compositor)
663 {
664         unsigned i;
665         int yes;
666         struct timespec res;
667
668         weston_log("Compositor capabilities:\n");
669         for (i = 0; i < ARRAY_LENGTH(capability_strings); i++) {
670                 yes = compositor->capabilities & capability_strings[i].bit;
671                 weston_log_continue(STAMP_SPACE "%s %s\n",
672                                     capability_strings[i].desc,
673                                     yes ? "yes" : "no");
674         }
675
676         weston_log_continue(STAMP_SPACE "presentation clock: %s, id %d\n",
677                             clock_name(compositor->presentation_clock),
678                             compositor->presentation_clock);
679
680         if (clock_getres(compositor->presentation_clock, &res) == 0)
681                 weston_log_continue(STAMP_SPACE
682                                 "presentation clock resolution: %d.%09ld s\n",
683                                 (int)res.tv_sec, res.tv_nsec);
684         else
685                 weston_log_continue(STAMP_SPACE
686                                 "presentation clock resolution: N/A\n");
687 }
688
689 static void
690 handle_primary_client_destroyed(struct wl_listener *listener, void *data)
691 {
692         struct wl_client *client = data;
693
694         weston_log("Primary client died.  Closing...\n");
695
696         wl_display_terminate(wl_client_get_display(client));
697 }
698
699 static int
700 weston_create_listening_socket(struct wl_display *display, const char *socket_name)
701 {
702         if (socket_name) {
703                 if (wl_display_add_socket(display, socket_name)) {
704                         weston_log("fatal: failed to add socket: %m\n");
705                         return -1;
706                 }
707         } else {
708                 socket_name = wl_display_add_socket_auto(display);
709                 if (!socket_name) {
710                         weston_log("fatal: failed to add socket: %m\n");
711                         return -1;
712                 }
713         }
714
715         setenv("WAYLAND_DISPLAY", socket_name, 1);
716
717         return 0;
718 }
719
720 WL_EXPORT void *
721 wet_load_module(const char *name, const char *entrypoint)
722 {
723         const char *builddir = getenv("WESTON_BUILD_DIR");
724         char path[PATH_MAX];
725         void *module, *init;
726
727         if (name == NULL)
728                 return NULL;
729
730         if (name[0] != '/') {
731                 if (builddir)
732                         snprintf(path, sizeof path, "%s/.libs/%s", builddir, name);
733                 else
734                         snprintf(path, sizeof path, "%s/%s", MODULEDIR, name);
735         } else {
736                 snprintf(path, sizeof path, "%s", name);
737         }
738
739         module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
740         if (module) {
741                 weston_log("Module '%s' already loaded\n", path);
742                 dlclose(module);
743                 return NULL;
744         }
745
746         weston_log("Loading module '%s'\n", path);
747         module = dlopen(path, RTLD_NOW);
748         if (!module) {
749                 weston_log("Failed to load module: %s\n", dlerror());
750                 return NULL;
751         }
752
753         init = dlsym(module, entrypoint);
754         if (!init) {
755                 weston_log("Failed to lookup init function: %s\n", dlerror());
756                 dlclose(module);
757                 return NULL;
758         }
759
760         return init;
761 }
762
763 static int
764 load_modules(struct weston_compositor *ec, const char *modules,
765              int *argc, char *argv[])
766 {
767         const char *p, *end;
768         char buffer[256];
769         int (*module_init)(struct weston_compositor *ec,
770                            int *argc, char *argv[]);
771
772         if (modules == NULL)
773                 return 0;
774
775         p = modules;
776         while (*p) {
777                 end = strchrnul(p, ',');
778                 snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p);
779
780                 if (strstr(buffer, "xwayland.so")) {
781                         if (wet_load_xwayland(ec) < 0)
782                                 return -1;
783                 } else {
784                         module_init = wet_load_module(buffer, "module_init");
785                         if (!module_init)
786                                 return -1;
787                         if (module_init(ec, argc, argv) < 0)
788                                 return -1;
789                 }
790                 p = end;
791                 while (*p == ',')
792                         p++;
793
794         }
795
796         return 0;
797 }
798
799 static int
800 weston_compositor_init_config(struct weston_compositor *ec,
801                               struct weston_config *config)
802 {
803         struct xkb_rule_names xkb_names;
804         struct weston_config_section *s;
805         int repaint_msec;
806         int vt_switching;
807
808         s = weston_config_get_section(config, "keyboard", NULL, NULL);
809         weston_config_section_get_string(s, "keymap_rules",
810                                          (char **) &xkb_names.rules, NULL);
811         weston_config_section_get_string(s, "keymap_model",
812                                          (char **) &xkb_names.model, NULL);
813         weston_config_section_get_string(s, "keymap_layout",
814                                          (char **) &xkb_names.layout, NULL);
815         weston_config_section_get_string(s, "keymap_variant",
816                                          (char **) &xkb_names.variant, NULL);
817         weston_config_section_get_string(s, "keymap_options",
818                                          (char **) &xkb_names.options, NULL);
819
820         if (weston_compositor_set_xkb_rule_names(ec, &xkb_names) < 0)
821                 return -1;
822
823         weston_config_section_get_int(s, "repeat-rate",
824                                       &ec->kb_repeat_rate, 40);
825         weston_config_section_get_int(s, "repeat-delay",
826                                       &ec->kb_repeat_delay, 400);
827
828         weston_config_section_get_bool(s, "vt-switching",
829                                        &vt_switching, true);
830         ec->vt_switching = vt_switching;
831
832         s = weston_config_get_section(config, "core", NULL, NULL);
833         weston_config_section_get_int(s, "repaint-window", &repaint_msec,
834                                       ec->repaint_msec);
835         if (repaint_msec < -10 || repaint_msec > 1000) {
836                 weston_log("Invalid repaint_window value in config: %d\n",
837                            repaint_msec);
838         } else {
839                 ec->repaint_msec = repaint_msec;
840         }
841         weston_log("Output repaint window is %d ms maximum.\n",
842                    ec->repaint_msec);
843
844         return 0;
845 }
846
847 static char *
848 weston_choose_default_backend(void)
849 {
850         char *backend = NULL;
851
852         if (getenv("WAYLAND_DISPLAY") || getenv("WAYLAND_SOCKET"))
853                 backend = strdup("wayland-backend.so");
854         else if (getenv("DISPLAY"))
855                 backend = strdup("x11-backend.so");
856         else
857                 backend = strdup(WESTON_NATIVE_BACKEND);
858
859         return backend;
860 }
861
862 static const struct { const char *name; uint32_t token; } transforms[] = {
863         { "normal",     WL_OUTPUT_TRANSFORM_NORMAL },
864         { "90",         WL_OUTPUT_TRANSFORM_90 },
865         { "180",        WL_OUTPUT_TRANSFORM_180 },
866         { "270",        WL_OUTPUT_TRANSFORM_270 },
867         { "flipped",    WL_OUTPUT_TRANSFORM_FLIPPED },
868         { "flipped-90", WL_OUTPUT_TRANSFORM_FLIPPED_90 },
869         { "flipped-180", WL_OUTPUT_TRANSFORM_FLIPPED_180 },
870         { "flipped-270", WL_OUTPUT_TRANSFORM_FLIPPED_270 },
871 };
872
873 WL_EXPORT int
874 weston_parse_transform(const char *transform, uint32_t *out)
875 {
876         unsigned int i;
877
878         for (i = 0; i < ARRAY_LENGTH(transforms); i++)
879                 if (strcmp(transforms[i].name, transform) == 0) {
880                         *out = transforms[i].token;
881                         return 0;
882                 }
883
884         *out = WL_OUTPUT_TRANSFORM_NORMAL;
885         return -1;
886 }
887
888 WL_EXPORT const char *
889 weston_transform_to_string(uint32_t output_transform)
890 {
891         unsigned int i;
892
893         for (i = 0; i < ARRAY_LENGTH(transforms); i++)
894                 if (transforms[i].token == output_transform)
895                         return transforms[i].name;
896
897         return "<illegal value>";
898 }
899
900 static int
901 load_configuration(struct weston_config **config, int32_t noconfig,
902                    const char *config_file)
903 {
904         const char *file = "weston.ini";
905         const char *full_path;
906
907         *config = NULL;
908
909         if (config_file)
910                 file = config_file;
911
912         if (noconfig == 0)
913                 *config = weston_config_parse(file);
914
915         if (*config) {
916                 full_path = weston_config_get_full_path(*config);
917
918                 weston_log("Using config file '%s'\n", full_path);
919                 setenv(WESTON_CONFIG_FILE_ENV_VAR, full_path, 1);
920
921                 return 0;
922         }
923
924         if (config_file && noconfig == 0) {
925                 weston_log("fatal: error opening or reading config file"
926                            " '%s'.\n", config_file);
927
928                 return -1;
929         }
930
931         weston_log("Starting with no config file.\n");
932         setenv(WESTON_CONFIG_FILE_ENV_VAR, "", 1);
933
934         return 0;
935 }
936
937 static void
938 handle_exit(struct weston_compositor *c)
939 {
940         wl_display_terminate(c->wl_display);
941 }
942
943 static enum weston_drm_backend_output_mode
944 drm_configure_output(struct weston_compositor *c,
945                      bool use_current_mode,
946                      const char *name,
947                      struct weston_drm_backend_output_config *config)
948 {
949         struct weston_config *wc = wet_get_config(c);
950         struct weston_config_section *section;
951         char *s;
952         int scale;
953         enum weston_drm_backend_output_mode mode =
954                 WESTON_DRM_BACKEND_OUTPUT_PREFERRED;
955
956         section = weston_config_get_section(wc, "output", "name", name);
957         weston_config_section_get_string(section, "mode", &s, "preferred");
958         if (strcmp(s, "off") == 0) {
959                 free(s);
960                 return WESTON_DRM_BACKEND_OUTPUT_OFF;
961         }
962
963         if (use_current_mode || strcmp(s, "current") == 0) {
964                 mode = WESTON_DRM_BACKEND_OUTPUT_CURRENT;
965         } else if (strcmp(s, "preferred") != 0) {
966                 config->modeline = s;
967                 s = NULL;
968         }
969         free(s);
970
971         weston_config_section_get_int(section, "scale", &scale, 1);
972         config->base.scale = scale >= 1 ? scale : 1;
973         weston_config_section_get_string(section, "transform", &s, "normal");
974         if (weston_parse_transform(s, &config->base.transform) < 0)
975                 weston_log("Invalid transform \"%s\" for output %s\n",
976                            s, name);
977         free(s);
978
979         weston_config_section_get_string(section,
980                                          "gbm-format", &config->gbm_format, NULL);
981         weston_config_section_get_string(section, "seat", &config->seat, "");
982         return mode;
983 }
984
985 static void
986 configure_input_device(struct weston_compositor *compositor,
987                        struct libinput_device *device)
988 {
989         struct weston_config_section *s;
990         struct weston_config *config = wet_get_config(compositor);
991         int enable_tap;
992         int enable_tap_default;
993
994         s = weston_config_get_section(config,
995                                       "libinput", NULL, NULL);
996
997         if (libinput_device_config_tap_get_finger_count(device) > 0) {
998                 enable_tap_default =
999                         libinput_device_config_tap_get_default_enabled(
1000                                 device);
1001                 weston_config_section_get_bool(s, "enable_tap",
1002                                                &enable_tap,
1003                                                enable_tap_default);
1004                 libinput_device_config_tap_set_enabled(device,
1005                                                        enable_tap);
1006         }
1007 }
1008
1009 static int
1010 load_drm_backend(struct weston_compositor *c,
1011                  int *argc, char **argv, struct weston_config *wc)
1012 {
1013         struct weston_drm_backend_config config = {{ 0, }};
1014         struct weston_config_section *section;
1015         int ret = 0;
1016
1017         const struct weston_option options[] = {
1018                 { WESTON_OPTION_INTEGER, "connector", 0, &config.connector },
1019                 { WESTON_OPTION_STRING, "seat", 0, &config.seat_id },
1020                 { WESTON_OPTION_INTEGER, "tty", 0, &config.tty },
1021                 { WESTON_OPTION_BOOLEAN, "current-mode", 0, &config.use_current_mode },
1022                 { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &config.use_pixman },
1023         };
1024
1025         parse_options(options, ARRAY_LENGTH(options), argc, argv);
1026
1027         section = weston_config_get_section(wc, "core", NULL, NULL);
1028         weston_config_section_get_string(section,
1029                                          "gbm-format", &config.gbm_format,
1030                                          NULL);
1031
1032         config.base.struct_version = WESTON_DRM_BACKEND_CONFIG_VERSION;
1033         config.base.struct_size = sizeof(struct weston_drm_backend_config);
1034         config.configure_output = drm_configure_output;
1035         config.configure_device = configure_input_device;
1036
1037         ret = weston_compositor_load_backend(c, WESTON_BACKEND_DRM,
1038                                              &config.base);
1039
1040         free(config.gbm_format);
1041         free(config.seat_id);
1042
1043         return ret;
1044 }
1045
1046 static int
1047 load_headless_backend(struct weston_compositor *c,
1048                       int *argc, char **argv, struct weston_config *wc)
1049 {
1050         struct weston_headless_backend_config config = {{ 0, }};
1051         int ret = 0;
1052         char *transform = NULL;
1053
1054         config.width = 1024;
1055         config.height = 640;
1056
1057         const struct weston_option options[] = {
1058                 { WESTON_OPTION_INTEGER, "width", 0, &config.width },
1059                 { WESTON_OPTION_INTEGER, "height", 0, &config.height },
1060                 { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &config.use_pixman },
1061                 { WESTON_OPTION_STRING, "transform", 0, &transform },
1062                 { WESTON_OPTION_BOOLEAN, "no-outputs", 0, &config.no_outputs },
1063         };
1064
1065         parse_options(options, ARRAY_LENGTH(options), argc, argv);
1066
1067         config.transform = WL_OUTPUT_TRANSFORM_NORMAL;
1068         if (transform) {
1069                 if (weston_parse_transform(transform, &config.transform) < 0)
1070                         weston_log("Invalid transform \"%s\"\n", transform);
1071                 free(transform);
1072         }
1073
1074         config.base.struct_version = WESTON_HEADLESS_BACKEND_CONFIG_VERSION;
1075         config.base.struct_size = sizeof(struct weston_headless_backend_config);
1076
1077         /* load the actual wayland backend and configure it */
1078         ret = weston_compositor_load_backend(c, WESTON_BACKEND_HEADLESS,
1079                                              &config.base);
1080
1081         return ret;
1082 }
1083
1084 static void
1085 weston_rdp_backend_config_init(struct weston_rdp_backend_config *config)
1086 {
1087         config->base.struct_version = WESTON_RDP_BACKEND_CONFIG_VERSION;
1088         config->base.struct_size = sizeof(struct weston_rdp_backend_config);
1089
1090         config->width = 640;
1091         config->height = 480;
1092         config->bind_address = NULL;
1093         config->port = 3389;
1094         config->rdp_key = NULL;
1095         config->server_cert = NULL;
1096         config->server_key = NULL;
1097         config->env_socket = 0;
1098         config->no_clients_resize = 0;
1099 }
1100
1101 static int
1102 load_rdp_backend(struct weston_compositor *c,
1103                 int *argc, char *argv[], struct weston_config *wc)
1104 {
1105         struct weston_rdp_backend_config config  = {{ 0, }};
1106         int ret = 0;
1107
1108         weston_rdp_backend_config_init(&config);
1109
1110         const struct weston_option rdp_options[] = {
1111                 { WESTON_OPTION_BOOLEAN, "env-socket", 0, &config.env_socket },
1112                 { WESTON_OPTION_INTEGER, "width", 0, &config.width },
1113                 { WESTON_OPTION_INTEGER, "height", 0, &config.height },
1114                 { WESTON_OPTION_STRING,  "address", 0, &config.bind_address },
1115                 { WESTON_OPTION_INTEGER, "port", 0, &config.port },
1116                 { WESTON_OPTION_BOOLEAN, "no-clients-resize", 0, &config.no_clients_resize },
1117                 { WESTON_OPTION_STRING,  "rdp4-key", 0, &config.rdp_key },
1118                 { WESTON_OPTION_STRING,  "rdp-tls-cert", 0, &config.server_cert },
1119                 { WESTON_OPTION_STRING,  "rdp-tls-key", 0, &config.server_key }
1120         };
1121
1122         parse_options(rdp_options, ARRAY_LENGTH(rdp_options), argc, argv);
1123
1124         ret = weston_compositor_load_backend(c, WESTON_BACKEND_RDP,
1125                                              &config.base);
1126
1127         free(config.bind_address);
1128         free(config.rdp_key);
1129         free(config.server_cert);
1130         free(config.server_key);
1131         return ret;
1132 }
1133
1134 static int
1135 load_fbdev_backend(struct weston_compositor *c,
1136                       int *argc, char **argv, struct weston_config *wc)
1137 {
1138         struct weston_fbdev_backend_config config = {{ 0, }};
1139         struct weston_config_section *section;
1140         char *s = NULL;
1141         int ret = 0;
1142
1143         const struct weston_option fbdev_options[] = {
1144                 { WESTON_OPTION_INTEGER, "tty", 0, &config.tty },
1145                 { WESTON_OPTION_STRING, "device", 0, &config.device },
1146         };
1147
1148         parse_options(fbdev_options, ARRAY_LENGTH(fbdev_options), argc, argv);
1149
1150         if (!config.device)
1151                 config.device = strdup("/dev/fb0");
1152
1153         section = weston_config_get_section(wc, "output", "name", "fbdev");
1154         weston_config_section_get_string(section, "transform", &s, "normal");
1155         if (weston_parse_transform(s, &config.output_transform) < 0)
1156                 weston_log("Invalid transform \"%s\" for output fbdev\n", s);
1157         free(s);
1158
1159         config.base.struct_version = WESTON_FBDEV_BACKEND_CONFIG_VERSION;
1160         config.base.struct_size = sizeof(struct weston_fbdev_backend_config);
1161         config.configure_device = configure_input_device;
1162
1163         /* load the actual wayland backend and configure it */
1164         ret = weston_compositor_load_backend(c, WESTON_BACKEND_FBDEV,
1165                                              &config.base);
1166
1167         free(config.device);
1168
1169         return ret;
1170 }
1171
1172 static int
1173 weston_x11_backend_config_append_output_config(struct weston_x11_backend_config *config,
1174                                                struct weston_x11_backend_output_config *output_config) {
1175         struct weston_x11_backend_output_config *new_outputs;
1176
1177         new_outputs = realloc(config->outputs, (config->num_outputs+1) *
1178                               sizeof(struct weston_x11_backend_output_config));
1179         if (new_outputs == NULL)
1180                 return -1;
1181
1182         config->outputs = new_outputs;
1183         config->outputs[config->num_outputs].width = output_config->width;
1184         config->outputs[config->num_outputs].height = output_config->height;
1185         config->outputs[config->num_outputs].transform = output_config->transform;
1186         config->outputs[config->num_outputs].scale = output_config->scale;
1187         config->outputs[config->num_outputs].name = strdup(output_config->name);
1188         config->num_outputs++;
1189
1190         return 0;
1191 }
1192
1193 static int
1194 load_x11_backend(struct weston_compositor *c,
1195                  int *argc, char **argv, struct weston_config *wc)
1196 {
1197         struct weston_x11_backend_output_config default_output;
1198         struct weston_x11_backend_config config = {{ 0, }};
1199         struct weston_config_section *section;
1200         int ret = 0;
1201         int option_width = 0;
1202         int option_height = 0;
1203         int option_scale = 0;
1204         int option_count = 1;
1205         int output_count = 0;
1206         char const *section_name;
1207         int i;
1208         uint32_t j;
1209
1210         const struct weston_option options[] = {
1211                { WESTON_OPTION_INTEGER, "width", 0, &option_width },
1212                { WESTON_OPTION_INTEGER, "height", 0, &option_height },
1213                { WESTON_OPTION_INTEGER, "scale", 0, &option_scale },
1214                { WESTON_OPTION_BOOLEAN, "fullscreen", 'f', &config.fullscreen },
1215                { WESTON_OPTION_INTEGER, "output-count", 0, &option_count },
1216                { WESTON_OPTION_BOOLEAN, "no-input", 0, &config.no_input },
1217                { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &config.use_pixman },
1218         };
1219
1220         parse_options(options, ARRAY_LENGTH(options), argc, argv);
1221
1222         section = NULL;
1223         while (weston_config_next_section(wc, &section, &section_name)) {
1224                 struct weston_x11_backend_output_config current_output = { 0, };
1225                 char *t;
1226                 char *mode;
1227
1228                 if (strcmp(section_name, "output") != 0) {
1229                         continue;
1230                 }
1231
1232                 weston_config_section_get_string(section, "name", &current_output.name, NULL);
1233                 if (current_output.name == NULL || current_output.name[0] != 'X') {
1234                         free(current_output.name);
1235                         continue;
1236                 }
1237
1238                 weston_config_section_get_string(section, "mode", &mode, "1024x600");
1239                 if (sscanf(mode, "%dx%d", &current_output.width,
1240                            &current_output.height) != 2) {
1241                         weston_log("Invalid mode \"%s\" for output %s\n",
1242                                    mode, current_output.name);
1243                         current_output.width = 1024;
1244                         current_output.height = 600;
1245                 }
1246                 free(mode);
1247                 if (current_output.width < 1)
1248                         current_output.width = 1024;
1249                 if (current_output.height < 1)
1250                         current_output.height = 600;
1251                 if (option_width)
1252                         current_output.width = option_width;
1253                 if (option_height)
1254                         current_output.height = option_height;
1255
1256                 weston_config_section_get_int(section, "scale", &current_output.scale, 1);
1257                 if (option_scale)
1258                         current_output.scale = option_scale;
1259
1260                 weston_config_section_get_string(section,
1261                                                  "transform", &t, "normal");
1262                 if (weston_parse_transform(t, &current_output.transform) < 0)
1263                         weston_log("Invalid transform \"%s\" for output %s\n",
1264                                    t, current_output.name);
1265                 free(t);
1266
1267                 if (weston_x11_backend_config_append_output_config(&config, &current_output) < 0) {
1268                         ret = -1;
1269                         goto out;
1270                 }
1271
1272                 output_count++;
1273                 if (output_count >= option_count)
1274                         break;
1275         }
1276
1277         default_output.name = NULL;
1278         default_output.width = option_width ? option_width : 1024;
1279         default_output.height = option_height ? option_height : 600;
1280         default_output.scale = option_scale ? option_scale : 1;
1281         default_output.transform = WL_OUTPUT_TRANSFORM_NORMAL;
1282
1283         for (i = output_count; i < option_count; i++) {
1284                 if (asprintf(&default_output.name, "screen%d", i) < 0) {
1285                         ret = -1;
1286                         goto out;
1287                 }
1288
1289                 if (weston_x11_backend_config_append_output_config(&config, &default_output) < 0) {
1290                         ret = -1;
1291                         free(default_output.name);
1292                         goto out;
1293                 }
1294                 free(default_output.name);
1295         }
1296
1297         config.base.struct_version = WESTON_X11_BACKEND_CONFIG_VERSION;
1298         config.base.struct_size = sizeof(struct weston_x11_backend_config);
1299
1300         /* load the actual backend and configure it */
1301         ret = weston_compositor_load_backend(c, WESTON_BACKEND_X11,
1302                                              &config.base);
1303
1304 out:
1305         for (j = 0; j < config.num_outputs; ++j)
1306                 free(config.outputs[j].name);
1307         free(config.outputs);
1308
1309         return ret;
1310 }
1311
1312 static void
1313 weston_wayland_output_config_init(struct weston_wayland_backend_output_config *output_config,
1314                                   struct weston_config_section *config_section,
1315                                   int option_width, int option_height,
1316                                   int option_scale)
1317 {
1318         char *mode, *t, *str;
1319         unsigned int slen;
1320
1321         weston_config_section_get_string(config_section, "name", &output_config->name,
1322                                          NULL);
1323         if (output_config->name) {
1324                 slen = strlen(output_config->name);
1325                 slen += strlen(WINDOW_TITLE " - ");
1326                 str = malloc(slen + 1);
1327                 if (str)
1328                         snprintf(str, slen + 1, WINDOW_TITLE " - %s",
1329                                  output_config->name);
1330                 free(output_config->name);
1331                 output_config->name = str;
1332         }
1333         if (!output_config->name)
1334                 output_config->name = strdup(WINDOW_TITLE);
1335
1336         weston_config_section_get_string(config_section,
1337                                          "mode", &mode, "1024x600");
1338         if (sscanf(mode, "%dx%d", &output_config->width, &output_config->height) != 2) {
1339                 weston_log("Invalid mode \"%s\" for output %s\n",
1340                            mode, output_config->name);
1341                 output_config->width = 1024;
1342                 output_config->height = 640;
1343         }
1344         free(mode);
1345
1346         if (option_width)
1347                 output_config->width = option_width;
1348         if (option_height)
1349                 output_config->height = option_height;
1350
1351         weston_config_section_get_int(config_section, "scale", &output_config->scale, 1);
1352
1353         if (option_scale)
1354                 output_config->scale = option_scale;
1355
1356         weston_config_section_get_string(config_section,
1357                                          "transform", &t, "normal");
1358         if (weston_parse_transform(t, &output_config->transform) < 0)
1359                 weston_log("Invalid transform \"%s\" for output %s\n",
1360                            t, output_config->name);
1361         free(t);
1362
1363 }
1364
1365 static void
1366 weston_wayland_backend_config_release(struct weston_wayland_backend_config *config)
1367 {
1368         int i;
1369
1370         for (i = 0; i < config->num_outputs; ++i) {
1371                 free(config->outputs[i].name);
1372         }
1373         free(config->cursor_theme);
1374         free(config->display_name);
1375         free(config->outputs);
1376 }
1377
1378 /*
1379  * Append a new output struct at the end of new_config.outputs and return a
1380  * pointer to the newly allocated structure or NULL if fail. The allocated
1381  * structure is NOT cleared nor set to default values.
1382  */
1383 static struct weston_wayland_backend_output_config *
1384 weston_wayland_backend_config_add_new_output(struct weston_wayland_backend_config *config)
1385 {
1386         struct weston_wayland_backend_output_config *outputs;
1387         const size_t element_size = sizeof(struct weston_wayland_backend_output_config);
1388
1389         outputs = realloc(config->outputs,
1390                           (config->num_outputs + 1) * element_size);
1391         if (!outputs)
1392                 return NULL;
1393         config->num_outputs += 1;
1394         config->outputs = outputs;
1395         return &(config->outputs[config->num_outputs - 1]);
1396 }
1397
1398 static int
1399 load_wayland_backend_config(struct weston_compositor *compositor, int *argc,
1400                             char *argv[], struct weston_config *wc,
1401                             struct weston_wayland_backend_config *config)
1402 {
1403         struct weston_config_section *section;
1404         struct weston_wayland_backend_output_config *oc;
1405         int count, width, height, scale;
1406         const char *section_name;
1407         char *name;
1408
1409         const struct weston_option wayland_options[] = {
1410                 { WESTON_OPTION_INTEGER, "width", 0, &width },
1411                 { WESTON_OPTION_INTEGER, "height", 0, &height },
1412                 { WESTON_OPTION_INTEGER, "scale", 0, &scale },
1413                 { WESTON_OPTION_STRING, "display", 0, &config->display_name },
1414                 { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &config->use_pixman },
1415                 { WESTON_OPTION_INTEGER, "output-count", 0, &count },
1416                 { WESTON_OPTION_BOOLEAN, "fullscreen", 0, &config->fullscreen },
1417                 { WESTON_OPTION_BOOLEAN, "sprawl", 0, &config->sprawl },
1418         };
1419
1420         width = 0;
1421         height = 0;
1422         scale = 0;
1423         config->display_name = NULL;
1424         config->use_pixman = 0;
1425         count = 1;
1426         config->fullscreen = 0;
1427         config->sprawl = 0;
1428         parse_options(wayland_options,
1429                       ARRAY_LENGTH(wayland_options), argc, argv);
1430
1431         config->cursor_size = 32;
1432         config->cursor_theme = NULL;
1433         config->base.struct_size = sizeof(struct weston_wayland_backend_config);
1434         config->base.struct_version = WESTON_WAYLAND_BACKEND_CONFIG_VERSION;
1435
1436         section = weston_config_get_section(wc, "shell", NULL, NULL);
1437         weston_config_section_get_string(section, "cursor-theme",
1438                                          &config->cursor_theme, NULL);
1439         weston_config_section_get_int(section, "cursor-size",
1440                                       &config->cursor_size, 32);
1441
1442         if (config->sprawl) {
1443                 /* do nothing, everything is already set */
1444                 return 0;
1445         }
1446
1447         if (config->fullscreen) {
1448                 oc = weston_wayland_backend_config_add_new_output(config);
1449                 if (!oc)
1450                         return -1;
1451
1452                 oc->width = width;
1453                 oc->height = height;
1454                 oc->name = NULL;
1455                 oc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
1456                 oc->scale = 1;
1457
1458                 return 0;
1459         }
1460
1461         section = NULL;
1462         while (weston_config_next_section(wc, &section, &section_name)) {
1463                 if (!section_name || strcmp(section_name, "output") != 0)
1464                         continue;
1465                 weston_config_section_get_string(section, "name", &name, NULL);
1466                 if (name == NULL)
1467                         continue;
1468
1469                 if (name[0] != 'W' || name[1] != 'L') {
1470                         free(name);
1471                         continue;
1472                 }
1473                 free(name);
1474
1475                 oc = weston_wayland_backend_config_add_new_output(config);
1476                 if (!oc)
1477                         return -1;
1478
1479                 weston_wayland_output_config_init(oc, section, width,
1480                                                   height, scale);
1481                 --count;
1482         }
1483
1484         if (!width)
1485                 width = 1024;
1486         if (!height)
1487                 height = 640;
1488         if (!scale)
1489                 scale = 1;
1490
1491         while (count > 0) {
1492                 oc = weston_wayland_backend_config_add_new_output(config);
1493                 if (!oc)
1494                         return -1;
1495
1496                 oc->width = width;
1497                 oc->height = height;
1498                 oc->name = NULL;
1499                 oc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
1500                 oc->scale = scale;
1501
1502                 --count;
1503         }
1504
1505         return 0;
1506 }
1507
1508 static int
1509 load_wayland_backend(struct weston_compositor *c,
1510                      int *argc, char **argv, struct weston_config *wc)
1511 {
1512         struct weston_wayland_backend_config config = {{ 0, }};
1513         int ret = 0;
1514
1515         ret = load_wayland_backend_config(c, argc, argv, wc, &config);
1516         if (ret < 0) {
1517                 weston_wayland_backend_config_release(&config);
1518                 return ret;
1519         }
1520
1521         /* load the actual wayland backend and configure it */
1522         ret = weston_compositor_load_backend(c, WESTON_BACKEND_WAYLAND,
1523                                              &config.base);
1524         weston_wayland_backend_config_release(&config);
1525         return ret;
1526 }
1527
1528
1529 static int
1530 load_backend(struct weston_compositor *compositor, const char *backend,
1531              int *argc, char **argv, struct weston_config *config)
1532 {
1533         if (strstr(backend, "headless-backend.so"))
1534                 return load_headless_backend(compositor, argc, argv, config);
1535         else if (strstr(backend, "rdp-backend.so"))
1536                 return load_rdp_backend(compositor, argc, argv, config);
1537         else if (strstr(backend, "fbdev-backend.so"))
1538                 return load_fbdev_backend(compositor, argc, argv, config);
1539         else if (strstr(backend, "drm-backend.so"))
1540                 return load_drm_backend(compositor, argc, argv, config);
1541         else if (strstr(backend, "x11-backend.so"))
1542                 return load_x11_backend(compositor, argc, argv, config);
1543         else if (strstr(backend, "wayland-backend.so"))
1544                 return load_wayland_backend(compositor, argc, argv, config);
1545
1546         weston_log("Error: unknown backend \"%s\"\n", backend);
1547         return -1;
1548 }
1549
1550 static char *
1551 copy_command_line(int argc, char * const argv[])
1552 {
1553         FILE *fp;
1554         char *str = NULL;
1555         size_t size = 0;
1556         int i;
1557
1558         fp = open_memstream(&str, &size);
1559         if (!fp)
1560                 return NULL;
1561
1562         fprintf(fp, "%s", argv[0]);
1563         for (i = 1; i < argc; i++)
1564                 fprintf(fp, " %s", argv[i]);
1565         fclose(fp);
1566
1567         return str;
1568 }
1569
1570 int main(int argc, char *argv[])
1571 {
1572         int ret = EXIT_FAILURE;
1573         char *cmdline;
1574         struct wl_display *display;
1575         struct weston_compositor *ec;
1576         struct wl_event_source *signals[4];
1577         struct wl_event_loop *loop;
1578         int i, fd;
1579         char *backend = NULL;
1580         char *shell = NULL;
1581         char *modules = NULL;
1582         char *option_modules = NULL;
1583         char *log = NULL;
1584         char *server_socket = NULL;
1585         int32_t idle_time = -1;
1586         int32_t help = 0;
1587         char *socket_name = NULL;
1588         int32_t version = 0;
1589         int32_t noconfig = 0;
1590         int32_t numlock_on;
1591         char *config_file = NULL;
1592         struct weston_config *config = NULL;
1593         struct weston_config_section *section;
1594         struct wl_client *primary_client;
1595         struct wl_listener primary_client_destroyed;
1596         struct weston_seat *seat;
1597         struct wet_compositor user_data;
1598
1599         const struct weston_option core_options[] = {
1600                 { WESTON_OPTION_STRING, "backend", 'B', &backend },
1601                 { WESTON_OPTION_STRING, "shell", 0, &shell },
1602                 { WESTON_OPTION_STRING, "socket", 'S', &socket_name },
1603                 { WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time },
1604                 { WESTON_OPTION_STRING, "modules", 0, &option_modules },
1605                 { WESTON_OPTION_STRING, "log", 0, &log },
1606                 { WESTON_OPTION_BOOLEAN, "help", 'h', &help },
1607                 { WESTON_OPTION_BOOLEAN, "version", 0, &version },
1608                 { WESTON_OPTION_BOOLEAN, "no-config", 0, &noconfig },
1609                 { WESTON_OPTION_STRING, "config", 'c', &config_file },
1610         };
1611
1612         cmdline = copy_command_line(argc, argv);
1613         parse_options(core_options, ARRAY_LENGTH(core_options), &argc, argv);
1614
1615         if (help) {
1616                 free(cmdline);
1617                 usage(EXIT_SUCCESS);
1618         }
1619
1620         if (version) {
1621                 printf(PACKAGE_STRING "\n");
1622                 free(cmdline);
1623
1624                 return EXIT_SUCCESS;
1625         }
1626
1627         weston_log_set_handler(vlog, vlog_continue);
1628         weston_log_file_open(log);
1629
1630         weston_log("%s\n"
1631                    STAMP_SPACE "%s\n"
1632                    STAMP_SPACE "Bug reports to: %s\n"
1633                    STAMP_SPACE "Build: %s\n",
1634                    PACKAGE_STRING, PACKAGE_URL, PACKAGE_BUGREPORT,
1635                    BUILD_ID);
1636         weston_log("Command line: %s\n", cmdline);
1637         free(cmdline);
1638         log_uname();
1639
1640         verify_xdg_runtime_dir();
1641
1642         display = wl_display_create();
1643
1644         loop = wl_display_get_event_loop(display);
1645         signals[0] = wl_event_loop_add_signal(loop, SIGTERM, on_term_signal,
1646                                               display);
1647         signals[1] = wl_event_loop_add_signal(loop, SIGINT, on_term_signal,
1648                                               display);
1649         signals[2] = wl_event_loop_add_signal(loop, SIGQUIT, on_term_signal,
1650                                               display);
1651
1652         wl_list_init(&child_process_list);
1653         signals[3] = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
1654                                               NULL);
1655
1656         if (!signals[0] || !signals[1] || !signals[2] || !signals[3])
1657                 goto out_signals;
1658
1659         if (load_configuration(&config, noconfig, config_file) < 0)
1660                 goto out_signals;
1661         user_data.config = config;
1662
1663         section = weston_config_get_section(config, "core", NULL, NULL);
1664
1665         if (!backend) {
1666                 weston_config_section_get_string(section, "backend", &backend,
1667                                                  NULL);
1668                 if (!backend)
1669                         backend = weston_choose_default_backend();
1670         }
1671
1672         ec = weston_compositor_create(display, &user_data);
1673         if (ec == NULL) {
1674                 weston_log("fatal: failed to create compositor\n");
1675                 goto out;
1676         }
1677
1678         if (weston_compositor_init_config(ec, config) < 0)
1679                 goto out;
1680
1681         if (load_backend(ec, backend, &argc, argv, config) < 0) {
1682                 weston_log("fatal: failed to create compositor backend\n");
1683                 goto out;
1684         }
1685
1686         catch_signals();
1687         segv_compositor = ec;
1688
1689         if (idle_time < 0)
1690                 weston_config_section_get_int(section, "idle-time", &idle_time, -1);
1691         if (idle_time < 0)
1692                 idle_time = 300; /* default idle timeout, in seconds */
1693
1694         ec->idle_time = idle_time;
1695         ec->default_pointer_grab = NULL;
1696         ec->exit = handle_exit;
1697
1698         weston_compositor_log_capabilities(ec);
1699
1700         server_socket = getenv("WAYLAND_SERVER_SOCKET");
1701         if (server_socket) {
1702                 weston_log("Running with single client\n");
1703                 if (!safe_strtoint(server_socket, &fd))
1704                         fd = -1;
1705         } else {
1706                 fd = -1;
1707         }
1708
1709         if (fd != -1) {
1710                 primary_client = wl_client_create(display, fd);
1711                 if (!primary_client) {
1712                         weston_log("fatal: failed to add client: %m\n");
1713                         goto out;
1714                 }
1715                 primary_client_destroyed.notify =
1716                         handle_primary_client_destroyed;
1717                 wl_client_add_destroy_listener(primary_client,
1718                                                &primary_client_destroyed);
1719         } else if (weston_create_listening_socket(display, socket_name)) {
1720                 goto out;
1721         }
1722
1723         if (!shell)
1724                 weston_config_section_get_string(section, "shell", &shell,
1725                                                  "desktop-shell.so");
1726
1727         if (load_modules(ec, shell, &argc, argv) < 0)
1728                 goto out;
1729
1730         weston_config_section_get_string(section, "modules", &modules, "");
1731         if (load_modules(ec, modules, &argc, argv) < 0)
1732                 goto out;
1733
1734         if (load_modules(ec, option_modules, &argc, argv) < 0)
1735                 goto out;
1736
1737         section = weston_config_get_section(config, "keyboard", NULL, NULL);
1738         weston_config_section_get_bool(section, "numlock-on", &numlock_on, 0);
1739         if (numlock_on) {
1740                 wl_list_for_each(seat, &ec->seat_list, link) {
1741                         struct weston_keyboard *keyboard =
1742                                 weston_seat_get_keyboard(seat);
1743
1744                         if (keyboard)
1745                                 weston_keyboard_set_locks(keyboard,
1746                                                           WESTON_NUM_LOCK,
1747                                                           WESTON_NUM_LOCK);
1748                 }
1749         }
1750
1751         for (i = 1; i < argc; i++)
1752                 weston_log("fatal: unhandled option: %s\n", argv[i]);
1753         if (argc > 1)
1754                 goto out;
1755
1756         weston_compositor_wake(ec);
1757
1758         wl_display_run(display);
1759
1760         /* Allow for setting return exit code after
1761         * wl_display_run returns normally. This is
1762         * useful for devs/testers and automated tests
1763         * that want to indicate failure status to
1764         * testing infrastructure above
1765         */
1766         ret = ec->exit_code;
1767
1768 out:
1769         weston_compositor_destroy(ec);
1770
1771 out_signals:
1772         for (i = ARRAY_LENGTH(signals) - 1; i >= 0; i--)
1773                 if (signals[i])
1774                         wl_event_source_remove(signals[i]);
1775
1776         wl_display_destroy(display);
1777
1778         weston_log_file_close();
1779
1780         if (config)
1781                 weston_config_destroy(config);
1782         free(config_file);
1783         free(backend);
1784         free(shell);
1785         free(socket_name);
1786         free(option_modules);
1787         free(log);
1788         free(modules);
1789
1790         return ret;
1791 }