From cde931654d1966be6989e6c8f3cfacb23e6822a2 Mon Sep 17 00:00:00 2001
From: mickeyl <mickeyl>
Date: Wed, 31 Aug 2005 10:21:12 +0000
Subject: - add support for the new Switches type in the Linux Input System (coming with 2.6.14)

- use the new Switches support to rewrite the hinge sensor handling on Zaurus models w/ 2.6
- add Switches support to SysInfo, OInputSystem, oinputsystemdemo
---
(limited to 'libopie2')

diff --git a/libopie2/opiecore/device/odevice_zaurus.cpp b/libopie2/opiecore/device/odevice_zaurus.cpp
index 33d5cd6..a75f566 100644
--- a/libopie2/opiecore/device/odevice_zaurus.cpp
+++ b/libopie2/opiecore/device/odevice_zaurus.cpp
@@ -44,6 +44,8 @@
 #include <qcopchannel_qws.h>
 
 /* STD */
+#include <string.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <math.h>
 #include <stdlib.h>
@@ -304,8 +306,10 @@ void Zaurus::initButtons()
         case Model_Zaurus_SLC3000: // fallthrough
         case Model_Zaurus_SLC1000: // fallthrough
         case Model_Zaurus_SLC7x0:
-            if ( isQWS( ) ) {
-                addPreHandler(this); // hinge-sensor-handler
+            if ( isQWS( ) )
+            {   // setup hinge sensor stuff
+                addPreHandler(this);
+                initHingeSensor();
             }
             pz_buttons = z_buttons_c700;
             buttoncount = ARRAY_SIZE(z_buttons_c700);
@@ -662,13 +666,66 @@ OHingeStatus Zaurus::readHingeSensor() const
     }
     else
     {
-        // corgi keyboard is event source 0 in OZ kernel 2.6
+        /*
+         * The corgi keyboard is event source 0 in OZ kernel 2.6.
+         * Hinge status is reported via Input System Switchs 0 and 1 like that:
+         *
+         * -------------------------
+         * | SW0 | SW1 |    CASE   |
+         * |-----|-----|-----------|
+         * |  0     0    Landscape |
+         * |  0     1    Portrait  |
+         * |  1     0    Unknown   |
+         * |  1     1    Closed    |
+         * -------------------------
+         */
         OInputDevice* keyboard = OInputSystem::instance()->device( "event0" );
-        if ( keyboard && keyboard->isHeld( OInputDevice::Key_KP0 ) ) return CASE_LANDSCAPE;
-        else if ( keyboard && keyboard->isHeld( OInputDevice::Key_KP1 ) ) return CASE_PORTRAIT;
-        else if ( keyboard && keyboard->isHeld( OInputDevice::Key_KP2 ) ) return CASE_CLOSED;
-        qWarning("Zaurus::readHingeSensor() - couldn't compute hinge status!" );
-        return CASE_UNKNOWN;
+        bool switch0 = true;
+        bool switch1 = false;
+        if ( keyboard )
+        {
+            switch0 = keyboard->isHeld( OInputDevice::Switch0 );
+            switch1 = keyboard->isHeld( OInputDevice::Switch1 );
+        }
+        if ( switch0 )
+        {
+            return switch1 ? CASE_CLOSED : CASE_UNKNOWN;
+        }
+        else
+        {
+            return switch1 ? CASE_PORTRAIT : CASE_LANDSCAPE;
+        }
+    }
+}
+
+void Zaurus::initHingeSensor()
+{
+    if ( m_embedix ) return;
+
+    m_hinge.setName( "/dev/input/event0" );
+    if ( !m_hinge.open( IO_ReadOnly ) )
+    {
+        qDebug( "Zaurus::init() - Couldn't open /dev/input/event0 for read (%s)", strerror( errno ) );
+        return;
+    }
+
+    QSocketNotifier* sn = new QSocketNotifier( m_hinge.handle(), QSocketNotifier::Read, this );
+    QObject::connect( sn, SIGNAL(activated(int)), this, SLOT(hingeSensorTriggered()) );
+}
+
+void Zaurus::hingeSensorTriggered()
+{
+    qDebug( "Zaurus::hingeSensorTriggered() - got event" );
+    struct input_event e;
+    if ( ::read( m_hinge.handle(), &e, sizeof e ) > 0 )
+    {
+        qDebug( "Zaurus::hingeSensorTriggered() - event has type %d, code %d, value %d", e.type, e.code, e.value );
+        if ( e.type != EV_SW ) return;
+        if ( readHingeSensor() != CASE_UNKNOWN )
+        {
+            qDebug( "Zaurus::hingeSensorTriggered() - got valid switch event, calling rotateDefault()" );
+            QCopChannel::send( "QPE/Rotation", "rotateDefault()" );
+        }
     }
 }
 
diff --git a/libopie2/opiecore/device/odevice_zaurus.h b/libopie2/opiecore/device/odevice_zaurus.h
index 677e29f..bf30bc6 100644
--- a/libopie2/opiecore/device/odevice_zaurus.h
+++ b/libopie2/opiecore/device/odevice_zaurus.h
@@ -33,6 +33,7 @@
 #include "odevice_abstractmobiledevice.h"
 
 /* QT */
+#include <qfile.h>
 #include <qwindowsystem_qws.h>
 
 #ifndef ARRAY_SIZE
@@ -99,6 +100,10 @@ class Zaurus : public OAbstractMobileDevice, public QWSServer::KeyboardFilter
   protected:
     virtual void init(const QString&);
     virtual void initButtons();
+    void initHingeSensor();
+
+  protected slots:
+    void hingeSensorTriggered();
 
   public:
     virtual bool setDisplayBrightness( int b );
@@ -128,6 +133,7 @@ class Zaurus : public OAbstractMobileDevice, public QWSServer::KeyboardFilter
     QString m_backlightdev;
     OLedState m_leds[1];
     bool m_embedix;
+    QFile m_hinge;
 };
 
 struct z_button {
diff --git a/libopie2/opiecore/linux/oinputsystem.cpp b/libopie2/opiecore/linux/oinputsystem.cpp
index bad27ed..ebc417f 100644
--- a/libopie2/opiecore/linux/oinputsystem.cpp
+++ b/libopie2/opiecore/linux/oinputsystem.cpp
@@ -188,6 +188,22 @@ bool OInputDevice::isHeld( Key bit ) const
 }
 
 
+bool OInputDevice::isHeld( Switch bit ) const
+{
+    BIT_MASK( switches, SW_MAX );
+
+    if( ioctl( _fd, EVIOCGSW( sizeof(switches) ), switches ) < 0 )
+    {
+        perror( "EVIOCGSW" );
+        return false;
+    }
+    else
+    {
+        return BIT_TEST( switches, bit );
+    }
+}
+
+
 QString OInputDevice::globalKeyMask() const
 {
     BIT_MASK( keys, KEY_MAX );
@@ -210,6 +226,28 @@ QString OInputDevice::globalKeyMask() const
 }
 
 
+QString OInputDevice::globalSwitchMask() const
+{
+    BIT_MASK( switches, SW_MAX );
+
+    if( ioctl( _fd, EVIOCGSW( sizeof(switches) ), switches ) < 0 )
+    {
+        perror( "EVIOCGSW" );
+        return QString::null;
+    }
+    else
+    {
+        QString switchmask;
+        for ( int i = 0; i < SW_MAX; ++i )
+        {
+            if ( BIT_TEST( switches, i ) ) switchmask.append( QString().sprintf( "%0d, ", i ) );
+        }
+        return switchmask;
+
+    }
+}
+
+
 bool OInputDevice::isValid( const QString& path )
 {
     char buf[BUFSIZE] = "<unknown>";
diff --git a/libopie2/opiecore/linux/oinputsystem.h b/libopie2/opiecore/linux/oinputsystem.h
index 9676e73..fb5f498 100644
--- a/libopie2/opiecore/linux/oinputsystem.h
+++ b/libopie2/opiecore/linux/oinputsystem.h
@@ -94,7 +94,7 @@ class OInputDevice : public QObject
     OInputDevice( QObject* parent, const char* name = 0 );
     ~OInputDevice();
 
-    #include "oinputsystemenums.h"
+    #include <opie2/oinputsystemenums.h>
 
   public:
     /**
@@ -119,9 +119,18 @@ class OInputDevice : public QObject
      */
     bool isHeld( Key ) const;
     /**
+     * @returns whether a given @a Switch is being held at the moment
+     */
+    bool isHeld( Switch ) const;
+    /**
      * @internal
      * @returns a string containing a printable form of the global keymask
      */
+    QString globalSwitchMask() const;
+    /**
+     * @internal
+     * @returns a string containing a printable form of the global switchmask
+     */
     QString globalKeyMask() const;
     /**
      * @internal
diff --git a/libopie2/opiecore/linux/oinputsystemenums.h b/libopie2/opiecore/linux/oinputsystemenums.h
deleted file mode 100644
index 3461e5a..0000000
--- a/libopie2/opiecore/linux/oinputsystemenums.h
+++ b/dev/null
@@ -1,405 +0,0 @@
-
-    enum Feature
-    {
-        Synchronous     = EV_SYN,
-        Keys            = EV_KEY,
-        Relative        = EV_REL,
-        Absolute        = EV_ABS,
-        Miscellaneous   = EV_MSC,
-        Leds            = EV_LED,
-        Sound           = EV_SND,
-        AutoRepeat      = EV_REP,
-        ForceFeedback   = EV_FF,
-        PowerManagement = EV_PWR,
-        ForceFeedbackStatus = EV_FF_STATUS,
-    };
-    
-    enum Bus
-    {
-        PCI             = BUS_PCI,
-        ISAPNP          = BUS_ISAPNP,
-        HIL             = BUS_HIL,
-        BLUETOOTH       = BUS_BLUETOOTH,
-        ISA             = BUS_ISA,
-        I8042           = BUS_I8042,
-        XTKBD           = BUS_XTKBD,
-        RS232           = BUS_RS232,
-        GAMEPORT        = BUS_GAMEPORT,
-        PARPORT         = BUS_PARPORT,
-        AMIGA           = BUS_AMIGA,
-        ADB             = BUS_ADB,
-        I2C             = BUS_I2C,
-        HOST            = BUS_HOST,
-    };
-    
-    enum Key
-    {
-        Key_RESERVED		= 0,
-        Key_ESC			= 1,
-        Key_1			= 2,
-        Key_2			= 3,
-        Key_3			= 4,
-        Key_4			= 5,
-        Key_5			= 6,
-        Key_6			= 7,
-        Key_7			= 8,
-        Key_8			= 9,
-        Key_9			= 10,
-        Key_0			= 11,
-        Key_MINUS		= 12,
-        Key_EQUAL		= 13,
-        Key_BACKSPACE		= 14,
-        Key_TAB			= 15,
-        Key_Q			= 16,
-        Key_W			= 17,
-        Key_E			= 18,
-        Key_R			= 19,
-        Key_T			= 20,
-        Key_Y			= 21,
-        Key_U			= 22,
-        Key_I			= 23,
-        Key_O			= 24,
-        Key_P			= 25,
-        Key_LEFTBRACE		= 26,
-        Key_RIGHTBRACE		= 27,
-        Key_ENTER		= 28,
-        Key_LEFTCTRL		= 29,
-        Key_A			= 30,
-        Key_S			= 31,
-        Key_D			= 32,
-        Key_F			= 33,
-        Key_G			= 34,
-        Key_H			= 35,
-        Key_J			= 36,
-        Key_K			= 37,
-        Key_L			= 38,
-        Key_SEMICOLON		= 39,
-        Key_APOSTROPHE		= 40,
-        Key_GRAVE		= 41,
-        Key_LEFTSHIFT		= 42,
-        Key_BACKSLASH		= 43,
-        Key_Z			= 44,
-        Key_X			= 45,
-        Key_C			= 46,
-        Key_V			= 47,
-        Key_B			= 48,
-        Key_N			= 49,
-        Key_M			= 50,
-        Key_COMMA		= 51,
-        Key_DOT			= 52,
-        Key_SLASH		= 53,
-        Key_RIGHTSHIFT		= 54,
-        Key_KPASTERISK		= 55,
-        Key_LEFTALT		= 56,
-        Key_SPACE		= 57,
-        Key_CAPSLOCK		= 58,
-        Key_F1			= 59,
-        Key_F2			= 60,
-        Key_F3			= 61,
-        Key_F4			= 62,
-        Key_F5			= 63,
-        Key_F6			= 64,
-        Key_F7			= 65,
-        Key_F8			= 66,
-        Key_F9			= 67,
-        Key_F10			= 68,
-        Key_NUMLOCK		= 69,
-        Key_SCROLLLOCK		= 70,
-        Key_KP7			= 71,
-        Key_KP8			= 72,
-        Key_KP9			= 73,
-        Key_KPMINUS		= 74,
-        Key_KP4			= 75,
-        Key_KP5			= 76,
-        Key_KP6			= 77,
-        Key_KPPLUS		= 78,
-        Key_KP1			= 79,
-        Key_KP2			= 80,
-        Key_KP3			= 81,
-        Key_KP0			= 82,
-        Key_KPDOT		= 83,
-
-        Key_ZENKAKUHANKAKU	= 85,
-        Key_102ND		= 86,
-        Key_F11			= 87,
-        Key_F12			= 88,
-        Key_RO			= 89,
-        Key_KATAKANA		= 90,
-        Key_HIRAGANA		= 91,
-        Key_HENKAN		= 92,
-        Key_KATAKANAHIRAGANA	= 93,
-        Key_MUHENKAN		= 94,
-        Key_KPJPCOMMA		= 95,
-        Key_KPENTER		= 96,
-        Key_RIGHTCTRL		= 97,
-        Key_KPSLASH		= 98,
-        Key_SYSRQ		= 99,
-        Key_RIGHTALT		= 100,
-        Key_LINEFEED		= 101,
-        Key_HOME		= 102,
-        Key_UP			= 103,
-        Key_PAGEUP		= 104,
-        Key_LEFT		= 105,
-        Key_RIGHT		= 106,
-        Key_END			= 107,
-        Key_DOWN		= 108,
-        Key_PAGEDOWN		= 109,
-        Key_INSERT		= 110,
-        Key_DELETE		= 111,
-        Key_MACRO		= 112,
-        Key_MUTE		= 113,
-        Key_VOLUMEDOWN		= 114,
-        Key_VOLUMEUP		= 115,
-        Key_POWER		= 116,
-        Key_KPEQUAL		= 117,
-        Key_KPPLUSMINUS		= 118,
-        Key_PAUSE		= 119,
-
-        Key_KPCOMMA		= 121,
-        Key_HANGUEL		= 122,
-        Key_HANJA		= 123,
-        Key_YEN			= 124,
-        Key_LEFTMETA		= 125,
-        Key_RIGHTMETA		= 126,
-        Key_COMPOSE		= 127,
-
-        Key_STOP		= 128,
-        Key_AGAIN		= 129,
-        Key_PROPS		= 130,
-        Key_UNDO		= 131,
-        Key_FRONT		= 132,
-        Key_COPY		= 133,
-        Key_OPEN		= 134,
-        Key_PASTE		= 135,
-        Key_FIND		= 136,
-        Key_CUT			= 137,
-        Key_HELP		= 138,
-        Key_MENU		= 139,
-        Key_CALC		= 140,
-        Key_SETUP		= 141,
-        Key_SLEEP		= 142,
-        Key_WAKEUP		= 143,
-        Key_FILE		= 144,
-        Key_SENDFILE		= 145,
-        Key_DELETEFILE		= 146,
-        Key_XFER		= 147,
-        Key_PROG1		= 148,
-        Key_PROG2		= 149,
-        Key_WWW			= 150,
-        Key_MSDOS		= 151,
-        Key_COFFEE		= 152,
-        Key_DIRECTION		= 153,
-        Key_CYCLEWINDOWS	= 154,
-        Key_MAIL		= 155,
-        Key_BOOKMARKS		= 156,
-        Key_COMPUTER		= 157,
-        Key_BACK		= 158,
-        Key_FORWARD		= 159,
-        Key_CLOSECD		= 160,
-        Key_EJECTCD		= 161,
-        Key_EJECTCLOSECD	= 162,
-        Key_NEXTSONG		= 163,
-        Key_PLAYPAUSE		= 164,
-        Key_PREVIOUSSONG	= 165,
-        Key_STOPCD		= 166,
-        Key_RECORD		= 167,
-        Key_REWIND		= 168,
-        Key_PHONE		= 169,
-        Key_ISO			= 170,
-        Key_CONFIG		= 171,
-        Key_HOMEPAGE		= 172,
-        Key_REFRESH		= 173,
-        Key_EXIT		= 174,
-        Key_MOVE		= 175,
-        Key_EDIT		= 176,
-        Key_SCROLLUP		= 177,
-        Key_SCROLLDOWN		= 178,
-        Key_KPLEFTPAREN		= 179,
-        Key_KPRIGHTPAREN	= 180,
-
-        Key_F13			= 183,
-        Key_F14			= 184,
-        Key_F15			= 185,
-        Key_F16			= 186,
-        Key_F17			= 187,
-        Key_F18			= 188,
-        Key_F19			= 189,
-        Key_F20			= 190,
-        Key_F21			= 191,
-        Key_F22			= 192,
-        Key_F23			= 193,
-        Key_F24			= 194,
-
-        Key_PLAYCD		= 200,
-        Key_PAUSECD		= 201,
-        Key_PROG3		= 202,
-        Key_PROG4		= 203,
-        Key_SUSPEND		= 205,
-        Key_CLOSE		= 206,
-        Key_PLAY		= 207,
-        Key_FASTFORWARD		= 208,
-        Key_BASSBOOST		= 209,
-        Key_PRINT		= 210,
-        Key_HP			= 211,
-        Key_CAMERA		= 212,
-        Key_SOUND		= 213,
-        Key_QUESTION		= 214,
-        Key_EMAIL		= 215,
-        Key_CHAT		= 216,
-        Key_SEARCH		= 217,
-        Key_CONNECT		= 218,
-        Key_FINANCE		= 219,
-        Key_SPORT		= 220,
-        Key_SHOP		= 221,
-        Key_ALTERASE		= 222,
-        Key_CANCEL		= 223,
-        Key_BRIGHTNESSDOWN	= 224,
-        Key_BRIGHTNESSUP	= 225,
-        Key_MEDIA		= 226,
-
-        Key_UNKNOWN		= 240,
-
-        Button_MISC		= 0x100,
-        Button_0			= 0x100,
-        Button_1			= 0x101,
-        Button_2			= 0x102,
-        Button_3			= 0x103,
-        Button_4			= 0x104,
-        Button_5			= 0x105,
-        Button_6			= 0x106,
-        Button_7			= 0x107,
-        Button_8			= 0x108,
-        Button_9			= 0x109,
-
-        Button_MOUSE		= 0x110,
-        Button_LEFT		= 0x110,
-        Button_RIGHT		= 0x111,
-        Button_MIDDLE		= 0x112,
-        Button_SIDE		= 0x113,
-        Button_EXTRA		= 0x114,
-        Button_FORWARD		= 0x115,
-        Button_BACK		= 0x116,
-        Button_TASK		= 0x117,
-
-        Button_JOYSTICK		= 0x120,
-        Button_TRIGGER		= 0x120,
-        Button_THUMB		= 0x121,
-        Button_THUMB2		= 0x122,
-        Button_TOP			= 0x123,
-        Button_TOP2		= 0x124,
-        Button_PINKIE		= 0x125,
-        Button_BASE		= 0x126,
-        Button_BASE2		= 0x127,
-        Button_BASE3		= 0x128,
-        Button_BASE4		= 0x129,
-        Button_BASE5		= 0x12a,
-        Button_BASE6		= 0x12b,
-        Button_DEAD		= 0x12f,
-
-        Button_GAMEPAD		= 0x130,
-        Button_A			= 0x130,
-        Button_B			= 0x131,
-        Button_C			= 0x132,
-        Button_X			= 0x133,
-        Button_Y			= 0x134,
-        Button_Z			= 0x135,
-        Button_TL			= 0x136,
-        Button_TR			= 0x137,
-        Button_TL2			= 0x138,
-        Button_TR2			= 0x139,
-        Button_SELECT		= 0x13a,
-        Button_START		= 0x13b,
-        Button_MODE		= 0x13c,
-        Button_THUMBL		= 0x13d,
-        Button_THUMBR		= 0x13e,
-
-        Button_DIGI		= 0x140,
-        Button_TOOL_PEN		= 0x140,
-        Button_TOOL_RUBBER		= 0x141,
-        Button_TOOL_BRUSH		= 0x142,
-        Button_TOOL_PENCIL		= 0x143,
-        Button_TOOL_AIRBRUSH	= 0x144,
-        Button_TOOL_FINGER		= 0x145,
-        Button_TOOL_MOUSE		= 0x146,
-        Button_TOOL_LENS		= 0x147,
-        Button_TOUCH		= 0x14a,
-        Button_STYLUS		= 0x14b,
-        Button_STYLUS2		= 0x14c,
-        Button_TOOL_DOUBLETAP	= 0x14d,
-        Button_TOOL_TRIPLETAP	= 0x14e,
-
-        Button_WHEEL		= 0x150,
-        Button_GEAR_DOWN		= 0x150,
-        Button_GEAR_UP		= 0x151,
-
-        Key_OK			= 0x160,
-        Key_SELECT 		= 0x161,
-        Key_GOTO		= 0x162,
-        Key_CLEAR		= 0x163,
-        Key_POWER2		= 0x164,
-        Key_OPTION		= 0x165,
-        Key_INFO		= 0x166,
-        Key_TIME		= 0x167,
-        Key_VENDOR		= 0x168,
-        Key_ARCHIVE		= 0x169,
-        Key_PROGRAM		= 0x16a,
-        Key_CHANNEL		= 0x16b,
-        Key_FAVORITES		= 0x16c,
-        Key_EPG			= 0x16d,
-        Key_PVR			= 0x16e,
-        Key_MHP			= 0x16f,
-        Key_LANGUAGE		= 0x170,
-        Key_TITLE		= 0x171,
-        Key_SUBTITLE		= 0x172,
-        Key_ANGLE		= 0x173,
-        Key_ZOOM		= 0x174,
-        Key_MODE		= 0x175,
-        Key_KEYBOARD		= 0x176,
-        Key_SCREEN		= 0x177,
-        Key_PC			= 0x178,
-        Key_TV			= 0x179,
-        Key_TV2			= 0x17a,
-        Key_VCR			= 0x17b,
-        Key_VCR2		= 0x17c,
-        Key_SAT			= 0x17d,
-        Key_SAT2		= 0x17e,
-        Key_CD			= 0x17f,
-        Key_TAPE		= 0x180,
-        Key_RADIO		= 0x181,
-        Key_TUNER		= 0x182,
-        Key_PLAYER		= 0x183,
-        Key_TEXT		= 0x184,
-        Key_DVD			= 0x185,
-        Key_AUX			= 0x186,
-        Key_MP3			= 0x187,
-        Key_AUDIO		= 0x188,
-        Key_VIDEO		= 0x189,
-        Key_DIRECTORY		= 0x18a,
-        Key_LIST		= 0x18b,
-        Key_MEMO		= 0x18c,
-        Key_CALENDAR		= 0x18d,
-        Key_RED			= 0x18e,
-        Key_GREEN		= 0x18f,
-        Key_YELLOW		= 0x190,
-        Key_BLUE		= 0x191,
-        Key_CHANNELUP		= 0x192,
-        Key_CHANNELDOWN		= 0x193,
-        Key_FIRST		= 0x194,
-        Key_LAST		= 0x195,
-        Key_AB			= 0x196,
-        Key_NEXT		= 0x197,
-        Key_RESTART		= 0x198,
-        Key_SLOW		= 0x199,
-        Key_SHUFFLE		= 0x19a,
-        Key_BREAK		= 0x19b,
-        Key_PREVIOUS		= 0x19c,
-        Key_DIGITS		= 0x19d,
-        Key_TEEN		= 0x19e,
-        Key_TWEN		= 0x19f,
-
-        Key_DEL_EOL		= 0x1c0,
-        Key_DEL_EOS		= 0x1c1,
-        Key_INS_LINE		= 0x1c2,
-        Key_DEL_LINE		= 0x1c3,
-    };
-
diff --git a/libopie2/opiecore/linux_input.h b/libopie2/opiecore/linux_input.h
index b7a30bb..2df8a59 100644
--- a/libopie2/opiecore/linux_input.h
+++ b/libopie2/opiecore/linux_input.h
@@ -66,6 +66,7 @@ struct input_absinfo {
 #define EVIOCGKEY(len)		_IOC(_IOC_READ, 'E', 0x18, len)		/* get global keystate */
 #define EVIOCGLED(len)		_IOC(_IOC_READ, 'E', 0x19, len)		/* get all LEDs */
 #define EVIOCGSND(len)		_IOC(_IOC_READ, 'E', 0x1a, len)		/* get all sounds status */
+#define EVIOCGSW(len)		_IOC(_IOC_READ, 'E', 0x1b, len)		/* get all switch states */
 
 #define EVIOCGBIT(ev,len)	_IOC(_IOC_READ, 'E', 0x20 + ev, len)	/* get event bits */
 #define EVIOCGABS(abs)		_IOR('E', 0x40 + abs, struct input_absinfo)		/* get abs value/limits */
@@ -86,6 +87,7 @@ struct input_absinfo {
 #define EV_REL			0x02
 #define EV_ABS			0x03
 #define EV_MSC			0x04
+#define EV_SW			0x05
 #define EV_LED			0x11
 #define EV_SND			0x12
 #define EV_REP			0x14
@@ -521,6 +523,20 @@ struct input_absinfo {
 #define ABS_MAX			0x3f
 
 /*
+ * Switch events
+ */
+
+#define SW_0		0x00
+#define SW_1		0x01
+#define SW_2		0x02
+#define SW_3		0x03
+#define SW_4		0x04
+#define SW_5		0x05
+#define SW_6		0x06
+#define SW_7		0x07
+#define SW_MAX		0x0f
+
+/*
  * Misc events
  */
 
@@ -790,6 +806,7 @@ struct input_dev {
 	unsigned long ledbit[NBITS(LED_MAX)];
 	unsigned long sndbit[NBITS(SND_MAX)];
 	unsigned long ffbit[NBITS(FF_MAX)];
+	unsigned long swbit[NBITS(SW_MAX)];
 	int ff_effects_max;
 
 	unsigned int keycodemax;
@@ -811,6 +828,7 @@ struct input_dev {
 	unsigned long key[NBITS(KEY_MAX)];
 	unsigned long led[NBITS(LED_MAX)];
 	unsigned long snd[NBITS(SND_MAX)];
+	unsigned long sw[NBITS(SW_MAX)];
 
 	int absmax[ABS_MAX + 1];
 	int absmin[ABS_MAX + 1];
@@ -849,6 +867,7 @@ struct input_dev {
 #define INPUT_DEVICE_ID_MATCH_LEDBIT	0x200
 #define INPUT_DEVICE_ID_MATCH_SNDBIT	0x400
 #define INPUT_DEVICE_ID_MATCH_FFBIT	0x800
+#define INPUT_DEVICE_ID_MATCH_SWBIT	0x1000
 
 #define INPUT_DEVICE_ID_MATCH_DEVICE\
 	(INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT)
@@ -869,6 +888,7 @@ struct input_device_id {
 	unsigned long ledbit[NBITS(LED_MAX)];
 	unsigned long sndbit[NBITS(SND_MAX)];
 	unsigned long ffbit[NBITS(FF_MAX)];
+	unsigned long swbit[NBITS(SW_MAX)];
 
 	unsigned long driver_info;
 };
@@ -961,6 +981,11 @@ static inline void input_report_ff_status(struct input_dev *dev, unsigned int co
 	input_event(dev, EV_FF_STATUS, code, value);
 }
 
+static inline void input_report_switch(struct input_dev *dev, unsigned int code, int value)
+{
+	input_event(dev, EV_SW, code, !!value);
+}
+
 static inline void input_regs(struct input_dev *dev, struct pt_regs *regs)
 {
 	dev->regs = regs;
diff --git a/libopie2/opiecore/oinputsystemenums.h b/libopie2/opiecore/oinputsystemenums.h
index 3461e5a..728423a 100644
--- a/libopie2/opiecore/oinputsystemenums.h
+++ b/libopie2/opiecore/oinputsystemenums.h
@@ -6,6 +6,7 @@
         Relative        = EV_REL,
         Absolute        = EV_ABS,
         Miscellaneous   = EV_MSC,
+        Switches        = EV_SW,
         Leds            = EV_LED,
         Sound           = EV_SND,
         AutoRepeat      = EV_REP,
@@ -32,6 +33,18 @@
         HOST            = BUS_HOST,
     };
     
+    enum Switch
+    {
+        Switch0          = SW_0,
+        Switch1          = SW_1,
+        Switch2          = SW_2,
+        Switch3          = SW_3,
+        Switch4          = SW_4,
+        Switch5          = SW_5,
+        Switch6          = SW_6,
+        Switch7          = SW_7,
+    };
+
     enum Key
     {
         Key_RESERVED		= 0,
--
cgit v0.9.0.2