/*
 * $XFree86: xc/programs/Xserver/hw/kdrive/linux/ts.c,v 1.5 2001/07/11 02:58:19 keithp Exp $
 *
 * Derived from ps2.c by Jim Gettys
 *
 * Copyright © 1999 Keith Packard
 * Copyright © 2000 Compaq Computer Corporation
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Keith Packard or Compaq not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Keith Packard and Compaq makes no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * KEITH PACKARD AND COMPAQ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, 
 * IN NO EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#define NEED_EVENTS
#include "X.h"
#include "Xproto.h"
#include "inputstr.h"
#include "scrnintstr.h"
#include "kdrive.h"
#include "Xpoll.h"
#include <sys/ioctl.h>

typedef struct {
  unsigned short          pressure;
  unsigned short          x;
  unsigned short          y;
  unsigned short          pad;
  struct timeval  stamp;
} TS_EVENT;

static long lastx = 0, lasty = 0;
int TsScreen;
extern int TsFbdev;

void TsRead (int tsPort, void *closure) {
  TS_EVENT        event;
  long            buf[3];
  int             n;
  long            pressure;
  long            x, y;
  unsigned long   flags;
  unsigned long   buttons;

  n = Ps2ReadBytes(tsPort, (char *) &event, sizeof (event), sizeof (event));
  if (n >= sizeof (event)) {
    if (event.pressure >= 100) {
      flags = KD_BUTTON_1;
      x = (960 - event.x) * 640 / (920);
      y = (960 - event.y) * 480 / (920);
      //ErrorF("flags %d x %d y %dn",flags,event.x,event.y);
    }
    else {
      flags = KD_MOUSE_DELTA;
      x = lastx;
      y = lasty;
    }
    KdEnqueueMouseEvent(flags, x, y);
  }
}

char	*TsNames[] = {
  "/dev/ucb1x00-ts",
  "/dev/ts" /* temporary name; note this code can try
			   to open more than one device */
};

#define NUM_TS_NAMES	(sizeof (TsNames) / sizeof (TsNames[0]))

int TsInputType;

int TsInit (void) {
    int	    i;
    int	    TsPort;

    if (!TsInputType)
	TsInputType = KdAllocInputType ();
    for (i = 0; i < NUM_TS_NAMES; i++)    
    {
	TsPort = open (TsNames[i], 0);
	if (TsPort >= 0) 
	{
	    if (KdRegisterFd (TsInputType, TsPort, TsRead, 0))
		return 1;
	}
    }
    perror("Touch screen not found.\n");
    exit (1);
}

void
TsFini (void)
{
    KdUnregisterFds (TsInputType, TRUE);
}

KdMouseFuncs TsFuncs = {
    TsInit,
    TsFini
};
