1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
30 int main(int argc, char *argv[]) {
32 struct udev *udev = NULL;
33 struct udev_enumerate *enumerator = NULL;
34 struct udev_list_entry *first, *item;
36 const char *seat = NULL;
38 char *path = NULL, *device_node = NULL;
42 /* This binary will go away as soon as X natively supports
43 * display enumeration with udev in a way that covers both PCI
46 /* This will simply determine the fb device id of the graphics
47 * device assigned to a seat and write a configuration file
48 * from it and then spawn the real X server. */
50 /* If this file is removed, don't forget to remove the code
51 * that invokes this in gdm and other display managers. */
53 for (i = 1; i < argc; i++)
54 if (streq(argv[i], "-seat"))
57 if (isempty(seat) || streq(seat, "seat0")) {
58 argv[0] = (char*) X_SERVER;
59 execv(X_SERVER, argv);
60 log_error("Failed to execute real X server: %m");
66 log_error("Failed to allocate udev environment.");
70 enumerator = udev_enumerate_new(udev);
72 log_error("Failed to allocate udev enumerator.");
76 udev_enumerate_add_match_subsystem(enumerator, "graphics");
77 udev_enumerate_add_match_tag(enumerator, seat);
79 r = udev_enumerate_scan_devices(enumerator);
81 log_error("Failed to enumerate devices.");
85 first = udev_enumerate_get_list_entry(enumerator);
86 udev_list_entry_foreach(item, first) {
87 struct udev_device *d;
90 d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
94 dn = udev_device_get_devnode(d);
97 device_node = strdup(dn);
105 udev_device_unref(d);
112 log_error("Failed to find device node for seat %s.", seat);
116 r = mkdir_safe_label("/run/systemd/multi-session-x", 0755, 0, 0);
118 log_error("Failed to create directory: %s", strerror(-r));
122 path = strappend("/run/systemd/multi-session-x/", seat);
128 f = fopen(path, "we");
130 log_error("Failed to write configuration file: %m");
135 "Section \"Device\"\n"
136 " Identifier \"udev\"\n"
137 " Driver \"fbdev\"\n"
138 " Option \"fbdev\" \"%s\"\n"
140 "Section \"ServerFlags\"\n"
141 " Option \"AutoAddDevices\" \"True\"\n"
142 " Option \"AllowEmptyInput\" \"True\"\n"
143 " Option \"DontVTSwitch\" \"True\"\n"
145 "Section \"InputClass\"\n"
146 " Identifier \"Force Input Devices to Seat\"\n"
147 " Option \"GrabDevice\" \"True\"\n"
154 log_error("Failed to write configuration file: %m");
161 new_argv = alloca(sizeof(char*) * (argc + 3 + 1));
162 memcpy(new_argv, argv, sizeof(char*) * (argc + 2 + 1));
164 new_argv[0] = (char*) X_SERVER;
165 new_argv[argc+0] = (char*) "-config";
166 new_argv[argc+1] = path;
167 new_argv[argc+2] = (char*) "-sharevts";
168 new_argv[argc+3] = NULL;
170 udev_enumerate_unref(enumerator);
179 execv(X_SERVER, new_argv);
180 log_error("Failed to execute real X server: %m");
184 udev_enumerate_unref(enumerator);