Commit c41ab764 authored by runge's avatar runge

x11vnc: -add_keysyms dynamically add missing keysyms to X server

parent eb9a6928
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> 2004-07-26 Karl Runge <runge@karlrunge.com>
* x11vnc: first pass at doing modtweak via XKEYBOARD extension (-xkb) * x11vnc: first pass at doing modtweak via XKEYBOARD extension (-xkb)
* -skip_keycodes; reset modtweaks on event MappingNotify. * -skip_keycodes; reset modtweaks on event MappingNotify.
......
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> 2004-07-26 Karl Runge <runge@karlrunge.com>
* first pass at doing modtweak via XKEYBOARD extension (-xkb) * first pass at doing modtweak via XKEYBOARD extension (-xkb)
* -skip_keycodes option for use with -xkb * -skip_keycodes option for use with -xkb
......
...@@ -156,7 +156,7 @@ ...@@ -156,7 +156,7 @@
#endif #endif
/* date +'"lastmod: %Y-%m-%d";' */ /* date +'"lastmod: %Y-%m-%d";' */
char lastmod[] = "lastmod: 2004-07-26"; char lastmod[] = "lastmod: 2004-07-28";
/* X display info */ /* X display info */
Display *dpy = 0; Display *dpy = 0;
...@@ -257,6 +257,10 @@ void clear_modifiers(int init); ...@@ -257,6 +257,10 @@ void clear_modifiers(int init);
void clear_keys(void); void clear_keys(void);
void copy_screen(void); void copy_screen(void);
int add_keysym(KeySym);
void delete_keycode(KeyCode);
void delete_added_keycodes(void);
double dtime(double *); double dtime(double *);
void initialize_blackout(char *); void initialize_blackout(char *);
...@@ -347,6 +351,7 @@ int xkbcompat = 0; /* ignore XKEYBOARD extension */ ...@@ -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 = 0; /* try to open Xkb connection (for bell or other) */
int use_xkb_modtweak = 0; /* -xkb */ int use_xkb_modtweak = 0; /* -xkb */
char *skip_keycodes = NULL; 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 old_pointer = 0; /* use the old way of updating the pointer */
int single_copytile = 0; /* use the old way copy_tiles() */ int single_copytile = 0; /* use the old way copy_tiles() */
...@@ -476,6 +481,9 @@ void clean_up_exit (int ret) { ...@@ -476,6 +481,9 @@ void clean_up_exit (int ret) {
} }
} }
/* X keyboard cleanups */
delete_added_keycodes();
if (clear_mods == 1) { if (clear_mods == 1) {
clear_modifiers(0); clear_modifiers(0);
} else if (clear_mods == 2) { } else if (clear_mods == 2) {
...@@ -537,6 +545,10 @@ static void interrupted (int sig) { ...@@ -537,6 +545,10 @@ static void interrupted (int sig) {
break; break;
} }
} }
/* X keyboard cleanups */
delete_added_keycodes();
if (clear_mods == 1) { if (clear_mods == 1) {
clear_modifiers(0); clear_modifiers(0);
} else if (clear_mods == 2) { } else if (clear_mods == 2) {
...@@ -1810,6 +1822,107 @@ void clear_keys(void) { ...@@ -1810,6 +1822,107 @@ void clear_keys(void) {
XFlush(dpy); 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 * The following is for an experimental -remap option to allow the user
* to remap keystrokes. It is currently confusing wrt modifiers... * to remap keystrokes. It is currently confusing wrt modifiers...
...@@ -2337,6 +2450,18 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym, ...@@ -2337,6 +2450,18 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
got_kbstate = 1; got_kbstate = 1;
PKBSTATE 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) { if (!found && debug_keyboard) {
char *str = XKeysymToString(keysym); char *str = XKeysymToString(keysym);
fprintf(stderr, " *** NO key found for: 0x%x %s " fprintf(stderr, " *** NO key found for: 0x%x %s "
...@@ -2889,6 +3014,12 @@ static void modifier_tweak_keyboard(rfbBool down, rfbKeySym keysym, ...@@ -2889,6 +3014,12 @@ static void modifier_tweak_keyboard(rfbBool down, rfbKeySym keysym,
k = XKeysymToKeycode(dpy, (KeySym) keysym); k = XKeysymToKeycode(dpy, (KeySym) keysym);
X_UNLOCK; X_UNLOCK;
} }
if (k == NoSymbol && add_keysyms && ! IsModifierKey(keysym)) {
int new_kc = add_keysym(keysym);
if (new_kc) {
k = new_kc;
}
}
if (debug_keyboard) { if (debug_keyboard) {
rfbLog("modifier_tweak_keyboard: KeySym 0x%x \"%s\" -> " rfbLog("modifier_tweak_keyboard: KeySym 0x%x \"%s\" -> "
"KeyCode 0x%x%s\n", (int) keysym, XKeysymToString(keysym), "KeyCode 0x%x%s\n", (int) keysym, XKeysymToString(keysym),
...@@ -2993,6 +3124,12 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) { ...@@ -2993,6 +3124,12 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
k = XKeysymToKeycode(dpy, (KeySym) keysym); 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) { if (debug_keyboard) {
char *str = XKeysymToString(keysym); char *str = XKeysymToString(keysym);
rfbLog("keyboard(): KeySym 0x%x \"%s\" -> KeyCode 0x%x%s\n", rfbLog("keyboard(): KeySym 0x%x \"%s\" -> KeyCode 0x%x%s\n",
...@@ -3846,6 +3983,7 @@ void watch_xevents(void) { ...@@ -3846,6 +3983,7 @@ void watch_xevents(void) {
} }
if (XCheckTypedEvent(dpy, MappingNotify, &xev)) { if (XCheckTypedEvent(dpy, MappingNotify, &xev)) {
XRefreshKeyboardMapping((XMappingEvent *) &xev);
if (use_modifier_tweak) { if (use_modifier_tweak) {
X_UNLOCK; X_UNLOCK;
initialize_modtweak(); initialize_modtweak();
...@@ -7838,6 +7976,10 @@ static void print_help(void) { ...@@ -7838,6 +7976,10 @@ static void print_help(void) {
" keycodes. Use this option to help x11vnc in the reverse\n" " keycodes. Use this option to help x11vnc in the reverse\n"
" problem it tries to solve: Keysym -> Keycode(s) when\n" " problem it tries to solve: Keysym -> Keycode(s) when\n"
" ambiguities exist. E.g. -skip_keycodes 94,114\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 #if 0
"-xkbcompat Ignore the XKEYBOARD extension. Use as a workaround for\n" "-xkbcompat Ignore the XKEYBOARD extension. Use as a workaround for\n"
" some keyboard mapping problems. E.g. if you are using\n" " some keyboard mapping problems. E.g. if you are using\n"
...@@ -8394,6 +8536,8 @@ int main(int argc, char* argv[]) { ...@@ -8394,6 +8536,8 @@ int main(int argc, char* argv[]) {
skip_keycodes = argv[++i]; skip_keycodes = argv[++i];
} else if (!strcmp(arg, "-xkbcompat")) { } else if (!strcmp(arg, "-xkbcompat")) {
xkbcompat = 1; xkbcompat = 1;
} else if (!strcmp(arg, "-add_keysyms")) {
add_keysyms++;
} else if (!strcmp(arg, "-clear_mods")) { } else if (!strcmp(arg, "-clear_mods")) {
clear_mods = 1; clear_mods = 1;
} else if (!strcmp(arg, "-clear_keys")) { } else if (!strcmp(arg, "-clear_keys")) {
...@@ -8751,6 +8895,7 @@ int main(int argc, char* argv[]) { ...@@ -8751,6 +8895,7 @@ int main(int argc, char* argv[]) {
fprintf(stderr, "xkb: %d\n", use_xkb_modtweak); fprintf(stderr, "xkb: %d\n", use_xkb_modtweak);
fprintf(stderr, "skipkeys: %s\n", skip_keycodes ? skip_keycodes fprintf(stderr, "skipkeys: %s\n", skip_keycodes ? skip_keycodes
: "null"); : "null");
fprintf(stderr, "addkeysyms: %d\n", add_keysyms);
fprintf(stderr, "xkbcompat: %d\n", xkbcompat); fprintf(stderr, "xkbcompat: %d\n", xkbcompat);
fprintf(stderr, "clearmods: %d\n", clear_mods); fprintf(stderr, "clearmods: %d\n", clear_mods);
fprintf(stderr, "remap: %s\n", remap_file ? remap_file fprintf(stderr, "remap: %s\n", remap_file ? remap_file
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment