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