pythonkeyboardctypessdl-2pysdl2

PySDL2 and SDL_GetKeyboardState


I'm trying to learn SDL via PySDL2 (currently version 0.7.0; source / documentation). It provides a ctypes Python wrapper to (I assume) all of SDL's normal functions, and it provides a few more Pythonic functions via its sdl2.ext package to handle the nitty-gritty and return results in Python types. For example, sdl2.ext.get_events() will call sdl2.SDL_PumpEvents(), then peep at all the events on the queue and return them as a Python list.

However, I cannot tell if such a convenience function exists for SDL_GetKeyboardState(). The official SDL Wiki documentation for the function defines it as:

const Uint8* SDL_GetKeyboardState(int* numkeys)

where numkeys may be null (otherwise it will receive the length of the returned array) and the returned Uint8* is a pointer to an array of key states, indexed by SDL_Scancode values, which will hold 1 if the key is down or 0 if it is up.

PySDL2 does provide a direct call to SDL_GetKeyboardState via sdl2.keyboard.SDL_GetKeyboardState(numkeys), but that returns a ctypes value that is not immediately useful.

So my question is, is there some more Pythonic function for getting the current SDL keyboard state via PySDL2? If there is, what is it and how should it be used? If there's not, should one be submitted?

For reference, I think I figured out how to achieve this functionality myself, but it was a rough baptism in ctypes so I might have mangled something:

import ctypes
import sdl2


KEYBOARD_ARRAY_TYPE = ctypes.c_uint8 * sdl2.SDL_NUM_SCANCODES


def get_keyboard_state():
    """ Returns a pointer to the current SDL keyboard state,
    which is updated on SDL_PumpEvents. """
    raw_keystate = sdl2.keyboard.SDL_GetKeyboardState(None)
    pointer = ctypes.cast(raw_keystate, ctypes.POINTER(KEYBOARD_ARRAY_TYPE))
    return pointer.contents

Solution

  • Here's a modification that uses numkeys instead of the constant SDL_NUM_SCANCODES:

    import ctypes
    import sdl2
    
    def get_keyboard_state():
        """ Returns a list with the current SDL keyboard state,
        which is updated on SDL_PumpEvents. """
        numkeys = ctypes.c_int()
        keystate = sdl2.keyboard.SDL_GetKeyboardState(ctypes.byref(numkeys))
        ptr_t = ctypes.POINTER(ctypes.c_uint8 * numkeys.value)        
        return ctypes.cast(keystate, ptr_t)[0]