absolute coordinate mouse support
Alex Williamson
alex.williamson at hp.com
Wed Sep 21 12:40:28 PDT 2005
On Wed, 2005-09-21 at 15:16 -0400, Adam Jackson wrote:
> On Wednesday 21 September 2005 14:07, Alex Williamson wrote:
> > On Wed, 2005-09-21 at 13:50 -0400, James Cloos wrote:
> > > >>>>> "Alex" == Alex Williamson <alex.williamson at hp.com> writes:
> > >
> > > Alex> an tell me to switch to something besides the X "mouse" driver
> > >
> > > Perhaps evdev does what you want.
> >
> > Yes, I was just looking into that, thanks for mentioning it. The
> > evdev driver apparently ignores absolute data at the moment, but I think
> > I can add that without too much problem. Probably missing just because
> > absolute coordinate devices aren't nearly as common.
>
> There's an open bug for some absolute pointer support in evdev, it's one of
> the blockers on #968 and I'd like to see it merged.
Thanks for the pointer, I've grabbed the 6.8.2-2 patch from that bug
and have been adding support. Not being an X hacker, I'm sure it's
hideous, but it's a start and it works. Patch attached below if anyone
cares to comment on it. I'll attach it to the bug after I fiddle with
it a little more.
[snip]
> Unfortunately I don't know any good way to detect what sort of device is being
> examined. We could probably add a flag for this to the evdev protocol, but
> we'd still need an option to set this for older kernels.
I don't think it's necessary to care what kind of device you're
talking to. All we care about is that EV_ABS data is coming in and we
need to post it as a motion event. There already appear to be all the
flags we need. Thanks,
Alex
--
Alex Williamson HP Linux & Open Source Lab
--- evdev.c.orig 2005-09-21 11:53:17.000000000 -0600
+++ evdev.c 2005-09-21 13:28:01.000000000 -0600
@@ -66,6 +66,19 @@
static int wheel_left_button = 6;
static int wheel_right_button = 7;
+typedef struct _EvDevRec {
+ int min_x;
+ int max_x;
+ int old_x;
+ int min_y;
+ int max_y;
+ int old_y;
+ int screen_num;
+ int screen_width;
+ int screen_height;
+
+} EvDevRec, *EvDevPtr;
+
static void
PostButtonClicks(InputInfoPtr pInfo, int button, int count)
{
@@ -80,10 +93,12 @@
static void
EvdevReadInput(InputInfoPtr pInfo)
{
+ EvDevPtr pEv;
struct input_event ev;
int len, value;
int dx, dy;
+ pEv = (EvDevPtr)pInfo->private;
dx = 0;
dy = 0;
@@ -127,6 +142,20 @@
break;
case EV_ABS:
+ switch (ev.code) {
+ case ABS_X:
+ pEv->old_x = xf86ScaleAxis(value, 0, pEv->screen_width,
+ pEv->min_x, pEv->max_x);
+ xf86PostMotionEvent(pInfo->dev, 1, 0, 2, pEv->old_x, pEv->old_y);
+
+ break;
+
+ case ABS_Y:
+ pEv->old_y = xf86ScaleAxis(value, 0, pEv->screen_height,
+ pEv->min_y, pEv->max_y);
+ xf86PostMotionEvent(pInfo->dev, 1, 0, 2, pEv->old_x, pEv->old_y);
+ break;
+ }
break;
case EV_KEY:
@@ -464,8 +493,14 @@
EvdevInit(DeviceIntPtr device)
{
InputInfoPtr pInfo;
+ EvDevPtr pEv;
pInfo = device->public.devicePrivate;
+ pEv = (EvDevPtr)pInfo->private;
+
+ pEv->screen_num = 0; /* FIXME */
+ pEv->screen_width = screenInfo.screens[pEv->screen_num]->width;
+ pEv->screen_height = screenInfo.screens[pEv->screen_num]->height;
/* FIXME: This doesn't add buttons for keyboards with
* scrollwheels. */
@@ -536,7 +571,9 @@
{
char key_bitmask[(KEY_MAX + 7) / 8];
char rel_bitmask[(REL_MAX + 7) / 8];
- int i, has_axes, has_buttons, has_keys;
+ char abs_bitmask[(ABS_MAX + 7) / 8];
+ int i, has_axes, has_buttons, has_keys, nValues[5];
+ EvDevPtr pEv;
if (ioctl(pInfo->fd,
EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) < 0) {
@@ -544,6 +581,12 @@
return;
}
+ if (ioctl(pInfo->fd,
+ EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) < 0) {
+ xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
+ return;
+ }
+
if (ioctl(pInfo->fd,
EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
@@ -559,6 +602,25 @@
has_axes = TRUE;
}
+ if (TestBit(ABS_X, abs_bitmask) && TestBit(ABS_Y, abs_bitmask)) {
+ pEv = (EvDevPtr)pInfo->private;
+
+ if (ioctl(pInfo->fd, EVIOCGABS(ABS_X), nValues) == 0) {
+ pEv->min_x = nValues[1];
+ pEv->max_x = nValues[2];
+ }
+
+ if (ioctl(pInfo->fd, EVIOCGABS(ABS_Y), nValues) == 0) {
+ pEv->min_y = nValues[1];
+ pEv->max_y = nValues[2];
+ }
+
+ xf86Msg(X_INFO, "%s: Found x (%d-%d) and y (%d-%d) absolute axes\n",
+ pInfo->name,pEv->min_x, pEv->max_x,
+ pEv->min_y, pEv->max_y);
+ has_axes = TRUE;
+ }
+
if (TestBit(BTN_LEFT, key_bitmask)) {
xf86Msg(X_INFO, "%s: Found mouse buttons\n", pInfo->name);
@@ -601,6 +663,7 @@
InputInfoPtr pInfo;
MessageType deviceFrom = X_CONFIG;
const char *device;
+ EvDevPtr pEv;
if (!(pInfo = xf86AllocateInput(drv, 0)))
return NULL;
@@ -623,6 +686,10 @@
pInfo->always_core_feedback = 0;
pInfo->conf_idev = dev;
+ if (!(pEv = xcalloc(sizeof(EvDevRec), 1)))
+ return pInfo;
+ pInfo->private = pEv;
+
xf86CollectInputOptions(pInfo, NULL, NULL);
xf86ProcessCommonOptions(pInfo, pInfo->options);
More information about the xorg
mailing list