if (scaling && ! got_scrollcopyrect) { ; } else if (!strcmp(scroll_copyrect, "never")) {
if (!strcmp(scroll_copyrect, "never")) {
void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {	KeyCode k;	int idx, isbutton = 0;	allowed_input_t input;	time_t now = time(0);	double tnow;	static int skipped_last_down;	static rfbBool last_down;	static rfbKeySym last_keysym = NoSymbol;	static rfbKeySym max_keyrepeat_last_keysym = NoSymbol;	static double max_keyrepeat_last_time = 0.0;	dtime0(&tnow);	if (debug_keyboard) {		char *str;		X_LOCK;		str = XKeysymToString(keysym);		rfbLog("# keyboard(%s, 0x%x \"%s\")  %.4f\n", down ? "down":"up",		    (int) keysym, str ? str : "null", tnow - x11vnc_start);		X_UNLOCK;	}	if (skip_duplicate_key_events) {		if (keysym == last_keysym && down == last_down) {			if (debug_keyboard) {				rfbLog("skipping dup key event: %d 0x%x\n",				    down, keysym);			}			return;		}	}	last_down = down;	last_keysym = keysym;	last_keyboard_time = tnow;	last_rfb_down = down;	last_rfb_keysym = keysym;	last_rfb_keytime = tnow;	last_rfb_key_accepted = FALSE;	if (key_history_idx == -1) {		for (idx=0; idx<KEY_HIST; idx++) {			key_history[idx].sym = NoSymbol;			key_history[idx].down = FALSE;			key_history[idx].time = 0.0;		}	}	idx = ++key_history_idx;	if (key_history_idx >= KEY_HIST) {		key_history_idx = 0;		idx = 0;	}	key_history[idx].sym = keysym;	key_history[idx].down = down;	key_history[idx].time = tnow;	if (down && skip_duplicate_key_events &&	    (keysym == XK_Alt_L || keysym == XK_Super_L)) {		int i, k, run = 0;		double delay = 1.0;		KeySym ks;		for (i=0; i<16; i++) {			k = idx - i;			if (k < 0) k += KEY_HIST;			if (!key_history[k].down) {				continue;			}			ks = key_history[k].sym;			if (key_history[k].time < tnow - delay) {				break;			} else if (ks == keysym && ks == XK_Alt_L) {				run++;			} else if (ks == keysym && ks == XK_Super_L) {				run++;			} else {				break;			}		}		if (run == 3 && keysym == XK_Alt_L) {			rfbLog("3*Alt_L, calling: refresh_screen(0)\n");			refresh_screen(0);		} else if (run == 4 && keysym == XK_Alt_L) {			rfbLog("4*Alt_L, setting: do_copy_screen\n");			do_copy_screen = 1;		} else if (run == 5 && keysym == XK_Alt_L) {			;		} else if (run == 3 && keysym == XK_Super_L) {			rfbLog("3*Super_L, calling: set_xdamage_mark()\n");			set_xdamage_mark(0, 0, dpy_x, dpy_y);		} else if (run == 4 && keysym == XK_Super_L) {			rfbLog("4*Super_L, calling: check_xrecord_reset()\n");			check_xrecord_reset(1);		} else if (run == 5 && keysym == XK_Super_L) {			rfbLog("5*Super_L, calling: push_black_screen(0)\n");			push_black_screen(0);		}	}	if (!down && skipped_last_down) {		int db = debug_scroll;		if (keysym == max_keyrepeat_last_keysym) {			skipped_last_down = 0;			if (db) rfbLog("--- scroll keyrate skipping 0x%lx %s "			    "%.4f  %.4f\n", keysym, down ? "down":"up  ",			    tnow - x11vnc_start, tnow - max_keyrepeat_last_time); 			return;		}	}	if (down && max_keyrepeat_time > 0.0) {		int skip = 0;		int db = debug_scroll;		if (max_keyrepeat_last_keysym != NoSymbol &&		    max_keyrepeat_last_keysym != keysym) {			;		} else {			if (tnow < max_keyrepeat_last_time+max_keyrepeat_time) {				skip = 1;			}		}		max_keyrepeat_time = 0.0;		if (skip) {			if (db) rfbLog("--- scroll keyrate skipping 0x%lx %s "			    "%.4f  %.4f\n", keysym, down ? "down":"up  ",			    tnow - x11vnc_start, tnow - max_keyrepeat_last_time); 			max_keyrepeat_last_keysym = keysym;			skipped_last_down = 1;			return;		} else {			if (db) rfbLog("--- scroll keyrate KEEPING  0x%lx %s "			    "%.4f  %.4f\n", keysym, down ? "down":"up  ",			    tnow - x11vnc_start, tnow - max_keyrepeat_last_time); 		}	}	max_keyrepeat_last_keysym = keysym;	max_keyrepeat_last_time = tnow;	skipped_last_down = 0;	last_rfb_key_accepted = TRUE;	if (pipeinput_fh != NULL) {		pipe_keyboard(down, keysym, client);		if (! pipeinput_tee) {			if (! view_only || raw_fb) {	/* raw_fb hack */				last_keyboard_client = client;				last_event = last_input = now;				last_keyboard_input = now;						last_keysym = keysym;				last_rfb_down = down;				last_rfb_keysym = keysym;				last_rfb_keytime = tnow;				got_user_input++;				got_keyboard_input++;			}			return;		}	}	if (view_only) {		return;	}	get_allowed_input(client, &input);	if (! input.keystroke) {		return;	}	last_keyboard_client = client;	last_event = last_input = now;	last_keyboard_input = now;	last_keysym = keysym;	last_rfb_down = down;	last_rfb_keysym = keysym;	last_rfb_keytime = tnow;	got_user_input++;	got_keyboard_input++;		if (raw_fb && ! dpy) return;	/* raw_fb hack */	if (keyremaps) {		keyremap_t *remap = keyremaps;		while (remap != NULL) {			if (remap->before == keysym) {				keysym = remap->after;				isbutton = remap->isbutton;				if (debug_keyboard) {					X_LOCK;					rfbLog("keyboard(): remapping keysym: "					    "0x%x \"%s\" -> 0x%x \"%s\"\n",					    (int) remap->before,					    XKeysymToString(remap->before),					    (int) remap->after,					    remap->isbutton ? "button" :					    XKeysymToString(remap->after));					X_UNLOCK;				}				break;			}			remap = remap->next;		}	}	if (use_xrecord && ! xrecording && down) {		if (scaling && ! got_scrollcopyrect) {			;		} else if (!strcmp(scroll_copyrect, "never")) {			;		} else if (!strcmp(scroll_copyrect, "mouse")) {			;		} else if (! xrecord_skip_keysym(keysym)) {			snapshot_stack_list(0, 0.25);			xrecord_watch(1, SCR_KEY);			xrecord_set_by_keys = 1;			xrecord_keysym = keysym;		} else {			if (debug_scroll) {				char *str = XKeysymToString(keysym);				rfbLog("xrecord_skip_keysym: %s\n",				    str ? str : "NoSymbol");			}		}	}	if (isbutton) {		int mask, button = (int) keysym;		if (! down) {			return;	/* nothing to send */		}		if (debug_keyboard) {			rfbLog("keyboard(): remapping keystroke to button %d"			    " click\n", button);		}		dtime0(&last_key_to_button_remap_time);		X_LOCK;		/*		 * This in principle can be a little dicey... i.e. even		 * remap the button click to keystroke sequences!		 * Usually just will simulate the button click.		 */		mask = 1<<(button-1);		do_button_mask_change(mask, button);	/* down */		mask = 0;		do_button_mask_change(mask, button);	/* up */		XFlush(dpy);		X_UNLOCK;		return;	}	if (use_modifier_tweak) {		modifier_tweak_keyboard(down, keysym, client);		X_LOCK;		XFlush(dpy);		X_UNLOCK;		return;	}	X_LOCK;	k = XKeysymToKeycode(dpy, (KeySym) keysym);	if (k == NoSymbol && add_keysyms && ! IsModifierKey(keysym)) {		int new_kc = add_keysym(keysym);		if (new_kc) {			k = new_kc;		}	}	if (debug_keyboard) {		char *str = XKeysymToString(keysym);		rfbLog("keyboard(): KeySym 0x%x \"%s\" -> KeyCode 0x%x%s\n",		    (int) keysym, str ? str : "null", (int) k,		    k ? "" : " *ignored*");	}	if ( k != NoSymbol ) {		XTestFakeKeyEvent_wr(dpy, k, (Bool) down, CurrentTime);		XFlush(dpy);	}	X_UNLOCK;}