#include "xf86Version.h"
#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(3,9,0,0,0)
#define XFREE86_V4 1
#endif
#ifdef XFREE86_V4
#ifndef XFree86LOADER
#include <unistd.h>
#include <errno.h>
#endif
#include "misc.h"
#include "xf86.h"
#define NEED_XF86_TYPES
#if !defined(DGUX)
#include "xf86_ansic.h"
#include "xisb.h"
#endif
#include "xf86_OSproc.h"
#include "xf86Xinput.h"
#include "exevents.h"
#include "keysym.h"
#include "mipointer.h"
#ifdef XFree86LOADER
#include "xf86Module.h"
#endif
#define wait_for_fd(fd) xf86WaitForInput((fd), 1000)
#define tcflush(fd, n) xf86FlushInput((fd))
#undef read
#define read(a,b,c) xf86ReadSerial((a),(b),(c))
#undef write
#define write(a,b,c) xf86WriteSerial((a),(char*)(b),(c))
#undef close
#define close(a) xf86CloseSerial((a))
#define XCONFIG_PROBED "(==)"
#define XCONFIG_GIVEN "(**)"
#define xf86Verbose 1
#undef PRIVATE
#define PRIVATE(x) XI_PRIVATE(x)
static const char *default_options[] =
{
"BaudRate", "9600",
"DataBits", "8",
"StopBits", "1",
"Parity", "Odd",
"FlowControl", "Xoff",
"VTime", "10",
"VMin", "1",
NULL
};
static InputDriverPtr dedgeDrv;
#else
#include "Xos.h"
#include <signal.h>
#include <stdio.h>
#define NEED_EVENTS
#include "X.h"
#include "Xproto.h"
#include "misc.h"
#include "inputstr.h"
#include "scrnintstr.h"
#include "XI.h"
#include "XIproto.h"
#if defined(sun) && !defined(i386)
#define POSIX_TTY
#include <errno.h>
#include <termio.h>
#include <fcntl.h>
#include <ctype.h>
#include "extio.h"
#else
#include "compiler.h"
#ifdef XFree86LOADER
#include "xf86_libc.h"
#endif
#include "xf86.h"
#include "xf86Procs.h"
#include "xf86_OSlib.h"
#include "xf86_Config.h"
#include "xf86Xinput.h"
#include "atKeynames.h"
#endif
#if !defined(sun) || defined(i386)
#include "osdep.h"
#include "exevents.h"
#include "extnsionst.h"
#include "extinit.h"
#endif
#if defined(__QNX__) || defined(__QNXNTO__)
#define POSIX_TTY
#endif
#endif
#ifdef DBG
#undef DBG
#endif
#ifdef DEBUG
#undef DEBUG
#endif
static int debug_level = 10;
#define DEBUG 1
#if DEBUG
#define DBG(lvl, f) {if ((lvl) <= debug_level) f;}
#else
#define DBG(lvl, f)
#endif
#define ABSOLUTE_FLAG 1
#define STYLUS_FLAG 2
#define COMPATIBLE_FLAG 4
typedef struct {
char *dedgeDevice;
int dedgeInc;
int dedgeButTrans;
int dedgeOldX;
int dedgeOldY;
int dedgeOldProximity;
int dedgeOldPush;
int dedgeOldBarrel;
int dedgeOldPressure;
int dedgeMaxX;
int dedgeMaxY;
int dedgeXSize;
int dedgeXOffset;
int dedgeYSize;
int dedgeYOffset;
int dedgeRes;
int dedgeClickThresh;
int flags;
int dedgeIndex;
unsigned char dedgeData[5];
} DigitalEdgeDeviceRec, *DigitalEdgeDevicePtr;
#define DEDGE_SECTION_NAME "DigitalEdge"
#ifndef XFREE86_V4
#define PORT 1
#define DEVICENAME 2
#define THE_MODE 3
#define CURSOR 4
#define INCREMENT 5
#define BORDER 6
#define DEBUG_LEVEL 7
#define HISTORY_SIZE 8
#define ALWAYS_CORE 9
#define ACTIVE_AREA 10
#define ACTIVE_OFFSET 11
#define COMPATIBLE 12
#define CLICK_THRESHOLD 13
#if !defined(sun) || defined(i386)
static SymTabRec SumTab[] = {
{ENDSUBSECTION, "endsubsection"},
{PORT, "port"},
{DEVICENAME, "devicename"},
{THE_MODE, "mode"},
{CURSOR, "cursor"},
{INCREMENT, "increment"},
{BORDER, "border"},
{DEBUG_LEVEL, "debuglevel"},
{HISTORY_SIZE, "historysize"},
{ALWAYS_CORE, "alwayscore"},
{ACTIVE_AREA, "activearea"},
{ACTIVE_OFFSET, "activeoffset"},
{COMPATIBLE, "compatible"},
{CLICK_THRESHOLD, "clickthreshold"},
{-1, ""}
};
#define RELATIVE 1
#define ABSOLUTE 2
static SymTabRec SumModeTabRec[] = {
{RELATIVE, "relative"},
{ABSOLUTE, "absolute"},
{-1, ""}
};
#define PUCK 1
#define STYLUS 2
static SymTabRec SumPointTabRec[] = {
{PUCK, "puck"},
{STYLUS, "stylus"},
{-1, ""}
};
#endif
#endif
#define BUFFER_SIZE 256
#define XI_NAME "DIGITALEDGE"
#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
#define SS_TABID0 "0"
#define SS_FIRMID "z?"
#define SS_CONFIG "a"
#define SS_ABSOLUTE 'F'
#define SS_RELATIVE 'E'
#define SS_UPPER_ORIGIN "b"
#define SS_500LPI "h"
#define SS_PROMPT_MODE "B"
#define SS_STREAM_MODE "@"
#define SS_INCREMENT 'I'
#define SS_BINARY_FMT "zb"
#define SS_PROMPT "P"
static const char *ss_initstr =
SS_TABID0 SS_UPPER_ORIGIN SS_BINARY_FMT SS_STREAM_MODE;
#define PHASING_BIT 0x80
#define PROXIMITY_BIT 0x01
#define TABID_BIT 0x20
#define XSIGN_BIT 0x10
#define YSIGN_BIT 0x08
#define BUTTON_BITS 0x02
#define COORD_BITS 0x7f
#ifndef XFREE86_V4
#if defined(sun) && !defined(i386)
#define ENQUEUE suneqEnqueue
#else
#define ENQUEUE xf86eqEnqueue
extern void xf86eqEnqueue(
xEventPtr
);
#endif
extern void miPointerDeltaCursor(
int ,
int ,
unsigned long
);
#if !defined(sun) || defined(i386)
static Bool
xf86SumConfig(LocalDevicePtr * array, int inx, int max, LexPtr val)
{
LocalDevicePtr dev = array[inx];
DigitalEdgeDevicePtr priv = (DigitalEdgeDevicePtr) (dev->private);
int token;
int mtoken;
DBG(1, ErrorF("xf86SumConfig\n"));
while ((token = xf86GetToken(SumTab)) != ENDSUBSECTION) {
switch (token) {
case DEVICENAME:
if (xf86GetToken(NULL) != STRING)
xf86ConfigError("Option string expected");
else {
dev->name = strdup(val->str);
if (xf86Verbose)
ErrorF("%s DigitalEdge X device name is %s\n",
XCONFIG_GIVEN, dev->name);
}
break;
case PORT:
if (xf86GetToken(NULL) != STRING)
xf86ConfigError("Option string expected");
else {
priv->dedgeDevice = strdup(val->str);
if (xf86Verbose)
ErrorF("%s DigitalEdge port is %s\n", XCONFIG_GIVEN,
priv->dedgeDevice);
}
break;
case THE_MODE:
mtoken = xf86GetToken(SumModeTabRec);
if ((mtoken == EOF) || (mtoken == STRING)
|| (mtoken ==
NUMBER)) xf86ConfigError("Mode type token expected");
else {
switch (mtoken) {
case ABSOLUTE:
priv->flags |= ABSOLUTE_FLAG;
break;
case RELATIVE:
priv->flags &= ~ABSOLUTE_FLAG;
break;
default:
xf86ConfigError("Illegal Mode type");
break;
}
}
break;
case CURSOR:
mtoken = xf86GetToken(SumPointTabRec);
if ((mtoken == EOF) || (mtoken == STRING)
|| (mtoken ==
NUMBER)) xf86ConfigError("Cursor token expected");
else {
switch (mtoken) {
case STYLUS:
priv->flags |= STYLUS_FLAG;
break;
case PUCK:
priv->flags &= ~STYLUS_FLAG;
break;
default:
xf86ConfigError("Illegal cursor type");
break;
}
}
break;
case INCREMENT:
if (xf86GetToken(NULL) != NUMBER)
xf86ConfigError("Option number expected");
priv->dedgeInc = val->num;
if (xf86Verbose)
ErrorF("%s DigitalEdge increment value is %d\n",
XCONFIG_GIVEN, priv->dedgeInc);
break;
case CLICK_THRESHOLD:
if (xf86GetToken(NULL) != NUMBER)
xf86ConfigError("Option number expected");
priv->dedgeClickThresh = val->num;
if (xf86Verbose)
ErrorF("%s DigitalEdge click threshold is %d\n",
XCONFIG_GIVEN, priv->dedgeClickThresh);
break;
case DEBUG_LEVEL:
if (xf86GetToken(NULL) != NUMBER)
xf86ConfigError("Option number expected");
debug_level = val->num;
if (xf86Verbose) {
#if DEBUG
ErrorF("%s DigitalEdge debug level sets to %d\n",
XCONFIG_GIVEN, debug_level);
#else
ErrorF("%s DigitalEdge debug level not sets to %d because"
" debugging is not compiled\n", XCONFIG_GIVEN,
debug_level);
#endif
}
break;
case HISTORY_SIZE:
if (xf86GetToken(NULL) != NUMBER)
xf86ConfigError("Option number expected");
dev->history_size = val->num;
if (xf86Verbose)
ErrorF("%s DigitalEdge Motion history size is %d\n",
XCONFIG_GIVEN, dev->history_size);
break;
case COMPATIBLE:
priv->flags |= COMPATIBLE_FLAG;
if (xf86Verbose)
ErrorF
("DigitalEdge compatible - will not query firmware ID\n");
break;
case ALWAYS_CORE:
xf86AlwaysCore(dev, TRUE);
if (xf86Verbose)
ErrorF("%s DigitalEdge device always stays core pointer\n",
XCONFIG_GIVEN);
break;
case ACTIVE_AREA:
if (xf86GetToken(NULL) != NUMBER)
xf86ConfigError("Option number expected");
priv->dedgeXSize = val->num;
if (xf86GetToken(NULL) != NUMBER)
xf86ConfigError("Option number expected");
priv->dedgeYSize = val->num;
ErrorF("%s DigitalEdge active area set to %d.%1dx%d.%1d"
" inches\n", XCONFIG_GIVEN, priv->dedgeXSize / 10,
priv->dedgeXSize % 10, priv->dedgeYSize / 10,
priv->dedgeYSize % 10);
break;
case ACTIVE_OFFSET:
if (xf86GetToken(NULL) != NUMBER)
xf86ConfigError("Option number expected");
priv->dedgeXOffset = val->num;
if (xf86GetToken(NULL) != NUMBER)
xf86ConfigError("Option number expected");
priv->dedgeYOffset = val->num;
if (xf86Verbose)
ErrorF
("%s DigitalEdge active area offset set to %d.%1dx%d.%1d"
" inches\n", XCONFIG_GIVEN, priv->dedgeXOffset / 10,
priv->dedgeXOffset % 10, priv->dedgeYOffset / 10,
priv->dedgeYOffset % 10);
break;
case EOF:
FatalError("Unexpected EOF (missing EndSubSection)");
break;
default:
xf86ConfigError("DigitalEdge subsection keyword expected");
break;
}
}
DBG(1, ErrorF("xf86SumConfig name=%s\n", priv->dedgeDevice));
return Success;
}
#endif
#endif
static Bool
xf86SumConvert(LocalDevicePtr local,
int first,
int num,
int v0,
int v1, int v2, int v3, int v4, int v5, int *x, int *y)
{
if (first != 0 || num == 1)
return FALSE;
*x = v0 * screenInfo.screens[0]->width / 2430;
*y = v1 * screenInfo.screens[0]->height / 1950;
DBG(6, ErrorF("Adjusted coords x=%d y=%d\n", *x, *y));
return TRUE;
}
static Bool
xf86SumReverseConvert(LocalDevicePtr local, int x, int y, int *valuators)
{
DigitalEdgeDevicePtr priv = (DigitalEdgeDevicePtr) local->private;
valuators[0] = ((x * 2430) / screenInfo.screens[0]->width) + priv->dedgeXOffset;
valuators[1] = ((y * 1950) / screenInfo.screens[0]->height) + priv->dedgeYOffset;
DBG(6,
ErrorF("Adjusted valuators v0=%d v1=%d\n", valuators[0],
valuators[1]));
return TRUE;
}
static void xf86SumReadInput(LocalDevicePtr local)
{
DigitalEdgeDevicePtr priv = (DigitalEdgeDevicePtr) local->private;
int len, loop;
int is_absolute;
int x, y, push, barrel, prox, pressure;
DeviceIntPtr device;
unsigned char buffer[BUFFER_SIZE];
DBG(7, ErrorF("xf86SumReadInput BEGIN device=%s fd=%d\n",
priv->dedgeDevice, local->fd));
SYSCALL(len = read(local->fd, buffer, sizeof(buffer)));
if (len <= 0) {
Error("error reading DigitalEdge device");
return;
}
for (loop = 0; loop < len; loop++) {
if ((priv->dedgeIndex == 0) && !(buffer[loop] & PHASING_BIT)) {
DBG(6,
ErrorF("xf86SumReadInput bad magic number 0x%x\n",
buffer[loop]));;
continue;
}
priv->dedgeData[priv->dedgeIndex++] = buffer[loop];
if (priv->dedgeIndex == 7) {
priv->dedgeIndex = 0;
if (priv->flags & ABSOLUTE_FLAG) {
x = (int) priv->dedgeData[1] + ((int) priv->dedgeData[2] << 7);
y = 1950 - ((int) priv->dedgeData[3] + ((int) priv->dedgeData[4] << 7));
} else {
x =
priv->dedgeData[0] & XSIGN_BIT ? priv->
dedgeData[1] : -priv->dedgeData[1];
y =
priv->dedgeData[0] & YSIGN_BIT ? priv->
dedgeData[2] : -priv->dedgeData[2];
}
prox = (priv->dedgeData[0] & PROXIMITY_BIT) ? 1 : 0;
pressure = priv->dedgeData[6] + (priv->dedgeData[5] >> 4) * 128;
push = pressure > priv->dedgeClickThresh?1:0;
if ((priv->dedgeOldPressure) < priv->dedgeClickThresh && pressure == 1022) {
push = 0;
} else {
priv->dedgeOldPressure = pressure;
}
if (priv->dedgeData[0] & BUTTON_BITS) {
barrel = 1;
} else {
barrel = 0;
}
device = local->dev;
DBG(6, ErrorF("prox=%s\tx=%d\ty=%d\tbarrel=%d\tpressure=%d\n",
prox ? "true" : "false", x, y, barrel,
pressure));
is_absolute = (priv->flags & ABSOLUTE_FLAG);
if (prox) {
if (!(priv->dedgeOldProximity))
xf86PostProximityEvent(device, 1, 0, 3, x, y, pressure);
if (
(is_absolute
&& ((priv->dedgeOldX != x) || (priv->dedgeOldY != y)))
|| (!is_absolute && (x || y))) {
if (is_absolute || priv->dedgeOldProximity) {
xf86PostMotionEvent(device, is_absolute, 0, 3, x,
y, pressure);
}
}
if (priv->dedgeOldPush != push) {
int delta;
delta = push - priv->dedgeOldPush;
if (priv->dedgeOldPush != push) {
DBG(6,
ErrorF("xf86SumReadInput push delta=%d\n", delta));
xf86PostButtonEvent(device, is_absolute, 1,
(delta > 0), 0, 3, x, y, pressure);
}
}
if (priv->dedgeOldBarrel != barrel) {
int delta;
delta = barrel - priv->dedgeOldBarrel;
if (priv->dedgeOldBarrel != barrel) {
DBG(6,
ErrorF("xf86SumReadInput barrel delta=%d\n", delta));
xf86PostButtonEvent(device, is_absolute, 2,
(delta > 0), 0, 3, x, y, pressure);
}
}
priv->dedgeOldPush = push;
priv->dedgeOldBarrel = barrel;
priv->dedgeOldX = x;
priv->dedgeOldY = y;
priv->dedgeOldProximity = prox;
} else {
if (priv->dedgeOldProximity)
xf86PostProximityEvent(device, 0, 0, 3, x, y, pressure);
priv->dedgeOldProximity = 0;
}
}
}
DBG(7, ErrorF("xf86Sum(priv->dedgeData[0] & BUTTON_BITS)iReadInput END device=%p priv=%p\n",
(void *)local->dev, (void *)priv));
}
static void xf86SumControlProc(DeviceIntPtr device, PtrCtrl * ctrl)
{
DBG(2, ErrorF("xf86SumControlProc\n"));
}
#if 0
static char *xf86SumWriteAndRead(int fd, char *data, char *buffer, int len,
int cr_term)
{
int err, numread = 0;
#ifndef XFREE86_V4
fd_set readfds;
struct timeval timeout;
#endif
SYSCALL(err = write(fd, data, strlen(data)));
if (err == -1) {
Error("DigitalEdge write");
return NULL;
}
#ifndef XFREE86_V4
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
#endif
while (numread < len) {
#ifndef XFREE86_V4
timeout.tv_sec = 0;
timeout.tv_usec = 200000;
SYSCALL(err = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout));
#else
err = xf86WaitForInput(fd, 1000);
#endif
if (err == -1) {
Error("DigitalEdge select");
return NULL;
}
if (!err) {
ErrorF
("Timeout while reading DigitalEdge tablet. No tablet connected ???\n");
return NULL;
}
SYSCALL(err = read(fd, buffer + numread++, 1));
if (err == -1) {
Error("DigitalEdge read");
return NULL;
}
if (!err) {
--numread;
break;
}
if (cr_term && buffer[numread - 1] == '\r') {
buffer[numread - 1] = 0;
break;
}
}
buffer[numread] = 0;
return buffer;
}
#endif
static Bool xf86SumOpen(LocalDevicePtr local)
{
#ifndef XFREE86_V4
struct termios termios_tty;
struct timeval timeout;
#endif
char buffer[256];
int err, idx;
DigitalEdgeDevicePtr priv = (DigitalEdgeDevicePtr) local->private;
DBG(1, ErrorF("opening %s\n", priv->dedgeDevice));
#ifdef XFREE86_V4
local->fd = xf86OpenSerial(local->options);
#else
SYSCALL(local->fd = open(priv->dedgeDevice, O_RDWR | O_NDELAY, 0));
#endif
if (local->fd == -1) {
Error(priv->dedgeDevice);
return !Success;
}
DBG(2, ErrorF("%s opened as fd %d\n", priv->dedgeDevice, local->fd));
#ifndef XFREE86_V4
#ifdef POSIX_TTY
err = tcgetattr(local->fd, &termios_tty);
if (err == -1) {
Error("DigitalEdge tcgetattr");
return !Success;
}
termios_tty.c_iflag = IXOFF;
termios_tty.c_cflag =
B9600 | CS8 | CREAD | CLOCAL | HUPCL | PARENB | PARODD;
termios_tty.c_lflag = 0;
termios_tty.c_cc[VINTR] = 0;
termios_tty.c_cc[VQUIT] = 0;
termios_tty.c_cc[VERASE] = 0;
#ifdef VWERASE
termios_tty.c_cc[VWERASE] = 0;
#endif
#ifdef VREPRINT
termios_tty.c_cc[VREPRINT] = 0;
#endif
termios_tty.c_cc[VKILL] = 0;
termios_tty.c_cc[VEOF] = 0;
termios_tty.c_cc[VEOL] = 0;
#ifdef VEOL2
termios_tty.c_cc[VEOL2] = 0;
#endif
termios_tty.c_cc[VSUSP] = 0;
#ifdef VDISCARD
termios_tty.c_cc[VDISCARD] = 0;
#endif
#ifdef VLNEXT
termios_tty.c_cc[VLNEXT] = 0;
#endif
termios_tty.c_cc[VMIN] = 1;
termios_tty.c_cc[VTIME] = 10;
err = tcsetattr(local->fd, TCSANOW, &termios_tty);
if (err == -1) {
Error("DigitalEdge tcsetattr TCSANOW");
return !Success;
}
#else
Code for someone
else
to write to handle OSs without POSIX tty functions
#endif
#endif
DBG(1, ErrorF("initializing DigitalEdge tablet\n"));
SYSCALL(err = write(local->fd, "", 1));
if (err == -1) {
Error("DigitalEdge write");
return !Success;
}
#ifndef XFREE86_V4
timeout.tv_sec = 0;
timeout.tv_usec = 200000;
SYSCALL(err = select(0, NULL, NULL, NULL, &timeout));
#else
err = xf86WaitForInput(-1, 200);
#endif
if (err == -1) {
Error("DigitalEdge select");
return !Success;
}
SYSCALL(err =
write(local->fd, SS_PROMPT_MODE, strlen(SS_PROMPT_MODE)));
if (err == -1) {
Error("DigitalEdge write");
return !Success;
}
#ifndef XFREE86_V4
tcflush(local->fd, TCIFLUSH);
#else
xf86FlushInput(local->fd);
#endif
if (priv->dedgeXOffset > 0 && priv->dedgeYOffset > 0) {
if (priv->dedgeXSize * 50 < priv->dedgeMaxX - priv->dedgeXOffset &&
priv->dedgeYSize * 50 < priv->dedgeMaxY - priv->dedgeYOffset) {
priv->dedgeXOffset *= 50;
priv->dedgeYOffset *= 50;
} else {
ErrorF("%s DigitalEdge offset sets active area off tablet, "
"centering\n", XCONFIG_PROBED);
priv->dedgeXOffset = (priv->dedgeMaxX - priv->dedgeXSize) / 2;
priv->dedgeYOffset = (priv->dedgeMaxY - priv->dedgeYSize) / 2;
}
} else {
priv->dedgeXOffset = (priv->dedgeMaxX - priv->dedgeXSize) / 2;
priv->dedgeYOffset = (priv->dedgeMaxY - priv->dedgeYSize) / 2;
}
if (priv->dedgeInc > 95)
priv->dedgeInc = 95;
if (priv->dedgeInc < 1) {
if (priv->dedgeXSize / screenInfo.screens[0]->width <
priv->dedgeYSize / screenInfo.screens[0]->height)
priv->dedgeInc = priv->dedgeXSize / screenInfo.screens[0]->width;
else
priv->dedgeInc = priv->dedgeYSize / screenInfo.screens[0]->height;
if (priv->dedgeInc < 1)
priv->dedgeInc = 1;
if (xf86Verbose)
ErrorF("%s Using increment value of %d\n", XCONFIG_PROBED,
priv->dedgeInc);
}
for (idx = 0; ss_initstr[idx]; idx++) {
buffer[idx] = ss_initstr[idx];
}
buffer[idx++] = SS_INCREMENT;
buffer[idx++] = 32 + priv->dedgeInc;
buffer[idx++] =
(priv->flags & ABSOLUTE_FLAG) ? SS_ABSOLUTE : SS_RELATIVE;
buffer[idx] = 0;
SYSCALL(err = write(local->fd, buffer, idx));
if (err == -1) {
Error("DigitalEdge write");
return !Success;
}
if (err <= 0) {
SYSCALL(close(local->fd));
return !Success;
}
if (priv->dedgeClickThresh <= 0) {
priv->dedgeClickThresh = 700;
}
return Success;
}
static int xf86SumOpenDevice(DeviceIntPtr pSum)
{
LocalDevicePtr local = (LocalDevicePtr) pSum->public.devicePrivate;
DigitalEdgeDevicePtr priv = (DigitalEdgeDevicePtr) PRIVATE(pSum);
if (xf86SumOpen(local) != Success) {
if (local->fd >= 0) {
SYSCALL(close(local->fd));
}
local->fd = -1;
}
InitValuatorAxisStruct(pSum, 0, 0,
2430,
500,
0,
500);
InitValuatorAxisStruct(pSum, 1, 0,
1950,
500,
0,
500);
InitValuatorAxisStruct(pSum, 2, priv->dedgeClickThresh,
1022,
500,
0,
500);
return (local->fd != -1);
}
static int xf86SumProc(DeviceIntPtr pSum, int what)
{
CARD8 map[25];
int nbaxes;
int nbbuttons;
int loop;
LocalDevicePtr local = (LocalDevicePtr) pSum->public.devicePrivate;
DigitalEdgeDevicePtr priv = (DigitalEdgeDevicePtr) PRIVATE(pSum);
DBG(2,
ErrorF("BEGIN xf86SumProc dev=%p priv=%p what=%d\n", (void *)pSum,
(void *)priv, what));
switch (what) {
case DEVICE_INIT:
DBG(1, ErrorF("xf86SumProc pSum=%p what=INIT\n", (void *)pSum));
nbaxes = 3;
nbbuttons = (priv->flags & STYLUS_FLAG) ? 2 : 4;
for (loop = 1; loop <= nbbuttons; loop++)
map[loop] = loop;
if (InitButtonClassDeviceStruct(pSum, nbbuttons, map) == FALSE) {
ErrorF("unable to allocate Button class device\n");
return !Success;
}
if (InitFocusClassDeviceStruct(pSum) == FALSE) {
ErrorF("unable to init Focus class device\n");
return !Success;
}
if (InitPtrFeedbackClassDeviceStruct(pSum, xf86SumControlProc) ==
FALSE) {
ErrorF("unable to init ptr feedback\n");
return !Success;
}
if (InitProximityClassDeviceStruct(pSum) == FALSE) {
ErrorF("unable to init proximity class device\n");
return !Success;
}
if (InitValuatorClassDeviceStruct(pSum,
nbaxes,
xf86GetMotionEvents,
local->history_size,
(priv->flags & ABSOLUTE_FLAG) ?
Absolute : Relative) == FALSE) {
ErrorF("unable to allocate Valuator class device\n");
return !Success;
}
xf86MotionHistoryAllocate(local);
#ifndef XFREE86_V4
AssignTypeAndName(pSum, local->atom, local->name);
#endif
xf86SumOpenDevice(pSum);
break;
case DEVICE_ON:
DBG(1, ErrorF("xf86SumProc pSum=%p what=ON\n", (void *)pSum));
if ((local->fd < 0) && (!xf86SumOpenDevice(pSum))) {
return !Success;
}
SYSCALL(write(local->fd, SS_PROMPT, strlen(SS_PROMPT)));
#ifdef XFREE86_V4
xf86AddEnabledDevice(local);
#else
AddEnabledDevice(local->fd);
#endif
pSum->public.on = TRUE;
break;
case DEVICE_OFF:
DBG(1, ErrorF("xf86SumProc pSum=%p what=%s\n", (void *)pSum,
(what == DEVICE_CLOSE) ? "CLOSE" : "OFF"));
if (local->fd >= 0)
#ifdef XFREE86_V4
xf86RemoveEnabledDevice(local);
#else
RemoveEnabledDevice(local->fd);
#endif
pSum->public.on = FALSE;
break;
case DEVICE_CLOSE:
DBG(1, ErrorF("xf86SumProc pSum=%p what=%s\n", (void *)pSum,
(what == DEVICE_CLOSE) ? "CLOSE" : "OFF"));
SYSCALL(close(local->fd));
local->fd = -1;
break;
default:
ErrorF("unsupported mode=%d\n", what);
return !Success;
break;
}
DBG(2, ErrorF("END xf86SumProc Success what=%d dev=%p priv=%p\n",
what, (void *)pSum, (void *)priv));
return Success;
}
static void xf86SumClose(LocalDevicePtr local)
{
if (local->fd >= 0) {
SYSCALL(close(local->fd));
}
local->fd = -1;
}
static int xf86SumChangeControl(LocalDevicePtr local, xDeviceCtl * control)
{
xDeviceResolutionCtl *res;
res = (xDeviceResolutionCtl *) control;
if ((control->control != DEVICE_RESOLUTION)
|| (res->num_valuators < 1)) return (BadMatch);
return (Success);
}
static int xf86SumSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode)
{
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
DigitalEdgeDevicePtr priv = (DigitalEdgeDevicePtr) (local->private);
char newmode;
DBG(3, ErrorF("xf86SumSwitchMode dev=%p mode=%d\n", (void *)dev, mode));
switch (mode) {
case Absolute:
priv->flags |= ABSOLUTE_FLAG;
newmode = SS_ABSOLUTE;
break;
case Relative:
priv->flags &= ~ABSOLUTE_FLAG;
newmode = SS_RELATIVE;
break;
default:
DBG(1, ErrorF("xf86SumSwitchMode dev=%p invalid mode=%d\n",
(void *)dev, mode));
return BadMatch;
}
SYSCALL(write(local->fd, &newmode, 1));
return Success;
}
static LocalDevicePtr xf86SumAllocate(void)
{
#ifdef XFREE86_V4
LocalDevicePtr local = xf86AllocateInput(dedgeDrv, 0);
#else
LocalDevicePtr local = (LocalDevicePtr) xalloc(sizeof(LocalDeviceRec));
#endif
DigitalEdgeDevicePtr priv = (DigitalEdgeDevicePtr) xalloc(sizeof(DigitalEdgeDeviceRec));
#if defined (sun) && !defined(i386)
char *dev_name = getenv("DEDGESKETCH_DEV");
#endif
local->name = XI_NAME;
local->type_name = "DigitalEdge Tablet";
local->flags = 0;
#ifndef XFREE86_V4
#if !defined(sun) || defined(i386)
local->device_config = xf86SumConfig;
#endif
#endif
local->device_control = xf86SumProc;
local->read_input = xf86SumReadInput;
local->control_proc = xf86SumChangeControl;
local->close_proc = xf86SumClose;
local->switch_mode = xf86SumSwitchMode;
local->conversion_proc = xf86SumConvert;
local->reverse_conversion_proc = xf86SumReverseConvert;
local->fd = -1;
local->atom = 0;
local->dev = NULL;
local->private = priv;
local->private_flags = 0;
local->history_size = 0;
#if defined(sun) && !defined(i386)
if (dev_name) {
priv->dedgeDevice = (char *) xalloc(strlen(dev_name) + 1);
strcpy(priv->dedgeDevice, dev_name);
ErrorF("xf86SumOpen port changed to '%s'\n", priv->dedgeDevice);
} else {
priv->dedgeDevice = "";
}
#else
priv->dedgeDevice = "";
#endif
priv->dedgeInc = -1;
priv->dedgeOldX = -1;
priv->dedgeOldY = -1;
priv->dedgeOldProximity = 0;
priv->dedgeOldPush = 0;
priv->dedgeOldBarrel = 0;
priv->dedgeMaxX = -1;
priv->dedgeMaxY = -1;
priv->dedgeXSize = -1;
priv->dedgeXOffset = -1;
priv->dedgeYSize = -1;
priv->dedgeYOffset = -1;
priv->flags = 0;
priv->dedgeIndex = 0;
return local;
}
#ifndef XFREE86_V4
DeviceAssocRec dedgemasketch_assoc = {
DEDGE_SECTION_NAME,
xf86SumAllocate
};
#ifdef DYNAMIC_MODULE
int
#ifndef DLSYM_BUG
init_module(unsigned long server_version)
#else
init_xf86DigitalEdge(unsigned long server_version)
#endif
{
xf86AddDeviceAssoc(&dedgemasketch_assoc);
if (server_version != XF86_VERSION_CURRENT) {
ErrorF("Warning: DigitalEdgeKetch module compiled for version%s\n",
XF86_VERSION);
return 0;
} else {
return 1;
}
}
#endif
#else
static void
xf86SumUninit(InputDriverPtr drv,
LocalDevicePtr local,
int flags)
{
DigitalEdgeDevicePtr priv = (DigitalEdgeDevicePtr) local->private;
DBG(1, ErrorF("xf86DedgeUninit\n"));
xf86SumProc(local->dev, DEVICE_OFF);
xfree (priv);
xf86DeleteInput(local, 0);
}
static InputInfoPtr
xf86SumInit(InputDriverPtr drv,
IDevPtr dev,
int flags)
{
LocalDevicePtr local = NULL;
DigitalEdgeDevicePtr priv = NULL;
char *s;
dedgeDrv = drv;
local = xf86SumAllocate();
local->conf_idev = dev;
xf86CollectInputOptions(local, default_options, NULL);
xf86OptionListReport( local->options );
if (local)
priv = (DigitalEdgeDevicePtr) local->private;
if (!local || !priv) {
goto SetupProc_fail;
}
local->name = dev->identifier;
priv->dedgeDevice = xf86FindOptionValue(local->options, "Device");
if (!priv->dedgeDevice) {
xf86Msg (X_ERROR, "%s: No Device specified.\n", dev->identifier);
goto SetupProc_fail;
}
xf86ProcessCommonOptions(local, local->options);
xf86Msg(X_CONFIG, "%s serial device is %s\n", dev->identifier,
priv->dedgeDevice);
debug_level = xf86SetIntOption(local->options, "DebugLevel", 0);
if (debug_level > 0) {
xf86Msg(X_CONFIG, "Summa: debug level set to %d\n", debug_level);
}
s = xf86FindOptionValue(local->options, "Mode");
if (s && (xf86NameCmp(s, "absolute") == 0)) {
priv->flags = priv->flags | ABSOLUTE_FLAG;
}
else if (s && (xf86NameCmp(s, "relative") == 0)) {
priv->flags = priv->flags & ~ABSOLUTE_FLAG;
}
else if (s) {
xf86Msg(X_ERROR, "%s: invalid Mode (should be absolute or relative). "
"Using default.\n", dev->identifier);
}
xf86Msg(X_CONFIG, "%s is in %s mode\n", local->name,
(priv->flags & ABSOLUTE_FLAG) ? "absolute" : "relative");
s = xf86FindOptionValue(local->options, "Cursor");
if (s && (xf86NameCmp(s, "stylus") == 0)) {
priv->flags = priv->flags | STYLUS_FLAG;
}
else if (s && (xf86NameCmp(s, "puck") == 0)) {
priv->flags = priv->flags & ~STYLUS_FLAG;
}
else if (s) {
xf86Msg(X_ERROR, "%s: invalid Cursor (should be stylus or puck). "
"Using default.\n", dev->identifier);
}
xf86Msg(X_CONFIG, "%s is in cursor-mode %s\n", local->name,
(priv->flags & STYLUS_FLAG) ? "cursor" : "puck");
priv->dedgeInc = xf86SetIntOption(local->options, "increment", 0);
if (priv->dedgeInc != 0) {
xf86Msg(X_CONFIG, "%s: Increment = %d\n",
dev->identifier, priv->dedgeInc);
}
priv->dedgeClickThresh = xf86SetIntOption(local->options,
"clickthreshold", 0);
if (priv->dedgeClickThresh != 0) {
xf86Msg(X_CONFIG, "%s: click threshold is %d\n",
dev->identifier, priv->dedgeClickThresh);
}
priv->dedgeXSize = xf86SetIntOption(local->options, "XSize", 0);
if (priv->dedgeXSize != 0) {
xf86Msg(X_CONFIG, "%s: XSize = %d\n",
dev->identifier, priv->dedgeXSize);
}
priv->dedgeYSize = xf86SetIntOption(local->options, "YSize", 0);
if (priv->dedgeYSize != 0) {
xf86Msg(X_CONFIG, "%s: YSize = %d\n",
dev->identifier, priv->dedgeYSize);
}
priv->dedgeXOffset = xf86SetIntOption(local->options, "XOffset", 0);
if (priv->dedgeXOffset != 0) {
xf86Msg(X_CONFIG, "%s: XOffset = %d\n",
dev->identifier, priv->dedgeXOffset);
}
priv->dedgeYOffset = xf86SetIntOption(local->options, "YOffset", 0);
if (priv->dedgeYOffset != 0) {
xf86Msg(X_CONFIG, "%s: YOffset = %d\n",
dev->identifier, priv->dedgeYOffset);
}
local->flags |= XI86_POINTER_CAPABLE | XI86_CONFIGURED;
return local;
SetupProc_fail:
if (priv)
xfree(priv);
return local;
}
#ifdef XFree86LOADER
static
#endif
InputDriverRec DIGITALEDGE = {
1,
"digitaledge",
NULL,
xf86SumInit,
xf86SumUninit,
NULL,
0
};
#ifdef XFree86LOADER
static void
xf86SumUnplug(pointer p)
{
}
static pointer
xf86SumPlug(pointer module,
pointer options,
int *errmaj,
int *errmin)
{
xf86AddInputDriver(&DIGITALEDGE, module, 0);
return module;
}
static XF86ModuleVersionInfo xf86SumVersionRec =
{
"digitaledge",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XF86_VERSION_CURRENT,
1, 0, 0,
ABI_CLASS_XINPUT,
ABI_XINPUT_VERSION,
MOD_CLASS_XINPUT,
{0, 0, 0, 0}
};
XF86ModuleData digitaledgeModuleData = {&xf86SumVersionRec,
xf86SumPlug,
xf86SumUnplug};
#endif
#endif