summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/events.sld3
-rw-r--r--lib/events.sls83
-rw-r--r--lib/keys.sld3
-rw-r--r--lib/keys.sls252
-rw-r--r--lib/util.sld33
-rw-r--r--lib/xlib.sld4
-rw-r--r--lib/xlib.sls607
7 files changed, 985 insertions, 0 deletions
diff --git a/lib/events.sld b/lib/events.sld new file mode 100644 index 0000000..747d3ac --- /dev/null +++ b/lib/events.sld
@@ -0,0 +1,3 @@
1(module (acdwm events) ()
2 (import scheme (chicken base) (chicken module))
3 (include-relative "events.sls"))
diff --git a/lib/events.sls b/lib/events.sls new file mode 100644 index 0000000..9bb78ee --- /dev/null +++ b/lib/events.sls
@@ -0,0 +1,83 @@
1;;; (acdwm events) --- event handlers
2
3(import (acdwm keys)
4 (acdwm xlib)
5 (acdwm util)
6 (srfi 1))
7
8(export make-drag drag? drag-type drag-event drag-window drag-attrs)
9(define-record drag type event window attrs)
10
11(define drag (make-parameter #f))
12(define drag-types '(move resize))
13
14(define-public (initialize-drag type event)
15 (assert (memq type drag-types))
16 (let ((win (and (buttonpress? event)
17 (xevent-xbutton-subwindow event))))
18 (and win
19 (drag (make-drag type event win (get-window-attributes win))))))
20
21(define-public (cancel-drag)
22 (free-xevent (drag-event (drag)))
23 (free-xwindowattributes (drag-attrs (drag)))
24 (drag #f))
25
26(define-public (handle-events #!optional (dpy (get-display)))
27 (let loop ((this (get-next-event dpy)))
28 (dprint "handling a " (xevent-type-name (xevent-type this)))
29 (cond
30 ((keypress? this)
31 (handle-keypress this dpy)
32 (loop (get-next-event dpy)))
33 ((buttonpress? this)
34 (handle-buttonpress this)
35 (loop (get-next-event dpy)))
36 ((buttonrelease? this)
37 (handle-buttonrelease this)
38 (loop (get-next-event dpy)))
39 ((motionnotify? this)
40 (handle-motion this)
41 (loop (get-next-event dpy)))
42 ;; Make sure this is at the end!
43 (else
44 (loop (get-next-event dpy))))))
45
46;;; Handlers
47
48(define-public (handle-keypress event
49 #!optional (dpy (get-display)))
50 (let ((binding (find-keybinding event)))
51 (dprint "handle-keypress: " binding)
52 (and binding ((keybind-proc binding) event dpy))))
53
54(define-public (handle-buttonpress event
55 #!optional (dpy (get-display)))
56 (let ((binding (find-mousebinding event)))
57 (dprint "handle-buttonpress: " binding)
58 (and binding ((mousebind-proc binding) event dpy))))
59
60(define-public (handle-buttonrelease event
61 #!optional (dpy (get-display)))
62 (dprint "handle-buttonrelease")
63 (cancel-drag))
64
65(define-public (handle-motion event
66 #!optional (dpy (get-display)))
67 (dprint "handle-motion")
68 (when (drag)
69 (when (some? (drag-window (drag)))
70 (let ((xd (- (xevent-xbutton-x_root event)
71 (xevent-xbutton-x_root (drag-event (drag)))))
72 (yd (- (xevent-xbutton-y_root event)
73 (xevent-xbutton-y_root (drag-event (drag))))))
74 (let ((xnew (+ (xwindowattributes-x (drag-attrs (drag)))
75 (if (eq? (drag-type (drag)) 'move) xd 0)))
76 (ynew (+ (xwindowattributes-y (drag-attrs (drag)))
77 (if (eq? (drag-type (drag)) 'move) yd 0)))
78 (wnew (max 1 (+ (xwindowattributes-width (drag-attrs (drag)))
79 (if (eq? (drag-type (drag)) 'resize) xd 0))))
80 (hnew (max 1 (+ (xwindowattributes-height (drag-attrs (drag)))
81 (if (eq? (drag-type (drag)) 'resize) yd 0)))))
82 (dprint wnew "x" hnew "+" xnew "+" ynew)
83 (xmoveresizewindow dpy (drag-window (drag)) xnew ynew wnew hnew))))))
diff --git a/lib/keys.sld b/lib/keys.sld new file mode 100644 index 0000000..2a90845 --- /dev/null +++ b/lib/keys.sld
@@ -0,0 +1,3 @@
1(module (acdwm keys) ()
2 (import scheme (chicken base) (chicken module))
3 (include-relative "keys.sls"))
diff --git a/lib/keys.sls b/lib/keys.sls new file mode 100644 index 0000000..3be0384 --- /dev/null +++ b/lib/keys.sls
@@ -0,0 +1,252 @@
1;;; (acdwm keys) --- key (and button!) binding tools
2
3(import (chicken bitwise)
4 (chicken irregex)
5 (chicken memory)
6 (srfi 1)
7 (acdwm xlib)
8 (acdwm util))
9
10;;; Defining bindings
11
12(define-public bindings
13 (make-parameter '()))
14
15(export keybind keybind?
16 keybind-keycode keybind-modmask keybind-proc)
17(define-record keybind
18 (setter keycode)
19 (setter modmask)
20 (setter proc))
21
22(export mousebind mousebind?
23 mousebind-button mousebind-modmask mousebind-proc)
24(define-record mousebind
25 (setter button)
26 (setter modmask)
27 (setter proc))
28
29(define-public (bind kbd proc #!optional (dpy (get-display)))
30 ;;; Public interface for make-(keybind|mousebind).
31 (receive (key mods) (parse-bind-description kbd)
32 (print "binding " kbd " to " proc)
33 (let ((bind (if (<= 1 key 5)
34 (make-mousebind key mods proc)
35 (make-keybind (->keycode key dpy) mods proc))))
36 (bindings (cons bind (bindings)))
37 (print "bindings: " (bindings)))))
38
39(define-public (unbind kbd)
40 (receive (key mods) (parse-bind-description kbd)
41 #f ; TODO
42 ))
43
44;;; Matching bindings
45
46(define-public (keybind-match? kb ev #!optional (dpy (get-display)))
47 (and (or (keypress? ev) (keyrelease? ev))
48 (keybind? kb)
49 (and (= (xevent-xkey-keycode ev) (keybind-keycode kb))
50 (= (clean-mask (xevent-xkey-state ev)) (keybind-modmask kb))
51 (procedure? (keybind-proc kb)))))
52
53(define-public (find-keybinding ev)
54 (find (lambda (b) (keybind-match? b ev)) (bindings)))
55
56(define-public (mousebind-match? mb ev #!optional (dpy (get-display)))
57 (and (or (buttonpress? ev) (buttonrelease? ev))
58 (mousebind? mb)
59 (and (= (xevent-xbutton-button ev) (mousebind-button mb))
60 (= (clean-mask (xevent-xbutton-state ev)) (mousebind-modmask mb))
61 (procedure? (mousebind-proc mb)))))
62
63(define-public (find-mousebinding ev)
64 (find (lambda (b) (mousebind-match? b ev)) (bindings)))
65
66;;; Numlock & Modkeys
67
68(define numlock
69 (make-parameter 0))
70
71(define-public (update-numlock-mask #!optional (dpy (get-display)))
72 (call-with-modifier-keymap
73 (lambda (mm)
74 (let ((max-key-per-mod (xmodifierkeymap-max_keypermod mm)))
75 (do ((i 0 (add1 i)))
76 ((= i 8))
77 (do ((k 0 (add1 k)))
78 ((= k max-key-per-mod))
79 (let ((r (pointer-u8-ref ; a KeyBind is an unsigned char
80 (pointer+ (xmodifierkeymap-modifiermap mm)
81 (+ i (* max-key-per-mod k))))))
82 (when (= r (->keycode XK_NUM_LOCK))
83 (numlock (arithmetic-shift 1 i))))))))))
84
85(define-public (clean-mask mask)
86 (bitwise-and mask
87 (bitwise-not (bitwise-ior (numlock) LOCKMASK))
88 (bitwise-ior SHIFTMASK CONTROLMASK
89 MOD1MASK MOD2MASK MOD3MASK MOD4MASK MOD5MASK)))
90
91;;; Grabbing input
92
93(define *mods
94 (begin (update-numlock-mask)
95 (list 0 LOCKMASK (numlock) (bitwise-ior (numlock) LOCKMASK))))
96
97(define (grab-key key #!optional (dpy (get-display)))
98 (when (keybind? key)
99;; XXX (dprint "grabbing " )
100 (for-each (lambda (mod)
101 (xgrabkey dpy
102 (keybind-keycode key)
103 (bitwise-ior mod (keybind-modmask key))
104 (get-root dpy)
105 TRUE
106 GRABMODEASYNC
107 GRABMODEASYNC))
108 *mods)))
109
110(define (grab-button btn #!optional (dpy (get-display)))
111 (when (mousebind? btn)
112 (for-each (lambda (mod)
113 (xgrabbutton dpy
114 (mousebind-button btn)
115 (bitwise-ior mod (mousebind-modmask btn))
116 (get-root dpy)
117 TRUE
118 (bitwise-ior BUTTONPRESSMASK
119 BUTTONRELEASEMASK
120 POINTERMOTIONMASK)
121 GRABMODEASYNC
122 GRABMODEASYNC
123 NONE
124 NONE))
125 *mods)))
126
127(define-public (grab-input #!optional
128 (bindings (bindings))
129 (dpy (get-display)))
130 (xungrabkey dpy ANYKEY ANYMODIFIER (get-root dpy))
131 (for-each grab-key (filter keybind? bindings))
132 (for-each grab-button (filter mousebind? bindings)))
133
134;;; Parsing keybind descriptions
135;; `bind' does Emacs-style binding descriptions in DESC. That is, it accepts a
136;; string of the form MODS-KEY, where
137;; - MODS is one of C, S, M, 1, 2, 3, 4, 5 (M = 1) (case-insensitive)
138;; - KEY is one of
139;; - - mouse buttons b1, b2, b3, b4, b5 (case-insensitive)
140;; - - <D?XK_NAME> is passed through as a symbol
141;; - - otherwise it's figured out through the `keycaps' alist
142
143;; NOTE: parse-bind-description returns a KeySym
144(define-public (parse-bind-description desc)
145 (let* ((m (match-bind-desc desc))
146 (p (cond
147 ((not m) #f)
148 ((irregex-match-substring m 'btn) => parse-button-match)
149 ((irregex-match-substring m 'raw) => parse-raw-match)
150 ((irregex-match-substring m 'key) => parse-key-match)
151 (else #f))))
152 (if p
153 (values p (extract-modmask m))
154 (values #f #f))))
155
156(define (match-bind-desc desc)
157 (irregex-match '(: (? (=> mods (+ (or "C-" "S-" "M-"
158 "1-" "2-" "3-" "4-" "5-"))))
159 (or
160 (: (or #\B #\b) (=> btn ("12345")))
161 (: #\< (=> raw (+ (or alnum #\_))) #\>)
162 (=> key any)))
163 desc))
164
165(define (extract-modmask match)
166 (let ((m (irregex-match-substring match 'mods)))
167 (irregex-fold "[CSM12345]-"
168 (lambda (i n s)
169 (bitwise-ior s (case (string-ref
170 (irregex-match-substring n) 0)
171 ((#\C #\c) CONTROLMASK)
172 ((#\S #\s) SHIFTMASK)
173 ((#\M #\m #\1) MOD1MASK)
174 ((#\2) MOD2MASK)
175 ((#\3) MOD3MASK)
176 ((#\4) MOD4MASK)
177 ((#\5) MOD5MASK))))
178 0
179 (or m ""))))
180
181(define (parse-button-match btn)
182 (string->number btn))
183
184(define (parse-raw-match raw)
185 (string->keysym (string-append (if (irregex-match? "^D?XK_.*" raw) ""
186 "XK_")
187 (string-upcase raw))))
188
189(define (char<= . cs)
190 (apply <= (map char->integer cs)))
191
192(define (parse-key-match key)
193 (let ((ch (string-ref key 0)))
194 (cond
195 ((char<= #\a ch #\z)
196 (string->keysym (string-append "XK_LC" (string (char-upcase ch)))))
197 ((char<= #\A ch #\Z)
198 (string->keysym (string-append "XK_" (string ch))))
199 ((alist-ref ch keycaps))
200 (else
201 (let ((ks (char->integer (xstringtokeysym key))))
202 (if (zero? ks) #f ks))))))
203
204(define (string->keysym str)
205 (symbol->keysym (string->symbol str)))
206
207(define (string-upcase str)
208 (list->string (map char-upcase (string->list str))))
209
210(define keycaps
211 `((#\` . #x60) ; y no XK_GRAVE
212 (#\1 . ,XK_1)
213 (#\2 . ,XK_2)
214 (#\3 . ,XK_3)
215 (#\4 . ,XK_4)
216 (#\5 . ,XK_5)
217 (#\6 . ,XK_6)
218 (#\7 . ,XK_7)
219 (#\8 . ,XK_8)
220 (#\9 . ,XK_9)
221 (#\0 . ,XK_0)
222 (#\- . ,XK_MINUS)
223 (#\= . ,XK_EQUAL)
224 (#\[ . ,XK_BRACKETLEFT)
225 (#\] . ,XK_BRACKETRIGHT)
226 (#\\ . ,XK_BACKSLASH)
227 (#\; . ,XK_SEMICOLON)
228 (#\' . #x27) ; y no XK_APOSTROPHE
229 (#\, . ,XK_COMMA)
230 (#\. . ,XK_PERIOD)
231 (#\/ . ,XK_SLASH)
232 (#\~ . ,XK_ASCIITILDE)
233 (#\! . ,XK_EXCLAM)
234 (#\@ . ,XK_AT)
235 (#\# . ,XK_NUMBERSIGN)
236 (#\$ . ,XK_DOLLAR)
237 (#\% . ,XK_PERCENT)
238 (#\^ . ,XK_ASCIICIRCUM)
239 (#\& . ,XK_AMPERSAND)
240 (#\* . ,XK_ASTERISK)
241 (#\( . ,XK_PARENLEFT)
242 (#\) . ,XK_PARENRIGHT)
243 (#\_ . ,XK_UNDERSCORE)
244 (#\+ . ,XK_PLUS)
245 (#\{ . ,XK_BRACELEFT)
246 (#\} . ,XK_BRACERIGHT)
247 (#\| . ,XK_BAR)
248 (#\: . ,XK_COLON)
249 (#\" . ,XK_QUOTEDBL)
250 (#\< . ,XK_LESS)
251 (#\> . ,XK_GREATER)
252 (#\? . ,XK_QUESTION)))
diff --git a/lib/util.sld b/lib/util.sld new file mode 100644 index 0000000..fc6a24b --- /dev/null +++ b/lib/util.sld
@@ -0,0 +1,33 @@
1(module (acdwm util) (
2 define-public
3 ignore
4 DEBUG
5 dprint
6 )
7
8 (import scheme (chicken base)
9 (chicken port))
10
11 (define-syntax define-public
12 (syntax-rules ()
13 ((define-public (name . arg) forms ...)
14 (begin (export name)
15 (define (name . arg) forms ...)))
16 ((define-public (name args ...) forms ...)
17 (begin (export name)
18 (define (name args ...) forms ...)))
19 ((define-public name value)
20 (begin (export name)
21 (define name value)))))
22
23 (define (ignore . _) #f)
24
25 (define (eprint . xs)
26 (with-output-to-port (current-error-port)
27 (lambda () (apply print xs))))
28
29 (define DEBUG (make-parameter #f))
30
31 (define (dprint . xs)
32 (when (DEBUG)
33 (apply eprint xs))))
diff --git a/lib/xlib.sld b/lib/xlib.sld new file mode 100644 index 0000000..4206a86 --- /dev/null +++ b/lib/xlib.sld
@@ -0,0 +1,4 @@
1(module (acdwm xlib) ()
2 (import scheme (chicken base) (chicken module))
3 (reexport xlib)
4 (include-relative "xlib.sls"))
diff --git a/lib/xlib.sls b/lib/xlib.sls new file mode 100644 index 0000000..a1915c5 --- /dev/null +++ b/lib/xlib.sls
@@ -0,0 +1,607 @@
1;;; (acdw xlib) --- xlib wrapper ... wrapper
2;; Rationale: the xlib egg is by its own admission pretty raw. this library
3;; tries to cook it a little.
4
5(import xlib
6 (chicken bitwise)
7 (acdwm util))
8(import-for-syntax (acdwm util))
9
10(define *xdisplay
11 (make-parameter
12 (delay (xopendisplay #f))))
13
14(define-public (get-display)
15 (force (*xdisplay)))
16
17(define-public (get-screen #!optional (dpy (get-display)))
18 (xdefaultscreen dpy))
19
20(define-public (get-root #!optional (dpy (get-display)) scrn)
21 (dprint "getting root")
22 (xrootwindow dpy (or scrn (get-screen dpy))))
23
24;;; Constants
25
26(define-public TRUE 1)
27(define-public FALSE 0)
28
29;;; Working with X structures
30;; These functions wrap C functions with 'return pointers'
31
32(define-public (get-next-event #!optional (dpy (get-display)))
33 (let ((event (make-xevent)))
34 (xnextevent dpy event)
35 (dprint "get-next-event: " (xevent-type-name (xevent-type event)))
36 event))
37
38(define-public (get-next-masked-event mask #!optional (dpy (get-display)))
39 (let ((event (make-xevent)))
40 (xmaskevent dpy mask event)
41 event))
42
43(define-public (get-window-attributes win #!optional (dpy (get-display)))
44 (let ((attrs (make-xwindowattributes)))
45 (xgetwindowattributes dpy win attrs)
46 attrs))
47
48;; And these wrap C functions to make sure resources are freed
49
50(define-public (call-with-modifier-keymap proc #!optional (dpy (get-display)))
51 (let ((modmap (make-xmodifierkeymap)))
52 (dynamic-wind (lambda () (set! modmap (xgetmodifiermapping dpy)))
53 (lambda () (proc modmap))
54 (lambda () (free-xmodifierkeymap modmap)))))
55
56;;; Predicates
57
58(define-public (none? x) ; this could be zero? ... but maybe
59 (= NONE x)) ; it'll change!
60
61(define-public some? ; neologism
62 (complement none?))
63
64;; Events
65(define-syntax define-event-predicate
66 (syntax-rules ()
67 ((define-event-predicate predicate event)
68 (define-public (predicate ev*)
69 (= event (xevent-type ev*))))))
70
71(define-event-predicate buttonpress? BUTTONPRESS)
72(define-event-predicate buttonrelease? BUTTONRELEASE)
73(define-event-predicate circulatenotify? CIRCULATENOTIFY)
74(define-event-predicate clientmessage? CLIENTMESSAGE)
75(define-event-predicate colormapnotify? COLORMAPNOTIFY)
76(define-event-predicate createnotify? CREATENOTIFY)
77(define-event-predicate destroynotify? DESTROYNOTIFY)
78(define-event-predicate enternotify? ENTERNOTIFY)
79(define-event-predicate expose? EXPOSE)
80(define-event-predicate focuschangemask? FOCUSCHANGEMASK)
81(define-event-predicate graphicsexpose? GRAPHICSEXPOSE)
82(define-event-predicate gravitynotify? GRAVITYNOTIFY)
83(define-event-predicate keypress? KEYPRESS)
84(define-event-predicate keyrelease? KEYRELEASE)
85(define-event-predicate keymapnotify? KEYMAPNOTIFY)
86(define-event-predicate leavenotify? LEAVENOTIFY)
87(define-event-predicate mapnotify? MAPNOTIFY)
88(define-event-predicate maprequest? MAPREQUEST)
89(define-event-predicate mappingnotify? MAPPINGNOTIFY)
90(define-event-predicate motionnotify? MOTIONNOTIFY)
91(define-event-predicate propertynotify? PROPERTYNOTIFY)
92(define-event-predicate reparentnotify? REPARENTNOTIFY)
93(define-event-predicate resizerequest? RESIZEREQUEST)
94(define-event-predicate selectionclear? SELECTIONCLEAR)
95(define-event-predicate selectionnotify? SELECTIONNOTIFY)
96(define-event-predicate selectionrequest? SELECTIONREQUEST)
97(define-event-predicate substructureredirectmask? SUBSTRUCTUREREDIRECTMASK)
98(define-event-predicate unmapnotify? UNMAPNOTIFY)
99(define-event-predicate visibilitynotify? VISIBILITYNOTIFY)
100;; (define-event-predicate xconfigureevent? XCONFIGUREEVENT)
101;; (define-event-predicate xconfigurerequestevent? XCONFIGUREREQUESTEVENT)
102;; (define-event-predicate xdestroywindowevent? XDESTROYWINDOWEVENT)
103;; (define-event-predicate xfocusoutevent? XFOCUSOUTEVENT)
104;; (define-event-predicate xgravityevent? XGRAVITYEVENT)
105;; (define-event-predicate xmapevent? XMAPEVENT)
106;; (define-event-predicate xnoexposeevent? XNOEXPOSEEVENT)
107;; (define-event-predicate xreparentevent? XREPARENTEVENT)
108;; (define-event-predicate xunmapevent? XUNMAPEVENT)
109
110;;; Deconstructing the XEvent union type
111
112(define-syntax define-xevent->subevent
113 (er-macro-transformer
114 (lambda (x r c)
115 (define (string-append->symbol . ss)
116 (string->symbol (apply string-append ss)))
117 ;; (define-xevent->subevent name . props)
118 (let* ((name (symbol->string (cadr x)))
119 (evname (string-append name "event"))
120 (fnname (string-append->symbol "xevent->" name "event")))
121 `(,(r 'define-public) (,fnname ,(r 'xev))
122 (dprint ',fnname)
123 (,(r 'let) ((,(r 'out) (,(string-append->symbol "make-" evname))))
124 ,@(map (lambda (p)
125 ;; set-<evname>-<prop>! out (xevent-<name>-prop xev)
126 (let* ((pname (symbol->string p))
127 (form
128 `(,(string-append->symbol "set-" evname "-" pname "!")
129 ,(r 'out)
130 (,(string-append->symbol "xevent-" name "-" pname)
131 ,(r 'xev)))))
132 `(begin (dprint ',form)
133 ,form)))
134 (cddr x))
135 (,(r 'free-xevent) ,(r 'xev))
136 ,(r 'out)))))))
137
138
139(define-xevent->subevent xany
140 type display send_event serial type window)
141(define-xevent->subevent xkey
142 type serial send_event display window root subwindow time
143 x y x_root y_root state keycode same_screen)
144(define-xevent->subevent xbutton
145 type serial send_event display window root subwindow time
146 x y x_root y_root state button same_screen)
147(define-xevent->subevent xmotion
148 type serial send_event display window root subwindow time
149 x y x_root y_root state is_hint same_screen)
150(define-xevent->subevent xcrossing
151 type serial send_event display window root subwindow time
152 x y x_root y_root mode detail same_screen focus state)
153(define-xevent->subevent xexpose
154 type serial send_event display window x y width height count)
155(define-xevent->subevent xgraphicsexpose
156 type serial send_event display drawable x y width height
157 count major_code minor_code)
158(define-xevent->subevent xnoexpose
159 type serial send_event display drawable major_code minor_code)
160(define-xevent->subevent xvisibility
161 type serial send_event display window state)
162(define-xevent->subevent xcreatewindow
163 type serial send_event display parent window
164 x y width height border_width override_redirect)
165(define-xevent->subevent xdestroywindow
166 type serial send_event display event window)
167(define-xevent->subevent xunmap
168 type serial send_event display event window from_configure)
169(define-xevent->subevent xmap
170 type serial send_event display event window override_redirect)
171(define-xevent->subevent xmaprequest
172 type serial send_event display parent window)
173(define-xevent->subevent xreparent
174 type serial send_event display event window parent override_redirect)
175(define-xevent->subevent xconfigure
176 type serial send_event display event window
177 x y width height border_width above override_redirect)
178(define-xevent->subevent xgravity
179 type serial send_event display event window x y)
180(define-xevent->subevent xresizerequest
181 type serial send_event display window width height)
182(define-xevent->subevent xconfigurerequest
183 type serial send_event display parent window
184 x y width height border_width above detail value_mask)
185(define-xevent->subevent xcirculate
186 type serial send_event display event window place)
187(define-xevent->subevent xcirculaterequest
188 type serial send_event display parent window place)
189(define-xevent->subevent xproperty
190 type serial send_event display window atom time state)
191(define-xevent->subevent xselectionclear
192 type serial send_event display window selection time)
193(define-xevent->subevent xselectionrequest
194 type serial send_event display owner requestor selection
195 target property time)
196(define-xevent->subevent xselection
197 type serial send_event display requestor selection
198 target property time)
199(define-xevent->subevent xcolormap
200 type serial send_event display window colormap new state)
201(define-xevent->subevent xmapping
202 type serial send_event display window request first_keycode count)
203(define-xevent->subevent xerror
204 type display resourceid serial
205 error_code request_code minor_code)
206;; (define-xevent->subevent xfocuschange)
207#;(define-xevent->subevent xclient
208type serial send_event display window message_type format
209data-b data-s data-l)
210#;(define-xevent->subevent xkeymap
211type serial send_event display window key_vector)
212
213;;; Keysyms, keycodes, etc.
214
215(define (keysym->keycode ks #!optional (dpy (get-display)))
216 (char->integer (xkeysymtokeycode dpy ks)))
217
218(define-public (symbol->keysym xk_symbol)
219 ;;; XK_<NAME> => <the integer defined by XK_<NAME>>
220 (let ((ks (alist-ref xk_symbol keysyms)))
221 (and ks ks)))
222
223(define-public (->keycode keysym/xk_symbol #!optional (dpy (get-display)))
224 ;; Because it's all integers at the bottom, this function assumes that its
225 ;; argument denotes a Keysym.
226 (cond
227 ((number? keysym/xk_symbol)
228 (keysym->keycode keysym/xk_symbol))
229 ((symbol? keysym/xk_symbol)
230 (keysym->keycode (symbol->keysym keysym/xk_symbol)))
231 ((char? keysym/xk_symbol) ; a weird situation but w/e
232 (char->integer keysym/xk_symbol))
233 (else #f)))
234
235(define keysyms
236 `((XK_BACKSPACE . ,XK_BACKSPACE)
237 (XK_0 . ,XK_0)
238 (XK_1 . ,XK_1)
239 (XK_2 . ,XK_2)
240 (XK_3 . ,XK_3)
241 (XK_4 . ,XK_4)
242 (XK_5 . ,XK_5)
243 (XK_6 . ,XK_6)
244 (XK_7 . ,XK_7)
245 (XK_8 . ,XK_8)
246 (XK_9 . ,XK_9)
247 (XK_A . ,XK_A)
248 (XK_AACUTE . ,XK_AACUTE)
249 (XK_ACIRCUMFLEX . ,XK_ACIRCUMFLEX)
250 (XK_ACUTE . ,XK_ACUTE)
251 (XK_ADIAERESIS . ,XK_ADIAERESIS)
252 (XK_AE . ,XK_AE)
253 (XK_AGRAVE . ,XK_AGRAVE)
254 (XK_ALT_L . ,XK_ALT_L)
255 (XK_ALT_R . ,XK_ALT_R)
256 (XK_AMPERSAND . ,XK_AMPERSAND)
257 (XK_ARING . ,XK_ARING)
258 (XK_ASCIICIRCUM . ,XK_ASCIICIRCUM)
259 (XK_ASCIITILDE . ,XK_ASCIITILDE)
260 (XK_ASTERISK . ,XK_ASTERISK)
261 (XK_AT . ,XK_AT)
262 (XK_ATILDE . ,XK_ATILDE)
263 (XK_B . ,XK_B)
264 (XK_BACKSLASH . ,XK_BACKSLASH)
265 (XK_BAR . ,XK_BAR)
266 (XK_BEGIN . ,XK_BEGIN)
267 (XK_BRACELEFT . ,XK_BRACELEFT)
268 (XK_BRACERIGHT . ,XK_BRACERIGHT)
269 (XK_BRACKETLEFT . ,XK_BRACKETLEFT)
270 (XK_BRACKETRIGHT . ,XK_BRACKETRIGHT)
271 (XK_BREAK . ,XK_BREAK)
272 (XK_BROKENBAR . ,XK_BROKENBAR)
273 (XK_C . ,XK_C)
274 (XK_CANCEL . ,XK_CANCEL)
275 (XK_CAPS_LOCK . ,XK_CAPS_LOCK)
276 (XK_CCEDILLA . ,XK_CCEDILLA)
277 (XK_CEDILLA . ,XK_CEDILLA)
278 (XK_CENT . ,XK_CENT)
279 (XK_CLEAR . ,XK_CLEAR)
280 (XK_COLON . ,XK_COLON)
281 (XK_COMMA . ,XK_COMMA)
282 (XK_CONTROL_L . ,XK_CONTROL_L)
283 (XK_CONTROL_R . ,XK_CONTROL_R)
284 (XK_COPYRIGHT . ,XK_COPYRIGHT)
285 (XK_CURRENCY . ,XK_CURRENCY)
286 (XK_D . ,XK_D)
287 (XK_DEGREE . ,XK_DEGREE)
288 (XK_DELETE . ,XK_DELETE)
289 (XK_DIAERESIS . ,XK_DIAERESIS)
290 (XK_DIVISION . ,XK_DIVISION)
291 (XK_DOLLAR . ,XK_DOLLAR)
292 (XK_DOWN . ,XK_DOWN)
293 (XK_E . ,XK_E)
294 (XK_EACUTE . ,XK_EACUTE)
295 (XK_ECIRCUMFLEX . ,XK_ECIRCUMFLEX)
296 (XK_EDIAERESIS . ,XK_EDIAERESIS)
297 (XK_EGRAVE . ,XK_EGRAVE)
298 (XK_END . ,XK_END)
299 (XK_EQUAL . ,XK_EQUAL)
300 (XK_ESCAPE . ,XK_ESCAPE)
301 (XK_ETH . ,XK_ETH)
302 (XK_EXCLAM . ,XK_EXCLAM)
303 (XK_EXCLAMDOWN . ,XK_EXCLAMDOWN)
304 (XK_EXECUTE . ,XK_EXECUTE)
305 (XK_F . ,XK_F)
306 (XK_F1 . ,XK_F1)
307 (XK_F10 . ,XK_F10)
308 (XK_F11 . ,XK_F11)
309 (XK_F12 . ,XK_F12)
310 (XK_F13 . ,XK_F13)
311 (XK_F14 . ,XK_F14)
312 (XK_F15 . ,XK_F15)
313 (XK_F16 . ,XK_F16)
314 (XK_F17 . ,XK_F17)
315 (XK_F18 . ,XK_F18)
316 (XK_F19 . ,XK_F19)
317 (XK_F2 . ,XK_F2)
318 (XK_F20 . ,XK_F20)
319 (XK_F21 . ,XK_F21)
320 (XK_F22 . ,XK_F22)
321 (XK_F23 . ,XK_F23)
322 (XK_F24 . ,XK_F24)
323 (XK_F25 . ,XK_F25)
324 (XK_F26 . ,XK_F26)
325 (XK_F27 . ,XK_F27)
326 (XK_F28 . ,XK_F28)
327 (XK_F29 . ,XK_F29)
328 (XK_F3 . ,XK_F3)
329 (XK_F30 . ,XK_F30)
330 (XK_F31 . ,XK_F31)
331 (XK_F32 . ,XK_F32)
332 (XK_F33 . ,XK_F33)
333 (XK_F34 . ,XK_F34)
334 (XK_F35 . ,XK_F35)
335 (XK_F4 . ,XK_F4)
336 (XK_F5 . ,XK_F5)
337 (XK_F6 . ,XK_F6)
338 (XK_F7 . ,XK_F7)
339 (XK_F8 . ,XK_F8)
340 (XK_F9 . ,XK_F9)
341 (XK_FIND . ,XK_FIND)
342 (XK_G . ,XK_G)
343 (XK_GREATER . ,XK_GREATER)
344 (XK_GUILLEMOTLEFT . ,XK_GUILLEMOTLEFT)
345 (XK_GUILLEMOTRIGHT . ,XK_GUILLEMOTRIGHT)
346 (XK_H . ,XK_H)
347 (XK_HELP . ,XK_HELP)
348 (XK_HOME . ,XK_HOME)
349 (XK_HYPER_L . ,XK_HYPER_L)
350 (XK_HYPER_R . ,XK_HYPER_R)
351 (XK_HYPHEN . ,XK_HYPHEN)
352 (XK_I . ,XK_I)
353 (XK_IACUTE . ,XK_IACUTE)
354 (XK_ICIRCUMFLEX . ,XK_ICIRCUMFLEX)
355 (XK_IDIAERESIS . ,XK_IDIAERESIS)
356 (XK_IGRAVE . ,XK_IGRAVE)
357 (XK_INSERT . ,XK_INSERT)
358 (XK_J . ,XK_J)
359 (XK_K . ,XK_K)
360 (XK_KANJI . ,XK_KANJI)
361 (XK_KP_0 . ,XK_KP_0)
362 (XK_KP_1 . ,XK_KP_1)
363 (XK_KP_2 . ,XK_KP_2)
364 (XK_KP_3 . ,XK_KP_3)
365 (XK_KP_4 . ,XK_KP_4)
366 (XK_KP_5 . ,XK_KP_5)
367 (XK_KP_6 . ,XK_KP_6)
368 (XK_KP_7 . ,XK_KP_7)
369 (XK_KP_8 . ,XK_KP_8)
370 (XK_KP_9 . ,XK_KP_9)
371 (XK_KP_ADD . ,XK_KP_ADD)
372 (XK_KP_DECIMAL . ,XK_KP_DECIMAL)
373 (XK_KP_DIVIDE . ,XK_KP_DIVIDE)
374 (XK_KP_ENTER . ,XK_KP_ENTER)
375 (XK_KP_EQUAL . ,XK_KP_EQUAL)
376 (XK_KP_F1 . ,XK_KP_F1)
377 (XK_KP_F2 . ,XK_KP_F2)
378 (XK_KP_F3 . ,XK_KP_F3)
379 (XK_KP_F4 . ,XK_KP_F4)
380 (XK_KP_MULTIPLY . ,XK_KP_MULTIPLY)
381 (XK_KP_SEPARATOR . ,XK_KP_SEPARATOR)
382 (XK_KP_SPACE . ,XK_KP_SPACE)
383 (XK_KP_SUBTRACT . ,XK_KP_SUBTRACT)
384 (XK_KP_TAB . ,XK_KP_TAB)
385 (XK_L . ,XK_L)
386 (XK_L1 . ,XK_L1)
387 (XK_L10 . ,XK_L10)
388 (XK_L2 . ,XK_L2)
389 (XK_L3 . ,XK_L3)
390 (XK_L4 . ,XK_L4)
391 (XK_L5 . ,XK_L5)
392 (XK_L6 . ,XK_L6)
393 (XK_L7 . ,XK_L7)
394 (XK_L8 . ,XK_L8)
395 (XK_L9 . ,XK_L9)
396 (XK_LCA . ,XK_LCA)
397 (XK_LCAACUTE . ,XK_LCAACUTE)
398 (XK_LCACIRCUMFLEX . ,XK_LCACIRCUMFLEX)
399 (XK_LCADIAERESIS . ,XK_LCADIAERESIS)
400 (XK_LCAE . ,XK_LCAE)
401 (XK_LCAGRAVE . ,XK_LCAGRAVE)
402 (XK_LCARING . ,XK_LCARING)
403 (XK_LCATILDE . ,XK_LCATILDE)
404 (XK_LCB . ,XK_LCB)
405 (XK_LCC . ,XK_LCC)
406 (XK_LCCCEDILLA . ,XK_LCCCEDILLA)
407 (XK_LCD . ,XK_LCD)
408 (XK_LCE . ,XK_LCE)
409 (XK_LCEACUTE . ,XK_LCEACUTE)
410 (XK_LCECIRCUMFLEX . ,XK_LCECIRCUMFLEX)
411 (XK_LCEDIAERESIS . ,XK_LCEDIAERESIS)
412 (XK_LCEGRAVE . ,XK_LCEGRAVE)
413 (XK_LCETH . ,XK_LCETH)
414 (XK_LCF . ,XK_LCF)
415 (XK_LCG . ,XK_LCG)
416 (XK_LCH . ,XK_LCH)
417 (XK_LCI . ,XK_LCI)
418 (XK_LCIACUTE . ,XK_LCIACUTE)
419 (XK_LCICIRCUMFLEX . ,XK_LCICIRCUMFLEX)
420 (XK_LCIDIAERESIS . ,XK_LCIDIAERESIS)
421 (XK_LCIGRAVE . ,XK_LCIGRAVE)
422 (XK_LCJ . ,XK_LCJ)
423 (XK_LCK . ,XK_LCK)
424 (XK_LCL . ,XK_LCL)
425 (XK_LCM . ,XK_LCM)
426 (XK_LCN . ,XK_LCN)
427 (XK_LCNTILDE . ,XK_LCNTILDE)
428 (XK_LCO . ,XK_LCO)
429 (XK_LCOACUTE . ,XK_LCOACUTE)
430 (XK_LCOCIRCUMFLEX . ,XK_LCOCIRCUMFLEX)
431 (XK_LCODIAERESIS . ,XK_LCODIAERESIS)
432 (XK_LCOGRAVE . ,XK_LCOGRAVE)
433 (XK_LCOTILDE . ,XK_LCOTILDE)
434 (XK_LCP . ,XK_LCP)
435 (XK_LCQ . ,XK_LCQ)
436 (XK_LCR . ,XK_LCR)
437 (XK_LCS . ,XK_LCS)
438 (XK_LCT . ,XK_LCT)
439 (XK_LCTHORN . ,XK_LCTHORN)
440 (XK_LCU . ,XK_LCU)
441 (XK_LCUACUTE . ,XK_LCUACUTE)
442 (XK_LCUCIRCUMFLEX . ,XK_LCUCIRCUMFLEX)
443 (XK_LCUDIAERESIS . ,XK_LCUDIAERESIS)
444 (XK_LCUGRAVE . ,XK_LCUGRAVE)
445 (XK_LCV . ,XK_LCV)
446 (XK_LCW . ,XK_LCW)
447 (XK_LCX . ,XK_LCX)
448 (XK_LCY . ,XK_LCY)
449 (XK_LCYACUTE . ,XK_LCYACUTE)
450 (XK_LCZ . ,XK_LCZ)
451 (XK_LEFT . ,XK_LEFT)
452 (XK_LESS . ,XK_LESS)
453 (XK_LINEFEED . ,XK_LINEFEED)
454 (XK_M . ,XK_M)
455 (XK_MACRON . ,XK_MACRON)
456 (XK_MASCULINE . ,XK_MASCULINE)
457 (XK_MENU . ,XK_MENU)
458 (XK_META_L . ,XK_META_L)
459 (XK_META_R . ,XK_META_R)
460 (XK_MINUS . ,XK_MINUS)
461 (XK_MODE_SWITCH . ,XK_MODE_SWITCH)
462 (XK_MU . ,XK_MU)
463 (XK_MULTIPLY . ,XK_MULTIPLY)
464 (XK_MULTI_KEY . ,XK_MULTI_KEY)
465 (XK_N . ,XK_N)
466 (XK_NEXT . ,XK_NEXT)
467 (XK_NOBREAKSPACE . ,XK_NOBREAKSPACE)
468 (XK_NOTSIGN . ,XK_NOTSIGN)
469 (XK_NTILDE . ,XK_NTILDE)
470 (XK_NUMBERSIGN . ,XK_NUMBERSIGN)
471 (XK_NUM_LOCK . ,XK_NUM_LOCK)
472 (XK_O . ,XK_O)
473 (XK_OACUTE . ,XK_OACUTE)
474 (XK_OCIRCUMFLEX . ,XK_OCIRCUMFLEX)
475 (XK_ODIAERESIS . ,XK_ODIAERESIS)
476 (XK_OGRAVE . ,XK_OGRAVE)
477 (XK_ONEHALF . ,XK_ONEHALF)
478 (XK_ONEQUARTER . ,XK_ONEQUARTER)
479 (XK_ONESUPERIOR . ,XK_ONESUPERIOR)
480 (XK_OOBLIQUE . ,XK_OOBLIQUE)
481 (XK_ORDFEMININE . ,XK_ORDFEMININE)
482 (XK_OSLASH . ,XK_OSLASH)
483 (XK_OTILDE . ,XK_OTILDE)
484 (XK_P . ,XK_P)
485 (XK_PARAGRAPH . ,XK_PARAGRAPH)
486 (XK_PARENLEFT . ,XK_PARENLEFT)
487 (XK_PARENRIGHT . ,XK_PARENRIGHT)
488 (XK_PAUSE . ,XK_PAUSE)
489 (XK_PERCENT . ,XK_PERCENT)
490 (XK_PERIOD . ,XK_PERIOD)
491 (XK_PERIODCENTERED . ,XK_PERIODCENTERED)
492 (XK_PLUS . ,XK_PLUS)
493 (XK_PLUSMINUS . ,XK_PLUSMINUS)
494 (XK_PRINT . ,XK_PRINT)
495 (XK_PRIOR . ,XK_PRIOR)
496 (XK_Q . ,XK_Q)
497 (XK_QUESTION . ,XK_QUESTION)
498 (XK_QUESTIONDOWN . ,XK_QUESTIONDOWN)
499 (XK_QUOTEDBL . ,XK_QUOTEDBL)
500 (XK_QUOTELEFT . ,XK_QUOTELEFT)
501 (XK_QUOTERIGHT . ,XK_QUOTERIGHT)
502 (XK_R . ,XK_R)
503 (XK_R1 . ,XK_R1)
504 (XK_R10 . ,XK_R10)
505 (XK_R11 . ,XK_R11)
506 (XK_R12 . ,XK_R12)
507 (XK_R13 . ,XK_R13)
508 (XK_R14 . ,XK_R14)
509 (XK_R15 . ,XK_R15)
510 (XK_R2 . ,XK_R2)
511 (XK_R3 . ,XK_R3)
512 (XK_R4 . ,XK_R4)
513 (XK_R5 . ,XK_R5)
514 (XK_R6 . ,XK_R6)
515 (XK_R7 . ,XK_R7)
516 (XK_R8 . ,XK_R8)
517 (XK_R9 . ,XK_R9)
518 (XK_REDO . ,XK_REDO)
519 (XK_REGISTERED . ,XK_REGISTERED)
520 (XK_RETURN . ,XK_RETURN)
521 (XK_RIGHT . ,XK_RIGHT)
522 (XK_S . ,XK_S)
523 (XK_SCRIPT_SWITCH . ,XK_SCRIPT_SWITCH)
524 (XK_SECTION . ,XK_SECTION)
525 (XK_SELECT . ,XK_SELECT)
526 (XK_SEMICOLON . ,XK_SEMICOLON)
527 (XK_SHIFT_L . ,XK_SHIFT_L)
528 (XK_SHIFT_LOCK . ,XK_SHIFT_LOCK)
529 (XK_SHIFT_R . ,XK_SHIFT_R)
530 (XK_SLASH . ,XK_SLASH)
531 (XK_SPACE . ,XK_SPACE)
532 (XK_SSHARP . ,XK_SSHARP)
533 (XK_STERLING . ,XK_STERLING)
534 (XK_SUPER_L . ,XK_SUPER_L)
535 (XK_SUPER_R . ,XK_SUPER_R)
536 (XK_T . ,XK_T)
537 (XK_TAB . ,XK_TAB)
538 (XK_THORN . ,XK_THORN)
539 (XK_THREEQUARTERS . ,XK_THREEQUARTERS)
540 (XK_THREESUPERIOR . ,XK_THREESUPERIOR)
541 (XK_TWOSUPERIOR . ,XK_TWOSUPERIOR)
542 (XK_U . ,XK_U)
543 (XK_UACUTE . ,XK_UACUTE)
544 (XK_UCIRCUMFLEX . ,XK_UCIRCUMFLEX)
545 (XK_UDIAERESIS . ,XK_UDIAERESIS)
546 (XK_UGRAVE . ,XK_UGRAVE)
547 (XK_UNDERSCORE . ,XK_UNDERSCORE)
548 (XK_UNDO . ,XK_UNDO)
549 (XK_UP . ,XK_UP)
550 (XK_V . ,XK_V)
551 (XK_W . ,XK_W)
552 (XK_X . ,XK_X)
553 (XK_Y . ,XK_Y)
554 (XK_YACUTE . ,XK_YACUTE)
555 (XK_YDIAERESIS . ,XK_YDIAERESIS)
556 (XK_YEN . ,XK_YEN)
557 (XK_Z . ,XK_Z)
558 (DXK_ACUTE_ACCENT . ,DXK_ACUTE_ACCENT)
559 (DXK_CEDILLA_ACCENT . ,DXK_CEDILLA_ACCENT)
560 (DXK_CIRCUMFLEX_ACCENT . ,DXK_CIRCUMFLEX_ACCENT)
561 (DXK_DIAERESIS . ,DXK_DIAERESIS)
562 (DXK_GRAVE_ACCENT . ,DXK_GRAVE_ACCENT)
563 (DXK_REMOVE . ,DXK_REMOVE)
564 (DXK_RING_ACCENT . ,DXK_RING_ACCENT)
565 (DXK_TILDE . ,DXK_TILDE)))
566
567;;; Debugging
568
569(define xevent-types
570 `((,KEYPRESS . KEYPRESS)
571 (,KEYRELEASE . KEYRELEASE)
572 (,BUTTONPRESS . BUTTONPRESS)
573 (,BUTTONRELEASE . BUTTONRELEASE)
574 (,MOTIONNOTIFY . MOTIONNOTIFY)
575 (,ENTERNOTIFY . ENTERNOTIFY)
576 (,LEAVENOTIFY . LEAVENOTIFY)
577 (,FOCUSIN . FOCUSIN)
578 (,FOCUSOUT . FOCUSOUT)
579 (,KEYMAPNOTIFY . KEYMAPNOTIFY)
580 (,EXPOSE . EXPOSE)
581 (,GRAPHICSEXPOSE . GRAPHICSEXPOSE)
582 (,NOEXPOSE . NOEXPOSE)
583 (,VISIBILITYNOTIFY . VISIBILITYNOTIFY)
584 (,CREATENOTIFY . CREATENOTIFY)
585 (,DESTROYNOTIFY . DESTROYNOTIFY)
586 (,UNMAPNOTIFY . UNMAPNOTIFY)
587 (,MAPNOTIFY . MAPNOTIFY)
588 (,MAPREQUEST . MAPREQUEST)
589 (,REPARENTNOTIFY . REPARENTNOTIFY)
590 (,CONFIGURENOTIFY . CONFIGURENOTIFY)
591 (,CONFIGUREREQUEST . CONFIGUREREQUEST)
592 (,GRAVITYNOTIFY . GRAVITYNOTIFY)
593 (,RESIZEREQUEST . RESIZEREQUEST)
594 (,CIRCULATENOTIFY . CIRCULATENOTIFY)
595 (,CIRCULATEREQUEST . CIRCULATEREQUEST)
596 (,PROPERTYNOTIFY . PROPERTYNOTIFY)
597 (,SELECTIONCLEAR . SELECTIONCLEAR)
598 (,SELECTIONREQUEST . SELECTIONREQUEST)
599 (,SELECTIONNOTIFY . SELECTIONNOTIFY)
600 (,COLORMAPNOTIFY . COLORMAPNOTIFY)
601 (,CLIENTMESSAGE . CLIENTMESSAGE)
602 (,MAPPINGNOTIFY . MAPPINGNOTIFY)
603 #;(,GENERICEVENT . GENERICEVENT)))
604
605(define-public (xevent-type-name type)
606 (let ((x (assq type xevent-types)))
607 (and x (cdr x))))