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)

-- 
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 -w -r1.13 ws.man
--- man/ws.man  12 Jun 2012 17:12:50 -0000      1.13
+++ man/ws.man  9 Jul 2012 20:36:45 -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/ws.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-input-ws/src/ws.c,v
retrieving revision 1.57
diff -u -p -w -r1.57 ws.c
--- src/ws.c    8 Jul 2012 14:22:03 -0000       1.57
+++ src/ws.c    9 Jul 2012 20:36:46 -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,6 +157,59 @@ wsPreInit(InputDriverPtr drv, InputInfoP
                xf86IDrvMsg(pInfo, X_ERROR, "No Device specified.\n");
                goto fail;
        }
+
+       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;
+               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;
+               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)
+{
+       WSDevicePtr priv = (WSDevicePtr)pInfo->private;
+       MessageType buttons_from = X_CONFIG;
+       char *s;
+       int i, phy_btn = 1;
+
        priv->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0);
        if (priv->buttons == 0) {
                priv->buttons = DFLTBUTTONS;
@@ -210,10 +278,10 @@ wsPreInit(InputDriverPtr drv, InputInfoP
                }
                free(s);
        }
-       if (wsOpen(pInfo) != Success)
-               goto fail;
+
        if (ioctl(pInfo->fd, WSMOUSEIO_GTYPE, &priv->type) != 0)
-               goto fail;
+               return !Success;
+
        if (priv->type == WSMOUSE_TYPE_TPANEL) {
                pInfo->type_name = XI_TOUCHSCREEN;
                priv->raw = xf86SetBoolOption(pInfo->options, "Raw", 1);
@@ -231,7 +299,7 @@ wsPreInit(InputDriverPtr drv, InputInfoP
                    &priv->coords) != 0) {
                        xf86IDrvMsg(pInfo, X_ERROR,
                            "GCALIBCOORS failed %s\n", strerror(errno));
-                       goto fail;
+                       return !Success;
                }
 
                /* get default coordinate space from kernel */
@@ -246,6 +314,7 @@ wsPreInit(InputDriverPtr drv, InputInfoP
                priv->min_y = 0;
                priv->max_y = screenInfo.screens[priv->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);
@@ -256,26 +325,28 @@ wsPreInit(InputDriverPtr drv, InputInfoP
        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);
 
-       wsClose(pInfo);
-
        wsmbEmuPreInit(pInfo);
        wsWheelEmuPreInit(pInfo);
-       return Success;
 
-fail:
-       if (pInfo->fd >= 0)
-               wsClose(pInfo);
-       if (priv != NULL) {
-               free(priv);
-               pInfo->private = NULL;
+       return Success;
        }
-       return rc;
+
+static int
+wsPreInitKeyboard(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+       WSDevicePtr priv = (WSDevicePtr)pInfo->private;
+
+       pInfo->type_name = XI_KEYBOARD;
+
+       priv->rmlvo.rules = xf86SetStrOption(pInfo->options, "XkbRules", 
"base");
+       priv->rmlvo.model = xf86SetStrOption(pInfo->options, "XkbModel", 
"pc105");
+       priv->rmlvo.layout = xf86SetStrOption(pInfo->options, "XkbLayout", 
"us");
+       priv->rmlvo.variant = xf86SetStrOption(pInfo->options, "XkbVariant", 
NULL);
+       priv->rmlvo.options = xf86SetStrOption(pInfo->options, "XkbOptions", 
NULL);
+
+       return Success;
 }
 
 static void
@@ -284,6 +355,7 @@ wsUnInit(InputDriverPtr drv, InputInfoPt
        WSDevicePtr priv = (WSDevicePtr)pInfo->private;
 
        if (priv) {
+               XkbFreeRMLVOSet(&priv->rmlvo, FALSE);
                free(priv->devName);
                priv->devName = NULL;
        }
@@ -294,6 +366,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 +381,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,12 +397,29 @@ 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;
+       WSDevicePtr priv = (WSDevicePtr)pInfo->private;
+       unsigned char map[NBUTTONS + 1];
+       int i, xmin, xmax, ymin, ymax;
+       Atom btn_labels[NBUTTONS] = {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);
@@ -383,15 +474,30 @@ wsDeviceInit(DeviceIntPtr pWS)
            priv->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)
                wsInitCalibProperty(pWS);
        wsmbEmuInitProperty(pWS);
        wsWheelEmuInitProperty(pWS);
+
+       return Success;
+}
+
+static int
+wsDeviceInitKeyboard(DeviceIntPtr pWS)
+{
+       InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate;
+       WSDevicePtr priv = (WSDevicePtr)pInfo->private;
+
+       tcgetattr(pInfo->fd, &(priv->kbdtty));
+
+       if (!InitKeyboardDeviceStruct(pWS, &priv->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,15 +506,39 @@ 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->DeviceOn(pWS) != Success)
+               return !Success;
+
+       priv->buffer = XisbNew(pInfo->fd,
+           sizeof(struct wscons_event) * NUMEVENTS);
+       if (priv->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;
+       WSDevicePtr priv = (WSDevicePtr)pInfo->private;
+       struct wsmouse_calibcoords coords;
+
        if (priv->type == WSMOUSE_TYPE_TPANEL) {
                /* get calibration values */
                if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS, &coords) != 0) {
@@ -428,16 +558,33 @@ 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;
+       WSDevicePtr priv = (WSDevicePtr)pInfo->private;
+       struct termios nTty;
+       int mode = WSKBD_RAW;
+
+       nTty = priv->kbdtty;
+       nTty.c_iflag = IGNPAR | IGNBRK;
+       nTty.c_oflag = 0;
+       nTty.c_cflag = CREAD | CS8;
+       nTty.c_lflag = 0;
+       nTty.c_cc[VTIME] = 0;
+       nTty.c_cc[VMIN] = 1;
+       cfsetispeed(&nTty, 9600);
+       cfsetospeed(&nTty, 9600);
+       if (tcsetattr(pInfo->fd, TCSANOW, &nTty) < 0)
+               xf86IDrvMsg(pInfo, X_ERROR, "tcsetattr: %s\n", strerror(errno));
+       ioctl(pInfo->fd, WSKBDIO_SETMODE, &mode);
+
        return Success;
 }
 
@@ -446,9 +593,28 @@ 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->buffer) {
+               XisbFree(priv->buffer);
+               priv->buffer = NULL;
+       }
+       pWS->public.on = FALSE;
+}
+
+static void
+wsDeviceOffPointer(DeviceIntPtr pWS)
+{
+       InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate;
+       WSDevicePtr priv = (WSDevicePtr)pInfo->private;
+       struct wsmouse_calibcoords coords;
+
        wsmbEmuFinalize(pInfo);
        if (priv->type == WSMOUSE_TYPE_TPANEL) {
                /* Restore calibration data */
@@ -458,15 +624,17 @@ wsDeviceOff(DeviceIntPtr pWS)
                            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;
+       WSDevicePtr priv = (WSDevicePtr)pInfo->private;
+       int mode = WSKBD_TRANSLATED;
+
+       ioctl(pInfo->fd, WSKBDIO_SETMODE, &mode);
+       tcsetattr(pInfo->fd, TCSANOW, &(priv->kbdtty));
 }
 
 static void
@@ -515,8 +683,6 @@ 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;
@@ -531,11 +697,6 @@ wsReadInput(InputInfoPtr pInfo)
                        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 +704,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;
                }
@@ -603,7 +768,26 @@ wsReadInput(InputInfoPtr pInfo)
                        xf86PostMotionEvent(pInfo->dev, 1, 1, 1, ay);
                }
        }
-       return;
+}
+
+static void
+ConsoleReadInput(InputInfoPtr pInfo)
+{
+       WSDevicePtr priv = (WSDevicePtr)pInfo->private;
+       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
@@ -636,8 +820,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 +844,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,6 +873,37 @@ 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;
@@ -838,4 +1067,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)
+{
+       WSDevicePtr priv = (WSDevicePtr)pInfo->private;
+
+       switch (priv->scanprefix) {
+       case 0x00:
+               switch (*scancode) {
+               case 0x60:
+               case 0x61:
+                       priv->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:
+               priv->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:
+               priv->scanprefix = (*scancode == 0x1d) ? 0x1d : 0;
+               return FALSE;
+       case 0x1d:
+               priv->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 -w -r1.12 ws.h
--- src/ws.h    12 Jun 2012 17:44:56 -0000      1.12
+++ src/ws.h    9 Jul 2012 20:36:46 -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 */
@@ -33,6 +34,8 @@ extern int ws_debug_level;
 
 #define WS_NOMAP       0
 
+#define MIN_KEYCODE    8
+
 /* axis specific data for wheel */
 typedef struct {
        int negative;
@@ -54,6 +57,9 @@ typedef struct WSDevice {
        WheelAxis Z;
        WheelAxis W;
        struct wsmouse_calibcoords coords; /* mirror of the kernel values */
+       XkbRMLVOSet rmlvo;
+       struct termios kbdtty;
+       int scanprefix;
 
        /* # of buttons and config-file specified button mapping */
        unsigned int buttons;
@@ -80,6 +86,13 @@ typedef struct WSDevice {
                Time expires;           /* time of expiry */
                Time timeout;
        } emulateWheel;
+
+       int (*PreInit)(InputDriverPtr, InputInfoPtr, int);
+       int (*DeviceInit)(DeviceIntPtr);
+       int (*DeviceOn)(DeviceIntPtr);
+       void (*DeviceOff)(DeviceIntPtr);
+       int (*Open)(InputInfoPtr);
+       void (*Close)(InputInfoPtr);
 } WSDeviceRec, *WSDevicePtr;
 
 /* Middle mouse button emulation */

Reply via email to