/* * Copyright 2002 by Brian Goines (bgoines78@comcast.net) * * 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 Brian Goines not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Brian Goines makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * BRIAN GOINES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL FREDERIC LEPIED 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 ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * */ /* $XFree86: xc/programs/Xserver/hw/xfree86/input/jamstudio/js_x.c,v 1.3tsi Exp $ */ #include #include "xf86Version.h" #if XORG_VERSION_CURRENT >= XF86_VERSION_NUMERIC(3,9,0,0,0) #define XFREE86_V4 1 #endif #include "misc.h" #include "xf86.h" #include "xf86_ansic.h" #include "xf86_OSproc.h" #include "xf86Xinput.h" #include "exevents.h" /* Needed for InitValuator/Proximity stuff */ #include "mipointer.h" #ifdef XFree86LOADER #include "xf86Module.h" #endif #define JSX_XCOORD 65584 #define JSX_YCOORD 65585 #define JSX_PRESS 852016 #define JSX_BTN 852034 #define SYSCALL(call) while(((call) == -1) && (errno == EINTR)) #ifdef XFREE86_V4 struct hiddev_event { unsigned hid; signed int value; }; typedef struct { int jsxFd; int jsxTimeout; char *jsxDevice; int jsxOldX; int jsxOldY; int jsxOldPress; int jsxOldBtn; int jsxOldNotify; int jsxMaxX; int jsxMaxY; int jsxMinX; int jsxMinY; int jsxPressMax; int jsxPressMin; int jsxPressDiv; } JS_XDevRec, *JS_XDevPtr; static void xf86JS_XReadInput(LocalDevicePtr local) { JS_XDevPtr priv = local->private; struct hiddev_event event; int x = priv->jsxOldX, y = priv->jsxOldY, press = priv->jsxOldPress; int btn = priv->jsxOldBtn; int btn_notify = priv->jsxOldNotify; while (read(local->fd, &event, sizeof(struct hiddev_event)) == sizeof(struct hiddev_event)) { switch (event.hid) { case JSX_XCOORD: x = event.value; break; case JSX_YCOORD: y = event.value; break; case JSX_PRESS: press = event.value / priv->jsxPressDiv; break; case JSX_BTN: priv->jsxOldBtn = btn = event.value; break; } } x = x > 0 ? x : 0; x = x < priv->jsxMaxX ? x : priv->jsxMaxX; y = y > 0 ? y : 0; y = y < priv->jsxMaxY ? y : priv->jsxMaxY; press = press > 0 ? press : 0; press = press < priv->jsxPressMax ? press : priv->jsxPressMax; if ((press > priv->jsxPressMin) && (btn == 1)) btn_notify = 1; else btn_notify = 0; if ((x != priv->jsxOldX) || (y != priv->jsxOldY) || (press != priv->jsxOldPress)) { xf86PostMotionEvent(local->dev, 1, 0, 3, x, y, press); priv->jsxOldX = x; priv->jsxOldY = y; priv->jsxOldPress = press; } if (btn_notify != priv->jsxOldNotify) { xf86PostButtonEvent(local->dev, 0, 1, btn_notify, 0, 3, x, y, press); priv->jsxOldNotify = btn_notify; } } static int xf86JS_XConnect(DeviceIntPtr pJS_X) { LocalDevicePtr local = (LocalDevicePtr) pJS_X->public.devicePrivate; JS_XDevPtr priv = local->private; local->fd = xf86OpenSerial(local->options); InitValuatorAxisStruct(pJS_X, 0, priv->jsxMinX, priv->jsxMaxX, priv->jsxMaxX / 7.5, 0, priv->jsxMaxX / 7.5); InitValuatorAxisStruct(pJS_X, 1, priv->jsxMinY, priv->jsxMaxY, priv->jsxMaxY / 5.5, 0, priv->jsxMaxY / 5.5); InitValuatorAxisStruct(pJS_X, 2, priv->jsxPressMin, priv->jsxPressMax, 128, 0, 128); return (local->fd > 0); } static Bool xf86JS_XConvert(LocalDevicePtr local, int first, int num, int v0, int v1, int v2, int v3, int v4, int v5, int *x, int *y) { JS_XDevPtr priv = local->private; int width, height; int deltaX, deltaY; width = miPointerCurrentScreen()->width; height = miPointerCurrentScreen()->height; /* deltaX=(float)width/priv->jsxMaxX; deltaY=(float)height/priv->jsxMaxY; */ deltaX = priv->jsxMaxX / width; deltaY = priv->jsxMaxY / height; *x = v0 / deltaX; *y = v1 / deltaY; xf86XInputSetScreen(local, 0, *x, *y); return TRUE; } static void xf86JS_XControlProc(DeviceIntPtr device, PtrCtrl * ctrl) { return; } static int xf86JS_XProc(DeviceIntPtr pJS_X, int operation) { LocalDevicePtr local = (LocalDevicePtr) pJS_X->public.devicePrivate; int nbaxes = 3; /* X Y Pressure */ int nbuttons = 1; /* This this is necessary for most apps to work. */ CARD8 map[2] = { 0, 1 }; switch (operation) { case DEVICE_INIT: if (InitButtonClassDeviceStruct(pJS_X, nbuttons, map) == FALSE) return !Success; if (InitFocusClassDeviceStruct(pJS_X) == FALSE) return !Success; if (InitPtrFeedbackClassDeviceStruct(pJS_X, xf86JS_XControlProc) == FALSE) return !Success; if (InitProximityClassDeviceStruct(pJS_X) == FALSE) return !Success; if (InitValuatorClassDeviceStruct(pJS_X, nbaxes, xf86GetMotionEvents, local->history_size, Absolute | OutOfProximity) == FALSE) return !Success; else xf86MotionHistoryAllocate(local); xf86JS_XConnect(pJS_X); break; case DEVICE_ON: if (local->fd == -1) xf86JS_XConnect(pJS_X); xf86AddEnabledDevice(local); pJS_X->public.on = TRUE; break; case DEVICE_OFF: if (local->fd > 0) xf86RemoveEnabledDevice(local); case DEVICE_CLOSE: if (local->fd > 0) { SYSCALL(close(local->fd)); local->fd = -1; } break; default: xf86Msg(X_ERROR, "JamStudio: Unhandled operation number %d.\n", operation); break; } return Success; } static int xf86JS_XChangeControl(LocalDevicePtr local, xDeviceCtl * control) { return Success; } static int xf86JS_XSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode) { return Success; } static LocalDevicePtr xf86JS_XAllocate(InputDriverPtr drv) { LocalDevicePtr local; JS_XDevPtr priv = xalloc(sizeof(JS_XDevRec)); if (!priv) return NULL; local = xf86AllocateInput(drv, 0); if (!local) { xfree(priv); return NULL; } memset(priv, 0, sizeof(JS_XDevRec)); local->name = "JAMSTUDIO"; local->flags = 0; local->device_control = xf86JS_XProc; local->read_input = xf86JS_XReadInput; local->close_proc = NULL; local->control_proc = xf86JS_XChangeControl; local->switch_mode = xf86JS_XSwitchMode; local->conversion_proc = xf86JS_XConvert; local->fd = -1; local->atom = 0; local->dev = NULL; local->private = priv; local->type_name = "JamStudio"; local->history_size = 0; local->old_x = local->old_y = -1; priv->jsxFd = -1; priv->jsxTimeout = 0; priv->jsxDevice = NULL; priv->jsxOldX = -1; priv->jsxOldY = -1; priv->jsxOldPress = priv->jsxOldBtn = priv->jsxOldNotify = -1; priv->jsxMaxX = 8000; priv->jsxMaxY = 6000; priv->jsxMinX = 0; priv->jsxMinY = 0; priv->jsxPressMin = 5; priv->jsxPressMax = 127; priv->jsxPressDiv = 2; return local; } static void xf86JS_XUnInit(InputDriverPtr drv, LocalDevicePtr local, int flags) { JS_XDevPtr priv = local->private; xf86JS_XProc(local->dev, DEVICE_CLOSE); xfree(priv); xf86DeleteInput(local, 0); } static InputInfoPtr xf86JS_XInit(InputDriverPtr drv, IDevPtr dev, int flags) { LocalDevicePtr local = NULL; JS_XDevPtr priv = NULL; pointer options; if ((local = xf86JS_XAllocate(drv)) == NULL) { xf86Msg(X_ERROR, "Could not allocate local device.\n"); return NULL; } local->conf_idev = dev; xf86CollectInputOptions(local, NULL, NULL); options = local->options; local->name = dev->identifier; priv = (JS_XDevPtr) local->private; priv->jsxDevice = xf86FindOptionValue(options, "Device"); xf86ProcessCommonOptions(local, local->options); if (!priv->jsxDevice) { xf86Msg(X_ERROR, "JamStudio: No Device specified.\n"); return NULL; } priv->jsxMaxX = xf86SetIntOption(options, "MaxX", 8000); priv->jsxMaxY = xf86SetIntOption(options, "MaxY", 6000); priv->jsxMinX = xf86SetIntOption(options, "MinX", 0); priv->jsxMinY = xf86SetIntOption(options, "MinY", 0); priv->jsxPressMax = xf86SetIntOption(options, "PressMax", 127); priv->jsxPressMin = xf86SetIntOption(options, "PressMin", 5); priv->jsxPressDiv = xf86SetIntOption(options, "PressDiv", 2); local->flags |= XI86_POINTER_CAPABLE | XI86_CONFIGURED; return (local); } InputDriverRec JAMSTUDIO = { 1, "js_x", NULL, xf86JS_XInit, xf86JS_XUnInit, NULL, 0 }; #ifdef XFree86LOADER static void xf86JS_XUnplug(pointer p) { return; } static pointer xf86JS_XPlug(pointer module, pointer options, int *errmaj, int *errmin) { xf86AddInputDriver(&JAMSTUDIO, module, 0); return module; } static XF86ModuleVersionInfo xf86JS_XVersionRec = { "js_x", MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, XORG_VERSION_CURRENT, 1, 0, 0, ABI_CLASS_XINPUT, ABI_XINPUT_VERSION, MOD_CLASS_XINPUT, {0, 0, 0, 0} /* signature, to be patched into the file by a tool */ }; XF86ModuleData js_xModuleData = { &xf86JS_XVersionRec, xf86JS_XPlug, xf86JS_XUnplug }; #endif #endif