Reputation: 1714
I'm currently having a problem with Xlib where whenever I call XKeysymToKeycode()
and pass in an uppercase KeySym
, it returns a lowercase KeyCode
. Google doesn't really seem to have an answer to this question, or too much documentation at all on the functions I'm using, for that matter.
Here's the code I am using:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>
int main(void) {
Display *display;
char *ptr;
char c[2] = {0, 0};
KeySym ksym;
KeyCode kcode;
display = XOpenDisplay(0);
ptr = "Test";
while (*ptr) {
c[0] = *ptr;
ksym = XStringToKeysym(c);
printf("Before XKeysymToKeycode(): %s\n", XKeysymToString(ksym));
kcode = XKeysymToKeycode(display, ksym);
printf("Key code after XKeysymToKeycode(): %s\n", XKeysymToString(XKeycodeToKeysym(display, kcode, 0)));
ptr++;
}
XCloseDisplay(display);
return 0;
}
It can be compiled with gcc -o sendkeys sendkeys_min.c -lX11 -lXtst -g -Wall -Wextra -pedantic -ansi
(Assuming it has been saved as sendkeys_min.c
.)
The current output is the following:
Before XKeysymToKeycode(): T
Key code after XKeysymToKeycode(): t
Before XKeysymToKeycode(): e
Key code after XKeysymToKeycode(): e
Before XKeysymToKeycode(): s
Key code after XKeysymToKeycode(): s
Before XKeysymToKeycode(): t
Key code after XKeysymToKeycode(): t
The expected output, is, of course, that the first T in "Test" is still uppercase after being ran through XKeysymToKeycode()
. (Note that this is not my actual program, but a simplified version for posting here. In the actual program, I am sending key events with the resulting keycode, and the keys sent still have the problem exhibited here (They all become lowercase))
Upvotes: 1
Views: 3498
Reputation: 241881
KeySyms
and KeyCodes
are semantically different, and there is not a 1-1 relationship between them.
A KeyCode
is an arbitrary small integer representing a key on the keyboard. (Not a character. A key.) Xlib requires that key codes be in the range [8, 255]
, but fortunately most keyboards have only a bit more than 100 keys.
A KeySym
is a representation of some actual character associated with a key. There will almost always be several of these: lower- and upper-case letters correspond to the same key on most terminal layouts.
So there is no such thing as an "upper-case" or "lower-case" KeyCode
. When you get the KeyCode
corresponding to a Keysym, you are actually losing information.
In Xlib, a given key has at least four corresponding KeySyms
(lower-case, upper-case, alternate lower-case, alternate upper-case), although some might be unassigned. When you ask for the KeySym
corresponding to a KeyCode
, you need to supply an index; index 0 (as in your code) will get the unshifted unmodified character.
For a given keypress, the translation to a KeySym will take into account the state of the modifier keys. There are eight of these, including the Shift
and Lock
modifiers. Ignoring Lock
, which complicates the situation, the shift modifier key would normally turn lower-case letters into their upper-case equivalents (for alphabetic keys).
Keyboard handling is much more complicated than that brief summary, but it's a start.
For your task, you probably should take a look at XkbKeysymToModifiers
.
Upvotes: 6