4

I am using xlib to get keyboard input I want to simulate windows its getAsynckeystate() to check if a button is being pressed I tried using a timer to fix the result but its still broken. the function should always return true if 'z' is held down even if other keys are pressed or released at the same time (not working right now)

Code below

bool KeyboardState::keyPressed(Display* d, Window curFocus,int revert, Window root) {
XEvent ev;
XNextEvent(d, &ev);
clock_t startTime;
switch (ev.type) {
    case FocusOut:
        if (curFocus != root)
            XSelectInput(d, curFocus, 0);

        XGetInputFocus(d, &curFocus, &revert);
        printf("New focus is %d\n", (int) curFocus);

        if (curFocus == PointerRoot)
            curFocus = root;

        XSelectInput(d, curFocus, KeyReleaseMask | FocusChangeMask | KeyPressMask);
        break;

    case KeyPress:
        ks = XLookupKeysym(&(ev.xkey), 0);

        if (ks == XK_z) {

            keyState = true;
            startTime = clock();
        }
        break;
    case KeyRelease:
        if(ks == XK_z && startTime - clock() > 0){

        ks = XLookupKeysym(&(ev.xkey), 0);
            keyState = false;
        }
}
return keyState;
}
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
  • 1
    `if (ks == ...) ...; ks = ...;` If you first use a variable and then assign a value to it, your program has a slight chance of erratic behaviour. In addition, `clock()` is a wrong time function to check against, for a number of reasons, and the check itself is redundant. A key release cannot arrive before a key press. – n. m. could be an AI Jul 31 '16 at 11:01
  • My program doesn't care about press presses or key releases they both get fired at the same time Why does the unix system not support the famous 'HOLD KEY' event..... – Mercenary_Frank Jul 31 '16 at 11:13
  • I cannot parse your sentence. Your program has a bug right after `case KeyRelease`, fix it. Sorry, no idea what a 'HOLD KEY' event is and what it's famous for. – n. m. could be an AI Jul 31 '16 at 11:18
  • For holding a key like if you do this in windows `if(getasynckeystate('z')){}` why can't the same thing exist in linux no wonder nobody uses this OS... – Mercenary_Frank Jul 31 '16 at 11:26
  • This is not a place to post rants. – n. m. could be an AI Jul 31 '16 at 11:42
  • https://tronche.com/gui/x/xlib/input/XQueryKeymap.html – n. m. could be an AI Jul 31 '16 at 11:51
  • Thank you it works sorry for being so angry I spend the entire day looking for that function – Mercenary_Frank Jul 31 '16 at 11:57

2 Answers2

3

n.m linked following function which is accepted as answer:

tronche.com/gui/x/xlib/input/XQueryKeymap.html

Andrew Bainbridge
  • 4,651
  • 3
  • 35
  • 50
Andreas
  • 5,086
  • 3
  • 16
  • 36
0

I wrote the following code snippet to help do keyboard shortcuts with multiple non-modifier keys e.g. super + up + right.

#include <X11/Xlib.h>

// Returns 0 if key is not down;
// A non-zero integer if it is down.
// targetString should be appropriate for XStringToKeysym.
int is_down(Display *dis, char *targetString)
{
    char keys_return[32] = {0};
    KeySym targetSym = XStringToKeysym(targetString);
    KeyCode targetCode = XKeysymToKeycode(dis, targetSym);

    int targetByte = targetCode / 8;
    int targetBit = targetCode % 8;
    int targetMask = 0x01 << targetBit;
    
    XQueryKeymap(dis, keys_return);
    return keys_return[targetByte] & targetMask;
}

I've posted a more complete example with compilation instructions on GitHub. You can find a complete list of key names in a file named X11/keysymdef.h; on my Arch computer it was at /usr/include/X11/keysymdef.h. I also found an example on the web as the second Google result for x11 keysymdef.

Mark Peschel
  • 115
  • 3
  • 10