/* * Copyright 1996 by Steven Lang * * 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 Steven Lang not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. Steven Lang makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * STEVEN LANG DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL STEVEN LANG 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 ACTIONS, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Steve Harris , 2000-02-23 * Southampton, UK * * Based on the xf86Summa driver, exensively hacked. Most of the bad * indenting is not my fault, dammit! * * Probably buggy as hell, no idea what the initialisation strings are, * no idea how to ack it. If the tablet stops responding power cycle it. */ /* $XFree86: xc/programs/Xserver/hw/xfree86/input/digitaledge/DigitalEdge.c,v 1.8 2003/09/24 03:16:58 dawes Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xorgVersion.h" #include #include #include #include "misc.h" #include "xf86.h" #define NEED_XF86_TYPES #if !defined(DGUX) #include "xisb.h" #endif #include "xf86_OSproc.h" #include "xf86Xinput.h" #include "exevents.h" /* Needed for InitValuator/Proximity stuff */ #include #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) /* * Be sure to set vmin appropriately for your device's protocol. You want to * read a full packet before returning */ static const char *default_options[] = { "BaudRate", "9600", "DataBits", "8", "StopBits", "1", "Parity", "Odd", "FlowControl", "Xoff", "VTime", "10", "VMin", "1", NULL }; static InputDriverPtr dedgeDrv; /* ** Debugging macros */ #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 /* ** Device records */ #define ABSOLUTE_FLAG 1 #define STYLUS_FLAG 2 #define COMPATIBLE_FLAG 4 typedef struct { char *dedgeDevice; /* device file name */ int dedgeInc; /* increment between transmits */ int dedgeButTrans; /* button translation flags */ int dedgeOldX; /* previous X position */ int dedgeOldY; /* previous Y position */ int dedgeOldProximity; /* previous proximity */ int dedgeOldPush; /* previous buttons state */ int dedgeOldBarrel; /* previous buttons state */ int dedgeOldPressure; /* previous pen pressure */ int dedgeMaxX; /* max X value */ int dedgeMaxY; /* max Y value */ int dedgeXSize; /* active area X size */ int dedgeXOffset; /* active area X offset */ int dedgeYSize; /* active area Y size */ int dedgeYOffset; /* active area Y offset */ int dedgeRes; /* resolution in lines per inch */ int dedgeClickThresh; /* Click threshold in arbitary units */ int flags; /* various flags */ int dedgeIndex; /* number of bytes read */ unsigned char dedgeData[7]; /* data read on the device */ } DigitalEdgeDeviceRec, *DigitalEdgeDevicePtr; /* ** Configuration data */ #define DEDGE_SECTION_NAME "DigitalEdge" /* ** Contants and macro */ #define BUFFER_SIZE 256 /* size of reception buffer */ #define XI_NAME "DIGITALEDGE" /* X device name for the stylus */ #define SYSCALL(call) while(((call) == -1) && (errno == EINTR)) #define SS_TABID0 "0" /* Tablet ID 0 */ #define SS_FIRMID "z?" /* Request firmware ID string */ #define SS_CONFIG "a" /* Send configuration (max coords) */ #define SS_ABSOLUTE 'F' /* Absolute mode */ #define SS_RELATIVE 'E' /* Relative mode */ #define SS_UPPER_ORIGIN "b" /* Origin upper left */ #define SS_500LPI "h" /* 500 lines per inch */ #define SS_PROMPT_MODE "B" /* Prompt mode */ #define SS_STREAM_MODE "@" /* Stream mode */ #define SS_INCREMENT 'I' /* Set increment */ #define SS_BINARY_FMT "zb" /* Binary reporting */ #define SS_PROMPT "P" /* Prompt for current position */ 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 /* ** External declarations */ /* ** xf86SumConvert ** Convert valuators to X and Y. */ 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; } /* ** xf86SumReverseConvert ** Convert X and Y to valuators. */ 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; } /* ** xf86SumReadInput ** Reads from the DigitalEdge and posts any new events to the server. */ 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++) { /* Format of 5 bytes data packet for DigitalEdge Tablets Byte 1 bit 7 Phasing bit always 1 bit 6 Proximity bit bit 5 Tablet ID bit 4 X sign (Always 1 for absolute) bit 3 Y sign (Always 1 for absolute) bit 2-0 Button status Byte 2 bit 7 Always 0 bits 6-0 = X6 - X0 Byte 3 (Absolute mode only) bit 7 Always 0 bits 6-0 = X13 - X7 Byte 4 bit 7 Always 0 bits 6-0 = Y6 - Y0 Byte 5 (Absolute mode only) bit 7 Always 0 bits 6-0 = Y13 - Y7 */ if ((priv->dedgeIndex == 0) && !(buffer[loop] & PHASING_BIT)) { /* magic bit is not OK */ DBG(6, ErrorF("xf86SumReadInput bad magic number 0x%x\n", buffer[loop]));; continue; } priv->dedgeData[priv->dedgeIndex++] = buffer[loop]; if (priv->dedgeIndex == 7) { /* the packet is OK */ /* reset char count for next read */ 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); /* coordonates are ready we can send events */ 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 { /* !PROXIMITY */ /* Any changes in buttons are ignored when !proximity */ 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)); } /* ** xf86SumControlProc ** It really does do something. Honest! */ static void xf86SumControlProc(DeviceIntPtr device, PtrCtrl * ctrl) { DBG(2, ErrorF("xf86SumControlProc\n")); } #if 0 /* ** xf86SumWriteAndRead ** Write data, and get the response. */ static char *xf86SumWriteAndRead(int fd, char *data, char *buffer, int len, int cr_term) { int err, numread = 0; SYSCALL(err = write(fd, data, strlen(data))); if (err == -1) { Error("DigitalEdge write"); return NULL; } while (numread < len) { err = xf86WaitForInput(fd, 1000); 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 /* ** xf86SumOpen ** Open and initialize the tablet, as well as probe for any needed data. */ static Bool xf86SumOpen(LocalDevicePtr local) { char buffer[256]; int err, idx; DigitalEdgeDevicePtr priv = (DigitalEdgeDevicePtr) local->private; DBG(1, ErrorF("opening %s\n", priv->dedgeDevice)); local->fd = xf86OpenSerial(local->options); if (local->fd == -1) { Error(priv->dedgeDevice); return !Success; } DBG(2, ErrorF("%s opened as fd %d\n", priv->dedgeDevice, local->fd)); DBG(1, ErrorF("initializing DigitalEdge tablet\n")); /* Send reset (NULL) to the tablet */ SYSCALL(err = write(local->fd, "", 1)); if (err == -1) { Error("DigitalEdge write"); return !Success; } /* wait 200 mSecs, just in case */ err = xf86WaitForInput(-1, 200); if (err == -1) { Error("DigitalEdge select"); return !Success; } /* Put it in prompt mode so it doens't say anything before we're ready */ SYSCALL(err = write(local->fd, SS_PROMPT_MODE, strlen(SS_PROMPT_MODE))); if (err == -1) { Error("DigitalEdge write"); return !Success; } /* Clear any pending input */ xf86FlushInput(local->fd); 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) { /* Make a guess as to the best increment value given video mode */ 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); } /* Sets up the tablet mode to increment, stream, and such */ 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) { /* Make up a value */ priv->dedgeClickThresh = 700; } return Success; } /* ** xf86SumOpenDevice ** Opens and initializes the device driver stuff or dedgepthin. */ 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; } /* Set the real values */ InitValuatorAxisStruct(pSum, 0, 0, /* min val */ 2430, /* max val */ 500, /* resolution */ 0, /* min_res */ 500); /* max_res */ InitValuatorAxisStruct(pSum, 1, 0, /* min val */ 1950, /* max val */ 500, /* resolution */ 0, /* min_res */ 500); /* max_res */ InitValuatorAxisStruct(pSum, 2, priv->dedgeClickThresh, /* min val */ 1022, /* max val */ 500, /* resolution */ 0, /* min_res */ 500); /* max_res */ return (local->fd != -1); } /* ** xf86SumProc ** Handle requests to do stuff to the driver. */ 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; /* X, Y, pressure */ 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, #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3 xf86GetMotionEvents, #endif local->history_size, (priv->flags & ABSOLUTE_FLAG) ? Absolute : Relative) == FALSE) { ErrorF("unable to allocate Valuator class device\n"); return !Success; } /* allocate the motion history buffer if needed */ xf86MotionHistoryAllocate(local); /* open the device to gather informations */ 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))); xf86AddEnabledDevice(local); 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) xf86RemoveEnabledDevice(local); 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; } /* ** xf86SumClose ** It... Uh... Closes the physical device? */ static void xf86SumClose(LocalDevicePtr local) { if (local->fd >= 0) { SYSCALL(close(local->fd)); } local->fd = -1; } /* ** xf86SumChangeControl ** When I figure out what it does, it will do it. */ 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); } /* ** xf86SumSwitchMode ** Switches the mode. For now just absolute or relative, hopefully ** more on the way. */ 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; } /* ** xf86SumAllocate ** Allocates the device structures for the DigitalEdge. */ static LocalDevicePtr xf86SumAllocate(void) { LocalDevicePtr local = xf86AllocateInput(dedgeDrv, 0); 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; /*XI86_NO_OPEN_ON_INIT; */ 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 = ""; /* device file name */ #endif priv->dedgeInc = -1; /* re-transmit position on increment */ priv->dedgeOldX = -1; /* previous X position */ priv->dedgeOldY = -1; /* previous Y position */ priv->dedgeOldProximity = 0; /* previous proximity */ priv->dedgeOldPush = 0; /* previous buttons state */ priv->dedgeOldBarrel = 0; /* previous buttons state */ priv->dedgeMaxX = -1; /* max X value */ priv->dedgeMaxY = -1; /* max Y value */ priv->dedgeXSize = -1; /* active area X */ priv->dedgeXOffset = -1; /* active area X offset */ priv->dedgeYSize = -1; /* active area Y */ priv->dedgeYOffset = -1; /* active area U offset */ priv->flags = 0; /* various flags */ priv->dedgeIndex = 0; /* number of bytes read */ return local; } /* * xf86SumUninit -- * * called when the driver is unloaded. */ 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); } /* * xf86SumInit -- * * called when the module subsection is found in XF86Config */ 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; /* Serial Device is mandatory */ priv->dedgeDevice = xf86FindOptionValue(local->options, "Device"); if (!priv->dedgeDevice) { xf86Msg (X_ERROR, "%s: No Device specified.\n", dev->identifier); goto SetupProc_fail; } /* Process the common options. */ xf86ProcessCommonOptions(local, local->options); /* Optional configuration */ 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); } /* mark the device configured */ local->flags |= XI86_POINTER_CAPABLE | XI86_CONFIGURED; /* return the LocalDevice */ return local; SetupProc_fail: if (priv) xfree(priv); return local; } _X_EXPORT InputDriverRec DIGITALEDGE = { 1, /* driver version */ "digitaledge", /* driver name */ NULL, /* identify */ xf86SumInit, /* pre-init */ xf86SumUninit, /* un-init */ NULL, /* module */ 0 /* ref count */ }; /* *************************************************************************** * * Dynamic loading functions * *************************************************************************** */ #ifdef XFree86LOADER /* * xf86SumUnplug -- * * called when the module subsection is found in XF86Config */ static void xf86SumUnplug(pointer p) { } /* * xf86SumPlug -- * * called when the module subsection is found in XF86Config */ static pointer xf86SumPlug(pointer module, pointer options, int *errmaj, int *errmin) { xf86AddInputDriver(&DIGITALEDGE, module, 0); return module; } static XF86ModuleVersionInfo xf86SumVersionRec = { "digitaledge", MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, XORG_VERSION_CURRENT, PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, ABI_CLASS_XINPUT, ABI_XINPUT_VERSION, MOD_CLASS_XINPUT, {0, 0, 0, 0} /* signature, to be patched into the file by */ /* a tool */ }; _X_EXPORT XF86ModuleData digitaledgeModuleData = { &xf86SumVersionRec, xf86SumPlug, xf86SumUnplug }; #endif /* XFree86LOADER */ /* end of xf86DigitalEdge.c */