How can I intercept and block the caps lock toggle event globally, leaving other events intact? - c

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

Related

X11/Xlib: virtual keyboard input and keyboard mapping synchronization issue

For an automated test application I have to simulate large amount of unicode keyboard input into an old X11 application (of which I don't have any source access).
My program takes the input from an UCS-2 LE encoded input stream via stdin and the basic operation is as follows:
Save current keyboard layout and lock modifiers (XDisplayKeycodes, XGetKeyboardMapping, XkbGetState)
Unlock active modifiers (XkbLockModifiers)
Disable all X11 slave keyboard devices via Xinput2 extension
Read input into a key press queue until n unique symbols are encountered, where n is the number of possible keycodes as returned by XDisplayKeycodes.
Map these n unique X11 KeySyms via XChangeKeyboardMapping on the n available KeyCodes
Type the correct KeyCodes for all enqueued KeySyms via XTestFakeKeyEvent
Clear the queue and continue at 4.) until no input is available
Reactivate keyboards and restore initial modifiers and mappings
Basically this system works better and much more performant than any virtual X11 key input tool I've seen so far.
However, there is an issue I can currently only fix using ugly delays:
As any other X11 application, the target application receives a MappingNotify (request==Keyboard) event from the X server after my application succeeded in changing the keyboard mapping table.
The usual response of a X11 client is to call XRefreshKeyboardMapping to update Xlib's knowledge of the new keyboard layout.
Now if the the client has some lag processing its X11 event queue, the XRefreshKeyboardMapping call might return a too recent mapping that is already some generations too far in the future.
E.g. my input generator has already done the fourth XChangeKeyboardMapping when the target application just arrived at handling the second MappingNotify event in its XEvent queue handler.
Actually it should get the second generation of the map, which isn't available at the X server anymore at that time.
Unfortunately there is no map id or version of any kind in the keyboard MappingNotify event so that XRefreshKeyboardMapping could refer to a specific map ... and the X server does not seem to keep a history either.
The result is that the X11 application's KeyCode to KeySym conversion operates with an invalid layout and generates wrong KeySyms.
So basically I have to wait until all clients (or at least the one with the input focus) have requested and received my last XChangeKeyboardMapping map before I am allowed to do the next XChangeKeyboardMapping.
I can fix 99.9% of the errors using a delay before XChangeKeyboardMapping and that delay is calculated by some ugly witchcraft (amount of key strokes etc.) and is way to high if 100% accuracy has to be achieved.
So my question is if there is any way to programmatically be notified or to check if a X11 client has completed XRefreshKeyboardMapping or if its map is in sync with the server map?
If not, is there a way to get another X11 client's current mapping via xlib (to check if the map is current)?
Thanks for any hints!
I've done something similar on Windows in the past. I had the luxury of being able to use the SendInput function which accepts a KEYBDINPUT structure with KEYEVENTF_UNICODE flag. Unfortunately X11 does not support direct keystroke synthesizing of Unicode characters.
Since I cannot comment yet I'm forced to give a suggestion as answer:
Have you considered using the clipboard instead in order to transfer your "unicode input" into this X11 application's input field ?
You also might consider using direct Unicode input if that application uses a toolkit that supports this:
E.g. programs based on GTK+ (that includes all GNOME applications) support Unicode input.
Hold Ctrl + Shift and type u followed by the Unicode hex digits and release Ctrl and Shift again.
I guess it should be easy to synthesize these sequences using the Xtest extension.

How to detect when text is replaced in GtkTextBuffer instead of delete followed by insert?

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.

Get a list of dead keys in X11

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.

What are the exit codes used by RASPHONE.exe?

Due to a major time constraint, need to stick with invoking rasphone.exe from my c program, rather than best approach of using RAS API's. From my code, when the rasphone pop's up a dialler window to the user, if the user click's on cancel button, i have to stop blocking another set of code.
Ultimately, i need to handle the rasphone returns to control my code flow based on the Success/Failure-Cancel. How to do this? Also, is there any other possibility for silent dialling without any popup?I hope no, as its discussed.

GLUT doesn't detect properly more then 2 keys pressed?

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...

Resources