|
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // template\template_variant\specific\keyboard.cpp |
|
15 // Access to Template polled keyboard |
|
16 // The code here implements a simple polled keyboard driver. |
|
17 // This is an alternative to the interrupt-driven driver in keyboard_interrupt.cpp. |
|
18 // This example assumes that we have a non-intelligent keyboard |
|
19 // consisting of a number of i/o lines arranged in a grid. |
|
20 // You can use this code as a starting point and modify it to suit |
|
21 // your hardware. |
|
22 // |
|
23 // |
|
24 |
|
25 #include <template_assp.h> |
|
26 #include "platform.h" |
|
27 #include <kernel/kpower.h> |
|
28 #include <e32keys.h> |
|
29 |
|
30 |
|
31 |
|
32 // The TKeyboardState class is used to encapsulate the state of |
|
33 // the keyboard. i.e which keys are currently being pressed. |
|
34 // To determine which keys are being pressed, typically a voltage |
|
35 // is applied to each row in turn (or column, depending on the hardware) |
|
36 // and the output is read resulting in a bitmask for each row. |
|
37 // |
|
38 // For example, the keys could be arranged as follows (where a '1' indicates |
|
39 // that a key is currently being pressed : |
|
40 // EXAMPLE ONLY |
|
41 // |
|
42 // Translated |
|
43 // Column# 0 1 2 3 4 5 6 7 8 9 A B C D E F KeyCode |
|
44 // Row# |
|
45 // 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 60 to 6F |
|
46 // 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 to 5F |
|
47 // 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 40 to 4F |
|
48 // 3 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 30 to 3F |
|
49 // Input-> 2 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 20 to 2F |
|
50 // 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 to 1F |
|
51 // 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 to 0F |
|
52 // |
|
53 // output-> 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 |
|
54 // |
|
55 // TO DO: (mandadory) |
|
56 // Modify TKeyboardState (or provide an alternative) to model the |
|
57 // real keyboard state |
|
58 // |
|
59 // EXAMPLE ONLY |
|
60 class TKeyboardState |
|
61 { |
|
62 public: |
|
63 |
|
64 enum TDimensions |
|
65 { |
|
66 KRows = 7, |
|
67 KColumns = 16 |
|
68 }; |
|
69 |
|
70 public: |
|
71 TKeyboardState(); |
|
72 void Clear(); |
|
73 TBool IsKeyReady(); |
|
74 TUint32 GetKeyCode(); |
|
75 TKeyboardState operator&(const TKeyboardState& aState); |
|
76 TKeyboardState operator|(const TKeyboardState& aState); |
|
77 TKeyboardState operator~(); |
|
78 |
|
79 public: |
|
80 TUint32 iKeyBitMask[KRows]; |
|
81 }; |
|
82 |
|
83 /** |
|
84 Constructor |
|
85 */ |
|
86 TKeyboardState::TKeyboardState() |
|
87 { |
|
88 Clear(); |
|
89 } |
|
90 |
|
91 /** |
|
92 Clears the array of bitmasks |
|
93 */ |
|
94 void TKeyboardState::Clear() |
|
95 { |
|
96 for (TInt row=0; row<KRows; row++) |
|
97 iKeyBitMask[row] = 0; |
|
98 } |
|
99 |
|
100 /** |
|
101 Determines whether any keys are being pressed by examining the |
|
102 array of bitmasks to determine whether any bits are set |
|
103 |
|
104 @return ETrue if one or more keys are being pressed |
|
105 */ |
|
106 TBool TKeyboardState::IsKeyReady() |
|
107 { |
|
108 for (TInt row=0; row<KRows; row++) |
|
109 { |
|
110 if (iKeyBitMask[row] != 0) |
|
111 return ETrue; |
|
112 } |
|
113 |
|
114 return EFalse; |
|
115 } |
|
116 |
|
117 /** |
|
118 Scans the array of bitmasks and returns a keycode representing |
|
119 the first bit that it finds that is on. |
|
120 E.g. : |
|
121 if the first bit on the first row is set, then 1 is returned, |
|
122 if the third bit on the first row is set, then 3 is returned. etc. |
|
123 |
|
124 Once a bit is found it is cleared to avoid reading it again. |
|
125 |
|
126 NB Before calling this function, IsKeyReady() should be called |
|
127 to determine whether a key code is available. |
|
128 |
|
129 @return a 32-bit keycode representing a key that is currently pressed |
|
130 */ |
|
131 |
|
132 TUint32 TKeyboardState::GetKeyCode() |
|
133 { |
|
134 TInt keyNum = 0; |
|
135 for (TInt row=0; row<KRows; row++) |
|
136 { |
|
137 TUint32 bitMask = 1; |
|
138 for (TInt col=0; col<KColumns; col++) |
|
139 { |
|
140 if (iKeyBitMask[row] & bitMask) |
|
141 { |
|
142 iKeyBitMask[row] &= ~bitMask; |
|
143 return keyNum; |
|
144 } |
|
145 bitMask<<= 1; |
|
146 keyNum++; |
|
147 } |
|
148 } |
|
149 return 0; |
|
150 } |
|
151 |
|
152 /** |
|
153 Perform a bitwise AND between two TKeyboardState objects |
|
154 by AND-ing together all the 32-bit integers |
|
155 |
|
156 @return a new instance of a TKeyboardState object containing the result |
|
157 */ |
|
158 TKeyboardState TKeyboardState::operator&(const TKeyboardState& aState) |
|
159 { |
|
160 TKeyboardState state = *this; |
|
161 |
|
162 for (TInt row=0; row<KRows; row++) |
|
163 state.iKeyBitMask[row]&= aState.iKeyBitMask[row];; |
|
164 |
|
165 return state; |
|
166 } |
|
167 |
|
168 /** |
|
169 Perform a bitwise OR between two TKeyboardState objects |
|
170 by OR-ing together all the 32-bit integers |
|
171 |
|
172 @return a new instance of a TKeyboardState object containing the result |
|
173 */ |
|
174 TKeyboardState TKeyboardState::operator|(const TKeyboardState& aState) |
|
175 { |
|
176 TKeyboardState state = *this; |
|
177 |
|
178 for (TInt row=0; row<KRows; row++) |
|
179 state.iKeyBitMask[row]|= aState.iKeyBitMask[row];; |
|
180 |
|
181 return state; |
|
182 } |
|
183 |
|
184 /** |
|
185 Perform a bitwise NOT (one's complement) of a KeyboardState object |
|
186 by NOT-ing all the 32-bit integers |
|
187 |
|
188 @return a new instance of a TKeyboardState object containing the result |
|
189 */ |
|
190 TKeyboardState TKeyboardState::operator~() |
|
191 { |
|
192 TKeyboardState state = *this; |
|
193 |
|
194 for (TInt row=0; row<KRows; row++) |
|
195 state.iKeyBitMask[row] = ~state.iKeyBitMask[row]; |
|
196 |
|
197 return state; |
|
198 } |
|
199 |
|
200 // |
|
201 // |
|
202 // TO DO: (optional) |
|
203 // |
|
204 // Modify this conversion table to suit your keyboard layout |
|
205 // EXAMPLE ONLY |
|
206 // |
|
207 |
|
208 const TUint8 convertCode[] = |
|
209 { |
|
210 //Row 0 (bottom row) |
|
211 EStdKeyLeftAlt , EStdKeyHash , EStdKeyNull , EStdKeyLeftCtrl , |
|
212 EStdKeyLeftFunc , EStdKeyEscape , '1' , '2' , |
|
213 '9' , '0' , EStdKeyMinus , EStdKeyEquals , |
|
214 EStdKeyNull , EStdKeyBackspace , EStdKeyNull , EStdKeyNull , |
|
215 //Row 1 |
|
216 EStdKeyNull , EStdKeyBackSlash , EStdKeyLeftShift , EStdKeyNull , |
|
217 EStdKeyNull , EStdKeyDelete , EStdKeyNull , 'T' , |
|
218 'Y' , 'U' , 'I' , EStdKeyEnter , |
|
219 EStdKeyRightShift , EStdKeyDownArrow , EStdKeyNull , EStdKeyNull , |
|
220 //Row 2 |
|
221 EStdKeyNull , EStdKeyTab , EStdKeyNull , EStdKeyNull , |
|
222 EStdKeyNull , 'Q' , 'W' , 'E' , |
|
223 'R' , 'O' , 'P' , EStdKeySquareBracketLeft , |
|
224 EStdKeyNull , EStdKeySquareBracketRight,EStdKeyNull , EStdKeyNull , |
|
225 //Row 3 |
|
226 EStdKeyNull , 'Z' , EStdKeyNull , EStdKeyNull , |
|
227 EStdKeyNull , EStdKeyCapsLock , EStdKeyNull , EStdKeyNull , |
|
228 'K' , 'L' , EStdKeySemiColon , EStdKeySingleQuote , |
|
229 EStdKeyNull , EStdKeyUpArrow , EStdKeyNull , EStdKeyNull , |
|
230 //Row 4 |
|
231 EStdKeyNull , EStdKeyTab , EStdKeyNull , EStdKeyNull, |
|
232 EStdKeyNull , 'Q' , 'W' , 'E' , |
|
233 'R' , 'O' , 'P' , EStdKeySquareBracketLeft , |
|
234 EStdKeyNull , EStdKeySquareBracketRight, EStdKeyNull , EStdKeyNull , |
|
235 //Row 5 |
|
236 EStdKeyNull , 'X' , EStdKeyNull , EStdKeyNull , |
|
237 EStdKeyNull , 'C' , 'V' , 'B' , |
|
238 'N' , 'M' , EStdKeyComma , EStdKeyFullStop , |
|
239 EStdKeyNull , EStdKeySpace , EStdKeyNull , EStdKeyNull , |
|
240 //Row 6 |
|
241 EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , |
|
242 EStdKeyNull , '3' , '4' , '5' , |
|
243 '6' , '7' , '8' , EStdKeyMenu , |
|
244 EStdKeyNull , EStdKeyRightArrow , EStdKeyNull , EStdKeyNull |
|
245 }; |
|
246 |
|
247 |
|
248 |
|
249 |
|
250 // EXAMPLE ONLY |
|
251 const TKeyboard KConfigKeyboardType = EKeyboard_Full; |
|
252 const TInt KConfigKeyboardDeviceKeys = 0; |
|
253 const TInt KConfigKeyboardAppsKeys = 0; |
|
254 |
|
255 |
|
256 // |
|
257 // TO DO: (optional) |
|
258 // |
|
259 // Set the keyboard scan rate in milliseconds |
|
260 // |
|
261 |
|
262 // EXAMPLE ONLY |
|
263 const TInt KScanRate = 50; // poll every 1/20 of a second (i.e. every 50 milliseconds) |
|
264 |
|
265 |
|
266 _LIT(KLitKeyboard,"Keyboard"); |
|
267 |
|
268 |
|
269 // |
|
270 // TO DO: (optional) |
|
271 // |
|
272 // Add any private functions and data you require |
|
273 // |
|
274 NONSHARABLE_CLASS(DKeyboardTemplate) : public DPowerHandler |
|
275 { |
|
276 public: |
|
277 DKeyboardTemplate(); |
|
278 TInt Create(); |
|
279 |
|
280 // from DPowerHandler |
|
281 void PowerUp(); |
|
282 void PowerDown(TPowerState); |
|
283 |
|
284 private: |
|
285 static void HandleMessage(TAny* aPtr); |
|
286 void HandleMsg(TMessageBase* aMsg); |
|
287 |
|
288 static TInt HalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2); |
|
289 TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2); |
|
290 |
|
291 static void PowerUpDfcFn(TAny* aPtr); |
|
292 void PowerUpDfc(); |
|
293 |
|
294 static void PowerDownDfcFn(TAny* aPtr); |
|
295 void PowerDownDfc(); |
|
296 |
|
297 static void TimerCallback(TAny* aDriver); |
|
298 static void TimerDfcFn(TAny* aDriver); |
|
299 void Poll(); |
|
300 |
|
301 void KeyboardInfo(TKeyboardInfoV01& aInfo); |
|
302 |
|
303 void KeyboardOn(); |
|
304 void KeyboardOff(); |
|
305 void KeyboardPowerUp(); |
|
306 |
|
307 private: |
|
308 TDfcQue* iDfcQ; |
|
309 TMessageQue iMsgQ; |
|
310 TDfc iPowerUpDfc; |
|
311 TDfc iPowerDownDfc; |
|
312 TBool iKeyboardOn; |
|
313 NTimer iTimer; |
|
314 TInt iTimerTicks; |
|
315 TDfc iTimerDfc; |
|
316 |
|
317 // a bitmask indicating which keys were pressed down on the last timer tick |
|
318 TKeyboardState iKeyStateLast; |
|
319 |
|
320 // a bitmask indicating the set of keys for which we have sent an EKeyDown event |
|
321 TKeyboardState iKeysDown; |
|
322 }; |
|
323 |
|
324 /** |
|
325 constructor |
|
326 */ |
|
327 DKeyboardTemplate::DKeyboardTemplate() |
|
328 : DPowerHandler(KLitKeyboard), |
|
329 iMsgQ(HandleMessage, this, NULL, 1), |
|
330 iPowerUpDfc(PowerUpDfcFn, this, 6), |
|
331 iPowerDownDfc(PowerDownDfcFn, this, 7), |
|
332 iTimer(&DKeyboardTemplate::TimerCallback, (TAny*) this), |
|
333 iTimerDfc(TimerDfcFn, this, 1) |
|
334 { |
|
335 // Convert the scan rate from milliseconds to nanokernel ticks (normally 1/64 of a second) |
|
336 iTimerTicks = NKern::TimerTicks(KScanRate); |
|
337 } |
|
338 |
|
339 /** |
|
340 Second-phase constructor |
|
341 Assigns queues for all the DFCs and starts the keyboard-polling timer |
|
342 |
|
343 Called by factory function at ordinal 0 |
|
344 */ |
|
345 TInt DKeyboardTemplate::Create() |
|
346 { |
|
347 iDfcQ=Kern::DfcQue0(); |
|
348 |
|
349 iKeyboardOn = EFalse; |
|
350 |
|
351 // install the HAL function |
|
352 TInt r = Kern::AddHalEntry(EHalGroupKeyboard, DKeyboardTemplate::HalFunction, this); |
|
353 if (r != KErrNone) |
|
354 return r; |
|
355 |
|
356 iTimerDfc.SetDfcQ(iDfcQ); |
|
357 |
|
358 iPowerUpDfc.SetDfcQ(iDfcQ); |
|
359 iPowerDownDfc.SetDfcQ(iDfcQ); |
|
360 iMsgQ.SetDfcQ(iDfcQ); |
|
361 iMsgQ.Receive(); |
|
362 |
|
363 // install the power handler |
|
364 Add(); |
|
365 |
|
366 // Power up the device and start the timer |
|
367 KeyboardPowerUp(); |
|
368 |
|
369 return r; |
|
370 } |
|
371 |
|
372 /** |
|
373 Calback for the keyboard-polling timer |
|
374 Called in the context of an ISR |
|
375 |
|
376 @param aPtr A pointer to an instance of DKeyboardTemplate |
|
377 */ |
|
378 void DKeyboardTemplate::TimerCallback(TAny *aPtr) |
|
379 { |
|
380 // schedule a DFC |
|
381 DKeyboardTemplate& k=*(DKeyboardTemplate*)aPtr; |
|
382 k.iTimerDfc.Add(); |
|
383 } |
|
384 |
|
385 |
|
386 /** |
|
387 DFC scheduled by the keyboard-polling timer when it expires |
|
388 |
|
389 @param aPtr A pointer to an instance of DKeyboardTemplate |
|
390 */ |
|
391 void DKeyboardTemplate::TimerDfcFn(TAny* aPtr) |
|
392 { |
|
393 ((DKeyboardTemplate*)aPtr)->Poll(); |
|
394 } |
|
395 |
|
396 |
|
397 /** |
|
398 Reads scan codes from the keyboard until there are none left |
|
399 Called from the keyboard-polling timer's DFC |
|
400 */ |
|
401 void DKeyboardTemplate::Poll() |
|
402 { |
|
403 __KTRACE_OPT(KHARDWARE,Kern::Printf("DKeyboardTemplate::EventDfc")); |
|
404 |
|
405 |
|
406 TKeyboardState keyState; |
|
407 |
|
408 // |
|
409 // TO DO: (mandatory) |
|
410 // Read new key state into the array of bitmasks in keyState |
|
411 // This typically involves applying a voltage to each row from 0 to KRows-1, |
|
412 // reading the output state of the i/o lines at every step |
|
413 // - this represents the keys that are pressed on each row - |
|
414 // and storing the output of each row as a bitmask into keyState.iKeyBitMask[n], |
|
415 // where n = the row being accessed |
|
416 // |
|
417 |
|
418 // To enable a simple de-bouncing algorithm, |
|
419 // work out which keys have been pressed down for at least two timer |
|
420 // ticks by AND-ing together the last bitmask with the current bitmask |
|
421 TKeyboardState keysStillDown = keyState & iKeyStateLast; |
|
422 |
|
423 |
|
424 // Similarly, work out which keys have been "un-pressed" for at least two timer |
|
425 // ticks by AND-ing together the one's complement of the last bitmask with the |
|
426 // one's complement of the current bitmask and |
|
427 // then AND-ing this with the set of keys for which we have sent an EKeyDown |
|
428 // event to give the set of keys for which we need to send an EKeyUp event |
|
429 TKeyboardState keysStillUp = (~keyState & ~iKeyStateLast) & iKeysDown; |
|
430 |
|
431 // save the current state for next time |
|
432 iKeyStateLast = keyState; |
|
433 |
|
434 // update the set of keys for which we have sent an EKeyDown event |
|
435 iKeysDown = iKeysDown | keysStillDown; |
|
436 iKeysDown = iKeysDown & ~keysStillUp; |
|
437 |
|
438 // process all the key-down events |
|
439 while (keysStillDown.IsKeyReady()) // while there are keys we haven't processed |
|
440 { |
|
441 TRawEvent e; |
|
442 TUint keyCode = keysStillDown.GetKeyCode(); // Read keycodes from bitmask |
|
443 |
|
444 __KTRACE_OPT(KHARDWARE,Kern::Printf("EKeyDown: #%02x\n",keyCode)); |
|
445 |
|
446 // |
|
447 // TO DO: (mandatory) |
|
448 // |
|
449 // Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released) |
|
450 // as per below EXAMPLE ONLY: |
|
451 // |
|
452 __ASSERT_DEBUG(keyCode < (sizeof(convertCode) / sizeof(TUint8)), Kern::Fault("Keyboard", __LINE__)); |
|
453 TUint8 stdKey = convertCode[keyCode]; |
|
454 |
|
455 e.Set(TRawEvent::EKeyDown, stdKey, 0); |
|
456 Kern::AddEvent(e); |
|
457 } |
|
458 |
|
459 // process all the key-up events |
|
460 while (keysStillUp.IsKeyReady()) // while there are keys we haven't processed |
|
461 { |
|
462 TRawEvent e; |
|
463 TUint keyCode = keysStillUp.GetKeyCode(); // Read keycodes from bitmask |
|
464 |
|
465 __KTRACE_OPT(KHARDWARE,Kern::Printf("EKeyUp: #%02x\n",keyCode)); |
|
466 |
|
467 // |
|
468 // TO DO: (mandatory) |
|
469 // |
|
470 // Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released) |
|
471 // as per below EXAMPLE ONLY: |
|
472 // |
|
473 __ASSERT_DEBUG(keyCode < (sizeof(convertCode) / sizeof(TUint8)), Kern::Fault("Keyboard", __LINE__)); |
|
474 TUint8 stdKey = convertCode[keyCode]; |
|
475 |
|
476 e.Set(TRawEvent::EKeyUp, stdKey, 0); |
|
477 Kern::AddEvent(e); |
|
478 } |
|
479 |
|
480 // start the timer again |
|
481 iTimer.OneShot(iTimerTicks); |
|
482 } |
|
483 |
|
484 |
|
485 |
|
486 /** |
|
487 Notifies the peripheral of system power up. |
|
488 Called by the power manager during a transition from standby. |
|
489 Schedules a DFC to handle the power up. |
|
490 */ |
|
491 void DKeyboardTemplate::PowerUp() |
|
492 { |
|
493 iPowerUpDfc.Enque(); |
|
494 } |
|
495 |
|
496 |
|
497 /** |
|
498 static DFC to handle powering up the keyboard |
|
499 |
|
500 @param aPtr A pointer to an instance of DKeyboardTemplate |
|
501 */ |
|
502 void DKeyboardTemplate::PowerUpDfcFn(TAny* aPtr) |
|
503 { |
|
504 ((DKeyboardTemplate*)aPtr)->PowerUpDfc(); |
|
505 } |
|
506 |
|
507 |
|
508 /** |
|
509 DFC to handle powering up the keyboard |
|
510 */ |
|
511 void DKeyboardTemplate::PowerUpDfc() |
|
512 { |
|
513 __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardTemplate::PowerUpDfc()")); |
|
514 KeyboardOn(); |
|
515 |
|
516 // Indicate to power handle that powered up is complete |
|
517 PowerUpDone(); |
|
518 } |
|
519 |
|
520 /** |
|
521 Powers up the keyboard |
|
522 May be called as a result of a power transition or from the HAL |
|
523 */ |
|
524 void DKeyboardTemplate::KeyboardOn() |
|
525 { |
|
526 __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardOn() iKeyboardOn=%d", iKeyboardOn)); |
|
527 |
|
528 if (!iKeyboardOn) // make sure we don't initialize more than once |
|
529 KeyboardPowerUp(); |
|
530 } |
|
531 |
|
532 /** |
|
533 Powers up the keyboard |
|
534 Assumes that the keyboard is currently powered off |
|
535 */ |
|
536 void DKeyboardTemplate::KeyboardPowerUp() |
|
537 { |
|
538 __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardPowerUp()")); |
|
539 |
|
540 iKeyboardOn = ETrue; |
|
541 |
|
542 iKeyStateLast.Clear(); |
|
543 iKeysDown.Clear(); |
|
544 |
|
545 // Send key up events for EStdKeyOff (Fn+Esc) event |
|
546 TRawEvent e; |
|
547 e.Set(TRawEvent::EKeyUp,EStdKeyEscape,0); |
|
548 Kern::AddEvent(e); |
|
549 e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0); |
|
550 Kern::AddEvent(e); |
|
551 |
|
552 // Start the periodic tick for the selected rate. |
|
553 // This will call TimerCallback() in the context of an ISR |
|
554 iTimer.OneShot(iTimerTicks); |
|
555 } |
|
556 |
|
557 |
|
558 /** |
|
559 Requests keyboard to power down. |
|
560 Called by the power manager during a transition to standby or power off |
|
561 Schedules a DFC to handle the power up. |
|
562 |
|
563 @param aPowerState the current power state |
|
564 */ |
|
565 void DKeyboardTemplate::PowerDown(TPowerState) |
|
566 { |
|
567 iPowerDownDfc.Enque(); |
|
568 } |
|
569 |
|
570 /** |
|
571 static DFC to handle powering down the keyboard |
|
572 |
|
573 @param aPtr A pointer to an instance of DKeyboardTemplate |
|
574 */ |
|
575 void DKeyboardTemplate::PowerDownDfcFn(TAny* aPtr) |
|
576 { |
|
577 ((DKeyboardTemplate*)aPtr)->PowerDownDfc(); |
|
578 } |
|
579 |
|
580 /** |
|
581 DFC to handle powering down the keyboard |
|
582 */ |
|
583 void DKeyboardTemplate::PowerDownDfc() |
|
584 { |
|
585 __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardTemplate::PowerDownDfc()")); |
|
586 KeyboardOff(); |
|
587 PowerDownDone(); |
|
588 } |
|
589 |
|
590 /** |
|
591 Powers down the keyboard |
|
592 May be called as a result of a power transition or from the HAL |
|
593 */ |
|
594 void DKeyboardTemplate::KeyboardOff() |
|
595 { |
|
596 __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardOff() iKeyboardOn=%d", iKeyboardOn)); |
|
597 |
|
598 // cancel the keyboard-polling timer |
|
599 iTimerDfc.Cancel(); |
|
600 iTimer.Cancel(); |
|
601 |
|
602 iKeyboardOn = EFalse; |
|
603 } |
|
604 |
|
605 |
|
606 /** |
|
607 static message handler for processing power up/down messages |
|
608 posted internally from HalFunction() |
|
609 |
|
610 @param aPtr A pointer to an instance of DKeyboardTemplate |
|
611 */ |
|
612 void DKeyboardTemplate::HandleMessage(TAny* aPtr) |
|
613 { |
|
614 DKeyboardTemplate& h=*(DKeyboardTemplate*)aPtr; |
|
615 TMessageBase* pM=h.iMsgQ.iMessage; |
|
616 if (pM) |
|
617 h.HandleMsg(pM); |
|
618 } |
|
619 |
|
620 /** |
|
621 Message handler for processing power up/down messages |
|
622 posted internally from HalFunction() |
|
623 |
|
624 param aMsg A message indicating whether to power the keyboard on or off |
|
625 */ |
|
626 void DKeyboardTemplate::HandleMsg(TMessageBase* aMsg) |
|
627 { |
|
628 if (aMsg->iValue) |
|
629 KeyboardOn(); |
|
630 else |
|
631 KeyboardOff(); |
|
632 aMsg->Complete(KErrNone,ETrue); |
|
633 } |
|
634 |
|
635 |
|
636 /** |
|
637 Retrieves information about the keyboard |
|
638 Called from HalFunction() |
|
639 |
|
640 @param aInfo a caller-supplied class which on return contains information about the keyboard |
|
641 */ |
|
642 void DKeyboardTemplate::KeyboardInfo(TKeyboardInfoV01& aInfo) |
|
643 { |
|
644 __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardTemplate::KeyboardInfo")); |
|
645 aInfo.iKeyboardType=KConfigKeyboardType; |
|
646 aInfo.iDeviceKeys=KConfigKeyboardDeviceKeys; |
|
647 aInfo.iAppsKeys=KConfigKeyboardAppsKeys; |
|
648 } |
|
649 |
|
650 |
|
651 /** |
|
652 HAL handler function |
|
653 |
|
654 @param aPtr a pointer to an instance of DLcdPowerHandler |
|
655 @param aFunction the function number |
|
656 @param a1 an arbitrary parameter |
|
657 @param a2 an arbitrary parameter |
|
658 */ |
|
659 TInt DKeyboardTemplate::HalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) |
|
660 { |
|
661 DKeyboardTemplate* pH=(DKeyboardTemplate*)aPtr; |
|
662 return pH->HalFunction(aFunction,a1,a2); |
|
663 } |
|
664 |
|
665 |
|
666 /** |
|
667 a HAL entry handling function for HAL group attribute EHalGroupKeyboard |
|
668 |
|
669 @param a1 an arbitrary argument |
|
670 @param a2 an arbitrary argument |
|
671 @return KErrNone if successful |
|
672 */ |
|
673 TInt DKeyboardTemplate::HalFunction(TInt aFunction, TAny* a1, TAny* a2) |
|
674 { |
|
675 TInt r=KErrNone; |
|
676 |
|
677 __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardTemplate::HalFunction %d", aFunction)); |
|
678 |
|
679 switch(aFunction) |
|
680 { |
|
681 case EKeyboardHalKeyboardInfo: |
|
682 { |
|
683 TPckgBuf<TKeyboardInfoV01> kPckg; |
|
684 KeyboardInfo(kPckg()); |
|
685 Kern::InfoCopy(*(TDes8*)a1,kPckg); |
|
686 break; |
|
687 } |
|
688 |
|
689 case EKeyboardHalSetKeyboardState: |
|
690 { |
|
691 if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EKeyboardHalSetKeyboardState"))) |
|
692 return KErrPermissionDenied; |
|
693 if ((TBool)a1) |
|
694 { |
|
695 TThreadMessage& m=Kern::Message(); |
|
696 m.iValue = ETrue; |
|
697 m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered up |
|
698 } |
|
699 else |
|
700 { |
|
701 TThreadMessage& m=Kern::Message(); |
|
702 m.iValue = EFalse; |
|
703 m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered down |
|
704 } |
|
705 } |
|
706 break; |
|
707 |
|
708 case EKeyboardHalKeyboardState: |
|
709 kumemput32(a1, &iKeyboardOn, sizeof(TBool)); |
|
710 break; |
|
711 |
|
712 default: |
|
713 r=KErrNotSupported; |
|
714 break; |
|
715 } |
|
716 return r; |
|
717 } |
|
718 |
|
719 |
|
720 |
|
721 DECLARE_STANDARD_EXTENSION() |
|
722 { |
|
723 __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver")); |
|
724 |
|
725 // create keyboard driver |
|
726 TInt r=KErrNoMemory; |
|
727 DKeyboardTemplate* pK=new DKeyboardTemplate; |
|
728 if (pK) |
|
729 r=pK->Create(); |
|
730 |
|
731 __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r)); |
|
732 return r; |
|
733 } |