1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com> 3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat All rights reserved. 4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatThis file is part of x11vnc. 6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatx11vnc is free software; you can redistribute it and/or modify 8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatit under the terms of the GNU General Public License as published by 9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthe Free Software Foundation; either version 2 of the License, or (at 10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatyour option) any later version. 11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatx11vnc is distributed in the hope that it will be useful, 13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatbut WITHOUT ANY WARRANTY; without even the implied warranty of 14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatGNU General Public License for more details. 16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatYou should have received a copy of the GNU General Public License 18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatalong with x11vnc; if not, write to the Free Software 19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA 20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehator see <http://www.gnu.org/licenses/>. 21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatIn addition, as a special exception, Karl J. Runge 23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatgives permission to link the code of its release of x11vnc with the 24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatOpenSSL project's "OpenSSL" library (or with modified versions of it 25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthat use the same license as the "OpenSSL" library), and distribute 26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthe linked executables. You must obey the GNU General Public License 27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatin all respects for all of the code used other than "OpenSSL". If you 28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatmodify this file, you may extend this exception to your version of the 29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatfile, but you are not obligated to do so. If you do not wish to do 30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatso, delete this exception statement from your version. 31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat*/ 32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* -- keyboard.c -- */ 34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "x11vnc.h" 36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "xwrappers.h" 37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "xrecord.h" 38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "xinerama.h" 39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "pointer.h" 40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "userinput.h" 41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "win_utils.h" 42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "rates.h" 43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "cleanup.h" 44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "allowed_input_t.h" 45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "unixpw.h" 46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "v4l.h" 47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "linuxfb.h" 48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "uinput.h" 49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "macosx.h" 50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "screen.h" 51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid get_keystate(int *keystate); 53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid clear_modifiers(int init); 54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint track_mod_state(rfbKeySym keysym, rfbBool down, rfbBool set); 55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid clear_keys(void); 56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid clear_locks(void); 57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_autorepeat_state(void); 58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_initial_autorepeat_state(void); 59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid autorepeat(int restore, int bequiet); 60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid check_add_keysyms(void); 61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint add_keysym(KeySym keysym); 62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid delete_added_keycodes(int bequiet); 63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid initialize_remap(char *infile); 64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint sloppy_key_check(int key, rfbBool down, rfbKeySym keysym, int *new_kc); 65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid switch_to_xkb_if_better(void); 66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *short_kmbcf(char *str); 67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid initialize_allowed_input(void); 68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid initialize_modtweak(void); 69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid initialize_keyboard_and_pointer(void); 70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid get_allowed_input(rfbClientPtr client, allowed_input_t *input); 71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatdouble typing_rate(double time_window, int *repeating); 72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint skip_cr_when_scaling(char *mode); 73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client); 74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void delete_keycode(KeyCode kc, int bequiet); 77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int count_added_keycodes(void); 78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void add_remap(char *line); 79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void add_dead_keysyms(char *str); 80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void initialize_xkb_modtweak(void); 81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym, 82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr client); 83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void tweak_mod(signed char mod, rfbBool down); 84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void modifier_tweak_keyboard(rfbBool down, rfbKeySym keysym, 85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr client); 86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client); 87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Routine to retreive current state keyboard. 1 means down, 0 up. 91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid get_keystate(int *keystate) { 93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11 94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!keystate) {} 96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, k; 99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char keys[32]; 100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* n.b. caller decides to X_LOCK or not. */ 104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XQueryKeymap(dpy, keys); 105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<32; i++) { 106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char c = keys[i]; 107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (k=0; k < 8; k++) { 109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (c & 0x1) { 110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keystate[8*i + k] = 1; 111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keystate[8*i + k] = 0; 113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat c = c >> 1; 115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif /* NO_X11 */ 118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Try to KeyRelease any non-Lock modifiers that are down. 122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid clear_modifiers(int init) { 124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11 125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!init) {} 127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static KeyCode keycodes[256]; 130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static KeySym keysyms[256]; 131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static char *keystrs[256]; 132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static int kcount = 0, first = 1; 133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int keystate[256]; 134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, j, minkey, maxkey, syms_per_keycode; 135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym *keymap; 136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym keysym; 137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeyCode keycode; 138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* n.b. caller decides to X_LOCK or not. */ 142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (first) { 143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * we store results in static arrays, to aid interrupted 145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * case, but modifiers could have changed during session... 146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XDisplayKeycodes(dpy, &minkey, &maxkey); 148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1), 150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat &syms_per_keycode); 151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = minkey; i <= maxkey; i++) { 153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j = 0; j < syms_per_keycode; j++) { 154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str; 155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = keymap[ (i - minkey) * syms_per_keycode + j ]; 156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == NoSymbol || ! ismodkey(keysym)) { 157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keycode = XKeysymToKeycode(dpy, keysym); 160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keycode == NoSymbol) { 161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keycodes[kcount] = keycode; 164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysyms[kcount] = keysym; 165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = XKeysymToString(keysym); 166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! str) str = "null"; 167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keystrs[kcount] = strdup(str); 168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kcount++; 169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFree_wr((void *) keymap); 172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat first = 0; 173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (init) { 175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat get_keystate(keystate); 179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i < kcount; i++) { 180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = keysyms[i]; 181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keycode = keycodes[i]; 182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! keystate[(int) keycode]) { 184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (clear_mods) { 188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("clear_modifiers: up: %-10s (0x%x) " 189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "keycode=0x%x\n", keystrs[i], keysym, keycode); 190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, keycode, False, CurrentTime); 192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFlush_wr(dpy); 194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif /* NO_X11 */ 195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic KeySym simple_mods[] = { 198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_Shift_L, XK_Shift_R, 199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_Control_L, XK_Control_R, 200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_Meta_L, XK_Meta_R, 201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_Alt_L, XK_Alt_R, 202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_Super_L, XK_Super_R, 203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_Hyper_L, XK_Hyper_R, 204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_Mode_switch, 205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat NoSymbol 206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}; 207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define NSIMPLE_MODS 13 208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint track_mod_state(rfbKeySym keysym, rfbBool down, rfbBool set) { 210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym sym = (KeySym) keysym; 211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static rfbBool isdown[NSIMPLE_MODS]; 212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static int first = 1; 213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, cnt = 0; 214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * simple tracking method for the modifier state without 217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * contacting the Xserver. Ignores, of course what keys are 218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * pressed on the physical display. 219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This is unrelated to our mod_tweak and xkb stuff. 221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Just a simple thing for wireframe/scroll heuristics, 222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * sloppy keys etc. 223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (first) { 226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<NSIMPLE_MODS; i++) { 227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat isdown[i] = FALSE; 228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat first = 0; 230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sym != NoSymbol) { 233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<NSIMPLE_MODS; i++) { 234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sym == simple_mods[i]) { 235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (set) { 236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat isdown[i] = down; 237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 1; 238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (isdown[i]) { 240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 1; 241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* not a modifier */ 249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (set) { 250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* called with NoSymbol: return number currently pressed: */ 257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<NSIMPLE_MODS; i++) { 258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (isdown[i]) { 259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cnt++; 260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return cnt; 263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Attempt to set all keys to Up position. Can mess up typing at the 267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * physical keyboard so use with caution. 268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid clear_keys(void) { 270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int k, keystate[256]; 271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* n.b. caller decides to X_LOCK or not. */ 275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat get_keystate(keystate); 276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (k=0; k<256; k++) { 277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keystate[k]) { 278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeyCode keycode = (KeyCode) k; 279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("clear_keys: keycode=%d\n", keycode); 280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, keycode, False, CurrentTime); 281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFlush_wr(dpy); 284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid clear_locks(void) { 288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11 289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XModifierKeymap *map; 293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, j, k = 0; 294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned int state = 0; 295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* n.b. caller decides to X_LOCK or not. */ 299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_XKEYBOARD 300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (xkb_present) { 301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XkbStateRec kbstate; 302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XkbGetState(dpy, XkbUseCoreKbd, &kbstate); 303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("locked: 0x%x\n", kbstate.locked_mods); 304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("latched: 0x%x\n", kbstate.latched_mods); 305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("compat: 0x%x\n", kbstate.compat_state); 306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state = kbstate.locked_mods; 307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! state) { 308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state = kbstate.compat_state; 309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else 311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state = mask_state(); 314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* this may contain non-locks too... */ 315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("state: 0x%x\n", state); 316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! state) { 318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat map = XGetModifierMapping(dpy); 321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! map) { 322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 8; i++) { 325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int did = 0; 326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j = 0; j < map->max_keypermod; j++) { 327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! did && state & (0x1 << i)) { 328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (map->modifiermap[k]) { 329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeyCode key = map->modifiermap[k]; 330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym ks = XKeycodeToKeysym(dpy, key, 0); 331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *nm = XKeysymToString(ks); 332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("toggling: %03d / %03d -- %s\n", key, ks, nm ? nm : "BadKey"); 333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat did = 1; 334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, key, True, CurrentTime); 335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat usleep(10*1000); 336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, key, False, CurrentTime); 337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFlush_wr(dpy); 338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k++; 341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFreeModifiermap(map); 344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFlush_wr(dpy); 345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("state: 0x%x\n", mask_state()); 346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Kludge for -norepeat option: we turn off keystroke autorepeat in 351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the X server when clients are connected. This may annoy people at 352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the physical display. We do this because 'key down' and 'key up' 353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * user input events may be separated by 100s of ms due to screen fb 354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * processing or link latency, thereby inducing the X server to apply 355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * autorepeat when it should not. Since the *client* is likely doing 356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * keystroke autorepeating as well, it kind of makes sense to shut it 357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * off if no one is at the physical display... 358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int save_auto_repeat = -1; 360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_autorepeat_state(void) { 362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11 363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET(0) 364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XKeyboardState kstate; 367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET(0) 369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XGetKeyboardControl(dpy, &kstate); 372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return kstate.global_auto_repeat; 374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif /* NO_X11 */ 375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_initial_autorepeat_state(void) { 378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (save_auto_repeat < 0) { 379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat save_auto_repeat = get_autorepeat_state(); 380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return save_auto_repeat; 382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid autorepeat(int restore, int bequiet) { 385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11 386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!restore || !bequiet) {} 388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int global_auto_repeat; 391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XKeyboardControl kctrl; 392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (restore) { 396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (save_auto_repeat < 0) { 397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; /* nothing to restore */ 398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat global_auto_repeat = get_autorepeat_state(); 400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* read state and skip restore if equal (e.g. no clients) */ 401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (global_auto_repeat == save_auto_repeat) { 402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kctrl.auto_repeat_mode = save_auto_repeat; 407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XChangeKeyboardControl(dpy, KBAutoRepeatMode, &kctrl); 408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFlush_wr(dpy); 409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! bequiet && ! quiet) { 412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Restored X server key autorepeat to: %d\n", 413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat save_auto_repeat); 414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat global_auto_repeat = get_autorepeat_state(); 417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (save_auto_repeat < 0) { 418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * we only remember the state at startup 420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * to avoid confusing ourselves later on. 421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat save_auto_repeat = global_auto_repeat; 423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kctrl.auto_repeat_mode = AutoRepeatModeOff; 427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XChangeKeyboardControl(dpy, KBAutoRepeatMode, &kctrl); 428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFlush_wr(dpy); 429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! bequiet && ! quiet) { 432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Disabled X server key autorepeat.\n"); 433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (no_repeat_countdown >= 0) { 434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" to force back on run: 'xset r on' (%d " 435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "times)\n", no_repeat_countdown+1); 436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif /* NO_X11 */ 440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * We periodically delete any keysyms we have added, this is to 444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * lessen our effect on the X server state if we are terminated abruptly 445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and cannot clear them and also to clear out any strange little used 446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ones that would just fill up the keymapping. 447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid check_add_keysyms(void) { 449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static time_t last_check = 0; 450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int clear_freq = 300, quiet = 1, count; 451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat time_t now = time(NULL); 452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (unixpw_in_progress) return; 454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (now > last_check + clear_freq) { 456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat count = count_added_keycodes(); 457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * only really delete if they have not typed recently 459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and we have added 8 or more. 460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (now > last_keyboard_input + 5 && count >= 8) { 462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat delete_added_keycodes(quiet); 464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_check = now; 467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic KeySym added_keysyms[0x100]; 471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* these are just for rfbLog messages: */ 473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic KeySym alltime_added_keysyms[1024]; 474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int alltime_len = 1024; 475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int alltime_num = 0; 476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint add_keysym(KeySym keysym) { 478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static int first = 1; 479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int n; 480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11 481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (first) { 482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (n=0; n < 0x100; n++) { 483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat added_keysyms[n] = NoSymbol; 484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat first = 0; 486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET(0) 488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!keysym) {} 489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int minkey, maxkey, syms_per_keycode; 492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int kc, ret = 0; 493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym *keymap; 494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (first) { 496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (n=0; n < 0x100; n++) { 497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat added_keysyms[n] = NoSymbol; 498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat first = 0; 500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET(0) 503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == NoSymbol) { 505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* there can be a race before MappingNotify */ 508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (n=0; n < 0x100; n++) { 509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (added_keysyms[n] == keysym) { 510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return n; 511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XDisplayKeycodes(dpy, &minkey, &maxkey); 515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1), 516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat &syms_per_keycode); 517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (kc = minkey+1; kc <= maxkey; kc++) { 519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, j, didmsg = 0, is_empty = 1; 520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str; 521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym newks[8]; 522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (n=0; n < syms_per_keycode; n++) { 524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keymap[ (kc-minkey) * syms_per_keycode + n] 525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat != NoSymbol) { 526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat is_empty = 0; 527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! is_empty) { 531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<8; i++) { 535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat newks[i] = NoSymbol; 536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (add_keysyms == 2) { 538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat newks[0] = keysym; /* XXX remove me */ 539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i=0; i < syms_per_keycode; i++) { 541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat newks[i] = keysym; 542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (i >= 7) break; 543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XChangeKeyboardMapping(dpy, kc, syms_per_keycode, 547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat newks, 1); 548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (alltime_num >= alltime_len) { 550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat didmsg = 1; /* something weird */ 551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j=0; j<alltime_num; j++) { 553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (alltime_added_keysyms[j] == keysym) { 554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat didmsg = 1; 555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! didmsg) { 560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = XKeysymToString(keysym); 561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("added missing keysym to X display: %03d " 562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "0x%x \"%s\"\n", kc, keysym, str ? str : "null"); 563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (alltime_num < alltime_len) { 565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat alltime_added_keysyms[alltime_num++] = keysym; 566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFlush_wr(dpy); 570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat added_keysyms[kc] = keysym; 571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ret = kc; 572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFree_wr(keymap); 575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return ret; 576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif /* NO_X11 */ 577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void delete_keycode(KeyCode kc, int bequiet) { 580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11 581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!kc || !bequiet) {} 583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int minkey, maxkey, syms_per_keycode, i; 586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym *keymap; 587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym ksym, newks[8]; 588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str; 589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XDisplayKeycodes(dpy, &minkey, &maxkey); 593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1), 594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat &syms_per_keycode); 595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<8; i++) { 597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat newks[i] = NoSymbol; 598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XChangeKeyboardMapping(dpy, kc, syms_per_keycode, newks, 1); 601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! bequiet && ! quiet) { 603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ksym = XKeycodeToKeysym(dpy, kc, 0); 604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = XKeysymToString(ksym); 605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("deleted keycode from X display: %03d 0x%x \"%s\"\n", 606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc, ksym, str ? str : "null"); 607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFree_wr(keymap); 610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFlush_wr(dpy); 611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif /* NO_X11 */ 612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int count_added_keycodes(void) { 615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int kc, count = 0; 616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (kc = 0; kc < 0x100; kc++) { 617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (added_keysyms[kc] != NoSymbol) { 618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat count++; 619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return count; 622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid delete_added_keycodes(int bequiet) { 625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int kc; 626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (kc = 0; kc < 0x100; kc++) { 627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (added_keysyms[kc] != NoSymbol) { 628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat delete_keycode(kc, bequiet); 629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat added_keysyms[kc] = NoSymbol; 630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * The following is for an experimental -remap option to allow the user 636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * to remap keystrokes. It is currently confusing wrt modifiers... 637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehattypedef struct keyremap { 639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym before; 640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym after; 641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int isbutton; 642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct keyremap *next; 643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} keyremap_t; 644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic keyremap_t *keyremaps = NULL; 646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void add_remap(char *line) { 648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char str1[256], str2[256]; 649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym ksym1, ksym2; 650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int isbtn = 0; 651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned int i; 652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static keyremap_t *current = NULL; 653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keyremap_t *remap; 654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sscanf(line, "%s %s", str1, str2) != 2) { 656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogEnable(1); 657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("remap: invalid line: %s\n", line); 658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat clean_up_exit(1); 659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sscanf(str1, "0x%x", &i) == 1) { 661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ksym1 = (KeySym) i; 662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ksym1 = XStringToKeysym(str1); 664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sscanf(str2, "0x%x", &i) == 1) { 666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ksym2 = (KeySym) i; 667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ksym2 = XStringToKeysym(str2); 669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ksym2 == NoSymbol) { 671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sscanf(str2, "Button%u", &i) == 1) { 672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ksym2 = (KeySym) i; 673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat isbtn = 1; 674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ksym1 == NoSymbol || ksym2 == NoSymbol) { 677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (strcasecmp(str2, "NoSymbol") && strcasecmp(str2, "None")) { 678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("warning: skipping invalid remap line: %s", line); 679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat remap = (keyremap_t *) malloc((size_t) sizeof(keyremap_t)); 683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat remap->before = ksym1; 684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat remap->after = ksym2; 685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat remap->isbutton = isbtn; 686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat remap->next = NULL; 687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("remapping: (%s, 0x%x) -> (%s, 0x%x) isbtn=%d\n", str1, 689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ksym1, str2, ksym2, isbtn); 690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keyremaps == NULL) { 692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keyremaps = remap; 693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat current->next = remap; 695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat current = remap; 697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void add_dead_keysyms(char *str) { 700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *p, *q; 701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i; 702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *list[] = { 703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "g grave dead_grave", 704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "a acute dead_acute", 705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "c asciicircum dead_circumflex", 706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "t asciitilde dead_tilde", 707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "m macron dead_macron", 708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "b breve dead_breve", 709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "D abovedot dead_abovedot", 710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "d diaeresis dead_diaeresis", 711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "o degree dead_abovering", 712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "A doubleacute dead_doubleacute", 713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "r caron dead_caron", 714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "e cedilla dead_cedilla", 715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* "x XXX-ogonek dead_ogonek", */ 716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* "x XXX-belowdot dead_belowdot", */ 717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* "x XXX-hook dead_hook", */ 718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* "x XXX-horn dead_horn", */ 719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat NULL 720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat }; 721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = str; 723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (*p != '\0') { 725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (isspace((unsigned char) (*p))) { 726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *p = '\0'; 727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p++; 729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!strcmp(str, "DEAD")) { 732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; list[i] != NULL; i++) { 733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = list[i] + 2; 734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat add_remap(p); 735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (!strcmp(str, "DEAD=missing")) { 737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; list[i] != NULL; i++) { 738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym ksym, ksym2; 739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int inmap = 0; 740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = strdup(list[i] + 2); 742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat q = strchr(p, ' '); 743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (q == NULL) { 744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(p); 745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *q = '\0'; 748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ksym = XStringToKeysym(p); 749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *q = ' '; 750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ksym == NoSymbol) { 751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(p); 752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (XKeysymToKeycode(dpy, ksym)) { 755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat inmap = 1; 756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if LIBVNCSERVER_HAVE_XKEYBOARD 758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! inmap && xkb_present && dpy) { 759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int kc, grp, lvl; 760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (kc = 0; kc < 0x100; kc++) { 761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (grp = 0; grp < 4; grp++) { 762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (lvl = 0; lvl < 8; lvl++) { 763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ksym2 = XkbKeycodeToKeysym(dpy, 764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc, grp, lvl); 765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ksym2 == NoSymbol) { 766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ksym2 == ksym) { 769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat inmap = 1; 770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 773a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 774a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((ksym2 = 0)) {} 778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! inmap) { 780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat add_remap(p); 781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(p); 783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if ((p = strchr(str, '=')) != NULL) { 785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (*p != '\0') { 786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; list[i] != NULL; i++) { 787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat q = list[i]; 788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (*p == *q) { 789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat q += 2; 790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat add_remap(q); 791a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 792a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p++; 795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * process the -remap string (file or mapping string) 801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid initialize_remap(char *infile) { 803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FILE *in; 804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *p, *q, line[256]; 805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keyremaps != NULL) { 807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* free last remapping */ 808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keyremap_t *next_remap, *curr_remap = keyremaps; 809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (curr_remap != NULL) { 810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat next_remap = curr_remap->next; 811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(curr_remap); 812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat curr_remap = next_remap; 813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keyremaps = NULL; 815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (infile == NULL || *infile == '\0') { 817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* just unset remapping */ 818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat in = fopen(infile, "r"); 822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (in == NULL) { 823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* assume cmd line key1-key2,key3-key4 */ 824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (strstr(infile, "DEAD") == infile) { 825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ; 826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (!strchr(infile, '-')) { 827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogEnable(1); 828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("remap: cannot open: %s\n", infile); 829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("fopen"); 830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat clean_up_exit(1); 831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((in = tmpfile()) == NULL) { 833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogEnable(1); 834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("remap: cannot open tmpfile for %s\n", infile); 835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("tmpfile"); 836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat clean_up_exit(1); 837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* copy in the string to file format */ 840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = infile; 841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (*p) { 842a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (*p == '-') { 843a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(in, " "); 844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (*p == ',' || *p == ' ' || *p == '\t') { 845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(in, "\n"); 846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(in, "%c", *p); 848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p++; 850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(in, "\n"); 852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fflush(in); 853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rewind(in); 854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (fgets(line, 256, in) != NULL) { 857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = lblanks(line); 858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (*p == '\0') { 859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (strchr(line, '#')) { 862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (strstr(p, "DEAD") == p) { 866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat add_dead_keysyms(p); 867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((q = strchr(line, '-')) != NULL) { 870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* allow Keysym1-Keysym2 notation */ 871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *q = ' '; 872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat add_remap(p); 874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fclose(in); 876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * preliminary support for using the Xkb (XKEYBOARD) extension for handling 880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * user input. inelegant, slow, and incomplete currently... but initial 881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * tests show it is useful for some setups. 882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehattypedef struct keychar { 884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeyCode code; 885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int group; 886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int level; 887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} keychar_t; 888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* max number of key groups and shift levels we consider */ 890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define GRP 4 891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define LVL 8 892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int lvl_max, grp_max, kc_min, kc_max; 893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic KeySym xkbkeysyms[0x100][GRP][LVL]; 894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic unsigned int xkbstate[0x100][GRP][LVL]; 895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic unsigned int xkbignore[0x100][GRP][LVL]; 896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic unsigned int xkbmodifiers[0x100][GRP][LVL]; 897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int multi_key[0x100], mode_switch[0x100], skipkeycode[0x100]; 898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int shift_keys[0x100]; 899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * for trying to order the keycodes to avoid problems, note the 902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * *first* keycode bound to it. kc_vec will be a permutation 903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * of 1...256 to get them in the preferred order. 904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int kc_vec[0x100]; 906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int kc1_shift, kc1_control, kc1_caplock, kc1_alt; 907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int kc1_meta, kc1_numlock, kc1_super, kc1_hyper; 908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int kc1_mode_switch, kc1_iso_level3_shift, kc1_multi_key; 909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint sloppy_key_check(int key, rfbBool down, rfbKeySym keysym, int *new_kc) { 911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!sloppy_keys) { 912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET(0) 916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11 917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!key || !down || !keysym || !new_kc) {} 918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 921a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!down && !keycode_state[key] && !IsModifierKey(keysym)) { 922a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, cnt = 0, downkey = -1; 923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int nmods_down = track_mod_state(NoSymbol, FALSE, FALSE); 924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int mods_down[256]; 925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (nmods_down) { 927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* tracking to skip down modifier keycodes. */ 928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i=0; i<256; i++) { 929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat mods_down[i] = 0; 930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 931a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i = 0; 932a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (simple_mods[i] != NoSymbol) { 933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym ksym = simple_mods[i]; 934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeyCode k = XKeysymToKeycode(dpy, ksym); 935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (k != NoSymbol && keycode_state[(int) k]) { 936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat mods_down[(int) k] = 1; 937a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 938a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 939a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i++; 940a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 941a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 942a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 943a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the keycode is already up... look for a single one 944a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * (non modifier) that is down 945a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 946a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<256; i++) { 947a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keycode_state[i]) { 948a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (nmods_down && mods_down[i]) { 949a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 950a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 951a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cnt++; 952a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat downkey = i; 953a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 954a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 955a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cnt == 1) { 956a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 957a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " sloppy_keys: %d/0x%x " 958a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "-> %d/0x%x (nmods: %d)\n", (int) key, 959a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (int) key, downkey, downkey, nmods_down); 960a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 961a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *new_kc = downkey; 962a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 1; 963a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 964a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 965a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 966a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif /* NO_X11 */ 967a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 968a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 969a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if !LIBVNCSERVER_HAVE_XKEYBOARD || SKIP_XKB 970a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 971a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* empty functions for no xkb */ 972a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void initialize_xkb_modtweak(void) {} 973a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym, 974a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr client) { 975a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!client || !down || !keysym) {} /* unused vars warning: */ 976a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 977a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid switch_to_xkb_if_better(void) {} 978a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 979a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 980a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 981a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid switch_to_xkb_if_better(void) { 982a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym keysym, *keymap; 983a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int miss_noxkb[256], miss_xkb[256], missing_noxkb = 0, missing_xkb = 0; 984a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, j, k, n, minkey, maxkey, syms_per_keycode; 985a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int syms_gt_4 = 0; 986a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int kc, grp, lvl; 987a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 988a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* non-alphanumeric on us keyboard */ 989a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym must_have[] = { 990a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_exclam, 991a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_at, 992a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_numbersign, 993a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_dollar, 994a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_percent, 995a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* XK_asciicircum, */ 996a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_ampersand, 997a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_asterisk, 998a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_parenleft, 999a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_parenright, 1000a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_underscore, 1001a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_plus, 1002a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_minus, 1003a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_equal, 1004a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_bracketleft, 1005a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_bracketright, 1006a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_braceleft, 1007a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_braceright, 1008a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_bar, 1009a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_backslash, 1010a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_semicolon, 1011a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* XK_apostrophe, */ 1012a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_colon, 1013a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_quotedbl, 1014a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_comma, 1015a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_period, 1016a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_less, 1017a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_greater, 1018a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_slash, 1019a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XK_question, 1020a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* XK_asciitilde, */ 1021a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* XK_grave, */ 1022a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat NoSymbol 1023a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat }; 1024a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1025a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! use_modifier_tweak || got_noxkb) { 1026a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 1027a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1028a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (use_xkb_modtweak) { 1029a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* already using it */ 1030a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 1031a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1032a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 1033a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1034a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XDisplayKeycodes(dpy, &minkey, &maxkey); 1035a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1036a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1), 1037a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat &syms_per_keycode); 1038a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1039a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* handle alphabetic char with only one keysym (no upper + lower) */ 1040a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = minkey; i <= maxkey; i++) { 1041a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym lower, upper; 1042a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2nd one */ 1043a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = keymap[(i - minkey) * syms_per_keycode + 1]; 1044a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym != NoSymbol) { 1045a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1046a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1047a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1st one */ 1048a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = keymap[(i - minkey) * syms_per_keycode + 0]; 1049a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == NoSymbol) { 1050a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1051a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1052a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XConvertCase(keysym, &lower, &upper); 1053a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (lower != upper) { 1054a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keymap[(i - minkey) * syms_per_keycode + 0] = lower; 1055a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keymap[(i - minkey) * syms_per_keycode + 1] = upper; 1056a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1057a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1058a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1059a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k = 0; 1060a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (must_have[k] != NoSymbol) { 1061a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int gotit = 0; 1062a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym must = must_have[k]; 1063a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = minkey; i <= maxkey; i++) { 1064a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j = 0; j < syms_per_keycode; j++) { 1065a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = keymap[(i-minkey) * syms_per_keycode + j]; 1066a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (j >= 4) { 1067a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (k == 0 && keysym != NoSymbol) { 1068a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* for k=0 count the high keysyms */ 1069a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat syms_gt_4++; 1070a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard > 1) { 1071a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str = XKeysymToString(keysym); 1072a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, "- high keysym mapping" 1073a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ": at %3d j=%d " 1074a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "'%s'\n", i, j, str ? str : "null"); 1075a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1076a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1077a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1078a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1079a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == must) { 1080a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard > 1) { 1081a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str = XKeysymToString(must); 1082a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, "- at %3d j=%d found " 1083a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "'%s'\n", i, j, str ? str : "null"); 1084a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1085a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* n.b. do not break, see syms_gt_4 above. */ 1086a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat gotit = 1; 1087a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1088a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1089a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1090a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! gotit) { 1091a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard > 1) { 1092a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str = XKeysymToString(must); 1093a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeyCode kc = XKeysymToKeycode(dpy, must); 1094a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, "- did not find 0x%lx '%s'\t" 1095a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "Ks2Kc: %d\n", must, str ? str:"null", kc); 1096a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc != None) { 1097a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int j2; 1098a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(j2=0; j2<syms_per_keycode; j2++) { 1099a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = keymap[(kc-minkey) * 1100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat syms_per_keycode + j2]; 1101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " %d=0x%lx", 1102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat j2, keysym); 1103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, "\n"); 1105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat missing_noxkb++; 1108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat miss_noxkb[k] = 1; 1109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 1110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat miss_noxkb[k] = 0; 1111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k++; 1113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat n = k; 1115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFree_wr(keymap); 1117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (missing_noxkb == 0 && syms_per_keycode > 4 && syms_gt_4 >= 0) { 1118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* we used to have syms_gt_4 >= 8, now always on. */ 1119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! raw_fb_str) { 1120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("\n"); 1121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("XKEYBOARD: number of keysyms per keycode %d is greater\n", syms_per_keycode); 1122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" than 4 and %d keysyms are mapped above 4.\n", syms_gt_4); 1123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" Automatically switching to -xkb mode.\n"); 1124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" If this makes the key mapping worse you can\n"); 1125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" disable it with the \"-noxkb\" option.\n"); 1126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" Also, remember \"-remap DEAD\" for accenting characters.\n"); 1127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("\n"); 1128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat use_xkb_modtweak = 1; 1131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 1132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (missing_noxkb == 0) { 1134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! raw_fb_str) { 1135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("\n"); 1136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("XKEYBOARD: all %d \"must have\" keysyms accounted for.\n", n); 1137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" Not automatically switching to -xkb mode.\n"); 1138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" If some keys still cannot be typed, try using -xkb.\n"); 1139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" Also, remember \"-remap DEAD\" for accenting characters.\n"); 1140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("\n"); 1141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 1143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (k=0; k<n; k++) { 1146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat miss_xkb[k] = 1; 1147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (kc = 0; kc < 0x100; kc++) { 1150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (grp = 0; grp < GRP; grp++) { 1151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (lvl = 0; lvl < LVL; lvl++) { 1152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* look up the Keysym, if any */ 1153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = XkbKeycodeToKeysym(dpy, kc, grp, lvl); 1154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == NoSymbol) { 1155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (k=0; k<n; k++) { 1158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == must_have[k]) { 1159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat miss_xkb[k] = 0; 1160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (k=0; k<n; k++) { 1167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (miss_xkb[k]) { 1168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat missing_xkb++; 1169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("\n"); 1173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (missing_xkb < missing_noxkb) { 1174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("XKEYBOARD:\n"); 1175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Switching to -xkb mode to recover these keysyms:\n"); 1176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 1177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("XKEYBOARD: \"must have\" keysyms better accounted" 1178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat " for\n"); 1179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("under -noxkb mode: not switching to -xkb mode:\n"); 1180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" xkb noxkb Keysym (\"X\" means present)\n"); 1183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" --- ----- -----------------------------\n"); 1184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (k=0; k<n; k++) { 1185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *xx, *xn, *name; 1186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = must_have[k]; 1188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == NoSymbol) { 1189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!miss_xkb[k] && !miss_noxkb[k]) { 1192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (miss_xkb[k]) { 1195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xx = " "; 1196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 1197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xx = " X "; 1198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (miss_noxkb[k]) { 1200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xn = " "; 1201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 1202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xn = " X "; 1203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat name = XKeysymToString(keysym); 1205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" %s %s 0x%lx %s\n", xx, xn, keysym, 1206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat name ? name : "null"); 1207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("\n"); 1209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (missing_xkb < missing_noxkb) { 1211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" If this makes the key mapping worse you can\n"); 1212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" disable it with the \"-noxkb\" option.\n"); 1213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("\n"); 1214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat use_xkb_modtweak = 1; 1216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 1218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" If some keys still cannot be typed, try using" 1219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat " -xkb.\n"); 1220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" Also, remember \"-remap DEAD\" for accenting" 1221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat " characters.\n"); 1222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("\n"); 1224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* sets up all the keymapping info via Xkb API */ 1227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void initialize_xkb_modtweak(void) { 1229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym ks; 1230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int kc, grp, lvl, k; 1231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned int state; 1232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 1234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Here is a guide: 1235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatWorkarounds arrays: 1237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatmulti_key[] indicates which keycodes have Multi_key (Compose) 1239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bound to them. 1240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatmode_switch[] indicates which keycodes have Mode_switch (AltGr) 1241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bound to them. 1242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatshift_keys[] indicates which keycodes have Shift bound to them. 1243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatskipkeycode[] indicates which keycodes are to be skipped 1244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for any lookups from -skip_keycodes option. 1245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatGroups and Levels, here is an example: 1247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ^ -------- 1249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat | L2 | A AE | 1250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat shift | | 1251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat level L1 | a ae | 1252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat -------- 1253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat G1 G2 1254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat group -> 1256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatTraditionally this it all a key could do. L1 vs. L2 selected via Shift 1258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatand G1 vs. G2 selected via Mode_switch. Up to 4 Keysyms could be bound 1259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatto a key. See initialize_modtweak() for an example of using that type 1260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatof keymap from XGetKeyboardMapping(). 1261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatXkb gives us up to 4 groups and 63 shift levels per key, with the 1263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatsituation being potentially different for each key. This is complicated, 1264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatand I don't claim to understand it all, but in the following we just think 1265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatof ranging over the group and level indices as covering all of the cases. 1266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatThis gives us an accurate view of the keymap. The main tricky part 1267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatis mapping between group+level and modifier state. 1268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatOn current linux/XFree86 setups (Xkb is enabled by default) the 1270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatinformation from XGetKeyboardMapping() (evidently the compat map) 1271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatis incomplete and inaccurate, so we are really forced to use the 1272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatXkb API. 1273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatxkbkeysyms[] For a (keycode,group,level) holds the KeySym (0 for none) 1275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatxkbstate[] For a (keycode,group,level) holds the corresponding 1276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat modifier state needed to get that KeySym 1277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatxkbignore[] For a (keycode,group,level) which modifiers can be 1278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ignored (the 0 bits can be ignored). 1279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatxkbmodifiers[] For the KeySym bound to this (keycode,group,level) store 1280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat the modifier mask. 1281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 1282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 1285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* initialize all the arrays: */ 1287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (kc = 0; kc < 0x100; kc++) { 1288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat multi_key[kc] = 0; 1289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat mode_switch[kc] = 0; 1290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skipkeycode[kc] = 0; 1291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat shift_keys[kc] = 0; 1292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (grp = 0; grp < GRP; grp++) { 1294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (lvl = 0; lvl < LVL; lvl++) { 1295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xkbkeysyms[kc][grp][lvl] = NoSymbol; 1296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xkbmodifiers[kc][grp][lvl] = -1; 1297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xkbstate[kc][grp][lvl] = -1; 1298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the array is 256*LVL*GRP, but we can make the searched region 1304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * smaller by computing the actual ranges. 1305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lvl_max = 0; 1307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat grp_max = 0; 1308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc_max = 0; 1309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc_min = 0x100; 1310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* first keycode for a modifier type (multi_key too) */ 1312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_shift = -1; 1313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_control = -1; 1314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_caplock = -1; 1315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_alt = -1; 1316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_meta = -1; 1317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_numlock = -1; 1318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_super = -1; 1319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_hyper = -1; 1320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_mode_switch = -1; 1321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_iso_level3_shift = -1; 1322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_multi_key = -1; 1323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * loop over all possible (keycode, group, level) triples 1326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and record what we find for it: 1327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 1329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("initialize_xkb_modtweak: XKB keycode -> keysyms " 1330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "mapping info:\n"); 1331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (kc = 0; kc < 0x100; kc++) { 1333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (grp = 0; grp < GRP; grp++) { 1334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (lvl = 0; lvl < LVL; lvl++) { 1335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned int ms, mods; 1336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int state_save = -1, mods_save = -1; 1337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym ks2; 1338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* look up the Keysym, if any */ 1340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ks = XkbKeycodeToKeysym(dpy, kc, grp, lvl); 1341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xkbkeysyms[kc][grp][lvl] = ks; 1342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* if no Keysym, on to next */ 1344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == NoSymbol) { 1345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * for various workarounds, note where these special 1349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * keys are bound to. 1350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Multi_key) { 1352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat multi_key[kc] = lvl+1; 1353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Mode_switch) { 1355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat mode_switch[kc] = lvl+1; 1356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Shift_L || ks == XK_Shift_R) { 1358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat shift_keys[kc] = lvl+1; 1359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Shift_L || ks == XK_Shift_R) { 1362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_shift == -1) { 1363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_shift = kc; 1364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Control_L || ks == XK_Control_R) { 1367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_control == -1) { 1368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_control = kc; 1369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Caps_Lock || ks == XK_Caps_Lock) { 1372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_caplock == -1) { 1373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_caplock = kc; 1374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Alt_L || ks == XK_Alt_R) { 1377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_alt == -1) { 1378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_alt = kc; 1379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Meta_L || ks == XK_Meta_R) { 1382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_meta == -1) { 1383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_meta = kc; 1384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Num_Lock) { 1387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_numlock == -1) { 1388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_numlock = kc; 1389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Super_L || ks == XK_Super_R) { 1392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_super == -1) { 1393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_super = kc; 1394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Hyper_L || ks == XK_Hyper_R) { 1397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_hyper == -1) { 1398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_hyper = kc; 1399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Mode_switch) { 1402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_mode_switch == -1) { 1403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_mode_switch = kc; 1404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_ISO_Level3_Shift) { 1407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_iso_level3_shift == -1) { 1408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_iso_level3_shift = kc; 1409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Multi_key) { /* not a modifier.. */ 1412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_multi_key == -1) { 1413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc1_multi_key = kc; 1414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * record maximum extent for group/level indices 1419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and keycode range: 1420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (grp > grp_max) { 1422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat grp_max = grp; 1423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (lvl > lvl_max) { 1425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lvl_max = lvl; 1426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc > kc_max) { 1428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc_max = kc; 1429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc < kc_min) { 1431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc_min = kc; 1432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * lookup on *keysym* (i.e. not kc, grp, lvl) 1436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and get the modifier mask. this is 0 for 1437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * most keysyms, only non zero for modifiers. 1438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ms = XkbKeysymToModifiers(dpy, ks); 1440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xkbmodifiers[kc][grp][lvl] = ms; 1441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Amusing heuristic (may have bugs). There are 1444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 8 modifier bits, so 256 possible modifier 1445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * states. We loop over all of them for this 1446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * keycode (simulating Key "events") and ask 1447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * XkbLookupKeySym to tell us the Keysym. Once it 1448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * matches the Keysym we have for this (keycode, 1449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * group, level), gotten via XkbKeycodeToKeysym() 1450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * above, we then (hopefully...) know that state 1451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * of modifiers needed to generate this keysym. 1452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 1453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Yes... keep your fingers crossed. 1454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 1455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Note that many of the 256 states give the 1456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Keysym, we just need one, and we take the 1457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * first one found. 1458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state = 0; 1460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(state < 256) { 1461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (XkbLookupKeySym(dpy, kc, state, &mods, 1462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat &ks2)) { 1463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* save these for workaround below */ 1465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (state_save == -1) { 1466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state_save = state; 1467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat mods_save = mods; 1468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks2 == ks) { 1470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * zero the irrelevant bits 1472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * by anding with mods. 1473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xkbstate[kc][grp][lvl] 1475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat = state & mods; 1476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * also remember the irrelevant 1478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * bits since it is handy. 1479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xkbignore[kc][grp][lvl] = mods; 1481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state++; 1486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (xkbstate[kc][grp][lvl] == (unsigned int) -1 1488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat && grp == 1) { 1489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Hack on Solaris 9 for Mode_switch 1491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * for Group2 characters. We force the 1492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Mode_switch modifier bit on. 1493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * XXX Need to figure out better what is 1494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * happening here. Is compat on somehow?? 1495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned int ms2; 1497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ms2 = XkbKeysymToModifiers(dpy, XK_Mode_switch); 1498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xkbstate[kc][grp][lvl] 1500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat = (state_save & mods_save) | ms2; 1501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xkbignore[kc][grp][lvl] = mods_save | ms2; 1503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 1506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str; 1507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " %03d G%d L%d mod=%s ", 1508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc, grp+1, lvl+1, bitprint(ms, 8)); 1509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, "state=%s ", 1510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bitprint(xkbstate[kc][grp][lvl], 8)); 1511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, "ignore=%s ", 1512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bitprint(xkbignore[kc][grp][lvl], 8)); 1513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = XKeysymToString(ks); 1514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " ks=0x%08lx \"%s\"\n", 1515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ks, str ? str : "null"); 1516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * kc_vec will be used in some places to find modifiers, etc 1523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * we apply some permutations to it as workarounds. 1524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (kc = 0; kc < 0x100; kc++) { 1526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc_vec[kc] = kc; 1527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_mode_switch != -1 && kc1_iso_level3_shift != -1) { 1530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc1_mode_switch < kc1_iso_level3_shift) { 1531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* we prefer XK_ISO_Level3_Shift: */ 1532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc_vec[kc1_mode_switch] = kc1_iso_level3_shift; 1533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc_vec[kc1_iso_level3_shift] = kc1_mode_switch; 1534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* any more? need to watch for undoing the above. */ 1537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * process the user supplied -skip_keycodes string. 1540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This is presumably a list if "ghost" keycodes, the X server 1541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * thinks they exist, but they do not. ghosts can lead to 1542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ambiguities in the reverse map: Keysym -> KeyCode + Modstate, 1543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * so if we can ignore them so much the better. Presumably the 1544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * user can never generate them from the physical keyboard. 1545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * There may be other reasons to deaden some keys. 1546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (skip_keycodes != NULL) { 1548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *p, *str = strdup(skip_keycodes); 1549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = strtok(str, ", \t\n\r"); 1550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (p) { 1551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k = 1; 1552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sscanf(p, "%d", &k) != 1 || k < 0 || k >= 0x100) { 1553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogEnable(1); 1554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("invalid skip_keycodes: %s %s\n", 1555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skip_keycodes, p); 1556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat clean_up_exit(1); 1557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skipkeycode[k] = 1; 1559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = strtok(NULL, ", \t\n\r"); 1560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(str); 1562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 1564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, "grp_max=%d lvl_max=%d\n", grp_max, lvl_max); 1565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic short **score_hint = NULL; 1569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 1570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Called on user keyboard input. Try to solve the reverse mapping 1571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * problem: KeySym (from VNC client) => KeyCode(s) to press to generate 1572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * it. The one-to-many KeySym => KeyCode mapping makes it difficult, as 1573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * does working out what changes to the modifier keypresses are needed. 1574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym, 1576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr client) { 1577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int kc, grp, lvl, i, kci; 1579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int kc_f[0x100], grp_f[0x100], lvl_f[0x100], state_f[0x100], found; 1580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int ignore_f[0x100]; 1581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned int state = 0; 1582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* these are used for finding modifiers, etc */ 1585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XkbStateRec kbstate; 1586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int got_kbstate = 0; 1587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int Kc_f, Grp_f = 0, Lvl_f = 0; 1588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat# define KLAST 10 1589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static int Kc_last_down[KLAST]; 1590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static KeySym Ks_last_down[KLAST]; 1591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static int klast = 0, khints = 1, anydown = 1; 1592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static int cnt = 0; 1593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!client || !down || !keysym) {} /* unused vars warning: */ 1595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 1597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 1599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (klast == 0) { 1601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, j; 1602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<KLAST; i++) { 1603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_last_down[i] = -1; 1604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Ks_last_down[i] = NoSymbol; 1605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (getenv("NOKEYHINTS")) { 1607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat khints = 0; 1608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (getenv("NOANYDOWN")) { 1610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat anydown = 0; 1611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (getenv("KEYSDOWN")) { 1613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat klast = atoi(getenv("KEYSDOWN")); 1614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (klast < 1) klast = 1; 1615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (klast > KLAST) klast = KLAST; 1616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 1617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat klast = 3; 1618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (khints && score_hint == NULL) { 1620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat score_hint = (short **) malloc(0x100 * sizeof(short *)); 1621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<0x100; i++) { 1622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat score_hint[i] = (short *) malloc(0x100 * sizeof(short)); 1623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<0x100; i++) { 1626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j=0; j<0x100; j++) { 1627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat score_hint[i][j] = -1; 1628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cnt++; 1633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cnt % 100 && khints && score_hint != NULL) { 1634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, j; 1635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<0x100; i++) { 1636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j=0; j<0x100; j++) { 1637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat score_hint[i][j] = -1; 1638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 1643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str = XKeysymToString(keysym); 1644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard > 1) { 1646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("----------start-xkb_tweak_keyboard (%s) " 1647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "--------\n", down ? "DOWN" : "UP"); 1648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("xkb_tweak_keyboard: %s keysym=0x%x \"%s\"\n", 1651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat down ? "down" : "up", (int) keysym, str ? str : "null"); 1652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * set everything to not-yet-found. 1656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * these "found" arrays (*_f) let us dynamically consider the 1657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * one-to-many Keysym -> Keycode issue. we set the size at 256, 1658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * but of course only very few will be found. 1659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 0x100; i++) { 1661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc_f[i] = -1; 1662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat grp_f[i] = -1; 1663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lvl_f[i] = -1; 1664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state_f[i] = -1; 1665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ignore_f[i] = -1; 1666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat found = 0; 1668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * loop over all (keycode, group, level) triples looking for 1671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * matching keysyms. Amazingly this isn't slow (but maybe if 1672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * you type really fast...). Hash lookup into a linked list of 1673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * (keycode,grp,lvl) triples would be the way to improve this 1674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * in the future if needed. 1675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (kc = kc_min; kc <= kc_max; kc++) { 1677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (grp = 0; grp < grp_max+1; grp++) { 1678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (lvl = 0; lvl < lvl_max+1; lvl++) { 1679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym != xkbkeysyms[kc][grp][lvl]) { 1680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* got a keysym match */ 1683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state = xkbstate[kc][grp][lvl]; 1684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard > 1) { 1686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *s1, *s2; 1687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat s1 = XKeysymToString(XKeycodeToKeysym(dpy, 1688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc, 0)); 1689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! s1) s1 = "null"; 1690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat s2 = XKeysymToString(keysym); 1691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! s2) s2 = "null"; 1692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " got match kc=%03d=0x%02x G%d" 1693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat " L%d ks=0x%x \"%s\" (basesym: \"%s\")\n", 1694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc, kc, grp+1, lvl+1, keysym, s2, s1); 1695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " need state: %s\n", 1696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bitprint(state, 8)); 1697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " ignorable : %s\n", 1698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bitprint(xkbignore[kc][grp][lvl], 8)); 1699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* save it if state is OK and not told to skip */ 1702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (state == (unsigned int) -1) { 1703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (skipkeycode[kc] && debug_keyboard) { 1706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " xxx skipping keycode: %d " 1707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "G%d/L%d\n", kc, grp+1, lvl+1); 1708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (skipkeycode[kc]) { 1710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (found > 0 && kc == kc_f[found-1]) { 1713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* ignore repeats for same keycode */ 1714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc_f[found] = kc; 1717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat grp_f[found] = grp; 1718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lvl_f[found] = lvl; 1719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state_f[found] = state; 1720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ignore_f[found] = xkbignore[kc][grp][lvl]; 1721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat found++; 1722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define PKBSTATE \ 1727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " --- current mod state:\n"); \ 1728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " mods : %s\n", bitprint(kbstate.mods, 8)); \ 1729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " base_mods : %s\n", bitprint(kbstate.base_mods, 8)); \ 1730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " latch_mods: %s\n", bitprint(kbstate.latched_mods, 8)); \ 1731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " lock_mods : %s\n", bitprint(kbstate.locked_mods, 8)); \ 1732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " compat : %s\n", bitprint(kbstate.compat_state, 8)); 1733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Now get the current state of the keyboard from the X server. 1736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This seems to be the safest way to go as opposed to our 1737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * keeping track of the modifier state on our own. Again, 1738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * this is fortunately not too slow. 1739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard > 1) { 1742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* get state early for debug output */ 1743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XkbGetState(dpy, XkbUseCoreKbd, &kbstate); 1744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat got_kbstate = 1; 1745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat PKBSTATE 1746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!found && add_keysyms && keysym && ! IsModifierKey(keysym)) { 1749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int new_kc = add_keysym(keysym); 1750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (new_kc != 0) { 1751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat found = 1; 1752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc_f[0] = new_kc; 1753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat grp_f[0] = 0; 1754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lvl_f[0] = 0; 1755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state_f[0] = 0; 1756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!found && debug_keyboard) { 1760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str = XKeysymToString(keysym); 1761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " *** NO key found for: 0x%x %s " 1762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "*keystroke ignored*\n", keysym, str ? str : "null"); 1763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!found) { 1765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 1766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 1767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * we try to optimize here if found > 1 1771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * e.g. minimize lvl or grp, or other things to give 1772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * "safest" scenario to simulate the keystrokes. 1773a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1774a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (found > 1) { 1776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (down) { 1777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int l, score[0x100]; 1778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int best = 0, best_score = -1; 1779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* need to break the tie... */ 1780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! got_kbstate) { 1781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XkbGetState(dpy, XkbUseCoreKbd, &kbstate); 1782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat got_kbstate = 1; 1783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (khints && keysym < 0x100) { 1785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int ks = (int) keysym, j; 1786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j=0; j< 0x100; j++) { 1787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat score_hint[ks][j] = -1; 1788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (l=0; l < found; l++) { 1791a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int myscore = 0, b = 0x1, i; 1792a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int curr, curr_state = kbstate.mods; 1793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int need, need_state = state_f[l]; 1794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int ignore_state = ignore_f[l]; 1795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* see how many modifiers need to be changed */ 1797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<8; i++) { 1798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat curr = b & curr_state; 1799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat need = b & need_state; 1800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! (b & ignore_state)) { 1801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ; 1802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (curr == need) { 1803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ; 1804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 1805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat myscore++; 1806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat b = b << 1; 1808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat myscore *= 100; 1810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* throw in some minimization of lvl too: */ 1812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat myscore += 2*lvl_f[l] + grp_f[l]; 1813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * XXX since we now internally track 1816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * keycode_state[], we could throw that into 1817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the score as well. I.e. if it is already 1818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * down, it is pointless to think we can 1819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * press it down further! E.g. 1820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * myscore += 1000 * keycode_state[kc_f[l]]; 1821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Also could watch multiple modifier 1822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * problem, e.g. Shift+key -> Alt 1823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * keycode = 125 on my keyboard. 1824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat score[l] = myscore; 1827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard > 1) { 1828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " *** score for " 1829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "keycode %03d: %4d\n", 1830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc_f[l], myscore); 1831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (khints && keysym < 0x100 && kc_f[l] < 0x100) { 1833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat score_hint[(int) keysym][kc_f[l]] = (short) score[l]; 1834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (l=0; l < found; l++) { 1837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int myscore = score[l]; 1838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (best_score == -1 || myscore < best_score) { 1839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat best = l; 1840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat best_score = myscore; 1841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1842a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1843a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_f = kc_f[best]; 1844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Grp_f = grp_f[best]; 1845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Lvl_f = lvl_f[best]; 1846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state = state_f[best]; 1847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 1849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* up */ 1850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, Kc_loc = -1; 1851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_f = -1; 1852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* first try the scores we remembered when the key went down: */ 1854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (khints && keysym < 0x100) { 1855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* low keysyms, ascii, only */ 1856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int ks = (int) keysym; 1857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int ok = 1, lbest = 0, l; 1858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat short sbest = -1; 1859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (l=0; l < found; l++) { 1860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (kc_f[l] < 0x100) { 1861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int key = (int) kc_f[l]; 1862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! keycode_state[key]) { 1863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (score_hint[ks][key] < 0) { 1866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ok = 0; 1867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sbest < 0 || score_hint[ks][key] < sbest) { 1870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sbest = score_hint[ks][key]; 1871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lbest = l; 1872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 1874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ok = 0; 1875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ok && sbest != -1) { 1879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_f = kc_f[lbest]; 1880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard && Kc_f != -1) { 1882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " UP: found via score_hint, s/l=%d/%d\n", 1883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sbest, lbest); 1884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* next look at our list of recently pressed down keys */ 1888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (Kc_f == -1) { 1889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=klast-1; i>=0; i--) { 1890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * some people type really fast and leave 1892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * lots of keys down before releasing 1893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * them. this gives problem on weird 1894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * qwerty+dvorak keymappings where each 1895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * alpha character is on TWO keys. 1896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == Ks_last_down[i]) { 1898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int l; 1899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (l=0; l < found; l++) { 1900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (Kc_last_down[i] == kc_f[l]) { 1901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int key = (int) kc_f[l]; 1902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keycode_state[key]) { 1903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_f = Kc_last_down[i]; 1904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_loc = i; 1905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (Kc_f != -1) { 1911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard && Kc_f != -1) { 1915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " UP: found via klast, i=%d\n", Kc_loc); 1916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* next just check for "best" one that is down */ 1920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (Kc_f == -1 && anydown) { 1921a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int l; 1922a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int best = -1, lbest = 0; 1923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * If it is already down, that is 1925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * a great hint. Use it. 1926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 1927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * note: keycode_state is internal and 1928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ignores someone pressing keys on the 1929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * physical display (but is updated 1930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * periodically to clean out stale info). 1931a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1932a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (l=0; l < found; l++) { 1933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int key = (int) kc_f[l]; 1934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int j, jmatch = -1; 1935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! keycode_state[key]) { 1937a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1938a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1939a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* break ties based on lowest XKeycodeToKeysym index */ 1940a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j=0; j<8; j++) { 1941a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym ks = XKeycodeToKeysym(dpy, kc_f[l], j); 1942a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks != NoSymbol && ks == keysym) { 1943a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat jmatch = j; 1944a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1945a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1946a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1947a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (jmatch == -1) { 1948a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 1949a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1950a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (best == -1 || jmatch < best) { 1951a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat best = jmatch; 1952a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lbest = l; 1953a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1954a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1955a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (best != -1) { 1956a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_f = kc_f[lbest]; 1957a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1958a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard && Kc_f != -1) { 1959a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " UP: found via downlist, l=%d\n", lbest); 1960a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1961a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1962a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1963a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* next, use the first one found that is down */ 1964a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (Kc_f == -1) { 1965a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int l; 1966a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (l=0; l < found; l++) { 1967a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int key = (int) kc_f[l]; 1968a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keycode_state[key]) { 1969a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_f = kc_f[l]; 1970a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1971a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1972a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1973a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard && Kc_f != -1) { 1974a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " UP: set to first one down, kc_f[%d]!!\n", l); 1975a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1976a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1977a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1978a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* last, use the first one found */ 1979a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (Kc_f == -1) { 1980a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* hope for the best... XXX check mods */ 1981a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_f = kc_f[0]; 1982a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard && Kc_f != -1) { 1983a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " UP: set to first one at all, kc_f[0]!!\n"); 1984a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1985a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1986a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1987a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 1988a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_f = kc_f[0]; 1989a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Grp_f = grp_f[0]; 1990a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Lvl_f = lvl_f[0]; 1991a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state = state_f[0]; 1992a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1993a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1994a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard && found > 1) { 1995a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int l; 1996a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str; 1997a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " *** found more than one keycode: "); 1998a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (l = 0; l < found; l++) { 1999a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, "%03d ", kc_f[l]); 2000a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2001a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (l = 0; l < found; l++) { 2002a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = XKeysymToString(XKeycodeToKeysym(dpy,kc_f[l],0)); 2003a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " \"%s\"", str ? str : "null"); 2004a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2005a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, ", picked this one: %03d (last down: %03d)\n", 2006a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_f, Kc_last_down[0]); 2007a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2008a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2009a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sloppy_keys) { 2010a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int new_kc; 2011a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sloppy_key_check(Kc_f, down, keysym, &new_kc)) { 2012a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_f = new_kc; 2013a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2014a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2015a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2016a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (down) { 2017a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2018a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * need to set up the mods for tweaking and other workarounds 2019a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2020a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int needmods[8], sentmods[8], Ilist[8], keystate[256]; 2021a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int involves_multi_key, shift_is_down; 2022a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, j, b, curr, need; 2023a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned int ms; 2024a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym ks; 2025a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Bool dn; 2026a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2027a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* remember these to aid the subsequent up case: */ 2028a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=KLAST-1; i >= 1; i--) { 2029a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Ks_last_down[i] = Ks_last_down[i-1]; 2030a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_last_down[i] = Kc_last_down[i-1]; 2031a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2032a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Ks_last_down[0] = keysym; 2033a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Kc_last_down[0] = Kc_f; 2034a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2035a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! got_kbstate) { 2036a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* get the current modifier state if we haven't yet */ 2037a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XkbGetState(dpy, XkbUseCoreKbd, &kbstate); 2038a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat got_kbstate = 1; 2039a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2040a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2041a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2042a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * needmods[] whether or not that modifier bit needs 2043a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * something done to it. 2044a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * < 0 means no, 2045a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 0 means needs to go up. 2046a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 1 means needs to go down. 2047a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 2048a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * -1, -2, -3 are used for debugging info to indicate 2049a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * why nothing needs to be done with the modifier, see below. 2050a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 2051a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * sentmods[] is the corresponding keycode to use 2052a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * to achieve the needmods[] requirement for the bit. 2053a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2054a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2055a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<8; i++) { 2056a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat needmods[i] = -1; 2057a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sentmods[i] = 0; 2058a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2059a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2060a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2061a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Loop over the 8 modifier bits and check if the current 2062a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * setting is what we need it to be or whether it should 2063a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * be changed (by us sending some keycode event) 2064a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 2065a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * If nothing needs to be done to it record why: 2066a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * -1 the modifier bit is ignored. 2067a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * -2 the modifier bit is ignored, but is correct anyway. 2068a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * -3 the modifier bit is correct. 2069a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2070a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2071a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat b = 0x1; 2072a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<8; i++) { 2073a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat curr = b & kbstate.mods; 2074a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat need = b & state; 2075a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2076a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! (b & xkbignore[Kc_f][Grp_f][Lvl_f])) { 2077a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* irrelevant modifier bit */ 2078a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat needmods[i] = -1; 2079a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (curr == need) needmods[i] = -2; 2080a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (curr == need) { 2081a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* already correct */ 2082a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat needmods[i] = -3; 2083a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (! curr && need) { 2084a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* need it down */ 2085a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat needmods[i] = 1; 2086a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (curr && ! need) { 2087a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* need it up */ 2088a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat needmods[i] = 0; 2089a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2090a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2091a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat b = b << 1; 2092a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2093a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2094a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2095a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Again we dynamically probe the X server for information, 2096a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * this time for the state of all the keycodes. Useful 2097a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * info, and evidently is not too slow... 2098a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2099a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat get_keystate(keystate); 2100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * We try to determine if Shift is down (since that can 2103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * screw up ISO_Level3_Shift manipulations). 2104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat shift_is_down = 0; 2106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (kc = kc_min; kc <= kc_max; kc++) { 2108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (skipkeycode[kc] && debug_keyboard) { 2109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " xxx skipping keycode: " 2110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%d\n", kc); 2111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (skipkeycode[kc]) { 2113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 2114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (shift_keys[kc] && keystate[kc]) { 2116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat shift_is_down = kc; 2117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Now loop over the modifier bits and try to deduce the 2123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * keycode presses/release require to match the desired 2124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * state. 2125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<8; i++) { 2127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (needmods[i] < 0 && debug_keyboard > 1) { 2128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int k = -needmods[i] - 1; 2129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *words[] = {"ignorable", 2130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "bitset+ignorable", "bitset"}; 2131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " +++ needmods: mod=%d is " 2132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "OK (%s)\n", i, words[k]); 2133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (needmods[i] < 0) { 2135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 2136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat b = 1 << i; 2139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard > 1) { 2141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " +++ needmods: mod=%d %s " 2142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "need it to be: %d %s\n", i, bitprint(b, 8), 2143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat needmods[i], needmods[i] ? "down" : "up"); 2144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Again, an inefficient loop, this time just 2148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * looking for modifiers... 2149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 2150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * note the use of kc_vec to prefer XK_ISO_Level3_Shift 2151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * over XK_Mode_switch. 2152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (kci = kc_min; kci <= kc_max; kci++) { 2154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (grp = 0; grp < grp_max+1; grp++) { 2155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (lvl = 0; lvl < lvl_max+1; lvl++) { 2156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int skip = 1, dbmsg = 0; 2157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc = kc_vec[kci]; 2159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ms = xkbmodifiers[kc][grp][lvl]; 2161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! ms || ms != (unsigned int) b) { 2162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 2163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (skipkeycode[kc] && debug_keyboard) { 2166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " xxx skipping keycode:" 2167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat " %d G%d/L%d\n", kc, grp+1, lvl+1); 2168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (skipkeycode[kc]) { 2170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 2171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ks = xkbkeysyms[kc][grp][lvl]; 2174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! ks) { 2175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 2176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Shift_L) { 2179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skip = 0; 2180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (ks == XK_Shift_R) { 2181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skip = 0; 2182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (ks == XK_Mode_switch) { 2183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skip = 0; 2184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (ks == XK_ISO_Level3_Shift) { 2185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skip = 0; 2186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (watch_capslock && kbstate.locked_mods & LockMask) { 2189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym >= 'A' && keysym <= 'Z') { 2190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ks == XK_Shift_L || ks == XK_Shift_R) { 2191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard > 1) { 2192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " A-Z caplock skip Shift\n"); 2193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skip = 1; 2195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (ks == XK_Caps_Lock) { 2196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard > 1) { 2197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " A-Z caplock noskip CapsLock\n"); 2198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skip = 0; 2200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Alt, Meta, Control, Super, 2205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Hyper, Num, Caps are skipped. 2206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 2207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * XXX need more work on Locks, 2208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and non-standard modifiers. 2209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * (e.g. XF86_Next_VMode using 2210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Ctrl+Alt) 2211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard > 1) { 2213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str = XKeysymToString(ks); 2214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int kt = keystate[kc]; 2215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " === for mod=%s " 2216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "found kc=%03d/G%d/L%d it is %d " 2217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%s skip=%d (%s)\n", bitprint(b,8), 2218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat kc, grp+1, lvl+1, kt, kt ? 2219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "down" : "up ", skip, str ? 2220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str : "null"); 2221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! skip && needmods[i] != 2224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keystate[kc] && sentmods[i] == 0) { 2225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sentmods[i] = kc; 2226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dbmsg = 1; 2227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard > 1 && dbmsg) { 2230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int nm = needmods[i]; 2231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " >>> we choose " 2232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "kc=%03d=0x%02x to change it to: " 2233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%d %s\n", kc, kc, nm, nm ? 2234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "down" : "up"); 2235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<8; i++) { 2242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * reverse order is useful for tweaking 2244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ISO_Level3_Shift before Shift, but assumes they 2245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * are in that order (i.e. Shift is first bit). 2246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int reverse = 1; 2248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (reverse) { 2249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Ilist[i] = 7 - i; 2250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Ilist[i] = i; 2252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * check to see if Multi_key is bound to one of the Mods 2257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * we have to tweak 2258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat involves_multi_key = 0; 2260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j=0; j<8; j++) { 2261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i = Ilist[j]; 2262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sentmods[i] == 0) continue; 2263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dn = (Bool) needmods[i]; 2264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!dn) continue; 2265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (multi_key[sentmods[i]]) { 2266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat involves_multi_key = i+1; 2267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (involves_multi_key && shift_is_down && needmods[0] < 0) { 2271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Workaround for Multi_key and shift. 2273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Assumes Shift is bit 1 (needmods[0]) 2274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 2276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " ^^^ trying to avoid " 2277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "inadvertent Multi_key from Shift " 2278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "(doing %03d up now)\n", shift_is_down); 2279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, shift_is_down, False, 2281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat CurrentTime); 2282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat involves_multi_key = 0; 2284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j=0; j<8; j++) { 2287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* do the Mod ups */ 2288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i = Ilist[j]; 2289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sentmods[i] == 0) continue; 2290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dn = (Bool) needmods[i]; 2291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (dn) continue; 2292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, sentmods[i], dn, CurrentTime); 2293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j=0; j<8; j++) { 2295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* next, do the Mod downs */ 2296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i = Ilist[j]; 2297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sentmods[i] == 0) continue; 2298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dn = (Bool) needmods[i]; 2299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!dn) continue; 2300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, sentmods[i], dn, CurrentTime); 2301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (involves_multi_key) { 2304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Reverse workaround for Multi_key and shift. 2306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 2308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " vvv trying to avoid " 2309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "inadvertent Multi_key from Shift " 2310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "(doing %03d down now)\n", shift_is_down); 2311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, shift_is_down, True, 2313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat CurrentTime); 2314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * With the above modifier work done, send the actual keycode: 2318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, Kc_f, (Bool) down, CurrentTime); 2320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Now undo the modifier work: 2323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j=7; j>=0; j--) { 2325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* reverse Mod downs we did */ 2326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i = Ilist[j]; 2327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sentmods[i] == 0) continue; 2328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dn = (Bool) needmods[i]; 2329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!dn) continue; 2330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, sentmods[i], !dn, 2331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat CurrentTime); 2332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j=7; j>=0; j--) { 2334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* finally reverse the Mod ups we did */ 2335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i = Ilist[j]; 2336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sentmods[i] == 0) continue; 2337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dn = (Bool) needmods[i]; 2338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (dn) continue; 2339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, sentmods[i], !dn, 2340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat CurrentTime); 2341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { /* for up case, hopefully just need to pop it up: */ 2344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, Kc_f, (Bool) down, CurrentTime); 2346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 2348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 2349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 2352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * For tweaking modifiers wrt the Alt-Graph key, etc. 2353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define LEFTSHIFT 1 2355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define RIGHTSHIFT 2 2356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define ALTGR 4 2357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char mod_state = 0; 2358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic char modifiers[0x100]; 2360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic KeyCode keycodes[0x100]; 2361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic KeyCode left_shift_code, right_shift_code, altgr_code, iso_level3_code; 2362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* workaround for X11R5, Latin 1 only */ 2364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef XConvertCase 2365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define XConvertCase(sym, lower, upper) \ 2366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat*(lower) = sym; \ 2367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat*(upper) = sym; \ 2368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (sym >> 8 == 0) { \ 2369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((sym >= XK_A) && (sym <= XK_Z)) \ 2370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *(lower) += (XK_a - XK_A); \ 2371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if ((sym >= XK_a) && (sym <= XK_z)) \ 2372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *(upper) -= (XK_a - XK_A); \ 2373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) \ 2374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *(lower) += (XK_agrave - XK_Agrave); \ 2375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) \ 2376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *(upper) -= (XK_agrave - XK_Agrave); \ 2377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) \ 2378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *(lower) += (XK_oslash - XK_Ooblique); \ 2379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if ((sym >= XK_oslash) && (sym <= XK_thorn)) \ 2380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *(upper) -= (XK_oslash - XK_Ooblique); \ 2381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 2382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *short_kmbcf(char *str) { 2385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, saw_k = 0, saw_m = 0, saw_b = 0, saw_c = 0, saw_f = 0, n = 10; 2386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *p, tmp[10]; 2387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<n; i++) { 2389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tmp[i] = '\0'; 2390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = str; 2393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i = 0; 2394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (*p) { 2395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((*p == 'K' || *p == 'k') && !saw_k) { 2396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tmp[i++] = 'K'; 2397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saw_k = 1; 2398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if ((*p == 'M' || *p == 'm') && !saw_m) { 2399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tmp[i++] = 'M'; 2400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saw_m = 1; 2401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if ((*p == 'B' || *p == 'b') && !saw_b) { 2402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tmp[i++] = 'B'; 2403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saw_b = 1; 2404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if ((*p == 'C' || *p == 'c') && !saw_c) { 2405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tmp[i++] = 'C'; 2406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saw_c = 1; 2407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if ((*p == 'F' || *p == 'f') && !saw_f) { 2408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tmp[i++] = 'F'; 2409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat saw_f = 1; 2410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p++; 2412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return(strdup(tmp)); 2414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 2415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid initialize_allowed_input(void) { 2417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str; 2418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (allowed_input_normal) { 2420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(allowed_input_normal); 2421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_normal = NULL; 2422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (allowed_input_view_only) { 2424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(allowed_input_view_only); 2425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_view_only = NULL; 2426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! allowed_input_str) { 2429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_normal = strdup("KMBCF"); 2430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_view_only = strdup(""); 2431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *p, *str = strdup(allowed_input_str); 2433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = strchr(str, ','); 2434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (p) { 2435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_view_only = strdup(p+1); 2436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *p = '\0'; 2437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_normal = strdup(str); 2438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_normal = strdup(str); 2440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_view_only = strdup(""); 2441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(str); 2443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* shorten them */ 2446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = short_kmbcf(allowed_input_normal); 2447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(allowed_input_normal); 2448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_normal = str; 2449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = short_kmbcf(allowed_input_view_only); 2451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(allowed_input_view_only); 2452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_view_only = str; 2453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (screen) { 2455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientIteratorPtr iter; 2456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr cl; 2457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat iter = rfbGetClientIterator(screen); 2459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while( (cl = rfbClientIteratorNext(iter)) ) { 2460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ClientData *cd = (ClientData *) cl->clientData; 2461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! cd) { 2463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 2464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if 0 2466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbLog("cd: %p\n", cd); 2467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbLog("cd->input: %s\n", cd->input); 2468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbLog("cd->login_viewonly: %d\n", cd->login_viewonly); 2469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbLog("allowed_input_view_only: %s\n", allowed_input_view_only); 2470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cd->input[0] == '=') { 2473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ; /* custom setting */ 2474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (cd->login_viewonly) { 2475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (*allowed_input_view_only != '\0') { 2476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->viewOnly = FALSE; 2477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cd->input[0] = '\0'; 2478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strncpy(cd->input, 2479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_view_only, CILEN); 2480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->viewOnly = TRUE; 2482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (allowed_input_normal) { 2485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cd->input[0] = '\0'; 2486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strncpy(cd->input, 2487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_normal, CILEN); 2488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbReleaseClientIterator(iter); 2492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 2494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid initialize_modtweak(void) { 2496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11 2497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 2498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 2500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym keysym, *keymap; 2501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, j, minkey, maxkey, syms_per_keycode; 2502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int use_lowest_index = 0; 2503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (use_xkb_modtweak) { 2505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat initialize_xkb_modtweak(); 2506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memset(modifiers, -1, sizeof(modifiers)); 2509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<0x100; i++) { 2510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keycodes[i] = NoSymbol; 2511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 2514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (getenv("MODTWEAK_LOWEST")) { 2516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat use_lowest_index = 1; 2517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 2520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XDisplayKeycodes(dpy, &minkey, &maxkey); 2521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1), 2523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat &syms_per_keycode); 2524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* handle alphabetic char with only one keysym (no upper + lower) */ 2526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = minkey; i <= maxkey; i++) { 2527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym lower, upper; 2528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2nd one */ 2529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = keymap[(i - minkey) * syms_per_keycode + 1]; 2530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym != NoSymbol) { 2531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 2532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1st one */ 2534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = keymap[(i - minkey) * syms_per_keycode + 0]; 2535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == NoSymbol) { 2536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 2537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XConvertCase(keysym, &lower, &upper); 2539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (lower != upper) { 2540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keymap[(i - minkey) * syms_per_keycode + 0] = lower; 2541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keymap[(i - minkey) * syms_per_keycode + 1] = upper; 2542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = minkey; i <= maxkey; i++) { 2545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 2546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (i == minkey) { 2547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("initialize_modtweak: keycode -> " 2548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "keysyms mapping info:\n"); 2549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, " %03d ", i); 2551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (j = 0; j < syms_per_keycode; j++) { 2553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 2554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *sym; 2555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if 0 2556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sym =XKeysymToString(XKeycodeToKeysym(dpy,i,j)); 2557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 2558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = keymap[(i-minkey)*syms_per_keycode+j]; 2559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sym = XKeysymToString(keysym); 2560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, "%-18s ", sym ? sym : "null"); 2562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (j == syms_per_keycode - 1) { 2563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr, "\n"); 2564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (j >= 4) { 2567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Something wacky in the keymapping. 2569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Ignore these non Shift/AltGr chords 2570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * for now... n.b. we try to automatically 2571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * switch to -xkb for this case. 2572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 2574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = keymap[ (i - minkey) * syms_per_keycode + j ]; 2576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( keysym >= ' ' && keysym < 0x100 2577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat && i == XKeysymToKeycode(dpy, keysym) ) { 2578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (use_lowest_index && keycodes[keysym] != NoSymbol) { 2579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 2580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keycodes[keysym] = i; 2582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat modifiers[keysym] = j; 2583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat left_shift_code = XKeysymToKeycode(dpy, XK_Shift_L); 2588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat right_shift_code = XKeysymToKeycode(dpy, XK_Shift_R); 2589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat altgr_code = XKeysymToKeycode(dpy, XK_Mode_switch); 2590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat iso_level3_code = NoSymbol; 2591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef XK_ISO_Level3_Shift 2592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat iso_level3_code = XKeysymToKeycode(dpy, XK_ISO_Level3_Shift); 2593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFree_wr ((void *) keymap); 2596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 2598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif /* NO_X11 */ 2599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 2600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 2602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * does the actual tweak: 2603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void tweak_mod(signed char mod, rfbBool down) { 2605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool is_shift = mod_state & (LEFTSHIFT|RIGHTSHIFT); 2606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Bool dn = (Bool) down; 2607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeyCode altgr = altgr_code; 2608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 2610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (mod < 0) { 2612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 2613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("tweak_mod: Skip: down=%d index=%d\n", down, 2614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (int) mod); 2615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 2619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("tweak_mod: Start: down=%d index=%d mod_state=0x%x" 2620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat " is_shift=%d\n", down, (int) mod, (int) mod_state, 2621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat is_shift); 2622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (use_iso_level3 && iso_level3_code) { 2625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat altgr = iso_level3_code; 2626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 2629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (is_shift && mod != 1) { 2630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (mod_state & LEFTSHIFT) { 2631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, left_shift_code, !dn, CurrentTime); 2632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (mod_state & RIGHTSHIFT) { 2634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, right_shift_code, !dn, CurrentTime); 2635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( ! is_shift && mod == 1 ) { 2638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, left_shift_code, dn, CurrentTime); 2639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( altgr && (mod_state & ALTGR) && mod != 2 ) { 2641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, altgr, !dn, CurrentTime); 2642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( altgr && ! (mod_state & ALTGR) && mod == 2 ) { 2644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, altgr, dn, CurrentTime); 2645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 2647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 2649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("tweak_mod: Finish: down=%d index=%d mod_state=0x%x" 2650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat " is_shift=%d\n", down, (int) mod, (int) mod_state, 2651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat is_shift); 2652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 2654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 2656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * tweak the modifier under -modtweak 2657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void modifier_tweak_keyboard(rfbBool down, rfbKeySym keysym, 2659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr client) { 2660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11 2661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 2662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!down || !keysym || !client) {} 2663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 2665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeyCode k; 2666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int tweak = 0; 2667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 2669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (use_xkb_modtweak) { 2671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xkb_tweak_keyboard(down, keysym, client); 2672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 2675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("modifier_tweak_keyboard: %s keysym=0x%x\n", 2676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat down ? "down" : "up", (int) keysym); 2677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define ADJUSTMOD(sym, state) \ 2680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == sym) { \ 2681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (down) { \ 2682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat mod_state |= state; \ 2683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { \ 2684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat mod_state &= ~state; \ 2685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } \ 2686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ADJUSTMOD(XK_Shift_L, LEFTSHIFT) 2689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ADJUSTMOD(XK_Shift_R, RIGHTSHIFT) 2690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ADJUSTMOD(XK_Mode_switch, ALTGR) 2691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( down && keysym >= ' ' && keysym < 0x100 ) { 2693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned int state = 0; 2694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tweak = 1; 2695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (watch_capslock && keysym >= 'A' && keysym <= 'Z') { 2696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 2697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat state = mask_state(); 2698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 2699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (state & LockMask) { 2701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* capslock set for A-Z, so no tweak */ 2702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 2703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k = XKeysymToKeycode(dpy, (KeySym) keysym); 2704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 2705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tweak = 0; 2706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tweak_mod(modifiers[keysym], True); 2708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k = keycodes[keysym]; 2709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 2712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k = XKeysymToKeycode(dpy, (KeySym) keysym); 2713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 2714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (k == NoSymbol && add_keysyms && ! IsModifierKey(keysym)) { 2716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int new_kc = add_keysym(keysym); 2717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (new_kc) { 2718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k = new_kc; 2719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sloppy_keys) { 2723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int new_kc; 2724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sloppy_key_check((int) k, down, keysym, &new_kc)) { 2725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k = (KeyCode) new_kc; 2726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 2730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str = XKeysymToString(keysym); 2731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("modifier_tweak_keyboard: KeySym 0x%x \"%s\" -> " 2732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "KeyCode 0x%x%s\n", (int) keysym, str ? str : "null", 2733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (int) k, k ? "" : " *ignored*"); 2734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( k != NoSymbol ) { 2736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 2737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, k, (Bool) down, CurrentTime); 2738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 2739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( tweak ) { 2742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tweak_mod(modifiers[keysym], False); 2743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif /* NO_X11 */ 2745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 2746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid initialize_keyboard_and_pointer(void) { 2748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef MACOSX 2750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (macosx_console) { 2751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat initialize_remap(remap_file); 2752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat initialize_pointer_map(pointer_remap); 2753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 2757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (use_modifier_tweak) { 2759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat initialize_modtweak(); 2760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat initialize_remap(remap_file); 2763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat initialize_pointer_map(pointer_remap); 2764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 2766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat clear_modifiers(1); 2767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (clear_mods == 1) { 2768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat clear_modifiers(0); 2769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (clear_mods == 3) { 2771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat clear_locks(); 2772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2773a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 2774a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 2775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid get_allowed_input(rfbClientPtr client, allowed_input_t *input) { 2777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ClientData *cd; 2778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str; 2779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->keystroke = 0; 2781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->motion = 0; 2782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->button = 0; 2783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->clipboard = 0; 2784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->files = 0; 2785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! client) { 2787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->keystroke = 1; 2788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->motion = 1; 2789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->button = 1; 2790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->clipboard = 1; 2791a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->files = 1; 2792a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cd = (ClientData *) client->clientData; 2796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! cd) { 2798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cd->input[0] != '-') { 2802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = cd->input; 2803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (client->viewOnly) { 2804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (allowed_input_view_only) { 2805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = allowed_input_view_only; 2806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = ""; 2808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (allowed_input_normal) { 2811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = allowed_input_normal; 2812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = "KMBCF"; 2814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (0) fprintf(stderr, "GAI: %s - %s\n", str, cd->input); 2817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (*str) { 2819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (*str == 'K') { 2820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->keystroke = 1; 2821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (*str == 'M') { 2822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->motion = 1; 2823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (*str == 'B') { 2824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->button = 1; 2825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (*str == 'C') { 2826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->clipboard = 1; 2827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (*str == 'F') { 2828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat input->files = 1; 2829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str++; 2831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 2833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void apply_remap(rfbKeySym *keysym, int *isbutton) { 2835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keyremaps) { 2836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keyremap_t *remap = keyremaps; 2837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (remap != NULL) { 2838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (remap->before == *keysym) { 2839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *keysym = remap->after; 2840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *isbutton = remap->isbutton; 2841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 2842a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str1, *str2; 2843a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 2844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str1 = XKeysymToString(remap->before); 2845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str2 = XKeysymToString(remap->after); 2846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("keyboard(): remapping keysym: " 2847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "0x%x \"%s\" -> 0x%x \"%s\"\n", 2848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (int) remap->before, 2849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str1 ? str1 : "null", 2850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (int) remap->after, 2851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat remap->isbutton ? "button" : 2852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str2 ? str2 : "null"); 2853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 2854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat remap = remap->next; 2858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 2861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* for -pipeinput mode */ 2863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) { 2864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int can_input = 0, uid = 0, isbutton = 0; 2865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_t input; 2866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *name; 2867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ClientData *cd = (ClientData *) client->clientData; 2868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat apply_remap(&keysym, &isbutton); 2870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (isbutton) { 2872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int mask, button = (int) keysym; 2873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x = cursor_x, y = cursor_y; 2874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *b, bstr[32]; 2875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!down) { 2877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 2880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("keyboard(): remapping keystroke to button %d" 2881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat " click\n", button); 2882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dtime0(&last_key_to_button_remap_time); 2884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This in principle can be a little dicey... i.e. even 2887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * remap the button click to keystroke sequences! 2888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Usually just will simulate the button click. 2889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* loop over possible multiclicks: Button123 */ 2892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sprintf(bstr, "%d", button); 2893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat b = bstr; 2894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (*b != '\0') { 2895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char t[2]; 2896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int butt; 2897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat t[0] = *b; 2898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat t[1] = '\0'; 2899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sscanf(t, "%d", &butt) == 1) { 2900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat mask = 1<<(butt-1); 2901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat pointer_event(mask, x, y, client); 2902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat mask = 0; 2903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat pointer_event(mask, x, y, client); 2904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat b++; 2906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (pipeinput_int == PIPEINPUT_VID) { 2911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat v4l_key_command(down, keysym, client); 2912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (pipeinput_int == PIPEINPUT_CONSOLE) { 2913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat console_key_command(down, keysym, client); 2914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (pipeinput_int == PIPEINPUT_UINPUT) { 2915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uinput_key_command(down, keysym, client); 2916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (pipeinput_int == PIPEINPUT_MACOSX) { 2917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat macosx_key_command(down, keysym, client); 2918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (pipeinput_int == PIPEINPUT_VNC) { 2919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat vnc_reflect_send_key((uint32_t) keysym, down); 2920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2921a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (pipeinput_fh == NULL) { 2922a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! view_only) { 2926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat get_allowed_input(client, &input); 2927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (input.keystroke) { 2928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat can_input = 1; /* XXX distinguish later */ 2929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2931a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cd) { 2932a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uid = cd->uid; 2933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! can_input) { 2935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uid = -uid; 2936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2937a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2938a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 2939a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat name = XKeysymToString(keysym); 2940a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 2941a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2942a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(pipeinput_fh, "Keysym %d %d %u %s %s\n", uid, down, 2943a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym, name ? name : "null", down ? "KeyPress" : "KeyRelease"); 2944a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2945a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fflush(pipeinput_fh); 2946a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat check_pipeinput(); 2947a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 2948a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2949a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehattypedef struct keyevent { 2950a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbKeySym sym; 2951a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool down; 2952a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat double time; 2953a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} keyevent_t; 2954a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2955a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define KEY_HIST 256 2956a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int key_history_idx = -1; 2957a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic keyevent_t key_history[KEY_HIST]; 2958a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2959a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatdouble typing_rate(double time_window, int *repeating) { 2960a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat double dt = 1.0, now = dnow(); 2961a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym key = NoSymbol; 2962a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, idx, cnt = 0, repeat_keys = 0; 2963a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2964a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (key_history_idx == -1) { 2965a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (repeating) { 2966a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *repeating = 0; 2967a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2968a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0.0; 2969a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2970a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (time_window > 0.0) { 2971a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dt = time_window; 2972a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2973a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<KEY_HIST; i++) { 2974a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat idx = key_history_idx - i; 2975a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (idx < 0) { 2976a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat idx += KEY_HIST; 2977a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2978a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! key_history[idx].down) { 2979a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 2980a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2981a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (now > key_history[idx].time + dt) { 2982a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2983a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2984a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cnt++; 2985a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (key == NoSymbol) { 2986a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat key = key_history[idx].sym; 2987a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat repeat_keys = 1; 2988a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (key == key_history[idx].sym) { 2989a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat repeat_keys++; 2990a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2991a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2992a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2993a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (repeating) { 2994a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (repeat_keys >= 2) { 2995a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *repeating = repeat_keys; 2996a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2997a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *repeating = 0; 2998a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2999a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3000a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3001a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 3002a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * n.b. keyrate could seem very high with libvncserver buffering them 3003a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * so avoid using small dt. 3004a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3005a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return ((double) cnt)/dt; 3006a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3007a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3008a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint skip_cr_when_scaling(char *mode) { 3009a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int got = 0; 3010a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3011a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!scaling) { 3012a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 3013a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3014a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3015a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (scaling_copyrect != scaling_copyrect0) { 3016a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* user override via -scale: */ 3017a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! scaling_copyrect) { 3018a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 1; 3019a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 3020a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 3021a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3022a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3023a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (*mode == 's') { 3024a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat got = got_scrollcopyrect; 3025a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (*mode == 'w') { 3026a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat got = got_wirecopyrect; 3027a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3028a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (scaling_copyrect || got) { 3029a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int lat, rate; 3030a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int link = link_rate(&lat, &rate); 3031a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (link == LR_DIALUP) { 3032a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 1; 3033a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (rate < 25) { 3034a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* the fill-in of the repair may be too slow */ 3035a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 1; 3036a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 3037a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 0; 3038a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3039a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 3040a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return 1; 3041a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3042a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3043a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3044a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 3045a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * key event handler. See the above functions for contortions for 3046a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * running under -modtweak. 3047a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3048a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbClientPtr last_keyboard_client = NULL; 3049a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3050a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) { 3051a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeyCode k; 3052a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int idx, isbutton = 0; 3053a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat allowed_input_t input; 3054a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat time_t now = time(NULL); 3055a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat double tnow; 3056a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static int skipped_last_down; 3057a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static rfbBool last_down; 3058a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static rfbKeySym last_keysym = NoSymbol; 3059a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static rfbKeySym max_keyrepeat_last_keysym = NoSymbol; 3060a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static double max_keyrepeat_last_time = 0.0; 3061a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static double max_keyrepeat_always = -1.0; 3062a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3063a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (threads_drop_input) { 3064a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3065a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3066a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3067a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dtime0(&tnow); 3068a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat got_keyboard_calls++; 3069a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3070a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 3071a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str; 3072a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 3073a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = XKeysymToString((KeySym) keysym); 3074a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 3075a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("# keyboard(%s, 0x%x \"%s\") uip=%d %.4f\n", 3076a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat down ? "down":"up", (int) keysym, str ? str : "null", 3077a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unixpw_in_progress, tnow - x11vnc_start); 3078a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3079a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3080a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym <= 0) { 3081a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("keyboard: skipping 0x0 keysym\n"); 3082a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3083a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3084a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3085a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (unixpw_in_progress) { 3086a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (unixpw_denied) { 3087a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("keyboard: ignoring keystroke 0x%x in " 3088a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "unixpw_denied=1 state\n", (int) keysym); 3089a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3090a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3091a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (client != unixpw_client) { 3092a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("keyboard: skipping other client in unixpw\n"); 3093a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3094a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3095a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3096a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unixpw_keystroke(down, keysym, 0); 3097a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3098a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3099a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (skip_duplicate_key_events) { 3102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == last_keysym && down == last_down) { 3103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 3104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("skipping dup key event: %d 0x%x\n", 3105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat down, keysym); 3106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (skip_lockkeys) { 3112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* we don't handle XK_ISO*_Lock or XK_Kana_Lock ... */ 3113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == XK_Scroll_Lock || keysym == XK_Num_Lock || 3114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym == XK_Caps_Lock || keysym == XK_Shift_Lock) { 3115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 3116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("skipping lock key event: %d 0x%x\n", 3117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat down, keysym); 3118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (keysym >= XK_KP_0 && keysym <= XK_KP_9) { 3121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* ugh this is probably what they meant... assume NumLock. */ 3122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 3123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("changed KP digit to regular digit: %d 0x%x\n", 3124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat down, keysym); 3125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = (keysym - XK_KP_0) + XK_0; 3127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (keysym == XK_KP_Decimal) { 3128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 3129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("changed XK_KP_Decimal to XK_period: %d 0x%x\n", 3130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat down, keysym); 3131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat keysym = XK_period; 3133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INPUT_LOCK; 3137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_down = down; 3139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_keysym = keysym; 3140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_keyboard_time = tnow; 3141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_down = down; 3143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_keysym = keysym; 3144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_keytime = tnow; 3145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_key_accepted = FALSE; 3146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (key_history_idx == -1) { 3148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (idx=0; idx<KEY_HIST; idx++) { 3149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat key_history[idx].sym = NoSymbol; 3150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat key_history[idx].down = FALSE; 3151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat key_history[idx].time = 0.0; 3152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat idx = ++key_history_idx; 3155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (key_history_idx >= KEY_HIST) { 3156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat key_history_idx = 0; 3157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat idx = 0; 3158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat key_history[idx].sym = keysym; 3160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat key_history[idx].down = down; 3161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat key_history[idx].time = tnow; 3162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (down && (keysym == XK_Alt_L || keysym == XK_Super_L)) { 3164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, k, run = 0, ups = 0; 3165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat double delay = 1.0; 3166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat KeySym ks; 3167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i=0; i<16; i++) { 3168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k = idx - i; 3169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (k < 0) k += KEY_HIST; 3170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!key_history[k].down) { 3171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ups++; 3172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 3173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ks = key_history[k].sym; 3175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (key_history[k].time < tnow - delay) { 3176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (ks == keysym && ks == XK_Alt_L) { 3178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat run++; 3179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (ks == keysym && ks == XK_Super_L) { 3180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat run++; 3181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 3182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (ups < 2) { 3186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ; 3187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (run == 3 && keysym == XK_Alt_L) { 3188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("3*Alt_L, calling: refresh_screen(0)\n"); 3189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat refresh_screen(0); 3190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (run == 4 && keysym == XK_Alt_L) { 3191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("4*Alt_L, setting: do_copy_screen\n"); 3192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat do_copy_screen = 1; 3193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (run == 5 && keysym == XK_Alt_L) { 3194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ; 3195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (run == 3 && keysym == XK_Super_L) { 3196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("3*Super_L, calling: set_xdamage_mark()\n"); 3197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat set_xdamage_mark(0, 0, dpy_x, dpy_y); 3198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (run == 4 && keysym == XK_Super_L) { 3199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("4*Super_L, calling: check_xrecord_reset()\n"); 3200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat check_xrecord_reset(1); 3201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (run == 5 && keysym == XK_Super_L) { 3202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("5*Super_L, calling: push_black_screen(0)\n"); 3203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat push_black_screen(0); 3204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef MAX_KEYREPEAT 3208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (max_keyrepeat_always < 0.0) { 3209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (getenv("MAX_KEYREPEAT")) { 3210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat max_keyrepeat_always = atof(getenv("MAX_KEYREPEAT")); 3211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 3212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat max_keyrepeat_always = 0.0; 3213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (max_keyrepeat_always > 0.0) { 3216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat max_keyrepeat_time = max_keyrepeat_always; 3217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 3219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (0) {max_keyrepeat_always=0;} 3220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 3221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!down && skipped_last_down) { 3222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int db = debug_scroll; 3223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (keysym == max_keyrepeat_last_keysym) { 3224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skipped_last_down = 0; 3225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (db) rfbLog("--- scroll keyrate skipping 0x%lx %s " 3226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%.4f %.4f\n", keysym, down ? "down":"up ", 3227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tnow - x11vnc_start, tnow - max_keyrepeat_last_time); 3228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INPUT_UNLOCK; 3229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (down && max_keyrepeat_time > 0.0) { 3233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int skip = 0; 3234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int db = debug_scroll; 3235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (max_keyrepeat_last_keysym != NoSymbol && 3237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat max_keyrepeat_last_keysym != keysym) { 3238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ; 3239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 3240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (tnow < max_keyrepeat_last_time+max_keyrepeat_time) { 3241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skip = 1; 3242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat max_keyrepeat_time = 0.0; 3245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (skip) { 3246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (db) rfbLog("--- scroll keyrate skipping 0x%lx %s " 3247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%.4f %.4f\n", keysym, down ? "down":"up ", 3248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tnow - x11vnc_start, tnow - max_keyrepeat_last_time); 3249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat max_keyrepeat_last_keysym = keysym; 3250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skipped_last_down = 1; 3251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INPUT_UNLOCK; 3252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 3254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (db) rfbLog("--- scroll keyrate KEEPING 0x%lx %s " 3255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%.4f %.4f\n", keysym, down ? "down":"up ", 3256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tnow - x11vnc_start, tnow - max_keyrepeat_last_time); 3257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat max_keyrepeat_last_keysym = keysym; 3260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat max_keyrepeat_last_time = tnow; 3261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat skipped_last_down = 0; 3262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_key_accepted = TRUE; 3263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (pipeinput_fh != NULL || pipeinput_int) { 3265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat pipe_keyboard(down, keysym, client); /* MACOSX here. */ 3266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! pipeinput_tee) { 3267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! view_only || raw_fb) { /* raw_fb hack */ 3268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_keyboard_client = client; 3269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_event = last_input = now; 3270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_keyboard_input = now; 3271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_keysym = keysym; 3273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_down = down; 3275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_keysym = keysym; 3276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_keytime = tnow; 3277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_key_injected = dnow(); 3278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat got_user_input++; 3280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat got_keyboard_input++; 3281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INPUT_UNLOCK; 3283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (view_only) { 3288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INPUT_UNLOCK; 3289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat get_allowed_input(client, &input); 3292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! input.keystroke) { 3293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INPUT_UNLOCK; 3294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat track_mod_state(keysym, down, TRUE); /* ignores remaps */ 3298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_keyboard_client = client; 3300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_event = last_input = now; 3301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_keyboard_input = now; 3302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_keysym = keysym; 3304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_down = down; 3306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_keysym = keysym; 3307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_keytime = tnow; 3308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat last_rfb_key_injected = dnow(); 3309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat got_user_input++; 3311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat got_keyboard_input++; 3312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RAWFB_RET_VOID 3314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat apply_remap(&keysym, &isbutton); 3317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (use_xrecord && ! xrecording && down) { 3319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!strcmp(scroll_copyrect, "never")) { 3321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ; 3322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (!strcmp(scroll_copyrect, "mouse")) { 3323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ; 3324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (skip_cr_when_scaling("scroll")) { 3325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ; 3326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (! xrecord_skip_keysym(keysym)) { 3327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat snapshot_stack_list(0, 0.25); 3328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xrecord_watch(1, SCR_KEY); 3329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xrecord_set_by_keys = 1; 3330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xrecord_keysym = keysym; 3331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 3332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_scroll) { 3333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str = XKeysymToString(keysym); 3334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("xrecord_skip_keysym: %s\n", 3335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str ? str : "NoSymbol"); 3336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (isbutton) { 3341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int mask, button = (int) keysym; 3342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *b, bstr[32]; 3343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (! down) { 3345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INPUT_UNLOCK; 3346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; /* nothing to send */ 3347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 3349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("keyboard(): remapping keystroke to button %d" 3350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat " click\n", button); 3351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dtime0(&last_key_to_button_remap_time); 3353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 3355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 3356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This in principle can be a little dicey... i.e. even 3357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * remap the button click to keystroke sequences! 3358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Usually just will simulate the button click. 3359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* loop over possible multiclicks: Button123 */ 3362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sprintf(bstr, "%d", button); 3363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat b = bstr; 3364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (*b != '\0') { 3365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char t[2]; 3366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int butt; 3367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat t[0] = *b; 3368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat t[1] = '\0'; 3369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sscanf(t, "%d", &butt) == 1) { 3370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat mask = 1<<(butt-1); 3371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat do_button_mask_change(mask, butt); /* down */ 3372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat mask = 0; 3373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat do_button_mask_change(mask, butt); /* up */ 3374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat b++; 3376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFlush_wr(dpy); 3378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 3379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INPUT_UNLOCK; 3380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (use_modifier_tweak) { 3384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat modifier_tweak_keyboard(down, keysym, client); 3385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 3386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFlush_wr(dpy); 3387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 3388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INPUT_UNLOCK; 3389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_LOCK; 3393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k = XKeysymToKeycode(dpy, (KeySym) keysym); 3395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (k == NoSymbol && add_keysyms && ! IsModifierKey(keysym)) { 3397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int new_kc = add_keysym(keysym); 3398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (new_kc) { 3399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k = new_kc; 3400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (debug_keyboard) { 3403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str = XKeysymToString(keysym); 3404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("keyboard(): KeySym 0x%x \"%s\" -> KeyCode 0x%x%s\n", 3405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (int) keysym, str ? str : "null", (int) k, 3406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat k ? "" : " *ignored*"); 3407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( k != NoSymbol ) { 3410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XTestFakeKeyEvent_wr(dpy, k, (Bool) down, CurrentTime); 3411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat XFlush_wr(dpy); 3412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat X_UNLOCK; 3415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INPUT_UNLOCK; 3416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3419