I'm trying to make a small game using (free)GLUT. I know that it's old and there are better alternatives, but currently I prefer to stick with it and use it as much as possible. I program with C.
I'm currently trying to make GLUT detect properly all the keys I press.
I use glutKeyboardFunc, glutKeyboardUpFunc, glutSpecialFunc and glutSpecialUpFunc to detect pressed keys and I store their state in a short array I created (I currently have only 5 usable keys, so I just created a specific array for them).
However, while everything works fine for 2 keys or less, the game doesn't detect properly 3 keys or more. While for some keys it detect the combination properly (that actually happens for only 1 specific combination), for others the functions simply don't detect the third key that I press.
I checked my code a few times, and there is nothing special about the combination that does work.
I also made glutKeyboardFunc and glutSpecialFunc directly print every key-press that they receive, and it seems they simply stop working after I press more then 2 keys.
Is it a known issue with GLUT or something? I googled a lot and didn't find anyone with a similar issue.
I am not very into GLUT but as I know, but you should make sure, that your keyboard supports more than 2 input keys at once. This feature is called n-key rollover. This page says, that 2-key rollover may be a common value for some keyboards, but you dont need to trust this source.
I'll clarify a point: The glutKeyBoardFunc is a callback i.e., it is invoked for every key pressed and re-executed over and over again and all the if-else (or switch-case) statements for various key combinations are executed. What it means is this - if you were to press 'A', '->' (right arrow) and 'D' all at once, depending on which key-press event was received first the callback will be executed accordingly. Sometimes with a delay and sometimes the on screen animation may stop momentarily.
GLUT is purely for educational/learning purposes but not good for full blown applications since that's not what it was designed for. You land up using OS specific libs or other languages (e.g., Qt) to embed OpenGL "window" within them and execute the keyboard events etc., The event handling in those (and/or OS specific frameworks) is radically different (and better) than GLUT.
You may want to keep your simultaneous key presses to a minimum. You may augment it with the mouse to get rid of the jerky response/processing...
Related
I need to check the toggled state of caps lock and block it.
I have tried using a low-level keyboard hook SetWindowsHookEx with WH_KEYBOARD_LL and checking for WPARAM==WM_KEYDOWN || WPARAM==WM_SYSKEYDOWN messages, and LPARAM.vkCode==VK_CAPITAL || LPARAM.scanCode==0x3A, but this results in me intercepting/blocking caps lock when it's held down/pressed, not when it's actually toggled.
It's important that I intercept the toggled event exclusively because I don't wish to rely on a single press of caps lock toggling its state, and I don't want to disrupt other events in case of caps lock being used as a modifier.
I'm currently using GetKeyState(VK_CAPITAL)&1 to check for caps lock state in my window callback, and forcing it back off with SendInput , but I would rather intercept/block it if any possible.
I have tried Raw Input as well, and it generates a pair of RI_KEY_BREAK And RI_KEY_MAKE messages when caps lock gets toggled, but (unless I'm mistaken), there is no way to block keys based on WM_INPUT messages, and trying to synchronize a hook and Raw Input seems to be difficult because the hook always gets them first.
Using GetKeyState or GetAsyncKeyState from a hook also seems not to work, as they seem to get the event after the hook.
Use GetAsyncKeyState to detect when/if the caps key is hit, and its current state (up or down).
Then call keybd_event (or SendInput) to programmatically set the caps key back to the state that you want it to be.
The following code snippet (along with other setup code) is included in this link, and will toggle CAPS lock on or off when executed:
RUN keybd_event ({&VK_CAPITAL}, 0, {&KEYEVENTF_KEYUP}, 0, OUTPUT intResult).
RUN keybd_event ({&VK_CAPITAL}, 0, {&KEYEVENTF_EXTENDEDKEY}, 0, OUTPUT intResult).
RUN keybd_event ({&VK_SHIFT}, 0, {&KEYEVENTF_KEYUP}, 0, OUTPUT intResult).
RUN keybd_event ({&VK_SHIFT}, 0, {&KEYEVENTF_EXTENDEDKEY}, 0, OUTPUT intResult).
The recommended way to deploy this implementation (GetAsyncKeyState / keybd_event combination) within your application is to encapsulate it into a worker thread set in a forever loop with sleep() set to allow sampling of the state approximately every 100ms.
(Note, I believe GetAsyncKeyState() over GetKeyState() is an improvement for what you want to do here as GetKeyState() gets the key status returned from the thread's message queue. The status does not reflect the
interrupt-level state associated with the hardware. GetAsyncKeyState()
specifies whether the key was pressed since the last call to
GetAsyncKeyState(), and whether the key is currently up or down.) With a reasonable and appropriate sample cycle using GetAsyncKeyState().
The concept above is comprised of functions that run in user-mode, therefore almost certainly limited to implementations of reaction algorithms (detect toggle, then execute another toggle.) as opposed to a true prevention algorithm. (ie, one that either re-maps a key to a no-op at run-time, or trap the request at a low level.)
Most true prevention algorithms would likely make use of Kernel mode driver calls, which are accessible and implementable via the WinAPI and for which concepts are introduce (among other places) by burrowing down through the content here RAWKEYBOARD into areas such as Keyboard and Mouse HID drivers.
A key-mapping approach
The method described below meets the primary need, i.e. to disable the the Caps Lock key from toggling the keyboard into CAPS mode. However, it does not maintain the ability of key to be used as a modifier once it has been re-mapped. (One of the criteria you list.)
The uncap project worked (almost out-of-the-box) for me to disable the Caps Lock key.
Before trying it, I recommend going through the README.md to get the details. In short, it uses a key map approach that allows keys to be mapped to different locations. I found it essentially does what it claims in terms of disabling Caps Lock, and it is capable of doing much more. This could be good or bad. Having the source code available allows you to create a pared down version that simply disables the Caps Key, or do other modifications as needed.
While exploring it, I found a couple of issues that I describe below under problems.
Note that the default behavior is to map Caps Lock key to VK_ESCAPE upon startup. I commented out the following line in the parseArguments(...) function to disable that feature so I could experiment with other mappings...
/*my.keymap[VK_CAPITAL] = VK_ESCAPE;*/
I used uncap.c as the only source file and the following on a Windows 10 machine:
gcc.exe -Wall -g -std=c89 -I"C:\Program Files (x86)\CodeBlocks\MinGW\mingw32\lib" -c C:\play_cb\uncap\uncap.c -o obj\Debug\uncap.o
Problems
It builds with a few warnings related to wrong number of arguments, or format specifiers in sprintf, but once addressing those issues, the code worked as described in this section of documentation.
Although the feature list claims "Disable key mappings easily by stopping Uncap.". did not work. Once the PC was re-booted, normal key mappings are restored.
If the keyboard is set to CAPS ON when uncap is executed, it remains in CAPS mode and the Caps Lock key is not able to undo it :)
I found this link useful when experimenting with mappings: Virtual key codes
You could set a low-level hook with SetWindowsHookEx. Refer to the thread: Best way to intercept pressing of Caps Lock
I have worked a great deal with the text system in Objective-C for macOS/iOS (e.g. NSTextView, NSTextStorage, etc.) I am now experimenting with GTK3 to see how well I can translate my project for use on Linux, etc.
I am brand new to using GTK, but after a few days of Google time and experimenting, I have a working text editor prototype with my custom code plugged in.
The problem is this -- I need to be able to detect when a user highlights a section of text, and then replaces it with other text (e.g. a keystroke). This is distinct from highlighting a section of text, hitting the delete key, and then typing the new text. A specific use example would be highlighting a word, then typing a double quote character in order to wrap the word in quotes (e.g. foo becomes "foo").
In Cocoa, one would receive replaceCharactersInRange: that indicates the range originally selected, as well as the new string to replace it with. I can then detect the presumed intent of the user based on the information received.
In GTK, it seems that we receive a delete-range signal, followed by a separate insert-text signal. Because of this separation, the code in the "insert" section has no way of knowing that the user intended to replace text, not insert new text.
I used the following to receive the signals above:
g_signal_connect(buffer, "insert-text", G_CALLBACK(insert_text_cb), NULL);
g_signal_connect(buffer, "delete-range", G_CALLBACK(delete_range_cb), NULL);
Is there something else I can do in order to tell that there is a delete, followed by an insert as part of the same user action?
Thanks for any pointers offered!
Instead of trying to correlate the delete and insert events, I would suggest creating a GAction for your desired action (e.g. toggle quotes around the selected text) and setting its shortcut key to " using gtk_application_set_accels_for_action().
For more information, check out this HowDoI wiki page.
No answers over the last month, so I kept brainstorming and digging around. I finally came up with this, which works, but is not quite as elegant as I had hoped.
Handle delete-range signal as before, but keep track of the the deleted text for later (e.g. in char * deletedText).
Handle the insert-text signal as before, but if we have a string in deletedText then change the behavior to perform a replacement instead of an insertion. In my case, this actually meant inserting the deleted text back in, and then performing the replacement.
Add a callback for the end-user-action signal, which indicates that all delete/inserts associated with a particular action are complete. In this callback, free deletedText from above and set to NULL (to indicate that everything has been handled).
Again -- this works, but feels a bit inelegant. And depending on how complex your delete/insert routines are, it may slow the performance slightly since some steps have to be duplicated. A better solution would be to detect during the delete-range callback that there is a pending insert-text callback and handle both steps at once. I have thus far not been able to do that.
Is there a way to check for dead keys in the current layout? I am currently capturing the users input for a project I am doing. I created a map of all keys on the keyboard, but there seems to be no flag or whatsoever defining a key as dead or not. I use libxkb in my current code.
The layout is retrieved using
KeySym * keysyms = XGetKeyboardMapping(display_, keycode_low, keycode_high - keycode_low + 1, &num_keysym);
I understand you need to know which key will not directly produce a character, maybe because you are writing a game and do not want to have it use keys as input that would require another key to be pressed to produce some output (if so, please mention in the question)
Not through standard Xlib calls, to my knowledge, and definitely not without actually pressing the respective key. Composing is entirely done within Xlib, and transparent to the front end. (For its original purpose, it should be as transparent as possible to work properly, after all)
You could, however, do the same thing that Xlib does and parse through the various Compose configuration files starting with $HOME/.Xcompose. But that could be a tedious process.
On second thought, I am definitely not proposing the following:
You could, for each key you are looking for information, create a synthetic keypress event and feed it into XLookupString. Hand in an emptied XComposeStatus structure as well. If the structure returns modified, this could be a strong hint you have found a compose key. But it could also mean the server modifies it without any need..... If I were very desparate, I'd probably try.
i am writing a c console application (for windows platform, using msc++ compiler) which requires reading state of some keyboard keys in very short time intervals (of the order of a couple of milliseconds). The read state is then fed into a FSM which provides rich key events (KEY_UP, KEY_RELEASED, KEY_DOWN, KEY_HELD_FOR_LONG_PERIOD, etc.) to rest of the application logic. (basically porting an embedded application to windows platform).
i don't know how to read key states, hence i googled and came across this answer. From what i understand, it basically scans the console events for any key (or mouse) events.
Although, the provided answer is a good starting point but the problem i face is that between successive 'reads' of keyboard state (and when time lag between successive reads is less than 50 ms), i get different answers (at times pressed, at times released) even when the key remains physically pressed. This messes up the FSM logic. But this is probably accepted behavior considering the console might not have new keyboard events in such short time duration. Unfortunately, this doesn't solve my problem.
So how can i
Read RAW state of keyboard keys through some API? (but it has to be consistent between successive reads in short time frames).
Or have .NET equivalent of KEY_UP, KEY_DOWN sort of events (or messages, callbacks, whatever is possible in c) over which i can write a little wrapper so that i don't have to change the FSM logic.
i have a limited understanding of available windows API to solve the task at hand. i am mainly a Embedded/C# guy who either works bare-metal (when developing firmware) or uses .net framework (when developing for windows).
You can read the raw keyboard state with GetAsyncKeyState or GetKeyboardState APIs.
After the suggestion of arx i looked back at the API and the keyboard events and figured out that it was my design of dealing with events which was giving me a problem.. i was polling the events as if they are 'signals' for the current state of keys. Rather events represent 'change' in the signal.
The original design was something like:
if ( there_is_an_event_for (KEY_A) ) // i assumed that events represents a key high state
Update_fsm_for_KEY_A (with_high_signal);
else
Update_fsm_for_KEY_A (with_low_signal);
Since the console gets events upon key_pressed and key_released, this design was inappropriate. This is a new design:
static bool last_key_state = false;
if ( there_is_a_key_pressed_event_for (KEY_A) )
last_key_state = true;
else if (there_is_a_key_released_event_for (KEY_B) )
last_key_state = false;
Update_fsm_for_KEY_A (last_key_state)
Thank You everyone for Your efforts and Help. i am posting and accepting this as an answer. Who knows this might help someone who is struggling with same problem.
I wrote a large complex C program around 20(!) years go. As far as I can recall it worked fine at the time in all respects - it was probably running on windows 95.
Now I need to use it again. Unfortunately the radio buttons in it do not appear to work properly any more (the ordinary push buttons are all behaving correctly). As I click on the radio buttons, I get some feedback that windows is acknowledging my click in as much as I see a dotted line appear around the button's text and the circle of the button goes grey for as long as my finger is on the button, but when I take my finger off I see that the selected button has not changed.
My suspicion is that I was perhaps getting away with some bad practice at the time which worked with windows 95 but no longer works on newer versions of windows, but I'm struggling work out what I did wrong. Any ideas?
EDIT: Its difficult to extract the relevant code because the message handling in this program was a tangled nightmare. Many buttons were created programatically at runtime and there were different message loops working when the program was in different modes of operation. The program was a customisable environment for running certain types of experiment. It even had its own built-in interpreted language! So I'm not expecting an answer like "you should have a comma instead of a semicolon at line 47", but perhaps something more like "I observed similar symptoms once in my program and it turned out to be ..... " .. or perhaps "the fact that the dotted rectangle is appearing means that process AAA has happened, but maybe step BBB has gone wrong".
EDIT: I've managed to extract some key code which my contain an error...
char *process_messages_one_at_a_time()
{
MSG msg;
int temp;
temp = PeekMessage(&msg,winh,0,0,PM_NOREMOVE);
if (temp)
{
GetMessage (&msg, NULL, 0, 0);
if (msg.message == WM_LBUTTONUP)
{
mouse_just_released_somewhere = TRUE;
}
TranslateMessage (&msg);
DispatchMessage (&msg);
}
if (button_command_waiting)
{
button_command_waiting = FALSE;
return (button_command_string);
}
else
{
return (NULL);
}
}
There are two simple things to check when using radio buttons. First is to make sure that each has the BS_AUTORADIOBUTTON property set. The second is to make sure that the first button in the tab order and the next control after the set of buttons (typically a group box) have the WS_GROUP property set, while the other buttons have it clear.
A few suggestions:
I'd try to use spy++ to monitor the messages in that dialog box, particularly to and from the radiobutton controls. I wonder if you'll see a BM_SETCHECK that your program is sending (ie, somewhere you're unchecking the button programatically).
Any chance your code ever checks the Windows version number? I've been burned a few times with an == where I should have used a >= to ensure version checking compatibility.
Do you sub-class any controls? I don't remember, but it seems to me there were a few ways sub-classing could go wrong (and the effects weren't immediately noticeable until newer versions of Windows rolled in).
Owner-drawing the control? It's really easy to for the owner-draw to not work with newer Windows GUI styles.
Working with old code like that, the memories come back to me in bits and pieces, rather than a flood, so it usually takes some time before it dawns on me what I was doing back then.
If you just want to get the program running to use it, might I suggest "compatibility mode".
http://www.howtogeek.com/howto/windows-vista/using-windows-vista-compatibility-mode/
However, if you have a larger, expected useful life of the software, you might want to consider rewriting it. Rewriting it is not anywhere near the complexity or work of the initial write because of a few factors:
Developing the requirements of a program is a substantial part of the required work in making a software package (the requirements are already done)
A lot of the code is already written and only parts may need to be slightly refactored in order to be updated
New library components may be more stable alternatives to parts of the existing codebase
You'll learn how to write current applications with current library facilities
You'll have an opportunity to comment or just generally refactor and cleanup the code (thus making it more maintainable for the anticipated, extended life)
The codebase will be more maintainable/compatible going forward for additional changes in both requirements and operating systems (both because it's updated and because you've had the opportunity to re-understand the entire codebase)
Hope that helps...