emacs-framebuffer

Emacs library to show images and documents in console using Linux framebuffer
Log | Files | Refs

commit 6ca2b981b04d3130706937262dd4740212673c37
parent a930802d6509edfca661e110459430759dbd1801
Author: Tomas Hlavaty <tom@logand.com>
Date:   Sun,  7 Jun 2020 23:26:52 +0200

add framebuffer-mode and install function

Diffstat:
Memacs-framebuffer.el | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 97 insertions(+), 13 deletions(-)

diff --git a/emacs-framebuffer.el b/emacs-framebuffer.el @@ -14,12 +14,9 @@ ;;; ;;; Example configuration: ;;; -;;; (require 'framebuffer) -;;; (eval-after-load 'dired -;;; '(progn -;;; (define-key dired-mode-map "I" 'framebuffer-image-file-dired) -;;; (define-key dired-mode-map "N" 'framebuffer-image-file-dired-next) -;;; (define-key dired-mode-map "P" 'framebuffer-image-file-dired-previous))) +;;; (unless (display-graphic-p) +;;; (require 'framebuffer) +;;; (framebuffer-install)) (defcustom framebuffer-width nil "Specify the framebuffer width." @@ -46,16 +43,25 @@ :type 'number :group 'framebuffer) +(defcustom framebuffer-image-mode-refresh-delay "2 sec" + "Specify the delay after which to refresh the image on the framebuffer." + :type 'string + :group 'framebuffer) + +(defvar framebuffer-size nil) + (defun framebuffer-size () (if (and framebuffer-width framebuffer-height) (cons framebuffer-width framebuffer-height) - (or - (with-temp-buffer - ;; TODO which framebuffer if more than one? - (insert-file-contents "/sys/class/graphics/fb0/modes") - (search-forward-regexp "\\([0-9]+\\)x\\([0-9]+\\)") - (cons (read (match-string 1)) (read (match-string 2)))) - (cons framebuffer-default-width framebuffer-default-height)))) + (or framebuffer-size + (setq framebuffer-size + (or + (with-temp-buffer + ;; TODO which framebuffer if more than one? + (insert-file-contents "/sys/class/graphics/fb0/modes") + (search-forward-regexp "\\([0-9]+\\)x\\([0-9]+\\)") + (cons (read (match-string 1)) (read (match-string 2)))) + (cons framebuffer-default-width framebuffer-default-height)))))) (defun framebuffer-draw-now (x y w h file) (with-temp-buffer @@ -216,4 +222,82 @@ (interactive "^p") (framebuffer-image-file-dired-next (if arg (- arg) -1))) +(defvar framebuffer-image-mode-image-size) + +(defun framebuffer-image-mode-draw-image () + (interactive) + (let ((file (buffer-file-name))) + (destructuring-bind (w &rest h) framebuffer-image-mode-image-size + (destructuring-bind (fbw &rest fbh) (framebuffer-size) + (destructuring-bind (x1 y1 x2 y2) (window-edges (get-buffer-window) t) ;; TODO for all visible windows + (let* ((fw (frame-width)) + (fh (frame-height)) + (cw (floor fbw fw)) + (ch (floor fbh fh)) + (wx (* x1 cw)) + (wy (* y1 ch)) + (ww (* (- x2 x1) cw)) + (wh (* (- y2 y1) ch)) + (scale (min (/ ww 1.0 w) (/ wh 1.0 h))) + (zw (floor (* scale w))) + (zh (floor (* scale h))) + (zx (+ wx (floor (- ww zw) 2))) + (zy (+ wy (floor (- wh zh) 2)))) + (framebuffer-draw zx zy zw zh file))))))) + +(defun framebuffer-image-mode-draw-image-repeatedly (buffer) + (when (buffer-live-p buffer) + (with-current-buffer buffer + (framebuffer-image-mode-draw-image) + (run-at-time framebuffer-image-mode-refresh-delay + nil + 'framebuffer-image-mode-draw-image-repeatedly + buffer)))) + +(defun framebuffer-image-mode-kill-buffer () + (interactive) + (kill-buffer)) + +(defvar framebuffer-image-mode-hook nil) + +(define-derived-mode framebuffer-image-mode fundamental-mode "fbi" + "Major mode for viewing images in framebuffer." + (set (make-local-variable 'framebuffer-image-mode-image-size) + (framebuffer-image-size (buffer-file-name))) + (with-silent-modifications + (erase-buffer) + (insert "file: ") + (insert (buffer-file-name)) + (insert "\n\n") + (insert "width: ") + (insert (format "%s" (car framebuffer-image-mode-image-size))) + (insert "\nheight: ") + (insert (format "%s" (cdr framebuffer-image-mode-image-size))) + (insert "\n\npress:\n") + (insert "- i: to draw the image\n") + (insert "- q: to kill the buffer\n")) + (setq buffer-read-only t) + (goto-char (point-min)) + (framebuffer-image-mode-draw-image-repeatedly (current-buffer)) + (run-hooks 'framebuffer-image-mode-hook)) + +(add-hook + 'framebuffer-image-mode-hook + (lambda () + (define-key framebuffer-image-mode-map "q" 'framebuffer-image-mode-kill-buffer))) + +(defun framebuffer-install () + (add-to-list 'auto-mode-alist '("\\.png\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.jpe?g\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.bmp\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.gif\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.tiff\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.ppm\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.pnm\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.xpm\\'" . framebuffer-image-mode)) + (with-eval-after-load 'dired + (define-key dired-mode-map "I" 'framebuffer-image-file-dired) + (define-key dired-mode-map "N" 'framebuffer-image-file-dired-next) + (define-key dired-mode-map "P" 'framebuffer-image-file-dired-previous))) + (provide 'framebuffer)