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