#include "xf86Aiptek.h"
static const char identification[] = "$Identification: 0 $";
static InputDriverPtr aiptekDrv;
static int debug_level = INI_DEBUG_LEVEL;
#ifdef XFree86LOADER
static
#endif
InputDriverRec AIPTEK =
{
1,
"aiptek",
NULL,
xf86AiptekInit,
xf86AiptekUninit,
NULL,
0
};
static KeySym aiptek_map[] =
{
NoSymbol,NoSymbol,NoSymbol,NoSymbol,NoSymbol,NoSymbol,NoSymbol,NoSymbol,
XK_F1, XK_F2, XK_F3, XK_F4, XK_F5, XK_F6, XK_F7, XK_F8,
XK_F9, XK_F10, XK_F11, XK_F12, XK_F13, XK_F14, XK_F15, XK_F16,
XK_F17, XK_F18, XK_F19, XK_F20, XK_F21, XK_F22, XK_F23, XK_F24,
XK_F25, XK_F26, XK_F27, XK_F28, XK_F29, XK_F30, XK_F31, XK_F32
};
static int linux_inputDevice_keyMap[] =
{
KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8,
KEY_F9, KEY_F10, KEY_F11, KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16,
KEY_F17, KEY_F18, KEY_F19, KEY_F20, KEY_F21, KEY_F22, KEY_F23, KEY_F24,
KEY_STOP, KEY_AGAIN, KEY_PROPS, KEY_UNDO, KEY_FRONT, KEY_COPY,
KEY_OPEN, KEY_PASTE
};
static KeySymsRec keysyms =
{
aiptek_map, 8, 0x27, 1
};
static const char *default_options[] =
{
"BaudRate", "9600",
"StopBits", "1",
"DataBits", "8",
"Parity", "None",
"VMin", "1",
"Vtime", "10",
"FlowControl", "Xoff",
NULL
};
static Bool
xf86AiptekConvert(LocalDevicePtr local,
int first,
int num,
int v0,
int v1,
int v2,
int v3,
int v4,
int v5,
int* x,
int* y)
{
AiptekDevicePtr device = (AiptekDevicePtr) local->private;
int xSize, ySize;
int width, height;
DBG(6, ErrorF("xf86AiptekConvert\n"));
xf86Msg(X_CONFIG, " xf86AiptekConvert(), with: first=%d, num=%d, v0=%d, "
"v1=%d, v2=%d, v3=%d,, v4=%d, v5=%d, x=%d, y=%d\n",
first, num, v0, v1, v2, v3, v4, v5, *x, *y);
if (first != 0 || num == 1)
{
return FALSE;
}
xSize = device->xBottom - device->xTop;
ySize = device->yBottom - device->yTop;
width = screenInfo.screens[device->screenNo]->width;
height = screenInfo.screens[device->screenNo]->height;
*x = (v0 * width) / xSize;
*y = (v1 * height) / ySize;
if ( device->flags & INVX_FLAG)
{
*x = width - *x;
}
if ( device->flags & INVY_FLAG)
{
*y = height - *y;
}
if (*x < 0)
{
*x = 0;
}
if (*x > width)
{
*x = width;
}
if (*y < 0)
{
*y = 0;
}
if (*y > height)
{
*y = height;
}
if (device->screenNo != 0)
{
xf86XInputSetScreen(local, device->screenNo, *x, *y);
}
xf86Msg(X_CONFIG, ": xf86AiptekConvert() exits, with: x=%d, y=%d\n",
*x, *y);
return TRUE;
}
static Bool
xf86AiptekReverseConvert(LocalDevicePtr local,
int x,
int y,
int* valuators)
{
AiptekDevicePtr device = (AiptekDevicePtr) local->private;
int xSize, ySize;
xf86Msg(X_CONFIG, ": xf86AiptekReverseConvert(), with: x=%d, y=%d, "
"valuators[0]=%d, valuators[1]=%d\n",
x, y, valuators[0], valuators[1] );
xSize = device->xBottom - device->xTop;
ySize = device->yBottom - device->yTop;
valuators[0] = (x*xSize) / screenInfo.screens[device->screenNo]->width;
valuators[1] = (y*ySize) / screenInfo.screens[device->screenNo]->height;
DBG(6, ErrorF("converted x,y (%d, %d) to (%d, %d)\n",
x, y, valuators[0], valuators[1] ));
if (device->screenNo != 0)
{
xf86XInputSetScreen(local,device->screenNo,valuators[0], valuators[1]);
}
xf86Msg(X_CONFIG, ": xf86AiptekReverseConvert() exits, with: "
"valuators[0]=%d, valuators[1]=%d\n",
valuators[0], valuators[1] );
return TRUE;
}
static void
xf86AiptekSendEvents(LocalDevicePtr local, int r_z)
{
AiptekDevicePtr device = (AiptekDevicePtr) local->private;
AiptekCommonPtr common = device->common;
int bCorePointer, bAbsolute;
int x, y, z, xTilt, yTilt;
if ((DEVICE_ID(device->flags) != common->currentValues.eventType))
{
DBG(7,ErrorF("xf86AiptekSendEvents: not the same device type (%u,%u)\n",
DEVICE_ID(device->flags), common->currentValues.eventType));
return;
}
bAbsolute = (device->flags & ABSOLUTE_FLAG);
bCorePointer = xf86IsCorePointer(local->dev);
if (bAbsolute)
{
x = common->currentValues.x;
y = common->currentValues.y;
z = r_z;
xTilt = common->currentValues.xTilt;
yTilt = common->currentValues.yTilt;
}
else
{
x = common->currentValues.x - common->previousValues.x;
y = common->currentValues.y - common->previousValues.y;
z = r_z - common->previousValues.z;
xTilt = common->currentValues.xTilt - common->previousValues.xTilt;
yTilt = common->currentValues.yTilt - common->previousValues.yTilt;
}
if (x > device->xBottom) {
x = device->xBottom;
}
if (y > device->yBottom) {
y = device->yBottom;
}
if (device->xTop > 0) {
DBG(10, ErrorF("Adjusting x, with xTop=%d\n", device->xTop));
x -= device->xTop;
}
if (device->yTop > 0) {
DBG(10, ErrorF("Adjusting y, with yTop=%d\n", device->yTop));
y -= device->yTop;
}
if (x < 0) {
x = 0;
}
if (y < 0) {
y = 0;
}
if (z < device->zMin) {
z = 0;
}
if (z > device->zMax) {
z = device->zMax;
}
if (common->currentValues.macroKey != VALUE_NA)
{
int i;
for (i = 0;
i < sizeof(linux_inputDevice_keyMap)/
sizeof(linux_inputDevice_keyMap[0]);
++i)
{
if (linux_inputDevice_keyMap[0]==common->currentValues.macroKey)
{
break;
}
}
xf86PostKeyEvent(local->dev, i+7, TRUE,
bAbsolute, 0, 5,
x, y, common->currentValues.button, xTilt, yTilt);
xf86PostKeyEvent(local->dev, i+7, FALSE,
bAbsolute, 0, 5,
x, y, common->currentValues.button, xTilt, yTilt);
}
if (common->currentValues.proximity)
{
if (!common->previousValues.proximity)
{
if (!bCorePointer)
{
xf86PostProximityEvent(local->dev, 1, 0, 5,
x, y, z, xTilt, yTilt);
}
}
if ((bAbsolute &&
(common->previousValues.x != common->currentValues.x ||
common->previousValues.y != common->currentValues.y ||
common->previousValues.z != common->currentValues.z)) ||
(!bAbsolute &&
(common->currentValues.x || common->currentValues.y)))
{
if (bAbsolute || common->previousValues.proximity)
{
xf86PostMotionEvent(local->dev, bAbsolute, 0, 5,
x, y, z, xTilt, yTilt);
}
}
if (common->previousValues.button != common->currentValues.button)
{
int delta;
delta = common->currentValues.button ^ common->previousValues.button;
while(delta)
{
int id;
id = ffs(delta);
delta &= ~(1 << (id-1));
xf86PostButtonEvent(local->dev, bAbsolute, id,
(common->currentValues.button & (1<<(id-1))), 0, 5,
x, y, z, xTilt, yTilt);
}
}
}
else
{
if (!bCorePointer)
{
if (common->previousValues.proximity)
{
xf86PostProximityEvent(local->dev, 0, 0, 5, x, y, z,
xTilt, yTilt);
}
}
common->previousValues.proximity = 0;
}
}
static void
xf86AiptekHIDReadInput(LocalDevicePtr local)
{
AiptekDevicePtr device = (AiptekDevicePtr) local->private;
AiptekCommonPtr common = device->common;
ssize_t len;
int i;
struct input_event* event;
char eventbuf[sizeof(struct input_event) * MAX_EVENTS];
int eventsInMessage;
double d_z;
double d_zCapacity;
SYSCALL(len = read(local->fd, eventbuf, sizeof(eventbuf)));
if (len <= 0)
{
ErrorF("Error reading Aiptek tablet: %s\n", strerror(errno));
return;
}
eventsInMessage = 0;
for (event=(struct input_event *)(eventbuf);
event<(struct input_event *)(eventbuf+len);
++event)
{
switch (event->type)
{
case EV_ABS:
{
switch (event->code)
{
case ABS_X:
{
++eventsInMessage;
common->currentValues.x = event->value;
}
break;
case ABS_Y:
{
++eventsInMessage;
common->currentValues.y = event->value;
}
break;
case ABS_PRESSURE:
{
++eventsInMessage;
common->currentValues.z = event->value;
}
break;
case ABS_TILT_X:
case ABS_RZ:
{
++eventsInMessage;
common->currentValues.xTilt = event->value;
}
break;
case ABS_TILT_Y:
{
++eventsInMessage;
common->currentValues.yTilt = event->value;
}
break;
case ABS_DISTANCE:
{
++eventsInMessage;
common->currentValues.distance = event->value;
}
break;
case ABS_WHEEL:
case ABS_THROTTLE:
{
++eventsInMessage;
common->currentValues.wheel = event->value;
}
break;
case ABS_MISC:
{
++eventsInMessage;
common->currentValues.proximity =
(event->value > 0 ? 1 : 0);
}
break;
}
}
break;
case EV_REL:
{
switch (event->code)
{
case REL_X:
{
++eventsInMessage;
common->currentValues.x =
common->previousValues.x + event->value;
}
break;
case REL_Y:
{
++eventsInMessage;
common->currentValues.y =
common->previousValues.y + event->value;
}
break;
case REL_WHEEL:
{
++eventsInMessage;
common->currentValues.wheel =
common->previousValues.wheel + event->value;
}
case REL_MISC:
{
++eventsInMessage;
common->currentValues.proximity =
(event->value > 0 ? 1 : 0);
}
break;
}
}
break;
case EV_KEY:
{
switch (event->code)
{
case BTN_TOOL_PEN:
case BTN_TOOL_PENCIL:
case BTN_TOOL_BRUSH:
case BTN_TOOL_AIRBRUSH:
{
++eventsInMessage;
common->currentValues.eventType = STYLUS_ID;
}
break;
case BTN_TOOL_RUBBER:
{
++eventsInMessage;
common->currentValues.eventType = ERASER_ID;
}
break;
case BTN_TOOL_MOUSE:
case BTN_TOOL_LENS:
{
++eventsInMessage;
common->currentValues.eventType = CURSOR_ID;
}
break;
case BTN_TOUCH:
{
++eventsInMessage;
common->currentValues.button |=
(event->value > 0 ? 1 : 0) * BUTTONS_EVENT_TOUCH;
}
break;
case BTN_STYLUS:
{
++eventsInMessage;
common->currentValues.button |=
(event->value > 0 ? 1 : 0) * BUTTONS_EVENT_STYLUS;
}
break;
case BTN_STYLUS2:
{
++eventsInMessage;
common->currentValues.button |=
(event->value > 0 ? 1 : 0) * BUTTONS_EVENT_STYLUS2;
}
break;
case BTN_LEFT:
{
++eventsInMessage;
common->currentValues.button |=
(event->value > 0 ? 1 : 0) * BUTTONS_EVENT_MOUSE_LEFT;
}
break;
case BTN_MIDDLE:
{
++eventsInMessage;
common->currentValues.button |=
(event->value > 0 ? 1 : 0) * BUTTONS_EVENT_MOUSE_MIDDLE;
}
break;
case BTN_RIGHT:
{
++eventsInMessage;
common->currentValues.button |=
(event->value > 0 ? 1 : 0) * BUTTONS_EVENT_MOUSE_RIGHT;
}
break;
case BTN_SIDE:
{
++eventsInMessage;
common->currentValues.button |=
(event->value > 0 ? 1 : 0) * BUTTONS_EVENT_SIDE_BTN;
}
break;
case BTN_EXTRA:
{
++eventsInMessage;
common->currentValues.button |=
(event->value > 0 ? 1 : 0) * BUTTONS_EVENT_EXTRA_BTN;
}
break;
default:
{
++eventsInMessage;
common->currentValues.macroKey = event->value;
}
break;
}
}
break;
}
#ifndef EV_SYN
if (event->type != EV_MSC)
#else
if (event->type != EV_MSC && event->type != EV_SYN)
#endif
{
continue;
}
if (eventsInMessage == 0)
{
continue;
}
eventsInMessage = 0;
if ((device->xThreshold > 1 &&
ABS(common->currentValues.x - common->previousValues.x)
<= device->xThreshold) ||
(device->yThreshold > 1 &&
ABS(common->currentValues.y - common->previousValues.y)
<= device->yThreshold) ||
(device->zThreshold > 1 &&
ABS(common->currentValues.z - common->previousValues.z)
<= device->zThreshold) ||
(device->xTiltThreshold > 1 &&
ABS(common->currentValues.xTilt - common->previousValues.xTilt)
<= device->xTiltThreshold) ||
(device->yTiltThreshold > 1 &&
ABS(common->currentValues.yTilt - common->previousValues.yTilt)
<= device->yTiltThreshold))
{
DBG(10, ErrorF("Event Filtered Out by Thresholds\n"));
continue;
}
if ((common->currentValues.x == common->previousValues.x) &&
(common->currentValues.y == common->previousValues.y) &&
(common->currentValues.z == common->previousValues.z) &&
(common->currentValues.proximity ==
common->previousValues.proximity) &&
(common->currentValues.button ==
common->previousValues.button) &&
(common->currentValues.macroKey ==
common->previousValues.macroKey))
{
DBG(10, ErrorF("Event Filtered Out\n"));
continue;
}
d_z = (double)common->currentValues.z;
d_zCapacity = (double)common->zCapacity;
switch (device->zMode)
{
case VALUE_NA:
case PRESSURE_MODE_LINEAR:
{
}
break;
case PRESSURE_MODE_SOFT_SMOOTH:
{
d_z = (d_z * d_z / d_zCapacity)+ 0.5;
}
break;
case PRESSURE_MODE_HARD_SMOOTH:
{
d_z = (d_zCapacity * sqrt( d_z / d_zCapacity)) + 0.5;
}
break;
}
for (i=0; i < common->numDevices; ++i)
{
AiptekDevicePtr dev = common->deviceArray[i]->private;
int id;
id = DEVICE_ID (dev->flags);
if (id == common->currentValues.eventType)
{
xf86AiptekSendEvents(common->deviceArray[i], (int) d_z);
}
}
common->previousValues.eventType = common->currentValues.eventType;
common->previousValues.x = common->currentValues.x;
common->previousValues.y = common->currentValues.y;
common->previousValues.z = common->currentValues.z;
common->previousValues.proximity = common->currentValues.proximity;
common->previousValues.button = common->currentValues.button;
common->previousValues.macroKey = common->currentValues.macroKey;
common->previousValues.xTilt = common->currentValues.xTilt;
common->previousValues.yTilt = common->currentValues.yTilt;
common->previousValues.distance = common->currentValues.distance;
common->previousValues.wheel = common->currentValues.wheel;
common->currentValues.macroKey = VALUE_NA;
}
}
static Bool
xf86AiptekHIDOpen(LocalDevicePtr local)
{
AiptekDevicePtr device = (AiptekDevicePtr)local->private;
AiptekCommonPtr common = device->common;
char name[256] = "Unknown";
int abs[5];
unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
int i, j;
int err = 0;
int version;
local->fd = xf86OpenSerial(local->options);
if (local->fd == -1)
{
ErrorF("xf86AiptekHIDOpen Error opening %s : %s\n", common->deviceName, strerror(errno));
return !Success;
}
ioctl(local->fd, EVIOCGNAME(sizeof(name)), name);
ErrorF("%s HID Device name: \"%s\"\n", XCONFIG_PROBED, name);
ioctl(local->fd, EVIOCGVERSION, &version);
ErrorF("%s HID Driver Version: %d.%d.%d\n", XCONFIG_PROBED,
version>>16, (version>>8) & 0xff, version & 0xff);
ErrorF("%s HID Driver knows it has %d devices configured\n", XCONFIG_PROBED,
common->numDevices);
ErrorF("%s HID Driver is using %d as the fd\n", XCONFIG_PROBED, local->fd);
for (i = 0; i < common->numDevices; ++i)
{
common->deviceArray[i]->read_input = xf86AiptekHIDReadInput;
common->deviceArray[i]->fd = local->fd;
common->deviceArray[i]->flags |= XI86_POINTER_CAPABLE | XI86_CONFIGURED;
}
common->open = xf86AiptekHIDOpen;
memset(bit, 0, sizeof(bit));
ioctl(local->fd, EVIOCGBIT(0, EV_MAX), bit[0]);
for (i = 0; i < EV_MAX; ++i)
{
if (TEST_BIT(i, bit[0]))
{
ioctl(local->fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
for (j = 0; j < KEY_MAX; ++j)
{
if (TEST_BIT(j, bit[i]))
{
if (i == EV_ABS)
{
ioctl(local->fd, EVIOCGABS(j), abs);
switch (j)
{
case ABS_X:
{
ErrorF("From ioctl() xCapacity=%d\n", abs[2]);
common->xCapacity = abs[2];
}
break;
case ABS_Y:
{
ErrorF("From ioctl() yCapacity=%d\n", abs[2]);
common->yCapacity = abs[2];
}
break;
case ABS_Z:
{
ErrorF("From ioctl() zCapacity=%d\n", abs[2]);
common->zCapacity = abs[2];
}
break;
}
}
}
}
}
}
if (err < 0)
{
ErrorF("xf86AiptekHIDOpen ERROR: %d\n", err);
SYSCALL(close(local->fd));
return !Success;
}
return Success;
}
static void
xf86AiptekControlProc(DeviceIntPtr device, PtrCtrl *ctrl)
{
DBG(2, ErrorF("xf86AiptekControlProc\n"));
}
static Bool
xf86AiptekOpen(LocalDevicePtr local)
{
AiptekDevicePtr device = (AiptekDevicePtr)local->private;
AiptekCommonPtr common = device->common;
int err, version;
DBG(1, ErrorF("Opening %s\n", common->deviceName));
local->fd = xf86OpenSerial(local->options);
if (local->fd < 0)
{
ErrorF("Error opening %s: %s\n", common->deviceName, strerror(errno));
return !Success;
}
DBG(1, ErrorF("Testing USB\n"));
SYSCALL(err = ioctl(local->fd, EVIOCGVERSION, &version));
if (!err)
{
int j;
SYSCALL(close(local->fd));
for(j=0; j<common->numDevices; ++j)
{
common->deviceArray[j]->read_input=xf86AiptekHIDReadInput;
}
common->open=xf86AiptekHIDOpen;
return xf86AiptekHIDOpen(local);
}
return !Success;
}
static int
xf86AiptekOpenDevice(DeviceIntPtr pDriver)
{
LocalDevicePtr local = (LocalDevicePtr)pDriver->public.devicePrivate;
AiptekDevicePtr device = (AiptekDevicePtr)PRIVATE(pDriver);
AiptekCommonPtr common = device->common;
double tabletRatio, screenRatio;
double xFactor, yFactor;
int gap, loop;
DBG(2, ErrorF("In xf86AiptekOpenDevice, with fd=%d\n", local->fd));
if (local->fd < 0)
{
if (common->initNumber > 2 ||
device->initNumber == common->initNumber)
{
if (common->open(local) != Success)
{
if (local->fd >= 0)
{
SYSCALL(close(local->fd));
}
local->fd = -1;
return !Success;
}
else
{
for (loop=0; loop < common->numDevices; ++loop)
{
common->deviceArray[loop]->fd = local->fd;
}
}
common->initNumber++;
}
device->initNumber = common->initNumber;
}
if (device->xMax != VALUE_NA ||
device->yMax != VALUE_NA)
{
if (device->xMax > common->xCapacity ||
device->xMax == VALUE_NA)
{
device->xMax = common->xCapacity;
xf86Msg(X_CONFIG, "xMax value invalid; adjusting to %d\n",
device->xMax);
}
if (device->yMax > common->yCapacity ||
device->yMax == VALUE_NA)
{
device->yMax = common->yCapacity;
xf86Msg(X_CONFIG,"yMax value invalid; adjusting to %d\n",
device->yMax);
}
device->xTop = 0;
device->yTop = 0;
device->xBottom = device->xMax;
device->yBottom = device->yMax;
}
if (device->xSize != VALUE_NA ||
device->ySize != VALUE_NA ||
device->xOffset != VALUE_NA ||
device->yOffset != VALUE_NA)
{
int message = 0;
if (device->xOffset != VALUE_NA &&
(device->xOffset > common->xCapacity ||
device->xOffset < 0))
{
message = 1;
device->xOffset = 0;
}
if (device->yOffset != VALUE_NA &&
(device->yOffset > common->yCapacity ||
device->yOffset < 0))
{
message = 1;
device->yOffset = 0;
}
if (device->xSize != VALUE_NA &&
(device->xSize > common->xCapacity ||
device->xSize < 0))
{
message = 1;
device->xSize = common->xCapacity;
}
if (device->ySize != VALUE_NA &&
(device->ySize > common->yCapacity ||
device->ySize < 0))
{
message = 1;
device->ySize = common->yCapacity;
}
if (device->xOffset == VALUE_NA ||
device->xSize == VALUE_NA)
{
if (device->xOffset == VALUE_NA)
{
message = 1;
device->xOffset = 0;
}
else
{
message = 1;
device->xSize = common->xCapacity - device->xOffset;
}
}
if (device->yOffset == VALUE_NA ||
device->ySize == VALUE_NA)
{
if (device->yOffset == VALUE_NA)
{
message = 1;
device->yOffset = 0;
}
else
{
message = 1;
device->ySize = common->yCapacity - device->yOffset;
}
}
if (device->xOffset + device->xSize > common->xCapacity)
{
message = 1;
device->xSize = common->xCapacity - device->xOffset;
}
if (device->yOffset + device->ySize > common->yCapacity)
{
message = 1;
device->ySize = common->yCapacity - device->yOffset;
}
if (message == 1)
{
xf86Msg(X_CONFIG,"xOffset/yOffset;xSize/ySize values wrong.\n");
xf86Msg(X_CONFIG,"xOffset adjusted to %d\n", device->xOffset);
xf86Msg(X_CONFIG,"yOffset adjusted to %d\n", device->yOffset);
xf86Msg(X_CONFIG,"xSize adjusted to %d\n", device->xSize);
xf86Msg(X_CONFIG,"ySize adjusted to %d\n", device->ySize);
}
device->xTop = device->xOffset;
device->yTop = device->yOffset;
device->xBottom = device->xOffset + device->xSize;
device->yBottom = device->yOffset + device->ySize;
}
if (device->xTop == VALUE_NA ||
device->xTop < 0 ||
device->xTop > common->xCapacity)
{
device->xTop = 0;
xf86Msg(X_CONFIG,"xTop invalid; adjusted to %d\n", device->xTop);
}
if (device->yTop == VALUE_NA ||
device->yTop < 0 ||
device->yTop > common->yCapacity)
{
device->yTop = 0;
xf86Msg(X_CONFIG,"yTop invalid; adjusted to %d\n", device->yTop);
}
if (device->xBottom == VALUE_NA ||
device->xBottom < 0 ||
device->xBottom > common->xCapacity)
{
device->xBottom = common->xCapacity;
xf86Msg(X_CONFIG,"xBottom invalid; adjusted to %d\n",
device->xBottom);
}
if (device->yBottom == VALUE_NA ||
device->yBottom < 0 ||
device->yBottom > common->yCapacity)
{
device->yBottom = common->yCapacity;
xf86Msg(X_CONFIG,"yBottom invalid; adjusted to %d\n",
device->yBottom);
}
if ( device->screenNo >= screenInfo.numScreens ||
device->screenNo == VALUE_NA ||
device->screenNo < 0)
{
device->screenNo = 0;
xf86Msg(X_CONFIG,"ScreenNo invalid; adjusted to %d\n",
device->screenNo);
}
if (device->flags & KEEP_SHAPE_FLAG)
{
int xDiff, yDiff;
xDiff = common->xCapacity - device->xTop;
yDiff = common->yCapacity - device->yTop;
tabletRatio = (double) xDiff / (double) yDiff;
screenRatio = (double) screenInfo.screens[device->screenNo]->width /
(double) screenInfo.screens[device->screenNo]->height;
DBG(2, ErrorF("Screen %d: screenRatio = %.3g, tabletRatio = %.3g\n",
device->screenNo, screenRatio, tabletRatio));
if (screenRatio > tabletRatio)
{
gap = (int)((double)common->yCapacity *
(1.0 - tabletRatio/screenRatio));
device->xBottom = common->xCapacity;
device->yBottom = common->yCapacity - gap;
DBG(2, ErrorF("Screen %d: 'Y' Gap of %d computed\n",
device->screenNo, gap));
}
else
{
gap = (int)((double)common->xCapacity *
(1.0 - screenRatio/tabletRatio));
device->xBottom = common->xCapacity - gap;
device->yBottom = common->yCapacity;
DBG(2, ErrorF("Screen %d: 'X' Gap of %d computed\n",
device->screenNo, gap));
}
}
xFactor = (double)screenInfo.screens[device->screenNo]->width/
(double)(device->xBottom - device->xTop);
yFactor = (double)screenInfo.screens[device->screenNo]->height/
(double)(device->yBottom - device->yTop);
if (device->xThreshold > common->xCapacity ||
device->xThreshold == VALUE_NA ||
device->xThreshold < 0)
{
device->xThreshold = 0;
}
if (device->yThreshold > common->yCapacity ||
device->yThreshold == VALUE_NA ||
device->yThreshold < 0)
{
device->yThreshold = 0;
}
if (device->zThreshold > common->zCapacity ||
device->zThreshold == VALUE_NA ||
device->zThreshold < 0)
{
device->zThreshold = 0;
}
InitValuatorAxisStruct(pDriver,
0,
0,
device->xBottom - device->xTop,
LPI2CPM(375),
LPI2CPM(375),
LPI2CPM(375));
InitValuatorAxisStruct(pDriver,
1,
0,
device->yBottom - device->yTop,
LPI2CPM(375),
LPI2CPM(375),
LPI2CPM(375));
InitValuatorAxisStruct(pDriver,
2,
0,
511,
512,
512,
512);
InitValuatorAxisStruct(pDriver,
3,
-128,
127,
256,
256,
256);
InitValuatorAxisStruct(pDriver,
4,
-128,
127,
256,
256,
256);
return (local->fd != -1);
}
static int
xf86AiptekProc(DeviceIntPtr pAiptek, int requestCode)
{
CARD8 map[512+1];
int numAxes;
int numButtons;
int loop;
LocalDevicePtr local = (LocalDevicePtr)pAiptek->public.devicePrivate;
AiptekDevicePtr device = (AiptekDevicePtr)PRIVATE(pAiptek);
DBG(2, ErrorF("xf86AiptekProc() type=%s flags=%d request=%d\n",
(DEVICE_ID(device->flags) == STYLUS_ID) ? "stylus" :
(DEVICE_ID(device->flags) == CURSOR_ID) ? "cursor" : "eraser",
device->flags, requestCode));
switch (requestCode)
{
case DEVICE_INIT:
{
DBG(1, ErrorF("xf86AiptekProc request=INIT\n"));
numAxes = 5;
numButtons = 5;
for(loop=1; loop<=numButtons; ++loop)
{
map[loop] = loop;
}
if (InitButtonClassDeviceStruct(pAiptek,numButtons,map) == FALSE)
{
ErrorF("Unable to init Button Class Device\n");
return !Success;
}
if (InitFocusClassDeviceStruct(pAiptek) == FALSE)
{
ErrorF("Unable to init Focus Class Device\n");
return !Success;
}
if (InitPtrFeedbackClassDeviceStruct(pAiptek,
xf86AiptekControlProc) == FALSE)
{
ErrorF("Unable to init Pointer Feedback Class Device\n");
return !Success;
}
if (InitProximityClassDeviceStruct(pAiptek) == FALSE)
{
ErrorF("Unable to init Proximity Class Device\n");
return !Success;
}
if (InitKeyClassDeviceStruct(pAiptek, &keysyms, NULL) ==FALSE)
{
ErrorF("Unable to init Key Class Device\n");
return !Success;
}
if (InitValuatorClassDeviceStruct(pAiptek,
numAxes,
xf86GetMotionEvents,
local->history_size,
((device->flags & ABSOLUTE_FLAG)
? Absolute : Relative) | OutOfProximity ) == FALSE)
{
ErrorF("Unable to allocate Valuator Class Device\n");
return !Success;
}
xf86MotionHistoryAllocate(local);
xf86AiptekOpenDevice(pAiptek);
}
break;
case DEVICE_ON:
{
DBG(1, ErrorF("xf86AiptekProc request=ON\n"));
if ((local->fd < 0) &&
(!xf86AiptekOpenDevice(pAiptek)))
{
ErrorF("Unable to open aiptek device\n");
return !Success;
}
ErrorF("Able to open aiptek device\n");
xf86AddEnabledDevice(local);
pAiptek->public.on = TRUE;
}
break;
case DEVICE_OFF:
{
DBG(1, ErrorF("xf86AiptekProc request=%s\n",
(requestCode == DEVICE_CLOSE) ? "CLOSE" : "OFF"));
if (local->fd >= 0)
{
xf86AiptekClose(local);
xf86RemoveEnabledDevice(local);
}
pAiptek->public.on = FALSE;
}
break;
case DEVICE_CLOSE:
{
DBG(1, ErrorF("xf86AiptekProc request=%s\n",
(requestCode == DEVICE_CLOSE) ? "CLOSE" : "OFF"));
xf86AiptekClose(local);
}
break;
default:
{
ErrorF("xf86AiptekProc - Unsupported mode=%d\n", requestCode);
return !Success;
}
break;
}
DBG(2, ErrorF("xf86AiptekProc Success request=%d\n", requestCode ));
return Success;
}
static void
xf86AiptekClose(LocalDevicePtr local)
{
if (local->fd >= 0)
{
SYSCALL(close(local->fd));
}
local->fd = -1;
}
static int
xf86AiptekChangeControl(LocalDevicePtr local, xDeviceCtl *control)
{
xDeviceResolutionCtl *res;
int *resolutions;
DBG(3, ErrorF("xf86AiptekChangeControl() entered\n"));
res = (xDeviceResolutionCtl *)control;
if ((control->control != DEVICE_RESOLUTION) ||
(res->num_valuators < 1))
{
DBG(3, ErrorF("xf86AiptekChangeControl abends\n"));
return (BadMatch);
}
resolutions = (int *)(res +1);
DBG(3, ErrorF("xf86AiptekChangeControl changing to res %d\n",
resolutions[0]));
return(Success);
}
static int
xf86AiptekSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode)
{
LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
AiptekDevicePtr device = (AiptekDevicePtr)(local->private);
DBG(3, ErrorF("xf86AiptekSwitchMode() dev=%p mode=%d\n", dev, mode));
switch(mode)
{
case Absolute:
{
device->flags |= ABSOLUTE_FLAG;
}
break;
case Relative:
{
device->flags &= ~ABSOLUTE_FLAG;
}
break;
default:
{
DBG(1, ErrorF("xf86AiptekSwitchMode dev=%p invalid mode=%d\n",
dev, mode));
return BadMatch;
}
break;
}
return Success;
}
static LocalDevicePtr
xf86AiptekAllocate(char* name,
int flag)
{
LocalDevicePtr local;
LocalDevicePtr* deviceArray;
AiptekDevicePtr device;
AiptekCommonPtr common;
DBG(3, ErrorF("xf86AiptekAllocate, with %s and %d\n", name, flag));
device = (AiptekDevicePtr) xalloc(sizeof(AiptekDeviceRec));
if (!device)
{
DBG(3, ErrorF("xf86AiptekAllocate failed to allocate 'device'\n"));
return NULL;
}
common = (AiptekCommonPtr) xalloc(sizeof(AiptekCommonRec));
if (!common)
{
DBG(3, ErrorF("xf86AiptekAllocate failed to allocate 'common'\n"));
xfree(device);
return NULL;
}
deviceArray = (LocalDevicePtr*) xalloc(sizeof(LocalDevicePtr));
if (!deviceArray)
{
DBG(3, ErrorF("xf86AiptekAllocate failed to allocate 'deviceArray'\n"));
xfree(device);
xfree(common);
return NULL;
}
local = xf86AllocateInput(aiptekDrv, 0);
if (!local)
{
DBG(3, ErrorF("xf86AiptekAllocate failed at xf86AllocateInput()\n"));
xfree(device);
xfree(common);
xfree(deviceArray);
return NULL;
}
local->name = name;
local->type_name = "Aiptek";
local->flags = 0;
local->device_control = xf86AiptekProc;
local->read_input = xf86AiptekHIDReadInput;
local->control_proc = xf86AiptekChangeControl;
local->close_proc = xf86AiptekClose;
local->switch_mode = xf86AiptekSwitchMode;
local->conversion_proc = xf86AiptekConvert;
local->reverse_conversion_proc = xf86AiptekReverseConvert;
local->fd = VALUE_NA;
local->atom = 0;
local->dev = NULL;
local->private = device;
local->private_flags = 0;
local->history_size = 0;
device->flags = flag;
device->xSize = VALUE_NA;
device->ySize = VALUE_NA;
device->xOffset = VALUE_NA;
device->yOffset = VALUE_NA;
device->xMax = VALUE_NA;
device->yMax = VALUE_NA;
device->zMin = VALUE_NA;
device->zMax = VALUE_NA;
device->xTop = VALUE_NA;
device->yTop = VALUE_NA;
device->xBottom = VALUE_NA;
device->yBottom = VALUE_NA;
device->xThreshold = VALUE_NA;
device->yThreshold = VALUE_NA;
device->zThreshold = VALUE_NA;
device->xTiltThreshold =VALUE_NA;
device->yTiltThreshold =VALUE_NA;
device->zMode = VALUE_NA;
device->initNumber = VALUE_NA;
device->screenNo = VALUE_NA;
device->common = common;
common->currentValues.eventType = 0;
common->currentValues.x = 0;
common->currentValues.y = 0;
common->currentValues.z = 0;
common->currentValues.xTilt = 0;
common->currentValues.yTilt = 0;
common->currentValues.proximity = 0;
common->currentValues.macroKey = VALUE_NA;
common->currentValues.button = 0;
common->currentValues.distance = 0;
common->currentValues.wheel = 0;
common->previousValues.eventType = 0;
common->previousValues.x = 0;
common->previousValues.y = 0;
common->previousValues.z = 0;
common->previousValues.xTilt = 0;
common->previousValues.yTilt = 0;
common->previousValues.proximity = 0;
common->previousValues.macroKey = VALUE_NA;
common->previousValues.button = 0;
common->previousValues.distance = 0;
common->previousValues.wheel = 0;
common->deviceName = "";
common->flags = 0;
common->deviceArray = deviceArray;
common->deviceArray[0]= local;
common->numDevices = 1;
common->xCapacity = 0;
common->yCapacity = 0;
common->zCapacity = 0;
common->open = xf86AiptekOpen;
return local;
}
static LocalDevicePtr
xf86AiptekAllocateStylus(void)
{
LocalDevicePtr local = xf86AiptekAllocate(XI_STYLUS, STYLUS_ID);
if (local)
{
local->type_name = "Stylus";
}
return local;
}
static LocalDevicePtr
xf86AiptekAllocateCursor(void)
{
LocalDevicePtr local = xf86AiptekAllocate(XI_CURSOR, CURSOR_ID);
if (local)
{
local->type_name = "Cursor";
}
return local;
}
static LocalDevicePtr
xf86AiptekAllocateEraser(void)
{
LocalDevicePtr local = xf86AiptekAllocate(XI_ERASER,
ABSOLUTE_FLAG|ERASER_ID);
if (local)
{
local->type_name = "Eraser";
}
return local;
}
DeviceAssocRec aiptek_stylus_assoc =
{
STYLUS_SECTION_NAME,
xf86AiptekAllocateStylus
};
DeviceAssocRec aiptek_cursor_assoc =
{
CURSOR_SECTION_NAME,
xf86AiptekAllocateCursor
};
DeviceAssocRec aiptek_eraser_assoc =
{
ERASER_SECTION_NAME,
xf86AiptekAllocateEraser
};
static void
xf86AiptekUninit(InputDriverPtr drv,
LocalDevicePtr local,
int flags)
{
AiptekDevicePtr device = (AiptekDevicePtr) local->private;
DBG(1, ErrorF("xf86AiptekUninit\n"));
xf86AiptekProc(local->dev, DEVICE_OFF);
if (device->common && device->common->xCapacity != -10101)
{
device->common->xCapacity = -10101;
xfree(device->common);
}
xfree (device);
xf86DeleteInput(local, 0);
}
static InputInfoPtr
xf86AiptekInit(InputDriverPtr drv,
IDevPtr dev,
int flags)
{
LocalDevicePtr local = NULL;
LocalDevicePtr fakeLocal = NULL;
AiptekDevicePtr device = NULL;
AiptekCommonPtr common = NULL;
LocalDevicePtr locals;
char* s;
int shared;
aiptekDrv = drv;
xf86Msg(X_INFO, "xf86AiptekInit(): begins\n");
fakeLocal = (LocalDevicePtr) xcalloc(1, sizeof(LocalDeviceRec));
if (!fakeLocal)
{
return NULL;
}
fakeLocal->conf_idev = dev;
xf86CollectInputOptions(fakeLocal, default_options, NULL);
s = xf86FindOptionValue(fakeLocal->options, "Type");
if (s && (xf86NameCmp(s, "stylus") == 0))
{
local = xf86AiptekAllocateStylus();
}
else if (s && (xf86NameCmp(s, "cursor") == 0))
{
local = xf86AiptekAllocateCursor();
}
else if (s && (xf86NameCmp(s, "eraser") == 0))
{
local = xf86AiptekAllocateEraser();
}
else
{
xf86Msg(X_ERROR, "%s: No type or invalid type specified.\n"
"Must be one of 'stylus', 'cursor', or 'eraser'\n",
dev->identifier);
}
if(!local)
{
xfree(fakeLocal);
return NULL;
}
device = (AiptekDevicePtr) local->private;
common = device->common;
local->options = fakeLocal->options;
local->conf_idev = fakeLocal->conf_idev;
local->name = dev->identifier;
xfree(fakeLocal);
common->deviceName = xf86FindOptionValue(local->options, "Device");
if(!common->deviceName)
{
xf86Msg(X_ERROR, "%s: No Device specified.\n", dev->identifier);
goto SetupProc_fail;
}
shared = 0;
for (locals = xf86FirstLocalDevice();
locals != NULL;
locals = locals->next)
{
if((local != locals) &&
(locals->device_control == xf86AiptekProc) &&
(strcmp(((AiptekDevicePtr)locals->private)->common->deviceName,
common->deviceName) == 0))
{
xf86Msg(X_CONFIG,
"xf86AiptekConfig: device shared between %s and %s\n",
local->name,
locals->name);
shared = 1;
xfree(common->deviceArray);
xfree(common);
common = device->common =
((AiptekDevicePtr) locals->private)->common;
common->numDevices++;
common->deviceArray = (LocalDevicePtr*)xrealloc(common->deviceArray,
sizeof(LocalDevicePtr)*common->numDevices);
common->deviceArray[common->numDevices-1] = local;
break;
}
else
{
xf86Msg(X_CONFIG,
"xf86AiptekConfig: device not shared btw %s and %s\n",
local->name, locals->name);
}
}
xf86ProcessCommonOptions(local, local->options);
if ( shared == 0)
{
xf86AiptekHIDOpen(local);
close(local->fd);
local->fd=-1;
}
xf86Msg(X_CONFIG, "%s device is %s\n", dev->identifier,
common->deviceName);
debug_level = xf86SetIntOption(local->options, "DebugLevel", debug_level);
if ( debug_level > 0)
{
xf86Msg(X_CONFIG, "Debug level set to %d\n", debug_level);
}
s = xf86FindOptionValue(local->options, "Pressure");
if ( s && (xf86NameCmp(s, "hard") == 0))
{
device->zMode = PRESSURE_MODE_HARD_SMOOTH;
}
else if ( s && (xf86NameCmp(s, "soft") == 0))
{
device->zMode = PRESSURE_MODE_SOFT_SMOOTH;
}
else if (s && (xf86NameCmp(s, "normal") == 0))
{
device->zMode = PRESSURE_MODE_LINEAR;
}
else if (s)
{
xf86Msg(X_ERROR, "%s: invalid Mode ('normal', 'soft' or 'hard').\n",
dev->identifier);
}
s = xf86FindOptionValue(local->options, "Mode");
if (s && (xf86NameCmp(s, "absolute") == 0))
{
device->flags |= ABSOLUTE_FLAG;
}
else if (s && (xf86NameCmp(s, "relative") == 0))
{
device->flags &= ~ABSOLUTE_FLAG;
}
else if (s)
{
xf86Msg(X_ERROR, "%s: invalid Mode ('absolute' or 'relative').\n",
dev->identifier);
device->flags |= ABSOLUTE_FLAG;
}
xf86Msg(X_CONFIG, "%s is in %s mode\n", local->name,
(device->flags & ABSOLUTE_FLAG) ? "absolute" : "relative");
#ifdef LINUX_INPUT
if (xf86SetBoolOption(local->options, "USB",
(common->open == xf86AiptekHIDOpen)))
{
local->read_input=xf86AiptekHIDReadInput;
common->open=xf86AiptekHIDOpen;
xf86Msg(X_CONFIG, "%s: reading USB link\n", dev->identifier);
}
#else
if (xf86SetBoolOption(local->options, "USB", 0))
{
ErrorF("The Aiptek USB driver isn't available for your platform.\n");
goto SetupProc_fail;
}
#endif
device->screenNo = xf86SetIntOption(local->options, "ScreenNo", VALUE_NA);
if (device->screenNo != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: attached to screen number %d\n",
dev->identifier, device->screenNo);
}
if (xf86SetBoolOption(local->options, "KeepShape", 0))
{
device->flags |= KEEP_SHAPE_FLAG;
xf86Msg(X_CONFIG, "%s: keeps shape\n", dev->identifier);
}
device->xSize = xf86SetIntOption(local->options, "XSize", device->xSize);
device->xSize = xf86SetIntOption(local->options, "SizeX", device->xSize);
if (device->xSize != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: XSize/SizeX = %d\n", dev->identifier,
device->xSize);
}
device->ySize = xf86SetIntOption(local->options, "YSize", device->ySize);
device->ySize = xf86SetIntOption(local->options, "SizeY", device->ySize);
if (device->ySize != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: YSize/SizeY = %d\n", dev->identifier,
device->ySize);
}
device->xOffset = xf86SetIntOption(local->options, "XOffset",
device->xOffset);
device->xOffset = xf86SetIntOption(local->options, "OffsetX",
device->xOffset);
if (device->xOffset != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: XOffset/OffsetX = %d\n", dev->identifier,
device->xOffset);
}
device->yOffset = xf86SetIntOption(local->options, "YOffset",
device->yOffset);
device->yOffset = xf86SetIntOption(local->options, "OffsetY",
device->yOffset);
if (device->yOffset != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: YOffset/OffsetY = %d\n", dev->identifier,
device->yOffset);
}
device->xThreshold = xf86SetIntOption(local->options, "XThreshold",
device->xThreshold);
device->xThreshold = xf86SetIntOption(local->options, "ThresholdX",
device->xThreshold);
if (device->xThreshold != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: XThreshold/ThresholdX = %d\n",
dev->identifier, device->xThreshold);
}
device->yThreshold = xf86SetIntOption(local->options, "YThreshold",
device->yThreshold);
device->yThreshold = xf86SetIntOption(local->options, "ThresholdY",
device->yThreshold);
if (device->yThreshold != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: YThreshold/ThresholdY = %d\n",
dev->identifier, device->yThreshold);
}
device->zThreshold = xf86SetIntOption(local->options, "ZThreshold",
device->zThreshold);
device->zThreshold = xf86SetIntOption(local->options, "ThresholdZ",
device->zThreshold);
if (device->zThreshold != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: ZThreshold/ThresholdZ = %d\n",
dev->identifier, device->zThreshold);
}
device->xTiltThreshold = xf86SetIntOption(local->options, "XTiltThreshold",
device->xTiltThreshold);
device->xTiltThreshold = xf86SetIntOption(local->options, "ThresholdXTilt",
device->xTiltThreshold);
if (device->xTiltThreshold != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: XTiltThreshold = %d\n",
dev->identifier, device->xTiltThreshold);
}
device->yTiltThreshold = xf86SetIntOption(local->options, "YTiltThreshold",
device->yTiltThreshold);
device->yTiltThreshold = xf86SetIntOption(local->options, "ThresholdYTilt",
device->yTiltThreshold);
if (device->yTiltThreshold != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: YTiltThreshold = %d\n",
dev->identifier, device->yTiltThreshold);
}
device->xMax = xf86SetIntOption(local->options, "XMax", device->xMax);
device->xMax = xf86SetIntOption(local->options, "MaxX", device->xMax);
if (device->xMax != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: XMax/MaxX = %d\n", dev->identifier,
device->xMax);
}
device->yMax = xf86SetIntOption(local->options, "YMax", device->yMax);
device->yMax = xf86SetIntOption(local->options, "MaxY", device->yMax);
if (device->yMax != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: YMax/MaxY = %d\n", dev->identifier,
device->yMax);
}
device->zMax = xf86SetIntOption(local->options, "ZMax", device->zMax);
device->zMax = xf86SetIntOption(local->options, "MaxZ", device->zMax);
if (device->zMax != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: ZMax/MaxZ = %d\n", dev->identifier,
device->zMax);
}
device->zMin = xf86SetIntOption(local->options, "ZMin", device->zMin);
device->zMin = xf86SetIntOption(local->options, "MinZ", device->zMin);
if (device->zMin != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: ZMin/MinZ = %d\n", dev->identifier,
device->zMin);
}
device->xTop = xf86SetIntOption(local->options, "TopX", device->xTop);
device->xTop = xf86SetIntOption(local->options, "XTop", device->xTop);
if (device->xTop != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: TopX/XTop = %d\n", dev->identifier,
device->xTop);
}
device->yTop = xf86SetIntOption(local->options, "TopY", device->yTop);
device->yTop = xf86SetIntOption(local->options, "YTop", device->yTop);
if (device->yTop != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: TopY/YTop = %d\n", dev->identifier,
device->yTop);
}
device->xBottom = xf86SetIntOption(local->options, "BottomX",
device->xBottom);
device->xBottom = xf86SetIntOption(local->options, "XBottom",
device->xBottom);
if (device->xBottom != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: BottomX/XBottom = %d\n", dev->identifier,
device->xBottom);
}
device->yBottom = xf86SetIntOption(local->options, "BottomY",
device->yBottom);
device->yBottom = xf86SetIntOption(local->options, "YBottom",
device->yBottom);
if (device->yBottom != VALUE_NA)
{
xf86Msg(X_CONFIG, "%s: BottomY/YBottom = %d\n", dev->identifier,
device->yBottom);
}
if (xf86SetBoolOption(local->options, "InvX", FALSE))
{
device->flags |= INVX_FLAG;
xf86Msg(X_CONFIG, "%s: InvX\n", dev->identifier);
}
if (xf86SetBoolOption(local->options, "InvY", FALSE))
{
device->flags |= INVY_FLAG;
xf86Msg(X_CONFIG, "%s: InvY\n", dev->identifier);
}
{
int val;
val = xf86SetIntOption(local->options, "BaudRate", 0);
switch(val)
{
case 19200:
break;
case 9600:
break;
default:
xf86Msg(X_ERROR, "%s: Illegal BaudRate (9600 or 19200).",
dev->identifier);
break;
}
if (xf86Verbose)
{
xf86Msg(X_CONFIG, "%s: BaudRate %u\n", dev->identifier,
val);
}
}
xf86Msg(X_CONFIG, "%s: xf86AiptekInit() finished\n", dev->identifier);
local->flags |= XI86_POINTER_CAPABLE | XI86_CONFIGURED;
return (local);
SetupProc_fail:
if (common)
xfree(common);
if (device)
xfree(device);
if (local)
xfree(local);
return NULL;
}
#ifdef XFree86LOADER
static void
xf86AiptekUnplug(pointer p)
{
DBG(1, ErrorF("xf86AiptekUnplug\n"));
}
static pointer
xf86AiptekPlug(pointer module,
pointer options,
int* errmaj,
int* errmin)
{
DBG(1, ErrorF("xf86AiptekPlug\n"));
xf86AddInputDriver(&AIPTEK, module, 0);
return module;
}
static XF86ModuleVersionInfo xf86AiptekVersionRec =
{
"aiptek",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XF86_VERSION_CURRENT,
1, 0, 0,
ABI_CLASS_XINPUT,
ABI_XINPUT_VERSION,
MOD_CLASS_XINPUT,
{0, 0, 0, 0}
};
XF86ModuleData aiptekModuleData =
{
&xf86AiptekVersionRec,
xf86AiptekPlug,
xf86AiptekUnplug
};
#endif