aboutsummaryrefslogtreecommitdiff
path: root/gnu/system/grub.scm
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/system/grub.scm')
-rw-r--r--gnu/system/grub.scm185
1 files changed, 165 insertions, 20 deletions
diff --git a/gnu/system/grub.scm b/gnu/system/grub.scm
index 41f45f1558..67375b45cf 100644
--- a/gnu/system/grub.scm
+++ b/gnu/system/grub.scm
@@ -23,9 +23,29 @@
#:use-module (guix records)
#:use-module (guix monads)
#:use-module (guix gexp)
+ #:use-module (guix download)
+ #:use-module (guix git-download)
+ #:autoload (gnu packages grub) (grub)
+ #:autoload (gnu packages inkscape) (inkscape)
+ #:autoload (gnu packages imagemagick) (imagemagick)
+ #:autoload (gnu packages compression) (gzip)
#:use-module (ice-9 match)
#:use-module (srfi srfi-1)
- #:export (grub-configuration
+ #:export (grub-image
+ grub-image?
+ grub-image-aspect-ratio
+ grub-image-file
+
+ grub-theme
+ grub-theme?
+ grub-theme-images
+ grub-theme-color-normal
+ grub-theme-color-highlight
+
+ %background-image
+ %default-theme
+
+ grub-configuration
grub-configuration?
grub-configuration-device
@@ -40,6 +60,45 @@
;;;
;;; Code:
+(define-record-type* <grub-image>
+ grub-image make-grub-image
+ grub-image?
+ (aspect-ratio grub-image-aspect-ratio ;rational number
+ (default 4/3))
+ (file grub-image-file)) ;file-valued gexp (SVG)
+
+(define-record-type* <grub-theme>
+ grub-theme make-grub-theme
+ grub-theme?
+ (images grub-theme-images
+ (default '())) ;list of <grub-image>
+ (color-normal grub-theme-color-normal
+ (default '((fg . cyan) (bg . blue))))
+ (color-highlight grub-theme-color-highlight
+ (default '((fg . white) (bg . blue)))))
+
+(define %artwork-repository
+ (origin
+ (method git-fetch)
+ (uri (git-reference
+ (url "git://git.savannah.gnu.org/guix/guix-artwork.git")
+ (commit "281157a")))
+ (sha256
+ (base32
+ "02x1myh013mzqnr28d4k1mxs4malv5vszpxdwkjarbhbbkchypz5"))))
+
+(define %background-image
+ (grub-image
+ (aspect-ratio 4/3)
+ (file #~(string-append #$%artwork-repository "/grub/guix-4-3.svg"))))
+
+(define %default-theme
+ ;; Default theme contributed by Felipe López.
+ (grub-theme
+ (images (list %background-image))
+ (color-highlight '((fg . white) (bg . black))) ;XXX: fg should be #x3bb7f5
+ (color-normal '((fg . light-gray) (bg . black))))) ;XXX: #x303030
+
(define-record-type* <grub-configuration>
grub-configuration make-grub-configuration
grub-configuration?
@@ -51,7 +110,9 @@
(default-entry grub-configuration-default-entry ; integer
(default 0))
(timeout grub-configuration-timeout ; integer
- (default 5)))
+ (default 5))
+ (theme grub-configuration-theme ; <grub-theme>
+ (default %default-theme)))
(define-record-type* <menu-entry>
menu-entry make-menu-entry
@@ -62,6 +123,88 @@
(default '())) ; list of string-valued gexps
(initrd menu-entry-initrd)) ; file name of the initrd as a gexp
+
+;;;
+;;; Background image & themes.
+;;;
+
+(define (svg->png svg)
+ "Build a PNG from SVG."
+ ;; Don't use #:local-build? so that it's substitutable.
+ (gexp->derivation "grub-image.png"
+ #~(zero?
+ (system* (string-append #$inkscape "/bin/inkscape")
+ "--without-gui"
+ (string-append "--export-png=" #$output)
+ #$svg))))
+
+(define (resize-image image width height)
+ "Resize IMAGE to WIDTHxHEIGHT."
+ ;; Don't use #:local-build? so that it's substitutable.
+ (let ((size (string-append (number->string width)
+ "x" (number->string height))))
+ (gexp->derivation "grub-image.resized.png"
+ #~(zero?
+ (system* (string-append #$imagemagick "/bin/convert")
+ "-resize" #$size #$image #$output)))))
+
+(define* (grub-background-image config #:key (width 640) (height 480))
+ "Return the GRUB background image defined in CONFIG with a ratio of
+WIDTH/HEIGHT, or #f if none was found."
+ (let* ((ratio (/ width height))
+ (image (find (lambda (image)
+ (= (grub-image-aspect-ratio image) ratio))
+ (grub-theme-images (grub-configuration-theme config)))))
+ (if image
+ (mlet %store-monad ((png (svg->png (grub-image-file image))))
+ (resize-image png width height))
+ (with-monad %store-monad
+ (return #f)))))
+
+(define (eye-candy config port)
+ "Return in %STORE-MONAD a gexp that writes to PORT (a port-valued gexp) the
+'grub.cfg' part concerned with graphics mode, background images, colors, and
+all that."
+ (define (theme-colors type)
+ (let* ((theme (grub-configuration-theme config))
+ (colors (type theme)))
+ (string-append (symbol->string (assoc-ref colors 'fg)) "/"
+ (symbol->string (assoc-ref colors 'bg)))))
+
+ (mlet* %store-monad ((image (grub-background-image config)))
+ (return (and image #~(format #$port "
+function load_video {
+ insmod vbe
+ insmod vga
+ insmod video_bochs
+ insmod video_cirrus
+}
+
+if loadfont ~a/share/grub/unicode.pf2; then
+ set gfxmode=640x480
+ load_video
+ insmod gfxterm
+ terminal_output gfxterm
+fi
+
+insmod png
+if background_image ~a; then
+ set color_normal=~a
+ set color_highlight=~a
+else
+ set menu_color_normal=cyan/blue
+ set menu_color_highlight=white/blue
+fi~%"
+ #$grub
+ #$image
+ #$(theme-colors grub-theme-color-normal)
+ #$(theme-colors grub-theme-color-highlight))))))
+
+
+;;;
+;;; Configuration file.
+;;;
+
(define* (grub-configuration-file config entries
#:key
(system (%current-system))
@@ -83,28 +226,30 @@ entries corresponding to old generations of the system."
#$linux (string-join (list #$@arguments))
#$initrd))))
- (define builder
- #~(call-with-output-file #$output
- (lambda (port)
- (format port "
+ (mlet %store-monad ((sugar (eye-candy config #~port)))
+ (define builder
+ #~(call-with-output-file #$output
+ (lambda (port)
+ #$sugar
+ (format port "
set default=~a
set timeout=~a
search.file ~a/bzImage~%"
- #$(grub-configuration-default-entry config)
- #$(grub-configuration-timeout config)
- #$(any (match-lambda
- (($ <menu-entry> _ linux)
- linux))
- all-entries))
- #$@(map entry->gexp all-entries)
-
- #$@(if (pair? old-entries)
- #~((format port "
+ #$(grub-configuration-default-entry config)
+ #$(grub-configuration-timeout config)
+ #$(any (match-lambda
+ (($ <menu-entry> _ linux)
+ linux))
+ all-entries))
+ #$@(map entry->gexp all-entries)
+
+ #$@(if (pair? old-entries)
+ #~((format port "
submenu \"GNU system, old configurations...\" {~%")
- #$@(map entry->gexp old-entries)
- (format port "}~%"))
- #~()))))
+ #$@(map entry->gexp old-entries)
+ (format port "}~%"))
+ #~()))))
- (gexp->derivation "grub.cfg" builder))
+ (gexp->derivation "grub.cfg" builder)))
;;; grub.scm ends here