keymap.scm 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2018 Mathieu Othacehe <m.othacehe@gmail.com>
  3. ;;;
  4. ;;; This file is part of GNU Guix.
  5. ;;;
  6. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  7. ;;; under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation; either version 3 of the License, or (at
  9. ;;; your option) any later version.
  10. ;;;
  11. ;;; GNU Guix is distributed in the hope that it will be useful, but
  12. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;;; GNU General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  18. (define-module (gnu installer keymap)
  19. #:use-module (guix records)
  20. #:use-module (sxml match)
  21. #:use-module (sxml simple)
  22. #:use-module (ice-9 binary-ports)
  23. #:use-module (ice-9 ftw)
  24. #:use-module (ice-9 match)
  25. #:use-module (ice-9 regex)
  26. #:export (<x11-keymap-model>
  27. x11-keymap-model
  28. make-x11-keymap-model
  29. x11-keymap-model?
  30. x11-keymap-model-name
  31. x11-keymap-model-description
  32. <x11-keymap-layout>
  33. x11-keymap-layout
  34. make-x11-keymap-layout
  35. x11-keymap-layout?
  36. x11-keymap-layout-name
  37. x11-keymap-layout-synopsis
  38. x11-keymap-layout-description
  39. x11-keymap-layout-variants
  40. <x11-keymap-variant>
  41. x11-keymap-variant
  42. make-x11-keymap-variant
  43. x11-keymap-variant?
  44. x11-keymap-variant-name
  45. x11-keymap-variant-description
  46. default-keyboard-model
  47. xkb-rules->models+layouts
  48. kmscon-update-keymap))
  49. (define-record-type* <x11-keymap-model>
  50. x11-keymap-model make-x11-keymap-model
  51. x11-keymap-model?
  52. (name x11-keymap-model-name) ;string
  53. (description x11-keymap-model-description)) ;string
  54. (define-record-type* <x11-keymap-layout>
  55. x11-keymap-layout make-x11-keymap-layout
  56. x11-keymap-layout?
  57. (name x11-keymap-layout-name) ;string
  58. (synopsis x11-keymap-layout-synopsis) ;string (e.g., "en")
  59. (description x11-keymap-layout-description) ;string (a whole phrase)
  60. (variants x11-keymap-layout-variants)) ;list of <x11-keymap-variant>
  61. (define-record-type* <x11-keymap-variant>
  62. x11-keymap-variant make-x11-keymap-variant
  63. x11-keymap-variant?
  64. (name x11-keymap-variant-name) ;string
  65. (description x11-keymap-variant-description)) ;string
  66. ;; Assume all modern keyboards have this model.
  67. (define default-keyboard-model (make-parameter "pc105"))
  68. (define (xkb-rules->models+layouts file)
  69. "Parse FILE and return two values, the list of supported X11-KEYMAP-MODEL
  70. and X11-KEYMAP-LAYOUT records. FILE is an XML file from the X Keyboard
  71. Configuration Database, describing possible XKB configurations."
  72. (define (model m)
  73. (sxml-match m
  74. [(model
  75. (configItem
  76. (name ,name)
  77. (description ,description)
  78. . ,rest))
  79. (x11-keymap-model
  80. (name name)
  81. (description description))]))
  82. (define (variant v)
  83. (sxml-match v
  84. [(variant
  85. ;; According to xbd-rules DTD, the definition of a
  86. ;; configItem is: <!ELEMENT configItem
  87. ;; (name,shortDescription*,description*,vendor?,
  88. ;; countryList?,languageList?,hwList?)>
  89. ;;
  90. ;; shortDescription and description are optional elements
  91. ;; but sxml-match does not support default values for
  92. ;; elements (only attributes). So to avoid writing as many
  93. ;; patterns as existing possibilities, gather all the
  94. ;; remaining elements but name in REST-VARIANT.
  95. (configItem
  96. (name ,name)
  97. . ,rest-variant))
  98. (x11-keymap-variant
  99. (name name)
  100. (description (car
  101. (assoc-ref rest-variant 'description))))]))
  102. (define (layout l)
  103. (sxml-match l
  104. [(layout
  105. (configItem
  106. (name ,name)
  107. . ,rest-layout)
  108. (variantList ,[variant -> v] ...))
  109. (x11-keymap-layout
  110. (name name)
  111. (synopsis (car
  112. (assoc-ref rest-layout 'shortDescription)))
  113. (description (car
  114. (assoc-ref rest-layout 'description)))
  115. (variants (list v ...)))]
  116. [(layout
  117. (configItem
  118. (name ,name)
  119. . ,rest-layout))
  120. (x11-keymap-layout
  121. (name name)
  122. (synopsis (car
  123. (assoc-ref rest-layout 'shortDescription)))
  124. (description (car
  125. (assoc-ref rest-layout 'description)))
  126. (variants '()))]))
  127. (let ((sxml (call-with-input-file file
  128. (lambda (port)
  129. (xml->sxml port #:trim-whitespace? #t)))))
  130. (match
  131. (sxml-match sxml
  132. [(*TOP*
  133. ,pi
  134. (xkbConfigRegistry
  135. (@ . ,ignored)
  136. (modelList ,[model -> m] ...)
  137. (layoutList ,[layout -> l] ...)
  138. . ,rest))
  139. (list
  140. (list m ...)
  141. (list l ...))])
  142. ((models layouts)
  143. (values models layouts)))))
  144. (define (kmscon-update-keymap model layout variant)
  145. "Update kmscon keymap with the provided MODEL, LAYOUT and VARIANT."
  146. (and=>
  147. (getenv "KEYMAP_UPDATE")
  148. (lambda (keymap-file)
  149. (unless (file-exists? keymap-file)
  150. (error "Unable to locate keymap update file"))
  151. ;; See file gnu/packages/patches/kmscon-runtime-keymap-switch.patch.
  152. ;; This dirty hack makes possible to update kmscon keymap at runtime by
  153. ;; writing an X11 keyboard model, layout and variant to a named pipe
  154. ;; referred by KEYMAP_UPDATE environment variable.
  155. (call-with-output-file keymap-file
  156. (lambda (port)
  157. (format port model)
  158. (put-u8 port 0)
  159. (format port layout)
  160. (put-u8 port 0)
  161. (format port variant)
  162. (put-u8 port 0))))))