How to get a num lock state using C/C++? - c++

I have read Gdk forum link which says that getting num lock state api is implemented since version 3.0. But I am using version 2.4 and I cannot update to version 3.0 as I need to support lower Linux version. Here is the discussion link:
http://mail.gnome.org/archives/commits-list/2010-July/msg00259.html
SO, is there any other way to get the num lock state using internal Linux command?
Regards,
iSight

Sample code to get the NumLock state. Let foo.c be:
#include <stdio.h>
#include <X11/Xlib.h>
int main(void) {
Display *dpy = XOpenDisplay(":0");
XKeyboardState x;
XGetKeyboardControl(dpy, &x);
XCloseDisplay(dpy);
printf("led_mask=%lx\n", x.led_mask);
printf("NumLock is %s\n", (x.led_mask & 2) ? "On" : "Off");
return 0;
}
Then this gives, tested with CentOS 5 on a Dell laptop:
gcc foo.c -o foo -lX11
foo
led_mask=2
NumLock is On
Or you could do something with popen("xset q | grep LED");.
The second bit of the mask is fairly common for NumLock, but I don't believe it is guaranteed.
Original answer: A good starting point is xev, available for about 20 years:
xev
And you can decode key events via:
foobar (XKeyEvent *bar) {
char dummy[20];
KeySym key;
KeySym keyKeypad;
XLookupString(bar, dummy, sizeof dummy, &key, 0);
keyKeypad = XKeycodeToKeysym(..., bar->keycode, NUMLOCK_Mask);
if (IsKeypadKey(keyKeypad))
...;
// ...
}

If you don't care about the Numlock state "while nothing is happening", and only when e.g. a keypress happens, the lowest overhead way is this.
For some XKeyEvent *xke
bool numlock = ((xke->state & Mod2Mask) == Mod2Mask);
For GDK, you might need something like Gdk.FilterFunc to get the xevent. Check xevent->type.
#include <Xlib.h>
XEvent = (XEvent *) &xevent // from Gdk.FilterFunc
int type = event ->type;
switch(type) {
case KeyPress:
case KeyRelease:
do_something_with((XKeyEvent *) event);
break;
}

I did some sniffing around, and I found a possible implementation with ioctl.h that polls the keyboard state and tests that against a couple of flags.
Take a look at this form post's implementation, and replace K_CAPSLOCK with K_NUMLOCK*. It's pretty fugly, but it can easily be wrapped in a function and tucked away.
*The reason for the replacement on the post was because of an old bug where caps lock and num lock were accidentally reversed. It should be fixed now.

I have checked the hard ware key code. Whenever num lock is on and pressed the number key at num pad i compare the hard ware key code which is universally constant to all manufacturer. Hence, I don't need to use ioctl.h header.

You can use this linux command to do it
{
if (num_lock == 0) system("setleds -F +num");
else if num_lock == 1) ; //do nothing
}

Related

How to use "pessimistic" Couchbase locking with the C API?

This is incredibly frustrating... I'm using the Couchbase v3 C API, and I ran into a problem that would be solved perfectly by using their "pessimistic" locking. After much effort I believe I've finally figured out how to lock records using it (with lcb_cmdget_locktime(), which presumably takes a parameter in microseconds), but I can't figure out how to unlock the record once I'm done with it, other than by letting it time out, which isn't an acceptable solution.
The documentation provides one example, here, but for some unknown reason it's in Javascript instead of C (!!!), and the concepts don't map to the C API.
Does anyone know how to unlock a pessimistic lock, or have any example C/C++ code using that API? Barring that, does anyone know where to find the source code for any of the non-C APIs that use the C one, since I should be able to work it out from there? (I haven't been able to locate any of those either, not sure they're open-source.)
Thank you for question
Time in seconds, note that the server might reset time to default, if it larger than maximum time (both durations are configurable). The following command will help to discover effective values for the feature.
$ cbstats -u Administrator -p password localhost all | grep ep_getl
ep_getl_default_timeout: 15
ep_getl_max_timeout: 30
To lock the key, one must use get operation with and set lock time using lcb_cmdget_locktime and capture CAS value in case of successful lock, for instance like this
struct my_result {
lcb_STATUS status{LCB_SUCCESS};
uint64_t cas{0};
};
static void get_callback(lcb_INSTANCE *instance, lcb_CALLBACK_TYPE, const lcb_RESPGET *resp)
{
my_result *res = nullptr;
lcb_respget_cookie(resp, (void **)&res);
res->status = lcb_respget_status(resp);
if (res->status == LCB_SUCCESS) {
lcb_respget_cas(resp, &res->cas);
}
}
It is good idea to put get with lock code into loop
uint64_t locked_cas{0};
int retries = 3;
while (retries > 0) {
std::string document_id{"foo"};
my_result result{};
lcb_CMDGET* cmd = nullptr;
lcb_cmdget_create(&cmd);
lcb_cmdget_key(cmd, document_id.c_str(), document_id.size());
lcb_cmdget_locktime(cmd, 5);
lcb_get(instance, &result, cmd);
lcb_cmdget_destroy(cmd);
lcb_wait(instance, LCB_WAIT_DEFAULT);
if (result.rc == LCB_SUCCESS) {
locked_cas = result.cas;
break;
} else if (result.rc == LCB_ERR_DOCUMENT_LOCKED || result.rc == LCB_ERR_TEMPORARY_FAILURE) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
--retries;
continue;
} else {
std::cerr << "Unexpected issue during get with lock: " << lcb_strerror_short(result.rc) << "\n";
break;
}
}
Once the key got locked, the update operation might be performed, but keep in mind that it MUST use locked_cas, otherwise mutation operation will fail.
std::string document_id{"foo"};
std::string new_value{"new value"};
lcb_CMDSTORE* cmd = nullptr;
lcb_cmdstore_create(&cmd, LCB_STORE_REPLACE);
lcb_cmdstore_key(cmd, document_id.c_str(), document_id.size());
lcb_cmdstore_value(cmd, new_value.c_str(), new_value.size());
lcb_cmdstore_cas(cmd, locked_cas);
lcb_store(instance, nullptr, cmd);
lcb_cmdstore_destroy(cmd);
lcb_wait(instance, LCB_WAIT_DEFAULT);
To unlock key you also need locked_cas, or just wait until server will unlock the document automatically.
std::string document_id{"foo"};
lcb_CMDUNLOCK *cmd = nullptr;
lcb_cmdunlock_create(&cmd);
lcb_cmdunlock_key(cmd, document_id.c_str(), document_id.size());
lcb_cmdunlock_cas(cmd, locked_cas);
lcb_unlock(instance, nullptr, cmd);
lcb_cmdunlock_destroy(cmd);
lcb_wait(instance, LCB_WAIT_DEFAULT);

Get Capslock state on Linux with Wayland

I am struggling with the following task: for our cross-platform application I want to enable a capslock warning for the user. This works perfectly on Windows and macOS and is a bit unnecessarily complicated but doable on Linux with X11, though I cannot find out how to do it properly on Wayland.
We are using Qt5, so the more Qt APIs I can use for this, the better. I see that Qt has a very extensive Wayland framework, but it seems to be designed primarily for writing your own compositor and not for accessing specifics of the underlying platform plugin.
Here's the code as far as I have it:
#include <QGuiApplication>
#include <qpa/qplatformnativeinterface.h>
// namespace required to avoid name clashes with declarations in XKBlib.h
namespace X11
{
#include <X11/XKBlib.h>
}
void checkCapslockState()
{
// ... Windows and macOS one-liners
// Here starts the Linux mess.
// At least I can query the display with this for both X11 and Wayland.
QPlatformNativeInterface* native = QGuiApplication::platformNativeInterface();
auto* display = native->nativeResourceForWindow("display", nullptr);
if (!display) {
return;
}
const QString platform = QGuiApplication::platformName();
if (platform == "xcb") {
unsigned state = 0;
if (X11::XkbGetIndicatorState(reinterpret_cast<X11::Display*>(display), XkbUseCoreKbd, &state) == Success) {
// works fine
newCapslockState = ((state & 1u) != 0);
}
} else if (platform == "wayland") {
// but how to proceed here?
// struct wl_display* waylandDisplay = reinterpret_cast<struct wl_display*>(display);
}
// ...
}
My understanding is that I have to get hold of the Wayland wl_seat object somehow, which holds information about the wl_keyboard. However, I cannot find a way to access these objects from the wl_display object alone without instantiating all sorts of contexts. The Qt application itself is already running as a Wayland client, so there should be a way to access these objects, I would assume. Unfortunately, the Wayland documentation on this is very sparse and quite opaque for someone not familiar with the whole architecture and Wayland's user base is still too small that things pop up on Google.
I found a solution, but I am far from satisfied with it.
I am using KWayland here, but it is possible to use the plain Wayland C API, of course. Be prepared to write 200-300 additional lines of boilerplate code, though. KWayland abstracts that a bit, but it is still pretty verbose. Even the X11 solution is shorter, let alone the one-liners of Windows and macOS.
I don't think this is a state in which Wayland will be pretty successful in the long-term. It's okay to have that much control on the lowest level, but there need to be proper high-level abstractions in place.
Long story short, here's the full code for all platforms:
#include <QGuiApplication>
#if defined(Q_OS_WIN)
#include <windows.h>
#elif defined(Q_OS_MACOS)
#include <CoreGraphics/CGEventSource.h>
#elif defined(Q_OS_UNIX)
#include <qpa/qplatformnativeinterface.h>
// namespace required to avoid name clashes with declarations in XKBlib.h
namespace X11
{
#include <X11/XKBlib.h>
}
#include <KF5/KWayland/Client/registry.h>
#include <KF5/KWayland/Client/seat.h>
#include <KF5/KWayland/Client/keyboard.h>
#endif
void MyCls::checkCapslockState()
{
const QString platform = QGuiApplication::platformName();
#if defined(Q_OS_WIN)
newCapslockState = (GetKeyState(VK_CAPITAL) == 1);
#elif defined(Q_OS_MACOS)
newCapslockState = ((CGEventSourceFlagsState(kCGEventSourceStateHIDSystemState) & kCGEventFlagMaskAlphaShift) != 0);
#elif defined(Q_OS_UNIX)
// get platform display
QPlatformNativeInterface* native = QGuiApplication::platformNativeInterface();
auto* display = native->nativeResourceForWindow("display", nullptr);
if (!display) {
return;
}
if (platform == "xcb") {
unsigned state = 0;
if (X11::XkbGetIndicatorState(reinterpret_cast<X11::Display*>(display), XkbUseCoreKbd, &state) == Success) {
newCapslockState = ((state & 1u) != 0);
}
} else if (platform == "wayland") {
if (!m_wlRegistry) {
auto* wlDisplay = reinterpret_cast<struct wl_display*>(display);
m_wlRegistry.reset(new KWayland::Client::Registry());
m_wlRegistry->create(wlDisplay);
m_wlRegistry->setup();
// wait for a seat to be announced
connect(m_wlRegistry.data(), &KWayland::Client::Registry::seatAnnounced, [this](quint32 name, quint32 version) {
auto* wlSeat = new KWayland::Client::Seat(m_wlRegistry.data());
wlSeat->setup(m_wlRegistry->bindSeat(name, version));
// wait for a keyboard to become available in the seat
connect(wlSeat, &KWayland::Client::Seat::hasKeyboardChanged, [wlSeat, this](bool hasKeyboard) {
if (hasKeyboard) {
auto* keyboard = wlSeat->createKeyboard(wlSeat);
// listen for a modifier change
connect(keyboard, &KWayland::Client::Keyboard::modifiersChanged,
[this](quint32 depressed, quint32 latched, quint32 locked, quint32 group) {
Q_UNUSED(depressed)
Q_UNUSED(latched)
Q_UNUSED(group)
newCapslockState = (locked & 2u) != 0;
// emit signals etc. here to notify outer non-callback
// context of the new value of newCapslockState
});
}
});
});
}
}
// do something with the newCapslockState state for any
// platform other than Wayland
}
m_wlRegistry is defined as a QScopedPointer<KWayland::Client::Registry> member in the header file.
This solution basically works, but suffers from either a bug in KWin or a weirdness of the protocol (I don't know which). Pressing the Capslock key will trigger the inner lambda callback twice: first time with bit 2 in locked set and a second time on key release with it unset. There is no reliable way of filtering out this second activation based on the other parameters passed (I tried ignoring when depressed != 0, but it's not working as expected). Pressing any other key after that will trigger the callback a third time with the bit set again. So when you are actually typing, the code works, but when you are just pressing Capslock, the behaviour is weird and less reliable than the solutions for other platforms. Since the Capslock indicator in the Plasma tray has the same issue, I would assume this is a bug.
As a KDE-specific solution, there appears to be another interface one could listen to called org_kde_kwin_keystate (https://github.com/KDE/kwayland/blob/master/src/client/protocols/keystate.xml). However, when I was testing it in a KDE Neon VM, the compositor did not announce this protocol extension, so I was unable to use it.

C++ Finding Index for Font temporarily added to System Font Table with AddFontResource() to use in Console

I am trying to temporarily install a font to use in the win32 console with
int AddFontResource(LPCTSTR lpszFilename);
and
BOOL WINAPI SetConsoleFont(HANDLE hOutput, DWORD fontIndex)
I got hold of this function from this site.
Although both functions seem to work fine I have no idea how to find the added font index to use with SetConsoleFont.
AddFontResource returns no index value or key to the temporary font.
Here is my relevant code:
#include "Level.h"
#include "ConsoleFont.h" //acquired from above mentioned site
#include <Windows.h>
//-------------------------------------------------------------------------------
void init();
void cleanup();
int main()
{
FileManager *pFileManager = new FileManager(); //unrelated
Level *lvl1 = new Level("filename",pFileManager); //unrelated
///TEMPORARY PLANNING
// using add font resource. how can i get this fonts index value?
int err = AddFontResource(L"Files/gamefont.fnt");
if (err == 0)
{
MessageBox(NULL,L"loading font failed",L"Error",0);
}
else
{
wchar_t message[100];
swprintf_s(message,100,L"AddFontResource returned: %d",err);
MessageBox(NULL,LPTSTR(message),L"error",0);
}
SendMessage(HWND_BROADCAST, WM_FONTCHANGE,0,0);
//acquiring handle to current active screen buffer
HANDLE tempHandle = GetStdHandle(STD_OUTPUT_HANDLE);
if (tempHandle == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,L"Failed to aquire Screen Buffer handle",L"Error",0);
}
//I dont know what to set this to. this is the crux of the problem.
DWORD fontIndex = 1;
if (FALSE == SetConsoleFont(tempHandle,fontIndex))
{
MessageBox(NULL,L"loading console font failed",L"Error",0);
}
//draws a house when in correct font
std::cout<<"!!!!!!!!#\n"
<<"!!!!!!!!!\n"
<<"! !! !! !\n"
<<"!!!!!!!!!\n"
<<"! !! !! !\n"
<<"!!!!!!!!!\n"
<<"! !! !! !\n"
<<"!!!!!!!!!\n"
<<"! !! !! !#\n"
<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<std::endl;
///PLANNING OVERS
bool quit = false;
while(!quit)
{
//still to be implemented
}
err = RemoveFontResource(L"Files/gamefont.fnt");
if (err==0)
{
MessageBox(NULL,L"removing font failed",L"Error",0);
}
return 0;
}
I don't know how to go about finding my new font's index value or even if this is possible using my current method.
If someone knows or has a better method please help me out.
any help or hints are appreciated. It must possible to use a custom font in the win32 Console without fiddling with the registry. I'm sure of it :)
Unfortunately you entered the dark world on Win APIs. There is no documentation (or atleast I could never find it) for a console font table lookup. You can try the method "GetNumberOfConsoleFonts()" to see what is returned. I think the font at index 10 is Lucida Console. You'll have to play around a little. Also, this may not work for the OS version you have. Worked for me on XP. Never had to try on anything else. And honestly, never got it fully working on XP too.
For the registry,
Fonts registries are here:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts
Console registries are here:
HKEY_CURRENT_USER\Console
If you end up modifying the registry, the changes may not be reflected immediately. You need to either restart the console or send a special WM_* message (sorry don't remember the name).
Will be great if you can find a solution/workaround :)
int err = AddFontResource(L"Files/gamefont.fnt");
if (err == 0)
{
MessageBox(NULL,L"loading font failed",L"Error",0);
}
else
{
wchar_t message[100];
swprintf_s(message,100,L"AddFontResource returned: %d",err);
MessageBox(NULL,LPTSTR(message),L"error",0);
}
this is wrong AddFontResource returns the number of fonts loaded, so the code in the ELSE doesn't make sense.

How to check if an opencv window is closed

How do you check if an opencv window has been closed?
I would like to do:
cvNamedWindow("main", 1);
while(!cvWindowIsClosed("main"))
{
cvShowImage("main", myImage);
}
but these is no such cvWindowIsClosed(...) function!
What you are trying to do can be achieved with cvGetWindowHandle():
The function cvGetWindowHandle returns the native window handle (HWND in case of Win32 and GtkWidget in case of GTK+). [Qt Backend Only] qt-specific details: The function cvGetWindowHandle returns the native window handle inheriting from the Qt class QWidget.
The idea is to get the handle of the window and then use specific platform API functions to check if that handle is still valid.
EDIT:
Or you could use the tradicional cvWaitKey() approach:
char exit_key_press = 0;
while (exit_key_press != 'q') // or key != ESC
{
// retrieve frame
// display frame
exit_key_press = cvWaitKey(10);
}
Suppose you have only one image window open, then clicking the 'x' button at its corner causes the waitkey() function to return a -1 value.
Then check if the cvGetWindowHandle("name_of_the_window") function returns 0 or not. If it does return 0, then the window is actually closed.
I have tested it in OpenCV3.
But I am still not very clear on the reason why the waitkey() return -. I will much appreciate if anyone explains why this happens.
[I don't know if my answer to this question will be relevant or not after such a long time. But hopefully if anyone else gets stuck with the same issue (like me), this answer might help them out.]
Thanks.
You can use the cv::getWindowProperty method.
Do like that:
cv::namedWindow("main", WINDOW_AUTOSIZE);
while(1)
{
cv::imshow("main", myImage);
// add this IF.
if (cv::getWindowProperty("main", WND_PROP_AUTOSIZE) == -1)
break;
}
When the windows be closed the getWindowProperty will return -1.
This should do
#include <opencv2/opencv.hpp>
std::string mTitle = "title of my window";
while (cvGetWindowHandle(mTitle.c_str()))
{
// ...
}
In Python OpenCV version 3.4.2, Ubuntu Bionic, cv2.getWindowProperty('Main', cv2.WND_PROP_VISIBLE) returns a floating 0.0 (zero) when the window is closed and 1.0 (one) when it's open, whether see-able or not. Yes, still a 1.0 when it's minimized or behind another window or on a different desktop.
Just before the end of the main(), put the following code:
int main(int, char**){
.
.
.
bool visible = true;
while(visible){
waitKey(1000);
visible = getWindowProperty("Main",WND_PROP_VISIBLE) > 0;
}
return 0;
}

How do I turn off or ignore key repeat for my curses application?

So I recently found curses (specifically PDcurses) and I'm just getting into it. Right now I'm trying to write a little space shooter type game with it and it's worked fine so far for rendering and getting menu type input, but now when I go into the game, I've noticed that key repeat is pretty bad for action games. I need to be able to hold the key and move my avatar every single frame that the key is down. I know how to do this with a normal Win32 application, but I don't have a window and therefore I don't have a wndproc and I can't control the messages the console recieves :/
I don't expect this is something for curses to handle, though if it can that would be awesome, I was really just looking for a work-around that plays nicely with curses.
I have tried cbreak(), nodelay() and raw() to no avail.
Additional info:
Microsoft Visual Studio 2010 Ultimate
PDcurses 3.4, from prebuilt binaries
Windows 7 x64 Ultimate
This is far from a complete solution, and I don't know how it'll interact with PDCurses, but it's an attempt:
In summary, grab the console's handle with GetStdHandle(), configure it for raw reading with SetConsoleMode(), and then read keys one at a time with ReadConsoleInput(). I use a std::set to keep track of the currently pressed keys and so ignore repeats.
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <cassert>
#include <set>
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE h=GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
BOOL success;
success=GetConsoleMode(h, &mode);
assert(success);
mode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
mode |= ENABLE_WINDOW_INPUT;
success=SetConsoleMode(h, mode);
assert(success);
INPUT_RECORD buffer[10];
std::set<WORD> keys_down;
while (true)
{
DWORD count=0;
success=ReadConsoleInput(h, buffer, 10, &count);
if (!success)
{
continue;
}
for (size_t i=0;i<count;++i)
{
switch (buffer[i].EventType)
{
case KEY_EVENT:
{
WORD keycode=buffer[i].Event.KeyEvent.wVirtualKeyCode;
if (buffer[i].Event.KeyEvent.bKeyDown)
{
if (keys_down.find(keycode)==keys_down.end())
{
std::cout<<"Key down: "<<keycode<<std::endl;
keys_down.insert(keycode);
}
}
else
{
if (keys_down.find(keycode)!=keys_down.end())
{
std::cout<<"Key up:"<<keycode<<std::endl;
keys_down.erase(keycode);
}
}
break;
}
default:
break;
}
}
}
}