summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2003-05-30 14:09:56 (UTC)
committer mickeyl <mickeyl>2003-05-30 14:09:56 (UTC)
commitd8cec07fe5e54a68afe4feca574f9f4d2433e0c1 (patch) (unidiff)
tree1afc53a2f82cc0f07406eb5f34d78180fc4477ce
parent110068bf31fdd0b9ced6cb8844489364f3fb3f91 (diff)
downloadopie-d8cec07fe5e54a68afe4feca574f9f4d2433e0c1.zip
opie-d8cec07fe5e54a68afe4feca574f9f4d2433e0c1.tar.gz
opie-d8cec07fe5e54a68afe4feca574f9f4d2433e0c1.tar.bz2
improved keyboard driver to support to levels of SHIFT operations
implement workaround for buggy switches driver (or even the hardware?) generating bogus key events which are now gracefully ignored :)
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--qt/qte234-for-opie091-simpad.patch192
1 files changed, 160 insertions, 32 deletions
diff --git a/qt/qte234-for-opie091-simpad.patch b/qt/qte234-for-opie091-simpad.patch
index 93f4be3..5959469 100644
--- a/qt/qte234-for-opie091-simpad.patch
+++ b/qt/qte234-for-opie091-simpad.patch
@@ -24,9 +24,17 @@
24 # else 24 # else
25 if ((mouseFD = open( "/dev/h3600_ts", O_RDONLY | O_NDELAY)) < 0) { 25 if ((mouseFD = open( "/dev/h3600_ts", O_RDONLY | O_NDELAY)) < 0) {
26 # endif 26 # endif
27 --- src/kernel/qkeyboard_qws.cpp.origSat May 24 16:49:38 2003 27 --- src/kernel/qkeyboard_qws.cpp.origFri May 30 16:05:20 2003
28 +++ src/kernel/qkeyboard_qws.cppMon May 26 19:52:05 2003 28 +++ src/kernel/qkeyboard_qws.cppFri May 30 16:03:41 2003
29@@ -131,6 +131,53 @@ 29@@ -37,6 +37,7 @@
30 #include <qapplication.h>
31 #include <qsocketnotifier.h>
32 #include <qnamespace.h>
33+#include <qdatetime.h>
34 #include <qtimer.h>
35
36 #include <stdlib.h>
37@@ -131,6 +132,59 @@
30 38
31 #endif // QNX6 39 #endif // QNX6
32 40
@@ -40,15 +48,14 @@
40+#include <linux/switches.h> 48+#include <linux/switches.h>
41+#define SIMPAD_SWITCHES_DEVICE "/dev/misc/switches" 49+#define SIMPAD_SWITCHES_DEVICE "/dev/misc/switches"
42+ 50+
43+// switches from top to down over the SIMpad surface 51+// switches from left top to right down over the SIMpad surface
44+ 52+
53+#define SIMPAD_SWITCH_POWER 0x02
45+#define SIMPAD_SWITCH_UPPER 0x10 54+#define SIMPAD_SWITCH_UPPER 0x10
46+
47+#define SIMPAD_SWITCH_UP 0x20 55+#define SIMPAD_SWITCH_UP 0x20
48+#define SIMPAD_SWITCH_DOWN 0x40 56+#define SIMPAD_SWITCH_DOWN 0x40
49+#define SIMPAD_SWITCH_LEFT 0x80 57+#define SIMPAD_SWITCH_LEFT 0x80
50+#define SIMPAD_SWITCH_RIGHT 0x100 58+#define SIMPAD_SWITCH_RIGHT 0x100
51+
52+#define SIMPAD_SWITCH_LOWER 0x8 59+#define SIMPAD_SWITCH_LOWER 0x8
53+ 60+
54+class QWSsimpadButtonsHandler : public QWSKeyboardHandler 61+class QWSsimpadButtonsHandler : public QWSKeyboardHandler
@@ -71,8 +78,15 @@
71+ int fd; 78+ int fd;
72+ int repeatdelay; 79+ int repeatdelay;
73+ int repeatperiod; 80+ int repeatperiod;
74+ int k;
75+ 81+
82+ int lastCode; // last native code
83+ int lastPress; // last press/release state
84+
85+ int k; // last emitted Qt key code
86+ int shiftKeyPressed; // true if one of the SHIFT keys has been pressed and not yet released
87+ bool shiftUsed; // true if SHIFT has been used
88+
89+ QTime eventTimer; // tracks time between raw events
76+ QTimer* repeater; 90+ QTimer* repeater;
77+ QSocketNotifier *notifier; 91+ QSocketNotifier *notifier;
78+}; 92+};
@@ -80,7 +94,7 @@
80 #ifdef QT_QWS_SL5XXX 94 #ifdef QT_QWS_SL5XXX
81 static const QWSServer::KeyMap keyM[] = { 95 static const QWSServer::KeyMap keyM[] = {
82 { Qt::Key_unknown,0xffff , 0xffff , 0xffff }, // 00 96 { Qt::Key_unknown,0xffff , 0xffff , 0xffff }, // 00
83@@ -396,7 +443,7 @@ 97@@ -396,7 +450,7 @@
84 for the list of codes). 98 for the list of codes).
85 <li>\a modifiers is the set of modifier keys (see Qt::Modifier). 99 <li>\a modifiers is the set of modifier keys (see Qt::Modifier).
86 <li>\a isPress says whether this is a press or a release. 100 <li>\a isPress says whether this is a press or a release.
@@ -89,7 +103,7 @@
89 mechanism, or an actual key press. 103 mechanism, or an actual key press.
90 </ul> 104 </ul>
91 */ 105 */
92@@ -1440,7 +1486,11 @@ 106@@ -1440,7 +1494,11 @@
93 } else { 107 } else {
94 type = spec; 108 type = spec;
95 } 109 }
@@ -102,21 +116,23 @@
102 if ( type == "Buttons" ) { 116 if ( type == "Buttons" ) {
103 #if defined(QT_QWS_YOPY) 117 #if defined(QT_QWS_YOPY)
104 handler = new QWSyopyButtonsHandler(); 118 handler = new QWSyopyButtonsHandler();
105@@ -1469,6 +1519,103 @@ 119@@ -1469,6 +1527,217 @@
106 return keyM; 120 return keyM;
107 } 121 }
108 122
109-#endif // QT_NO_QWS_KEYBOARD 123-#endif // QT_NO_QWS_KEYBOARD
110+ 124
111+/* 125+/*
112+ * SIMpad switches handler 126+ * SIMpad switches handler
113+ * (C) 2003 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> 127+ * (C) 2003 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de>
114+ */ 128+ */
115 129+
116 130+
117+QWSsimpadButtonsHandler::QWSsimpadButtonsHandler() 131+QWSsimpadButtonsHandler::QWSsimpadButtonsHandler()
118+ :QWSKeyboardHandler(), fd( -1 ), 132+ :QWSKeyboardHandler(), fd( -1 ),
119+ repeatdelay( 400 ), repeatperiod( 80 ) 133+ repeatdelay( 700 ), repeatperiod( 80 ),
134+ lastCode( 0 ), lastPress( 0 ),
135+ k( -1 ), shiftKeyPressed( 0 ), shiftUsed( false )
120+{ 136+{
121+ qDebug( "SimpadButtonsHandler()" ); 137+ qDebug( "SimpadButtonsHandler()" );
122+ fd = ::open( SIMPAD_SWITCHES_DEVICE, O_RDWR | O_NDELAY, 0 ); 138+ fd = ::open( SIMPAD_SWITCHES_DEVICE, O_RDWR | O_NDELAY, 0 );
@@ -125,7 +141,7 @@
125+ qWarning( "SimpadButtonsHandler(): can't open %s", SIMPAD_SWITCHES_DEVICE ); 141+ qWarning( "SimpadButtonsHandler(): can't open %s", SIMPAD_SWITCHES_DEVICE );
126+ return; 142+ return;
127+ } 143+ }
128+ 144
129+ notifier = new QSocketNotifier( fd, QSocketNotifier::Read, this ); 145+ notifier = new QSocketNotifier( fd, QSocketNotifier::Read, this );
130+ connect( notifier, SIGNAL( activated(int) ),this, SLOT( readSwitchesData() ) ); 146+ connect( notifier, SIGNAL( activated(int) ),this, SLOT( readSwitchesData() ) );
131+ 147+
@@ -156,27 +172,140 @@
156+ return; 172+ return;
157+ } 173+ }
158+ 174+
159+ qDebug( "SimpadButtonsHandler() - SwitchEvent = %0x | %0x", 175+ qDebug( "SimpadButtonsHandler() - Shift: %0x [used: %0x] + Event = %0x | %0x",
160+ switches.events[0], switches.states[0] ); 176+ shiftKeyPressed, shiftUsed, switches.events[0], switches.states[0] );
161+ 177+
162+ bool press = switches.states[0]; // == switches.event[0]; 178+ bool press = switches.states[0]; // == switches.event[0];
163+ int code = switches.events[0]; 179+ int code = switches.events[0];
164+ k = -1;
165+ 180+
166+ switch(code) 181+ //=========================================================================
182+
183+ /**
184+ * Work around a bug in the kernel keyboard driver emitting
185+ * bogus events when pressing multiple switches at once
186+ **/
187+
188+ if ( lastCode == 0 )
189+ {
190+ // first press ever
191+ eventTimer.start();
192+ lastPress = press;
193+ lastCode = code;
194+ }
195+ else
167+ { 196+ {
168+ case SIMPAD_SWITCH_UPPER: k = Qt::Key_Escape; break; 197+ int interval = eventTimer.restart();
169+ case SIMPAD_SWITCH_UP: k = Qt::Key_Up; break; 198+ qDebug( "event interval = %d", interval );
170+ case SIMPAD_SWITCH_DOWN: k = Qt::Key_Down; break; 199+ if ( code == lastCode && interval < 30 )
171+ case SIMPAD_SWITCH_LEFT: k = Qt::Key_Left; break; 200+ {
172+ case SIMPAD_SWITCH_RIGHT: k = Qt::Key_Right; break; 201+ qDebug( "event interval too small - ignoring bogus event" );
173+ case SIMPAD_SWITCH_LOWER: k = Qt::Key_Return; break; 202+ qDebug( "did I say i hate buggy kernel drivers? :-D" );
174+ default: k=-1; qWarning( "SimpadButtonsHandler() - unhandled event!" ); break; 203+ return;
204+ }
205+
206+ lastPress = press;
207+ lastCode = code;
175+ } 208+ }
176+ 209+
177+ bool repeatable = ( k != SIMPAD_SWITCH_UPPER && k != SIMPAD_SWITCH_LOWER ); 210+ /**
211+ * Actually it may also be a hardware problem, but I really don't like
212+ * to review kernel code for further inquiry. So just being lazy and
213+ * do the workaround in user space :-D
214+ **/
178+ 215+
179+ qDebug( "SimpadButtonsHandler() - Repeatable = %s", repeatable? "true":"false" ); 216+ //=====================================================================
217+
218+ if ( shiftKeyPressed )
219+ {
220+ // a shift key obviously is being held
221+ qDebug( "while shift key is being held..." );
222+
223+ if ( code != shiftKeyPressed )
224+ {
225+ // another key is being touched - that means shift mode for us!
226+ qDebug( " another key is being touched -> shift use now = true" );
227+
228+ shiftUsed = true;
229+
230+ if ( shiftKeyPressed == SIMPAD_SWITCH_LOWER ) // SHIFT 1
231+ {
232+ qDebug( " shift mode 1" );
233+ switch(code)
234+ {
235+ case SIMPAD_SWITCH_UP: k = Qt::Key_F9; break; // Shift1-Up = Calendar
236+ case SIMPAD_SWITCH_DOWN: k = Qt::Key_F10; break; // Shift1-Down = Contacts
237+ case SIMPAD_SWITCH_LEFT: k = Qt::Key_F13; break; // Shift1-Left = Mail
238+ case SIMPAD_SWITCH_RIGHT: k = Qt::Key_F11; break; // Shift1-Up = Menu
239+ case SIMPAD_SWITCH_UPPER: k = Qt::Key_F12; break; // Shift1-Upper = Home
240+ default: k=-1; qWarning( "SimpadButtonsHandler() - unhandled event for Shift 1 !" ); break;
241+ }
242+ }
243+ else if ( shiftKeyPressed == SIMPAD_SWITCH_UPPER ) // SHIFT 2
244+ {
245+ qDebug( " shift mode 2" );
246+ switch(code)
247+ {
248+ case SIMPAD_SWITCH_UP: k = Qt::Key_F5; break; // Shift2-Up = F5
249+ case SIMPAD_SWITCH_DOWN: k = Qt::Key_F6; break; // Shift2-Down = F6
250+ case SIMPAD_SWITCH_LEFT: k = Qt::Key_F7; break; // Shift2-Left = F7
251+ case SIMPAD_SWITCH_RIGHT: k = Qt::Key_F8; break; // Shift2-Up = F8
252+ case SIMPAD_SWITCH_LOWER: k = Qt::Key_F9; break; // Shift2-Lower = F9
253+ default: k=-1; qWarning( "SimpadButtonsHandler() - unhandled event for Shift 2!" ); break;
254+ }
255+ }
256+ }
257+ else
258+ {
259+ qDebug( " shift key has been released. checking if being used..." );
260+ shiftKeyPressed = 0;
261+
262+ if ( !shiftUsed )
263+ {
264+ qDebug( " ... has _not_ being used -> really emit the key" );
265+ k = ( code == SIMPAD_SWITCH_UPPER ? Qt::Key_Escape : Qt::Key_Return );
266+ qDebug( "Emitting key = %d (pressed)", k );
267+ processKeyEvent( 0, k, 0, true, true );
268+ qDebug( "Emitting key = %d (released)", k );
269+ processKeyEvent( 0, k, 0, false, true );
270+ return;
271+ }
272+ else
273+ {
274+ qDebug( " ... has being used -> doing nothing" );
275+ return;
276+ }
277+ }
278+ }
279+ else
280+ {
281+ qDebug( "standard mode - no shift yet..." );
282+
283+ switch(code)
284+ {
285+ case SIMPAD_SWITCH_UP: k = Qt::Key_Up; break;
286+ case SIMPAD_SWITCH_DOWN: k = Qt::Key_Down; break;
287+ case SIMPAD_SWITCH_LEFT: k = Qt::Key_Left; break;
288+ case SIMPAD_SWITCH_RIGHT: k = Qt::Key_Right; break;
289+
290+ case SIMPAD_SWITCH_UPPER: k=-1; shiftKeyPressed = code; shiftUsed = false; return;
291+ case SIMPAD_SWITCH_LOWER: k=-1; shiftKeyPressed = code; shiftUsed = false; return;
292+
293+ default: k=-1; qWarning( "SimpadButtonsHandler() - unhandled event!" ); break;
294+ }
295+ }
296+
297+ if ( k == -1 )
298+ {
299+ qDebug( "no key to emit - returning." );
300+ return;
301+ }
302+
303+ bool repeatable = ( k == Qt::Key_Up || k == Qt::Key_Down ||
304+ k == Qt::Key_Right || k == Qt::Key_Left );
305+
306+ qDebug( "key to emit = %d [%s] [repeat=%s]", k,
307+ press ? "press" : "release",
308+ repeatable ? "true":"false" );
180+ 309+
181+ if ( qt_screen->isTransformed() && k >= Qt::Key_Left && k <= Qt::Key_Down ) 310+ if ( qt_screen->isTransformed() && k >= Qt::Key_Left && k <= Qt::Key_Down )
182+ { 311+ {
@@ -191,16 +320,15 @@
191+ else 320+ else
192+ repeater->stop(); 321+ repeater->stop();
193+ 322+
194+ if ( k >= 0 ) 323+ qwsServer->processKeyEvent( 0, k, 0, press, false );
195+ {
196+ qwsServer->processKeyEvent( 0, k, 0, press, false );
197+ }
198+} 324+}
199+ 325+
200+ 326+
201+void QWSsimpadButtonsHandler::autoRepeat() 327+void QWSsimpadButtonsHandler::autoRepeat()
202+{ 328+{
329+ qDebug( "Emitting key = %d (released)", k );
203+ processKeyEvent( 0, k, 0, false, true ); 330+ processKeyEvent( 0, k, 0, false, true );
331+ qDebug( "Emitting key = %d (pressed)", k );
204+ processKeyEvent( 0, k, 0, true, true ); 332+ processKeyEvent( 0, k, 0, true, true );
205+ repeater->start(repeatperiod); 333+ repeater->start(repeatperiod);
206+} 334+}