|
|
1.1 root 1: /* $Id: keyboard.c,v 1.6 2003/10/16 02:48:18 fredette Exp $ */
2:
3: /* generic/keyboard.c - generic keyboard implementation support: */
4:
5: /*
6: * Copyright (c) 2003 Matt Fredette
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. All advertising materials mentioning features or use of this software
18: * must display the following acknowledgement:
19: * This product includes software developed by Matt Fredette.
20: * 4. The name of the author may not be used to endorse or promote products
21: * derived from this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33: * POSSIBILITY OF SUCH DAMAGE.
34: */
35:
36: #include <tme/common.h>
37: _TME_RCSID("$Id: keyboard.c,v 1.6 2003/10/16 02:48:18 fredette Exp $");
38:
39: /* includes: */
40: #include <tme/generic/keyboard.h>
41: #include <tme/hash.h>
42: #include <tme/misc.h>
43: #include <stdlib.h>
44:
45: /* macros: */
46:
47: /* the shortest possible time, in milliseconds, between two human
48: transitions on the same key: */
49: #define TME_KEYBOARD_SHORTEST_DOUBLE_MSEC (80)
50:
51: /* input stage zero uses a slightly expanded set of event types: */
52: #define TME_KEYBOARD_EVENT_IN0_RELEASE_USER (0)
53: #define TME_KEYBOARD_EVENT_IN0_PRESS_USER (1)
54: #define TME_KEYBOARD_EVENT_IN0_RELEASE_AUTO (2)
55: #define TME_KEYBOARD_EVENT_IN0_PRESS_AUTO (3)
56: #if TME_KEYBOARD_EVENT_RELEASE != TME_KEYBOARD_EVENT_IN0_RELEASE_USER
57: #error "TME_KEYBOARD_EVENT_RELEASE must be 0"
58: #endif
59: #if TME_KEYBOARD_EVENT_PRESS != TME_KEYBOARD_EVENT_IN0_PRESS_USER
60: #error "TME_KEYBOARD_EVENT_PRESS must be 1"
61: #endif
62:
63: /* this macro turns an input stage zero pressed value into the
64: corresponding release event type: */
65: #define TME_KEYBOARD_IN0_RELEASE_EVENT(pressed) ((pressed) ^ 1)
66:
67: /* these macros evaluate to nonzero iff a keyval is pressed in the
68: different stages: */
69: #define TME_KEYBOARD_PRESSED_IN0(keysym) \
70: ((keysym)->tme_keysym_state_in0_pressed)
71: #define TME_KEYBOARD_PRESSED_IN1(keysym) \
72: ((keysym)->tme_keysym_state_in1_keymode.tme_keymode_state_pressed)
73: #define _TME_KEYBOARD_PRESSED_IN2(keysym, prev) \
74: ((keysym)->tme_keysym_state_in2_pressed \
75: || (!(keysym)->tme_keysym_state_in2_released \
76: && prev))
77: #define TME_KEYBOARD_PRESSED_IN2(keysym) \
78: _TME_KEYBOARD_PRESSED_IN2(keysym, TME_KEYBOARD_PRESSED_IN1(keysym))
79: #define _TME_KEYBOARD_PRESSED_OUT0(keysym, prev)\
80: ((keysym)->tme_keysym_state_out0_pressed \
81: || (!(keysym)->tme_keysym_state_out0_released\
82: && prev))
83: #define TME_KEYBOARD_PRESSED_OUT0(keysym) \
84: _TME_KEYBOARD_PRESSED_OUT0(keysym, TME_KEYBOARD_PRESSED_IN2(keysym))
85: #define TME_KEYBOARD_PRESSED_OUT1(keycode) \
86: ((keycode)->tme_keycode_state_keymode.tme_keymode_state_pressed)
87:
88: /* types: */
89:
90: struct tme_keyboard_buffer_int;
91: struct tme_keysym_state;
92:
93: /* keymode state: */
94: struct tme_keymode_state {
95:
96: /* keys that may be autorepeating are kept on a linked list: */
97: struct tme_keymode_state *tme_keymode_state_next;
98:
99: /* the state for this keysym. technically, since output stage one
100: deals in keycodes, this really should be a void * and point to
101: the keysym state for input stage one, and point to the keycode
102: state for output stage one.
103:
104: however, avoiding the void * allows us to avoid some function
105: pointer casting, and in the output stage one case we don't care
106: which of the many keysyms that may map to the same keycode is
107: stored here - we just immediately grab the keycode state out of
108: that keysym: */
109: struct tme_keysym_state *tme_keymode_state_keysym;
110:
111: /* the keymode mode: */
112: int tme_keymode_state_mode;
113:
114: /* this is nonzero iff the key is pressed in the physical sense: */
115: int tme_keymode_state_pressed;
116:
117: /* the last time this key was released: */
118: tme_uint32_t tme_keymode_state_last_release;
119:
120: /* this is nonzero iff a genuine release should be ignored: */
121: int tme_keymode_state_ignore_release;
122: };
123:
124: /* a keymode stage: */
125: struct tme_keymode_stage {
126:
127: /* the global keymode: */
128: int tme_keymode_stage_global_mode;
129:
130: /* the list of keymode states for keys that must not autorepeat: */
131: struct tme_keymode_state *tme_keymode_stage_no_autorepeats;
132:
133: /* the next stage: */
134: int (*tme_keymode_stage_next) _TME_P((struct tme_keyboard_buffer_int *,
135: struct tme_keysym_state *,
136: tme_uint32_t));
137: };
138:
139: /* keycode state: */
140: struct tme_keycode_state {
141:
142: /* the keycode: */
143: tme_keyboard_keyval_t tme_keycode_state_keycode;
144:
145: /* the keycode keymode state: */
146: struct tme_keymode_state tme_keycode_state_keymode;
147: };
148:
149: /* keysym state. one of these is kept for every keysym controlled by
150: one or more input or output stages: */
151: struct tme_keysym_state {
152:
153: /* this keysym: */
154: tme_keyboard_keyval_t tme_keysym_state_keysym;
155:
156: /* input stage zero: */
157:
158: /* if greater than TME_KEYBOARD_MODIFIER_NONE, this is the modifier
159: that this keysym is attached to in input stage zero: */
160: int tme_keysym_state_in0_modifier;
161:
162: /* the keysym states for all keys attached to the same modifier in
163: input stage zero are kept on a linked list: */
164: struct tme_keysym_state *tme_keysym_state_in0_modifier_next;
165:
166: /* this is nonzero iff the keysym is being pressed in input stage
167: zero. it's really either FALSE, or
168: TME_KEYBOARD_EVENT_IN0_PRESS_USER, or
169: TME_KEYBOARD_EVENT_IN0_PRESS_AUTO, which is why the last two are
170: nonzero: */
171: unsigned int tme_keysym_state_in0_pressed;
172:
173: /* the last time this keysym was pressed in input stage zero. this
174: is a time in milliseconds: */
175: tme_uint32_t tme_keysym_state_in0_press_time;
176:
177: /* input stage one: */
178:
179: /* the input stage one keymode state: */
180: struct tme_keymode_state tme_keysym_state_in1_keymode;
181:
182: /* input stage two: */
183:
184: /* this is nonzero iff the keysym is being released in input stage
185: two: */
186: unsigned int tme_keysym_state_in2_released;
187:
188: /* this is nonzero iff the keysym is being pressed in input stage
189: two: */
190: unsigned int tme_keysym_state_in2_pressed;
191:
192: /* output stage zero: */
193:
194: /* if non-NULL, this is the keycode that this keysym is mapped to in
195: output stage zero: */
196: struct tme_keycode_state *tme_keysym_state_out0_keycode;
197:
198: /* if this keysym is not attached to any modifier on the output
199: stage zero, it may require that certain output side modifiers be
200: set or clear in order for the keycode to mean the given keysym: */
201: tme_keyboard_modifiers_t tme_keysym_state_out0_modifiers_set;
202: tme_keyboard_modifiers_t tme_keysym_state_out0_modifiers_clear;
203:
204: /* iff greater than TME_KEYBOARD_MODIFIER_NONE, this is the modifier
205: that this keysym is attached to in output stage zero: */
206: int tme_keysym_state_out0_modifier;
207:
208: /* the keysym states for all keys attached to the same modifier in
209: output stage zero are kept on a linked list: */
210: struct tme_keysym_state *tme_keysym_state_out0_modifier_next;
211:
212: /* this is nonzero iff the keysym is being released in output stage
213: zero: */
214: unsigned int tme_keysym_state_out0_released;
215:
216: /* this is nonzero iff the keysym is being pressed in output stage
217: zero: */
218: unsigned int tme_keysym_state_out0_pressed;
219:
220: /* if this keysym is pressed in the output stage zero but required
221: output stage zero modifier changes to be so, this is the list of
222: those changes. since most keyboards generate the same keysym
223: using the same modifier(s), this list will usually be empty: */
224: struct tme_keysym_state **tme_keysym_state_out0_keysyms;
225: unsigned int *tme_keysym_state_out0_press_flags;
226:
227: /* output stage one: */
228:
229: /* this is nonzero iff the next release seen by output stage one
230: will not affect the output modifiers mask: */
231: int tme_keysym_state_out1_ignore_release;
232: };
233:
234: /* keyboard macros are necessary because it's almost certain that the
235: keyboard you want to emulate has keysyms that your keyboard doesn't
236: have. one keyboard macro takes a *sequence* of one or more pressed
237: keysyms to a *set* of one or more released and pressed keysyms.
238:
239: all keysym macros are kept in a single tree, where a single branch
240: represents the next keysym in the sequences for one or more macros.
241:
242: a node in the macros tree is active iff the keysyms on the path
243: from the root node have been pressed in sequence and remain
244: pressed. if there are any macros at all, the root node is always
245: active: */
246: struct tme_keyboard_macro {
247:
248: /* a pointer up to our parent node, and the keysym on the branch
249: from our parent to us. for the root node, these are NULL and
250: TME_KEYBOARD_KEYVAL_UNDEF, respectively: */
251: struct tme_keyboard_macro *tme_keyboard_macro_parent;
252: tme_keyboard_keyval_t tme_keyboard_macro_keysym;
253:
254: /* all active nodes are on a list. the root node is always active,
255: and it must be the last node on this list - making the is-active
256: test for all other nodes as simple as testing this pointer
257: against NULL: */
258: struct tme_keyboard_macro *tme_keyboard_macro_active_next;
259:
260: /* non-leaf nodes branch out by keysym: */
261: tme_hash_t tme_keyboard_macro_branches;
262:
263: /* leaf nodes contain the set of keysyms that the recognized
264: sequence maps to. in addition to presses of one or more new
265: keysyms, this will normally include releases of some or all of
266: the keysyms in the original sequence: */
267: unsigned int tme_keyboard_macro_length;
268: struct tme_keysym_state **tme_keyboard_macro_keysyms;
269: unsigned int *tme_keyboard_macro_press_flags;
270: };
271:
272: /* an internal keyboard buffer: */
273: struct tme_keyboard_buffer_int {
274:
275: /* the public keyboard buffer. this must be first: */
276: struct tme_keyboard_buffer tme_keyboard_buffer;
277: #define tme_keyboard_buffer_int_size tme_keyboard_buffer.tme_keyboard_buffer_size
278: #define tme_keyboard_buffer_int_head tme_keyboard_buffer.tme_keyboard_buffer_head
279: #define tme_keyboard_buffer_int_tail tme_keyboard_buffer.tme_keyboard_buffer_tail
280: #define tme_keyboard_buffer_int_events tme_keyboard_buffer.tme_keyboard_buffer_events
281: #define tme_keyboard_buffer_int_log_handle tme_keyboard_buffer.tme_keyboard_buffer_log_handle
282:
283: /* the keysyms state, common to all stages: */
284: tme_hash_t tme_keyboard_buffer_int_keysyms_state;
285:
286: /* input stage zero: */
287:
288: /* this is nonzero iff input stage zero has modifier information,
289: and it's actually the mask of modifiers that we have keysyms for: */
290: unsigned int tme_keyboard_buffer_int_in0_have_modifiers;
291:
292: /* the lists of keysyms that are attached to input stage zero
293: modifiers: */
294: struct tme_keysym_state *tme_keyboard_buffer_int_in0_modkeys[TME_KEYBOARD_MODIFIER_MAX + 1];
295:
296: /* the current input stage zero modifiers mask: */
297: tme_keyboard_modifiers_t tme_keyboard_buffer_int_in0_modifiers;
298:
299: /* the current input stage zero pressed keycodes, mapped to their
300: corresponding struct tme_keysym_states: */
301: tme_hash_t tme_keyboard_buffer_int_in0_keycodes;
302:
303: /* input stage one: */
304:
305: /* the input stage one keymode stage: */
306: struct tme_keymode_stage tme_keyboard_buffer_int_in1_keymode_stage;
307:
308: /* input stage two: */
309:
310: /* this is NULL iff input stage two is a passthrough, else this is
311: the list of active nodes in the input stage two keysym macros
312: tree: */
313: struct tme_keyboard_macro *tme_keyboard_buffer_int_in2_macros_active;
314:
315: /* the root of the input stage two keysym macros tree: */
316: struct tme_keyboard_macro tme_keyboard_buffer_int_in2_macros_root;
317:
318: /* output stage zero: */
319:
320: /* this is nonzero iff output stage zero is just a passthrough: */
321: unsigned int tme_keyboard_buffer_int_out0_passthrough;
322:
323: /* the output stage zero keycodes: */
324: tme_hash_t tme_keyboard_buffer_int_out0_keycodes;
325:
326: /* this is nonzero iff the output stage zero lock modifier is to be
327: treated as caps lock: */
328: int tme_keyboard_buffer_int_out0_lock_is_caps;
329:
330: /* any output stage zero modifier that the Num_Lock keysym is
331: attached to: */
332: int tme_keyboard_buffer_int_out0_mod_num_lock;
333:
334: /* the lists of keysyms that are output stage zero modifiers: */
335: struct tme_keysym_state *tme_keyboard_buffer_int_out0_modkeys[TME_KEYBOARD_MODIFIER_MAX + 1];
336:
337: /* the current output stage zero modifiers mask: */
338: tme_keyboard_modifiers_t tme_keyboard_buffer_int_out0_modifiers;
339:
340: /* output stage one: */
341:
342: /* the output stage one keymode stage: */
343: struct tme_keymode_stage tme_keyboard_buffer_int_out1_keymode_stage;
344: };
345:
346: /* prototypes: */
347: static int _tme_keyboard_buffer_in2 _TME_P((struct tme_keyboard_buffer_int *,
348: struct tme_keysym_state *,
349: tme_uint32_t));
350: static int _tme_keyboard_buffer_out1_bottom _TME_P((struct tme_keyboard_buffer_int *,
351: struct tme_keysym_state *,
352: tme_uint32_t));
353:
354: /* this is for debugging only: */
355: #if 0
356: static void
357: _tme_keyboard_debug(const struct tme_keyboard_buffer_int *buffer,
358: const char *stage,
359: tme_keyboard_keyval_t keyval,
360: int is_press,
361: tme_uint32_t event_time)
362: {
363: struct tme_log_handle *handle;
364: const char *string;
365: extern const char *_tme_gtk_keyboard_keyval_name _TME_P((tme_keyboard_keyval_t));
366:
367: handle = buffer->tme_keyboard_buffer_int_log_handle;
368: if (handle == NULL) {
369: return;
370: }
371:
372: string = _tme_gtk_keyboard_keyval_name(keyval);
373: if (string == NULL) {
374: string = "???";
375: }
376:
377: tme_log(handle, 100, TME_OK,
378: (handle,
379: "%s event: time %lu key %lu (%s) %s",
380: stage,
381: (unsigned long) event_time,
382: (unsigned long) keyval,
383: string,
384: (is_press
385: ? "press"
386: : "release")));
387: }
388: #else
389: #define _tme_keyboard_debug(b, s, k, p, t) \
390: do { } while(/* CONSTCOND */ 0)
391: #endif
392:
393: /* this creates a new keyboard buffer: */
394: struct tme_keyboard_buffer *
395: tme_keyboard_buffer_new(unsigned int size)
396: {
397: struct tme_keyboard_buffer_int *buffer;
398: struct tme_keymode_stage *stage;
399: struct tme_keyboard_macro *root;
400: int modifier;
401:
402: /* round the buffer size up to a power of two: */
403: if (size & (size - 1)) {
404: do {
405: size &= (size - 1);
406: } while (size & (size - 1));
407: size <<= 1;
408: }
409:
410: /* allocate the buffer: */
411: buffer = tme_new0(struct tme_keyboard_buffer_int, 1);
412:
413: /* set the buffer size: */
414: buffer->tme_keyboard_buffer_int_size = size;
415:
416: /* set the head and tail pointers: */
417: buffer->tme_keyboard_buffer_int_head = 0;
418: buffer->tme_keyboard_buffer_int_tail = 0;
419:
420: /* allocate the buffer events: */
421: buffer->tme_keyboard_buffer_int_events
422: = tme_new(struct tme_keyboard_event, size);
423:
424: /* for now there is no log handle: */
425: buffer->tme_keyboard_buffer_int_log_handle = NULL;
426:
427: /* create the common keysyms state: */
428: buffer->tme_keyboard_buffer_int_keysyms_state
429: = tme_hash_new(tme_direct_hash,
430: tme_direct_compare,
431: (tme_hash_data_t) NULL);
432:
433: /* input stage zero begins with no modifiers: */
434: buffer->tme_keyboard_buffer_int_in0_have_modifiers = FALSE;
435:
436: /* initialize the input stage zero modifier keys lists: */
437: for (modifier = 0;
438: modifier <= TME_KEYBOARD_MODIFIER_MAX;
439: modifier++) {
440: buffer->tme_keyboard_buffer_int_in0_modkeys[modifier] = NULL;
441: }
442:
443: /* initialize the input stage zero modifiers mask: */
444: buffer->tme_keyboard_buffer_int_in0_modifiers = 0;
445:
446: /* initialize the input stage one keycodes hash: */
447: buffer->tme_keyboard_buffer_int_in0_keycodes
448: = tme_hash_new(tme_direct_hash,
449: tme_direct_compare,
450: (tme_hash_data_t) NULL);
451:
452: /* initialize the input stage one keymode stage: */
453: stage = &buffer->tme_keyboard_buffer_int_in1_keymode_stage;
454: stage->tme_keymode_stage_global_mode = 0;
455: stage->tme_keymode_stage_no_autorepeats = NULL;
456: stage->tme_keymode_stage_next = _tme_keyboard_buffer_in2;
457:
458: /* input stage two begins with no macros, so not even the root of
459: the macros tree is active: */
460: buffer->tme_keyboard_buffer_int_in2_macros_active = NULL;
461:
462: /* create the root of the input stage two keysym macros tree: */
463: root = &buffer->tme_keyboard_buffer_int_in2_macros_root;
464: root->tme_keyboard_macro_parent = NULL;
465: root->tme_keyboard_macro_keysym = TME_KEYBOARD_KEYVAL_UNDEF;
466: root->tme_keyboard_macro_active_next = NULL;
467: root->tme_keyboard_macro_branches
468: = tme_hash_new(tme_direct_hash,
469: tme_direct_compare,
470: (tme_hash_data_t) NULL);
471:
472: /* output stage zero begins as a passthrough: */
473: buffer->tme_keyboard_buffer_int_out0_passthrough = TRUE;
474:
475: /* initialize the output stage zero keycodes: */
476: buffer->tme_keyboard_buffer_int_out0_keycodes
477: = tme_hash_new(tme_direct_hash,
478: tme_direct_compare,
479: (tme_hash_data_t) NULL);
480:
481: /* the output stage zero lock modifier is assumed to be a Shift lock: */
482: buffer->tme_keyboard_buffer_int_out0_lock_is_caps
483: = FALSE;
484:
485: /* initialize the output stage zero modifier that the Num_Lock
486: keysym is attached to: */
487: buffer->tme_keyboard_buffer_int_out0_mod_num_lock
488: = TME_KEYBOARD_MODIFIER_NONE;
489:
490: /* initialize the output stage zero modifier keys lists: */
491: for (modifier = 0;
492: modifier <= TME_KEYBOARD_MODIFIER_MAX;
493: modifier++) {
494: buffer->tme_keyboard_buffer_int_out0_modkeys[modifier] = NULL;
495: }
496:
497: /* initialize the output stage zero modifiers mask: */
498: buffer->tme_keyboard_buffer_int_out0_modifiers = 0;
499:
500: /* initialize the output stage one keymode stage: */
501: stage = &buffer->tme_keyboard_buffer_int_out1_keymode_stage;
502: stage->tme_keymode_stage_global_mode = 0;
503: stage->tme_keymode_stage_no_autorepeats = NULL;
504: stage->tme_keymode_stage_next = _tme_keyboard_buffer_out1_bottom;
505:
506: /* done: */
507: return (&buffer->tme_keyboard_buffer);
508: }
509:
510: /* this destroys an entry in the common keysyms state: */
511: static void
512: _tme_keysym_state_destroy(tme_hash_data_t __keysym,
513: tme_hash_data_t _keysym,
514: void *_junk)
515: {
516: struct tme_keysym_state *keysym;
517:
518: /* recover the keysym state: */
519: keysym = (struct tme_keysym_state *) _keysym;
520:
521: /* if this keysym state has output stage zero keysym changes, free
522: them: */
523: if (keysym->tme_keysym_state_out0_keysyms != NULL) {
524: tme_free(keysym->tme_keysym_state_out0_keysyms);
525: tme_free(keysym->tme_keysym_state_out0_press_flags);
526: }
527:
528: /* free the state itself: */
529: tme_free(keysym);
530: }
531:
532: /* this recursively destroys the input stage two keysym macros tree: */
533: static void
534: _tme_keyboard_macro_destroy(tme_hash_data_t _keysym,
535: tme_hash_data_t _macro,
536: void *_junk)
537: {
538: struct tme_keyboard_macro *macro;
539:
540: /* get this macro: */
541: macro = (struct tme_keyboard_macro *) _macro;
542:
543: /* if this is a leaf node: */
544: if (macro->tme_keyboard_macro_branches == NULL) {
545:
546: /* free the keysyms and flags: */
547: tme_free(macro->tme_keyboard_macro_keysyms);
548: tme_free(macro->tme_keyboard_macro_press_flags);
549: }
550:
551: /* otherwise, recurse: */
552: else {
553: tme_hash_foreach(macro->tme_keyboard_macro_branches,
554: _tme_keyboard_macro_destroy,
555: NULL);
556: tme_hash_destroy(macro->tme_keyboard_macro_branches);
557: }
558:
559: /* free this tree node: */
560: tme_free(macro);
561: }
562:
563: /* this destroys an entry in the output stage zero keycodes state: */
564: static void
565: _tme_keycode_state_destroy(tme_hash_data_t __keycode,
566: tme_hash_data_t _keycode,
567: void *_junk)
568: {
569: struct tme_keycode_state *keycode;
570:
571: /* recover the keycode state: */
572: keycode = (struct tme_keycode_state *) _keycode;
573:
574: /* free the state itself: */
575: tme_free(keycode);
576: }
577:
578: /* this destroys a keyboard buffer: */
579: void
580: tme_keyboard_buffer_destroy(struct tme_keyboard_buffer *_buffer)
581: {
582: struct tme_keyboard_buffer_int *buffer;
583:
584: /* recover our data structure: */
585: buffer = (struct tme_keyboard_buffer_int *) _buffer;
586:
587: /* free the events: */
588: tme_free(buffer->tme_keyboard_buffer_int_events);
589:
590: /* destroy the common keysyms state: */
591: tme_hash_foreach(buffer->tme_keyboard_buffer_int_keysyms_state,
592: _tme_keysym_state_destroy,
593: NULL);
594: tme_hash_destroy(buffer->tme_keyboard_buffer_int_keysyms_state);
595:
596: /* destroy the input stage two keysym macros tree: */
597: tme_hash_foreach(buffer->tme_keyboard_buffer_int_in2_macros_root.tme_keyboard_macro_branches,
598: _tme_keyboard_macro_destroy,
599: NULL);
600: tme_hash_destroy(buffer->tme_keyboard_buffer_int_in2_macros_root.tme_keyboard_macro_branches);
601:
602: /* destroy the output stage zero keycodes: */
603: tme_hash_foreach(buffer->tme_keyboard_buffer_int_out0_keycodes,
604: _tme_keycode_state_destroy,
605: NULL);
606: tme_hash_destroy(buffer->tme_keyboard_buffer_int_out0_keycodes);
607:
608: /* destroy the buffer itself: */
609: tme_free(buffer);
610: }
611:
612: /* this gets the state for a keysym, creating a new state if one
613: doesn't exists yet: */
614: static struct tme_keysym_state *
615: _tme_keysym_state_get(struct tme_keyboard_buffer_int *buffer,
616: tme_keyboard_keyval_t _keysym)
617: {
618: struct tme_keysym_state *keysym;
619:
620: /* look up the state for this keysym: */
621: keysym
622: = ((struct tme_keysym_state *)
623: tme_hash_lookup(buffer->tme_keyboard_buffer_int_keysyms_state,
624: (tme_hash_data_t) _keysym));
625:
626: /* if the state doesn't exist, allocate it: */
627: if (keysym == NULL) {
628: keysym = tme_new0(struct tme_keysym_state, 1);
629:
630: /* initialize all fields that might not be properly initialized as
631: all-bits-zero: */
632: keysym->tme_keysym_state_keysym = _keysym;
633: keysym->tme_keysym_state_in0_modifier = TME_KEYBOARD_MODIFIER_NONE;
634: keysym->tme_keysym_state_in1_keymode.tme_keymode_state_keysym = keysym;
635: keysym->tme_keysym_state_out0_keycode = NULL;
636: keysym->tme_keysym_state_out0_modifier = TME_KEYBOARD_MODIFIER_NONE;
637: keysym->tme_keysym_state_out0_keysyms = NULL;
638: keysym->tme_keysym_state_out0_press_flags = NULL;
639:
640: /* insert this state into the hash: */
641: tme_hash_insert(buffer->tme_keyboard_buffer_int_keysyms_state,
642: (tme_hash_data_t) _keysym,
643: (tme_hash_data_t) keysym);
644: }
645:
646: /* done: */
647: return (keysym);
648: }
649:
650: /* this changes the set of keysyms that are attached to an input stage
651: zero modifier: */
652: int
653: tme_keyboard_buffer_in_modifier(struct tme_keyboard_buffer *_buffer,
654: int modifier,
655: const tme_keyboard_keyval_t *modkeys)
656: {
657: struct tme_keyboard_buffer_int *buffer;
658: struct tme_keysym_state *mod_keysym, **_mod_keysym;
659: tme_keyboard_keyval_t keysym;
660:
661: /* recover our data structure: */
662: buffer = (struct tme_keyboard_buffer_int *) _buffer;
663:
664: /* this must be a valid modifier: */
665: assert (modifier > TME_KEYBOARD_MODIFIER_NONE
666: && modifier <= TME_KEYBOARD_MODIFIER_MAX);
667:
668: /* remove all currently attached keysyms from this modifier: */
669: for (mod_keysym = buffer->tme_keyboard_buffer_int_in0_modkeys[modifier];
670: mod_keysym != NULL;
671: mod_keysym = mod_keysym->tme_keysym_state_in0_modifier_next) {
672: mod_keysym->tme_keysym_state_in0_modifier
673: = TME_KEYBOARD_MODIFIER_NONE;
674: }
675:
676: /* attach all of these new keysyms to this modifier: */
677: _mod_keysym = &buffer->tme_keyboard_buffer_int_in0_modkeys[modifier];
678: for (; (keysym = *(modkeys++)) != TME_KEYBOARD_KEYVAL_UNDEF; ) {
679: mod_keysym = _tme_keysym_state_get(buffer, keysym);
680: mod_keysym->tme_keysym_state_in0_modifier = modifier;
681: *_mod_keysym = mod_keysym;
682: _mod_keysym = &mod_keysym->tme_keysym_state_in0_modifier_next;
683: }
684: *_mod_keysym = NULL;
685:
686: /* input stage zero now has modifier information: */
687: buffer->tme_keyboard_buffer_int_in0_have_modifiers
688: |= (1 << modifier);
689:
690: return (TME_OK);
691: }
692:
693: /* this changes a keysym's input stage one keymode: */
694: int
695: tme_keyboard_buffer_in_mode(struct tme_keyboard_buffer *_buffer,
696: tme_keyboard_keyval_t _keysym, int mode)
697: {
698: struct tme_keyboard_buffer_int *buffer;
699: struct tme_keysym_state *keysym;
700:
701: /* recover our data structure: */
702: buffer = (struct tme_keyboard_buffer_int *) _buffer;
703:
704: /* there's no such thing as a global input keymode: */
705: assert (_keysym != TME_KEYBOARD_KEYVAL_UNDEF);
706:
707: /* TME_KEYBOARD_MODE_UNLOCK and TME_KEYBOARD_MODE_LOCK cannot be
708: combined with any other bits: */
709: if ((mode
710: & (TME_KEYBOARD_MODE_UNLOCK
711: | TME_KEYBOARD_MODE_LOCK))
712: && (mode
713: & (mode - 1))) {
714: return (EINVAL);
715: }
716:
717: /* none of the TME_KEYBOARD_MODE_FLAG_NO_AUTOREPEATS,
718: TME_KEYBOARD_MODE_FLAG_NO_RELEASES, and
719: TME_KEYBOARD_MODE_FLAG_LOCK_SOFT flags can be set
720: without TME_KEYBOARD_MODE_PASSTHROUGH: */
721: if ((mode
722: & (TME_KEYBOARD_MODE_FLAG_NO_AUTOREPEATS
723: | TME_KEYBOARD_MODE_FLAG_NO_RELEASES
724: | TME_KEYBOARD_MODE_FLAG_LOCK_SOFT))
725: && !(mode
726: & TME_KEYBOARD_MODE_PASSTHROUGH)) {
727: return (EINVAL);
728: }
729:
730: /* you cannot specify that an input key must not release, or
731: that it soft locks: */
732: if (mode
733: & (TME_KEYBOARD_MODE_FLAG_NO_RELEASES
734: | TME_KEYBOARD_MODE_FLAG_LOCK_SOFT)) {
735: return (EINVAL);
736: }
737:
738: /* look up this keysym and set the input stage one mode: */
739: keysym = _tme_keysym_state_get(buffer, _keysym);
740: keysym->tme_keysym_state_in1_keymode.tme_keymode_state_mode = mode;
741: return (TME_OK);
742: }
743:
744: /* this adds an input stage two keysym macro: */
745: int
746: tme_keyboard_buffer_in_macro(struct tme_keyboard_buffer *_buffer,
747: const tme_keyboard_keyval_t *keysyms_lhs,
748: const tme_keyboard_keyval_t *keysyms_rhs)
749: {
750: struct tme_keyboard_buffer_int *buffer;
751: unsigned int count_lhs, count_rhs;
752: unsigned int keysym_i, keysym_j, keysym_count;
753: tme_keyboard_keyval_t keysym;
754: struct tme_keysym_state **keysyms;
755: unsigned int *press_flags;
756: int rc;
757: struct tme_keyboard_macro *macro, *macro_next;
758:
759: /* recover our data structure: */
760: buffer = (struct tme_keyboard_buffer_int *) _buffer;
761:
762: /* count the number of keysyms on both sides: */
763: for (count_lhs = 0;
764: keysyms_lhs[count_lhs] != TME_KEYBOARD_KEYVAL_UNDEF;
765: count_lhs++);
766: for (count_rhs = 0;
767: keysyms_rhs[count_rhs] != TME_KEYBOARD_KEYVAL_UNDEF;
768: count_rhs++);
769:
770: /* there must be some left-hand side and some right-hand side: */
771: if (count_lhs == 0
772: || count_rhs == 0) {
773: return (EINVAL);
774: }
775:
776: /* create the final keysyms and press-flags arrays for the macro. any
777: keysym on the left hand side that is also on the right hand side
778: becomes a press, else a release, and any keysym on the right hand
779: side that isn't on the left hand side becomes a press: */
780: keysyms = tme_new(struct tme_keysym_state *, count_lhs + count_rhs);
781: press_flags = tme_new(unsigned int, count_lhs + count_rhs);
782: keysym_count = 0;
783: for (keysym_i = 0;
784: keysym_i < count_lhs;
785: keysym_i++) {
786: keysym = keysyms_lhs[keysym_i];
787:
788: /* see if this keysym is on the right hand side: */
789: for (keysym_j = 0;
790: keysym_j < count_rhs;
791: keysym_j++) {
792: if (keysym == keysyms_rhs[keysym_j]) {
793: break;
794: }
795: }
796:
797: /* set this keysym and press-flags: */
798: keysyms[keysym_count] = _tme_keysym_state_get(buffer, keysym);
799: press_flags[keysym_count] = (keysym_j < count_rhs);
800: keysym_count++;
801: }
802: for (keysym_j = 0;
803: keysym_j < count_rhs;
804: keysym_j++) {
805: keysym = keysyms_rhs[keysym_j];
806:
807: /* see if this keysym is on the left hand side: */
808: for (keysym_i = 0;
809: keysym_i < count_lhs;
810: keysym_i++) {
811: if (keysym == keysyms_lhs[keysym_i]) {
812: break;
813: }
814: }
815:
816: /* set this keysym and press-flags: */
817: if (keysym_i == count_lhs) {
818: keysyms[keysym_count] = _tme_keysym_state_get(buffer, keysym);
819: press_flags[keysym_count] = TRUE;
820: keysym_count++;
821: }
822: }
823:
824: /* the last keysym in any macro's right hand side must be a press: */
825: if (!press_flags[keysym_count - 1]) {
826: tme_free(keysyms);
827: tme_free(press_flags);
828: return (EINVAL);
829: }
830:
831: /* add this keysym macro to the macros tree. this macro's sequence
832: (i.e., its left-hand side) cannot be strictly longer, or strictly
833: shorter, or the same as any existing macro's sequence: */
834: macro = &buffer->tme_keyboard_buffer_int_in2_macros_root;
835: rc = TME_OK;
836: for (keysym_i = 0;
837: ;
838: keysym_i++) {
839:
840: /* if we handled all left-hand side keysyms: */
841: if (keysym_i == count_lhs) {
842:
843: /* if this node is already a non-leaf node, then this macro's
844: sequence is strictly shorter than an existing macro's
845: sequence: */
846: if (macro->tme_keyboard_macro_branches != NULL) {
847: rc = EEXIST;
848: }
849:
850: /* otherwise, if this node is already a leaf node, then this
851: macro's sequence is the same as an existing macro's sequence: */
852: else if (macro->tme_keyboard_macro_length > 0) {
853: rc = EEXIST;
854: }
855:
856: /* stop no matter what: */
857: break;
858: }
859:
860: /* if this node has no branch set: */
861: if (macro->tme_keyboard_macro_branches == NULL) {
862:
863: /* if this node is already a leaf node, then this macro's
864: sequence is strictly longer than an existing macro's
865: sequence: */
866: if (macro->tme_keyboard_macro_length > 0) {
867: rc = EEXIST;
868: break;
869: }
870:
871: /* otherwise, create a branch set for this node: */
872: macro->tme_keyboard_macro_branches
873: = tme_hash_new(tme_direct_hash,
874: tme_direct_compare,
875: (tme_hash_data_t) NULL);
876: }
877:
878: /* get the keysym: */
879: keysym = keysyms_lhs[keysym_i];
880:
881: /* look up this keysym in the branch set for this node: */
882: macro_next
883: = ((struct tme_keyboard_macro *)
884: tme_hash_lookup(macro->tme_keyboard_macro_branches, (tme_hash_data_t) keysym));
885:
886: /* if this keysym is a new branch, create a new macros tree node: */
887: if (macro_next == NULL) {
888: macro_next = tme_new0(struct tme_keyboard_macro, 1);
889: macro_next->tme_keyboard_macro_parent = macro;
890: macro_next->tme_keyboard_macro_keysym = keysym;
891: tme_hash_insert(macro->tme_keyboard_macro_branches,
892: (tme_hash_data_t) keysym,
893: (tme_hash_data_t) macro_next);
894: }
895:
896: /* advance in the tree: */
897: macro = macro_next;
898: }
899:
900: /* if this sequence couldn't be added to the sequences tree: */
901: if (rc != TME_OK) {
902: tme_free(keysyms);
903: tme_free(press_flags);
904: return (rc);
905: }
906:
907: /* finish this leaf node in the macros tree: */
908: macro->tme_keyboard_macro_length = keysym_count;
909: macro->tme_keyboard_macro_keysyms = keysyms;
910: macro->tme_keyboard_macro_press_flags = press_flags;
911:
912: /* if this is the first keysym macro added, set the root of the
913: keysym macros tree as active, making input stage two no longer a
914: passthrough: */
915: if (buffer->tme_keyboard_buffer_int_in2_macros_active
916: == NULL) {
917: buffer->tme_keyboard_buffer_int_in2_macros_active
918: = &buffer->tme_keyboard_buffer_int_in2_macros_root;
919: }
920:
921: return (TME_OK);
922: }
923:
924: /* this adds a single output stage zero keysym map entry: */
925: int
926: tme_keyboard_buffer_out_map(struct tme_keyboard_buffer *_buffer,
927: _tme_const struct tme_keyboard_map *map)
928: {
929: struct tme_keyboard_buffer_int *buffer;
930: struct tme_keysym_state *keysym;
931: struct tme_keycode_state *keycode;
932: struct tme_keymode_state *keymode;
933: int modifier;
934: tme_keyboard_modifiers_t modifiers_set, modifiers_clear;
935:
936: /* recover our data structure: */
937: buffer = (struct tme_keyboard_buffer_int *) _buffer;
938:
939: /* the keysym must be defined: */
940: assert (map->tme_keyboard_map_keysym
941: != TME_KEYBOARD_KEYVAL_UNDEF);
942:
943: /* get the state for this keysym: */
944: keysym = _tme_keysym_state_get(buffer, map->tme_keyboard_map_keysym);
945:
946: /* this keysym must not already have an output side keycode: */
947: if (keysym->tme_keysym_state_out0_keycode != NULL) {
948: return (EEXIST);
949: }
950:
951: /* lookup this keycode: */
952: keycode
953: = ((struct tme_keycode_state *)
954: tme_hash_lookup(buffer->tme_keyboard_buffer_int_out0_keycodes,
955: (tme_hash_data_t) map->tme_keyboard_map_keycode));
956:
957: /* if this keycode is new, allocate, initialize and add a structure
958: for it: */
959: if (keycode == NULL) {
960:
961: /* allocate the keycode state: */
962: keycode = tme_new0(struct tme_keycode_state, 1);
963:
964: /* initialize any parts of the keycode state that might not be
965: properly initialized as all-bits-zero. note that the keysym
966: stored in the keycode keymode state is the first keysym mapped
967: to the keycode: */
968: keycode->tme_keycode_state_keycode = map->tme_keyboard_map_keycode;
969: keymode = &keycode->tme_keycode_state_keymode;
970: keymode->tme_keymode_state_keysym = keysym;
971:
972: /* add the keycode structure: */
973: tme_hash_insert(buffer->tme_keyboard_buffer_int_out0_keycodes,
974: (tme_hash_data_t) map->tme_keyboard_map_keycode,
975: (tme_hash_data_t) keycode);
976: }
977:
978: /* set this keycode on this keysym: */
979: keysym->tme_keysym_state_out0_keycode = keycode;
980:
981: /* if this keysym is attached to an output side modifier: */
982: modifier = map->tme_keyboard_map_modifier;
983: if (modifier != TME_KEYBOARD_MODIFIER_NONE) {
984:
985: /* attach this keysym to the output side modifier: */
986: keysym->tme_keysym_state_out0_modifier
987: = modifier;
988: keysym->tme_keysym_state_out0_modifier_next
989: = buffer->tme_keyboard_buffer_int_out0_modkeys[modifier];
990: buffer->tme_keyboard_buffer_int_out0_modkeys[modifier]
991: = keysym;
992:
993: /* dispatch on any special keysym note: */
994: switch (map->tme_keyboard_map_keysym_note) {
995: default: assert(FALSE);
996: case TME_KEYBOARD_KEYSYM_NOTE_UNDEF:
997: break;
998: case TME_KEYBOARD_KEYSYM_NOTE_CAPS_LOCK:
999: if (modifier == TME_KEYBOARD_MODIFIER_LOCK) {
1000: buffer->tme_keyboard_buffer_int_out0_lock_is_caps = TRUE;
1001: }
1002: break;
1003: case TME_KEYBOARD_KEYSYM_NOTE_SHIFT_LOCK:
1004: break;
1005: case TME_KEYBOARD_KEYSYM_NOTE_NUM_LOCK:
1006: buffer->tme_keyboard_buffer_int_out0_mod_num_lock = modifier;
1007: break;
1008: }
1009:
1010: /* this keysym cannot require any output side modifiers to be set
1011: or clear: */
1012: assert (map->tme_keyboard_map_modifiers_set == 0
1013: && map->tme_keyboard_map_modifiers_clear == 0);
1014: }
1015:
1016: /* remember the output stage zero modifiers that must be set or
1017: clear for this mapping to work: */
1018: modifiers_set = map->tme_keyboard_map_modifiers_set;
1019: modifiers_clear = map->tme_keyboard_map_modifiers_clear;
1020: assert ((modifiers_set & modifiers_clear) == 0);
1021:
1022: /* if this keysym is lowercase, it also requires the shift modifier
1023: to be clear: */
1024: if (modifiers_clear
1025: & (1 << TME_KEYBOARD_MODIFIER_LOCK)) {
1026: modifiers_clear
1027: |= (1 << TME_KEYBOARD_MODIFIER_SHIFT);
1028: }
1029:
1030: keysym->tme_keysym_state_out0_modifiers_set = modifiers_set;
1031: keysym->tme_keysym_state_out0_modifiers_clear = modifiers_clear;
1032:
1033: /* output stage zero is no longer a passthrough: */
1034: buffer->tme_keyboard_buffer_int_out0_passthrough = FALSE;
1035:
1036: return (TME_OK);
1037: }
1038:
1039: /* this changes a keycode's output stage one mode: */
1040: int
1041: tme_keyboard_buffer_out_mode(struct tme_keyboard_buffer *_buffer,
1042: tme_keyboard_keyval_t _keycode, int mode)
1043: {
1044: struct tme_keyboard_buffer_int *buffer;
1045: struct tme_keycode_state *keycode;
1046:
1047: /* recover our data structure: */
1048: buffer = (struct tme_keyboard_buffer_int *) _buffer;
1049:
1050: /* TME_KEYBOARD_MODE_UNLOCK and TME_KEYBOARD_MODE_LOCK cannot be
1051: combined with any other bits: */
1052: if ((mode
1053: & (TME_KEYBOARD_MODE_UNLOCK
1054: | TME_KEYBOARD_MODE_LOCK))
1055: && (mode
1056: & (mode - 1))) {
1057: return (EINVAL);
1058: }
1059:
1060: /* none of the TME_KEYBOARD_MODE_FLAG_NO_AUTOREPEATS,
1061: TME_KEYBOARD_MODE_FLAG_NO_RELEASES, and
1062: TME_KEYBOARD_MODE_FLAG_LOCK_SOFT flags can be set
1063: without TME_KEYBOARD_MODE_PASSTHROUGH: */
1064: if ((mode
1065: & (TME_KEYBOARD_MODE_FLAG_NO_AUTOREPEATS
1066: | TME_KEYBOARD_MODE_FLAG_NO_RELEASES
1067: | TME_KEYBOARD_MODE_FLAG_LOCK_SOFT))
1068: && !(mode
1069: & TME_KEYBOARD_MODE_PASSTHROUGH)) {
1070: return (EINVAL);
1071: }
1072:
1073: /* you cannot specify that an output key must be unlocked: */
1074: if (mode & TME_KEYBOARD_MODE_UNLOCK) {
1075: return (EINVAL);
1076: }
1077:
1078: /* if we are setting the mode on a particular keycode: */
1079: if (_keycode != TME_KEYBOARD_KEYVAL_UNDEF) {
1080: keycode
1081: = ((struct tme_keycode_state *)
1082: tme_hash_lookup(buffer->tme_keyboard_buffer_int_out0_keycodes,
1083: (tme_hash_data_t) _keycode));
1084: if (keycode == NULL) {
1085: return (ENOENT);
1086: }
1087: keycode->tme_keycode_state_keymode.tme_keymode_state_mode = mode;
1088: }
1089:
1090: /* otherwise, we are setting the mode on the whole keyboard: */
1091: else {
1092:
1093: /* you can't set TME_KEYBOARD_MODE_GLOBAL at the global level: */
1094: if (mode == TME_KEYBOARD_MODE_GLOBAL) {
1095: return (EINVAL);
1096: }
1097:
1098: /* set the output stage one global mode: */
1099: buffer->tme_keyboard_buffer_int_out1_keymode_stage
1100: .tme_keymode_stage_global_mode = mode;
1101: }
1102:
1103: return (TME_OK);
1104: }
1105:
1106: /* this fixes the keyboard's output stage zero modifiers when they get
1107: out of sync with the emulated software reading the output keyboard: */
1108: tme_keyboard_modifiers_t
1109: tme_keyboard_buffer_out_modifiers(struct tme_keyboard_buffer *_buffer,
1110: tme_keyboard_modifiers_t modifiers_clear,
1111: tme_keyboard_modifiers_t modifiers_set)
1112: {
1113: struct tme_keyboard_buffer_int *buffer;
1114:
1115: /* recover our data structure: */
1116: buffer = (struct tme_keyboard_buffer_int *) _buffer;
1117:
1118: /* update the modifiers: */
1119: return (buffer->tme_keyboard_buffer_int_out0_modifiers
1120: = ((buffer->tme_keyboard_buffer_int_out0_modifiers
1121: & ~modifiers_clear)
1122: | modifiers_set));
1123: }
1124:
1125: /* this parses a single keysym macro: */
1126: int
1127: tme_keyboard_parse_macro(const char *string,
1128: tme_keyboard_keysym_lookup_t keysym_lookup,
1129: void *keysym_lookup_private,
1130: tme_keyboard_keyval_t **_keysyms_lhs,
1131: tme_keyboard_keyval_t **_keysyms_rhs)
1132: {
1133: char **tokens;
1134: int tokens_count, equals_token;
1135: int token_i;
1136: tme_keyboard_keyval_t keysym, *keysyms_lhs, *keysyms_rhs;
1137: struct tme_keyboard_lookup lookup;
1138: unsigned int count_lhs, count_rhs;
1139: int rc;
1140:
1141: /* tokenize this line: */
1142: tokens = tme_misc_tokenize(string, '#', &tokens_count);
1143: keysyms_lhs = tme_new(tme_keyboard_keyval_t, tokens_count);
1144: keysyms_rhs = tme_new(tme_keyboard_keyval_t, tokens_count);
1145: count_lhs = 0;
1146: count_rhs = 0;
1147:
1148: /* start the lookup structure: */
1149: lookup.tme_keyboard_lookup_context_length = 0;
1150: lookup.tme_keyboard_lookup_context = NULL;
1151:
1152: /* all of the tokens must be valid keysyms, except for a single
1153: mandatory "=" token, which must not be the first or last token: */
1154: equals_token = -1;
1155: rc = TME_OK;
1156: for (token_i = 0;
1157: token_i < tokens_count;
1158: token_i++) {
1159:
1160: /* check for an "=" token: */
1161: if (!strcmp(tokens[token_i], "=")) {
1162: if (equals_token >= 0
1163: || token_i == 0
1164: || token_i + 1 == tokens_count) {
1165: rc = EINVAL;
1166: break;
1167: }
1168: equals_token = token_i;
1169: continue;
1170: }
1171:
1172: /* a token on the left hand side must be a keysym that the
1173: caller can generate directly: */
1174: if (equals_token < 0) {
1175:
1176: /* get the keysym for this token: */
1177: lookup.tme_keyboard_lookup_string = tokens[token_i];
1178: lookup.tme_keyboard_lookup_flags = TME_KEYBOARD_LOOKUP_FLAG_OK_DIRECT;
1179: keysym = (*keysym_lookup)(keysym_lookup_private, &lookup);
1180: if (keysym == TME_KEYBOARD_KEYVAL_UNDEF) {
1181: rc = ENOENT;
1182: break;
1183: }
1184: keysyms_lhs[count_lhs++] = keysym;
1185: }
1186:
1187: /* otherwise, a token on the right hand side is either a keysym
1188: that the caller can generate directly, or the caller must
1189: be able to allocate a unique value for it: */
1190: else {
1191:
1192: /* get the keysym for this token: */
1193: lookup.tme_keyboard_lookup_string = tokens[token_i];
1194: lookup.tme_keyboard_lookup_flags = (TME_KEYBOARD_LOOKUP_FLAG_OK_DIRECT
1195: | TME_KEYBOARD_LOOKUP_FLAG_OK_ALLOC
1196: | TME_KEYBOARD_LOOKUP_FLAG_OK_ALLOC_NOW);
1197: keysym = (*keysym_lookup)(keysym_lookup_private, &lookup);
1198: assert (keysym != TME_KEYBOARD_KEYVAL_UNDEF);
1199: keysyms_rhs[count_rhs++] = keysym;
1200: }
1201: }
1202:
1203: /* if this macro didn't parse correctly: */
1204: if (rc != TME_OK) {
1205: tme_free_string_array(tokens, -1);
1206: tme_free(keysyms_lhs);
1207: tme_free(keysyms_rhs);
1208: return (rc);
1209: }
1210:
1211: /* finish the sides of the macro: */
1212: keysyms_lhs[count_lhs] = TME_KEYBOARD_KEYVAL_UNDEF;
1213: keysyms_rhs[count_rhs] = TME_KEYBOARD_KEYVAL_UNDEF;
1214:
1215: /* done: */
1216: *_keysyms_lhs = keysyms_lhs;
1217: *_keysyms_rhs = keysyms_rhs;
1218: tme_free_string_array(tokens, -1);
1219: return (TME_OK);
1220: }
1221:
1222: /* this parses a single keysym map entry: */
1223: int
1224: tme_keyboard_parse_map(const char *string,
1225: tme_keyboard_keysym_lookup_t keysym_lookup,
1226: void *keysym_lookup_private,
1227: struct tme_keyboard_map *map)
1228: {
1229: char **tokens, *p1, c;
1230: int tokens_count;
1231: int token_i;
1232: tme_keyboard_keyval_t keycode;
1233: int modifier, attached_modifier;
1234: tme_keyboard_modifiers_t modifiers_set, modifiers_clear;
1235: struct tme_keyboard_lookup lookup;
1236: int rc;
1237:
1238: /* tokenize this line: */
1239: tokens = tme_misc_tokenize(string, '#', &tokens_count);
1240: rc = TME_OK;
1241:
1242: /* there must be at least three tokens. the second token must be an
1243: equals sign, and the third token must be an integer that isn't
1244: TME_KEYBOARD_KEYVAL_UNDEF: */
1245: if (tokens_count < 3
1246: || strcmp(tokens[1], "=")
1247: || ((keycode = strtoul(tokens[2], &p1, 0))
1248: == TME_KEYBOARD_KEYVAL_UNDEF)
1249: || p1 == tokens[2]
1250: || *p1 != '\0') {
1251: rc = EINVAL;
1252: }
1253:
1254: /* any tokens after the third must all be modifier names: */
1255: else {
1256: attached_modifier = TME_KEYBOARD_MODIFIER_NONE;
1257: modifiers_set = 0;
1258: modifiers_clear = 0;
1259: for (token_i = 3;
1260: token_i < tokens_count;
1261: token_i++) {
1262:
1263: /* a token might be prefixed with '+' or '!': */
1264: p1 = tokens[token_i];
1265: c = *p1;
1266: if (c == '+'
1267: || c == '!') {
1268: p1++;
1269: }
1270:
1271: /* turn this token into a real modifier: */
1272: if (!strcmp(p1, "shift")) {
1273: modifier = TME_KEYBOARD_MODIFIER_SHIFT;
1274: }
1275: else if (!strcmp(p1, "lock")) {
1276: modifier = TME_KEYBOARD_MODIFIER_LOCK;
1277: }
1278: else if (!strcmp(p1, "control")) {
1279: modifier = TME_KEYBOARD_MODIFIER_CONTROL;
1280: }
1281: else if (!strcmp(p1, "mod1")) {
1282: modifier = TME_KEYBOARD_MODIFIER_MOD1;
1283: }
1284: else if (!strcmp(p1, "mod2")) {
1285: modifier = TME_KEYBOARD_MODIFIER_MOD2;
1286: }
1287: else if (!strcmp(p1, "mod3")) {
1288: modifier = TME_KEYBOARD_MODIFIER_MOD3;
1289: }
1290: else if (!strcmp(p1, "mod4")) {
1291: modifier = TME_KEYBOARD_MODIFIER_MOD4;
1292: }
1293: else if (!strcmp(p1, "mod5")) {
1294: modifier = TME_KEYBOARD_MODIFIER_MOD5;
1295: }
1296: else {
1297: rc = EINVAL;
1298: break;
1299: }
1300:
1301: /* if a modifier is prefixed with '+', it must be the only
1302: modifier token in the map entry, and it indicates that the
1303: keycode is attached to that modifier in this map: */
1304: if (c == '+') {
1305:
1306: /* if this is not the only modifier token in the map entry: */
1307: if (tokens_count != 4) {
1308: rc = EINVAL;
1309: break;
1310: }
1311:
1312: attached_modifier = modifier;
1313: }
1314:
1315: /* otherwise, if a modifier name is prefixed with '!', this
1316: modifier must be clear for this keycode to mean this keysym: */
1317: else if (c == '!') {
1318: modifiers_clear |= (1 << modifier);
1319: }
1320:
1321: /* otherwise, this modifier must be set for this keycode to mean
1322: this keysym: */
1323: else {
1324: modifiers_set |= (1 << modifier);
1325: }
1326: }
1327:
1328: /* the modifiers that must be set and the modifiers that must be
1329: clear cannot overlap: */
1330: if (modifiers_set & modifiers_clear) {
1331: rc = EINVAL;
1332: }
1333:
1334: /* if no error has been encountered yet: */
1335: if (rc == TME_OK) {
1336:
1337: /* make the keyboard map entry. we very deliberately set all
1338: bytes not allocated to structure members to all-bits-zero, so
1339: that identical keysym contexts truly are identical: */
1340: memset(map, 0, sizeof(*map));
1341: map->tme_keyboard_map_keycode = keycode;
1342: map->tme_keyboard_map_modifier = attached_modifier;
1343: map->tme_keyboard_map_modifiers_set = modifiers_set;
1344: map->tme_keyboard_map_modifiers_clear = modifiers_clear;
1345:
1346: /* take note of a special keysym: */
1347: if (!strcmp(tokens[0], "Caps_Lock")) {
1348: map->tme_keyboard_map_keysym_note
1349: = TME_KEYBOARD_KEYSYM_NOTE_CAPS_LOCK;
1350: }
1351: else if (!strcmp(tokens[0], "Shift_Lock")) {
1352: map->tme_keyboard_map_keysym_note
1353: = TME_KEYBOARD_KEYSYM_NOTE_SHIFT_LOCK;
1354: }
1355: else if (!strcmp(tokens[0], "Num_Lock")) {
1356: map->tme_keyboard_map_keysym_note
1357: = TME_KEYBOARD_KEYSYM_NOTE_NUM_LOCK;
1358: }
1359: else {
1360: map->tme_keyboard_map_keysym_note
1361: = TME_KEYBOARD_KEYSYM_NOTE_UNDEF;
1362: }
1363:
1364: /* the caller must be able to either directly generate this
1365: keysym or have allocated a value for it already (because a
1366: macro was previously added than can generate it). if neither
1367: is true, the lookup function must return
1368: TME_KEYBOARD_KEYVAL_UNDEF, but this function still does not
1369: fail. it is up to the caller to not add a map entry with an
1370: undefined keysym: */
1371: lookup.tme_keyboard_lookup_string
1372: = tokens[0];
1373: lookup.tme_keyboard_lookup_flags
1374: = (TME_KEYBOARD_LOOKUP_FLAG_OK_DIRECT
1375: | TME_KEYBOARD_LOOKUP_FLAG_OK_ALLOC);
1376: lookup.tme_keyboard_lookup_context_length
1377: = sizeof(*map);
1378: lookup.tme_keyboard_lookup_context
1379: = (tme_uint8_t *) map;
1380: map->tme_keyboard_map_keysym
1381: = (*keysym_lookup)(keysym_lookup_private, &lookup);
1382: }
1383: }
1384:
1385: /* free the tokens: */
1386: tme_free_string_array(tokens, -1);
1387:
1388: /* return the parsed map: */
1389: return (rc);
1390: }
1391:
1392: /* this adds an event to the event buffer: */
1393: static int
1394: _tme_keyboard_buffer_copyin(struct tme_keyboard_buffer_int *buffer,
1395: _tme_const struct tme_keyboard_event *event)
1396: {
1397: unsigned int buffer_head, buffer_size_mask;
1398:
1399: buffer_head = buffer->tme_keyboard_buffer_int_head;
1400: buffer_size_mask = buffer->tme_keyboard_buffer_int_size - 1;
1401:
1402: /* if the buffer is full: */
1403: if (((buffer_head + 1) & buffer_size_mask)
1404: == buffer->tme_keyboard_buffer_int_tail) {
1405: return (EAGAIN);
1406: }
1407:
1408: /* put this event into the buffer: */
1409: buffer->tme_keyboard_buffer_int_events[buffer_head]
1410: = *event;
1411:
1412: /* advance the head: */
1413: buffer->tme_keyboard_buffer_int_head
1414: = (buffer_head + 1) & buffer_size_mask;
1415:
1416: return (TME_OK);
1417: }
1418:
1419: /* this adds a difference to an event time, avoiding a result of
1420: TME_KEYBOARD_EVENT_TIME_UNDEF: */
1421: static tme_uint32_t
1422: _tme_keyboard_event_time_diff(tme_uint32_t event_time,
1423: tme_int32_t diff)
1424: {
1425: event_time += (tme_uint32_t) diff;
1426: if (event_time == TME_KEYBOARD_EVENT_TIME_UNDEF) {
1427: assert (diff != 0);
1428: event_time += (diff < 0 ? -1 : 1);
1429: }
1430: return (event_time);
1431: }
1432:
1433: /* this subtracts event_time1 from event_time0, handling the wrapping
1434: of the tme_uint32_t milliseconds values as best as possible: */
1435: static tme_int32_t
1436: _tme_keyboard_event_time_subtract(tme_uint32_t event_time0,
1437: tme_uint32_t event_time1)
1438: {
1439: tme_uint32_t event_time0_less_least;
1440: tme_uint32_t event_time_diff_unwrapped;
1441: tme_uint32_t event_time_diff_wrapped;
1442:
1443: /* if the two times are equal: */
1444: if (event_time0 == event_time1) {
1445: return (0);
1446: }
1447:
1448: /* calculate the unwrapped and wrapped differences between the
1449: two times: */
1450: if (event_time0 < event_time1) {
1451: event_time_diff_unwrapped = event_time1 - event_time0;
1452: event_time_diff_wrapped = 0 - event_time_diff_unwrapped;
1453: }
1454: else {
1455: event_time_diff_unwrapped = event_time0 - event_time1;
1456: event_time_diff_wrapped = 0 - event_time_diff_unwrapped;
1457: }
1458:
1459: /* calculate the event time that is the most in the past without
1460: being confused as being later than event_time0: */
1461: event_time0_less_least
1462: = (event_time0 - (((tme_uint32_t) -1) >> 1));
1463:
1464: /* if event_time0_less_least is literally greater than event_time0,
1465: the event time space that represents "less than event_time0" is
1466: not a single region in the tme_uint32_t space: */
1467: if (event_time0_less_least < event_time0) {
1468: return ((event_time0_less_least <= event_time1
1469: && event_time1 < event_time0)
1470: /* event_time1 is less than event_time0: */
1471: ? event_time_diff_unwrapped
1472: /* event_time1 is greater than event_time0: */
1473: : (event_time1 > event_time0
1474: ? 0 - event_time_diff_unwrapped
1475: : 0 - event_time_diff_wrapped));
1476: }
1477:
1478: /* otherwise, the event time space that represents "less than
1479: event_time0" is two regions in the tme_uint32_t space: */
1480: else {
1481: return ((event_time0_less_least <= event_time1
1482: || event_time1 < event_time0)
1483: /* event_time1 is less than event_time0: */
1484: ? (event_time1 < event_time0
1485: ? event_time_diff_unwrapped
1486: : event_time_diff_wrapped)
1487: /* event_time1 is greater than event_time0: */
1488: : 0 - event_time_diff_unwrapped);
1489: }
1490: }
1491:
1492: /* this runs a keymode stage. this is used for input stage one,
1493: and output stage one. roughly, a keymode stage tries to
1494: guarantee that a key has a specific press/release behavior
1495: (or "mode") for later stages. the particular modes are described
1496: in the case below: */
1497: static int
1498: _tme_keymode_stage(struct tme_keyboard_buffer_int *buffer,
1499: struct tme_keymode_stage *stage,
1500: struct tme_keymode_state *keymode,
1501: int is_press,
1502: tme_uint32_t event_time)
1503: {
1504: struct tme_keymode_state **_auto_keymode, *auto_keymode;
1505: int pressed_old, mode;
1506: int rc;
1507:
1508: /* check all keys on the no-autorepeats list: */
1509: for (_auto_keymode = &stage->tme_keymode_stage_no_autorepeats;
1510: (auto_keymode = *_auto_keymode) != NULL; ) {
1511:
1512: /* if the time of the last release from the earlier stages is
1513: undefined, that means that the last event from the earlier
1514: stages was a press: */
1515: if (auto_keymode->tme_keymode_state_last_release
1516: == TME_KEYBOARD_EVENT_TIME_UNDEF) {
1517:
1518: /* if the key we're checking happens to be the key that the
1519: earlier stages are calling us for: */
1520: if (auto_keymode == keymode) {
1521:
1522: /* this must be a release on this key: */
1523: assert (!is_press);
1524:
1525: /* set the release time on this key: */
1526: auto_keymode->tme_keymode_state_last_release = event_time;
1527:
1528: /* we've taken care of this call: */
1529: keymode = NULL;
1530: }
1531: }
1532:
1533: /* otherwise, the last event from the earlier stages was a release.
1534: if enough time has elapsed since then without a press from
1535: earlier stages: */
1536: else if (_tme_keyboard_event_time_subtract(event_time,
1537: auto_keymode->tme_keymode_state_last_release)
1538: > TME_KEYBOARD_SHORTEST_DOUBLE_MSEC) {
1539:
1540: /* now we're sure that the key has genuinely released.
1541: remove this key from the autorepeats list: */
1542: *_auto_keymode = auto_keymode->tme_keymode_state_next;
1543: auto_keymode->tme_keymode_state_next = NULL;
1544:
1545: /* if we're supposed to ignore the genuine release: */
1546: if (auto_keymode->tme_keymode_state_ignore_release) {
1547: auto_keymode->tme_keymode_state_ignore_release = FALSE;
1548: }
1549:
1550: /* otherwise, we're not supposed to ignore the genuine release: */
1551: else {
1552:
1553: /* flip the pressed state of the key: */
1554: auto_keymode->tme_keymode_state_pressed
1555: = !auto_keymode->tme_keymode_state_pressed;
1556:
1557: /* if this key is now pressed, or if we're allowed to
1558: pass releases, run the next stage: */
1559: mode = auto_keymode->tme_keymode_state_mode;
1560: if (mode == TME_KEYBOARD_MODE_GLOBAL) {
1561: mode = stage->tme_keymode_stage_global_mode;
1562: }
1563: if (auto_keymode->tme_keymode_state_pressed
1564: || !(mode
1565: & TME_KEYBOARD_MODE_FLAG_NO_RELEASES)) {
1566: rc = (*stage->tme_keymode_stage_next)
1567: (buffer,
1568: auto_keymode->tme_keymode_state_keysym,
1569: _tme_keyboard_event_time_diff(event_time, -1));
1570: assert (rc == TME_OK);
1571: }
1572: }
1573:
1574: /* continue now - by removing this key from the autorepeats
1575: list we've already advanced our position in the list for
1576: the next iteration: */
1577: continue;
1578: }
1579:
1580: /* otherwise, if the key we're checking happens to be the key that
1581: the earlier stages are calling us for: */
1582: else if (auto_keymode == keymode) {
1583:
1584: /* this must be a press on this key: */
1585: assert (is_press);
1586:
1587: /* now we're sure that this key is autorepeating. clear
1588: the last-release time: */
1589: auto_keymode->tme_keymode_state_last_release
1590: = TME_KEYBOARD_EVENT_TIME_UNDEF;
1591:
1592: /* we've taken care of this call: */
1593: keymode = NULL;
1594: }
1595:
1596: /* continue: */
1597: _auto_keymode = &auto_keymode->tme_keymode_state_next;
1598: }
1599:
1600: /* return now if we already finished processing this event: */
1601: if (keymode == NULL) {
1602: return (TME_OK);
1603: }
1604:
1605: /* get this key's mode: */
1606: mode = keymode->tme_keymode_state_mode;
1607: if (mode == TME_KEYBOARD_MODE_GLOBAL) {
1608: mode = stage->tme_keymode_stage_global_mode;
1609: }
1610:
1611: /* remember if this key was pressed in this stage before: */
1612: pressed_old = keymode->tme_keymode_state_pressed;
1613:
1614: /* unlock mode unlocks a key by turning every transition into a
1615: press transition and a release transition. think of a Caps Lock
1616: key on an input keyboard that *physically* locks down when you
1617: press it down - this is a nice property, because there's no
1618: mistaking that when you get a key press event, you know the key
1619: is both physically and *semantically* down until you get a key
1620: release, at which time you know just the opposite.
1621:
1622: however, this is a best case. many keyboards have Caps Lock, Num
1623: Lock, and other keys where their semantic pressed/release state
1624: doesn't match their physical pressed/release state. to make
1625: everything uniform, we need to bring the best-case keyboards down
1626: to the worst-case level: */
1627: if (mode == TME_KEYBOARD_MODE_UNLOCK) {
1628:
1629: /* we must not have this key as pressed: */
1630: assert (!pressed_old);
1631:
1632: /* press this key and run the next stage: */
1633: keymode->tme_keymode_state_pressed = TRUE;
1634: rc = (*stage->tme_keymode_stage_next)
1635: (buffer,
1636: keymode->tme_keymode_state_keysym,
1637: _tme_keyboard_event_time_diff(event_time, -1));
1638: assert (rc == TME_OK);
1639:
1640: /* release this key, and make sure the next stage
1641: gets run at the end of this function: */
1642: keymode->tme_keymode_state_pressed = FALSE;
1643: pressed_old = TRUE;
1644: }
1645:
1646: /* lock mode makes the key lock in the physical sense, like the
1647: best-case Caps Lock described above. since our events from
1648: earlier stages are worst-case, we need to ignore autorepeats, and
1649: each press/release pair must toggle our notion of whether or not
1650: the key is physically pressed: */
1651: else if (mode == TME_KEYBOARD_MODE_LOCK) {
1652:
1653: /* this must be a press: */
1654: assert (is_press);
1655:
1656: /* put this key on the no-autorepeats list: */
1657: keymode->tme_keymode_state_last_release
1658: = TME_KEYBOARD_EVENT_TIME_UNDEF;
1659: keymode->tme_keymode_state_next
1660: = stage->tme_keymode_stage_no_autorepeats;
1661: stage->tme_keymode_stage_no_autorepeats = keymode;
1662:
1663: /* if we have the key as pressed (locked): */
1664: if (pressed_old) {
1665:
1666: /* don't ignore the genuine release, when it is determined to
1667: have happened. if this mode has
1668: TME_KEYBOARD_MODE_FLAG_NO_RELEASES set, the genuine release
1669: code will handle it then: */
1670: keymode->tme_keymode_state_ignore_release = FALSE;
1671: }
1672:
1673: /* otherwise, we have the key as released (unlocked): */
1674: else {
1675:
1676: /* press this key: */
1677: keymode->tme_keymode_state_pressed = TRUE;
1678:
1679: /* ignore the genuine release, when it is determined
1680: to have happened: */
1681: keymode->tme_keymode_state_ignore_release = TRUE;
1682: }
1683: }
1684:
1685: /* passthrough mode generally passes events through: */
1686: else {
1687:
1688: assert (!pressed_old != !is_press);
1689:
1690: /* if this is a press: */
1691: if (is_press) {
1692:
1693: /* press this key: */
1694: keymode->tme_keymode_state_pressed = TRUE;
1695:
1696: /* if we must not pass through autorepeats: */
1697: if (mode & TME_KEYBOARD_MODE_FLAG_NO_AUTOREPEATS) {
1698:
1699: /* put this key on the no-autorepeats list: */
1700: keymode->tme_keymode_state_last_release
1701: = TME_KEYBOARD_EVENT_TIME_UNDEF;
1702: keymode->tme_keymode_state_next
1703: = stage->tme_keymode_stage_no_autorepeats;
1704: stage->tme_keymode_stage_no_autorepeats = keymode;
1705:
1706: /* don't ignore the genuine release, when it is
1707: determined to have happened. if this mode has
1708: TME_KEYBOARD_MODE_FLAG_NO_RELEASES set, the
1709: genuine release code will handle it then: */
1710: keymode->tme_keymode_state_ignore_release = FALSE;
1711: }
1712: }
1713:
1714: /* otherwise, this is a release: */
1715: else {
1716:
1717: /* release this key: */
1718: keymode->tme_keymode_state_pressed = FALSE;
1719:
1720: /* if this mode has TME_KEYBOARD_MODE_FLAG_NO_RELEASES set,
1721: we'll handle it below when we go to run the next stage: */
1722: }
1723: }
1724:
1725: /* stop processing this event now if the key's pressed state
1726: in this stage has not changed, or if the key is now released
1727: and we're not allowed to pass releases. otherwise, run the
1728: next stage: */
1729: return ((keymode->tme_keymode_state_pressed
1730: ? pressed_old
1731: : (!pressed_old
1732: || (mode
1733: & TME_KEYBOARD_MODE_FLAG_NO_RELEASES)))
1734: ? TME_OK
1735: : ((*stage->tme_keymode_stage_next)
1736: (buffer,
1737: keymode->tme_keymode_state_keysym,
1738: event_time)));
1739: }
1740:
1741: /* this is the bottom half of output stage one. this half does
1742: nothing except finally buffer an event for a keycode, and update
1743: the output modifiers mask: */
1744: static int
1745: _tme_keyboard_buffer_out1_bottom(struct tme_keyboard_buffer_int *buffer,
1746: struct tme_keysym_state *keysym,
1747: tme_uint32_t event_time)
1748: {
1749: struct tme_keycode_state *keycode;
1750: struct tme_keyboard_event event_buffer;
1751: int modifier;
1752: int is_press;
1753:
1754: /* get the keycode: */
1755: keycode = keysym->tme_keysym_state_out0_keycode;
1756:
1757: /* get whether or not this is a press: */
1758: is_press = TME_KEYBOARD_PRESSED_OUT1(keycode);
1759:
1760: _tme_keyboard_debug(buffer,
1761: "out1-bottom",
1762: keysym->tme_keysym_state_keysym,
1763: is_press,
1764: event_time);
1765:
1766: /* if this keysym is attached to a modifier, update the output
1767: modifiers mask: */
1768: /* XXX there might be a cleaner way to work the output modifier
1769: mask. it's suspicious that stages zero and one need to share the
1770: modifiers mask and the keysym to modifier mapping: */
1771: modifier = keysym->tme_keysym_state_out0_modifier;
1772: if (modifier != TME_KEYBOARD_MODIFIER_NONE) {
1773:
1774: /* if this is a press: */
1775: if (is_press) {
1776:
1777: /* if the modifier is currently clear: */
1778: if (!(buffer->tme_keyboard_buffer_int_out0_modifiers
1779: & (1 << modifier))) {
1780:
1781: /* set the modifier: */
1782: buffer->tme_keyboard_buffer_int_out0_modifiers
1783: |= (1 << modifier);
1784:
1785: /* iff this keysym soft-locks, the next release will not
1786: affect the output modifiers mask: */
1787: keysym->tme_keysym_state_out1_ignore_release
1788: = (keycode->tme_keycode_state_keymode.tme_keymode_state_mode
1789: & TME_KEYBOARD_MODE_FLAG_LOCK_SOFT);
1790: }
1791:
1792: /* otherwise, the modifier is currently set: */
1793: else {
1794:
1795: /* nothing to do. even if this keysym soft-locks, we won't
1796: clear the modifier until the release: */
1797: }
1798: }
1799:
1800: /* otherwise, this is a release: */
1801: else {
1802:
1803: /* if we're supposed to ignore this release: */
1804: if (keysym->tme_keysym_state_out1_ignore_release) {
1805: keysym->tme_keysym_state_out1_ignore_release = FALSE;
1806: }
1807:
1808: /* otherwise, if the modifier is currently set: */
1809: else if (buffer->tme_keyboard_buffer_int_out0_modifiers
1810: & (1 << modifier)) {
1811:
1812: /* clear the modifier: */
1813: buffer->tme_keyboard_buffer_int_out0_modifiers
1814: &= ~(1 << modifier);
1815: }
1816:
1817: /* otherwise, the modifier is currently clear: */
1818: else {
1819:
1820: /* nothing to do. a release would never set a modifier: */
1821: }
1822: }
1823: }
1824:
1825: /* finally buffer this keycode: */
1826: event_buffer.tme_keyboard_event_type
1827: = (is_press
1828: ? TME_KEYBOARD_EVENT_PRESS
1829: : TME_KEYBOARD_EVENT_RELEASE);
1830: event_buffer.tme_keyboard_event_keyval
1831: = keycode->tme_keycode_state_keycode;
1832: event_buffer.tme_keyboard_event_time
1833: = event_time;
1834: event_buffer.tme_keyboard_event_modifiers
1835: = buffer->tme_keyboard_buffer_int_out0_modifiers;
1836: return (_tme_keyboard_buffer_copyin(buffer, &event_buffer));
1837: }
1838:
1839: /* this is the top half of output stage one. it is the last output
1840: stage, that gives each keycode the specific behavior that it must
1841: have on the output keyboard: */
1842: static int
1843: _tme_keyboard_buffer_out1(struct tme_keyboard_buffer_int *buffer,
1844: struct tme_keysym_state *keysym,
1845: tme_uint32_t event_time)
1846: {
1847: struct tme_keycode_state *keycode;
1848:
1849: _tme_keyboard_debug(buffer,
1850: "out1-top",
1851: keysym->tme_keysym_state_keysym,
1852: TME_KEYBOARD_PRESSED_OUT0(keysym),
1853: event_time);
1854:
1855: /* get the keycode state: */
1856: keycode = keysym->tme_keysym_state_out0_keycode;
1857:
1858: /* run the keymode stage function: */
1859: return (_tme_keymode_stage(buffer,
1860: &buffer->tme_keyboard_buffer_int_out1_keymode_stage,
1861: &keycode->tme_keycode_state_keymode,
1862: TME_KEYBOARD_PRESSED_OUT0(keysym),
1863: event_time));
1864: }
1865:
1866: /* this is output stage zero. at this point, we have the final
1867: keysyms from the input keyboard, and this stage maps those keysyms
1868: to keycodes on the output keyboard.
1869:
1870: sometimes, the input keyboard may generate keysyms for which the
1871: output keyboard requires that certain modifiers be set or clear, at
1872: a time when the output modifiers mask isn't suitable. for example,
1873: this can happen when the input keyboard can generate a certain
1874: keysym without shifting, when the output keyboard requires
1875: shifting.
1876:
1877: when this happens, this stage is responsible for simulating presses
1878: or releases of modifiers on the output keyboard as needed to make
1879: sure that the keysym is properly obtained when the mapped keycode
1880: is pressed, and for undoing those changes when the mapped keycode
1881: is released: */
1882: static int
1883: _tme_keyboard_buffer_out0(struct tme_keyboard_buffer_int *buffer,
1884: struct tme_keysym_state *keysym,
1885: tme_uint32_t event_time)
1886: {
1887: struct tme_keyboard_event event_buffer;
1888: tme_keyboard_modifiers_t modifiers, modifiers_set, modifiers_clear;
1889: int num_lock_on;
1890: int is_press, mod_pressed_old, modifier;
1891: struct tme_keysym_state *mod_keysym, **keysyms;
1892: unsigned int *press_flags;
1893: int keysym_count;
1894: int modifier_stuck;
1895: int rc;
1896:
1897: _tme_keyboard_debug(buffer,
1898: "out0",
1899: keysym->tme_keysym_state_keysym,
1900: TME_KEYBOARD_PRESSED_IN2(keysym),
1901: event_time);
1902:
1903: /* get whether or not this is a press from earlier stages: */
1904: is_press = TME_KEYBOARD_PRESSED_IN2(keysym);
1905:
1906: /* if output stage zero is a passthrough, just buffer an event for
1907: the keysym and we're done processing this event: */
1908: if (buffer->tme_keyboard_buffer_int_out0_passthrough) {
1909:
1910: /* otherwise, simply buffer this event: */
1911: event_buffer.tme_keyboard_event_type
1912: = (is_press
1913: ? TME_KEYBOARD_EVENT_PRESS
1914: : TME_KEYBOARD_EVENT_RELEASE);
1915: event_buffer.tme_keyboard_event_keyval
1916: = keysym->tme_keysym_state_keysym;
1917: event_buffer.tme_keyboard_event_time
1918: = event_time;
1919: event_buffer.tme_keyboard_event_modifiers
1920: = 0;
1921: return (_tme_keyboard_buffer_copyin(buffer, &event_buffer));
1922: }
1923:
1924: /* if this keysym is not mapped to a keycode on the output keyboard,
1925: we don't have to process this event any more: */
1926: if (keysym->tme_keysym_state_out0_keycode == NULL) {
1927: return (TME_OK);
1928: }
1929:
1930: /* if this is a press from earlier stages: */
1931: if (is_press) {
1932:
1933: /* this keysym can't have any changes attached to it already: */
1934: assert (keysym->tme_keysym_state_out0_keysyms == NULL);
1935: keysyms = NULL;
1936: press_flags = NULL;
1937: keysym_count = 0;
1938:
1939: /* get the current output stage zero modifiers: */
1940: modifiers = buffer->tme_keyboard_buffer_int_out0_modifiers;
1941:
1942: /* get the sets of modifiers that must be clear and set for this
1943: keysym: */
1944: modifiers_clear = keysym->tme_keysym_state_out0_modifiers_clear;
1945: modifiers_set = keysym->tme_keysym_state_out0_modifiers_set;
1946: assert ((modifiers_clear & modifiers_set) == 0);
1947: assert ((modifiers_clear | modifiers_set) == 0
1948: || (keysym->tme_keysym_state_out0_modifier
1949: == TME_KEYBOARD_MODIFIER_NONE));
1950:
1951: /* if this keysym is uppercase, but the current modifiers are such
1952: that a lowercase keysym *might* be generated: */
1953: if ((modifiers_set & (1 << TME_KEYBOARD_MODIFIER_LOCK))
1954: && !(modifiers & (1 << TME_KEYBOARD_MODIFIER_LOCK))) {
1955:
1956: /* if shift is down, we must be generating uppercase keysyms, so
1957: forget about the lock modifier in this instance: */
1958: if (modifiers & (1 << TME_KEYBOARD_MODIFIER_SHIFT)) {
1959: modifiers_set &= ~(1 << TME_KEYBOARD_MODIFIER_LOCK);
1960: }
1961:
1962: /* otherwise, neither shift nor lock are down, so we are
1963: generating lowercase keysyms. since this keyboard might not
1964: have a lock modifier at all (and since it seems more
1965: reasonable to do it this way anyways), require the shift
1966: modifier to be set instead of the lock modifier in this
1967: instance: */
1968: else {
1969: modifiers_set &= ~(1 << TME_KEYBOARD_MODIFIER_LOCK);
1970: modifiers_set |= (1 << TME_KEYBOARD_MODIFIER_SHIFT);
1971: }
1972: }
1973:
1974: /* if this output keyboard has a Num_Lock key, and this keysym is
1975: sensitive to the Num_Lock setting, but the appropriate Num_Lock
1976: setting is already in effect, forget about Num_Lock for this
1977: instance: */
1978: modifier = buffer->tme_keyboard_buffer_int_out0_mod_num_lock;
1979: if (modifier != TME_KEYBOARD_MODIFIER_NONE
1980: && ((modifiers_clear
1981: | modifiers_set)
1982: & (1 << modifier))) {
1983:
1984: /* determine what Num_Lock setting is currently in effect. it
1985: is active if Num_Lock is pressed and there is no shifting
1986: active, or if Num_Lock is released and there is shifting
1987: active. NB that if the lock modifier is attached only to a
1988: Shift_Lock, that modifier also counts as shifting: */
1989: num_lock_on
1990: = (
1991:
1992: /* this term is 0 iff Num_Lock is pressed, else 1: */
1993: !(modifiers
1994: & (1 << modifier))
1995:
1996: !=
1997:
1998: /* this term is 0 iff shifting is active, else 1: */
1999: !(modifiers
2000: & ((1 << TME_KEYBOARD_MODIFIER_SHIFT)
2001: | (buffer->tme_keyboard_buffer_int_out0_lock_is_caps
2002: ? 0
2003: : (1 << TME_KEYBOARD_MODIFIER_LOCK)))));
2004:
2005: /* if this keysym requires Num_Lock to be clear, but it is
2006: not in effect, forget about Num_Lock for this instance: */
2007: if ((modifiers_clear & (1 << modifier))
2008: && !num_lock_on) {
2009: modifiers_clear &= ~(1 << modifier);
2010: }
2011:
2012: /* if this keysym requires Num_Lock to be set, but it is
2013: in effect, forget about Num_Lock for this instance: */
2014: if ((modifiers_set & (1 << modifier))
2015: && num_lock_on) {
2016: modifiers_set &= ~(1 << modifier);
2017: }
2018: }
2019:
2020: /* finish the set of modifiers that must be clear and set for this
2021: keysym, but aren't: */
2022: modifiers_clear &= modifiers;
2023: modifiers_set &= ~modifiers;
2024:
2025: /* try to generate release events for all keysyms attached to
2026: output modifiers that are set, but that need to be clear: */
2027: if (modifiers_clear != 0) {
2028:
2029: /* loop over the modifiers that need clearing: */
2030: for (modifier = 0;
2031: modifier <= TME_KEYBOARD_MODIFIER_MAX;
2032: modifier++) {
2033: if (!(modifiers_clear & (1 << modifier))) {
2034: continue;
2035: }
2036:
2037: /* try to release all of the keysyms attached to this modifier
2038: that are pressed: */
2039: modifier_stuck = FALSE;
2040: for (mod_keysym = buffer->tme_keyboard_buffer_int_out0_modkeys[modifier];
2041: mod_keysym != NULL;
2042: mod_keysym = mod_keysym->tme_keysym_state_out0_modifier_next) {
2043:
2044: /* XXX this is broken for modifiers that soft-lock. */
2045:
2046: /* ignore this keysym if it isn't pressed: */
2047: if (!TME_KEYBOARD_PRESSED_OUT0(mod_keysym)) {
2048: continue;
2049: }
2050:
2051: /* grow the keysyms and press flags arrays. the keysyms
2052: array always has one extra entry, which will be filled
2053: with NULL to terminate the array: */
2054: if (keysym_count == 0) {
2055: keysyms = tme_new(struct tme_keysym_state *, 2);
2056: press_flags = tme_new(unsigned int, 1);
2057: }
2058: else {
2059: keysyms = tme_renew(struct tme_keysym_state *, keysyms, keysym_count + 2);
2060: press_flags = tme_renew(unsigned int, press_flags, keysym_count + 1);
2061: }
2062:
2063: /* add this keysym to those arrays: */
2064: keysyms[keysym_count] = mod_keysym;
2065: press_flags[keysym_count] = FALSE;
2066: keysym_count++;
2067:
2068: /* release this modifier key. if this actually
2069: releases the key, run the next stage: */
2070: mod_keysym->tme_keysym_state_out0_released++;
2071: if (!TME_KEYBOARD_PRESSED_OUT0(mod_keysym)) {
2072: rc = _tme_keyboard_buffer_out1(buffer,
2073: mod_keysym,
2074: _tme_keyboard_event_time_diff(event_time, -1));
2075: assert (rc == TME_OK);
2076: }
2077:
2078: /* otherwise, this modifier is stuck on: */
2079: else {
2080: modifier_stuck = TRUE;
2081: }
2082: }
2083:
2084: /* if we were able to release all keysyms attached to this
2085: modifier, clear the modifier in the output keyboard mask: */
2086: if (!modifier_stuck) {
2087: buffer->tme_keyboard_buffer_int_out0_modifiers
2088: &= ~(1 << modifier);
2089: }
2090: }
2091: }
2092:
2093: /* try to generate press events for single keysyms attached to
2094: output modifiers that are clear, but that need to be set: */
2095: if (modifiers_set != 0) {
2096:
2097: /* loop over the modifiers that need setting: */
2098: for (modifier = 0;
2099: modifier <= TME_KEYBOARD_MODIFIER_MAX;
2100: modifier++) {
2101: if (!(modifiers_set & (1 << modifier))) {
2102: continue;
2103: }
2104:
2105: /* try to press a single keysym attached to this modifier: */
2106: mod_keysym = buffer->tme_keyboard_buffer_int_out0_modkeys[modifier];
2107: assert (mod_keysym != NULL);
2108:
2109: /* this keysym can't pressed - if it is, the modifier
2110: should be set: */
2111: assert (!TME_KEYBOARD_PRESSED_OUT0(mod_keysym));
2112:
2113: /* grow the keysyms and press flags arrays. the keysyms
2114: array always has one extra entry, which will be filled
2115: with NULL to terminate the array: */
2116: if (keysym_count == 0) {
2117: keysyms = tme_new(struct tme_keysym_state *, 2);
2118: press_flags = tme_new(unsigned int, 1);
2119: }
2120: else {
2121: keysyms = tme_renew(struct tme_keysym_state *, keysyms, keysym_count + 2);
2122: press_flags = tme_renew(unsigned int, press_flags, keysym_count + 1);
2123: }
2124:
2125: /* add this keysym to those arrays: */
2126: keysyms[keysym_count] = mod_keysym;
2127: press_flags[keysym_count] = TRUE;
2128: keysym_count++;
2129:
2130: /* press this modifier key. this must actually press the key,
2131: so run the next stage: */
2132: mod_keysym->tme_keysym_state_out0_pressed++;
2133: assert (TME_KEYBOARD_PRESSED_OUT0(mod_keysym));
2134: rc = _tme_keyboard_buffer_out1(buffer,
2135: mod_keysym,
2136: _tme_keyboard_event_time_diff(event_time, -1));
2137: assert (rc == TME_OK);
2138:
2139: /* set the modifier: */
2140: buffer->tme_keyboard_buffer_int_out0_modifiers
2141: |= (1 << modifier);
2142: }
2143: }
2144:
2145: /* remember any changes we made: */
2146: if (keysyms != NULL) {
2147: keysyms[keysym_count] = NULL;
2148: }
2149: keysym->tme_keysym_state_out0_keysyms = keysyms;
2150: keysym->tme_keysym_state_out0_press_flags = press_flags;
2151:
2152: /* run the next stage: */
2153: return (_tme_keyboard_buffer_out1(buffer,
2154: keysym,
2155: event_time));
2156: }
2157:
2158: /* otherwise, this is a release: */
2159: else {
2160:
2161: /* run the next stage: */
2162: rc = _tme_keyboard_buffer_out1(buffer,
2163: keysym,
2164: event_time);
2165: assert (rc == TME_OK);
2166:
2167: /* if this keysym tried to make any modifier changes, undo them: */
2168: keysyms = keysym->tme_keysym_state_out0_keysyms;
2169: press_flags = keysym->tme_keysym_state_out0_press_flags;
2170: if (keysyms != NULL) {
2171:
2172: /* loop over all of the modifiers we changed: */
2173: for (; (mod_keysym = *(keysyms++)) != NULL; ) {
2174:
2175: /* see if this modifier is pressed now: */
2176: mod_pressed_old = TME_KEYBOARD_PRESSED_OUT0(mod_keysym);
2177:
2178: /* undo the change we made to this modifier: */
2179: if (*(press_flags++)) {
2180: mod_keysym->tme_keysym_state_out0_pressed--;
2181: }
2182: else {
2183: mod_keysym->tme_keysym_state_out0_released--;
2184: }
2185:
2186: /* if the state of this modifier has changed, run the next
2187: stage: */
2188: if (TME_KEYBOARD_PRESSED_OUT0(mod_keysym) != mod_pressed_old) {
2189: rc = _tme_keyboard_buffer_out1(buffer,
2190: mod_keysym,
2191: _tme_keyboard_event_time_diff(event_time, +1));
2192: assert (rc == TME_OK);
2193: }
2194: }
2195:
2196: /* forget these modifier changes: */
2197: tme_free(keysym->tme_keysym_state_out0_keysyms);
2198: tme_free(keysym->tme_keysym_state_out0_press_flags);
2199: keysym->tme_keysym_state_out0_keysyms = NULL;
2200: keysym->tme_keysym_state_out0_press_flags = NULL;
2201: }
2202: }
2203:
2204: /* success: */
2205: return (TME_OK);
2206: }
2207:
2208: /* this is input stage two. at this point, we have the input keyboard
2209: cleaned up to the point where we can have macros for generating
2210: keysyms that the input keyboard can't generate on its own: */
2211: static int
2212: _tme_keyboard_buffer_in2(struct tme_keyboard_buffer_int *buffer,
2213: struct tme_keysym_state *keysym,
2214: tme_uint32_t event_time)
2215: {
2216: tme_keyboard_keyval_t _keysym;
2217: struct tme_keyboard_macro **_macro, *macro, *child, *parent;
2218: int is_press, pressed_old, sub_pressed_old;
2219: int update, keysym_i;
2220: struct tme_keysym_state *sub_keysym;
2221: int rc;
2222:
2223: _tme_keyboard_debug(buffer,
2224: "in2",
2225: keysym->tme_keysym_state_keysym,
2226: TME_KEYBOARD_PRESSED_IN1(keysym),
2227: event_time);
2228:
2229: /* get the keysym: */
2230: _keysym = keysym->tme_keysym_state_keysym;
2231:
2232: /* get whether or not this is a press from earlier stages: */
2233: is_press = TME_KEYBOARD_PRESSED_IN1(keysym);
2234:
2235: /* remember if this keysym was pressed in this stage before: */
2236: pressed_old = _TME_KEYBOARD_PRESSED_IN2(keysym, !is_press);
2237:
2238: /* visit all active macros tree nodes: */
2239: for (_macro = &buffer->tme_keyboard_buffer_int_in2_macros_active;
2240: (macro = *_macro) != NULL; ) {
2241:
2242: /* if this is a press, see if it advances this macro's sequence: */
2243: if (is_press) {
2244:
2245: /* ignore this macros tree node if it's a leaf, or if this
2246: keysym is not a branch out of this node to some child node: */
2247: if (macro->tme_keyboard_macro_branches == NULL
2248: || (child
2249: = ((struct tme_keyboard_macro *)
2250: tme_hash_lookup(macro->tme_keyboard_macro_branches,
2251: (tme_hash_data_t) _keysym))) == NULL) {
2252: _macro = ¯o->tme_keyboard_macro_active_next;
2253: continue;
2254: }
2255:
2256: /* the child node cannot already be active. if it is, that
2257: means that earlier stages didn't give us a release for this
2258: keysym: */
2259: assert (child->tme_keyboard_macro_active_next == NULL);
2260:
2261: /* make the child node active: */
2262: child->tme_keyboard_macro_active_next = macro;
2263: *_macro = child;
2264: _macro = ¯o->tme_keyboard_macro_active_next;
2265: macro = child;
2266: }
2267:
2268: /* otherwise, this is a release, so see if this release cancels
2269: any sequence: */
2270: else {
2271:
2272: /* ignore this macros tree node if this is not a release of a
2273: keysym somewhere on the path from the root to this node: */
2274: if (_keysym != macro->tme_keyboard_macro_keysym) {
2275: for (parent = macro->tme_keyboard_macro_parent;
2276: parent != NULL;
2277: parent = parent->tme_keyboard_macro_parent) {
2278: if (_keysym == parent->tme_keyboard_macro_keysym) {
2279: break;
2280: }
2281: }
2282: if (parent == NULL) {
2283: _macro = ¯o->tme_keyboard_macro_active_next;
2284: continue;
2285: }
2286: }
2287:
2288: /* make this macros tree node no longer active: */
2289: *_macro = macro->tme_keyboard_macro_active_next;
2290: macro->tme_keyboard_macro_active_next = NULL;
2291: }
2292:
2293: /* if this macro is not a leaf node, continue: */
2294: if (macro->tme_keyboard_macro_branches != NULL) {
2295: continue;
2296: }
2297:
2298: /* otherwise, this event has either activated or deactivated a
2299: macro. either do or undo this macro's presses and releases: */
2300: update = (is_press ? 1 : -1);
2301: for (keysym_i = macro->tme_keyboard_macro_length;
2302: keysym_i-- > 0; ) {
2303:
2304: /* get this keysym's state: */
2305: sub_keysym = macro->tme_keyboard_macro_keysyms[keysym_i];
2306:
2307: /* remember if this keysym was pressed in this stage before: */
2308: sub_pressed_old = TME_KEYBOARD_PRESSED_IN2(sub_keysym);
2309:
2310: /* update this keysym's state: */
2311: if (macro->tme_keyboard_macro_press_flags[keysym_i]) {
2312: sub_keysym->tme_keysym_state_in2_pressed += update;
2313: }
2314: else {
2315: sub_keysym->tme_keysym_state_in2_released += update;
2316: }
2317:
2318: /* if this keysym's pressed state in this stage has changed,
2319: run the next stage, unless this is the keysym that we
2320: were called with, in which case we'll handle this later: */
2321: if (sub_keysym != keysym
2322: && TME_KEYBOARD_PRESSED_IN2(sub_keysym) != sub_pressed_old) {
2323: rc = _tme_keyboard_buffer_out0(buffer, sub_keysym, event_time);
2324: assert (rc == TME_OK);
2325: }
2326: }
2327: }
2328:
2329: /* if this keysym's pressed state in this stage has changed, run
2330: the next stage, otherwise stop processing this event now: */
2331: return ((TME_KEYBOARD_PRESSED_IN2(keysym) != pressed_old)
2332: ? _tme_keyboard_buffer_out0(buffer, keysym, event_time)
2333: : TME_OK);
2334: }
2335:
2336: /* this is input stage one. at this point, the input keyboard is
2337: slightly cleaned up - consecutive presses have had a release
2338: inserted in between, releases of unpressed keys have been dropped,
2339: and as many inferred lost events as possible have been generated.
2340:
2341: this stage finishes cleaning up the input keyboard to the point
2342: where macros are useful. usually, the only keysyms that will have
2343: specific behaviors enforced here will be keysyms that are used like
2344: modifiers in input stage two macros, but that don't behave like
2345: modifiers on the input keyboard (i.e., they autorepeat) and so
2346: aren't good for use in multiple-key macros: */
2347: static int
2348: _tme_keyboard_buffer_in1(struct tme_keyboard_buffer_int *buffer,
2349: struct tme_keysym_state *keysym,
2350: tme_uint32_t event_time)
2351: {
2352:
2353: _tme_keyboard_debug(buffer,
2354: "in1",
2355: keysym->tme_keysym_state_keysym,
2356: TME_KEYBOARD_PRESSED_IN0(keysym),
2357: event_time);
2358:
2359: /* run the keymode stage function: */
2360: return (_tme_keymode_stage(buffer,
2361: &buffer->tme_keyboard_buffer_int_in1_keymode_stage,
2362: &keysym->tme_keysym_state_in1_keymode,
2363: TME_KEYBOARD_PRESSED_IN0(keysym),
2364: event_time));
2365: }
2366:
2367: /* this is the bottom half of input stage zero. at this point, events
2368: inferred by modifier changes have been generated, but otherwise the
2369: input keyboard hasn't been cleaned up.
2370:
2371: this half drops releases of keys that we don't think are pressed,
2372: generates a release in between two consecutive presses, and tracks
2373: the input modifier mask: */
2374: static int
2375: _tme_keyboard_buffer_in0_bottom(struct tme_keyboard_buffer_int *buffer,
2376: struct tme_keysym_state *keysym,
2377: const struct tme_keyboard_event *event)
2378: {
2379: struct tme_keysym_state *mod_keysym;
2380: struct tme_keyboard_event event_pseudo;
2381: int modifier, pressed_old;
2382: int rc;
2383:
2384: _tme_keyboard_debug(buffer,
2385: "in0-bottom",
2386: keysym->tme_keysym_state_keysym,
2387: (event->tme_keyboard_event_type
2388: & TME_KEYBOARD_EVENT_IN0_PRESS_USER),
2389: event->tme_keyboard_event_time);
2390:
2391: /* NB: event->tme_keyboard_event_modifiers is always the modifiers
2392: *mask from immediately before* the event, i.e., if this event is
2393: *for a modifier keysym, it does not reflect any change the press
2394: *or release of this keysym will cause: */
2395:
2396: /* remember if this keysym was pressed in this stage before: */
2397: pressed_old = TME_KEYBOARD_PRESSED_IN0(keysym);
2398:
2399: /* see if this keysym is attached to any known modifier: */
2400: modifier = (buffer->tme_keyboard_buffer_int_in0_have_modifiers
2401: ? keysym->tme_keysym_state_in0_modifier
2402: : TME_KEYBOARD_MODIFIER_NONE);
2403:
2404: /* dispatch on the event type: */
2405: switch (event->tme_keyboard_event_type) {
2406:
2407: /* an automatic input stage zero press: */
2408: case TME_KEYBOARD_EVENT_IN0_PRESS_AUTO:
2409: /* this keysym must not be pressed at all: */
2410: assert (!pressed_old);
2411: /* FALLTHROUGH */
2412:
2413: /* a user input stage zero press: */
2414: case TME_KEYBOARD_EVENT_IN0_PRESS_USER:
2415:
2416: /* if this keysym was already pressed, inject a release first -
2417: you can't press a key twice without releasing it in between: */
2418: if (pressed_old) {
2419:
2420: /* make the pseudoevent. assume that the release we dropped
2421: happened as soon as humanly possible after the press, but
2422: never after this new press: */
2423: event_pseudo.tme_keyboard_event_type
2424: = TME_KEYBOARD_IN0_RELEASE_EVENT(keysym->tme_keysym_state_in0_pressed);
2425: event_pseudo.tme_keyboard_event_time
2426: = _tme_keyboard_event_time_diff(keysym->tme_keysym_state_in0_press_time,
2427: TME_KEYBOARD_SHORTEST_DOUBLE_MSEC);
2428: if (_tme_keyboard_event_time_subtract(event_pseudo.tme_keyboard_event_time,
2429: event->tme_keyboard_event_time) <= 0) {
2430: event_pseudo.tme_keyboard_event_time
2431: = _tme_keyboard_event_time_diff(event->tme_keyboard_event_time, -1);
2432: }
2433: event_pseudo.tme_keyboard_event_modifiers
2434: = buffer->tme_keyboard_buffer_int_in0_modifiers;
2435:
2436: /* recurse with this pseudoevent: */
2437: rc = _tme_keyboard_buffer_in0_bottom(buffer,
2438: keysym,
2439: &event_pseudo);
2440: assert (rc == TME_OK);
2441: }
2442:
2443: /* this keysym is now pressed: */
2444: keysym->tme_keysym_state_in0_pressed = event->tme_keyboard_event_type;
2445: keysym->tme_keysym_state_in0_press_time = event->tme_keyboard_event_time;
2446:
2447: /* set any modifier in the mask: */
2448: assert (buffer->tme_keyboard_buffer_int_in0_modifiers
2449: == event->tme_keyboard_event_modifiers);
2450: if (modifier != TME_KEYBOARD_MODIFIER_NONE) {
2451: buffer->tme_keyboard_buffer_int_in0_modifiers |= (1 << modifier);
2452: }
2453: break;
2454:
2455: /* an automatic input stage zero release :*/
2456: case TME_KEYBOARD_EVENT_IN0_RELEASE_AUTO:
2457: assert (pressed_old == TME_KEYBOARD_EVENT_IN0_PRESS_AUTO);
2458: /* FALLTHROUGH */
2459:
2460: /* a user input stage zero release: */
2461: case TME_KEYBOARD_EVENT_IN0_RELEASE_USER:
2462:
2463: /* if this keysym wasn't already pressed, stop processing this
2464: event: */
2465: if (!pressed_old) {
2466: return (TME_OK);
2467: }
2468:
2469: /* this keysym is no longer pressed: */
2470: keysym->tme_keysym_state_in0_pressed = FALSE;
2471:
2472: /* if this keysym is attached to a modifier: */
2473: if (modifier != TME_KEYBOARD_MODIFIER_NONE) {
2474:
2475: /* if we can find no keysym attached to this modifier that is
2476: still pressed, clear the modifier in the mask: */
2477: for (mod_keysym = buffer->tme_keyboard_buffer_int_in0_modkeys[modifier];
2478: mod_keysym != NULL;
2479: mod_keysym = mod_keysym->tme_keysym_state_in0_modifier_next) {
2480: if (mod_keysym->tme_keysym_state_in0_pressed) {
2481: break;
2482: }
2483: }
2484: if (mod_keysym == NULL) {
2485: buffer->tme_keyboard_buffer_int_in0_modifiers &= ~(1 << modifier);
2486: }
2487: }
2488: break;
2489:
2490: default:
2491: abort();
2492: }
2493:
2494: /* run the next stage: */
2495: return (_tme_keyboard_buffer_in1(buffer,
2496: keysym,
2497: event->tme_keyboard_event_time));
2498: }
2499:
2500: /* this is the top half of input stage zero. this gets raw
2501: events from the input keyboard. if we get a modifiers mask with
2502: each event, and we know which input keyboard keysyms are attached
2503: to which modifiers, we can often infer presses and releases of
2504: these keysyms when our caller has missed those events.
2505:
2506: For example, this works well under X11 when the Caps_Lock or
2507: Num_Lock key "locks" and its state changes while our window doesn't
2508: have focus. When we do regain focus, we don't get press or release
2509: events for those changes, but we can get the current modifiers
2510: mask: */
2511: static int
2512: _tme_keyboard_buffer_in0(struct tme_keyboard_buffer_int *buffer,
2513: const struct tme_keyboard_event *event)
2514: {
2515: struct tme_keysym_state *keysym, *mod_keysym, *other_keysym;
2516: struct tme_keyboard_event event_pseudo;
2517: int modifier;
2518: tme_keyboard_modifiers_t modifiers, modifiers_set, modifiers_clear;
2519: int rc;
2520:
2521: _tme_keyboard_debug(buffer,
2522: "in0-top",
2523: event->tme_keyboard_event_keyval,
2524: (event->tme_keyboard_event_type
2525: == TME_KEYBOARD_EVENT_PRESS),
2526: event->tme_keyboard_event_time);
2527:
2528: assert (event->tme_keyboard_event_time
2529: != TME_KEYBOARD_EVENT_TIME_UNDEF);
2530:
2531: /* look up this keysym: */
2532: keysym
2533: = ((struct tme_keysym_state *)
2534: tme_hash_lookup(buffer->tme_keyboard_buffer_int_keysyms_state,
2535: (tme_hash_data_t) event->tme_keyboard_event_keyval));
2536:
2537:
2538: /* if input stage zero has modifier information: */
2539: if (buffer->tme_keyboard_buffer_int_in0_have_modifiers) {
2540:
2541: /* NB: event->tme_keyboard_event_modifiers is always the modifiers
2542: mask from immediately *before* the event, i.e., if this event
2543: is for a modifier keysym, it does not reflect any change this
2544: press or release of this keysym will cause to that mask: */
2545: modifiers = event->tme_keyboard_event_modifiers;
2546:
2547: /* get the mask of modifiers that been cleared and set unbeknownst
2548: to us before this event: */
2549: modifiers_clear =
2550: (buffer->tme_keyboard_buffer_int_in0_modifiers
2551: & ~modifiers
2552: & buffer->tme_keyboard_buffer_int_in0_have_modifiers);
2553: modifiers_set =
2554: (modifiers
2555: & ~buffer->tme_keyboard_buffer_int_in0_modifiers
2556: & buffer->tme_keyboard_buffer_int_in0_have_modifiers);
2557:
2558: /* generate the appropriate release events for all keysyms
2559: attached to modifiers that have been cleared: */
2560: if (modifiers_clear != 0) {
2561:
2562: /* loop over the modifiers that need clearing: */
2563: for (modifier = 0;
2564: modifier <= TME_KEYBOARD_MODIFIER_MAX;
2565: modifier++) {
2566: if (!(modifiers_clear & (1 << modifier))) {
2567: continue;
2568: }
2569:
2570: /* release all of the keysyms: */
2571: for (mod_keysym = buffer->tme_keyboard_buffer_int_in0_modkeys[modifier];
2572: mod_keysym != NULL;
2573: mod_keysym = mod_keysym->tme_keysym_state_in0_modifier_next) {
2574:
2575: /* ignore this keysym if it isn't pressed: */
2576: if (!mod_keysym->tme_keysym_state_in0_pressed) {
2577: continue;
2578: }
2579:
2580: /* make the pseudoevent: */
2581: event_pseudo.tme_keyboard_event_type
2582: = TME_KEYBOARD_IN0_RELEASE_EVENT(mod_keysym->tme_keysym_state_in0_pressed);
2583: event_pseudo.tme_keyboard_event_time
2584: = _tme_keyboard_event_time_diff(event->tme_keyboard_event_time, -1);
2585: event_pseudo.tme_keyboard_event_modifiers
2586: = buffer->tme_keyboard_buffer_int_in0_modifiers;
2587:
2588: /* call the bottom half with this pseudoevent: */
2589: rc = _tme_keyboard_buffer_in0_bottom(buffer,
2590: mod_keysym,
2591: &event_pseudo);
2592: assert (rc == TME_OK);
2593: }
2594: }
2595:
2596: /* all of the modifiers that needed clearing must now be clear: */
2597: assert ((buffer->tme_keyboard_buffer_int_in0_modifiers
2598: & modifiers_clear) == 0);
2599: }
2600:
2601: /* generate a press event for a single keysym attached to each
2602: modifier that has been set: */
2603: if (modifiers_set != 0) {
2604:
2605: /* loop over the modifiers that need setting: */
2606: for (modifier = 0;
2607: modifier <= TME_KEYBOARD_MODIFIER_MAX;
2608: modifier++) {
2609: if (!(modifiers_set & (1 << modifier))) {
2610: continue;
2611: }
2612:
2613: /* press the first keysym attached to this modifier: */
2614: mod_keysym = buffer->tme_keyboard_buffer_int_in0_modkeys[modifier];
2615: assert (mod_keysym != NULL);
2616:
2617: /* make the pseudoevent: */
2618: event_pseudo.tme_keyboard_event_type
2619: = TME_KEYBOARD_EVENT_IN0_PRESS_AUTO;
2620: event_pseudo.tme_keyboard_event_time
2621: = _tme_keyboard_event_time_diff(event->tme_keyboard_event_time, -1);
2622: event_pseudo.tme_keyboard_event_modifiers
2623: = buffer->tme_keyboard_buffer_int_in0_modifiers;
2624:
2625: /* call the bottom half with this pseudoevent: */
2626: rc = _tme_keyboard_buffer_in0_bottom(buffer,
2627: mod_keysym,
2628: &event_pseudo);
2629: assert (rc == TME_OK);
2630: }
2631:
2632: /* all of the modifiers that needed setting must now be set: */
2633: assert ((buffer->tme_keyboard_buffer_int_in0_modifiers
2634: & modifiers_set) == modifiers_set);
2635: }
2636:
2637: /* if the keysym in the event is undefined, we don't need to
2638: process this event any more. events with an undefined keysym
2639: can be used whenever the caller thinks that it has dropped
2640: keyboard events, and wants to do what it can to update the
2641: keyboard, and it can at least get the true current modifiers
2642: mask. this is common under X11: */
2643: if (event->tme_keyboard_event_keyval
2644: == TME_KEYBOARD_KEYVAL_UNDEF) {
2645: return (TME_OK);
2646: }
2647: }
2648:
2649: /* we must have a defined keysym: */
2650: assert (event->tme_keyboard_event_keyval
2651: != TME_KEYBOARD_KEYVAL_UNDEF);
2652:
2653: /* if we have no state for the keysym in this event, this keysym
2654: isn't controlled by any of the input stages: */
2655: if (keysym == NULL) {
2656:
2657: /* if there are output stages, having no state for this keysym
2658: means that this keysym doesn't exist on the output keyboard.
2659: we can stop processing this event now: */
2660: if (!buffer->tme_keyboard_buffer_int_out0_passthrough) {
2661: return (TME_OK);
2662: }
2663:
2664: /* otherwise, simply buffer this event: */
2665: event_pseudo = *event;
2666: switch (event->tme_keyboard_event_type) {
2667: case TME_KEYBOARD_EVENT_IN0_PRESS_USER:
2668: case TME_KEYBOARD_EVENT_IN0_PRESS_AUTO:
2669: event_pseudo.tme_keyboard_event_type = TME_KEYBOARD_EVENT_PRESS;
2670: break;
2671: case TME_KEYBOARD_EVENT_IN0_RELEASE_USER:
2672: case TME_KEYBOARD_EVENT_IN0_RELEASE_AUTO:
2673: event_pseudo.tme_keyboard_event_type = TME_KEYBOARD_EVENT_RELEASE;
2674: break;
2675: default: abort();
2676: }
2677: event_pseudo.tme_keyboard_event_modifiers = 0;
2678: return (_tme_keyboard_buffer_copyin(buffer, &event_pseudo));
2679: }
2680:
2681: /* if this event has a keycode: */
2682: if (event->tme_keyboard_event_keycode
2683: != TME_KEYBOARD_KEYVAL_UNDEF) {
2684:
2685: /* see if this keycode is already pressed in this stage: */
2686: other_keysym
2687: = ((struct tme_keysym_state *)
2688: tme_hash_lookup(buffer->tme_keyboard_buffer_int_in0_keycodes,
2689: (tme_hash_data_t) event->tme_keyboard_event_keycode));
2690:
2691: /* if this keycode is already pressed by another keysym in this
2692: stage, release the other keysym first: */
2693: if (other_keysym != NULL
2694: && other_keysym != keysym
2695: && TME_KEYBOARD_PRESSED_IN0(other_keysym)) {
2696:
2697: /* make the pseudoevent: */
2698: event_pseudo.tme_keyboard_event_type
2699: = TME_KEYBOARD_IN0_RELEASE_EVENT(other_keysym->tme_keysym_state_in0_pressed);
2700: event_pseudo.tme_keyboard_event_time
2701: = _tme_keyboard_event_time_diff(event->tme_keyboard_event_time, -1);
2702: event_pseudo.tme_keyboard_event_modifiers
2703: = buffer->tme_keyboard_buffer_int_in0_modifiers;
2704:
2705: /* call the bottom half with this pseudoevent: */
2706: rc = _tme_keyboard_buffer_in0_bottom(buffer,
2707: other_keysym,
2708: &event_pseudo);
2709: assert (rc == TME_OK);
2710: }
2711:
2712: /* if this is a press, remember that this keycode is pressed,
2713: else forget that this keycode is pressed: */
2714: if (event->tme_keyboard_event_type == TME_KEYBOARD_EVENT_PRESS) {
2715: tme_hash_insert(buffer->tme_keyboard_buffer_int_in0_keycodes,
2716: (tme_hash_data_t) event->tme_keyboard_event_keycode,
2717: (tme_hash_data_t) keysym);
2718: }
2719: else {
2720: tme_hash_remove(buffer->tme_keyboard_buffer_int_in0_keycodes,
2721: (tme_hash_data_t) event->tme_keyboard_event_keycode);
2722: }
2723: }
2724:
2725: /* call the bottom half with this event: */
2726: return (_tme_keyboard_buffer_in0_bottom(buffer,
2727: keysym,
2728: event));
2729: }
2730:
2731: /* this copies a keyboard event into the buffer: */
2732: int
2733: tme_keyboard_buffer_copyin(struct tme_keyboard_buffer *_buffer,
2734: const struct tme_keyboard_event *event)
2735: {
2736: struct tme_keyboard_buffer_int *buffer;
2737:
2738: /* recover our data structure: */
2739: buffer = (struct tme_keyboard_buffer_int *) _buffer;
2740:
2741: /* run input stage zero: */
2742: return (_tme_keyboard_buffer_in0(buffer, event));
2743: }
2744:
2745: /* this copies a keyval out of a keyboard buffer: */
2746: int
2747: tme_keyboard_buffer_copyout(struct tme_keyboard_buffer *buffer,
2748: struct tme_keyboard_event *event)
2749: {
2750: unsigned int buffer_tail, buffer_size_mask;
2751:
2752: buffer_tail = buffer->tme_keyboard_buffer_tail;
2753: buffer_size_mask = buffer->tme_keyboard_buffer_size - 1;
2754:
2755: /* if the buffer is empty: */
2756: if (buffer_tail == buffer->tme_keyboard_buffer_head) {
2757: return (EAGAIN);
2758: }
2759:
2760: /* get an event out of the buffer: */
2761: *event = buffer->tme_keyboard_buffer_events[buffer_tail];
2762:
2763: /* advance the tail: */
2764: buffer->tme_keyboard_buffer_tail = (buffer_tail + 1) & buffer_size_mask;
2765: return (TME_OK);
2766: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.