How to go from KeyCode to KeySym to Ascii/Unicode?
So I am finally taking my GUI seriously and currently working on textbox input.
The GUI is to work crossplatform Windows/X11, with as little dependencies as possible. I was originally using SDL_GetKeyState, but that didnt gave me caps or characters that needed the shift key.
So I decided to get rid of the SDL dependency, and I managed to Implement a working input handling algorithm for Windows using WinApi Calls GetKeyboardState, MapVirtualKeyEx and ToAscii.
Now I am doing the X11 part, so far I managed to get the Keyboard State with XQueryKeymap, grabed the keyboard mapping table (KeyCode to KeySym) with XGetKeyboardMapping, but the thing is that I get multiple keysyms for the same keycode, which makes sence since the same key outputs 'a' and 'A', but the question is... how can I A-find out which of the KeySyms is the correct one based on the keyboard state, and B-given the later 2 (keycode-keysym) how can I translate that into Ascii or Unicode?
I cant use events because that would probably mean having to own the main program window and such and that's really not posible.
As usual when I post these kind of questions I am tired and I am going to bed, so this may be trivial... I should look into XGetKeyboardMapping, I am thinking that maybe the KeySym count matches modifiers and you somewhat use the modifier index to find out which one to use.
Anyway, anyone has any ideas?
Thanks in Advance.
This document is horribly confusing, but I think it has your answer:
Quote:
Within a group, the choice of KeySym is determined by applying the first rule that is satisfied from the following list:
- The numlock modifier is on and the second KeySym is a keypad KeySym. In this case, if the Shift modifier is on, or if the Lock modifier is on and is interpreted as ShiftLock, then the first KeySym is used, otherwise the second KeySym is used.
- The Shift and Lock modifiers are both off. In this case, the first KeySym is used.
- The Shift modifier is off, and the Lock modifier is on and is interpreted as CapsLock. In this case, the first KeySym is used, but if that KeySym is lowercase alphabetic, then the corresponding uppercase KeySym is used instead.
- The Shift modifier is on, and the Lock modifier is on and is interpreted as CapsLock. In this case, the second KeySym is used, but if that KeySym is lowercase alphabetic, then the corresponding uppercase KeySym is used instead.
- The Shift modifier is on, or the Lock modifier is on and is interpreted as ShiftLock, or both. In this case, the second KeySym is used.
Thanks, I've almost have it figured it out, there is a function XKeycodeToKeysym that helps getting the KeySym, though its last parameter has to be calculated by te formula you posted, which I have not entirelly grasped yet.
Anyway, using XGetModifierMapping I get the necesary info to find out the KeySym index, so I should be getting it pretty soon.
To get from KeySym to unicode, I am using this code, which I got to from here.
Its been a long day of googling [smile].
Anyway, using XGetModifierMapping I get the necesary info to find out the KeySym index, so I should be getting it pretty soon.
To get from KeySym to unicode, I am using this code, which I got to from here.
Its been a long day of googling [smile].
Wouldn't it have been easier to read SDL keyboard events, which do provide shift key state, and maintain a cache of the keyboard state with which to implement a useful version of SDL_GetKeyState?
Quote: Original post by Nathan Baum
Wouldn't it have been easier to read SDL keyboard events, which do provide shift key state, and maintain a cache of the keyboard state with which to implement a useful version of SDL_GetKeyState?
No, for the following reasons:
- Using SDL events would make the library a wrapper for SDL, thus being dependent on SDL. I use SDL myself, but the idea is for the library to have "rendering independence", which means being able to plug it into a D3D application, a SDL free OpenGL application or even use GDI for rendering.
- I was infact using SDL_GetKeyState thru the rendering interface (to explain better, each "rendering Interface" is a separate DLL) so the library was SDL independent but the interface was not, I though rendering has nothing to do with input, so there is no reason to have that in there.
- SDL_GetKeyState returns an array of internal key states, whatever Unicode caracter returned by its event pump is lost, and retracing the steps to get from SDL_Key to Ascii/Unicode would have involved the same amount of work I have done so far. This one was actually the reason that made me make the switch once I realized Shift+1 was not printing "!" (I had a workaround for CAPS so I didnt noticed until now).
- Doing it this other way I can get International Character Support for free at least on Windows thanks to Localization
[Edited by - Kwizatz on March 22, 2007 11:39:19 AM]
This may help you, atleast it's got another function to check out. It's from my x11 event loop:
case KeyPress:
// Convert keycode to keysym
Key = XKeycodeToKeysym (XDisplay, Event.xkey.keycode, 0);
// Post it to the Keyboard input driver
inpKeyboard::PostKey (Key, inpKeyboard::KEY_PRESS);
// Get the char from this keysym
memset (Str, 0, 16);
len = XLookupString (&Event.xkey, Str, 16, NULL, NULL);
// Post it to the InputQue
if (len) InputQue::PostChar (Str[0]);
break;
I'm working towards using the event input system to track state and generate characters myself, as i'm trying to minimize my dependency on X so that someday the program will be able to run without X.
--Zims
case KeyPress:
// Convert keycode to keysym
Key = XKeycodeToKeysym (XDisplay, Event.xkey.keycode, 0);
// Post it to the Keyboard input driver
inpKeyboard::PostKey (Key, inpKeyboard::KEY_PRESS);
// Get the char from this keysym
memset (Str, 0, 16);
len = XLookupString (&Event.xkey, Str, 16, NULL, NULL);
// Post it to the InputQue
if (len) InputQue::PostChar (Str[0]);
break;
I'm working towards using the event input system to track state and generate characters myself, as i'm trying to minimize my dependency on X so that someday the program will be able to run without X.
--Zims
Quote: Original post by Zimans
This may help you, atleast it's got another function to check out. It's from my x11 event loop:
...
--Zims
Thanks, I pretty much have it done though, I decided to use XKeysymToKeycode to create the equivalent to the virtual key table on windows (for keypress events which are different than character events), building a keysym table would be insane.
Right now my problem is still with figuring out which column to pass XKeycodeToKeysym (What Null posted pretty much) since the explanation is so vague, what exactly is the Lock modifier? is it different than the Shift Modifier or caps Modifier? and there is this obscure line:
Quote: The Shift modifier is off, and the Lock modifier is on and is interpreted as CapsLock. In this case, the first KeySym is used, but if that KeySym is lowercase alphabetic, then the corresponding uppercase KeySym is used instead.
How am I supposed to know if a KeySym is lower or uppercase? create yet a new table? what about Cyrillic and all those other alphabets? will I have to create a lower and upper case table for each?
ARRRG! its driving me insane, so I am getting rid of the SDL_GetMouseState dependency while I come up with a solution, I've been looking at the source code for XLookupString, the solution is there, but its not very evident.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement