SOURCES: xf86Aiptek.c (NEW), xf86Aiptek.h (NEW) 6563d4d5fd3490c9da...
qboosh
qboosh at pld-linux.org
Tue Dec 19 10:12:06 CET 2006
Author: qboosh Date: Tue Dec 19 09:12:06 2006 GMT
Module: SOURCES Tag: HEAD
---- Log message:
6563d4d5fd3490c9da3270822d3e7a26 xf86Aiptek.c
23ecd0431c9fac1faf3b80569086bf6c xf86Aiptek.h
- from http://dl.sourceforge.net/aiptektablet/xorg-x11-drv-aiptek-1.0.1-2RvP.src.rpm
---- Files affected:
SOURCES:
xf86Aiptek.c (NONE -> 1.1) (NEW), xf86Aiptek.h (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/xf86Aiptek.c
diff -u /dev/null SOURCES/xf86Aiptek.c:1.1
--- /dev/null Tue Dec 19 10:12:06 2006
+++ SOURCES/xf86Aiptek.c Tue Dec 19 10:12:01 2006
@@ -0,0 +1,4770 @@
+/*
+ * xf86Aiptek
+ *
+ * This driver assumes Linux Input Device support, available for USB devices.
+ *
+ * Copyright 2003 by Bryan W. Headley. <bwheadley at earthlink.net>
+ *
+ * Lineage: This driver is based on both the xf86HyperPen and xf86Wacom tablet
+ * drivers.
+ *
+ * xf86HyperPen -- modified from xf86Summa (c) 1996 Steven Lang
+ * (c) 2000 Roland Jansen
+ * (c) 2000 Christian Herzog (button & 19200 baud support)
+ *
+ * xf86Wacom -- (c) 1995-2001 Frederic Lepied
+ *
+ *
+ * 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 Bryan W. Headley not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Bryan W. Headley makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * BRYAN W. HEADLEY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL BRYAN W. HEADLEY 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.
+ *
+ * Version 0.0, 1-Jan-2003, Bryan W. Headley
+ * - Initial release.
+ *
+ * Version 1.0, 21-Aug-2003 - 20-Sep-2003, Bryan W. Headley
+ * o Implement support for the Wheel device
+ * o Implement driver parameter dynamic reconfiguration mechanism,
+ * allowing a client application to both query and program the
+ * driver. The communication layer uses the XInput PtrFeedbackControl
+ * mechanism.
+ * o Bug fixes from Adrzej Szombierksi <qq at kuku.eu.org> and
+ * martin.schneebacher <masc at theaterzentrum.at>.
+ * o Way too many issues with definition of TRUE|FALSE, versus
+ * Success|BadMatch. Cannot rely on 'if (so)' syntax to work;
+ * basically refactored all if statements as a matter of policy.
+ * Also got rid of 'implied bools' by comparing bitmasks != 0.
+ * Bryan W. Headley, Jan-3-2004.
+ *
+ * Version 1.1, 16-Feb-2004, Bryan W. Headley
+ * o Added stub routines for hotplug
+ * o Deal with logical and physical device paths.
+ *
+ * Version 1.2, 6-June-2004, Bryan W. Headley
+ * o Get rid of some kruft. Some dangling pointers repaired, if statements
+ * fixed, and AiptekIsValidDevice logic fixed.
+ */
+
+/* $Header$ */
+
+/*
+ *
+ * Section "InputDevice"
+ * Identifier "stylus" # a name of your choosing
+ * Driver "aiptek"
+ * Option "Type" "string" # {stylus|cursor|eraser}
+ * Option "Device" "pathname" # {/dev/input/event0}
+ * Option "Mode" "string" # {absolute|relative}
+ * Option "Cursor" "string" # {stylus|puck}
+ * Option "USB" "bool" # {on|off}
+ * Option "ScreenNo" "int"
+ * Option "KeepShape" "bool" # {on|off}
+ * Option "AlwaysCore" "bool" # {on|off}
+ * Option "DebugLevel" "int"
+ * Option "HistorySize" "int"
+ *
+ * # This defines whether we are doing smoothing on pressure inputs.
+ * # 'linear' infers no smoothing; there is also a soft and hard
+ * # algorithm.
+ * Option "Pressure" "string" # {soft|hard|linear}
+ * Option "PressCurve" "y0,..,y511"
+ *
+ * # ------------------------------------------------------------------
+ * # These parameters describe active area. There are three different
+ * # sets of parameters you can use. Use of one set of parameters
+ * # precludes using the others. Forgetting that will cause undue
+ * # confusion.
+ * #
+ * # 1) xMax/yMax: The drawing area is assumed to begin at (0,0); what you
+ * # are therefore doing is describing the maximum X and Y coordinate
+ * # values of the opposite corner of the rectangle.
+ *
+ * Option "XMax" "int"
+ * Option "YMax" "int"
+ *
+ * # 2) xOffset/yOffset, xSize/ySize. The coordinate pair, xOffset, yOffset
+ * # describes the physical location of what will be considered to be
+ * # coordinate (0,0); xSize/ySize describes the coordinate of the
+ * # opposite corner of the rectangle, using relative coordinates
+ * # (e.g., with width and height.)
+ *
+ * Option "XSize" "int"
+ * Option "YSize" "int"
+ * Option "XOffset" "int"
+ * Option "YOffset" "int"
+ *
+ * # 3) xTop/yTop, xBottom, yBottom. xTop/yTop describes the physical
+ * # location of what will be considered coordinate (0,0);
+ * # xBottom/yBottom describes the coordinate of the opposite corner
+ * # of the rectangle, using physical coordinates.
+ *
+ * Option "XTop" "int"
+ * Option "YTop" "int"
+ * Option "XBottom" "int"
+ * Option "YBottom" "int"
+ *
+ * # End of 'Active Area' parameters
+ * # ------------------------------------------------------------------
+ *
+ *
+ * # Minimal and maximal pressure values that will be accepted.
+ * # Totally unrelated to thesholds, described below.
+ * Option "ZMax" "int"
+ * Option "ZMin" "int"
+ *
+ * # Threshold describes the minimal delta between this reading
+ * # and the previous reading. For example, if xThreshold is set to
+ * # 5 and you move the x coordinate by 2, that movement willl not
+ * # be reported to the X server. Movement will only be reported should
+ * # you move the stylus/mouse >= 5.
+ * Option "XThreshold" "int"
+ * Option "YThreshold" "int"
+ * Option "ZThreshold" "int"
+ *
+ * EndSection
+ *
+ *----------------------------------------------------------------------
+ * Commentary:
+ * 1. Identifier: what you name your input device is not significant to the
+ * X-Server. But it does afford you the opportunity to use names
+ * that infer what the device type is. It would be advantageous
+ * to use names like 'AiptekCursor', but we impose no standards on
+ * you with respect to that.
+ * 2. Type: you may have sections for each driver type ('stylus',
+ * 'eraser', and 'cursor'.) Since all three types may concurrently be
+ * associated with the same tablet, you'll likely associate
+ * all three with the same device (e.g., /dev/input/eventX.) Unless,
+ * you own more than one tablet, and only want the second one to
+ * operate as the stylus...
+ * 3. Device: obviously, if you have more than one tablet, then each
+ * will be mapped to different /dev/input/eventX paths. Use unique
+ * Identifiers for all devices.
+ * 4. Multiple tablet support works if each tablet is mapped to a different
+ * X-Server screen (ScreenNo.) There's nothing in place for multiple
+ * tablets to service the same screen at the same time (e.g., Xinerama
+ * supporting multiple display drivers.) If you want that, feel free
+ * to write it, and submit patches :-)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86Aiptek.h"
+
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+
+/***********************************************************************
+ * Function/Macro keys variables.
+ *
+ * This is a list of X keystrokes the macro keys can send. We're supporting
+ * up to 32 function keys, plus the escape key. Even with the 12000U, there
+ * are only 24 keys (and 12 macro keys on the 8000U and lesser.) So, we're
+ * supporting more keys than your tablet actually has. Call it future
+ * capacity planning, if you must.
+ */
+static KeySym aiptek_map[] =
+{
+ /* 0x00 .. 0x07 */
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol,
+ /* 0x08 .. 0x0f */
+ XK_F1, XK_F2, XK_F3, XK_F4, XK_F5, XK_F6, XK_F7, XK_F8,
+ /* 0x10 .. 0x17 */
+ XK_F9, XK_F10, XK_F11, XK_F12, XK_F13, XK_F14, XK_F15, XK_F16,
+ /* 0x18 .. 0x1f */
+ XK_F17, XK_F18, XK_F19, XK_F20, XK_F21, XK_F22, XK_F23, XK_F24,
+ /* 0x20 .. 0x27 */
+ XK_F25, XK_F26, XK_F27, XK_F28, XK_F29, XK_F30, XK_F31, XK_F32
+};
+
+/* This is the map of Linux Event Input system keystrokes sent for
+ * the macro keys. There are gaps in the integral values of these
+ * 'defines', so we cannot do a numeric transformation process.
+ * We therefore are left with a lookup process which finds the offset
+ * from the base element of this array, then applying same to aiptekKeysymMap.
+ * Oh, and there's the issue of the first 8 codes not being (re)definable
+ * in X. Just as well: X wants an offset into aiptekKeysymMap, instead
+ * of the KeySym code.
+ */
+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
+};
+
+/* minKeyCode = 8 because this is the min legal key code */
+static KeySymsRec keysyms =
+{
+ /* map minKeyCode maxKC width */
+ aiptek_map, 8, 0x27, 1
+};
+
+/* These are the parameter settings, and their default values.
+ * We use this to make a 'fakeLocal'...
+ */
+static const char *default_options[] =
+{
+ "BaudRate", "9600",
+ NULL
+};
+
+static const char* pStylusDevice = "stylus";
+static const char* pCursorDevice = "cursor";
+static const char* pEraserDevice = "eraser";
+static const char* pUnknownDevice = "unknown";
+
+/***********************************************************************
+ * AiptekIsValidFileDescriptor
+ *
+ * Determines whether a given fd is valid/open by abusing
+ * the UNIX notion that anything >= 0 is valid, and our
+ * vapid notion that VALUE_NA is a legal value for a closed
+ * handle. But it does get rid of stupidity of 'if (fd < 0)', which
+ * defeats the purpose of a #define...
+ */
+static Bool
+AiptekIsValidFileDescriptor(
+ int fd)
+{
+ if (fd == VALUE_NA)
+ {
+ return BadMatch;
+ }
+ return Success;
+}
+
+/***********************************************************************
+ * AiptekDispatcher
+ *
+ * Call dispatcher for this driver.
+ */
+static Bool
+AiptekDispatcher(
+ DeviceIntPtr dev,
+ int requestCode)
+{
+ const char *methodName = "AiptekDispatcher";
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ AiptekDevicePtr device = (AiptekDevicePtr) PRIVATE (dev);
+
+ CHECK_DEVICE_INT_PTR (dev, __LINE__);
+ CHECK_LOCAL_DEVICE_PTR (local, __LINE__);
+ CHECK_AIPTEK_DEVICE_PTR (device, __LINE__);
+
+ DBG (1, xf86Msg (X_INFO, "%s: entry\n", methodName));
+
+ switch (requestCode)
+ {
+ case DEVICE_INIT:
+ {
+ DBG(1, xf86Msg(X_INFO,
+ "%s: type=%s DeviceIntPtr.id=%d request=DEVICE_INIT\n",
+ methodName,
+ (DEVICE_ID (device->deviceId) == STYLUS_ID) ? pStylusDevice :
+ (DEVICE_ID (device->deviceId) == CURSOR_ID) ? pCursorDevice :
+ (DEVICE_ID (device->deviceId) == ERASER_ID) ? pEraserDevice :
+ pUnknownDevice, dev->id));
+
+ if (AiptekAllocateDriverClasses (dev) == BadMatch ||
+ AiptekOpenDriver (dev) == BadMatch)
+ {
+ return BadMatch;
+ }
+ }
+ break;
+
+ case DEVICE_ON:
+ {
+ DBG(1, xf86Msg(X_INFO,
+ "%s device type=%s, DeviceIntPtr.id=%d, request=DEVICE_ON\n",
+ methodName,
+ (DEVICE_ID (device->deviceId) == STYLUS_ID) ? pStylusDevice :
+ (DEVICE_ID (device->deviceId) == CURSOR_ID) ? pCursorDevice :
+ (DEVICE_ID (device->deviceId) == ERASER_ID) ? pEraserDevice :
+ pUnknownDevice, dev->id));
+
+ if (AiptekIsValidFileDescriptor (local->fd) == BadMatch &&
+ AiptekOpenDriver (dev) == BadMatch)
+ {
+ xf86Msg (X_ERROR, "%s: type=%s, Unable to open Aiptek Device\n",
+ methodName,
+ (DEVICE_ID (device->deviceId) == STYLUS_ID) ? pStylusDevice :
+ (DEVICE_ID (device->deviceId) == CURSOR_ID) ? pCursorDevice :
+ (DEVICE_ID (device->deviceId) == ERASER_ID) ? pEraserDevice :
+ pUnknownDevice);
+ dev->inited = FALSE;
+ return BadMatch;
+ }
+ xf86AddEnabledDevice (local);
+ dev->public.on = TRUE;
+ }
+ break;
+
+ case DEVICE_OFF:
+ {
+ DBG (1, xf86Msg(X_INFO,
+ "%s: device type=%s, DeviceIntPtr.id=%d, request=DEVICE_OFF\n",
+ methodName,
+ (DEVICE_ID (device->deviceId) == STYLUS_ID) ? pStylusDevice :
+ (DEVICE_ID (device->deviceId) == CURSOR_ID) ? pCursorDevice :
+ (DEVICE_ID (device->deviceId) == ERASER_ID) ? pEraserDevice :
+ pUnknownDevice, dev->id));
+
+ if (AiptekIsValidFileDescriptor (local->fd) == Success)
+ {
+ xf86RemoveEnabledDevice (local);
+ /* AiptekCloseDriver(local); */
+ }
+ dev->public.on = FALSE;
+ }
+ break;
+
+ case DEVICE_CLOSE:
+ {
+ DBG (1, xf86Msg(X_INFO,
+ "%s DEVICE_CLOSE, device type=%s, DeviceIntPtr.id=%d, request=DEVICE_CLOSE\n",
+ methodName,
+ (DEVICE_ID (device->deviceId) == STYLUS_ID) ? pStylusDevice :
+ (DEVICE_ID (device->deviceId) == CURSOR_ID) ? pCursorDevice :
+ (DEVICE_ID (device->deviceId) == ERASER_ID) ? pEraserDevice :
+ pUnknownDevice, dev->id));
+
+ if (AiptekIsValidFileDescriptor (local->fd) == Success)
+ {
+ xf86RemoveEnabledDevice (local);
+ AiptekCloseDriver (local);
+ }
+ dev->public.on = FALSE;
+ }
+ break;
+
+ default:
+ {
+ xf86Msg (X_ERROR,
+ "%s: device type=%s, DeviceIntPtr.id=%d, Unsupported request=%d\n",
+ methodName,
+ (DEVICE_ID (device->deviceId) == STYLUS_ID) ? pStylusDevice :
+ (DEVICE_ID (device->deviceId) == CURSOR_ID) ? pCursorDevice :
+ (DEVICE_ID (device->deviceId) == ERASER_ID) ? pEraserDevice :
+ pUnknownDevice, dev->id, requestCode);
+ return BadMatch;
+ }
+ break;
+ }
+ DBG (1, xf86Msg (X_INFO, "%s: type=%s, ends successfully\n",
+ methodName,
+ (DEVICE_ID (device->deviceId) == STYLUS_ID) ? pStylusDevice :
+ (DEVICE_ID (device->deviceId) == CURSOR_ID) ? pCursorDevice :
+ (DEVICE_ID (device->deviceId) == ERASER_ID) ? pEraserDevice :
+ pUnknownDevice));
+ return Success;
+}
+
+/***********************************************************************
+ * AiptekAllocateDriverStructs --
+ *
+ * Helper to AiptekDispatcher -- performs the 'DEVICE_INIT' function.
+ */
+static Bool
+AiptekAllocateDriverClasses(
+ DeviceIntPtr dev)
+{
+ const char *methodName = "AiptekAllocateDeviceClasses";
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ AiptekDevicePtr device = (AiptekDevicePtr) PRIVATE (dev);
+ CARD8 map[(32 << 4) + 1];
+ int numAxes;
+ int numButtons;
+ int loop;
+
+ CHECK_DEVICE_INT_PTR (dev, __LINE__);
+ CHECK_LOCAL_DEVICE_PTR (local, __LINE__);
+ CHECK_AIPTEK_DEVICE_PTR (device, __LINE__);
+
+ DBG (1, xf86Msg (X_INFO, "%s: begins, device=%s\n", methodName, local->name));
+
+ numAxes = 6; /* X, Y, Z, xTilt, yTilt, wheel */
+ numButtons = 5; /* three mice; max 5 stylus */
+
+ memset (map, 0, sizeof (map));
+ for (loop = 1; loop <= numButtons; ++loop)
+ {
+ map[loop] = loop;
+ }
+
+ /* These routines are typedef'd for Bool, yet return
+ * TRUE|FALSE, which is polar opposite of definition
+ * for Success|BadMatch (1,0 versus 0,1)
+ */
+ if (InitButtonClassDeviceStruct(dev, numButtons, map) == FALSE ||
+ InitFocusClassDeviceStruct(dev) == FALSE ||
+ InitPtrFeedbackClassDeviceStruct(dev, AiptekPtrFeedbackHandler) == FALSE ||
+ InitProximityClassDeviceStruct(dev) == FALSE ||
+ InitKeyClassDeviceStruct(dev, &keysyms, NULL) == FALSE ||
+ InitValuatorClassDeviceStruct(dev, numAxes, xf86GetMotionEvents,
+ local->history_size, ((device->flags & ABSOLUTE_FLAG) != 0
+ ? Absolute
+ : Relative) | OutOfProximity) == FALSE)
+ {
+ xf86Msg (X_ERROR, "%s: abends: Cannot allocate Class Device Struct(s)\n",
+ methodName);
+ return BadMatch;
+ }
+
+ /* Allocate the motion history buffer if needed
+ */
+ xf86MotionHistoryAllocate(local);
+
+ DBG (1, xf86Msg (X_INFO, "%s: ends successfully\n", methodName));
+ return Success;
+}
+
+/***********************************************************************
+ * AiptekUninit --
+ *
+ * Called when the driver instance is unloaded.
+ */
+static void
+AiptekUninit(
+ InputDriverPtr drv,
+ LocalDevicePtr local,
+ int flags)
+{
+ const char *methodName = "AiptekUninit";
+ AiptekDevicePtr device = (AiptekDevicePtr) local->private;
+
+ CHECK_INPUT_DRIVER_PTR (drv, __LINE__);
+ CHECK_LOCAL_DEVICE_PTR (local, __LINE__);
+ CHECK_AIPTEK_DEVICE_PTR (device, __LINE__);
+
+ DBG (1, xf86Msg (X_INFO, "%s: entry\n", methodName));
+
+ if (AiptekDispatcher (local->dev, DEVICE_OFF) == BadMatch)
+ {
+ return;
+ }
+
+ if (device->devicePath != NULL)
+ {
+ xfree (device->devicePath);
+ device->devicePath = NULL;
+ }
+ if (device != NULL)
+ {
+ xfree (device);
+ device = NULL;
+ }
+ xf86DeleteInput (local, 0);
+ DBG (1, xf86Msg (X_INFO, "%s: ends successfully\n", methodName));
+}
+
+/***********************************************************************
+ * AiptekInit --
+ *
+ * Called when the module subsection is found in XF86Config4.
+ * This parses the parameters found in the given section of the file.
+ */
+static InputInfoPtr
+AiptekInit(
+ InputDriverPtr drv,
+ IDevPtr dev,
+ int flags)
+{
+ const char *methodName = "AiptekInit";
+ LocalDevicePtr local = NULL;
+ LocalDevicePtr fakeLocal;
+ AiptekDevicePtr device;
+ char *devicePath;
+ char *tempStr;
+
+ CHECK_INPUT_DRIVER_PTR (drv, __LINE__);
+ CHECK_I_DEV_PTR (dev, __LINE__);
+
+ xf86Msg (X_INFO, "%s: begins for '%s'\n", methodName, dev->identifier);
+
+ fakeLocal = (LocalDevicePtr) xcalloc (1, sizeof (LocalDeviceRec));
+ if (fakeLocal == NULL)
+ {
+ xf86Msg (X_ERROR, "%s: cannot allocate a LocalDevicePtr struct\n",
+ methodName);
+ return NULL;
+ }
+
+ fakeLocal->conf_idev = dev;
+
+ /* We use fakeLocal here because we need something to parse
+ * what driver type is being asked for (stylus, eraser, cursor.)
+ * But, building a 'real' LocalDevicePtr means knowing which type
+ * of device we're building, which we don't yet know :-) Hence,
+ * the 'fake' struct.
+ */
+ xf86CollectInputOptions (fakeLocal, default_options, NULL);
+
+ /* Device
+ */
+ devicePath = xf86FindOptionValue (fakeLocal->options, "Device");
+ if (devicePath == NULL)
+ {
+ xf86Msg (X_ERROR, "%s: '%s': No Device specified.\n", methodName,
+ dev->identifier);
+ goto SetupProc_fail;
+ }
+
+ /* Type
+ */
+ tempStr = xf86FindOptionValue (fakeLocal->options, "Type");
+ if (tempStr != NULL && xf86NameCmp (tempStr, "stylus") == 0)
+ {
+ local = AiptekAllocateLocal (drv, dev->identifier, devicePath,
+ STYLUS_ID, 0);
+ }
+ else if (tempStr != NULL && xf86NameCmp (tempStr, "cursor") == 0)
+ {
+ local = AiptekAllocateLocal (drv, dev->identifier, devicePath,
+ CURSOR_ID, 0);
+ }
+ else if (tempStr != NULL && xf86NameCmp (tempStr, "eraser") == 0)
+ {
+ local = AiptekAllocateLocal (drv, dev->identifier, devicePath,
+ ERASER_ID, ABSOLUTE_FLAG);
+ }
+ else if (tempStr != NULL && xf86NameCmp (tempStr, "rubber") == 0)
+ {
+ local = AiptekAllocateLocal (drv, dev->identifier, devicePath,
+ ERASER_ID, ABSOLUTE_FLAG);
+ }
+ else
+ {
+ xf86Msg (X_ERROR, "%s: '%s': No type or invalid type specified.\n"
+ "Must be one of 'stylus', 'cursor', or 'eraser'\n",
+ methodName, dev->identifier);
+ }
+
+ /* Capture errors allocating LocalDevicePtr and AiptekDevicePtr
+ */
+ if (local == NULL)
+ {
+ xfree (fakeLocal);
+ return NULL;
+ }
+
+ /* Paranoia is a good thing :-)
+ */
+ device = (AiptekDevicePtr) local->private;
+ if (device == NULL)
+ {
+ xfree (local);
+ return NULL;
+ }
+
+ /* Move the options from fakeLocal over to local, now that we
+ * have a 'real' LocalDevicePtr.
+ */
+ local->options = fakeLocal->options;
+ local->conf_idev = fakeLocal->conf_idev;
+ local->name = dev->identifier;
+ xfree (fakeLocal);
+
+ /* If there are no other devices sharing this device, then we also have
+ * no AiptekCommonPtr, either. So, let's build one of those..
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list