services: guix-publish: Add zstd compression by default.
[jackhill/guix/guix.git] / gnu / services / xorg.scm
CommitLineData
db4fdc04 1;;; GNU Guix --- Functional package management for GNU
92753a8b 2;;; Copyright © 2017 Andy Wingo <wingo@igalia.com>
dd0804c6 3;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
4bd43bbe 4;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
e57c2adb 5;;; Copyright © 2018, 2019 Timothy Sample <samplet@ngyro.com>
24f11b06 6;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
bab7a495 7;;; Copyright © 2019 Tim Gesthuizen <tim.gesthuizen@yahoo.de>
779d96c9 8;;; Copyright © 2020 shtwzrd <shtwzrd@protonmail.com>
50be0da7 9;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net>
d8258177 10;;; Copyright © 2020 Alex Griffin <a@ajgrf.com>
db4fdc04
LC
11;;;
12;;; This file is part of GNU Guix.
13;;;
14;;; GNU Guix is free software; you can redistribute it and/or modify it
15;;; under the terms of the GNU General Public License as published by
16;;; the Free Software Foundation; either version 3 of the License, or (at
17;;; your option) any later version.
18;;;
19;;; GNU Guix is distributed in the hope that it will be useful, but
20;;; WITHOUT ANY WARRANTY; without even the implied warranty of
21;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22;;; GNU General Public License for more details.
23;;;
24;;; You should have received a copy of the GNU General Public License
25;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
26
27(define-module (gnu services xorg)
84dfb458 28 #:use-module (gnu artwork)
db4fdc04 29 #:use-module (gnu services)
0190c1c0 30 #:use-module (gnu services shepherd)
6e828634 31 #:use-module (gnu system pam)
598757e0 32 #:use-module (gnu system keyboard)
607fcc75 33 #:use-module (gnu services base)
6e99c01b 34 #:use-module (gnu services dbus)
dfc8ccbf 35 #:use-module (gnu packages base)
bdb36958 36 #:use-module (gnu packages guile)
db4fdc04 37 #:use-module (gnu packages xorg)
7e614198 38 #:use-module (gnu packages fonts)
db4fdc04 39 #:use-module (gnu packages gl)
1f564c15 40 #:use-module (gnu packages glib)
5fd66a37 41 #:use-module (gnu packages display-managers)
607fcc75 42 #:use-module (gnu packages freedesktop)
9e4eddb4 43 #:use-module (gnu packages gnustep)
6e99c01b 44 #:use-module (gnu packages gnome)
db4fdc04
LC
45 #:use-module (gnu packages admin)
46 #:use-module (gnu packages bash)
6e99c01b 47 #:use-module (gnu system shadow)
e429325d 48 #:use-module (guix build-system trivial)
b5f4e686 49 #:use-module (guix gexp)
e87f0591 50 #:use-module (guix store)
6726282b 51 #:use-module (guix packages)
db4fdc04 52 #:use-module (guix derivations)
ffc3a02b 53 #:use-module (guix records)
65a67bf7 54 #:use-module (guix deprecation)
d2e59637 55 #:use-module (srfi srfi-1)
6726282b 56 #:use-module (srfi srfi-9)
d2e59637
LC
57 #:use-module (srfi srfi-26)
58 #:use-module (ice-9 match)
b2e56451
LC
59 #:export (xorg-configuration
60 xorg-configuration?
61 xorg-configuration-modules
62 xorg-configuration-fonts
63 xorg-configuration-drivers
64 xorg-configuration-resolutions
65 xorg-configuration-extra-config
66 xorg-configuration-server
67 xorg-configuration-server-arguments
68
79fd74fa 69 %default-xorg-modules
d344f5a5 70 %default-xorg-fonts
fe0826d5
VH
71 %default-xorg-server-arguments
72
92753a8b 73 xorg-wrapper
d1cdd7ba 74 xorg-start-command
f2901d82 75 xinitrc
e429325d 76 xorg-server-service-type
f2901d82 77
0ecc3bf3
LC
78 %default-slim-theme
79 %default-slim-theme-name
b37f86d7 80
4b7513e0 81 slim-configuration
b37f86d7
LC
82 slim-configuration?
83 slim-configuration-slim
84 slim-configuration-allow-empty-passwords?
85 slim-configuration-auto-login?
86 slim-configuration-default-user
87 slim-configuration-theme
88 slim-configuration-theme-name
89 slim-configuration-xauth
90 slim-configuration-shepherd
91 slim-configuration-auto-login-session
bab7a495 92 slim-configuration-xorg
61569171
DNB
93 slim-configuration-display
94 slim-configuration-vt
bab7a495 95 slim-configuration-sessreg
b37f86d7 96
4b7513e0 97 slim-service-type
6726282b
LC
98 slim-service
99
24e96431
100 screen-locker
101 screen-locker?
6726282b 102 screen-locker-service-type
6e99c01b
AW
103 screen-locker-service
104
607fcc75
LC
105 localed-configuration
106 localed-configuration?
107 localed-service-type
108
6e99c01b
AW
109 gdm-configuration
110 gdm-service-type
305a732a 111 gdm-service
50be0da7
JK
112
113 handle-xorg-configuration
305a732a 114 set-xorg-configuration))
db4fdc04
LC
115
116;;; Commentary:
117;;;
118;;; Services that relate to the X Window System.
119;;;
120;;; Code:
121
d344f5a5 122(define %default-xorg-modules
fd96f94f
PN
123 ;; Default list of modules loaded by the server. When multiple drivers
124 ;; match, the first one in the list is loaded.
d344f5a5
LC
125 (list xf86-video-vesa
126 xf86-video-fbdev
fd96f94f 127 xf86-video-amdgpu
d344f5a5
LC
128 xf86-video-ati
129 xf86-video-cirrus
130 xf86-video-intel
131 xf86-video-mach64
132 xf86-video-nouveau
133 xf86-video-nv
134 xf86-video-sis
135
136 ;; Libinput is the new thing and is recommended over evdev/synaptics:
137 ;; <http://who-t.blogspot.fr/2015/01/xf86-input-libinput-compatibility-with.html>.
138 xf86-input-libinput
139
140 xf86-input-evdev
141 xf86-input-keyboard
142 xf86-input-mouse
143 xf86-input-synaptics))
144
145(define %default-xorg-fonts
146 ;; Default list of fonts available to the X server.
147 (list (file-append font-alias "/share/fonts/X11/75dpi")
148 (file-append font-alias "/share/fonts/X11/100dpi")
149 (file-append font-alias "/share/fonts/X11/misc")
150 (file-append font-alias "/share/fonts/X11/cyrillic")
4afc903a
LC
151 (file-append font-misc-misc ;default fonts for xterm
152 "/share/fonts/X11/misc")
d344f5a5
LC
153 (file-append font-adobe75dpi "/share/fonts/X11/75dpi")))
154
b2e56451
LC
155(define %default-xorg-server-arguments
156 ;; Default command-line arguments for X.
157 '("-nolisten" "tcp"))
158
159;; Configuration of an Xorg server.
160(define-record-type* <xorg-configuration>
161 xorg-configuration make-xorg-configuration
162 xorg-configuration?
163 (modules xorg-configuration-modules ;list of packages
779d96c9 164 ; filter out modules not supported on current system
165 (default (filter
166 (lambda (p)
167 (member (%current-system)
168 (package-supported-systems p)))
169 %default-xorg-modules)))
b2e56451
LC
170 (fonts xorg-configuration-fonts ;list of packges
171 (default %default-xorg-fonts))
172 (drivers xorg-configuration-drivers ;list of strings
173 (default '()))
174 (resolutions xorg-configuration-resolutions ;list of tuples
175 (default '()))
598757e0
LC
176 (keyboard-layout xorg-configuration-keyboard-layout ;#f | <keyboard-layout>
177 (default #f))
b2e56451
LC
178 (extra-config xorg-configuration-extra-config ;list of strings
179 (default '()))
180 (server xorg-configuration-server ;package
181 (default xorg-server))
182 (server-arguments xorg-configuration-server-arguments ;list of strings
183 (default %default-xorg-server-arguments)))
184
185(define (xorg-configuration->file config)
186 "Compute an Xorg configuration file corresponding to CONFIG, an
187<xorg-configuration> record."
8b158e8b
CR
188 (let ((xorg-server (xorg-configuration-server config)))
189 (define all-modules
190 ;; 'xorg-server' provides 'fbdevhw.so' etc.
191 (append (xorg-configuration-modules config)
192 (list xorg-server)))
d344f5a5 193
8b158e8b
CR
194 (define build
195 #~(begin
196 (use-modules (ice-9 match)
197 (srfi srfi-1)
198 (srfi srfi-26))
d344f5a5 199
8b158e8b
CR
200 (call-with-output-file #$output
201 (lambda (port)
202 (define drivers
203 '#$(xorg-configuration-drivers config))
d344f5a5 204
8b158e8b
CR
205 (define (device-section driver)
206 (string-append "
f703413e
LC
207Section \"Device\"
208 Identifier \"device-" driver "\"
209 Driver \"" driver "\"
210EndSection"))
db4fdc04 211
8b158e8b
CR
212 (define (screen-section driver resolutions)
213 (string-append "
d2e59637
LC
214Section \"Screen\"
215 Identifier \"screen-" driver "\"
216 Device \"device-" driver "\"
217 SubSection \"Display\"
218 Modes "
219 (string-join (map (match-lambda
d1cdd7ba
LC
220 ((x y)
221 (string-append "\"" (number->string x)
222 "x" (number->string y) "\"")))
d2e59637
LC
223 resolutions)) "
224 EndSubSection
225EndSection"))
226
8b158e8b
CR
227 (define (input-class-section layout variant model options)
228 (string-append "
598757e0
LC
229Section \"InputClass\"
230 Identifier \"evdev keyboard catchall\"
231 MatchIsKeyboard \"on\"
232 Option \"XkbLayout\" " (object->string layout)
233 (if variant
234 (string-append " Option \"XkbVariant\" \""
235 variant "\"")
236 "")
237 (if model
238 (string-append " Option \"XkbModel\" \""
239 model "\"")
240 "")
241 (match options
242 (()
243 "")
244 (_
245 (string-append " Option \"XkbOptions\" \""
246 (string-join options ",") "\""))) "
247
248 MatchDevicePath \"/dev/input/event*\"
249 Driver \"evdev\"
250EndSection\n"))
251
8b158e8b
CR
252 (define (expand modules)
253 ;; Append to MODULES the relevant /lib/xorg/modules
254 ;; sub-directories.
255 (append-map (lambda (module)
256 (filter-map (lambda (directory)
257 (let ((full (string-append module
258 directory)))
259 (and (file-exists? full)
260 full)))
261 '("/lib/xorg/modules/drivers"
262 "/lib/xorg/modules/input"
263 "/lib/xorg/modules/multimedia"
264 "/lib/xorg/modules/extensions")))
265 modules))
db4fdc04 266
8b158e8b
CR
267 (display "Section \"Files\"\n" port)
268 (for-each (lambda (font)
269 (format port " FontPath \"~a\"~%" font))
270 '#$(xorg-configuration-fonts config))
271 (for-each (lambda (module)
272 (format port
273 " ModulePath \"~a\"~%"
274 module))
275 (append (expand '#$all-modules)
d344f5a5 276
8b158e8b
CR
277 ;; For fbdevhw.so and so on.
278 (list #$(file-append xorg-server
279 "/lib/xorg/modules"))))
280 (display "EndSection\n" port)
281 (display "
db4fdc04 282Section \"ServerFlags\"
e30442b5 283 Option \"AllowMouseOpenFail\" \"on\"
d344f5a5 284EndSection\n" port)
12422c9d 285
8b158e8b
CR
286 (display (string-join (map device-section drivers) "\n")
287 port)
288 (newline port)
289 (display (string-join
290 (map (cut screen-section <>
291 '#$(xorg-configuration-resolutions config))
292 drivers)
293 "\n")
294 port)
295 (newline port)
d344f5a5 296
8b158e8b
CR
297 (let ((layout #$(and=> (xorg-configuration-keyboard-layout config)
298 keyboard-layout-name))
299 (variant #$(and=> (xorg-configuration-keyboard-layout config)
300 keyboard-layout-variant))
301 (model #$(and=> (xorg-configuration-keyboard-layout config)
302 keyboard-layout-model))
303 (options '#$(and=> (xorg-configuration-keyboard-layout config)
304 keyboard-layout-options)))
305 (when layout
306 (display (input-class-section layout variant model options)
307 port)
308 (newline port)))
598757e0 309
8b158e8b
CR
310 (for-each (lambda (config)
311 (display config port))
312 '#$(xorg-configuration-extra-config config))))))
d344f5a5 313
8b158e8b 314 (computed-file "xserver.conf" build)))
db4fdc04 315
79fd74fa
AW
316(define (xorg-configuration-directory modules)
317 "Return a directory that contains the @code{.conf} files for X.org that
318includes the @code{share/X11/xorg.conf.d} directories of each package listed
319in @var{modules}."
4ee96a79
LC
320 (with-imported-modules '((guix build utils))
321 (computed-file "xorg.conf.d"
322 #~(begin
323 (use-modules (guix build utils)
324 (srfi srfi-1))
325
326 (define files
327 (append-map (lambda (module)
328 (find-files (string-append
329 module
330 "/share/X11/xorg.conf.d")
331 "\\.conf$"))
332 (list #$@modules)))
333
334 (mkdir #$output)
335 (for-each (lambda (file)
336 (symlink file
337 (string-append #$output "/"
338 (basename file))))
339 files)
340 #t))))
79fd74fa 341
b2e56451
LC
342(define* (xorg-wrapper #:optional (config (xorg-configuration)))
343 "Return a derivation that builds a script to start the X server with the
344given @var{config}. The resulting script should be used in place of
345@code{/usr/bin/X}."
be1c2c54
LC
346 (define exp
347 ;; Write a small wrapper around the X server.
348 #~(begin
349 (setenv "XORG_DRI_DRIVER_PATH" (string-append #$mesa "/lib/dri"))
350 (setenv "XKB_BINDIR" (string-append #$xkbcomp "/bin"))
351
b2e56451 352 (let ((X (string-append #$(xorg-configuration-server config) "/bin/X")))
92753a8b
AW
353 (apply execl X X
354 "-xkbdir" (string-append #$xkeyboard-config "/share/X11/xkb")
b2e56451
LC
355 "-config" #$(xorg-configuration->file config)
356 "-configdir" #$(xorg-configuration-directory
357 (xorg-configuration-modules config))
92753a8b
AW
358 (cdr (command-line))))))
359
360 (program-file "X-wrapper" exp))
be1c2c54 361
b2e56451
LC
362(define* (xorg-start-command #:optional (config (xorg-configuration)))
363 "Return a @code{startx} script in which the modules, fonts, etc. specified
364in @var{config}, are available. The result should be used in place of
365@code{startx}."
92753a8b 366 (define X
b2e56451
LC
367 (xorg-wrapper config))
368
92753a8b
AW
369 (define exp
370 ;; Write a small wrapper around the X server.
371 #~(apply execl #$X #$X ;; Second #$X is for argv[0].
b2e56451
LC
372 "-logverbose" "-verbose" "-terminate"
373 #$@(xorg-configuration-server-arguments config)
24f11b06 374 (cdr (command-line))))
be1c2c54 375
92753a8b 376 (program-file "startx" exp))
db4fdc04 377
956607e3 378(define* (xinitrc #:key fallback-session)
24d56899
SB
379 "Return a system-wide xinitrc script that starts the specified X session,
380which should be passed to this script as the first argument. If not, the
65c0f436
LC
381@var{fallback-session} will be used or, if @var{fallback-session} is false, a
382desktop session from the system or user profile will be used."
8779d342
LC
383 (define builder
384 #~(begin
65c0f436
LC
385 (use-modules (ice-9 match)
386 (ice-9 regex)
387 (ice-9 ftw)
4e1efba4 388 (ice-9 rdelim)
65c0f436
LC
389 (srfi srfi-1)
390 (srfi srfi-26))
8779d342 391
16c33bfb
LC
392 (define (close-all-fdes)
393 ;; Close all the open file descriptors except 0 to 2.
394 (let loop ((fd 3))
395 (when (< fd 4096) ;FIXME: use sysconf + _SC_OPEN_MAX
396 (false-if-exception (close-fdes fd))
397 (loop (+ 1 fd)))))
398
b2bd7c25
LC
399 (define (exec-from-login-shell command . args)
400 ;; Run COMMAND from a login shell so that it gets to see the same
401 ;; environment variables that one gets when logging in on a tty, for
402 ;; instance.
403 (let* ((pw (getpw (getuid)))
e0b85670
SB
404 (shell (passwd:shell pw)))
405 ;; Close any open file descriptors. This is all the more
406 ;; important that SLiM itself exec's us directly without closing
407 ;; its own file descriptors!
408 (close-all-fdes)
409
410 ;; The '--login' option is supported at least by Bash and zsh.
411 (execl shell shell "--login" "-c"
412 (string-join (cons command args)))))
413
65c0f436
LC
414 (define system-profile
415 "/run/current-system/profile")
416
417 (define user-profile
418 (and=> (getpw (getuid))
419 (lambda (pw)
420 (string-append (passwd:dir pw) "/.guix-profile"))))
421
422 (define (xsession-command desktop-file)
423 ;; Read from DESKTOP-FILE its X session command and return it as a
424 ;; list.
425 (define exec-regexp
426 (make-regexp "^[[:blank:]]*Exec=(.*)$"))
427
428 (call-with-input-file desktop-file
429 (lambda (port)
430 (let loop ()
431 (match (read-line port)
432 ((? eof-object?) #f)
433 ((= (cut regexp-exec exec-regexp <>) result)
434 (if result
435 (string-tokenize (match:substring result 1))
436 (loop))))))))
437
438 (define (find-session profile)
439 ;; Return an X session command from PROFILE or #f if none was found.
440 (let ((directory (string-append profile "/share/xsessions")))
441 (match (scandir directory
442 (cut string-suffix? ".desktop" <>))
443 ((or () #f)
444 #f)
445 ((sessions ...)
446 (any xsession-command
447 (map (cut string-append directory "/" <>)
448 sessions))))))
449
e0b85670
SB
450 (let* ((home (getenv "HOME"))
451 (xsession-file (string-append home "/.xsession"))
452 (session (match (command-line)
65c0f436
LC
453 ((_)
454 #$(if fallback-session
455 #~(list #$fallback-session)
456 #f))
457 ((_ x ..1)
458 x))))
e0b85670
SB
459 (if (file-exists? xsession-file)
460 ;; Run ~/.xsession when it exists.
617e87bf
LC
461 (apply exec-from-login-shell xsession-file
462 (or session '()))
65c0f436
LC
463 ;; Otherwise, start the specified session or a fallback.
464 (apply exec-from-login-shell
465 (or session
466 (find-session user-profile)
467 (find-session system-profile)))))))
c510cbb4 468
be1c2c54 469 (program-file "xinitrc" builder))
9e4eddb4 470
50be0da7
JK
471(define-syntax handle-xorg-configuration
472 (syntax-rules ()
473 "Generate the `compose' and `extend' entries of a login manager
474`service-type' to handle specifying the `xorg-configuration' through
475a `service-extension', as used by `set-xorg-configuration'."
476 ((_ configuration-record service-type-definition)
477 (service-type
478 (inherit service-type-definition)
479 (compose (lambda (extensions)
480 (match extensions
481 (() #f)
482 ((config . _) config))))
483 (extend (lambda (config xorg-configuration)
484 (if xorg-configuration
485 (configuration-record
486 (inherit config)
487 (xorg-configuration xorg-configuration))
488 config)))))))
489
e429325d
SB
490(define (xorg-server-profile-service config)
491 ;; XXX: profile-service-type only accepts <package> objects.
492 (list
493 (package
494 (name "xorg-wrapper")
495 (version (package-version xorg-server))
496 (source (xorg-wrapper config))
497 (build-system trivial-build-system)
498 (arguments
499 '(#:modules ((guix build utils))
500 #:builder
501 (begin
502 (use-modules (guix build utils))
503 (let* ((source (assoc-ref %build-inputs "source"))
504 (out (assoc-ref %outputs "out"))
505 (bin (string-append out "/bin")))
506 (mkdir-p bin)
507 (symlink source (string-append bin "/X"))
508 (symlink source (string-append bin "/Xorg"))
509 #t))))
510 (home-page (package-home-page xorg-server))
511 (synopsis (package-synopsis xorg-server))
512 (description (package-description xorg-server))
513 (license (package-license xorg-server)))))
514
515(define xorg-server-service-type
516 (service-type
517 (name 'xorg-server)
518 (extensions
519 (list (service-extension profile-service-type
520 xorg-server-profile-service)))
521 (default-value (xorg-configuration))
522 (description "Add @command{X} to the system profile, to be used with
523@command{sx} or @command{xinit}.")))
524
0ecc3bf3
LC
525\f
526;;;
527;;; SLiM log-in manager.
528;;;
529
0ecc3bf3
LC
530(define %default-slim-theme
531 ;; Theme based on work by Felipe López.
9e41130b 532 (file-append %artwork-repository "/slim"))
0ecc3bf3
LC
533
534(define %default-slim-theme-name
535 ;; This must be the name of the sub-directory in %DEFAULT-SLIM-THEME that
536 ;; contains the actual theme files.
2f9f792a 537 "1.x")
0ecc3bf3 538
0adfe95a
LC
539(define-record-type* <slim-configuration>
540 slim-configuration make-slim-configuration
541 slim-configuration?
542 (slim slim-configuration-slim
543 (default slim))
b37f86d7
LC
544 (allow-empty-passwords? slim-configuration-allow-empty-passwords?
545 (default #t))
546 (auto-login? slim-configuration-auto-login?
547 (default #f))
548 (default-user slim-configuration-default-user
549 (default ""))
550 (theme slim-configuration-theme
551 (default %default-slim-theme))
552 (theme-name slim-configuration-theme-name
553 (default %default-slim-theme-name))
0adfe95a
LC
554 (xauth slim-configuration-xauth
555 (default xauth))
26b94866
AK
556 (shepherd slim-configuration-shepherd
557 (default shepherd))
b37f86d7 558 (auto-login-session slim-configuration-auto-login-session
65c0f436 559 (default #f))
554b8607
LC
560 (xorg-configuration slim-configuration-xorg
561 (default (xorg-configuration)))
61569171
DNB
562 (display slim-configuration-display
563 (default ":0"))
564 (vt slim-configuration-vt
565 (default "vt7"))
736e45a2
DM
566 (sessreg slim-configuration-sessreg
567 (default sessreg)))
0adfe95a
LC
568
569(define (slim-pam-service config)
570 "Return a PAM service for @command{slim}."
571 (list (unix-pam-service
572 "slim"
e6b1a224 573 #:login-uid? #t
0adfe95a
LC
574 #:allow-empty-passwords?
575 (slim-configuration-allow-empty-passwords? config))))
576
d4053c71 577(define (slim-shepherd-service config)
61569171
DNB
578 (let* ((xinitrc (xinitrc #:fallback-session
579 (slim-configuration-auto-login-session config)))
580 (xauth (slim-configuration-xauth config))
581 (startx (xorg-start-command (slim-configuration-xorg config)))
582 (display (slim-configuration-display config))
583 (vt (slim-configuration-vt config))
584 (shepherd (slim-configuration-shepherd config))
585 (theme-name (slim-configuration-theme-name config))
586 (sessreg (slim-configuration-sessreg config))
587 (lockfile (string-append "/var/run/slim-" vt ".lock")))
588 (define slim.cfg
0adfe95a
LC
589 (mixed-text-file "slim.cfg" "
590default_path /run/current-system/profile/bin
591default_xserver " startx "
61569171
DNB
592display_name " display "
593xserver_arguments " vt "
0adfe95a 594xauth_path " xauth "/bin/xauth
61569171
DNB
595authfile /var/run/slim-" vt ".auth
596lockfile " lockfile "
597logfile /var/log/slim-" vt ".log
0adfe95a
LC
598
599# The login command. '%session' is replaced by the chosen session name, one
600# of the names specified in the 'sessions' setting: 'wmaker', 'xfce', etc.
601login_cmd exec " xinitrc " %session
602sessiondir /run/current-system/profile/share/xsessions
603session_msg session (F1 to change):
736e45a2
DM
604sessionstart_cmd " sessreg "/bin/sessreg -a -l $DISPLAY %user
605sessionstop_cmd " sessreg "/bin/sessreg -d -l $DISPLAY %user
0adfe95a 606
26b94866
AK
607halt_cmd " shepherd "/sbin/halt
608reboot_cmd " shepherd "/sbin/reboot\n"
0adfe95a
LC
609(if (slim-configuration-auto-login? config)
610 (string-append "auto_login yes\ndefault_user "
611 (slim-configuration-default-user config) "\n")
612 "")
613(if theme-name
614 (string-append "current_theme " theme-name "\n")
61569171
DNB
615 "")))
616
617 (define theme
618 (slim-configuration-theme config))
619
620 (list (shepherd-service
621 (documentation "Xorg display server")
6ad799d7
LC
622 (provision (append
623 ;; For compatibility, also provide 'xorg-server'.
624 (if (string=? vt "vt7")
625 '(xorg-server)
626 '())
627
628 (list (symbol-append 'xorg-server-
629 (string->symbol vt)))))
61569171
DNB
630 (requirement '(user-processes host-name udev))
631 (start
632 #~(lambda ()
633 ;; A stale lock file can prevent SLiM from starting, so remove it to
634 ;; be on the safe side.
635 (false-if-exception (delete-file lockfile))
636
637 (fork+exec-command
638 (list (string-append #$(slim-configuration-slim config)
639 "/bin/slim")
640 "-nodaemon")
641 #:environment-variables
642 (list (string-append "SLIM_CFGFILE=" #$slim.cfg)
643 #$@(if theme
644 (list #~(string-append "SLIM_THEMESDIR=" #$theme))
645 #~())))))
646 (stop #~(make-kill-destructor))
647 (respawn? #t)))))
0adfe95a
LC
648
649(define slim-service-type
50be0da7
JK
650 (handle-xorg-configuration slim-configuration
651 (service-type (name 'slim)
652 (extensions
653 (list (service-extension shepherd-root-service-type
654 slim-shepherd-service)
655 (service-extension pam-root-service-type
656 slim-pam-service)
e9b82124 657
50be0da7
JK
658 ;; Unconditionally add xterm to the system profile, to
659 ;; avoid bad surprises.
660 (service-extension profile-service-type
661 (const (list xterm)))))
662
dd0804c6
LC
663 (default-value (slim-configuration))
664 (description
665 "Run the SLiM graphical login manager for X11."))))
0adfe95a 666
65a67bf7
LC
667(define-deprecated (slim-service #:key (slim slim)
668 (allow-empty-passwords? #t) auto-login?
669 (default-user "")
670 (theme %default-slim-theme)
671 (theme-name %default-slim-theme-name)
672 (xauth xauth) (shepherd shepherd)
673 (auto-login-session #f)
674 (startx (xorg-start-command)))
675 slim-service-type
db4fdc04 676 "Return a service that spawns the SLiM graphical login manager, which in
51da7ca0
LC
677turn starts the X display server with @var{startx}, a command as returned by
678@code{xorg-start-command}.
db4fdc04 679
04e4e6ab
LC
680@cindex X session
681
682SLiM automatically looks for session types described by the @file{.desktop}
683files in @file{/run/current-system/profile/share/xsessions} and allows users
684to choose a session from the log-in screen using @kbd{F1}. Packages such as
685@var{xfce}, @var{sawfish}, and @var{ratpoison} provide @file{.desktop} files;
686adding them to the system-wide set of packages automatically makes them
687available at the log-in screen.
688
689In addition, @file{~/.xsession} files are honored. When available,
690@file{~/.xsession} must be an executable that starts a window manager
691and/or other X clients.
692
51da7ca0
LC
693When @var{allow-empty-passwords?} is true, allow logins with an empty
694password. When @var{auto-login?} is true, log in automatically as
24d56899 695@var{default-user} with @var{auto-login-session}.
0ecc3bf3
LC
696
697If @var{theme} is @code{#f}, the use the default log-in theme; otherwise
698@var{theme} must be a gexp denoting the name of a directory containing the
699theme to use. In that case, @var{theme-name} specifies the name of the
4bd43bbe 700theme."
0adfe95a
LC
701 (service slim-service-type
702 (slim-configuration
703 (slim slim)
704 (allow-empty-passwords? allow-empty-passwords?)
705 (auto-login? auto-login?) (default-user default-user)
706 (theme theme) (theme-name theme-name)
94b9abd9 707 (xauth xauth) (shepherd shepherd)
554b8607 708 (auto-login-session auto-login-session))))
db4fdc04 709
6726282b
LC
710\f
711;;;
712;;; Screen lockers & co.
713;;;
714
715(define-record-type <screen-locker>
716 (screen-locker name program empty?)
717 screen-locker?
718 (name screen-locker-name) ;string
719 (program screen-locker-program) ;gexp
720 (empty? screen-locker-allows-empty-passwords?)) ;Boolean
721
722(define screen-locker-pam-services
723 (match-lambda
724 (($ <screen-locker> name _ empty?)
725 (list (unix-pam-service name
726 #:allow-empty-passwords? empty?)))))
727
728(define screen-locker-setuid-programs
729 (compose list screen-locker-program))
730
731(define screen-locker-service-type
732 (service-type (name 'screen-locker)
733 (extensions
734 (list (service-extension pam-root-service-type
735 screen-locker-pam-services)
736 (service-extension setuid-program-service-type
dd0804c6
LC
737 screen-locker-setuid-programs)))
738 (description
739 "Allow the given program to be used as a screen locker for
740the graphical server by making it setuid-root, so it can authenticate users,
741and by creating a PAM service for it.")))
6726282b
LC
742
743(define* (screen-locker-service package
744 #:optional
745 (program (package-name package))
746 #:key allow-empty-passwords?)
d64e1746 747 "Add @var{package}, a package for a screen locker or screen saver whose
6726282b
LC
748command is @var{program}, to the set of setuid programs and add a PAM entry
749for it. For example:
750
751@lisp
9e41130b 752 (screen-locker-service xlockmore \"xlock\")
6726282b
LC
753@end lisp
754
755makes the good ol' XlockMore usable."
756 (service screen-locker-service-type
757 (screen-locker program
9e41130b 758 (file-append package "/bin/" program)
6726282b
LC
759 allow-empty-passwords?)))
760
607fcc75
LC
761\f
762;;;
763;;; Locale service.
764;;;
765
766(define-record-type* <localed-configuration>
767 localed-configuration make-localed-configuration
768 localed-configuration?
769 (localed localed-configuration-localed
770 (default localed))
771 (keyboard-layout localed-configuration-keyboard-layout
772 (default #f)))
773
774(define (localed-dbus-service config)
775 "Return the 'localed' D-Bus service for @var{config}, a
776@code{<localed-configuration>} record."
777 (define keyboard-layout
778 (localed-configuration-keyboard-layout config))
779
780 ;; The primary purpose of 'localed' is to tell GDM what the "current" Xorg
781 ;; keyboard layout is. If 'localed' is missing, or if it's unable to
782 ;; determine the current XKB layout, then GDM forcefully installs its
783 ;; default XKB config (US English). Here we communicate the configured
784 ;; layout through environment variables.
785
786 (if keyboard-layout
787 (let* ((layout (keyboard-layout-name keyboard-layout))
788 (variant (keyboard-layout-variant keyboard-layout))
789 (model (keyboard-layout-model keyboard-layout))
790 (options (keyboard-layout-options keyboard-layout)))
791 (list (wrapped-dbus-service
792 (localed-configuration-localed config)
793 "libexec/localed/localed"
794 `(("GUIX_XKB_LAYOUT" ,layout)
795 ,@(if variant
796 `(("GUIX_XKB_VARIANT" ,variant))
797 '())
798 ,@(if model
799 `(("GUIX_XKB_MODEL" ,model))
800 '())
801 ,@(if (null? options)
802 '()
803 `(("GUIX_XKB_OPTIONS"
804 ,(string-join options ","))))))))
3ef3bdf1 805 '()))
607fcc75
LC
806
807(define localed-service-type
13615849
LC
808 (let ((package (lambda (config)
809 ;; Don't bother if the user didn't specify any keyboard
810 ;; layout.
811 (if (localed-configuration-keyboard-layout config)
812 (list (localed-configuration-localed config))
813 '()))))
607fcc75
LC
814 (service-type (name 'localed)
815 (extensions
816 (list (service-extension dbus-root-service-type
817 localed-dbus-service)
818 (service-extension udev-service-type package)
819 (service-extension polkit-service-type package)
820
821 ;; Add 'localectl' to the profile.
822 (service-extension profile-service-type package)))
823
824 ;; This service can be extended, typically by the X login
825 ;; manager, to communicate the chosen Xorg keyboard layout.
13615849
LC
826 (compose (lambda (extensions)
827 (find keyboard-layout? extensions)))
607fcc75
LC
828 (extend (lambda (config keyboard-layout)
829 (localed-configuration
830 (inherit config)
831 (keyboard-layout keyboard-layout))))
832 (description
833 "Run the locale daemon, @command{localed}, which can be used
834to control the system locale and keyboard mapping from user programs such as
835the GNOME desktop environment.")
836 (default-value (localed-configuration)))))
837
838\f
839;;;
840;;; GNOME Desktop Manager.
841;;;
842
6e99c01b
AW
843(define %gdm-accounts
844 (list (user-group (name "gdm") (system? #t))
845 (user-account
846 (name "gdm")
847 (group "gdm")
acb41a40 848 (supplementary-groups '("video"))
6e99c01b
AW
849 (system? #t)
850 (comment "GNOME Display Manager user")
851 (home-directory "/var/lib/gdm")
852 (shell (file-append shadow "/sbin/nologin")))))
853
a43e9157
LC
854(define %gdm-activation
855 ;; Ensure /var/lib/gdm is owned by the "gdm" user. This is normally the
856 ;; case but could be wrong if the "gdm" user was created, then removed, and
857 ;; then recreated under a different UID/GID: <https://bugs.gnu.org/37423>.
858 (with-imported-modules '((guix build utils))
859 #~(begin
860 (use-modules (guix build utils))
861
862 (let* ((gdm (getpwnam "gdm"))
863 (uid (passwd:uid gdm))
864 (gid (passwd:gid gdm))
865 (st (stat "/var/lib/gdm" #f)))
866 ;; Recurse into /var/lib/gdm only if it has wrong ownership.
867 (when (and st
868 (or (not (= uid (stat:uid st)))
869 (not (= gid (stat:gid st)))))
870 (for-each (lambda (file)
871 (chown file uid gid))
872 (find-files "/var/lib/gdm"
873 #:directories? #t)))))))
874
1f564c15 875(define dbus-daemon-wrapper
dcb3a0fe
TS
876 (program-file
877 "gdm-dbus-wrapper"
878 #~(begin
879 (use-modules (srfi srfi-26))
880
881 (define system-profile
882 "/run/current-system/profile")
883
884 (define user-profile
885 (and=> (getpw (getuid))
886 (lambda (pw)
887 (string-append (passwd:dir pw) "/.guix-profile"))))
888
889 ;; If we are able to find the user's profile, we can add it to
890 ;; the search paths set below. We need to do this so that D-Bus
891 ;; can start services installed by the user. This allows
892 ;; applications that require session D-Bus services (e.g,
893 ;; 'evolution') to work even if those services are only available
894 ;; in the user's profile. See <https://bugs.gnu.org/35267>.
895 (define profiles
896 (if user-profile
897 (list user-profile system-profile)
898 (list system-profile)))
899
900 (setenv "XDG_CONFIG_DIRS"
901 (string-join (map (cut string-append <> "/etc/xdg") profiles)
902 ":"))
903 (setenv "XDG_DATA_DIRS"
904 (string-join (map (cut string-append <> "/share") profiles)
905 ":"))
906 (apply execl (string-append #$dbus "/bin/dbus-daemon")
907 (program-arguments)))))
1f564c15 908
6e99c01b
AW
909(define-record-type* <gdm-configuration>
910 gdm-configuration make-gdm-configuration
911 gdm-configuration?
912 (gdm gdm-configuration-gdm (default gdm))
913 (allow-empty-passwords? gdm-configuration-allow-empty-passwords? (default #t))
6e99c01b 914 (auto-login? gdm-configuration-auto-login? (default #f))
1f564c15 915 (dbus-daemon gdm-configuration-dbus-daemon (default dbus-daemon-wrapper))
88f95687 916 (debug? gdm-configuration-debug? (default #f))
6e99c01b 917 (default-user gdm-configuration-default-user (default #f))
7e614198
TS
918 (gnome-shell-assets gdm-configuration-gnome-shell-assets
919 (default (list adwaita-icon-theme font-cantarell)))
554b8607
LC
920 (xorg-configuration gdm-configuration-xorg
921 (default (xorg-configuration)))
41fa9f18
TS
922 (x-session gdm-configuration-x-session
923 (default (xinitrc))))
6e99c01b 924
e57c2adb
TS
925(define (gdm-configuration-file config)
926 (mixed-text-file "gdm-custom.conf"
927 "[daemon]\n"
928 "#User=gdm\n"
929 "#Group=gdm\n"
930 (if (gdm-configuration-auto-login? config)
931 (string-append
932 "AutomaticLoginEnable=true\n"
933 "AutomaticLogin="
934 (or (gdm-configuration-default-user config)
935 (error "missing default user for auto-login"))
936 "\n")
937 (string-append
938 "AutomaticLoginEnable=false\n"
939 "#AutomaticLogin=\n"))
940 "#TimedLoginEnable=false\n"
941 "#TimedLogin=\n"
942 "#TimedLoginDelay=0\n"
9111f975
LP
943 ;; Disable initial system setup inside GDM.
944 ;; Whatever settings are set there should already be
945 ;; taken care of through `guix system'.
946 ;; See also
947 ;; <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=39281>.
948 "InitialSetupEnable=false\n"
e57c2adb
TS
949 ;; Enable me once X is working.
950 "WaylandEnable=false\n"
951 "\n"
952 "[debug]\n"
88f95687
TS
953 "Enable=" (if (gdm-configuration-debug? config)
954 "true"
955 "false") "\n"
e57c2adb
TS
956 "\n"
957 "[security]\n"
958 "#DisallowTCP=true\n"
959 "#AllowRemoteAutoLogin=false\n"))
6e99c01b
AW
960
961(define (gdm-pam-service config)
962 "Return a PAM service for @command{gdm}."
963 (list
964 (pam-service
e6b1a224
LC
965 (inherit (unix-pam-service "gdm-autologin"
966 #:login-uid? #t))
6e99c01b 967 (auth (list (pam-entry
d8258177 968 (control "optional")
6e99c01b
AW
969 (module (file-append (gdm-configuration-gdm config)
970 "/lib/security/pam_gdm.so")))
971 (pam-entry
972 (control "sufficient")
973 (module "pam_permit.so")))))
974 (pam-service
975 (inherit (unix-pam-service "gdm-launch-environment"))
976 (auth (list (pam-entry
977 (control "required")
978 (module "pam_permit.so")))))
de409e82 979 (unix-pam-service "gdm-password"
e6b1a224 980 #:login-uid? #t
de409e82
TS
981 #:allow-empty-passwords?
982 (gdm-configuration-allow-empty-passwords? config))))
6e99c01b
AW
983
984(define (gdm-shepherd-service config)
985 (list (shepherd-service
986 (documentation "Xorg display server (GDM)")
987 (provision '(xorg-server))
988 (requirement '(dbus-system user-processes host-name udev))
6e99c01b
AW
989 (start #~(lambda ()
990 (fork+exec-command
991 (list #$(file-append (gdm-configuration-gdm config)
992 "/bin/gdm"))
993 #:environment-variables
994 (list (string-append
e57c2adb
TS
995 "GDM_CUSTOM_CONF="
996 #$(gdm-configuration-file config))
1f564c15
TS
997 (string-append
998 "GDM_DBUS_DAEMON="
999 #$(gdm-configuration-dbus-daemon config))
e57c2adb 1000 (string-append
6e99c01b 1001 "GDM_X_SERVER="
554b8607
LC
1002 #$(xorg-wrapper
1003 (gdm-configuration-xorg config)))
41fa9f18
TS
1004 (string-append
1005 "GDM_X_SESSION="
1006 #$(gdm-configuration-x-session config))
7e614198
TS
1007 (string-append
1008 "XDG_DATA_DIRS="
1009 ((lambda (ls) (string-join ls ":"))
1010 (map (lambda (path)
1011 (string-append path "/share"))
1012 ;; XXX: Remove gnome-shell below when GDM
1013 ;; can depend on GNOME Shell directly.
1014 (cons #$gnome-shell
1015 '#$(gdm-configuration-gnome-shell-assets
1016 config)))))))))
6e99c01b
AW
1017 (stop #~(make-kill-destructor))
1018 (respawn? #t))))
1019
1020(define gdm-service-type
50be0da7
JK
1021 (handle-xorg-configuration gdm-configuration
1022 (service-type (name 'gdm)
1023 (extensions
1024 (list (service-extension shepherd-root-service-type
1025 gdm-shepherd-service)
1026 (service-extension activation-service-type
1027 (const %gdm-activation))
1028 (service-extension account-service-type
1029 (const %gdm-accounts))
1030 (service-extension pam-root-service-type
1031 gdm-pam-service)
1032 (service-extension profile-service-type
1033 gdm-configuration-gnome-shell-assets)
1034 (service-extension dbus-root-service-type
1035 (compose list
1036 gdm-configuration-gdm))
1037 (service-extension localed-service-type
1038 (compose
1039 xorg-configuration-keyboard-layout
1040 gdm-configuration-xorg))))
1041 (default-value (gdm-configuration))
1042 (description
1043 "Run the GNOME Desktop Manager (GDM), a program that allows
1044you to log in in a graphical session, whether or not you use GNOME."))))
6e99c01b 1045
65a67bf7
LC
1046(define-deprecated (gdm-service #:key (gdm gdm)
1047 (allow-empty-passwords? #t)
1048 (x-server (xorg-wrapper)))
1049 gdm-service-type
6e99c01b
AW
1050 "Return a service that spawns the GDM graphical login manager, which in turn
1051starts the X display server with @var{X}, a command as returned by
1052@code{xorg-wrapper}.
1053
1054@cindex X session
1055
1056GDM automatically looks for session types described by the @file{.desktop}
1057files in @file{/run/current-system/profile/share/xsessions} and allows users
1058to choose a session from the log-in screen using @kbd{F1}. Packages such as
1059@var{xfce}, @var{sawfish}, and @var{ratpoison} provide @file{.desktop} files;
1060adding them to the system-wide set of packages automatically makes them
1061available at the log-in screen.
1062
1063In addition, @file{~/.xsession} files are honored. When available,
1064@file{~/.xsession} must be an executable that starts a window manager
1065and/or other X clients.
1066
1067When @var{allow-empty-passwords?} is true, allow logins with an empty
1068password."
1069 (service gdm-service-type
1070 (gdm-configuration
1071 (gdm gdm)
554b8607 1072 (allow-empty-passwords? allow-empty-passwords?))))
6e99c01b 1073
305a732a
LC
1074(define* (set-xorg-configuration config
1075 #:optional
1076 (login-manager-service-type
1077 gdm-service-type))
1078 "Tell the log-in manager (of type @var{login-manager-service-type}) to use
1079@var{config}, an <xorg-configuration> record."
1080 (simple-service 'set-xorg-configuration
1081 login-manager-service-type
1082 config))
1083
db4fdc04 1084;;; xorg.scm ends here