aboutsummaryrefslogtreecommitdiff
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2018, 2021 Mathieu Othacehe <othacehe@gnu.org>
;;; Copyright © 2020 Florian Pelz <pelzflorian@pelzflorian.de>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu installer keymap)
  #:use-module (guix records)
  #:use-module (sxml match)
  #:use-module (sxml simple)
  #:use-module (ice-9 binary-ports)
  #:use-module (ice-9 ftw)
  #:use-module (ice-9 match)
  #:use-module (ice-9 regex)
  #:export (<x11-keymap-model>
            x11-keymap-model
            make-x11-keymap-model
            x11-keymap-model?
            x11-keymap-model-name
            x11-keymap-model-description

            <x11-keymap-layout>
            x11-keymap-layout
            make-x11-keymap-layout
            x11-keymap-layout?
            x11-keymap-layout-name
            x11-keymap-layout-synopsis
            x11-keymap-layout-description
            x11-keymap-layout-variants

            <x11-keymap-variant>
            x11-keymap-variant
            make-x11-keymap-variant
            x11-keymap-variant?
            x11-keymap-variant-name
            x11-keymap-variant-description

            default-keyboard-model
            xkb-rules->models+layouts
            kmscon-update-keymap))

(define-record-type* <x11-keymap-model>
  x11-keymap-model make-x11-keymap-model
  x11-keymap-model?
  (name            x11-keymap-model-name) ;string
  (description     x11-keymap-model-description)) ;string

(define-record-type* <x11-keymap-layout>
  x11-keymap-layout make-x11-keymap-layout
  x11-keymap-layout?
  (name            x11-keymap-layout-name) ;string
  (synopsis        x11-keymap-layout-synopsis)    ;string (e.g., "en")
  (description     x11-keymap-layout-description) ;string (a whole phrase)
  (variants        x11-keymap-layout-variants)) ;list of <x11-keymap-variant>

(define-record-type* <x11-keymap-variant>
  x11-keymap-variant make-x11-keymap-variant
  x11-keymap-variant?
  (name            x11-keymap-variant-name) ;string
  (description     x11-keymap-variant-description)) ;string

;; Assume all modern keyboards have this model.
(define default-keyboard-model (make-parameter "pc105"))

(define (xkb-rules->models+layouts file)
  "Parse FILE and return two values, the list of supported X11-KEYMAP-MODEL
and X11-KEYMAP-LAYOUT records. FILE is an XML file from the X Keyboard
Configuration Database, describing possible XKB configurations."
  (define maybe-empty
    (match-lambda
      ((x) x)
      (#f "")))

  (define (model m)
    (sxml-match m
                [(model
                  (configItem
                   (name ,name)
                   (description ,description)
                   . ,rest))
                 (x11-keymap-model
                  (name name)
                  (description description))]))

  (define (variant v)
    (sxml-match v
                [(variant
                  ;; According to xbd-rules DTD, the definition of a
                  ;; configItem is: <!ELEMENT configItem
                  ;; (name,shortDescription*,description*,vendor?,
                  ;; countryList?,languageList?,hwList?)>
                  ;;
                  ;; shortDescription and description are optional elements
                  ;; but sxml-match does not support default values for
                  ;; elements (only attributes). So to avoid writing as many
                  ;; patterns as existing possibilities, gather all the
                  ;; remaining elements but name in REST-VARIANT.
                  (configItem
                   (name ,name)
                   . ,rest-variant))
                 (x11-keymap-variant
                  (name name)
                  (description (maybe-empty
                                (assoc-ref rest-variant 'description))))]))

  (define (layout l)
    (sxml-match l
                [(layout
                  (configItem
                   (name ,name)
                   . ,rest-layout)
                  (variantList ,[variant -> v] ...))
                 (x11-keymap-layout
                  (name name)
                  (synopsis (maybe-empty
                             (assoc-ref rest-layout 'shortDescription)))
                  (description (maybe-empty
                                (assoc-ref rest-layout 'description)))
                  (variants (list v ...)))]
                [(layout
                  (configItem
                   (name ,name)
                   . ,rest-layout))
                 (x11-keymap-layout
                  (name name)
                  (synopsis (maybe-empty
                             (assoc-ref rest-layout 'shortDescription)))
                  (description (maybe-empty
                                (assoc-ref rest-layout 'description)))
                  (variants '()))]))

  (let ((sxml (call-with-input-file file
                (lambda (port)
                  (xml->sxml port #:trim-whitespace? #t)))))
    (match
        (sxml-match sxml
                    [(*TOP*
                      ,pi
                      (xkbConfigRegistry
                       (@ . ,ignored)
                       (modelList ,[model -> m] ...)
                       (layoutList ,[layout -> l] ...)
                       . ,rest))
                     (list
                      (list m ...)
                      (list l ...))])
      ((models layouts)
       (values models layouts)))))

(define (kmscon-update-keymap model layout variant options)
  "Update kmscon keymap with the provided MODEL, LAYOUT, VARIANT and OPTIONS."
  (and=>
   (getenv "KEYMAP_UPDATE")
   (lambda (keymap-file)
     (unless (file-exists? keymap-file)
       (error "Unable to locate keymap update file"))

     ;; See file gnu/packages/patches/kmscon-runtime-keymap-switch.patch.
     ;; This dirty hack makes possible to update kmscon keymap at runtime by
     ;; writing an X11 keyboard model, layout and variant to a named pipe
     ;; referred by KEYMAP_UPDATE environment variable.
     (call-with-output-file keymap-file
       (lambda (port)
         (format port model)
         (put-u8 port 0)

         (format port layout)
         (put-u8 port 0)

         (format port (or variant ""))
         (put-u8 port 0)

         (format port (or options ""))
         (put-u8 port 0))))))
7c'>gnu: qtractor: Update to 0.9.19....* gnu/packages/music.scm (qtractor): Update to 0.9.19. Tobias Geerinckx-Rice 2021-01-02gnu: padthv1: Update to 0.9.19....* gnu/packages/music.scm (padthv1): Update to 0.9.19. Tobias Geerinckx-Rice 2021-01-02gnu: samplv1: Update to 0.9.19....* gnu/packages/music.scm (samplv1): Update to 0.9.19. Tobias Geerinckx-Rice 2021-01-02gnu: drumkv1: Update to 0.9.19....* gnu/packages/music.scm (drumkv1): Update to 0.9.19. Tobias Geerinckx-Rice 2021-01-02gnu: synthv1: Update to 0.9.19....* gnu/packages/music.scm (synthv1): Update to 0.9.19. Tobias Geerinckx-Rice 2020-12-31gnu: vmpk: Update to 0.8.0....* gnu/packages/music.scm (vmpk): Update to 0.8.0. Ricardo Wurmus 2020-12-31gnu: drumstick: Update to 2.0.0....* gnu/packages/music.scm (drumstick): Update to 2.0.0. [inputs]: Add qttools. [native-inputs]: Add graphviz. Ricardo Wurmus 2020-12-30gnu: zrythm: Update to 1.0.0-alpha.6.0.1....* gnu/packages/music.scm (zrythm): Update to 1.0.0-alpha.6.0.1. Signed-off-by: Leo Famulari <leo@famulari.name> Ryan Prior via Guix-patches via 2020-12-30gnu: milkytracker: Update to 1.03.00....* gnu/packages/music.scm (milkytracker): Update to 1.03.00. Signed-off-by: Leo Famulari <leo@famulari.name> Vincent Legoll 2020-12-29gnu: frescobaldi: Update to 3.1.3....* gnu/packages/music.scm (frescobaldi): Update to 3.1.3. Nicolas Goaziou 2020-12-28gnu: rosegarden: Update to 20.12....* gnu/packages/music.scm (rosegarden): Update to 20.12. Nicolas Goaziou 2020-12-27gnu: portmidi: Install pkg-config file....* gnu/packages/music.scm (portmidi)[arguments]: Add 'install-pkg-config phase. Kei Kebreau 2020-12-27gnu: powertabeditor: Update to 2.0.0-alpha14....* gnu/packages/music.scm (powertabeditor): Update to 2.0.0-alpha14. [arguments]: Add phase "fix-pugixml-detection". Ricardo Wurmus 2020-12-20gnu: pd: Update to 0.51-3....* gnu/packages/music.scm (pd): Update to 0.51-3. Tobias Geerinckx-Rice 2020-11-26gnu: Add audacious....* gnu/packages/music.scm (audacious): New variable. Signed-off-by: Nicolas Goaziou <mail@nicolasgoaziou.fr> Kei Kebreau 2020-11-19gnu: Don't append '.git' to GitHub uris....* gnu/packages/admin.scm (nmrpflash)[source]: Remove '.git' from URI. * gnu/packages/aidc.scm (zxing-cpp), * gnu/packages/assembly.scm (mbuild), * gnu/packages/audio.scm (opensles, wildmidi, tinyalsa), * gnu/packages/browser-extensions.scm (ublock-origin-chromium), * gnu/packages/check.scm (mutest), * gnu/packages/compression.scm (unshield), * gnu/packages/coq.scm (subset), * gnu/packages/dictionaries.scm (translate-shell), * gnu/packages/disk.scm (memkind), * gnu/packages/documentation.scm (latex2html), * gnu/packages/emacs-xyz.scm (emacs-chronometrist, emacs-flycheck-ledger, emacs-counsel-notmuch, emacs-spaceline, emacs-org-generate), * gnu/packages/embedded.scm (ebusd, ebusd-configuration), * gnu/packages/enchant.scm (nuspell), * gnu/packages/fontutils.scm (woff2), * gnu/packages/geo.scm (memphis), * gnu/packages/gimp.scm (mrg), * gnu/packages/gnome-xyz.scm (gnome-shell-extension-appindicator), * gnu/packages/gnome.scm (parlatype), * gnu/packages/golang.scm (go-github-com-tv42-httpunix, go-github-com-ayufan-golang-kardianos-service), * gnu/packages/graphics.scm (eglexternalplatform, egl-wayland, mmm, directfb, flux), * gnu/packages/gstreamer.scm (openni2, ccextractor, libvisual, graphene), * gnu/packages/guile-xyz.scm (guile-srfi-180, guile-torrent), * gnu/packages/image.scm (openjpeg-data), * gnu/packages/java.scm (javacc), * gnu/packages/language.scm (liblouis, liblouisutdml), * gnu/packages/linux.scm (pamela, ttyebus), * gnu/packages/lxqt.scm (lxqt-connman-applet), * gnu/packages/mail.scm (libetpan), * gnu/packages/man.scm (ronn), * gnu/packages/music.scm (tascam-gtk, artyfx), * gnu/packages/networking.scm (srt, lksctp-tools, nng, nanomsg), * gnu/packages/python-crypto.scm (pure-python-otr), * gnu/packages/qt.scm (qtspell), * gnu/packages/raspberry-pi.scm (raspi-gpio, raspi-open-firmware), * gnu/packages/rdp.scm (freerdp), * gnu/packages/ruby.scm (ruby-prawn-templates, ruby-treetop, ruby-gimme, ruby-standard, ruby-rubocop-ast, ruby-rexml, ruby-range-compressor, ruby-regexp-property-values, ruby-regexp-parser, ruby-rubocop, ruby-pdf-reader, ruby-pdf-inspector, ruby-prawn), * gnu/packages/syncthing.scm (syncthing-gtk), * gnu/packages/video.scm (svt-hevc, mediasdk, libvideogfx, libde265, tslib), * gnu/packages/xml.scm (libxmlb, libxmlplusplus)[source]: Same. Efraim Flashner 2020-11-19gnu: Add glyr....* gnu/packages/music.scm (glyr): New variable. Signed-off-by: Christopher Baines <mail@cbaines.net> Riku Viitanen 2020-11-10gnu: amsynth: Find external commands....* gnu/packages/music.scm (amsynth)[arguments]: Add a ‘patch-file-names’ phase. [inputs]: Add unzip and which. Tobias Geerinckx-Rice 2020-11-10gnu: amsynth: Order inputs alphabetically....* gnu/packages/music.scm (amsynth)[inputs, native-inputs]: Sort. Tobias Geerinckx-Rice