Exemplo n.º 1
0
static int
register_events(Display		*dpy,
		XDeviceInfo	*info,
		char		*dev_name,
		Bool		handle_proximity)
{
  int			number = 0;	/* number of events registered */
  XEventClass		event_list[7];
  int			i;
  XDevice		*device;
  Window		root_win;
  unsigned long	screen;
  XInputClassInfo	*ip;

  screen = DefaultScreen(dpy);
  root_win = RootWindow(dpy, screen);

  device = XOpenDevice(dpy, info->id);

  if (!device) {
    fprintf(stderr, "unable to open device '%s'\n", dev_name);
    return 0;
  }

  if (device->num_classes > 0) {
    for (ip = device->classes, i=0; i<info->num_classes; ip++, i++) {
      switch (ip->input_class) {
      case KeyClass:
	DeviceKeyPress(device, key_press_type, event_list[number]); number++;
	DeviceKeyRelease(device, key_release_type, event_list[number]); number++;
	break;

      case ButtonClass:
	DeviceButtonPress(device, button_press_type, event_list[number]); number++;
	DeviceButtonRelease(device, button_release_type, event_list[number]); number++;
	break;

      case ValuatorClass:
	DeviceMotionNotify(device, motion_type, event_list[number]); number++;
	if (handle_proximity) {
	  ProximityIn(device, proximity_in_type, event_list[number]); number++;
	  ProximityOut(device, proximity_out_type, event_list[number]); number++;
	}
	break;

      default:
	fprintf(stderr, "unknown class\n");
	break;
      }
    }

    if (XSelectExtensionEvent(dpy, root_win, event_list, number)) {
      fprintf(stderr, "error selecting extended events\n");
      return 0;
    }
  }
  return number;
}
Exemplo n.º 2
0
static int
register_events(XDeviceInfo *info, XDevice *device,
    Bool handle_proximity)
{
	int		 number = 0;	/* number of events registered */
	XEventClass	 event_list[7];
	int		 i;
	unsigned long	 screen;
	XInputClassInfo	*ip;

	screen = DefaultScreen(display);

	if (device->num_classes > 0) {
		for (ip = device->classes, i=0; i<info->num_classes;
		     ip++, i++) {
			switch (ip->input_class) {
			case ButtonClass:
				DeviceButtonPress(device, button_press_type,
				    event_list[number]);
				number++;
				DeviceButtonRelease(device,
				    button_release_type, event_list[number]);
				number++;
				break;

			case ValuatorClass:
				DeviceMotionNotify(device, motion_type,
				    event_list[number]); number++;
				if (handle_proximity) {
					ProximityIn(device, proximity_in_type,
					    event_list[number]); number++;
					ProximityOut(device,
					    proximity_out_type,
					    event_list[number]); number++;
				}
				break;

			default:
				fprintf(stderr,
				    "Found unknown device class %d\n",
				    ip->input_class);
				break;
			}
		}

		if (XSelectExtensionEvent(display, root, event_list, number)) {
			fprintf(stderr, "Error selecting extended events\n");
			return 0;
		}
	}
	return number;
}
Exemplo n.º 3
0
void kis_x11_init_tablet()
{
    KisConfig cfg;
    bool disableTouchOnCanvas = cfg.disableTouchOnCanvas();

    // TODO: free this structure on exit
    KIS_X11 = new KisX11Data;
    KIS_X11->display = QX11Info::display();

    kis_x11_create_intern_atoms();

    // XInputExtension
    KIS_X11->use_xinput = false;
    KIS_X11->xinput_major = 0;
    KIS_X11->xinput_eventbase = 0;
    KIS_X11->xinput_errorbase = 0;

    // See if Xinput is supported on the connected display
    KIS_X11->ptrXCloseDevice = 0;
    KIS_X11->ptrXListInputDevices = 0;
    KIS_X11->ptrXOpenDevice = 0;
    KIS_X11->ptrXFreeDeviceList = 0;
    KIS_X11->ptrXSelectExtensionEvent = 0;
    KIS_X11->use_xinput = XQueryExtension(KIS_X11->display, "XInputExtension", &KIS_X11->xinput_major,
                                          &KIS_X11->xinput_eventbase, &KIS_X11->xinput_errorbase);
    if (KIS_X11->use_xinput) {
        KIS_X11->ptrXCloseDevice = XINPUT_LOAD(XCloseDevice);
        KIS_X11->ptrXListInputDevices = XINPUT_LOAD(XListInputDevices);
        KIS_X11->ptrXOpenDevice = XINPUT_LOAD(XOpenDevice);
        KIS_X11->ptrXFreeDeviceList = XINPUT_LOAD(XFreeDeviceList);
        KIS_X11->ptrXSelectExtensionEvent = XINPUT_LOAD(XSelectExtensionEvent);
    }

    if (KIS_X11->use_xinput) {
        int ndev,
            i,
            j;
        bool gotStylus,
            gotEraser;
        XDeviceInfo *devices = 0, *devs;
        XInputClassInfo *ip;
        XAnyClassPtr any;
        XValuatorInfoPtr v;
        XAxisInfoPtr a;
        XDevice *dev = 0;

        bool needCheckIfItIsReallyATablet;
        bool touchWacomTabletWorkaround;

        if (KIS_X11->ptrXListInputDevices) {
            devices = KIS_X11->ptrXListInputDevices(KIS_X11->display, &ndev);
            if (!devices)
                qWarning("QApplication: Failed to get list of tablet devices");
        }
        if (!devices)
            ndev = -1;

        QTabletEvent::TabletDevice deviceType;
        for (devs = devices, i = 0; i < ndev && devs; i++, devs++) {
            dev = 0;
            deviceType = QTabletEvent::NoDevice;
            gotStylus = false;
            gotEraser = false;
            needCheckIfItIsReallyATablet = false;
            touchWacomTabletWorkaround = false;

#if defined(Q_OS_IRIX)
#else


                if (devs->type == KIS_ATOM(XWacomStylus) || devs->type == KIS_ATOM(XTabletStylus) ||devs->type == KIS_ATOM(XInputTablet)) {
                    if (devs->type == KIS_ATOM(XInputTablet)) {
                        kis_haveEvdevTablets = true;
                    }
                    deviceType = QTabletEvent::Stylus;
                    gotStylus = true;
                } else if (devs->type == KIS_ATOM(XWacomEraser) || devs->type == KIS_ATOM(XTabletEraser)) {
                    deviceType = QTabletEvent::XFreeEraser;
                    gotEraser = true;
                } else if ((devs->type == KIS_ATOM(XInputKeyboard) ||
                            devs->type == KIS_ATOM(AiptekStylus))
                           && QString(devs->name) == "Aiptek") {
                    /**
                     * Some really "nice" tablets (more precisely,
                     * Genius G-Pen 510 (aiptek driver)) report that
                     * they are a "keyboard". Well, we cannot convince
                     * them that they are not, so just check if this
                     * "keyboard" has motion and proximity events. If
                     * it looks like a duck... :)
                     */
                    kis_haveEvdevTablets = true;
                    deviceType = QTabletEvent::Stylus;
                    gotStylus = true;
                    needCheckIfItIsReallyATablet = true;
                } else if (disableTouchOnCanvas &&
                           devs->type == KIS_ATOM(WacomTouch) &&
                           QString(devs->name).contains("Wacom")) {

                    kis_haveEvdevTablets = true;
                    deviceType = QTabletEvent::Stylus;
                    gotStylus = true;
                    touchWacomTabletWorkaround = true;
                }

#endif
            if (deviceType == QTabletEvent::NoDevice)
                continue;

            if (gotStylus || gotEraser) {
                if (KIS_X11->ptrXOpenDevice)
                    dev = KIS_X11->ptrXOpenDevice(KIS_X11->display, devs->id);

                if (!dev)
                    continue;

                QTabletDeviceData device_data;
                device_data.deviceType = deviceType;
                device_data.eventCount = 0;
                device_data.device = dev;
                device_data.xinput_motion = -1;
                device_data.xinput_key_press = -1;
                device_data.xinput_key_release = -1;
                device_data.xinput_button_press = -1;
                device_data.xinput_button_release = -1;
                device_data.xinput_proximity_in = -1;
                device_data.xinput_proximity_out = -1;
                device_data.isTouchWacomTablet = touchWacomTabletWorkaround;
                //device_data.widgetToGetPress = 0;

                if (dev->num_classes > 0) {
                    for (ip = dev->classes, j = 0; j < dev->num_classes;
                         ip++, j++) {
                        switch (ip->input_class) {
                        case KeyClass:
                            DeviceKeyPress(dev, device_data.xinput_key_press,
                                           device_data.eventList[device_data.eventCount]);
                            if (device_data.eventList[device_data.eventCount])
                                ++device_data.eventCount;
                            DeviceKeyRelease(dev, device_data.xinput_key_release,
                                             device_data.eventList[device_data.eventCount]);
                            if (device_data.eventList[device_data.eventCount])
                                ++device_data.eventCount;
                            break;
                        case ButtonClass:
                            DeviceButtonPress(dev, device_data.xinput_button_press,
                                              device_data.eventList[device_data.eventCount]);
                            if (device_data.eventList[device_data.eventCount])
                                ++device_data.eventCount;
                            DeviceButtonRelease(dev, device_data.xinput_button_release,
                                                device_data.eventList[device_data.eventCount]);
                            if (device_data.eventList[device_data.eventCount])
                                ++device_data.eventCount;
                            break;
                        case ValuatorClass:
                            // I'm only going to be interested in motion when the
                            // stylus is already down anyway!
                            DeviceMotionNotify(dev, device_data.xinput_motion,
                                               device_data.eventList[device_data.eventCount]);
                            if (device_data.eventList[device_data.eventCount])
                                ++device_data.eventCount;
                            ProximityIn(dev, device_data.xinput_proximity_in, device_data.eventList[device_data.eventCount]);
                            if (device_data.eventList[device_data.eventCount])
                                ++device_data.eventCount;
                            ProximityOut(dev, device_data.xinput_proximity_out, device_data.eventList[device_data.eventCount]);
                            if (device_data.eventList[device_data.eventCount])
                                ++device_data.eventCount;
                        default:
                            break;
                        }
                    }
                }

                if (needCheckIfItIsReallyATablet &&
                    (device_data.xinput_motion == -1 ||
                     device_data.xinput_proximity_in == -1 ||
                     device_data.xinput_proximity_out == -1)) {
                    continue;
                }

                if (KisTabletDebugger::instance()->initializationDebugEnabled()) {
                    dbgTablet << "###################################";
                    dbgTablet << "# Adding a tablet device:" << devs->name;
                    dbgTablet << "Device Type:" << KisTabletDebugger::tabletDeviceToString(deviceType);
                }

                device_data.savedAxesData.tryFetchAxesMapping(dev);

                // get the min/max value for pressure!
                any = (XAnyClassPtr) (devs->inputclassinfo);
                for (j = 0; j < devs->num_classes; j++) {
                    if (any->c_class == ValuatorClass) {
                        v = (XValuatorInfoPtr) any;
                        a = (XAxisInfoPtr) ((char *) v +
                                            sizeof (XValuatorInfo));
#if defined (Q_OS_IRIX)
#else
                        device_data.minX = a[0].min_value;
                        device_data.maxX = a[0].max_value;
                        device_data.minY = a[1].min_value;
                        device_data.maxY = a[1].max_value;
                        device_data.minPressure = a[2].min_value;
                        device_data.maxPressure = a[2].max_value;
                        device_data.minTanPressure = 0;
                        device_data.maxTanPressure = 0;
                        device_data.minZ = 0;
                        device_data.maxZ = 0;
                        device_data.minRotation = a[5].min_value;
                        device_data.maxRotation = a[5].max_value;

                        if (KisTabletDebugger::instance()->initializationDebugEnabled()) {
                            dbgTablet << "# Axes limits data";
                            dbgTablet << "X:       " << device_data.minX << device_data.maxX;
                            dbgTablet << "Y:       " << device_data.minY << device_data.maxY;
                            dbgTablet << "Z:       " << device_data.minZ << device_data.maxZ;
                            dbgTablet << "Pressure:" << device_data.minPressure << device_data.maxPressure;
                            dbgTablet << "Rotation:" << device_data.minRotation << device_data.maxRotation;
                            dbgTablet << "T. Pres: " << device_data.minTanPressure << device_data.maxTanPressure;
                        }

#endif

                        // got the max pressure no need to go further...
                        break;
                    }
                    any = (XAnyClassPtr) ((char *) any + any->length);
                } // end of for loop

                qt_tablet_devices()->append(device_data);
            } // if (gotStylus || gotEraser)
        }
        if (KIS_X11->ptrXFreeDeviceList)
            KIS_X11->ptrXFreeDeviceList(devices);
    }
}
Exemplo n.º 4
0
int Run(Display* pDisp, UI* pUI, FORMATTYPE fmt, const char* pszDeviceName)
{
	int nRtn;
	XDevice* pDev;
	XDeviceInfoPtr pDevInfo;
	int nEventListCnt = 0;
	XEventClass eventList[32];
	XEventClass cls;

	/* get the device by name */
	pDevInfo = GetDevice(pDisp,pszDeviceName);
	if (!pDevInfo)
	{
		fprintf(stderr,"Unable to find input device '%s'\n",pszDeviceName);
		return 1;
	}

	/* open device */
	pDev = XOpenDevice(pDisp,pDevInfo->id);
	if (!pDev)
	{
		fprintf(stderr,"Unable to open input device '%s'\n",pszDeviceName);
		return 1;
	}

	/* key events */
	DeviceKeyPress(pDev,gnInputEvent[INPUTEVENT_KEY_PRESS],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	DeviceKeyRelease(pDev,gnInputEvent[INPUTEVENT_KEY_RELEASE],cls);
	if (cls) eventList[nEventListCnt++] = cls;

	/* focus events */
	DeviceFocusIn(pDev,gnInputEvent[INPUTEVENT_FOCUS_IN],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	DeviceFocusOut(pDev,gnInputEvent[INPUTEVENT_FOCUS_OUT],cls);
	if (cls) eventList[nEventListCnt++] = cls;

	/* button events */
	DeviceButtonPress(pDev,gnInputEvent[INPUTEVENT_BTN_PRESS],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	DeviceButtonRelease(pDev,gnInputEvent[INPUTEVENT_BTN_RELEASE],cls);
	if (cls) eventList[nEventListCnt++] = cls;

	/* proximity events */
	ProximityIn(pDev,gnInputEvent[INPUTEVENT_PROXIMITY_IN],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	ProximityOut(pDev,gnInputEvent[INPUTEVENT_PROXIMITY_OUT],cls);
	if (cls) eventList[nEventListCnt++] = cls;

	/* motion events */
	DeviceMotionNotify(pDev,gnInputEvent[INPUTEVENT_MOTION_NOTIFY],cls);
	if (cls) eventList[nEventListCnt++] = cls;

	/* device state */
	DeviceStateNotify(pDev,gnInputEvent[INPUTEVENT_DEVICE_STATE_NOTIFY],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	DeviceMappingNotify(pDev,
			gnInputEvent[INPUTEVENT_DEVICE_MAPPING_NOTIFY],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	ChangeDeviceNotify(pDev,gnInputEvent[INPUTEVENT_CHANGE_DEVICE_NOTIFY],cls);
	if (cls) eventList[nEventListCnt++] = cls;

#if 0
	/* this cuts the motion data down - not sure if this is useful */
	DevicePointerMotionHint(pDev,
			gnInputEvent[INPUTEVENT_DEVICE_POINTER_MOTION_HINT],cls);
	if (cls) eventList[nEventListCnt++] = cls;
#endif

	/* button motion */
	DeviceButtonMotion(pDev,
			gnInputEvent[INPUTEVENT_DEVICE_BUTTON_MOTION],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	DeviceButton1Motion(pDev,
			gnInputEvent[INPUTEVENT_DEVICE_BUTTON1_MOTION],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	DeviceButton2Motion(pDev,
			gnInputEvent[INPUTEVENT_DEVICE_BUTTON2_MOTION],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	DeviceButton3Motion(pDev,
			gnInputEvent[INPUTEVENT_DEVICE_BUTTON3_MOTION],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	DeviceButton4Motion(pDev,
			gnInputEvent[INPUTEVENT_DEVICE_BUTTON4_MOTION],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	DeviceButton5Motion(pDev,
			gnInputEvent[INPUTEVENT_DEVICE_BUTTON5_MOTION],cls);
	if (cls) eventList[nEventListCnt++] = cls;

	/* specify which events to report */
	/* XSelectInput(pDisp,wnd,0x00FFFFFF ^ PointerMotionHintMask); */
	/* XSelectExtensionEvent(pDisp,wnd,eventList,nEventListCnt); */

	/* grab device - work whether pointer is in active window or not */
	XGrabDevice(pDisp,pDev,DefaultRootWindow(pDisp),
			0, /* no owner events */
			nEventListCnt, eventList, /* events */
			GrabModeAsync, /* don't queue, give me whatever you got */
			GrabModeAsync, /* same */
			CurrentTime);

	/* fire up the UI */
	if ((nRtn=pUI->Init()) != 0)
		fprintf(stderr,"failed to initialize UI\n");
	else
	{
		if ((nRtn=pUI->Run(pDisp,pDevInfo,fmt)) != 0)
			fprintf(stderr,"failed to run UI\n");
		pUI->Term();
	}

	XUngrabDevice(pDisp,pDev,CurrentTime);
	XFree(pDev);
	XCloseDisplay(pDisp);

	return nRtn;
}
Exemplo n.º 5
0
static PyObject * xextdev_grab(PyObject *self, PyObject *args)
{
	XEventClass cls;
	const char *devname;
	int devid;
	XAnyClassPtr pClass;
	int j;
	XEventClass eventList[32];
	int nEventListCnt = 0;

	if (!display) {
		ASSERTCOND(display = XOpenDisplay(NULL),"open display");

		/* polling this seems to be the only way 
		* 	 * to do a timed wait on X events */
		x11_fd = ConnectionNumber(display);

		xdevList = (XDeviceInfoPtr) XListInputDevices(display, &devcount);
		if (!xdevList) {
			fprintf(stderr,"Failed to get input device list\n");
			return Py_BuildValue("i", 0);
		}
	}

	if (!PyArg_ParseTuple(args, "i", &devid))
		return Py_BuildValue("i", 0);

	ASSERTCOND(devid<devcount,
		   "Tried to grab non-existing device id %d (max %d)",
		   devid,devcount);

	xdevInfo = xdevList + devid;
	devname = xdevInfo->name;

	val = NULL;

	pClass = xdevInfo->inputclassinfo;
	for (j=0; j<xdevInfo->num_classes; ++j)
	{
		switch (pClass->class) {
		case ValuatorClass:
			val = (XValuatorInfoPtr)pClass;
			break;
		}
		pClass = (XAnyClassPtr)((char*)pClass + pClass->length);
	}

	ASSERTCOND(val,"xinputextdev: Unable to get valuator "
		   "information of '%s'\n",devname);

	/* open device */
	ASSERTCOND(xdev = XOpenDevice(display,xdevInfo->id),
		   "xinputextdev: Unable to open "
		   "input device '%s'\n",devname);

	/* button events */
	DeviceButtonPress(xdev,inputEventTypes[INPUTEVENT_BTN_PRESS],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	DeviceButtonRelease(xdev,inputEventTypes[INPUTEVENT_BTN_RELEASE],cls);
	if (cls) eventList[nEventListCnt++] = cls;

	/* motion events */
	DeviceMotionNotify(xdev,inputEventTypes[INPUTEVENT_MOTION_NOTIFY],cls);
	if (cls) eventList[nEventListCnt++] = cls;

	/* proximity events */
	ProximityOut(xdev,inputEventTypes[INPUTEVENT_PROXIMITY_OUT],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	ProximityIn(xdev,inputEventTypes[INPUTEVENT_PROXIMITY_IN],cls);
	if (cls) eventList[nEventListCnt++] = cls;

	/* grab device */
	int err = XGrabDevice(display,xdev,DefaultRootWindow(display),
			      0,nEventListCnt,eventList,
			      GrabModeAsync,GrabModeAsync,CurrentTime);

	if (err == AlreadyGrabbed)
		fprintf(stderr,"xinputextdev: Grab error: AlreadyGrabbed\n");
	else if (err == GrabNotViewable)
		fprintf(stderr, "xinputextdev: Grab error: GrabNotViewable\n");
	else if (err == GrabFrozen)
		fprintf(stderr, "xinputextdev: Grab error: GrabFrozen\n");
	else {
		printf("xinputextdev: Device '%s' grabbed.\n",devname);
		return Py_BuildValue("[i,i]",
				     val->axes[0].max_value,
				     val->axes[1].max_value);
	}

	return Py_BuildValue("i", 0);
}