예제 #1
0
파일: taskbar.c 프로젝트: no0p/windowlab
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();
}
예제 #2
0
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;
    }
}
예제 #3
0
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);
}
예제 #4
0
void MSPulldownMenu::done(void)
{
  ungrab();
  unmap();
  if (item()!=0) item()->menu()->done();
  reset();
}
예제 #5
0
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();
}
예제 #7
0
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);
  }
}
예제 #8
0
파일: grab.c 프로젝트: 00001/plan9port
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);
}
예제 #9
0
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();
    }
}
예제 #10
0
long
GUISUMOAbstractView::onRightBtnRelease(FXObject*, FXSelector , void* data) {
    destroyPopup();
    if (!myChanger->onRightBtnRelease(data) && !myApp->isGaming()) {
        openObjectDialog();
    }
    ungrab();
    return 1;
}
예제 #11
0
파일: sxhkd.c 프로젝트: lernisto/sxhkd
void toggle_grab_cmd(void)
{
	PUTS("toggle grab");
	if (grabbed) {
		ungrab();
	} else {
		grab();
	}
}
예제 #12
0
파일: grab.c 프로젝트: 00001/plan9port
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);
		}
	}
}
예제 #13
0
파일: sxhkd.c 프로젝트: lernisto/sxhkd
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();
}
예제 #14
0
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;
}
예제 #16
0
파일: Viewport.cpp 프로젝트: ldematte/beppe
long Viewport::onRightBtnRelease(FXObject* , FXSelector, void* ptr)
{
	FXEvent *ev=(FXEvent*)ptr;

	RightBtn = false;	
	checkOperation(ev);
	if (!LeftBtn)
		ungrab();
	return 1;
}
예제 #17
0
파일: taskbar.c 프로젝트: no0p/windowlab
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();
}
예제 #18
0
파일: TextLabel.cpp 프로젝트: tindzk/Xfe
// 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;
}
예제 #19
0
파일: types.c 프로젝트: 4144/sxhkd
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();
}
예제 #20
0
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;
}
예제 #21
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;
  }
예제 #22
0
    bool KeyActionSettingsWidget::x11Event(XEvent *event)
    {
        if(grabbing_)
        {
            if(event->type == KeyPress)
            {
                key = FakeInput::Key(event);
            }
            else if(event->type == KeyRelease && grabbing_)
            {
                ungrab();
            }
        }

        return false;
    }
예제 #23
0
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;
}
예제 #24
0
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;
  }
예제 #25
0
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;
}
예제 #26
0
// 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*)&current);
        } else if (event->click_count == 2) {
            handle(this, FXSEL(SEL_DOUBLECLICKED, 0), (void*)&current);
        } else if (event->click_count == 3) {
            handle(this, FXSEL(SEL_TRIPLECLICKED, 0), (void*)&current);
        }

        // 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*)&current);
        }
        return 1;
    }
    return 0;
}
예제 #27
0
파일: Item.cpp 프로젝트: LADI/ladish
/** 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;
}
예제 #28
0
/* 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);
		}

	}

}
예제 #29
0
void QQuickMultiPointTouchArea::touchUngrabEvent()
{
    ungrab();
}
예제 #30
0
파일: sxhkd.c 프로젝트: lernisto/sxhkd
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;
}