Topic: Touchscreen pressure

According to all the documentation I can find, the chumby touchscreen is supposed to report a pressure value. However, my chumby (HW 3.8 according to the chumby info panel) does not seem to do so; whether I read the touchscreen with a program of my own or by cat-ing /proc/chumby/touchscreen/coordinates, the pressure value seems to flip-flop between two apparently arbitrary numbers near 5000 (which change every once in a while). For example:

175: x=2436 y=1658 p=4992 pen-down
174: x=2399 y=1660 p=5129 pen-down
173: x=2365 y=1660 p=4992 pen-down
172: x=2333 y=1657 p=5129 pen-down
171: x=2298 y=1655 p=4992 pen-down
170: x=2268 y=1651 p=5129 pen-down

It doesn't seem to be causing any problems for any of the regular chumby apps. Is this normal? Is there a way to fix this?

It is pitch black. You are likely to be eaten by a grue.

Re: Touchscreen pressure

It's *very* hard to get any type of meaningful pressure information out of this type of resistive touchscreen.  It turns out that at low pressure, the reported coordinates are completely meaningless - so you can sort of tell that someone's gently touching the screen *somewhere*, or know they're pressing hard at a *particular* location.

We basically threshold the values and perform a lot of filtering shenanigans in order to deliver simple up/down events to the Flash Player, which would not support pressure values even if we had them.

You're welcome to download the source to the touchscreen driver and see if you can find a better way to get pressure information along with accurate location.  We'd love to see someone take a crack at improving this.

Capacitive touchscreens are much, much better at this sort of thing.

Re: Touchscreen pressure

Try there though it's really hard to get the exect preasure value but here's what you can try

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>

#include <X11/extensions/Xsp.h>

#define uint unsigned int

Display *dpy;
Window win;
int screen;
int xres;
int yres;

/* device specific data */
#define DEV_X_DELTA 3378
#define DEV_Y_DELTA 3080
#define DEV_X_CORRECTION -300
#define DEV_Y_CORRECTION -454

/**
   translate raw device coordinates to screen coordinates
*/
#define TRANSLATE_RAW_COORDS(x, y) \
{ \
  * x += DEV_X_CORRECTION;\
  * y += DEV_Y_CORRECTION;\
  * x = xres - (xres * *x) / DEV_X_DELTA;\
  * y = yres - (yres * *y) / DEV_Y_DELTA;\
}

/**
   set foreground color of default gc
*/
static void
setcolor(uint r, uint g, uint b)
{
  XColor col;
  col.red   = r;
  col.green = g;
  col.blue  = b;
  XAllocColor(dpy,
              DefaultColormap (dpy, screen),
              &col);
  XSetForeground(dpy,
                 DefaultGC (dpy, screen),
                 col.pixel);
}

/**
   main program
*/
int
main (int argc, char *argv
{
  long key_pressed;

  XEvent event;
  XSPRawTouchscreenEvent xsp_event;

  int xsp_event_base=-1;
  int xsp_error_base=-1;
  int xsp_major=-1;
  int xsp_minor=-1;

  int t_x=0;
  int t_y=0;

  int circle_angle = 360*64;

  uint radius=0;
  uint done = 0;

  Atom atoms_WINDOW_STATE;
  Atom atoms_WINDOW_STATE_FULLSCREEN;

  /* open X display */
  dpy = XOpenDisplay(0);

  if (!dpy)
    goto exit;

  screen = DefaultScreen   (dpy);
  xres   = ScreenOfDisplay (dpy, DefaultScreen(dpy))->width;
  yres   = ScreenOfDisplay (dpy, DefaultScreen(dpy))->height;

  atoms_WINDOW_STATE
    = XInternAtom(dpy, "_NET_WM_STATE",False);
  atoms_WINDOW_STATE_FULLSCREEN
    = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN",False);

  /* create the Window */
  win = XCreateSimpleWindow(dpy, RootWindow(dpy, screen), 0, 0,
                            xres, yres, 0,
                            BlackPixel(dpy, screen),
                            WhitePixel(dpy, screen));

  /* Set the wmhints needed for fullscreen */
  XChangeProperty(dpy, win, atoms_WINDOW_STATE, XA_ATOM, 32,
                  PropModeReplace,
                  (unsigned char *) &atoms_WINDOW_STATE_FULLSCREEN, 1);

  /* get xsp event base */
  XSPQueryExtension(dpy,
                    &xsp_event_base,
                    &xsp_error_base,
                    &xsp_major,
                    &xsp_minor);

  if (xsp_event_base < 0)
    goto exit;

  /* activate raw touchscreen data */
  XSPSetTSRawMode(dpy, True);

  XSelectInput(dpy, win, StructureNotifyMask | ExposureMask | KeyPressMask);
  XMapWindow(dpy, win);
  XClearWindow(dpy, win);

  XFlush(dpy);

  /* clean queue */
  XSync(dpy, True);

  setcolor(0, 0, 0);
  while (!done)
  {
    /* if there are events */
    if (XEventsQueued(dpy, QueuedAfterReading) > 0)
    {
      XNextEvent(dpy, &event);

      /* if it's xsp event */
      if (event.type == xsp_event_base)
        {
          memcpy(&xsp_event, &event,
                 sizeof(XSPRawTouchscreenEvent));

          t_x = xsp_event.x;
          t_y = xsp_event.y;

          /* translate raw coordinates */
          TRANSLATE_RAW_COORDS(&t_x, &t_y);

          /* draw filled circle in translated coords,
             using pressure for size */
          radius = xsp_event.pressure - 100;
          if (radius < 0)
            radius = 1;

          XFillArc(dpy,
                   win,
                   DefaultGC(dpy, screen),
                   t_x-radius,
                   t_y-radius,
                   radius+radius,
                   radius+radius,
                   0 ,
                   circle_angle);

          XFlush(dpy);
        }
      else
        {
          /* some other event */
          switch (event.type)
            {
            case KeyPress :
              done = 1;
              break;

            default :
              break;

            }
        }
    }
  }

  exit :

  /* set back normal event mode */
  XSPSetTSRawMode(dpy, False);

  XCloseDisplay(dpy);
  return 0;
}

Re: Touchscreen pressure

Errr....what?

The chumby does not run X, and even if it did, this code would require that the touchscreen driver were reporting useful pressure data, which it doesn't for the reasons outlined above.

Re: Touchscreen pressure

It's true, the chumby does not run X and the code above doesn't actually make much sense in the scheme of things here.