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