-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
cl-menu.ros
executable file
·142 lines (129 loc) · 4.47 KB
/
cl-menu.ros
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/bin/sh
#|-*- mode:lisp -*-|#
#|
exec ros -Q -- $0 "$@"
|#
#|
This is the simple beginings to a dmenu written in Common Lisp because
some times C just isn't enough.
WARNING: This is not at all complete or even functional.
To run this simply install Roswell and make this file executable.
Roswell installation instructions:
https://roswell.github.io/Installation.html
|#
(progn ;;init forms
(ros:ensure-asdf)
#+quicklisp(ql:quickload '(clx) :silent t)
)
(defpackage :ros.script.cl-menu.3849918680
(:use :cl))
(in-package :ros.script.cl-menu.3849918680)
(in-package :xlib)
;; TODO Add multi monitor support utilizing the display-number
;; TODO Handle user input
;; TODO Implement sorting algorithm
;; TODO Properly handle events and close display
(declaim (optimize (speed 3) (safety 1)))
(defstruct (menu (:constructor create-menu (prompt font text window gcontext)))
(prompt ">" :type string :read-only t)
(font nil :type font :read-only t)
(text "" :type string)
(window nil :type window)
(gcontext nil :type gcontext))
(defun h-center-of-monitor (display)
(let ((screen (display-default-screen display))
(monitor-x (xlib/xinerama:screen-info-x
(car (xlib/xinerama::xinerama-query-screens display)))))
(truncate (+ monitor-x (screen-width screen))
2)))
(defun get-text-width (font border text)
(+ (text-width font text) (* 2 border)))
(defun get-text-height (font border)
(+ (max-char-ascent font)
(max-char-descent font) (* 2 border)))
(declaim (ftype (function (string string display &optional string) menu) make-menu))
(defun make-menu (text prompt display &optional (font-name "fixed"))
(progn
(print display)
(let* ((screen (display-default-screen display))
(font (open-font display font-name))
(border 1)
(x (h-center-of-monitor display))
(y 0)
(bg (screen-black-pixel screen))
(fg (screen-white-pixel screen))
(win (create-window :parent (screen-root screen)
;; :override-redirect :on
:save-under :on
:x x :y y
:width (get-text-width font border text) :height (get-text-height font border)
:background bg
:border fg
:border-width border
:colormap (screen-default-colormap screen)
:bit-gravity :center
:event-mask (make-event-mask :exposure
:key-press
:key-release
:button-press
)))
(gcontext (create-gcontext :drawable win
:background bg
:foreground fg
:font font)))
(create-menu
prompt
font
text
win
gcontext))))
(declaim (ftype (function (menu display) t) display-menu))
(defun display-menu (menu display)
(progn
(let ((font (menu-font menu))
(text (menu-text menu))
(width (get-text-width (menu-font menu) 1 (menu-text menu)))
(gcontext (menu-gcontext menu)))
(map-window (menu-window menu))
;; (loop for ev = (process-event display :handler
;; (lambda (&rest event-slots
;; &key event-key
;; &allow-other-keys)
;; (case event-key
;; ((or :key-release :key-press)
;; "hello")))
;; :timeout nil)
;; do (print ev))
(event-case (display ;; :discard-p t :force-output-p t
)
(:key-press ()
t)
(:exposure ;; Come here on exposure events
(window count)
(when (zerop count) ;; Ignore all but the last exposure event
(with-state (window)
(let ((x (truncate (- (drawable-width window) width) 2))
(y (truncate (- (+ (drawable-height window)
(max-char-ascent font))
(max-char-descent font))
2)))
;; Draw text centered in window
(clear-area window)
(draw-glyphs window gcontext x y text)))
;; Returning non-nil causes event-case to exit
nil))
(:button-press () t))
) ;; exit event-case
(when display
(close-display display :abort nil))))
(declaim (ftype (function (string string &optional string) t) cl-menu))
(defun cl-menu (text prompt &optional (font-name "fixed"))
"Start cl-menu on HOST with STRING in FONT "
(let ((display (open-display
(car (get-default-display)))))
(display-menu (make-menu text prompt display)
display)))
(defun main (&rest argv)
(declare (ignorable argv))
(cl-menu "hello world" "> "))
;;; vim: set ft=lisp lisp: