Check Q button is held down using GLUT? - c++

What function can I use to check if the Q button (or any other button is pressed down) and what will be the value needed to specify this for the Q button?

Using glut you need to define a Keyboard Handler function, and tell GLUT to use it for handling key strokes. Something along the lines of:
bool is_q_pressed = false;
void KeyboardHandler(unsigned char key, int x, int y)
{
switch (key)
{
case "q":
case "Q":
is_q_pressed = !is_q_pressed;
if (is_q_pressed)
// do something... or elsewhere in program
break;
}
}
void KeyboardUpHandler(unsigned char key, int x, int y)
{
switch (key)
{
case "q":
case "Q":
is_q_pressed = false;
break;
}
}
int main()
{
// Other glut init functions...
...
// Keyboard handler
glutKeyboardFunc(KeyboardHandler);
// Keyboard up handler
glutKeyboardUpFunc(KeyboardUpHandler);
...
glutMainLoop();
return 0;
}
EDIT: Added support for keyboard up. Using global variables isn't the best practice, but GLUT almost forces you to use them to keep track of program states. The good thing is that you can use the global variable (is_q_pressed) anywhere in your program... like in the idle() for some logic, or in the draw function to draw something if that key is pressed.
And, as #aslg said, you can make an array of bools to keep track of every key pressed, check his answer for ideas too :)

The simplest thing you can do is to use an array of bools with enough bools to contain the 256 regular keys and the special keys (right, left, etc.. ).
bool keys[256];
Use the KeyDown func to set the matching key to true, and KeyUp to set false.
void KeyboardDown( int key, int x, int y ) {
if ( isalpha( key ) ) {
key = toupper( key );
}
keys[ key ] = true;
}
void KeyboardUp( int key, int x, int y ) {
if ( isalpha( key ) ) {
key = toupper( key );
}
keys[ key ] = false;
}
The toupper just makes sure that pressing q or Q is the same whether Caps-lock is on or off. You don't have to use it if you don't need it.
Then somewhere in the update code you can check if a key was pressed like
if ( keys['Q'] ) {
// do things
}

Related

Getting key name from keycode (X11 XGrabKey)

I have a global key event handler in linux as below. I need to know which keyboard is grabbed. For example if key 'P' is pressed I get the corresponding key code. Is there any way to get the key name ("P") from this unsigned key code ?
#include <xcb/xcb.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <QtX11Extras/QX11Info>
void EventFilter::setup(QWidget *target)
{
this->target = target;
Display * display = QX11Info::display();
unsigned int modifiers = ControlMask;
keycode = XKeysymToKeycode(display, XK_A);
XGrabKey(display, keycode, modifiers, DefaultRootWindow(display), 1, GrabModeAsync, GrabModeAsync);
}
bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *)
{
if (eventType == "xcb_generic_event_t")
{
xcb_generic_event_t* xcbevent = static_cast<xcb_generic_event_t *>(message);
switch(xcbevent->response_type)
{
case XCB_KEY_PRESS:
xcb_key_press_event_t * keypress_event = static_cast<xcb_key_press_event_t *>(message);
if(keypress_event->state & XCB_MOD_MASK_CONTROL)
{
if(keypress_event->detail == keycode)
{
//print key name here
}
}
}
}
return false;
}
Given a key code, from the event detail field, you can get the KeySym using the XkbKeycodeToKeysym function, then a textual representation of the pressed key, passing the KeySym to the XKeysymToString function.
Have this extra include:
#include <X11/XKBlib.h>
Then, in the event handler:
case XCB_KEY_PRESS:
xcb_key_press_event_t * keypress_event = static_cast<xcb_key_press_event_t *>(message);
xcb_keycode_t code = keypress_event->detail;
qDebug() << XKeysymToString( XkbKeycodeToKeysym(QX11Info::display(), code, 0, 0) );
In the example above, an index of 0 is passed as the last argument of XkbKeycodeToKeysym. This will return the symbol for the pressed key as if the shift key (or caps lock, or any other modifier key) is not pressed. Passing an index of 1 will return the symbol as if the shift key was pressed. Other values (i.e. 2) will yield symbols one obtains pressing more modifier keys (e.g. in my italian keyboard I have to press Alt Gr to type square brackets).
Please notice, the returned string is really a name to identify the keyboard symbol, which can be, for example, a, b, c or X for letters, but comma, or backslash for other symbols.

Detect only one keypress in C++

I'm trying to use the glut framework to handle keypresses for a game I'm writing in c++. When a specific key is pressed, I want to start drawing a new curve and so I create a new curve and add it to my container of curves. However, when I use onKeyboard and debug I see that this function is called over and over when a key is pressed, not just on the initial press. Therefore, it's creating about 12 curves every time a key is pressed. My code for onKeyboard is below. Any help would be appreciated greatly!
void onKeyboard(unsigned char key,int x, int y) {
keysPressed[key] = true;
switch (key) {
case 'l':
curvesContainer.addCurve(new lCurve());
break;
case 'p':
curvesContainer.addCurve(new pCurve());
}
glutPostRedisplay();
}
You would simply check if keyPressed[key] is already true, and only add your curve if it is false.
void onKeyboard(unsigned char key,int x, int y)
{
if (keysPressed[key] == false)
{
keysPressed[key] = true;
switch (key)
{
case 'l':
curvesContainer.addCurve(new lCurve());
break;
case 'p':
curvesContainer.addCurve(new pCurve());
break;
}
}
glutPostRedisplay();
}
You will additionally need to clear keysPressed[key] in an onKeyUp event, using glutKeyboardUpFunc
void onKeyUp(unsigned char key,int x, int y)
{
keysPressed[key] == false;
}
glutIgnoreKeyRepeat(1) is probably what you want. (1 = on)
Use input flush define in studio.in
It avoid rest of input

wxWidgets keyboard event

I have a problem with using Key event:
there is example in documentation:
void OnChar(wxKeyEvent& event, double moveSpeed)
{
wxChar uc = event.GetUnicodeKey();
if ( uc != WXK_NONE )
{
...
}
else // No Unicode equivalent.
{
// It's a special key, deal with all the known ones:
switch ( event.GetKeyCode() )
{
case WXK_LEFT:
case WXK_RIGHT:
break;
case WXK_F1:
break;
}
}
but what if i have to use keyboards event in different function ?
I know that in other library you can simply use:
if (keyDown(SDLK_DOWN))
{
//code
}
but how can I use that in wxwidgets ?
You can use wxGetKeyStats() function if you really need to, but usually you definitely want to react to keyboard events instead of checking for the key state.

Better implantation of key pressed down

I am currently executing a GetAsyncKeyState event handler when the 'c' key is pressed down in C++.
Here is my code:
bool isKeyPressed = false;
void someFuntionOne()
{
if( GetAsyncKeyState( 'C' ) & 0x8000)
{
if(isKeyPressed)
{
isKeyPressed = false;
}
else
{
isKeyPressed = true;
}
}
}
void someFunctionTwo()
{
if(isKeyPressed)
{
// Do something
}
}
So bassically I want to know if the 'C' has been pressed not held down so I use my boolean variable isKeyPressed to tell me if the key was pushed down at any point. If it was pressed, set isKeyPressed to true and if it was pressed again set isKeyPressed to false.
The problem I have with this is I am running a huge OpenGL/C++ program that takes a lot of time to go around and execute the entire program in a single iteration so if the user presses down on the 'C' key, the program may not catch that event in time because it is still executing the rest of the other code and is currently not at the section of the code where it checks if GetAsyncKeyState( 'C' ) & 0x8000.
Is there a better way I can check for this event where the program is always listening for the event to happen at any point of execution time? How can I implement this?
Usually whoever delivers the events to your application will queue them until the application has the chance to process them, i.e. at the end of each main loop iteration. So ideally you would react to the events at that stage. An (ugly) alternative is something like:
bool keyWasPressed = false;
void processKeyEvent() {
if( <C is pressed>) {
keyWasPressed = true;
}
}
void someFunction() {
if(keyWasPressed) {
keyWayPressed = false;
// Do something
}
}

Handling key events in SDL and C++

I'm in the process of migrating a program from GLUT to SDL. In my current program pressing the a key results in a different response then pressing the A key. This was pretty straightforward to do in GLUT as it the keyboard function callback passed in the ASCII value of the key that was pressed.
void keyPressedFn(unsigned char key, int x, int y){
switch(key){
case 'a':
// do work for a
break;
case 'A':
// do work for A
break;
}
}
I'm struggling to replicate similar functionality in SDL as pressing the a key produces the same response regardless of if SHIFT or CAPS LOCK are pressed as well.
Is there a simple way of replicating the above function in SDL?
Edit: In the example above I only show how to handle one key, in practice however, I am going to have a list of about 15 keys that I want to respond to differently if the shift key is pressed as well.
Check the keyboard modifiers that are present when you get a keydown event. For example:
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
if(event.key.keysym.sym == SDLK_a)
{
if(event.key.keysym.mod & KMOD_SHIFT)
{
// Handle 'A'
}
else
{
// Handle 'a'
}
}
break;
...
}
}
SDL_keysym has mod field, which contains state of modifier keys at the time the event has been emitted. Bit-AND it with KMOD_SHIFT to check whether Shift has been active. See SDL wiki.
Why not just do this?
void keyPressedFn(unsigned char key, int x, int y){
switch(key){
case 'a':
case 'A':
// do work for A or a
break;
}
}
Do you have some other concerns that you cannot do as what I have suggested? If not I think this is as simple as it can get.