Reputation: 1691
I am building an application for which I need to periodically get information about users keyboard. It is going to be user idle detection application. I have a fairly simple solution to periodically check if the mouse has been moved. But I can't figure any reasonable non root way to detect if the keyboard has been pressed.
I was thinking about registering a hook every timer timeout and on any key press to unregister it. So if there is no key press for a long time then my program will know if the user is idle.
Anyway, I couldn't find any global hooks for any key, including modifiers. Is there an easy way to do this? Or would someone have a better way to detect keyboard idleness?
Thanks
Upvotes: 5
Views: 1695
Reputation: 230
I have some code that can track keyboard activity for you.
#include "stdafx.h"
#include <stdio.h>
#include "windows.h"
#include "iostream"
using namespace std;
int main(void)
{
HANDLE hStdInput, hStdOutput, hEvent;
INPUT_RECORD ir[128];
DWORD nRead;
COORD xy;
UINT i;
hStdInput = GetStdHandle(STD_INPUT_HANDLE);
hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
FlushConsoleInputBuffer(hStdInput);
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
HANDLE handles[2] = { hEvent, hStdInput };
while (WaitForMultipleObjects(2, handles, FALSE, INFINITE))
{
ReadConsoleInput(hStdInput, ir, 128, &nRead);
for (i = 0; i<nRead; i++)
{
switch (ir[i].EventType)
{
case KEY_EVENT:
if (ir[i].Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)
SetEvent(hEvent);
else
{
xy.X = 0; xy.Y = 0;
SetConsoleCursorPosition(hStdOutput, xy);
printf
(
"AsciiCode = %d: symbol = %c\n",
ir[i].Event.KeyEvent.uChar.AsciiChar,
ir[i].Event.KeyEvent.uChar.AsciiChar
);
// note that some keys have a AsciiCode of 0 such as shift, ctrl, and the
// rest you can try out yourself
}
break;
}
}
};
return 0;
}
In this code it tracks keyboard activity and for now it shows the key you pressed and its AsciiCode, also for shift,ctrl, etc the key name won't be shown.
Upvotes: -3
Reputation: 1691
After a lot of searching I found this:
bool kbdActivity(Display* display) // checks for key presses
{
XQueryKeymap(display, keymap); // asks x server for current keymap
for (int i=0; i<32; i++) // for 0 to 32 (keymap size)
{
if (prevKeymap[i] != keymap[i]) // if previous keymap does not
{ // equal current keymap
XQueryKeymap(display, prevKeymap); // ask for new keymap
return true; // exit with true
}
}
return false; // no change == no activity
}
When I call it every 100-300ms it detects any pressed key anywhere in X.
Upvotes: 4
Reputation: 30248
Have a look at xautolock
source, which does exactly what you need, for both keyboard and mouse.
http://www.ibiblio.org/pub/Linux/X11/screensavers/xautolock-2.2.tgz
Upvotes: 1