Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Apr 2010 02:37:13 +0400
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        arch@FreeBSD.org
Subject:   Re: touch panel support
Message-ID:  <20100415223713.GF97761@FreeBSD.org>
In-Reply-To: <20100326211706.GI18894@FreeBSD.org>
References:  <20100326211706.GI18894@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
  My further hacking on getting touch panel working with FreeBSD.

On Sat, Mar 27, 2010 at 12:17:06AM +0300, Gleb Smirnoff wrote:
T>   And then I've got a problem. Our mouse subsystem is not ready for
T> touch panels. Our mouse(4) protocol does not support mouse driver
T> passing _absolute_ coordinates to the mouse(4) subsystem. It only
T> expects a relative movement of the mouse.  But _absolute_ coordinates
T> are principal idea of any touch panel.

Well, syscons actually have support for absolute mouse movement. We
need just this tiny patch, to get it working.

Index: scmouse.c
===================================================================
--- scmouse.c   (revision 206501)
+++ scmouse.c   (working copy)
@@ -700,6 +700,7 @@
            scp->mouse_xpos = mouse->u.data.x;
            scp->mouse_ypos = mouse->u.data.y;
            set_mouse_pos(scp);
+           goto motion;
            splx(s);
            break;
 
@@ -732,6 +733,7 @@
                cur_scp->mouse_ypos += mouse->u.data.y;
                set_mouse_pos(cur_scp);
            }
+motion:
            f = 0;
            if (mouse->operation == MOUSE_ACTION) {
                f = cur_scp->mouse_buttons ^ mouse->u.data.buttons;

This also requires userland (moused(8)) to put absolute coordinates
into mouse->u.data and provide MOUSE_MOVEABS command instead of
MOUSE_ACTION.

The patch to moused(8) looks like following. First, we need to
recognize a mouse protocol, that works with absolute coordinates:

@@ -1584,6 +1629,9 @@
        }
     }
 
+    if (rodent.mode.protocol == MOUSE_PROTO_EGALAX)
+       rodent.flags |= AbsoluteXY;
+
     debug("proto params: %02x %02x %02x %02x %d %02x %02x",
        cur_proto[0], cur_proto[1], cur_proto[2], cur_proto[3],
        cur_proto[4], cur_proto[5], cur_proto[6]);
@ -2170,6 +2218,22 @@
        prev_y = y;
        break;
 
+    case MOUSE_PROTO_EGALAX:           /* eGalax */
+       x = (pBuf[1] << 7) | pBuf[2];
+       y = (pBuf[3] << 7) | pBuf[4];
+
+       act->flags = 0;
+       act->button = 0; /* TODO */
+       if (x != prev_x || y != prev_y) {
+               act->dx = prev_x = x;
+               act->dy = prev_y = y;
+               act->flags |= MOUSE_POSCHANGED;
+       }
+
+       return (act->flags);
+
+       break;
+
     case MOUSE_PROTO_BUS:              /* Bus */
     case MOUSE_PROTO_INPORT:           /* InPort */
        act->button = butmapmsc[(~pBuf[0]) & MOUSE_MSC_BUTTONS];

Then we need to pass these absolute coords to mouse(4):

@@ -1295,11 +1335,14 @@
                if (action2.flags & MOUSE_POSCHANGED) {
                    mouse.operation = MOUSE_MOTION_EVENT;
                    mouse.u.data.buttons = action2.button;
-                   if (rodent.flags & ExponentialAcc) {
+                   if (rodent.flags & AbsoluteXY) {
+                       absmove(action2.dx, action2.dy,
+                           &mouse.u.data.x, &mouse.u.data.y);
+                       mouse.operation = MOUSE_MOVEABS;
+                   } else if (rodent.flags & ExponentialAcc) {
                        expoacc(action2.dx, action2.dy,
                            &mouse.u.data.x, &mouse.u.data.y);
-                   }
-                   else {
+                   } else {
                        linacc(action2.dx, action2.dy,
                            &mouse.u.data.x, &mouse.u.data.y);
                    }
@@ -1311,11 +1354,14 @@
            } else {
                mouse.operation = MOUSE_ACTION;
                mouse.u.data.buttons = action2.button;
-               if (rodent.flags & ExponentialAcc) {
+               if (rodent.flags & AbsoluteXY) {
+                   absmove(action2.dx, action2.dy,
+                       &mouse.u.data.x, &mouse.u.data.y);
+                   mouse.operation = MOUSE_MOVEABS;
+               } else if (rodent.flags & ExponentialAcc) {
                    expoacc(action2.dx, action2.dy,
                        &mouse.u.data.x, &mouse.u.data.y);
-               }
-               else {
+               } else {
                    linacc(action2.dx, action2.dy,
                        &mouse.u.data.x, &mouse.u.data.y);
                }

The absmove() function should perform calibration and then assign
u.data.x to calibrated x from touchpanel, and y accordingly.

Doing calibration in moused(8) is a problem. Userland can't guess or
access pixel size of the syscons. Currently I've just hardcoded
calibration into absmove() with my values, and get all this
stuff working. Stilus moves mouse pointer flawlessly and correctly
in the syscons. :)

But, unfortunately, this is a zero step towards touchscreen working
in X. Although we got working absolute mouse pointer in syscons,
we can't pass it through sysmouse(4) protocol :(

-- 
Totus tuus, Glebius.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100415223713.GF97761>