??????ó???
??????????????????????????????ο????????????????????????????????????????????????Щ????????????????д???????????????????????????????????
??????ó???????????????????????????????????????????ù????ие?????????????????ó?????????????????????????
??????????????ó????????????????????????ο?(Gtk+??Qt???????????????????????????????????????????????????????????????????3?????
????· ??????????????????????????????
????· ??????????????????????????????
?????????Gtk????Qt????????????X11???????????????????????????м?????
????X11??????????????????
????· ??? XGrabPointer ?? XGrabKeyboard ???????????????????
????· ??? XRecord Extension ??????????????????
????XGrabPointer ?? XGrabKeyboard ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
??????????ó??????????????????????????????????????????????????????????????????????????????????????? XRecord ???X11????????????????????????????????????
???????????
????X11??Linux?1?????????????????????????????????????????????????????? XServer ???????
????Linux??????????????????????????????????????е??
??????????????→XServer???????????????ο?→??ο?(X Client)?????????????????ó???→?????????????????????????→??ο?X Client)????????????????????????→XServer??????????→??????ε???????
????????????е? X Client ???????????? Gtk+??Qt??Щ??ο???? xcb/xlib ?? XServer ??????????????????????????????????????????????????ο????????????API??????????????????????д?????Xcb/Xlib ???????????????
?????? XRecord ????? XServer ????????????????? XRecord ???????????????? XServer ???棬?? XServer ?????????????????????????????????? XRecord?? ????????????????? XRecord ????У??????????????????????XServer?????XRecord?? XRecord?????????????????????д????ó??????????ó??????????????????????????д????
????????ж??????????????????????????????е???????????????????е??κ???????????????а?????????в?????????????????????????
??????????
????????????????????????? event_monitor.cpp ?У??????????????????????
// ??? XRecord ?????????????????????????????????????ó?????
// ??????????????? QThread ??EventMonitor????????????????????????
EventMonitor::EventMonitor(QObject *parent) : QThread(parent)
{
// ????±??λ????????????????????
isPress = false;
}
void EventMonitor::run()
{
// ??????? XRecord Э??? X ???????
Display* display = XOpenDisplay(0);
// ????????
if (display == 0) {
fprintf(stderr?? "unable to open display ");
return;
}
// ????? XRecordCreateContext ????? XRecordClientSpec ????
// XRecordAllClients ??????? "??????? X Client" ?????
XRecordClientSpec clients = XRecordAllClients;
// ???? XRecordRange ??????XRecordRange ???????????????Χ
XRecordRange* range = XRecordAllocRange();
// ????????Χ???
if (range == 0) {
fprintf(stderr?? "unable to allocate XRecordRange ");
return;
}
// ?????????????Χ????Χ??????ó? KeyPress?? ??Χ??β???ó? MotionNotify ??
// ???????????? KeyPress??KeyRelase??ButtonPress??ButtonRelease??MotionNotify???????
memset(range?? 0?? sizeof(XRecordRange));
range->device_events.first = KeyPress;
range->device_events.last  = MotionNotify;
// ????????????????????????????Χ????????“?????????”
// ???? XRecordContext ????? XRecordEnableContext ???????????????????
XRecordContext context = XRecordCreateContext (display?? 0?? &clients?? 1?? &range?? 1);
if (context == 0) {
fprintf(stderr?? "XRecordCreateContext failed ");
return;
}
// ??? range ???
XFree(range);
// XSync ?????????????? X ???????????? X Server
// ???? X Server ????????????????????? XRecord ?? Client ????
XSync(display?? True);
// ???????????? XRecord Э??????? X ????
Display* display_datalink = XOpenDisplay(0);
// ????????
if (display_datalink == 0) {
fprintf(stderr?? "unable to open second display ");
return;
}
// ???? XRecordEnableContext ???????? XRecord ??????
// XRecordEnableContext ????????????????????????????????????????????????
// X Server ????????????????????????????
if (!XRecordEnableContext(display_datalink?? context??  callback?? (XPointer) this)) {
fprintf(stderr?? "XRecordEnableContext() failed ");
return;
}
}
// handleRecordEvent ??????wrapper?????? XRecord ???????????????
void EventMonitor::callback(XPointer ptr?? XRecordInterceptData* data)
{
((EventMonitor *) ptr)->handleRecordEvent(data);
}
// ??????? X ???????????????
void EventMonitor::handleRecordEvent(XRecordInterceptData* data)
{
if (data->category == XRecordFromServer) {
// ??? xEvent ????
xEvent * event = (xEvent *)data->data;
switch (event->u.u.type) {
case ButtonPress:
// ????????????????? buttonPress ???
if (filterWheelEvent(event->u.u.detail)) {
isPress = true;
emit buttonPress(
event->u.keyButtonPointer.rootX??
event->u.keyButtonPointer.rootY);
}
break;
case MotionNotify:
// ????????????????????????? buttonDrag ???
if (isPress) {
emit buttonDrag(
event->u.keyButtonPointer.rootX??
event->u.keyButtonPointer.rootY);
}
break;
case ButtonRelease:
// ????????????????? buttonRelase ???
if (filterWheelEvent(event->u.u.detail)) {
isPress = false;
emit buttonRelease(
event->u.keyButtonPointer.rootX??
event->u.keyButtonPointer.rootY);
}
break;
case KeyPress:
// ???? keyPress ?????????????? code
emit keyPress(((unsigned char*) data->data)[1]);
break;
case KeyRelease:
// ???? keyRelease ?????????????? code
emit keyRelease(((unsigned char*) data->data)[1]);
break;
default:
break;
}
}
// ??????
fflush(stdout);
XRecordFreeData(data);
}
// ??????????
bool EventMonitor::filterWheelEvent(int detail)
{
return detail != WheelUp && detail != WheelDown && detail != WheelLeft && detail != WheelRight;
}
????????????
????????????????? https://github.com/WHLUG/xrecord-example ????????????????????????
????mkdir build
????cd build
????qmake ..
????make
????./xrecord-example
?????????????????????Qt????????????????????????????????????????????????и??????????????????С?

???????????????????????????????
????????????д???→?????????????????→?????????????У??????→?????????????о?API?????????????→????????????
????????????????????????????????????????д?????????????????Щ?????????????????