SDL 2: How to read shift+X keys?

https://wiki.libsdl.org/SDLKeycodeLookup
Here, it shows (for example) 33 = 0x21 (’!’) = SDLK_EXCLAIM.
https://wiki.libsdl.org/SDL_Scancode
Here it shows “!” = (none) = SDLK_EXCLAIM.

In the event loop I check for SDL_KEYDOWN, and then do, SDL_GetScancodeName(event->key.keysym.scancode), and it shows “1”, and SDL_GetKeyName(event->key.keysym.sym) also shows “1” instead of showing “!”.
I then try shift + “a” (should be “A”) but, it shows “a”.
What am I missing here?

What you are missing is the SDL_TEXTINPUT event. See here:
https://wiki.libsdl.org/SDL_TextInputEvent

Call SDL_StartTextInput(), then start checking for SDL_TEXTINPUT events.
Use the characters that the event gives you. This is a change from SDL1.2,
where properly dealing with different keyboard layouts, input devices (e.g.
mobile virtual keyboard), and different character sets (or Unicode) was not
possible.

Jonny DOn Thu, Feb 26, 2015 at 3:48 PM, Sparks wrote:

https://wiki.libsdl.org/SDLKeycodeLookup
Here, it shows (for example) 33 = 0x21 (’!’) = SDLK_EXCLAIM.
https://wiki.libsdl.org/SDL_Scancode
Here it shows “!” = (none) = SDLK_EXCLAIM.

In the event loop I check for SDL_KEYDOWN, and then do,
SDL_GetScancodeName(event->key.keysym.scancode), and it shows “1”, and
SDL_GetKeyName(event->key.keysym.sym) also shows “1” instead of showing “!”.
I then try shift + “a” (should be “A”) but, it shows “a”.
What am I missing here?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Yes, I know about this, but, that isn’t what I need, SDL_TEXTINPUT is too limiting with having to do SDL_Start/StopTextInput() when we want keyboard input, since other keys can be used at the same time. That is why we must manually do this, like the “old” way, which seems broken now?
If both the scancode and the keycode both have “!” as an entry, then, it should be possible to have “!” given in the keycode or scancode.

Uppercase ‘A’ should be value 65, lower case ‘a’ should be 97 according to the ASCII table, that is the same behavior we want with SDL 2.

Jonny D wrote:> What you are missing is the SDL_TEXTINPUT event.?? See here:https://wiki.libsdl.org/SDL_TextInputEvent (https://wiki.libsdl.org/SDL_TextInputEvent)

Call SDL_StartTextInput(), then start checking for SDL_TEXTINPUT events.?? Use the characters that the event gives you.?? This is a change from SDL1.2, where properly dealing with different keyboard layouts, input devices (e.g. mobile virtual keyboard), and different character sets (or Unicode) was not possible.

Jonny D

On Thu, Feb 26, 2015 at 3:48 PM, Sparks <> wrote:

  https://wiki.libsdl.org/SDLKeycodeLookup (https://wiki.libsdl.org/SDLKeycodeLookup)

Here, it shows (for example) 33 = 0x21 (’!’) = SDLK_EXCLAIM.
https://wiki.libsdl.org/SDL_Scancode (https://wiki.libsdl.org/SDL_Scancode)
Here it shows “!” = (none) = SDLK_EXCLAIM.

In the event loop I check for SDL_KEYDOWN, and then do, SDL_GetScancodeName(event->key.keysym.scancode), and it shows “1”, and SDL_GetKeyName(event->key.keysym.sym) also shows “1” instead of showing “!”.
I then try shift + “a” (should be “A”) but, it shows “a”.
What am I missing here?

Don’t forget SDL_KEYDOWN/UP deal mainly with scancodes, which only represent one key type, regardless of whether there is an alternative type when the shift, alt or ctrl key is held down.

You could try various conversion routines, like getting the key name from the scancode and then checking to see if the shift key is pressed, and which point you convert the ASCII code to uppercase. However, there are a few exceptions - for example, with space you would get the word “Space”.

Sparks wrote:

Yes, I know about this, but, that isn’t what I need, SDL_TEXTINPUT is too limiting with having to do SDL_Start/StopTextInput() when we want keyboard input, since other keys can be used at the same time. That is why we must manually do this, like the “old” way, which seems broken now?
If both the scancode and the keycode both have “!” as an entry, then, it should be possible to have “!” given in the keycode or scancode.

Uppercase ‘A’ should be value 65, lower case ‘a’ should be 97 according to the ASCII table, that is the same behavior we want with SDL 2.

Just to make it more clear, before SDL 1 had this struct
typedef struct{
Uint8 scancode;
SDLKey sym;
SDLMod mod;
Uint16 unicode;
} SDL_keysym;

Where SDL_keysym.unicode would have, in this case contained “!” and “A” respectively. The SDL_keysym.sym would have been “1” and “a” respectively in my example.

That is what I need, and I can’t seem to find a way to mimic that behavior anymore? :frowning:

What would be wrong with using SDL_StartTextInput() and leaving it on for
desktop systems? You would do the same processing, unless I’m
misunderstanding what you’re doing.

Alternatively, use SDL_GetModState() and you can then shift certain ascii
values yourself.

Jonny DOn Thu, Feb 26, 2015 at 5:17 PM, Sparks wrote:

Sparks wrote:

Yes, I know about this, but, that isn’t what I need, SDL_TEXTINPUT is
too limiting with having to do SDL_Start/StopTextInput() when we want
keyboard input, since other keys can be used at the same time. That is why
we must manually do this, like the “old” way, which seems broken now?
If both the scancode and the keycode both have “!” as an entry, then, it
should be possible to have “!” given in the keycode or scancode.

Uppercase ‘A’ should be value 65, lower case ‘a’ should be 97 according to
the ASCII table, that is the same behavior we want with SDL 2.

Just to make it more clear, before SDL 1 had this struct
typedef struct{
Uint8 scancode;
SDLKey sym;
SDLMod mod;
Uint16 unicode;
} SDL_keysym;

Where SDL_keysym.unicode would have, in this case contained “!” and "A"
respectively. The SDL_keysym.sym would have been “1” and “a” respectively
in my example.

That is what I need, and I can’t seem to find a way to mimic that behavior
anymore? [image: Sad]


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

What would be wrong with using SDL_StartTextInput() and leaving it on
for desktop systems? You would do the same processing, unless I’m
misunderstanding what you’re doing.

Agree.

Alternatively, use SDL_GetModState() and you can then shift certain
ascii values yourself.

Bad idea… this might somehow work for a-z, but will utterly fail at all
other keys (including numbers), because of different keyboard layouts.
Just use SDL_TEXTINPUT events for textinput.
It’s really worth the effort.

Cheers,
DanielOn 02/27/2015 12:49 AM, Jonathan Dearborn wrote:

Jonny D

On Thu, Feb 26, 2015 at 5:17 PM, Sparks <ametalspark-SDL2 at yahoo.com <mailto:ametalspark-SDL2 at yahoo.com>> wrote:

__



Sparks wrote:	

Yes, I know about this, but, that isn't what I need, SDL_TEXTINPUT
is too limiting with having to do SDL_Start/StopTextInput() when we
want keyboard input, since other keys can be used at the same time.
That is why we must manually do this, like the "old" way, which
seems broken now?
If both the scancode and the keycode both have "!" as an entry,
then, it should be possible to have "!" given in the keycode or
scancode.

Uppercase 'A' should be value 65, lower case 'a' should be 97
according to the ASCII table, that is the same behavior we want with
SDL 2.
	


Just to make it more clear, before SDL 1 had this struct
typedef struct{
Uint8 scancode;
SDLKey sym;
SDLMod mod;
Uint16 unicode;
} SDL_keysym;

Where SDL_keysym.unicode would have, in this case contained "!" and
"A" respectively. The SDL_keysym.sym would have been "1" and "a"
respectively in my example.

That is what I need, and I can't seem to find a way to mimic that
behavior anymore? Sad

_______________________________________________
SDL mailing list
SDL at lists.libsdl.org <mailto:SDL at lists.libsdl.org>
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Jonny D wrote:

What would be wrong with using SDL_StartTextInput() and leaving it on for desktop systems??? You would do the same processing, unless I’m misunderstanding what you’re doing.

Alternatively, use SDL_GetModState() and you can then shift certain ascii values yourself.

Jonny D

I thought if you leave SDL_StartTextInput() ‘on’, that it would swallow up all key presses from that point on, until you turn that off?
Do you still get SDL_KEYDOWN events, along with SDL_TEXTINPUT & SDL_TEXTEDITING events?
In other words, would I get a SDL_KEYDOWN event for pressing “shift a” (would generate a ‘a’), and that will be “A” in the SDL_TEXTINPUT event?

Yeah, you still get SDL_KEYDOWN when it is on. That way you can handle
non-printing keys too (like backspace).

Good luck!
Jonny DOn Thu, Feb 26, 2015 at 7:14 PM, Sparks wrote:

Jonny D wrote:
What would be wrong with using SDL_StartTextInput() and leaving it on for
desktop systems?? You would do the same processing, unless I’m
misunderstanding what you’re doing.

Alternatively, use SDL_GetModState() and you can then shift certain ascii
values yourself.

Jonny D

I thought if you leave SDL_StartTextInput() ‘on’, that it would swallow up
all key presses from that point on, until you turn that off?
Do you still get SDL_KEYDOWN events, along with SDL_TEXTINPUT &
SDL_TEXTEDITING events?
In other words, would I get a SDL_KEYDOWN event for pressing “shift a”
(would generate a ‘a’), and that will be “A” in the SDL_TEXTINPUT event?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Sparks wrote:

Do you still get SDL_KEYDOWN events, along with SDL_TEXTINPUT & SDL_TEXTEDITING events?

Yes.

Sparks wrote:

In other words, would I get a SDL_KEYDOWN event for pressing “shift a” (would generate a ‘a’), and that will be “A” in the SDL_TEXTINPUT event?

Yes, exactly.

You can use SDL_KEYDOWN to detect stuff like Backspace to erase the last char or ESC being pressed to cancel editing.------------------------
bigosaur.com

What exactly are you trying to do? I can’t tell from the conversation if you’re trying to issue alternate game commands if a mod key is pressed (press ‘w’ to walk, press ‘w’ + ‘Shift’ to run) or implement some kind of text input interface like a chat client. Is your initial post the results of debugging or do you really need the character output? Sorry if you’ve made it clear, and I’ve just missed it.------------------------
"You all look like lions to me. Lets be rabbits again."
https://github.com/ts-williams

I also do not get it.

  1. How do I get correct ASCII or Unicode key on the Keyboard UP event? The SDL_TEXTINPUT is not worth here as it does not provide Keyboard UP event.

  2. How do I convert the event.key.keysym.sym which seems to be a scancode now i.e. not reflecting SHIFT key, to a true SDL_Keycode? Is there a function that can get the scan code or keysym.sym, state of option keys (shift etc.) and return correct SDL_Keycode based on keyboard layout?

  3. How do I distinguish if the key sent to SDL_KEYDOWN event was already consumed by SDL_TEXTINPUT to not repeat event processing? Is there a way to check if the SDL_Keycode is a ‘printable character’ already sent to SDL_TEXTINPUT?

My use case is simple, I need to forward Key Down and Key Up codes in their correct form to some large legacy code that can’t be updated. I need to forward all of them, not only printable characters.

Consider this case:

  1. Press Shift
  2. Press ‘1’ (generating ‘!’)
  3. Release Shift
  4. Release ‘1’

When the ‘1’ key is released the Shift key is no longer pressed, so do you expect to get an UP event for ‘1’ or ‘!’? The whole idea of returning a character code for the UP event seems flawed to me.

Good point. I am struggling with similar situation already, the code I am using has also underlying SHIFT-transforming as that is C64 emulator, thus even there the keyboard has also its own layout. So consider that I need to translate for example " key (i.e. the Shift + ’ on common keyboards) to SHIFT+2, but also I need to Key UP it properly as if not it will stay pressed and repeated.
Not sure what should be a proper solution here, but after deep thinking I may just skip that and think about our own layout based solely on scan codes.

Nevertheless, some function like for example SDL_TranslateScancode(scancode, is shift, is control, is alt, is super) that can translate scancode, shift state etc, based on currently selected OS keyboard layout to standardised SDL_Keycode would be really beneficial.

The problem is that key presses aren’t necessarily (directly) related to characters.
See for example dead keys: pressing first [`] and then [e] will (on many keyboard layouts with “dead keys” enabled) give you an “è” - just pressing [`] doesn’t do anything (for text input) until you press a second key. Of course you still want two SDL_KEYDOWN/UP events, one for each pressed key, but there will only be one SDL_TEXTINPUT event with the “è”.

And there’s even more complicated key combinations for other chars, especially in asian languages (AFAIK); but also think about those combinations like ALT + 0169 to get the © sign (I think this is at least supported on Windows?).

So I don’t think it’s possible to write a SDL_TranslateScancode() function that works reliably.

OTOH I do understand your problem, of course emulators are a very special usecase (compared to games or even normal applications where your SDL-using code should “know” whether it wants to handle a keypress or text input right now, or where to send those different events).
Maybe having a half-assed SDL_TranslateScancode() that at least works as far as possible (by ignoring dead key combinations and such) could be useful for usecases like yours - or also for the SDL1.2-via-SDL2 wrapper which has a very similar problem (because in SDL1.2 there were no textinput events, but key events had a unicode char member).

Disclaimer: I know nothing about C64, never used one.

C64 Keyboard Layouts – breadbox64.com mentions that the C64 could support different keyboard layouts by replacing a ROM.
I wonder if it would be possible to somehow set the emulated C64s keyboard layout (by dynamically emulating the ROM accordingly) in the emulator to match the real one of the host, so you at least don’t need to translate Shift + ['] to Shift + [2], but could just pass on the keypresses to the emulator as they are. Of course that’s not straightforward with SDL either, because for this approach (just like for yours) you need to know the actual layout (incl. what chars modifiers generate), which SDL doesn’t provide. Possible workarounds: 1. let the user select a C64 layout that hopefully is close to their actual layout 2. write OS-specific code to query the keyboard layout.

By the way, whatever you do, key in mind that even Shift + ['] isn’t “common” - it’s that way on US layout keyboards, but not on most other layouts, including German or even UK.

Thanks for the idea, it is really cool, but old fashioned Commodore 64 coders (i.e. users) will not allow that :slight_smile: the aim of the emulator is low-level debugging before putting on the real hardware.

I am going to stick to scancodes and selectable and configurable layouts by the user, thus at least some multiplatform OS name for the selected keyboard layout would be handy, so we can build our own keyboard layout translations database, like it was done with gamepad controllers. Will dig into documentation. Thanks again :slight_smile: