On Tue, Jul 10, 2012 at 02:44:53AM +0600, Alexandr Shadchin wrote: > On Mon, Jul 09, 2012 at 10:35:55PM +0600, Alexandr Shadchin wrote: > > Add functional xf86-input-keyboard in xf86-input-ws (no new features) > > > > For test add or rewrite xorg.conf: > > > > Section "InputClass" > > Identifier "keyboard defaults" > > MatchIsKeyboard "on" > > > > Driver "ws" > > Option "Device" "/dev/wskbd" > > > > Option "XkbModel" "your setting" > > Option "XkbLayout" "your setting" > > Option "XkbVariant" "your setting" > > Option "XKbOptions" "your setting" > > EndSection > > > > Welcome any feedback. > > > > Fix decode extra keys (ex. multimedia) >
Suggestion mpi@: allocate memory only for pointer device or keyboard (but not both together) -- Alexandr Shadchin Index: man/ws.man =================================================================== RCS file: /cvs/xenocara/driver/xf86-input-ws/man/ws.man,v retrieving revision 1.13 diff -u -p -r1.13 ws.man --- man/ws.man 12 Jun 2012 17:12:50 -0000 1.13 +++ man/ws.man 11 Jul 2012 12:28:19 -0000 @@ -199,6 +199,38 @@ is mapped to the negative W axis motion .I N2 is mapped to the positive W axis motion. Default:\ "6\ 7". +.TP 4 +.BI "Option \*qXkbRules\*q \*q" rules \*q +Specifies which XKB rules file to use for interpreting the +.BR XkbModel , +.BR XkbLayout , +.BR XkbVariant , +and +.B XkbOptions +settings. +Default:\ "base". +.TP 4 +.BI "Option \*qXkbModel\*q \*q" modelname \*q +Specifies the XKB keyboard model name. +Default:\ "pc105". +.TP 4 +.BI "Option \*qXkbLayout\*q \*q" layoutname \*q +Specifies the XKB keyboard layout name. +This is usually the country or language type of the keyboard. +Default:\ "us". +.TP 4 +.BI "Option \*qXkbVariant\*q \*q" variants \*q +Specifies the XKB keyboard variant components. +These can be used to enhance the keyboard layout details. +Default:\ not\ set. +.TP 4 +.BI "Option \*qXkbOptions\*q \*q" options \*q +Specifies the XKB keyboard option components. +These can be used to enhance the keyboard behaviour. +Default:\ not\ set. +.PP +For a list of available XKB options, see +.B xkeyboard-config(__miscmansuffix__). .SH "SUPPORTED PROPERTIES" The following properties are provided by the .B ws Index: src/emumb.c =================================================================== RCS file: /cvs/xenocara/driver/xf86-input-ws/src/emumb.c,v retrieving revision 1.13 diff -u -p -r1.13 emumb.c --- src/emumb.c 8 Jul 2012 14:22:03 -0000 1.13 +++ src/emumb.c 11 Jul 2012 12:28:19 -0000 @@ -54,7 +54,7 @@ enum { MBEMU_AUTO }; -static Atom prop_mbemu; /* Middle button emulation on/off property */ +static Atom prop_mbemu; /* Middle button emulation on/off property */ static Atom prop_mbtimeout; /* Middle button timeout property */ /* @@ -194,20 +194,21 @@ static signed char stateTab[11][5][3] = int wsmbEmuTimer(InputInfoPtr pInfo) { - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; int sigstate; int id; sigstate = xf86BlockSIGIO(); - priv->emulateMB.pending = FALSE; - if ((id = stateTab[priv->emulateMB.state][4][0]) != 0) { + cursor->emulateMB.pending = FALSE; + if ((id = stateTab[cursor->emulateMB.state][4][0]) != 0) { xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0); - priv->emulateMB.state = stateTab[priv->emulateMB.state][4][2]; + cursor->emulateMB.state = + stateTab[cursor->emulateMB.state][4][2]; } else { xf86IDrvMsg(pInfo, X_ERROR, "Got unexpected buttonTimer in state %d\n", - priv->emulateMB.state); + cursor->emulateMB.state); } xf86UnblockSIGIO(sigstate); @@ -226,17 +227,17 @@ wsmbEmuTimer(InputInfoPtr pInfo) BOOL wsmbEmuFilterEvent(InputInfoPtr pInfo, int button, BOOL press) { - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; int id; int *btstate; int ret = FALSE; - if (!priv->emulateMB.enabled) + if (!cursor->emulateMB.enabled) return ret; /* Disable emulation when middle button event is detected */ - if (button == 2 && priv->emulateMB.enabled == MBEMU_AUTO) { - priv->emulateMB.enabled = FALSE; + if (button == 2 && cursor->emulateMB.enabled == MBEMU_AUTO) { + cursor->emulateMB.enabled = FALSE; return ret; } @@ -244,30 +245,31 @@ wsmbEmuFilterEvent(InputInfoPtr pInfo, i if (button != 1 && button != 3) return ret; - btstate = &priv->emulateMB.buttonstate; + btstate = &cursor->emulateMB.buttonstate; if (press) *btstate |= (button == 1) ? 0x1 : 0x2; else *btstate &= (button == 1) ? ~0x1 : ~0x2; - if ((id = stateTab[priv->emulateMB.state][*btstate][0]) != 0) { + if ((id = stateTab[cursor->emulateMB.state][*btstate][0]) != 0) { xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0); ret = TRUE; } - if ((id = stateTab[priv->emulateMB.state][*btstate][1]) != 0) { + if ((id = stateTab[cursor->emulateMB.state][*btstate][1]) != 0) { xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0); ret = TRUE; } - priv->emulateMB.state = stateTab[priv->emulateMB.state][*btstate][2]; + cursor->emulateMB.state = + stateTab[cursor->emulateMB.state][*btstate][2]; - if (stateTab[priv->emulateMB.state][4][0] != 0) { - priv->emulateMB.expires = GetTimeInMillis() - + priv->emulateMB.timeout; - priv->emulateMB.pending = TRUE; + if (stateTab[cursor->emulateMB.state][4][0] != 0) { + cursor->emulateMB.expires = GetTimeInMillis() + + cursor->emulateMB.timeout; + cursor->emulateMB.pending = TRUE; ret = TRUE; } else { - priv->emulateMB.pending = FALSE; + cursor->emulateMB.pending = FALSE; } return ret; } @@ -276,11 +278,11 @@ void wsmbEmuWakeupHandler(pointer data, int i, pointer LastSelectMask) { InputInfoPtr pInfo = (InputInfoPtr)data; - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; int ms; - if (priv->emulateMB.pending) { - ms = priv->emulateMB.expires - GetTimeInMillis(); + if (cursor->emulateMB.pending) { + ms = cursor->emulateMB.expires - GetTimeInMillis(); if (ms <= 0) wsmbEmuTimer(pInfo); } @@ -291,11 +293,11 @@ wsmbEmuBlockHandler(pointer data, struct pointer LastSelectMask) { InputInfoPtr pInfo = (InputInfoPtr)data; - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; int ms; - if (priv->emulateMB.pending) { - ms = priv->emulateMB.expires - GetTimeInMillis(); + if (cursor->emulateMB.pending) { + ms = cursor->emulateMB.expires - GetTimeInMillis(); if (ms <= 0) ms = 0; AdjustWaitForDelay(waitTime, ms); @@ -305,19 +307,19 @@ wsmbEmuBlockHandler(pointer data, struct void wsmbEmuPreInit(InputInfoPtr pInfo) { - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; int timeout; DBG(1, ErrorF("wsmbEmuPreInit\n")); - priv->emulateMB.enabled = MBEMU_AUTO; + cursor->emulateMB.enabled = MBEMU_AUTO; if (xf86FindOption(pInfo->options, "Emulate3Buttons")) { - priv->emulateMB.enabled = xf86SetBoolOption(pInfo->options, + cursor->emulateMB.enabled = xf86SetBoolOption(pInfo->options, "Emulate3Buttons", MBEMU_ENABLED); xf86IDrvMsg(pInfo, X_INFO, "Forcing middle mouse button " "emulation %s.\n", - (priv->emulateMB.enabled) ? "on" : "off"); + (cursor->emulateMB.enabled) ? "on" : "off"); } timeout = xf86SetIntOption(pInfo->options, "Emulate3Timeout", 50); @@ -327,7 +329,7 @@ wsmbEmuPreInit(InputInfoPtr pInfo) xf86IDrvMsg(pInfo, X_WARNING, "Using built-in timeout value\n"); timeout = 50; } - priv->emulateMB.timeout = timeout; + cursor->emulateMB.timeout = timeout; } void @@ -349,7 +351,7 @@ wsmbEmuSetProperty(DeviceIntPtr dev, Ato BOOL checkonly) { InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate; - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; DBG(1, ErrorF("wsmbEmuSetProperty %s\n", NameForAtom(atom))); @@ -359,7 +361,7 @@ wsmbEmuSetProperty(DeviceIntPtr dev, Ato return BadMatch; if (!checkonly) - priv->emulateMB.enabled = *((BOOL*)val->data); + cursor->emulateMB.enabled = *((BOOL*)val->data); } else if (atom == prop_mbtimeout) { int timeout; @@ -373,7 +375,7 @@ wsmbEmuSetProperty(DeviceIntPtr dev, Ato return BadValue; if (!checkonly) - priv->emulateMB.timeout = timeout; + cursor->emulateMB.timeout = timeout; } return Success; @@ -386,7 +388,7 @@ void wsmbEmuInitProperty(DeviceIntPtr dev) { InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate; - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; int rc; DBG(1, ErrorF("wsmbEmuInitProperty\n")); @@ -394,7 +396,7 @@ wsmbEmuInitProperty(DeviceIntPtr dev) prop_mbemu = MakeAtom(WS_PROP_MIDBUTTON, strlen(WS_PROP_MIDBUTTON), TRUE); rc = XIChangeDeviceProperty(dev, prop_mbemu, XA_INTEGER, 8, - PropModeReplace, 1, &priv->emulateMB.enabled, FALSE); + PropModeReplace, 1, &cursor->emulateMB.enabled, FALSE); if (rc != Success) { xf86IDrvMsg(pInfo, X_ERROR, "cannot create device property %s: %d\n", @@ -406,7 +408,7 @@ wsmbEmuInitProperty(DeviceIntPtr dev) prop_mbtimeout = MakeAtom(WS_PROP_MIDBUTTON_TIMEOUT, strlen(WS_PROP_MIDBUTTON_TIMEOUT), TRUE); rc = XIChangeDeviceProperty(dev, prop_mbtimeout, XA_INTEGER, 32, - PropModeReplace, 1, &priv->emulateMB.timeout, FALSE); + PropModeReplace, 1, &cursor->emulateMB.timeout, FALSE); if (rc != Success) { xf86IDrvMsg(pInfo, X_ERROR, "cannot create device property %s: %d\n", Index: src/emuwheel.c =================================================================== RCS file: /cvs/xenocara/driver/xf86-input-ws/src/emuwheel.c,v retrieving revision 1.2 diff -u -p -r1.2 emuwheel.c --- src/emuwheel.c 8 Jul 2012 13:51:11 -0000 1.2 +++ src/emuwheel.c 11 Jul 2012 12:28:19 -0000 @@ -61,20 +61,20 @@ static int wsWheelEmuSetProperty(DeviceI BOOL wsWheelEmuFilterButton(InputInfoPtr pInfo, unsigned int button, int press) { - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; int ms; - if (!priv->emulateWheel.enabled) + if (!cursor->emulateWheel.enabled) return FALSE; - if (priv->emulateWheel.button == button) { - priv->emulateWheel.button_state = press; + if (cursor->emulateWheel.button == button) { + cursor->emulateWheel.button_state = press; if (press) { - priv->emulateWheel.expires = GetTimeInMillis() + - priv->emulateWheel.timeout; + cursor->emulateWheel.expires = GetTimeInMillis() + + cursor->emulateWheel.timeout; } else { - ms = priv->emulateWheel.expires - GetTimeInMillis(); + ms = cursor->emulateWheel.expires - GetTimeInMillis(); if (ms > 0) { /* @@ -94,40 +94,42 @@ wsWheelEmuFilterButton(InputInfoPtr pInf BOOL wsWheelEmuFilterMotion(InputInfoPtr pInfo, int dx, int dy) { - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; WheelAxisPtr pAxis = NULL, pOtherAxis = NULL; int value; - if (!priv->emulateWheel.enabled) + if (!cursor->emulateWheel.enabled) return FALSE; /* * Handle our motion events if the emuWheel button is pressed. * Wheel button of 0 means always emulate wheel. */ - if (priv->emulateWheel.button_state || priv->emulateWheel.button == 0) { - if (priv->emulateWheel.button) { - int ms = priv->emulateWheel.expires - GetTimeInMillis(); + if (cursor->emulateWheel.button_state || + cursor->emulateWheel.button == 0) { + if (cursor->emulateWheel.button) { + int ms = + cursor->emulateWheel.expires - GetTimeInMillis(); if (ms > 0) return TRUE; } if (dx) { - pAxis = &(priv->emulateWheel.X); - pOtherAxis = &(priv->emulateWheel.Y); + pAxis = &(cursor->emulateWheel.X); + pOtherAxis = &(cursor->emulateWheel.Y); value = dx; } else if (dy) { - pAxis = &(priv->emulateWheel.Y); - pOtherAxis = &(priv->emulateWheel.X); + pAxis = &(cursor->emulateWheel.Y); + pOtherAxis = &(cursor->emulateWheel.X); value = dy; } else return FALSE; /* * Reset the inertia of the other axis when a scroll event - * was sent to avoid the buildup of erroneous scroll events if the - * user doesn't move in a perfectly straight line. + * was sent to avoid the buildup of erroneous scroll events if + * the user doesn't move in a perfectly straight line. */ if (pAxis) { if (wsWheelEmuInertia(pInfo, pAxis, value)) @@ -143,7 +145,7 @@ wsWheelEmuFilterMotion(InputInfoPtr pInf static int wsWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value) { - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; int button, inertia; int rc = 0; @@ -154,13 +156,13 @@ wsWheelEmuInertia(InputInfoPtr pInfo, Wh if (axis->traveled_distance < 0) { button = axis->negative; - inertia = -priv->emulateWheel.inertia; + inertia = -cursor->emulateWheel.inertia; } else { button = axis->positive; - inertia = priv->emulateWheel.inertia; + inertia = cursor->emulateWheel.inertia; } - while (abs(axis->traveled_distance) > priv->emulateWheel.inertia) { + while (abs(axis->traveled_distance) > cursor->emulateWheel.inertia) { axis->traveled_distance -= inertia; wsButtonClicks(pInfo, button, 1); rc++; @@ -172,21 +174,21 @@ wsWheelEmuInertia(InputInfoPtr pInfo, Wh void wsWheelEmuPreInit(InputInfoPtr pInfo) { - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; int button, inertia, timeout; - priv->emulateWheel.enabled = xf86SetBoolOption(pInfo->options, + cursor->emulateWheel.enabled = xf86SetBoolOption(pInfo->options, "EmulateWheel", FALSE); button = xf86SetIntOption(pInfo->options, "EmulateWheelButton", 4); - if (button < 0 || button > NBUTTONS) { + if (button < 0 || button > MAXBUTTONS) { xf86IDrvMsg(pInfo, X_WARNING, "Invalid EmulateWheelButton value: %d\n", button); xf86IDrvMsg(pInfo, X_WARNING, "Wheel emulation disabled\n"); - priv->emulateWheel.enabled = FALSE; + cursor->emulateWheel.enabled = FALSE; button = 4; } - priv->emulateWheel.button = button; + cursor->emulateWheel.button = button; inertia = xf86SetIntOption(pInfo->options, "EmulateWheelInertia", 10); if (inertia <= 0) { @@ -195,7 +197,7 @@ wsWheelEmuPreInit(InputInfoPtr pInfo) xf86IDrvMsg(pInfo, X_WARNING, "Using built-in inertia value\n"); inertia = 10; } - priv->emulateWheel.inertia = inertia; + cursor->emulateWheel.inertia = inertia; timeout = xf86SetIntOption(pInfo->options, "EmulateWheelTimeout", 200); if (timeout < 0) { @@ -204,11 +206,11 @@ wsWheelEmuPreInit(InputInfoPtr pInfo) xf86IDrvMsg(pInfo, X_WARNING, "Using built-in timeout value\n"); timeout = 200; } - priv->emulateWheel.timeout = timeout; + cursor->emulateWheel.timeout = timeout; - wsWheelHandleButtonMap(pInfo, &(priv->emulateWheel.Y), + wsWheelHandleButtonMap(pInfo, &(cursor->emulateWheel.Y), "YAxisMapping", "4 5"); - wsWheelHandleButtonMap(pInfo, &(priv->emulateWheel.X), + wsWheelHandleButtonMap(pInfo, &(cursor->emulateWheel.X), "XAxisMapping", NULL); } @@ -217,7 +219,7 @@ wsWheelEmuSetProperty(DeviceIntPtr dev, BOOL checkonly) { InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate; - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; if (atom == prop_wheel_emu) { if (val->format != 8 || val->size != 1 || @@ -225,7 +227,7 @@ wsWheelEmuSetProperty(DeviceIntPtr dev, return BadMatch; if (!checkonly) - priv->emulateWheel.enabled = *((BOOL*)val->data); + cursor->emulateWheel.enabled = *((BOOL*)val->data); } else if (atom == prop_wheel_button) { int button; @@ -235,11 +237,11 @@ wsWheelEmuSetProperty(DeviceIntPtr dev, button = *((CARD8*)val->data); - if (button < 0 || button > NBUTTONS) + if (button < 0 || button > MAXBUTTONS) return BadValue; if (!checkonly) - priv->emulateWheel.button = button; + cursor->emulateWheel.button = button; } else if (atom == prop_wheel_axismap) { int x_negative, x_positive; int y_negative, y_positive; @@ -253,10 +255,10 @@ wsWheelEmuSetProperty(DeviceIntPtr dev, y_negative = *(((CARD8*)val->data) + 2); y_positive = *(((CARD8*)val->data) + 3); - if (x_negative < 0 || x_negative > NBUTTONS || - x_positive < 0 || x_positive > NBUTTONS || - y_negative < 0 || y_negative > NBUTTONS || - y_positive < 0 || y_positive > NBUTTONS) + if (x_negative < 0 || x_negative > MAXBUTTONS || + x_positive < 0 || x_positive > MAXBUTTONS || + y_negative < 0 || y_negative > MAXBUTTONS || + y_positive < 0 || y_positive > MAXBUTTONS) return BadValue; if ((x_negative == WS_NOMAP && x_positive != WS_NOMAP) || @@ -266,10 +268,10 @@ wsWheelEmuSetProperty(DeviceIntPtr dev, return BadValue; if (!checkonly) { - priv->emulateWheel.X.negative = x_negative; - priv->emulateWheel.X.positive = x_positive; - priv->emulateWheel.Y.negative = y_negative; - priv->emulateWheel.Y.positive = y_positive; + cursor->emulateWheel.X.negative = x_negative; + cursor->emulateWheel.X.positive = x_positive; + cursor->emulateWheel.Y.negative = y_negative; + cursor->emulateWheel.Y.positive = y_positive; } } else if (atom == prop_wheel_inertia) { int inertia; @@ -284,7 +286,7 @@ wsWheelEmuSetProperty(DeviceIntPtr dev, return BadValue; if (!checkonly) - priv->emulateWheel.inertia = inertia; + cursor->emulateWheel.inertia = inertia; } else if (atom == prop_wheel_timeout) { int timeout; @@ -298,7 +300,7 @@ wsWheelEmuSetProperty(DeviceIntPtr dev, return BadValue; if (!checkonly) - priv->emulateWheel.timeout = timeout; + cursor->emulateWheel.timeout = timeout; } return Success; @@ -308,13 +310,13 @@ void wsWheelEmuInitProperty(DeviceIntPtr dev) { InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate; - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; char vals[4]; int rc; prop_wheel_emu = MakeAtom(WS_PROP_WHEEL, strlen(WS_PROP_WHEEL), TRUE); rc = XIChangeDeviceProperty(dev, prop_wheel_emu, XA_INTEGER, 8, - PropModeReplace, 1, &priv->emulateWheel.enabled, FALSE); + PropModeReplace, 1, &cursor->emulateWheel.enabled, FALSE); if (rc != Success) { xf86IDrvMsg(pInfo, X_ERROR, "cannot create device property %s: %d\n", @@ -323,10 +325,10 @@ wsWheelEmuInitProperty(DeviceIntPtr dev) } XISetDevicePropertyDeletable(dev, prop_wheel_emu, FALSE); - vals[0] = priv->emulateWheel.X.negative; - vals[1] = priv->emulateWheel.X.positive; - vals[2] = priv->emulateWheel.Y.negative; - vals[3] = priv->emulateWheel.Y.positive; + vals[0] = cursor->emulateWheel.X.negative; + vals[1] = cursor->emulateWheel.X.positive; + vals[2] = cursor->emulateWheel.Y.negative; + vals[3] = cursor->emulateWheel.Y.positive; prop_wheel_axismap = MakeAtom(WS_PROP_WHEEL_AXES, strlen(WS_PROP_WHEEL_AXES), TRUE); @@ -343,7 +345,7 @@ wsWheelEmuInitProperty(DeviceIntPtr dev) prop_wheel_inertia = MakeAtom(WS_PROP_WHEEL_INERTIA, strlen(WS_PROP_WHEEL_INERTIA), TRUE); rc = XIChangeDeviceProperty(dev, prop_wheel_inertia, XA_INTEGER, 16, - PropModeReplace, 1, &priv->emulateWheel.inertia, FALSE); + PropModeReplace, 1, &cursor->emulateWheel.inertia, FALSE); if (rc != Success) { xf86IDrvMsg(pInfo, X_ERROR, "cannot create device property %s: %d\n", @@ -355,7 +357,7 @@ wsWheelEmuInitProperty(DeviceIntPtr dev) prop_wheel_timeout = MakeAtom(WS_PROP_WHEEL_TIMEOUT, strlen(WS_PROP_WHEEL_TIMEOUT), TRUE); rc = XIChangeDeviceProperty(dev, prop_wheel_timeout, XA_INTEGER, 32, - PropModeReplace, 1, &priv->emulateWheel.timeout, FALSE); + PropModeReplace, 1, &cursor->emulateWheel.timeout, FALSE); if (rc != Success) { xf86IDrvMsg(pInfo, X_ERROR, "cannot create device property %s: %d\n", @@ -367,7 +369,7 @@ wsWheelEmuInitProperty(DeviceIntPtr dev) prop_wheel_button = MakeAtom(WS_PROP_WHEEL_BUTTON, strlen(WS_PROP_WHEEL_BUTTON), TRUE); rc = XIChangeDeviceProperty(dev, prop_wheel_button, XA_INTEGER, 8, - PropModeReplace, 1, &priv->emulateWheel.button, FALSE); + PropModeReplace, 1, &cursor->emulateWheel.button, FALSE); if (rc != Success) { xf86IDrvMsg(pInfo, X_ERROR, "cannot create device property %s: %d\n", Index: src/ws.c =================================================================== RCS file: /cvs/xenocara/driver/xf86-input-ws/src/ws.c,v retrieving revision 1.57 diff -u -p -r1.57 ws.c --- src/ws.c 8 Jul 2012 14:22:03 -0000 1.57 +++ src/ws.c 11 Jul 2012 12:28:19 -0000 @@ -23,10 +23,10 @@ #include <errno.h> #include <sys/ioctl.h> #include <sys/time.h> -#include <dev/wscons/wsconsio.h> #include <xorg-server.h> #include <xf86.h> +#include <xf86Priv.h> #include <xf86_OSproc.h> #include <X11/extensions/XI.h> #include <X11/extensions/XIproto.h> @@ -35,6 +35,7 @@ #include <xisb.h> #include <mipointer.h> #include <extinit.h> +#include <xkbsrv.h> #include "ws.h" @@ -42,25 +43,45 @@ #include "ws-properties.h" #include <xserver-properties.h> +#define CAPSFLAG (1 << 0) +#define NUMFLAG (1 << 1) +#define SCROLLFLAG (1 << 2) +#define COMPOSEFLAG (1 << 4) + static MODULESETUPPROTO(SetupProc); static MODULETEARDOWNPROTO(TearDownProc); static int wsPreInit(InputDriverPtr, InputInfoPtr, int); +static int wsPreInitPointer(InputDriverPtr, InputInfoPtr, int); +static int wsPreInitKeyboard(InputDriverPtr, InputInfoPtr, int); static void wsUnInit(InputDriverPtr, InputInfoPtr, int); static int wsProc(DeviceIntPtr, int); static int wsDeviceInit(DeviceIntPtr); +static int wsDeviceInitPointer(DeviceIntPtr); +static int wsDeviceInitKeyboard(DeviceIntPtr); static int wsDeviceOn(DeviceIntPtr); +static int wsDeviceOnPointer(DeviceIntPtr); +static int wsDeviceOnKeyboard(DeviceIntPtr); static void wsDeviceOff(DeviceIntPtr); +static void wsDeviceOffPointer(DeviceIntPtr); +static void wsDeviceOffKeyboard(DeviceIntPtr); static void wsReadInput(InputInfoPtr); +static void ConsoleReadInput(InputInfoPtr); static void wsSendButtons(InputInfoPtr, int); static int wsSwitchMode(ClientPtr, DeviceIntPtr, int); -static Bool wsOpen(InputInfoPtr); -static void wsClose(InputInfoPtr); +static int wsOpenPointer(InputInfoPtr); +static int wsOpenKeyboard(InputInfoPtr); +static void wsClosePointer(InputInfoPtr); +static void wsCloseKeyboard(InputInfoPtr); static void wsControlProc(DeviceIntPtr , PtrCtrl *); +static void wsKeyboardBell(int, DeviceIntPtr, pointer, int); +static void wsKeyboardCtrl(DeviceIntPtr, KeybdCtrl *); static void wsInitCalibProperty(DeviceIntPtr); static int wsSetCalibProperty(DeviceIntPtr, Atom, XIPropertyValuePtr, BOOL); +static Bool translate_XT_to_X(InputInfoPtr, int *); + static Atom prop_calibration; static Atom prop_swap; @@ -121,16 +142,10 @@ static int wsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) { WSDevicePtr priv; - MessageType buttons_from = X_CONFIG; - char *s; - int i, phy_btn = 1, rc = BadValue; - priv = (WSDevicePtr)calloc(1, sizeof(WSDeviceRec)); - if (priv == NULL) { - rc = BadAlloc; - goto fail; - } - pInfo->private = priv; + pInfo->private = priv = (WSDevicePtr)calloc(1, sizeof(WSDeviceRec)); + if (priv == NULL) + return BadAlloc; #ifdef DEBUG ws_debug_level = xf86SetIntOption(pInfo->options, "DebugLevel", @@ -142,10 +157,76 @@ wsPreInit(InputDriverPtr drv, InputInfoP xf86IDrvMsg(pInfo, X_ERROR, "No Device specified.\n"); goto fail; } - priv->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0); - if (priv->buttons == 0) { - priv->buttons = DFLTBUTTONS; - buttons_from = X_DEFAULT; + + if (strstr(priv->devName, "/dev/wsmouse") != NULL) { + priv->PreInit = wsPreInitPointer; + priv->DeviceInit = wsDeviceInitPointer; + priv->DeviceOn = wsDeviceOnPointer; + priv->DeviceOff = wsDeviceOffPointer; + priv->Open = wsOpenPointer; + priv->Close = wsClosePointer; + + priv->cursor = (WSPointerPtr)calloc(1, sizeof(WSPointerRec)); + if (priv->cursor == NULL) + goto fail; + + pInfo->read_input = wsReadInput; + } else if (strstr(priv->devName, "/dev/wskbd") != NULL) { + priv->PreInit = wsPreInitKeyboard; + priv->DeviceInit = wsDeviceInitKeyboard; + priv->DeviceOn = wsDeviceOnKeyboard; + priv->DeviceOff = wsDeviceOffKeyboard; + priv->Open = wsOpenKeyboard; + priv->Close = wsCloseKeyboard; + + priv->keyboard = + (WSKeyboardPtr)calloc(1, sizeof(WSKeyboardRec)); + if (priv->keyboard == NULL) + goto fail; + + pInfo->read_input = ConsoleReadInput; + } else { + xf86IDrvMsg(pInfo, X_ERROR, "wrong device\n"); + goto fail; + } + + pInfo->device_control = wsProc; + pInfo->switch_mode = wsSwitchMode; + + if (priv->Open(pInfo) != Success) + goto fail; + + if (priv->PreInit(drv, pInfo, flags) != Success) + goto fail; + + priv->Close(pInfo); + + return Success; + +fail: + if (pInfo->fd >= 0) + priv->Close(pInfo); + if (priv != NULL) { + free(priv); + pInfo->private = NULL; + } + return BadValue; +} + +static int +wsPreInitPointer(InputDriverPtr drv, InputInfoPtr pInfo, int flags) +{ + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; + char *s; + int i, phy_btn = 1; + + cursor->buttons = xf86SetIntOption(pInfo->options, + "Buttons", MINBUTTONS); + if (cursor->buttons < MINBUTTONS || cursor->buttons > MAXBUTTONS) { + xf86IDrvMsg(pInfo, X_WARNING, + "Invalid Buttons value: %d\n", cursor->buttons); + xf86IDrvMsg(pInfo, X_WARNING, "Using built-in minimal value\n"); + cursor->buttons = MINBUTTONS; } /* Check for user-defined button mapping */ @@ -157,51 +238,51 @@ wsPreInit(InputDriverPtr drv, InputInfoP do { btn = strtol(map, &end, 10); - if (end == map || btn < 0 || btn > NBUTTONS) { + if (end == map || btn < 0 || btn > MAXBUTTONS) { xf86IDrvMsg(pInfo, X_ERROR, "Invalid button mapping. Using defaults\n"); phy_btn = 1; /* ensure defaults start at 1 */ break; } - priv->btnmap[phy_btn++] = btn; + cursor->btnmap[phy_btn++] = btn; map = end; - } while (end && *end != '\0' && phy_btn <= NBUTTONS); + } while (end && *end != '\0' && phy_btn <= MAXBUTTONS); free(s); } - for (i = phy_btn; i <= NBUTTONS; i++) - priv->btnmap[i] = i; + for (i = phy_btn; i <= MAXBUTTONS; i++) + cursor->btnmap[i] = i; - wsWheelHandleButtonMap(pInfo, &(priv->Z), "ZAxisMapping", "4 5"); - wsWheelHandleButtonMap(pInfo, &(priv->W), "WAxisMapping", "6 7"); + wsWheelHandleButtonMap(pInfo, &(cursor->Z), "ZAxisMapping", "4 5"); + wsWheelHandleButtonMap(pInfo, &(cursor->W), "WAxisMapping", "6 7"); - priv->screen_no = xf86SetIntOption(pInfo->options, "ScreenNo", 0); + cursor->screen_no = xf86SetIntOption(pInfo->options, "ScreenNo", 0); xf86IDrvMsg(pInfo, X_CONFIG, "associated screen: %d\n", - priv->screen_no); - if (priv->screen_no < 0 || priv->screen_no >= screenInfo.numScreens) - priv->screen_no = 0; + cursor->screen_no); + if (cursor->screen_no < 0 || cursor->screen_no >= screenInfo.numScreens) + cursor->screen_no = 0; - priv->swap_axes = xf86SetBoolOption(pInfo->options, "SwapXY", 0); - if (priv->swap_axes) { + cursor->swap_axes = xf86SetBoolOption(pInfo->options, "SwapXY", 0); + if (cursor->swap_axes) { xf86IDrvMsg(pInfo, X_CONFIG, "device will work with X and Y axes swapped\n"); } - priv->inv_x = 0; - priv->inv_y = 0; + cursor->inv_x = 0; + cursor->inv_y = 0; s = xf86SetStrOption(pInfo->options, "Rotate", NULL); if (s) { if (xf86NameCmp(s, "CW") == 0) { - priv->inv_x = 1; - priv->inv_y = 0; - priv->swap_axes = 1; + cursor->inv_x = 1; + cursor->inv_y = 0; + cursor->swap_axes = 1; } else if (xf86NameCmp(s, "CCW") == 0) { - priv->inv_x = 0; - priv->inv_y = 1; - priv->swap_axes = 1; + cursor->inv_x = 0; + cursor->inv_y = 1; + cursor->swap_axes = 1; } else if (xf86NameCmp(s, "UD") == 0) { - priv->inv_x = 1; - priv->inv_y = 1; + cursor->inv_x = 1; + cursor->inv_y = 1; } else { xf86IDrvMsg(pInfo, X_ERROR, "\"%s\" is not a valid " "value for Option \"Rotate\"\n", s); @@ -210,72 +291,81 @@ wsPreInit(InputDriverPtr drv, InputInfoP } free(s); } - if (wsOpen(pInfo) != Success) - goto fail; - if (ioctl(pInfo->fd, WSMOUSEIO_GTYPE, &priv->type) != 0) - goto fail; - if (priv->type == WSMOUSE_TYPE_TPANEL) { + + if (ioctl(pInfo->fd, WSMOUSEIO_GTYPE, &cursor->type) != 0) + return !Success; + + if (cursor->type == WSMOUSE_TYPE_TPANEL) { pInfo->type_name = XI_TOUCHSCREEN; - priv->raw = xf86SetBoolOption(pInfo->options, "Raw", 1); - if (priv->raw) { + cursor->raw = xf86SetBoolOption(pInfo->options, "Raw", 1); + if (cursor->raw) { xf86IDrvMsg(pInfo, X_CONFIG, "device will work in raw mode\n"); } } else { pInfo->type_name = XI_MOUSE; - priv->raw = 0; + cursor->raw = 0; } - if (priv->type == WSMOUSE_TYPE_TPANEL && priv->raw) { + if (cursor->type == WSMOUSE_TYPE_TPANEL && cursor->raw) { if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS, - &priv->coords) != 0) { + &cursor->coords) != 0) { xf86IDrvMsg(pInfo, X_ERROR, "GCALIBCOORS failed %s\n", strerror(errno)); - goto fail; + return !Success; } /* get default coordinate space from kernel */ - priv->min_x = priv->coords.minx; - priv->max_x = priv->coords.maxx; - priv->min_y = priv->coords.miny; - priv->max_y = priv->coords.maxy; + cursor->min_x = cursor->coords.minx; + cursor->max_x = cursor->coords.maxx; + cursor->min_y = cursor->coords.miny; + cursor->max_y = cursor->coords.maxy; } else { /* in calibrated mode, coordinate space, is screen coords */ - priv->min_x = 0; - priv->max_x = screenInfo.screens[priv->screen_no]->width - 1; - priv->min_y = 0; - priv->max_y = screenInfo.screens[priv->screen_no]->height - 1; + cursor->min_x = cursor->min_y = 0; + cursor->max_x = + screenInfo.screens[cursor->screen_no]->width - 1; + cursor->max_y = + screenInfo.screens[cursor->screen_no]->height - 1; } - /* Allow options to override this */ - priv->min_x = xf86SetIntOption(pInfo->options, "MinX", priv->min_x); - xf86IDrvMsg(pInfo, X_INFO, "minimum x position: %d\n", priv->min_x); - priv->max_x = xf86SetIntOption(pInfo->options, "MaxX", priv->max_x); - xf86IDrvMsg(pInfo, X_INFO, "maximum x position: %d\n", priv->max_x); - priv->min_y = xf86SetIntOption(pInfo->options, "MinY", priv->min_y); - xf86IDrvMsg(pInfo, X_INFO, "minimum y position: %d\n", priv->min_y); - priv->max_y = xf86SetIntOption(pInfo->options, "MaxY", priv->max_y); - xf86IDrvMsg(pInfo, X_INFO, "maximum y position: %d\n", priv->max_y); - - pInfo->device_control = wsProc; - pInfo->read_input = wsReadInput; - pInfo->switch_mode = wsSwitchMode; - xf86IDrvMsg(pInfo, buttons_from, "Buttons: %d\n", priv->buttons); + /* Allow options to override this */ + cursor->min_x = xf86SetIntOption(pInfo->options, "MinX", cursor->min_x); + xf86IDrvMsg(pInfo, X_INFO, "minimum x position: %d\n", cursor->min_x); + cursor->max_x = xf86SetIntOption(pInfo->options, "MaxX", cursor->max_x); + xf86IDrvMsg(pInfo, X_INFO, "maximum x position: %d\n", cursor->max_x); + cursor->min_y = xf86SetIntOption(pInfo->options, "MinY", cursor->min_y); + xf86IDrvMsg(pInfo, X_INFO, "minimum y position: %d\n", cursor->min_y); + cursor->max_y = xf86SetIntOption(pInfo->options, "MaxY", cursor->max_y); + xf86IDrvMsg(pInfo, X_INFO, "maximum y position: %d\n", cursor->max_y); - wsClose(pInfo); + xf86IDrvMsg(pInfo, X_INFO, "Buttons: %d\n", cursor->buttons); wsmbEmuPreInit(pInfo); wsWheelEmuPreInit(pInfo); + return Success; +} -fail: - if (pInfo->fd >= 0) - wsClose(pInfo); - if (priv != NULL) { - free(priv); - pInfo->private = NULL; - } - return rc; +static int +wsPreInitKeyboard(InputDriverPtr drv, InputInfoPtr pInfo, int flags) +{ + WSKeyboardPtr keyboard = ((WSDevicePtr)pInfo->private)->keyboard; + + pInfo->type_name = XI_KEYBOARD; + + keyboard->rmlvo.rules = xf86SetStrOption(pInfo->options, + "XkbRules", "base"); + keyboard->rmlvo.model = xf86SetStrOption(pInfo->options, + "XkbModel", "pc105"); + keyboard->rmlvo.layout = xf86SetStrOption(pInfo->options, + "XkbLayout", "us"); + keyboard->rmlvo.variant = xf86SetStrOption(pInfo->options, + "XkbVariant", NULL); + keyboard->rmlvo.options = xf86SetStrOption(pInfo->options, + "XkbOptions", NULL); + + return Success; } static void @@ -284,6 +374,8 @@ wsUnInit(InputDriverPtr drv, InputInfoPt WSDevicePtr priv = (WSDevicePtr)pInfo->private; if (priv) { + if (priv->keyboard) + XkbFreeRMLVOSet(&priv->keyboard->rmlvo, FALSE); free(priv->devName); priv->devName = NULL; } @@ -294,6 +386,7 @@ static int wsProc(DeviceIntPtr pWS, int what) { InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; + WSDevicePtr priv = (WSDevicePtr)pInfo->private; switch (what) { case DEVICE_INIT: @@ -308,7 +401,8 @@ wsProc(DeviceIntPtr pWS, int what) case DEVICE_CLOSE: DBG(1, ErrorF("WS DEVICE_CLOSE\n")); - wsClose(pInfo); + if (pInfo->fd >= 0) + priv->Close(pInfo); break; default: @@ -323,24 +417,41 @@ wsDeviceInit(DeviceIntPtr pWS) { InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; WSDevicePtr priv = (WSDevicePtr)pInfo->private; - int xmin, xmax, ymin, ymax; - Atom btn_labels[NBUTTONS] = {0}; - Atom axes_labels[NAXES] = {0}; DBG(1, ErrorF("WS DEVICE_INIT\n")); + pWS->public.on = FALSE; + if (priv->Open(pInfo) != Success) + return !Success; + + if (priv->DeviceInit(pWS) != Success) + return !Success; + + return Success; +} + +static int +wsDeviceInitPointer(DeviceIntPtr pWS) +{ + InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; + unsigned char map[MAXBUTTONS + 1]; + int i, xmin, xmax, ymin, ymax; + Atom btn_labels[MAXBUTTONS] = {0}; + Atom axes_labels[NAXES] = {0}; + btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); - if (!InitButtonClassDeviceStruct(pWS, min(priv->buttons, NBUTTONS), - btn_labels, priv->btnmap)) + if (!InitButtonClassDeviceStruct(pWS, cursor->buttons, + btn_labels, cursor->btnmap)) return !Success; - if (priv->type == WSMOUSE_TYPE_TPANEL) { - xmin = priv->min_x; - xmax = priv->max_x; - ymin = priv->min_y; - ymax = priv->max_y; + if (cursor->type == WSMOUSE_TYPE_TPANEL) { + xmin = cursor->min_x; + xmax = cursor->max_x; + ymin = cursor->min_y; + ymax = cursor->max_y; } else { xmin = -1; xmax = -1; @@ -348,7 +459,7 @@ wsDeviceInit(DeviceIntPtr pWS) ymax = -1; } - if (priv->swap_axes) { + if (cursor->swap_axes) { int tmp; tmp = xmin; xmin = ymin; @@ -357,7 +468,7 @@ wsDeviceInit(DeviceIntPtr pWS) xmax = ymax; ymax = tmp; } - if (priv->type == WSMOUSE_TYPE_TPANEL) { + if (cursor->type == WSMOUSE_TYPE_TPANEL) { axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); } else { @@ -366,7 +477,7 @@ wsDeviceInit(DeviceIntPtr pWS) } if (!InitValuatorClassDeviceStruct(pWS, NAXES, axes_labels, GetMotionHistorySize(), - priv->type == WSMOUSE_TYPE_TPANEL ? Absolute : Relative)) + cursor->type == WSMOUSE_TYPE_TPANEL ? Absolute : Relative)) return !Success; if (!InitPtrFeedbackClassDeviceStruct(pWS, wsControlProc)) return !Success; @@ -374,24 +485,39 @@ wsDeviceInit(DeviceIntPtr pWS) xf86InitValuatorAxisStruct(pWS, 0, axes_labels[0], xmin, xmax, 1, 0, 1, - priv->type == WSMOUSE_TYPE_TPANEL ? Absolute : Relative); + cursor->type == WSMOUSE_TYPE_TPANEL ? Absolute : Relative); xf86InitValuatorDefaults(pWS, 0); xf86InitValuatorAxisStruct(pWS, 1, axes_labels[1], ymin, ymax, 1, 0, 1, - priv->type == WSMOUSE_TYPE_TPANEL ? Absolute : Relative); + cursor->type == WSMOUSE_TYPE_TPANEL ? Absolute : Relative); xf86InitValuatorDefaults(pWS, 1); - pWS->public.on = FALSE; - if (wsOpen(pInfo) != Success) { - return !Success; - } - - if (priv->type == WSMOUSE_TYPE_TPANEL) + if (cursor->type == WSMOUSE_TYPE_TPANEL) wsInitCalibProperty(pWS); wsmbEmuInitProperty(pWS); wsWheelEmuInitProperty(pWS); + + return Success; +} + +static int +wsDeviceInitKeyboard(DeviceIntPtr pWS) +{ + InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; + WSKeyboardPtr keyboard = ((WSDevicePtr)pInfo->private)->keyboard; + + tcgetattr(pInfo->fd, &(keyboard->kbdtty)); + + if (!InitKeyboardDeviceStruct(pWS, &keyboard->rmlvo, + wsKeyboardBell, wsKeyboardCtrl)) { + xf86IDrvMsg(pInfo, X_ERROR, "Keyboard initialization failed. " + "This could be a missing or incorrect setup of " + "xkeyboard-config.\n"); + return !Success; + } + return Success; } @@ -400,26 +526,53 @@ wsDeviceOn(DeviceIntPtr pWS) { InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; WSDevicePtr priv = (WSDevicePtr)pInfo->private; - struct wsmouse_calibcoords coords; DBG(1, ErrorF("WS DEVICE ON\n")); - if ((pInfo->fd < 0) && (wsOpen(pInfo) != Success)) { + + if ((pInfo->fd < 0) && (priv->Open(pInfo) != Success)) { xf86IDrvMsg(pInfo, X_ERROR, "wsOpen failed %s\n", strerror(errno)); return !Success; } - if (priv->type == WSMOUSE_TYPE_TPANEL) { + if (priv->DeviceOn(pWS) != Success) + return !Success; + + if (priv->cursor) { + priv->cursor->buffer = XisbNew(pInfo->fd, + sizeof(struct wscons_event) * NUMEVENTS); + if (priv->cursor->buffer == NULL) { + xf86IDrvMsg(pInfo, X_ERROR, + "cannot alloc xisb buffer\n"); + priv->Close(pInfo); + return !Success; + } + } + + xf86AddEnabledDevice(pInfo); + pWS->public.on = TRUE; + + return Success; +} + +static int +wsDeviceOnPointer(DeviceIntPtr pWS) +{ + InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; + struct wsmouse_calibcoords coords; + + if (cursor->type == WSMOUSE_TYPE_TPANEL) { /* get calibration values */ if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS, &coords) != 0) { xf86IDrvMsg(pInfo, X_ERROR, "GCALIBCOORS failed %s\n", strerror(errno)); return !Success; } - memcpy(&priv->coords, &coords, sizeof coords); + memcpy(&cursor->coords, &coords, sizeof coords); /* set raw mode */ - if (coords.samplelen != priv->raw) { - coords.samplelen = priv->raw; + if (coords.samplelen != cursor->raw) { + coords.samplelen = cursor->raw; if (ioctl(pInfo->fd, WSMOUSEIO_SCALIBCOORDS, &coords) != 0) { xf86IDrvMsg(pInfo, X_ERROR, @@ -428,16 +581,31 @@ wsDeviceOn(DeviceIntPtr pWS) } } } - priv->buffer = XisbNew(pInfo->fd, - sizeof(struct wscons_event) * NUMEVENTS); - if (priv->buffer == NULL) { - xf86IDrvMsg(pInfo, X_ERROR, "cannot alloc xisb buffer\n"); - wsClose(pInfo); - return !Success; - } - xf86AddEnabledDevice(pInfo); + wsmbEmuOn(pInfo); - pWS->public.on = TRUE; + + return Success; +} + +static int +wsDeviceOnKeyboard(DeviceIntPtr pWS) +{ + InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; + WSKeyboardPtr keyboard = ((WSDevicePtr)pInfo->private)->keyboard; + int mode = WSKBD_RAW; + + keyboard->kbdtty.c_iflag = IGNPAR | IGNBRK; + keyboard->kbdtty.c_oflag = 0; + keyboard->kbdtty.c_cflag = CREAD | CS8; + keyboard->kbdtty.c_lflag = 0; + keyboard->kbdtty.c_cc[VTIME] = 0; + keyboard->kbdtty.c_cc[VMIN] = 1; + cfsetispeed(&(keyboard->kbdtty), 9600); + cfsetospeed(&(keyboard->kbdtty), 9600); + if (tcsetattr(pInfo->fd, TCSANOW, &(keyboard->kbdtty)) < 0) + xf86IDrvMsg(pInfo, X_ERROR, "tcsetattr: %s\n", strerror(errno)); + ioctl(pInfo->fd, WSKBDIO_SETMODE, &mode); + return Success; } @@ -446,42 +614,63 @@ wsDeviceOff(DeviceIntPtr pWS) { InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; WSDevicePtr priv = (WSDevicePtr)pInfo->private; - struct wsmouse_calibcoords coords; DBG(1, ErrorF("WS DEVICE OFF\n")); + + priv->DeviceOff(pWS); + if (pInfo->fd >= 0) { + xf86RemoveEnabledDevice(pInfo); + priv->Close(pInfo); + } + if (priv->cursor && priv->cursor->buffer) { + XisbFree(priv->cursor->buffer); + priv->cursor->buffer = NULL; + } + pWS->public.on = FALSE; +} + +static void +wsDeviceOffPointer(DeviceIntPtr pWS) +{ + InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; + struct wsmouse_calibcoords coords; + wsmbEmuFinalize(pInfo); - if (priv->type == WSMOUSE_TYPE_TPANEL) { + if (cursor->type == WSMOUSE_TYPE_TPANEL) { /* Restore calibration data */ - memcpy(&coords, &priv->coords, sizeof coords); + memcpy(&coords, &cursor->coords, sizeof coords); if (ioctl(pInfo->fd, WSMOUSEIO_SCALIBCOORDS, &coords) != 0) { xf86IDrvMsg(pInfo, X_ERROR, "SCALIBCOORS failed %s\n", strerror(errno)); } } - if (pInfo->fd >= 0) { - xf86RemoveEnabledDevice(pInfo); - wsClose(pInfo); - } - if (priv->buffer) { - XisbFree(priv->buffer); - priv->buffer = NULL; - } - pWS->public.on = FALSE; +} + +static void +wsDeviceOffKeyboard(DeviceIntPtr pWS) +{ + InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; + WSKeyboardPtr keyboard = ((WSDevicePtr)pInfo->private)->keyboard; + int mode = WSKBD_TRANSLATED; + + ioctl(pInfo->fd, WSKBDIO_SETMODE, &mode); + tcsetattr(pInfo->fd, TCSANOW, &(keyboard->kbdtty)); } static void wsReadInput(InputInfoPtr pInfo) { - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; static struct wscons_event eventList[NUMEVENTS]; int n, c; struct wscons_event *event = eventList; unsigned char *pBuf; - XisbBlockDuration(priv->buffer, -1); + XisbBlockDuration(cursor->buffer, -1); pBuf = (unsigned char *)eventList; n = 0; - while (n < sizeof(eventList) && (c = XisbRead(priv->buffer)) >= 0) { + while (n < sizeof(eventList) && (c = XisbRead(cursor->buffer)) >= 0) { pBuf[n++] = (unsigned char)c; } @@ -490,7 +679,7 @@ wsReadInput(InputInfoPtr pInfo) n /= sizeof(struct wscons_event); while (n--) { - int buttons = priv->lastButtons; + int buttons = cursor->lastButtons; int dx = 0, dy = 0, dz = 0, dw = 0, ax = 0, ay = 0; int zbutton = 0, wbutton = 0; @@ -515,27 +704,20 @@ wsReadInput(InputInfoPtr pInfo) break; case WSCONS_EVENT_MOUSE_ABSOLUTE_X: DBG(4, ErrorF("Absolute X %d\n", event->value)); - if (event->value == 4095) - break; ax = event->value; - if (priv->inv_x) - ax = priv->max_x - ax + priv->min_x; + if (cursor->inv_x) + ax = cursor->max_x - ax + cursor->min_x; break; case WSCONS_EVENT_MOUSE_ABSOLUTE_Y: DBG(4, ErrorF("Absolute Y %d\n", event->value)); ay = event->value; - if (priv->inv_y) - ay = priv->max_y - ay + priv->min_y; + if (cursor->inv_y) + ay = cursor->max_y - ay + cursor->min_y; break; case WSCONS_EVENT_MOUSE_DELTA_Z: DBG(4, ErrorF("Relative Z %d\n", event->value)); dz = event->value; break; - case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: - /* ignore those */ - ++event; - continue; - break; case WSCONS_EVENT_MOUSE_DELTA_W: DBG(4, ErrorF("Relative W %d\n", event->value)); dw = event->value; @@ -543,6 +725,10 @@ wsReadInput(InputInfoPtr pInfo) default: xf86IDrvMsg(pInfo, X_WARNING, "bad wsmouse event type=%d\n", event->type); + /* FALLTHROUGH */ + case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: + case WSCONS_EVENT_MOUSE_ABSOLUTE_W: + /* ignore those */ ++event; continue; } @@ -557,25 +743,23 @@ wsReadInput(InputInfoPtr pInfo) dx, dy)); xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy); } - if (dz && priv->Z.negative != WS_NOMAP - && priv->Z.positive != WS_NOMAP) { - zbutton = (dz < 0) ? priv->Z.negative : - priv->Z.positive; + if (dz && cursor->Z.negative != WS_NOMAP + && cursor->Z.positive != WS_NOMAP) { + zbutton = (dz < 0) ? cursor->Z.negative : + cursor->Z.positive; DBG(4, ErrorF("Z -> button %d\n", zbutton)); wsButtonClicks(pInfo, zbutton, abs(dz)); } - if (dw && priv->W.negative != WS_NOMAP - && priv->W.positive != WS_NOMAP) { - wbutton = (dw < 0) ? priv->W.negative : - priv->W.positive; + if (dw && cursor->W.negative != WS_NOMAP + && cursor->W.positive != WS_NOMAP) { + wbutton = (dw < 0) ? cursor->W.negative : + cursor->W.positive; DBG(4, ErrorF("W -> button %d\n", wbutton)); wsButtonClicks(pInfo, wbutton, abs(dw)); } - if (priv->lastButtons != buttons) { - /* button event */ + if (cursor->lastButtons != buttons) wsSendButtons(pInfo, buttons); - } - if (priv->swap_axes) { + if (cursor->swap_axes) { int tmp; tmp = ax; @@ -583,8 +767,8 @@ wsReadInput(InputInfoPtr pInfo) ay = tmp; } if (ax) { - dx = ax - priv->old_ax; - priv->old_ax = ax; + dx = ax - cursor->old_ax; + cursor->old_ax = ax; if (wsWheelEmuFilterMotion(pInfo, dx, 0)) continue; @@ -593,8 +777,8 @@ wsReadInput(InputInfoPtr pInfo) xf86PostMotionEvent(pInfo->dev, 1, 0, 1, ax); } if (ay) { - dy = ay - priv->old_ay; - priv->old_ay = ay; + dy = ay - cursor->old_ay; + cursor->old_ay = ay; if (wsWheelEmuFilterMotion(pInfo, 0, dy)) continue; @@ -603,16 +787,34 @@ wsReadInput(InputInfoPtr pInfo) xf86PostMotionEvent(pInfo->dev, 1, 1, 1, ay); } } - return; +} + +static void +ConsoleReadInput(InputInfoPtr pInfo) +{ + unsigned char buf[64]; + int scancode, n, i; + + if ((n = read(pInfo->fd, buf, sizeof(buf))) > 0) { + for (i = 0; i < n; i++) { + scancode = buf[i] & 0x7f; + + if (!translate_XT_to_X(pInfo, &scancode)) + continue; + + xf86PostKeyboardEvent(pInfo->dev, + scancode, buf[i] & 0x80 ? FALSE : TRUE); + } + } } static void wsSendButtons(InputInfoPtr pInfo, int buttons) { - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; int change, button, press; - change = buttons ^ priv->lastButtons; + change = buttons ^ cursor->lastButtons; while (change) { button = ffs(change); press = buttons & (1 << (button - 1)); @@ -627,7 +829,7 @@ wsSendButtons(InputInfoPtr pInfo, int bu xf86PostButtonEvent(pInfo->dev, TRUE, button, press, 0, 0); DBG(3, ErrorF("post button event %d %d\n", button, press)); } - priv->lastButtons = buttons; + cursor->lastButtons = buttons; } static int @@ -636,8 +838,8 @@ wsSwitchMode(ClientPtr client, DeviceInt return BadMatch; } -static Bool -wsOpen(InputInfoPtr pInfo) +static int +wsOpenPointer(InputInfoPtr pInfo) { WSDevicePtr priv = (WSDevicePtr)pInfo->private; #ifdef __NetBSD__ @@ -660,14 +862,28 @@ wsOpen(InputInfoPtr pInfo) return Success; } +static int +wsOpenKeyboard(InputInfoPtr pInfo) +{ + pInfo->fd = xf86Info.consoleFd; + + return Success; +} + static void -wsClose(InputInfoPtr pInfo) +wsClosePointer(InputInfoPtr pInfo) { xf86CloseSerial(pInfo->fd); pInfo->fd = -1; } static void +wsCloseKeyboard(InputInfoPtr pInfo) +{ + pInfo->fd = -1; +} + +static void wsControlProc(DeviceIntPtr device, PtrCtrl *ctrl) { /* Nothing to do, dix handles all settings */ @@ -675,10 +891,41 @@ wsControlProc(DeviceIntPtr device, PtrCt } static void +wsKeyboardBell(int percent, DeviceIntPtr device, pointer ctrl, int unused) +{ + InputInfoPtr pInfo = (InputInfoPtr)device->public.devicePrivate; + struct wskbd_bell_data wsb; + + wsb.which = WSKBD_BELL_DOALL; + wsb.pitch = ((KeybdCtrl *)ctrl)->bell_pitch; + wsb.period = ((KeybdCtrl *)ctrl)->bell_duration; + wsb.volume = percent; + ioctl(pInfo->fd, WSKBDIO_COMPLEXBELL, &wsb); +} + +static void +wsKeyboardCtrl(DeviceIntPtr device, KeybdCtrl *ctrl) +{ + InputInfoPtr pInfo = (InputInfoPtr)device->public.devicePrivate; + unsigned long leds = 0; + + if (ctrl->leds & CAPSFLAG) + leds |= WSKBD_LED_CAPS; + if (ctrl->leds & NUMFLAG) + leds |= WSKBD_LED_NUM; + if (ctrl->leds & SCROLLFLAG) + leds |= WSKBD_LED_SCROLL; + if (ctrl->leds & COMPOSEFLAG) + leds |= WSKBD_LED_COMPOSE; + + ioctl(pInfo->fd, WSKBDIO_SETLEDS, &leds); +} + +static void wsInitCalibProperty(DeviceIntPtr device) { InputInfoPtr pInfo = (InputInfoPtr)device->public.devicePrivate; - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; int rc; DBG(1, ErrorF("wsInitCalibProperty\n")); @@ -686,7 +933,7 @@ wsInitCalibProperty(DeviceIntPtr device) prop_calibration = MakeAtom(WS_PROP_CALIBRATION, strlen(WS_PROP_CALIBRATION), TRUE); rc = XIChangeDeviceProperty(device, prop_calibration, XA_INTEGER, 32, - PropModeReplace, 4, &priv->min_x, FALSE); + PropModeReplace, 4, &cursor->min_x, FALSE); if (rc != Success) { xf86IDrvMsg(pInfo, X_ERROR, "cannot create device property %s: %d\n", @@ -698,7 +945,7 @@ wsInitCalibProperty(DeviceIntPtr device) prop_swap = MakeAtom(WS_PROP_SWAP_AXES, strlen(WS_PROP_SWAP_AXES), TRUE); rc = XIChangeDeviceProperty(device, prop_swap, XA_INTEGER, 8, - PropModeReplace, 1, &priv->swap_axes, FALSE); + PropModeReplace, 1, &cursor->swap_axes, FALSE); if (rc != Success) { xf86IDrvMsg(pInfo, X_ERROR, "cannot create device property %s: %d\n", @@ -717,7 +964,7 @@ wsSetCalibProperty(DeviceIntPtr device, BOOL checkonly) { InputInfoPtr pInfo = (InputInfoPtr)device->public.devicePrivate; - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; struct wsmouse_calibcoords coords; int need_update = 0; AxisInfoPtr ax = device->valuator->axes, @@ -733,31 +980,31 @@ wsSetCalibProperty(DeviceIntPtr device, if (!checkonly) { if (val->size == 0) { DBG(1, ErrorF(" uncalibrate\n")); - priv->min_x = 0; - priv->max_x = -1; - priv->min_y = 0; - priv->max_y = -1; + cursor->min_x = 0; + cursor->max_x = -1; + cursor->min_y = 0; + cursor->max_y = -1; } else { - priv->min_x = ((int *)(val->data))[0]; - priv->max_x = ((int *)(val->data))[1]; - priv->min_y = ((int *)(val->data))[2]; - priv->max_y = ((int *)(val->data))[3]; + cursor->min_x = ((int *)(val->data))[0]; + cursor->max_x = ((int *)(val->data))[1]; + cursor->min_y = ((int *)(val->data))[2]; + cursor->max_y = ((int *)(val->data))[3]; DBG(1, ErrorF(" calibrate %d %d %d %d\n", - priv->min_x, priv->max_x, - priv->min_y, priv->max_y)); + cursor->min_x, cursor->max_x, + cursor->min_y, cursor->max_y)); need_update++; } /* Update axes descriptors */ - if (!priv->swap_axes) { - ax->min_value = priv->min_x; - ax->max_value = priv->max_x; - ay->min_value = priv->min_y; - ay->max_value = priv->max_y; + if (!cursor->swap_axes) { + ax->min_value = cursor->min_x; + ax->max_value = cursor->max_x; + ay->min_value = cursor->min_y; + ay->max_value = cursor->max_y; } else { - ax->min_value = priv->min_y; - ax->max_value = priv->max_y; - ay->min_value = priv->min_x; - ay->max_value = priv->max_x; + ax->min_value = cursor->min_y; + ax->max_value = cursor->max_y; + ay->min_value = cursor->min_x; + ay->max_value = cursor->max_x; } } } else if (atom == prop_swap) { @@ -765,28 +1012,28 @@ wsSetCalibProperty(DeviceIntPtr device, val->size != 1) return BadMatch; if (!checkonly) { - priv->swap_axes = *((BOOL *)val->data); - DBG(1, ErrorF("swap_axes %d\n", priv->swap_axes)); + cursor->swap_axes = *((BOOL *)val->data); + DBG(1, ErrorF("swap_axes %d\n", cursor->swap_axes)); need_update++; } } if (need_update) { /* Update the saved values to be restored on device off */ - priv->coords.minx = priv->min_x; - priv->coords.maxx = priv->max_x; - priv->coords.miny = priv->min_y; - priv->coords.maxy = priv->max_y; - priv->coords.swapxy = priv->swap_axes; + cursor->coords.minx = cursor->min_x; + cursor->coords.maxx = cursor->max_x; + cursor->coords.miny = cursor->min_y; + cursor->coords.maxy = cursor->max_y; + cursor->coords.swapxy = cursor->swap_axes; /* Update the kernel calibration table */ - coords.minx = priv->min_x; - coords.maxx = priv->max_x; - coords.miny = priv->min_y; - coords.maxy = priv->max_y; - coords.swapxy = priv->swap_axes; - coords.samplelen = priv->raw; - coords.resx = priv->coords.resx; - coords.resy = priv->coords.resy; + coords.minx = cursor->min_x; + coords.maxx = cursor->max_x; + coords.miny = cursor->min_y; + coords.maxy = cursor->max_y; + coords.swapxy = cursor->swap_axes; + coords.samplelen = cursor->raw; + coords.resx = cursor->coords.resx; + coords.resy = cursor->coords.resy; if (ioctl(pInfo->fd, WSMOUSEIO_SCALIBCOORDS, &coords) != 0) { xf86IDrvMsg(pInfo, X_ERROR, "SCALIBCOORDS failed %s\n", strerror(errno)); @@ -799,7 +1046,7 @@ void wsWheelHandleButtonMap(InputInfoPtr pInfo, WheelAxisPtr pAxis, const char* axis_name, const char* default_value) { - WSDevicePtr priv = (WSDevicePtr)pInfo->private; + WSPointerPtr cursor = ((WSDevicePtr)pInfo->private)->cursor; char *option_string; int b1, b2; @@ -810,16 +1057,16 @@ wsWheelHandleButtonMap(InputInfoPtr pInf default_value); if (option_string) { if (sscanf(option_string, "%d %d", &b1, &b2) == 2 && - b1 > 0 && b1 <= NBUTTONS && - b2 > 0 && b2 <= NBUTTONS) { + b1 > 0 && b1 <= MAXBUTTONS && + b2 > 0 && b2 <= MAXBUTTONS) { xf86IDrvMsg(pInfo, X_CONFIG, "%s: buttons %d and %d\n", axis_name, b1, b2); pAxis->negative = b1; pAxis->positive = b2; - if (max(b1, b2) > priv->buttons) - priv->buttons = max(b1, b2); + if (max(b1, b2) > cursor->buttons) + cursor->buttons = max(b1, b2); } else { xf86IDrvMsg(pInfo, X_WARNING, "Invalid %s value: \"%s\"\n", @@ -838,4 +1085,63 @@ wsButtonClicks(InputInfoPtr pInfo, int b xf86PostButtonEvent(pInfo->dev, TRUE, button, 1, 0, 0); xf86PostButtonEvent(pInfo->dev, TRUE, button, 0, 0, 0); } +} + +static Bool +translate_XT_to_X(InputInfoPtr pInfo, int *scancode) +{ + WSKeyboardPtr keyboard = ((WSDevicePtr)pInfo->private)->keyboard; + + switch (keyboard->scanprefix) { + case 0x00: + switch (*scancode) { + case 0x60: + case 0x61: + keyboard->scanprefix = *scancode; + return FALSE; + case 0x72: *scancode = 0x6d; break; /* Compose */ + case 0x73: *scancode = 0x6b; break; /* LMeta */ + case 0x74: *scancode = 0x6c; break; /* RMeta */ + } + break; + case 0x60: + keyboard->scanprefix = 0; + switch (*scancode) { + case 0x38: *scancode = 0x69; break; /* RAlt */ + case 0x1d: *scancode = 0x65; break; /* RCtrl */ + case 0x52: *scancode = 0x62; break; /* Insert */ + case 0x53: *scancode = 0x63; break; /* Delete */ + case 0x47: *scancode = 0x59; break; /* Home */ + case 0x4f: *scancode = 0x5f; break; /* End */ + case 0x49: *scancode = 0x5b; break; /* PgUp */ + case 0x51: *scancode = 0x61; break; /* PgDn */ + case 0x4b: *scancode = 0x5c; break; /* Left */ + case 0x48: *scancode = 0x5a; break; /* Up */ + case 0x50: *scancode = 0x60; break; /* Down */ + case 0x4d: *scancode = 0x5e; break; /* Right */ + case 0x35: *scancode = 0x68; break; /* KP Div */ + case 0x1c: *scancode = 0x64; break; /* KP Enter */ + case 0x37: *scancode = 0x67; break; /* PrtSrc */ + case 0x46: *scancode = 0x6a; break; /* Break */ + case 0x5b: *scancode = 0x6b; break; /* LMeta */ + case 0x5c: *scancode = 0x6c; break; /* RMeta */ + case 0x5d: *scancode = 0x6d; break; /* Menu */ + case 0x5e: *scancode = 0x84; break; /* Power */ + case 0x2a: return FALSE; /* XXX PrtSrc */ + default: + *scancode += 0x78; + } + break; + case 0x61: + keyboard->scanprefix = (*scancode == 0x1d) ? 0x1d : 0; + return FALSE; + case 0x1d: + keyboard->scanprefix = 0; + if (*scancode != 0x45) + return FALSE; + *scancode = 0x66; /* Pause */ + } + + *scancode += MIN_KEYCODE; + return TRUE; } Index: src/ws.h =================================================================== RCS file: /cvs/xenocara/driver/xf86-input-ws/src/ws.h,v retrieving revision 1.12 diff -u -p -r1.12 ws.h --- src/ws.h 12 Jun 2012 17:44:56 -0000 1.12 +++ src/ws.h 11 Jul 2012 12:28:19 -0000 @@ -14,6 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <termios.h> #include <dev/wscons/wsconsio.h> /* #undef DEBUG */ @@ -27,12 +28,15 @@ extern int ws_debug_level; #endif #define NAXES 2 /* X and Y axes only */ -#define NBUTTONS 32 /* max theoretical buttons */ -#define DFLTBUTTONS 3 /* default number of buttons */ #define NUMEVENTS 16 /* max # of ws events to read at once */ +#define MINBUTTONS 3 /* min buttons */ +#define MAXBUTTONS 32 /* max theoretical buttons */ + #define WS_NOMAP 0 +#define MIN_KEYCODE 8 + /* axis specific data for wheel */ typedef struct { int negative; @@ -40,8 +44,7 @@ typedef struct { int traveled_distance; } WheelAxis, *WheelAxisPtr; -typedef struct WSDevice { - char *devName; /* device name */ +typedef struct { int type; /* ws device type */ unsigned int lastButtons; /* last state of buttons */ int old_ax, old_ay; @@ -57,7 +60,7 @@ typedef struct WSDevice { /* # of buttons and config-file specified button mapping */ unsigned int buttons; - unsigned char btnmap[NBUTTONS + 1]; + unsigned char btnmap[MAXBUTTONS + 1]; /* Middle mouse button emulation */ struct { @@ -80,6 +83,26 @@ typedef struct WSDevice { Time expires; /* time of expiry */ Time timeout; } emulateWheel; +} WSPointerRec, *WSPointerPtr; + +typedef struct { + XkbRMLVOSet rmlvo; + struct termios kbdtty; + int scanprefix; +} WSKeyboardRec, *WSKeyboardPtr; + +typedef struct { + char *devName; /* device name */ + + int (*PreInit)(InputDriverPtr, InputInfoPtr, int); + int (*DeviceInit)(DeviceIntPtr); + int (*DeviceOn)(DeviceIntPtr); + void (*DeviceOff)(DeviceIntPtr); + int (*Open)(InputInfoPtr); + void (*Close)(InputInfoPtr); + + WSPointerPtr cursor; + WSKeyboardPtr keyboard; } WSDeviceRec, *WSDevicePtr; /* Middle mouse button emulation */