x11vnc: -add_keysyms dynamically add missing keysyms to X server

pull/1/head
runge 20 years ago
parent eb9a6928b0
commit c41ab764b8

@ -1,3 +1,6 @@
2004-07-28 Karl Runge <runge@karlrunge.com>
* x11vnc: -add_keysyms dynamically add missing keysyms to X server
2004-07-26 Karl Runge <runge@karlrunge.com>
* x11vnc: first pass at doing modtweak via XKEYBOARD extension (-xkb)
* -skip_keycodes; reset modtweaks on event MappingNotify.

@ -1,3 +1,6 @@
2004-07-28 Karl Runge <runge@karlrunge.com>
* -add_keysyms dynamically add missing keysyms to X server
2004-07-26 Karl Runge <runge@karlrunge.com>
* first pass at doing modtweak via XKEYBOARD extension (-xkb)
* -skip_keycodes option for use with -xkb

@ -156,7 +156,7 @@
#endif
/* date +'"lastmod: %Y-%m-%d";' */
char lastmod[] = "lastmod: 2004-07-26";
char lastmod[] = "lastmod: 2004-07-28";
/* X display info */
Display *dpy = 0;
@ -257,6 +257,10 @@ void clear_modifiers(int init);
void clear_keys(void);
void copy_screen(void);
int add_keysym(KeySym);
void delete_keycode(KeyCode);
void delete_added_keycodes(void);
double dtime(double *);
void initialize_blackout(char *);
@ -347,6 +351,7 @@ int xkbcompat = 0; /* ignore XKEYBOARD extension */
int use_xkb = 0; /* try to open Xkb connection (for bell or other) */
int use_xkb_modtweak = 0; /* -xkb */
char *skip_keycodes = NULL;
int add_keysyms = 0; /* automatically add keysyms to X server */
int old_pointer = 0; /* use the old way of updating the pointer */
int single_copytile = 0; /* use the old way copy_tiles() */
@ -476,6 +481,9 @@ void clean_up_exit (int ret) {
}
}
/* X keyboard cleanups */
delete_added_keycodes();
if (clear_mods == 1) {
clear_modifiers(0);
} else if (clear_mods == 2) {
@ -537,6 +545,10 @@ static void interrupted (int sig) {
break;
}
}
/* X keyboard cleanups */
delete_added_keycodes();
if (clear_mods == 1) {
clear_modifiers(0);
} else if (clear_mods == 2) {
@ -1810,6 +1822,107 @@ void clear_keys(void) {
XFlush(dpy);
}
static KeySym added_keysyms[0x100];
int add_keysym(KeySym keysym) {
int minkey, maxkey, syms_per_keycode;
int kc, n, ret = 0;
static int first = 1;
KeySym *keymap;
if (first) {
for (n=0; n < 0x100; n++) {
added_keysyms[n] = NoSymbol;
}
first = 0;
}
if (keysym == NoSymbol) {
return 0;
}
XDisplayKeycodes(dpy, &minkey, &maxkey);
keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1),
&syms_per_keycode);
for (kc = minkey+1; kc <= maxkey; kc++) {
int i, is_empty = 1;
char *str;
KeySym new[8];
for (n=0; n < syms_per_keycode; n++) {
if (keymap[ (kc-minkey) * syms_per_keycode + n]
!= NoSymbol) {
is_empty = 0;
break;
}
}
if (! is_empty) {
continue;
}
for (i=0; i<8; i++) {
new[i] = NoSymbol;
}
if (add_keysyms == 2) {
for(i=0; i < syms_per_keycode; i++) {
new[i] = keysym;
if (i >= 7) break;
}
} else {
new[0] = keysym;
}
XChangeKeyboardMapping(dpy, kc, syms_per_keycode,
new, 1);
str = XKeysymToString(keysym);
rfbLog("added missing keysym to X display: %03d 0x%x \"%s\"\n",
kc, keysym, str ? str : "null");
XFlush(dpy);
added_keysyms[kc] = keysym;
ret = kc;
break;
}
XFree(keymap);
return ret;
}
void delete_keycode(KeyCode kc) {
int minkey, maxkey, syms_per_keycode, i;
KeySym *keymap;
KeySym ksym, new[8];
char *str;
XDisplayKeycodes(dpy, &minkey, &maxkey);
keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1),
&syms_per_keycode);
for (i=0; i<8; i++) {
new[i] = NoSymbol;
}
XChangeKeyboardMapping(dpy, kc, syms_per_keycode, new, 1);
ksym = XKeycodeToKeysym(dpy, kc, 0);
str = XKeysymToString(ksym);
rfbLog("deleted keycode from X display: %03d 0x%x \"%s\"\n",
kc, ksym, str ? str : "null");
XFree(keymap);
XFlush(dpy);
}
void delete_added_keycodes(void) {
int kc;
for (kc = 0; kc < 0x100; kc++) {
if (added_keysyms[kc] != NoSymbol) {
delete_keycode(kc);
added_keysyms[kc] = NoSymbol;
}
}
}
/*
* The following is for an experimental -remap option to allow the user
* to remap keystrokes. It is currently confusing wrt modifiers...
@ -2337,6 +2450,18 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
got_kbstate = 1;
PKBSTATE
}
if (!found && add_keysyms && keysym && ! IsModifierKey(keysym)) {
int new_kc = add_keysym(keysym);
if (new_kc != 0) {
found = 1;
kc_f[0] = new_kc;
grp_f[0] = 0;
lvl_f[0] = 0;
state_f[0] = 0;
}
}
if (!found && debug_keyboard) {
char *str = XKeysymToString(keysym);
fprintf(stderr, " *** NO key found for: 0x%x %s "
@ -2889,6 +3014,12 @@ static void modifier_tweak_keyboard(rfbBool down, rfbKeySym keysym,
k = XKeysymToKeycode(dpy, (KeySym) keysym);
X_UNLOCK;
}
if (k == NoSymbol && add_keysyms && ! IsModifierKey(keysym)) {
int new_kc = add_keysym(keysym);
if (new_kc) {
k = new_kc;
}
}
if (debug_keyboard) {
rfbLog("modifier_tweak_keyboard: KeySym 0x%x \"%s\" -> "
"KeyCode 0x%x%s\n", (int) keysym, XKeysymToString(keysym),
@ -2993,6 +3124,12 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
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",
@ -3846,6 +3983,7 @@ void watch_xevents(void) {
}
if (XCheckTypedEvent(dpy, MappingNotify, &xev)) {
XRefreshKeyboardMapping((XMappingEvent *) &xev);
if (use_modifier_tweak) {
X_UNLOCK;
initialize_modtweak();
@ -7838,6 +7976,10 @@ static void print_help(void) {
" keycodes. Use this option to help x11vnc in the reverse\n"
" problem it tries to solve: Keysym -> Keycode(s) when\n"
" ambiguities exist. E.g. -skip_keycodes 94,114\n"
"-add_keysyms If a keysym is received from a VNC viewer, but\n"
" that keysym does not exist in the X server, then\n"
" add the keysym to the X server's keyboard mapping.\n"
" Added keysyms will be removed when exiting.\n"
#if 0
"-xkbcompat Ignore the XKEYBOARD extension. Use as a workaround for\n"
" some keyboard mapping problems. E.g. if you are using\n"
@ -8394,6 +8536,8 @@ int main(int argc, char* argv[]) {
skip_keycodes = argv[++i];
} else if (!strcmp(arg, "-xkbcompat")) {
xkbcompat = 1;
} else if (!strcmp(arg, "-add_keysyms")) {
add_keysyms++;
} else if (!strcmp(arg, "-clear_mods")) {
clear_mods = 1;
} else if (!strcmp(arg, "-clear_keys")) {
@ -8751,6 +8895,7 @@ int main(int argc, char* argv[]) {
fprintf(stderr, "xkb: %d\n", use_xkb_modtweak);
fprintf(stderr, "skipkeys: %s\n", skip_keycodes ? skip_keycodes
: "null");
fprintf(stderr, "addkeysyms: %d\n", add_keysyms);
fprintf(stderr, "xkbcompat: %d\n", xkbcompat);
fprintf(stderr, "clearmods: %d\n", clear_mods);
fprintf(stderr, "remap: %s\n", remap_file ? remap_file

Loading…
Cancel
Save