Я работаю в проекте, который должен распознавать позиции физических клавиш, Control, Shift и Winkey. Мне нужно знать, где находится каждая из клавиш «Влево» или «Вправо» на клавиатуре.
Для этого мне нужно обработать X11events и WinEvents, используя Qt. Я сделал это довольно хорошо в Windows, забыв ужасную часть об Alt Gr, я пока не могу справиться. В Linux я пытался сделать то же самое:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#if WIN32
#include <windows.h>
#else
#include <X11/XKBlib.h>
#ifdef KeyPress
const int XKeyPress = KeyPress;
#undef KeyPress
#endif
#endif
#include "main.h"
#include <QFile>
#include <QDebug>
#include <QX11Info>
#if WIN32
bool MainWindow::winEvent( MSG* msg, long* result )
{
if(msg->message == WM_KEYDOWN || msg->message == WM_HOTKEY)
{
SHORT state;
switch(msg->wParam)
{
case VK_CONTROL:
// the Alt Gr is handled using Ctrl+Alt+Shift (I Guess)
state = GetKeyState(VK_SHIFT);
if(state == TRUE)
keyPressEvent(msg->wParam, "Key_AltGr");
else{
state = GetKeyState(VK_LCONTROL);
if(state & VK_LCONTROL)
keyPressEvent(msg->wParam, "Key_ControlL");
else
keyPressEvent(msg->wParam, "Key_ControlR");
}
break;
case VK_SHIFT:
state = GetKeyState(VK_LSHIFT);
if(state & VK_LSHIFT)
keyPressEvent(msg->wParam, "Key_ShiftL");
else
keyPressEvent(msg->wParam, "Key_ShiftR");
break;
case VK_MENU:// alt
state = GetKeyState(VK_SHIFT);
if(state == TRUE)
keyPressEvent(msg->wParam, "Key_AltGr");
break;
case VK_SNAPSHOT:
keyPressEvent(msg->wParam, "Key_Print");
break;
default:
return false;
}
return true;
}
return false;
}
#else
bool MainWindow::x11Event(XEvent *xe)
{
switch(xe->type)
{
case XKeyPress:
switch (xe->xkey.keycode)
{
case 37://Control_L
keyPressEvent(xe->xkey.keycode, "Key_ControlL");
break;
case 105://Control_R
keyPressEvent(xe->xkey.keycode, "Key_ControlR");
break;
case 50://Shift_L
keyPressEvent(xe->xkey.keycode, "Key_ShiftL");
break;
case 62://Shift_R
keyPressEvent(xe->xkey.keycode, "Key_ShiftR");
break;
case 133://Super_L
keyPressEvent(xe->xkey.keycode, "Key_SuperL");
break;
case 134://Super_R
keyPressEvent(xe->xkey.keycode, "Key_SuperR");
break;
default:
return false;
}
return true;
break;
}
return false;
}
#endif
в методе x11Event, случай XKeyPress (в режиме отладки - 2) никогда не выполняется, но если вы посмотрите на:
grep KeyPress /usr/include/X11/X.h
#define KeyPressMask (1L<<0)
#define KeyPress 2
Константа верна, но тип никогда не равен 2. Если я изменю константу XKeyPress на 28, она будет выглядеть как
maiko@cits-d530:release$ grep 28 /usr/include/X11/X.h
#define PropertyNotify 28
#define FirstExtensionError 128
хорошо работает.
Thx