| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 |
|
| 20 | (define-module (gnu installer keymap)
|
| 21 | #:use-module (guix records)
|
| 22 | #:use-module (sxml match)
|
| 23 | #:use-module (sxml simple)
|
| 24 | #:use-module (ice-9 binary-ports)
|
| 25 | #:use-module (ice-9 ftw)
|
| 26 | #:use-module (ice-9 match)
|
| 27 | #:use-module (ice-9 regex)
|
| 28 | #:export (<x11-keymap-model>
|
| 29 | x11-keymap-model
|
| 30 | make-x11-keymap-model
|
| 31 | x11-keymap-model?
|
| 32 | x11-keymap-model-name
|
| 33 | x11-keymap-model-description
|
| 34 |
|
| 35 | <x11-keymap-layout>
|
| 36 | x11-keymap-layout
|
| 37 | make-x11-keymap-layout
|
| 38 | x11-keymap-layout?
|
| 39 | x11-keymap-layout-name
|
| 40 | x11-keymap-layout-synopsis
|
| 41 | x11-keymap-layout-description
|
| 42 | x11-keymap-layout-variants
|
| 43 |
|
| 44 | <x11-keymap-variant>
|
| 45 | x11-keymap-variant
|
| 46 | make-x11-keymap-variant
|
| 47 | x11-keymap-variant?
|
| 48 | x11-keymap-variant-name
|
| 49 | x11-keymap-variant-description
|
| 50 |
|
| 51 | default-keyboard-model
|
| 52 | xkb-rules->models+layouts
|
| 53 | kmscon-update-keymap))
|
| 54 |
|
| 55 | (define-record-type* <x11-keymap-model>
|
| 56 | x11-keymap-model make-x11-keymap-model
|
| 57 | x11-keymap-model?
|
| 58 | (name x11-keymap-model-name) |
| 59 | (description x11-keymap-model-description)) |
| 60 |
|
| 61 | (define-record-type* <x11-keymap-layout>
|
| 62 | x11-keymap-layout make-x11-keymap-layout
|
| 63 | x11-keymap-layout?
|
| 64 | (name x11-keymap-layout-name) |
| 65 | (synopsis x11-keymap-layout-synopsis) |
| 66 | (description x11-keymap-layout-description) |
| 67 | (variants x11-keymap-layout-variants)) |
| 68 |
|
| 69 | (define-record-type* <x11-keymap-variant>
|
| 70 | x11-keymap-variant make-x11-keymap-variant
|
| 71 | x11-keymap-variant?
|
| 72 | (name x11-keymap-variant-name) |
| 73 | (description x11-keymap-variant-description)) |
| 74 |
|
| 75 | |
| 76 | (define default-keyboard-model (make-parameter "pc105"))
|
| 77 |
|
| 78 | (define (xkb-rules->models+layouts file)
|
| 79 | "Parse FILE and return two values, the list of supported X11-KEYMAP-MODEL
|
| 80 | and X11-KEYMAP-LAYOUT records. FILE is an XML file from the X Keyboard
|
| 81 | Configuration Database, describing possible XKB configurations."
|
| 82 | (define maybe-empty
|
| 83 | (match-lambda
|
| 84 | ((x) x)
|
| 85 | (#f "")))
|
| 86 |
|
| 87 | (define (model m)
|
| 88 | (sxml-match m
|
| 89 | [(model
|
| 90 | (configItem
|
| 91 | (name ,name)
|
| 92 | (description ,description)
|
| 93 | . ,rest))
|
| 94 | (x11-keymap-model
|
| 95 | (name name)
|
| 96 | (description description))]))
|
| 97 |
|
| 98 | (define (variant v)
|
| 99 | (sxml-match v
|
| 100 | [(variant
|
| 101 | |
| 102 | |
| 103 | |
| 104 | |
| 105 | |
| 106 | |
| 107 | |
| 108 | |
| 109 | |
| 110 | |
| 111 | (configItem
|
| 112 | (name ,name)
|
| 113 | . ,rest-variant))
|
| 114 | (x11-keymap-variant
|
| 115 | (name name)
|
| 116 | (description (maybe-empty
|
| 117 | (assoc-ref rest-variant 'description))))]))
|
| 118 |
|
| 119 | (define (layout l)
|
| 120 | (sxml-match l
|
| 121 | [(layout
|
| 122 | (configItem
|
| 123 | (name ,name)
|
| 124 | . ,rest-layout)
|
| 125 | (variantList ,[variant -> v] ...))
|
| 126 | (x11-keymap-layout
|
| 127 | (name name)
|
| 128 | (synopsis (maybe-empty
|
| 129 | (assoc-ref rest-layout 'shortDescription)))
|
| 130 | (description (maybe-empty
|
| 131 | (assoc-ref rest-layout 'description)))
|
| 132 | (variants (list v ...)))]
|
| 133 | [(layout
|
| 134 | (configItem
|
| 135 | (name ,name)
|
| 136 | . ,rest-layout))
|
| 137 | (x11-keymap-layout
|
| 138 | (name name)
|
| 139 | (synopsis (maybe-empty
|
| 140 | (assoc-ref rest-layout 'shortDescription)))
|
| 141 | (description (maybe-empty
|
| 142 | (assoc-ref rest-layout 'description)))
|
| 143 | (variants '()))]))
|
| 144 |
|
| 145 | (let ((sxml (call-with-input-file file
|
| 146 | (lambda (port)
|
| 147 | (xml->sxml port #:trim-whitespace? #t)))))
|
| 148 | (match
|
| 149 | (sxml-match sxml
|
| 150 | [(*TOP*
|
| 151 | ,pi
|
| 152 | (xkbConfigRegistry
|
| 153 | (@ . ,ignored)
|
| 154 | (modelList ,[model -> m] ...)
|
| 155 | (layoutList ,[layout -> l] ...)
|
| 156 | . ,rest))
|
| 157 | (list
|
| 158 | (list m ...)
|
| 159 | (list l ...))])
|
| 160 | ((models layouts)
|
| 161 | (values models layouts)))))
|
| 162 |
|
| 163 | (define (kmscon-update-keymap model layout variant options)
|
| 164 | "Update kmscon keymap with the provided MODEL, LAYOUT, VARIANT and OPTIONS."
|
| 165 | (and=>
|
| 166 | (getenv "KEYMAP_UPDATE")
|
| 167 | (lambda (keymap-file)
|
| 168 | (unless (file-exists? keymap-file)
|
| 169 | (error "Unable to locate keymap update file"))
|
| 170 |
|
| 171 | |
| 172 | |
| 173 | |
| 174 | |
| 175 | (call-with-output-file keymap-file
|
| 176 | (lambda (port)
|
| 177 | (format port model)
|
| 178 | (put-u8 port 0)
|
| 179 |
|
| 180 | (format port layout)
|
| 181 | (put-u8 port 0)
|
| 182 |
|
| 183 | (format port (or variant ""))
|
| 184 | (put-u8 port 0)
|
| 185 |
|
| 186 | (format port (or options ""))
|
| 187 | (put-u8 port 0))))))
|