source: release/1.2/source/cocoa-ide/hemlock/src/key-event.lisp

Last change on this file was 9200, checked in by Gary Byers, 17 years ago

synch with trunk

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.7 KB
RevLine 
[8428]1;;; -*- Log: hemlock.log; Package: Hemlock-Internals -*-
[6]2;;;
3;;; **********************************************************************
4;;; This code was written as part of the CMU Common Lisp project at
5;;; Carnegie Mellon University, and has been placed in the public domain.
6;;;
7#+CMU (ext:file-comment
8 "$Header$")
9;;;
10;;; **********************************************************************
11;;;
[8428]12;;; This file implements key-events for representing editor input.
[6]13;;;
14;;; Written by Blaine Burks and Bill Chiles.
15;;;
16
[8428]17(in-package :hemlock-internals)
18
19
20
21;;; Objects involved in key events:
22;;; (1) a KEY-EVENT describes a combination of a KEYSYM and MODIFIERS. KEY-EVENTS
23;;; are interned, so there is a unique key-event for each combination of keysym and
24;;; modifiers.
25;;; (2) A KEYSYM is an object representing a key. It must be declared to be so via
26;;; define-keysym. A KEYSYM must be defined before a key-event based on it can be
27;;; defined.
28;;; (3) A CODE is a system-dependent fixnum value for a KEYSYM. It must be defined
29;;; before any events actually occur, but it doesn't need to be defined in order to
[6]30;;; create key-events.
[8428]31;;;
32;;; The Keysym can be the same as a code, but separating them deals with a bootstrapping
33;;; problem: keysyms cannot be defined before hemlock is loaded, but hemlock wants to
34;;; define key events while it's loading. So we define key events using keysyms, and let
[6]35;;; their codes be defined later
36
37
38;;;; Keysym <==> Name translation.
39
40;;; Keysyms are named by case-insensitive names. However, if the name
41;;; consists of a single character, the name is case-sensitive.
42;;;
43
44;;; This table maps a keysym to a list of names. The first name is the
45;;; preferred printing name.
46;;;
47(defvar *keysyms-to-names*)
48
49;;; This table maps all keysym names to the appropriate keysym.
50;;;
51(defvar *names-to-keysyms*)
52
53(declaim (inline name-keysym keysym-names keysym-preferred-name))
54
55(defun name-keysym (name)
56 "This returns the keysym named name. If name is unknown, this returns nil."
57 (gethash (get-name-case-right name) *names-to-keysyms*))
58
59(defun keysym-names (keysym)
60 "This returns the list of all names for keysym. If keysym is undefined,
[6703]61 this returns nil."
62 (or (gethash keysym *keysyms-to-names*)
63 (let* ((name (char-name (code-char keysym))))
64 (when name (setf (gethash keysym *keysyms-to-names*)
[6]65 (list name))))))
66
67(defun keysym-preferred-name (keysym)
68 "This returns the preferred name for keysym, how it is typically printed.
[6703]69 If keysym is undefined, this returns nil."
[6]70 (car (keysym-names keysym)))
71
72
73
74
75;;;; Character key-event stuff.
76
77;;; GET-NAME-CASE-RIGHT -- Internal.
78;;;
79;;; This returns the canonical string for a keysym name for use with
80;;; hash tables.
81;;;
82(defun get-name-case-right (string)
[8428]83 (if (= (length string) 1) string (string-downcase string)))
[6]84
85;;; DEFINE-KEYSYM -- Public
86;;;
87(defun define-keysym (keysym preferred-name &rest other-names)
88 "This establishes a mapping from preferred-name to keysym for purposes of
89 specifying key-events in #k syntax. Other-names also map to keysym, but the
90 system uses preferred-name when printing key-events. The names are
91 case-insensitive simple-strings. Redefining a keysym or re-using names has
92 undefined effects."
93 (setf (gethash keysym *keysyms-to-names*) (cons preferred-name other-names))
94 (dolist (name (cons preferred-name other-names))
[8428]95 (setf (gethash (get-name-case-right name) *names-to-keysyms*) keysym)))
96
97;;; This is an a-list mapping native modifier bit masks to defined key-event
[6]98;;; modifier names.
99;;;
100(defvar *modifier-translations*)
101
102;;; This is an ordered a-list mapping defined key-event modifier names to the
103;;; appropriate mask for the modifier. Modifier names have a short and a long
104;;; version. For each pair of names for the same mask, the names are
105;;; contiguous in this list, and the short name appears first.
106;;; PRINT-PRETTY-KEY-EVENT and KEY-EVENT-BITS-MODIFIERS rely on this.
107;;;
108(defvar *modifiers-to-internal-masks*)
109
110
[6998]111
[6]112
[6998]113
114(defvar *mouse-translation-info*)
115
116;;; MOUSE-TRANSLATION-INFO -- Internal.
117;;;
118;;; This returns the requested information, :keysym or :shifted-modifier-name,
[9200]119;;; for the button cross event-key. If the information is undefined, this
[6998]120;;; signals an error.
121;;;
122#+unused
123(defun mouse-translation-info (button event-key info)
124 (let ((event-dispatch (svref *mouse-translation-info* button)))
125 (unless event-dispatch
126 (error "No defined mouse translation information for button ~S." button))
127 (let ((data (ecase event-key
128 (:button-press (button-press-info event-dispatch))
129 (:button-release (button-release-info event-dispatch)))))
130 (unless data
131 (error
132 "No defined mouse translation information for button ~S and event ~S."
133 button event-key))
[6]134 (ecase info
135 (:keysym (button-keysym data))
[6998]136 (:shifted-modifier-name (button-shifted-modifier-name data))))))
137
138
139(eval-when (:compile-toplevel :execute)
140 (defmacro button-press-info (event-dispatch) `(car ,event-dispatch))
141 (defmacro button-release-info (event-dispatch) `(cdr ,event-dispatch))
142 (defmacro button-keysym (info) `(car ,info))
143 (defmacro button-shifted-modifier-name (info) `(cdr ,info))
144)
145
146;;; MOUSE-TRANSLATION-INFO -- Internal.
147;;;
148;;; This returns the requested information, :keysym or :shifted-modifier-name,
149;;; for the button cross event-key. If the information is undefined, this
150;;; signals an error.
151;;;
152(defun mouse-translation-info (button event-key info)
153 (let ((event-dispatch (svref *mouse-translation-info* button)))
154 (unless event-dispatch
155 (error "No defined mouse translation information for button ~S." button))
156 (let ((data (ecase event-key
157 (:button-press (button-press-info event-dispatch))
158 (:button-release (button-release-info event-dispatch)))))
159 (unless data
160 (error
161 "No defined mouse translation information for button ~S and event ~S."
162 button event-key))
163 (ecase info
164 (:keysym (button-keysym data))
165 (:shifted-modifier-name (button-shifted-modifier-name data))))))
166
167;;; (setf MOUSE-TRANSLATION-INFO) -- Internal.
168;;;
169;;; This walks into *mouse-translation-info* the same way MOUSE-TRANSLATION-INFO
170;;; does, filling in the data structure on an as-needed basis, and stores
171;;; the value for the indicated info.
172;;;
173(defun (setf mouse-translation-info) (value button event-key info)
174 (let ((event-dispatch (svref *mouse-translation-info* button)))
175 (unless event-dispatch
176 (setf event-dispatch
177 (setf (svref *mouse-translation-info* button) (cons nil nil))))
178 (let ((data (ecase event-key
179 (:button-press (button-press-info event-dispatch))
180 (:button-release (button-release-info event-dispatch)))))
181 (unless data
182 (setf data
183 (ecase event-key
184 (:button-press
185 (setf (button-press-info event-dispatch) (cons nil nil)))
186 (:button-release
187 (setf (button-release-info event-dispatch) (cons nil nil))))))
188 (ecase info
189 (:keysym
190 (setf (button-keysym data) value))
191 (:shifted-modifier-name
192 (setf (button-shifted-modifier-name data) value))))))
193
194
195
[8428]196;;; DEFINE-MOUSE-KEYSYM -- Public.
[6998]197;;;
198(defun define-mouse-keysym (button keysym name shifted-bit event-key)
199 "This defines keysym named name for the X button cross the X event-key."
200 (unless (<= 1 button 5)
201 (error "Buttons are number 1-5, not ~D." button))
202 (setf (gethash keysym *keysyms-to-names*) (list name))
203 (setf (gethash (get-name-case-right name) *names-to-keysyms*) keysym)
204 (setf (mouse-translation-info button event-key :keysym) keysym)
205 (setf (mouse-translation-info button event-key :shifted-modifier-name)
[6]206 shifted-bit))
207
208
[778]209
210
[6]211;;;; Stuff for parsing #k syntax.
[778]212
[6]213
[8428]214
[6]215(defstruct (key-event (:print-function %print-key-event)
216 (:constructor %make-key-event (keysym bits)))
217 (bits nil :type fixnum)
218 (keysym nil))
[8428]219
[6]220(defun %print-key-event (object stream ignore)
221 (declare (ignore ignore))
222 (write-string "#<Key-Event " stream)
223 (print-pretty-key object stream)
224 (write-char #\> stream))
[8428]225
[6]226;;; This maps Common Lisp CHAR-CODE's to character classes for parsing #k
227;;; syntax.
228;;;
229(defvar *key-character-classes* (make-array hemlock-char-code-limit
230 :initial-element :other))
231
232;;; These characters are special:
233;;; #\< .......... :ISO-start - Signals start of an ISO character.
234;;; #\> .......... :ISO-end - Signals end of an ISO character.
235;;; #\- .......... :modifier-terminator - Indicates last *id-namestring*
236;;; was a modifier.
237;;; #\" .......... :EOF - Means we have come to the end of the character.
238;;; #\{a-z, A-Z} .. :letter - Means the char is a letter.
239;;; #\space ....... :event-terminator- Indicates the last *id-namestring*
240;;; was a character name.
241;;;
242;;; Every other character has class :other.
243;;;
244(hi::do-alpha-chars (char :both)
245 (setf (svref *key-character-classes* (char-code char)) :letter))
246(setf (svref *key-character-classes* (char-code #\<)) :ISO-start)
247(setf (svref *key-character-classes* (char-code #\>)) :ISO-end)
248(setf (svref *key-character-classes* (char-code #\-)) :modifier-terminator)
249(setf (svref *key-character-classes* (char-code #\space)) :event-terminator)
250(setf (svref *key-character-classes* (char-code #\")) :EOF)
251
252;;; This holds the characters built up while lexing a potential keysym or
253;;; modifier identifier.
254;;;
255(defvar *id-namestring*
256 (make-array 30 :adjustable t :fill-pointer 0 :element-type 'base-char))
257
258;;; PARSE-KEY-FUN -- Internal.
259;;;
[8428]260;;; This is the #k dispatch macro character reader. It is a FSM that parses
[6]261;;; key specifications. It returns either a VECTOR form or a MAKE-KEY-EVENT
262;;; form. Since key-events are unique at runtime, we cannot create them at
263;;; readtime, returning the constant object from READ. Wherever a #k appears,
264;;; there's a form that at loadtime or runtime will return the unique key-event
265;;; or vector of unique key-events.
266;;;
267(defun parse-key-fun (stream sub-char count)
268 (declare (ignore sub-char count))
269 (setf (fill-pointer *id-namestring*) 0)
270 (prog ((bits 0)
271 (key-event-list ())
[8428]272 char class)
[6]273 (unless (char= (read-char stream) #\")
274 (error "Keys must be delimited by ~S." #\"))
275 ;; Skip any leading spaces in the string.
276 (peek-char t stream)
277 (multiple-value-setq (char class) (get-key-char stream))
278 (ecase class
279 ((:letter :other :escaped) (go ID))
280 (:ISO-start (go ISOCHAR))
281 (:ISO-end (error "Angle brackets must be escaped."))
282 (:modifier-terminator (error "Dash must be escaped."))
283 (:EOF (error "No key to read.")))
284 ID
285 (vector-push-extend char *id-namestring*)
286 (multiple-value-setq (char class) (get-key-char stream))
287 (ecase class
288 ((:letter :other :escaped) (go ID))
289 (:event-terminator (go GOT-CHAR))
290 (:modifier-terminator (go GOT-MODIFIER))
291 ((:ISO-start :ISO-end) (error "Angle brackets must be escaped."))
292 (:EOF (go GET-LAST-CHAR)))
293 GOT-CHAR
294 (push `(make-key-event ,(copy-seq *id-namestring*) ,bits)
[8428]295 key-event-list)
[6]296 (setf (fill-pointer *id-namestring*) 0)
297 (setf bits 0)
298 ;; Skip any whitespace between characters.
299 (peek-char t stream)
300 (multiple-value-setq (char class) (get-key-char stream))
301 (ecase class
302 ((:letter :other :escaped) (go ID))
303 (:ISO-start (go ISOCHAR))
304 (:ISO-end (error "Angle brackets must be escaped."))
305 (:modifier-terminator (error "Dash must be escaped."))
306 (:EOF (go FINAL)))
307 GOT-MODIFIER
308 (let ((modifier-name (car (assoc *id-namestring*
309 *modifiers-to-internal-masks*
310 :test #'string-equal))))
311 (unless modifier-name
312 (error "~S is not a defined modifier." *id-namestring*))
313 (setf (fill-pointer *id-namestring*) 0)
314 (setf bits (logior bits (key-event-modifier-mask modifier-name))))
315 (multiple-value-setq (char class) (get-key-char stream))
316 (ecase class
317 ((:letter :other :escaped) (go ID))
318 (:ISO-start (go ISOCHAR))
319 (:ISO-end (error "Angle brackets must be escaped."))
320 (:modifier-terminator (error "Dash must be escaped."))
321 (:EOF (error "Expected something naming a key-event, got EOF.")))
322 ISOCHAR
323 (multiple-value-setq (char class) (get-key-char stream))
324 (ecase class
325 ((:letter :event-terminator :other :escaped)
326 (vector-push-extend char *id-namestring*)
327 (go ISOCHAR))
328 (:ISO-start (error "Open Angle must be escaped."))
329 (:modifier-terminator (error "Dash must be escaped."))
330 (:EOF (error "Bad syntax in key specification, hit eof."))
331 (:ISO-end (go GOT-CHAR)))
332 GET-LAST-CHAR
333 (push `(make-key-event ,(copy-seq *id-namestring*) ,bits)
334 key-event-list)
335 FINAL
336 (return (if (cdr key-event-list)
337 `(vector ,@(nreverse key-event-list))
338 `,(car key-event-list)))))
339
340(set-dispatch-macro-character #\# #\k #'parse-key-fun)
341
342(defconstant key-event-escape-char #\\
343 "The escape character that #k uses.")
344
345;;; GET-KEY-CHAR -- Internal.
346;;;
347;;; This is used by PARSE-KEY-FUN.
348;;;
349(defun get-key-char (stream)
350 (let ((char (read-char stream t nil t)))
351 (cond ((char= char key-event-escape-char)
352 (let ((char (read-char stream t nil t)))
353 (values char :escaped)))
354 (t (values char (svref *key-character-classes* (char-code char)))))))
355
356
357
358
359;;;; Code to deal with modifiers.
360
361(defvar *modifier-count* 0
362 "The number of modifiers that is currently defined.")
363
364(eval-when (:compile-toplevel :execute :load-toplevel)
365
366(defconstant modifier-count-limit 6
367 "The maximum number of modifiers supported.")
368
369); eval-when
370
371;;; This is purely a list for users.
372;;;
373(defvar *all-modifier-names* ()
374 "A list of all the names of defined modifiers.")
375
376;;; Note that short-name is pushed into *modifiers-to-internal-masks* after
377;;; long-name. PRINT-PRETTY-KEY-EVENT and KEY-EVENT-BITS-MODIFIERS rely on
378;;; this feature.
379;;;
380(defun define-key-event-modifier (long-name short-name)
381 "This establishes long-name and short-name as modifier names for purposes
382 of specifying key-events in #k syntax. The names are case-insensitive and
383 must be strings. If either name is already defined, this signals an error."
384 (when (= *modifier-count* modifier-count-limit)
385 (error "Maximum of ~D modifiers allowed." modifier-count-limit))
386 (let ((long-name (string-capitalize long-name))
387 (short-name (string-capitalize short-name)))
388 (flet ((frob (name)
389 (when (assoc name *modifiers-to-internal-masks*
390 :test #'string-equal)
391 (restart-case
392 (error "Modifier name has already been defined -- ~S" name)
393 (blow-it-off ()
394 :report "Go on without defining this modifier."
395 (return-from define-key-event-modifier nil))))))
396 (frob long-name)
397 (frob short-name))
398 (unwind-protect
399 (let ((new-bits (ash 1 *modifier-count*)))
400 (push (cons long-name new-bits) *modifiers-to-internal-masks*)
401 (push (cons short-name new-bits) *modifiers-to-internal-masks*)
402 (pushnew long-name *all-modifier-names* :test #'string-equal)
403 ;; Sometimes the long-name is the same as the short-name.
404 (pushnew short-name *all-modifier-names* :test #'string-equal))
405 (incf *modifier-count*))))
406
[8428]407;;;
[6]408;;; RE-INITIALIZE-KEY-EVENTS at the end of this file defines the system
[8428]409;;; default key-event modifiers.
410;;;
[6]411
412;;; DEFINE-MODIFIER-BIT -- Public.
413;;;
[8428]414(defun define-modifier-bit (bit-mask modifier-name)
[6]415 "This establishes a mapping from bit-mask to a define key-event modifier-name."
416 (let ((map (assoc modifier-name *modifiers-to-internal-masks*
417 :test #'string-equal)))
[8428]418 (unless map (error "~S an undefined modifier name." modifier-name))
[6]419 (push (cons bit-mask (car map)) *modifier-translations*)))
420
421;;;
422;;; RE-INITIALIZE-KEY-EVENTS at the end of this file defines the system
423;;; default modifiers, mapping them to some system default key-event
424;;; modifiers.
425;;;
426
427(defun make-key-event-bits (&rest modifier-names)
428 "This returns bits suitable for MAKE-KEY-EVENT from the supplied modifier
429 names. If any name is undefined, this signals an error."
430 (let ((mask 0))
431 (dolist (mod modifier-names mask)
432 (let ((this-mask (cdr (assoc mod *modifiers-to-internal-masks*
433 :test #'string-equal))))
434 (unless this-mask (error "~S is an undefined modifier name." mod))
435 (setf mask (logior mask this-mask))))))
436
437;;; KEY-EVENT-BITS-MODIFIERS -- Public.
438;;;
439(defun key-event-bits-modifiers (bits)
440 "This returns a list of key-event modifier names, one for each modifier
441 set in bits."
442 (let ((res nil))
443 (do ((map (cdr *modifiers-to-internal-masks*) (cddr map)))
444 ((null map) res)
445 (when (logtest bits (cdar map))
446 (push (caar map) res)))))
447
448;;; KEY-EVENT-MODIFIER-MASK -- Public.
449;;;
450(defun key-event-modifier-mask (modifier-name)
451 "This function returns a mask for modifier-name. This mask is suitable
452 for use with KEY-EVENT-BITS. If modifier-name is undefined, this signals
453 an error."
454 (let ((res (cdr (assoc modifier-name *modifiers-to-internal-masks*
455 :test #'string-equal))))
456 (unless res (error "Undefined key-event modifier -- ~S." modifier-name))
457 res))
[8428]458
[6]459
[8428]460
[6]461
462;;;; Key event lookup -- GET-KEY-EVENT and MAKE-KEY-EVENT.
463
464(defvar *key-events*)
465
466;;; GET-KEY-EVENT* -- Internal.
467;;;
[8428]468;;; This finds the key-event specified by keysym and bits. If the key-event
[7052]469;;; does not already exist, this creates it. This assumes keysym is defined,
470;;; and if it isn't, this will make a key-event anyway that will cause an
471;;; error when the system tries to print it.
472;;;
473(defun get-key-event* (keysym bits)
[8428]474 (let* ((char (and (fixnump keysym) (code-char keysym))))
475 (when (and char (standard-char-p char))
476 (let* ((mask (key-event-modifier-mask "Shift")))
[6]477 (when (logtest bits mask)
478 (setq bits (logandc2 bits mask)
[8428]479 keysym (char-code (char-upcase char)))))))
480 (let* ((data (cons keysym bits)))
481 (or (gethash data *key-events*)
482 (setf (gethash data *key-events*) (%make-key-event keysym bits)))))
483
484;;;
485(defvar *keysym-to-code*)
486(defvar *code-to-keysym*)
487
488(defmacro define-keysym-code (keysym code)
489 `(progn
490 (setf (gethash ,keysym *keysym-to-code*) ,code)
491 (setf (gethash ,code *code-to-keysym*) ,keysym)))
492
493(defun keysym-for-code (code)
[6]494 (or (gethash code *code-to-keysym*) code))
495
496(defun code-for-keysym (keysym)
497 (or (gethash keysym *keysym-to-code*) (and (fixnump keysym) keysym)))
498
499;;;
500(defun make-key-event (object &optional (bits 0))
[8428]501 "This returns a key-event described by object with bits. Object is one of
502 keysym, string, or key-event. When object is a key-event, this uses
503 KEY-EVENT-KEYSYM. You can form bits with MAKE-KEY-EVENT-BITS or
504 KEY-EVENT-MODIFIER-MASK."
[6]505 (etypecase object
506 (integer
507 (let ((keysym (keysym-for-code object)))
508 (unless (keysym-names keysym)
509 (error "~S is an undefined code." object))
510 (get-key-event* keysym bits)))
511 #|(character
512 (let* ((name (char-name object))
513 (keysym (name-keysym (or name (string object)))))
514 (unless keysym
515 (error "~S is an undefined keysym." object))
516 (get-key-event* keysym bits)))|#
517 (string
518 (let ((keysym (name-keysym object)))
519 (unless keysym
520 (error "~S is an undefined keysym." object))
521 (get-key-event* keysym bits)))
522 (key-event
523 (get-key-event* (key-event-keysym object) bits))))
524
525;;; KEY-EVENT-BIT-P -- Public.
526;;;
527(defun key-event-bit-p (key-event bit-name)
528 "This returns whether key-event has the bit set named by bit-name. This
529 signals an error if bit-name is undefined."
530 (let ((mask (cdr (assoc bit-name *modifiers-to-internal-masks*
531 :test #'string-equal))))
532 (unless mask
533 (error "~S is not a defined modifier." bit-name))
534 (not (zerop (logand (key-event-bits key-event) mask)))))
535
536
537
538
539;;;; KEY-EVENT-CHAR and CHAR-KEY-EVENT.
540
541;;; This maps key-events to characters. Users modify this by SETF'ing
[6703]542;;; KEY-EVENT-CHAR.
[8428]543;;;
[6]544(defvar *key-event-characters*)
545
546(defun key-event-char (key-event)
547 "Returns the character associated with key-event. This is SETF'able."
548 (check-type key-event key-event)
549 (or (gethash key-event *key-event-characters*)
550 (code-char (code-for-keysym (key-event-keysym key-event)))))
551
552(defun %set-key-event-char (key-event character)
553 (check-type character character)
554 (check-type key-event key-event)
555 (setf (gethash key-event *key-event-characters*) character))
556;;;
557(defsetf key-event-char %set-key-event-char)
558
559
560;;; This maps characters to key-events. Users modify this by SETF'ing
561;;; CHAR-KEY-EVENT.
562;;;
563(defvar *character-key-events*)
564
565(defun char-key-event (char)
566 "Returns the key-event associated with char. This is SETF'able."
567 (check-type char character)
568 (svref *character-key-events* (char-code char)))
569
570(defun %set-char-key-event (char key-event)
571 (check-type char character)
572 (check-type key-event key-event)
573 (setf (svref *character-key-events* (char-code char)) key-event))
574;;;
575(defsetf char-key-event %set-char-key-event)
576
577
578
579
580;;;; DO-ALPHA-KEY-EVENTS.
581
582(defmacro alpha-key-events-loop (var start-keysym end-keysym result body)
583 (let ((n (gensym)))
584 `(do ((,n ,start-keysym (1+ ,n)))
585 ((> ,n ,end-keysym) ,result)
586 (let ((,var (make-key-event ,n 0)))
587 (when (alpha-char-p (key-event-char ,var))
588 ,@body)))))
589
590(defmacro do-alpha-key-events ((var kind &optional result) &rest forms)
591 "(DO-ALPHA-KEY-EVENTS (var kind [result]) {form}*)
592 This macro evaluates each form with var bound to a key-event representing an
593 alphabetic character. Kind is one of :lower, :upper, or :both, and this
594 binds var to each key-event in order as specified in the X11 protocol
595 specification. When :both is specified, this processes lowercase letters
596 first."
597 (case kind
598 (:both
599 `(progn (alpha-key-events-loop ,var 97 122 nil ,forms)
600 (alpha-key-events-loop ,var 65 90 ,result ,forms)))
601 (:lower
602 `(alpha-key-events-loop ,var 97 122 ,result ,forms))
603 (:upper
[8428]604 `(alpha-key-events-loop ,var 65 90 ,result ,forms))
[6]605 (t (error "Kind argument not one of :lower, :upper, or :both -- ~S."
606 kind))))
607
608
609
610
611;;;; PRINT-PRETTY-KEY and PRINT-PRETTY-KEY-EVENT.
612
613;;; PRINT-PRETTY-KEY -- Internal
614;;;
615(defun print-pretty-key (key &optional (stream *standard-output*) long-names-p)
616 "This prints key, a key-event or vector of key-events, to stream in a
617 user-expected fashion. Long-names-p indicates whether modifiers should
618 print with their long or short name."
[8428]619 (etypecase key
[6]620 (key-event (print-pretty-key-event key stream long-names-p))
621 (vector
622 (let ((length-1 (1- (length key))))
623 (dotimes (i (length key))
624 (let ((key-event (aref key i)))
625 (print-pretty-key-event key-event stream long-names-p)
626 (unless (= i length-1) (write-char #\space stream))))))))
627
628;;; PRINT-PRETTY-KEY-EVENT -- Internal
629;;;
630;;; Note, this makes use of the ordering in the a-list
631;;; *modifiers-to-internal-masks* by CDDR'ing down it by starting on a short
632;;; name or a long name.
633;;;
634(defun print-pretty-key-event (key-event &optional (stream *standard-output*)
635 long-names-p)
636 "This prints key-event to stream. Long-names-p indicates whether modifier
637 names should appear using the long name or short name."
638 (do ((map (if long-names-p
639 (cdr *modifiers-to-internal-masks*)
640 *modifiers-to-internal-masks*)
641 (cddr map)))
642 ((null map))
[8428]643 (when (not (zerop (logand (cdar map) (key-event-bits key-event))))
644 (write-string (caar map) stream)
645 (write-char #\- stream)))
646 (let* ((name (keysym-preferred-name (key-event-keysym key-event)))
647 (spacep (position #\space (the simple-string name))))
[6]648 (when spacep (write-char #\< stream))
649 (write-string name stream)
650 (when spacep (write-char #\> stream))))
651
652;;; PRETTY-KEY-STRING - Public.
653;;;
654(defun pretty-key-string (key &optional long-names-p)
655 (with-output-to-string (s)
[8428]656 (print-pretty-key key s long-names-p)))
[6]657
658
659;;;; Re-initialization.
660
661;;; RE-INITIALIZE-KEY-EVENTS -- Internal.
662;;;
663(defun re-initialize-key-events ()
[8428]664 "This blows away all data associated with keysyms, modifiers, mouse
665 translations, and key-event/characters mapping. Then it re-establishes
[6]666 the system defined key-event modifiers and the system defined
667 modifier mappings to some of those key-event modifiers.
[6998]668
[6]669 When recompiling this file, you should load it and call this function
670 before using any part of the key-event interface, especially before
[8428]671 defining all your keysyms and using #k syntax."
[6]672 (setf *keysyms-to-names* (make-hash-table :test #'eql))
673 (setf *names-to-keysyms* (make-hash-table :test #'equal))
[8428]674 (setf *keysym-to-code* (make-hash-table :test #'eql))
[6]675 (setf *code-to-keysym* (make-hash-table :test #'eql))
676 (setf *modifier-translations* ())
677 (setf *modifiers-to-internal-masks* ())
678 (setf *mouse-translation-info* (make-array 6 :initial-element nil))
679 (setf *modifier-count* 0)
680 (setf *all-modifier-names* ())
681 (setf *key-events* (make-hash-table :test #'equal))
682 (setf *key-event-characters* (make-hash-table))
[7595]683 (setf *character-key-events*
[6]684 (make-array hemlock-char-code-limit :initial-element nil))
685
686 (define-key-event-modifier "Hyper" "H")
687 (define-key-event-modifier "Super" "S")
688 (define-key-event-modifier "Meta" "M")
689 (define-key-event-modifier "Control" "C")
690 (define-key-event-modifier "Shift" "Shift")
691 (define-key-event-modifier "Lock" "Lock")
692
693)
694
695;;; Initialize stuff if not already initialized.
696;;;
697(unless (boundp '*keysyms-to-names*)
698 (re-initialize-key-events))
Note: See TracBrowser for help on using the repository browser.