BGE patch: add state engine support in the logic bricks.
[blender.git] / source / gameengine / GameLogic / SCA_KeyboardSensor.cpp
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  * Sensor for keyboard input
29  */
30 #include "SCA_KeyboardSensor.h"
31 #include "SCA_KeyboardManager.h"
32 #include "SCA_LogicManager.h"
33 #include "StringValue.h"
34 #include "SCA_IInputDevice.h"
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 /* ------------------------------------------------------------------------- */
41 /* Native functions                                                          */
42 /* ------------------------------------------------------------------------- */
43
44 SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr,
45                                                                            short int hotkey,
46                                                                            short int qual,
47                                                                            short int qual2,
48                                                                            bool bAllKeys,
49                                                                            const STR_String& targetProp,
50                                                                            const STR_String& toggleProp,
51                                                                            SCA_IObject* gameobj,
52                                                                            PyTypeObject* T )
53         :SCA_ISensor(gameobj,keybdmgr,T),
54          m_pKeyboardMgr(keybdmgr),
55          m_hotkey(hotkey),
56          m_qual(qual),
57          m_qual2(qual2),
58          m_bAllKeys(bAllKeys),
59          m_targetprop(targetProp),
60          m_toggleprop(toggleProp)
61 {
62         if (hotkey == SCA_IInputDevice::KX_ESCKEY)
63                 keybdmgr->GetInputDevice()->HookEscape();
64 //      SetDrawColor(0xff0000ff);
65         Init();
66 }
67
68
69
70 SCA_KeyboardSensor::~SCA_KeyboardSensor()
71 {
72 }
73
74 void SCA_KeyboardSensor::Init()
75 {
76         // this function is used when the sensor is disconnected from all controllers
77         // by the state engine. It reinitializes the sensor as if it was just created.
78         // However, if the target key is pressed when the sensor is reactivated, it
79         // will not generated an event (see remark in Evaluate()).
80         m_val = 0;
81 }
82
83 CValue* SCA_KeyboardSensor::GetReplica()
84 {
85         CValue* replica = new SCA_KeyboardSensor(*this);
86         // this will copy properties and so on...
87         CValue::AddDataToReplica(replica);
88
89         return replica;
90 }
91
92
93
94 short int SCA_KeyboardSensor::GetHotkey()
95 {
96         return m_hotkey;
97 }
98
99
100
101 bool SCA_KeyboardSensor::IsPositiveTrigger()
102
103         bool result = (m_val != 0);
104
105         if (m_invert)
106                 result = !result;
107                 
108         return result;
109 }
110
111
112
113 bool SCA_KeyboardSensor::TriggerOnAllKeys()
114
115         return m_bAllKeys;
116 }
117
118
119
120 bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
121 {
122         bool result    = false;
123         SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
124         
125         //      cerr << "SCA_KeyboardSensor::Eval event, sensing for "<< m_hotkey << " at device " << inputdev << "\n";
126
127         /* See if we need to do logging: togPropState exists and is
128      * different from 0 */
129         CValue* myparent = GetParent();
130         CValue* togPropState = myparent->GetProperty(m_toggleprop);
131         if (togPropState &&
132                 (((int)togPropState->GetNumber()) != 0) )
133         {
134                 LogKeystrokes();
135         }
136
137
138
139         /* Now see whether events must be bounced. */
140         if (m_bAllKeys)
141         {
142                 bool justactivated = false;
143                 bool justreleased = false;
144                 bool active = false;
145
146                 for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
147                 {
148                         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
149                         switch (inevent.m_status) 
150                         { 
151                         case SCA_InputEvent::KX_JUSTACTIVATED:
152                                 justactivated = true;
153                                 break;
154                         case SCA_InputEvent::KX_JUSTRELEASED:
155                                 justreleased = true;
156                                 break;
157                         case SCA_InputEvent::KX_ACTIVE:
158                                 active = true;
159                                 break;
160                         }
161                 }
162
163                 if (justactivated)
164                 {
165                         m_val=1;
166                         result = true;
167                 } else
168                 {
169                         if (justreleased)
170                         {
171                                 m_val=(active)?1:0;
172                                 result = true;
173                         } else
174                         {
175                                 if (active)
176                                 {
177                                         if (m_val == 0)
178                                         {
179                                                 //see comment below
180                                                 //m_val = 1;
181                                                 //result = true;
182                                                 ;
183                                         }
184                                 } else
185                                 {
186                                         if (m_val == 1)
187                                         {
188                                                 m_val = 0;
189                                                 result = true;
190                                         }
191                                 }
192                         }
193                 }
194
195
196         } else
197         {
198
199         //              cerr << "======= SCA_KeyboardSensor::Evaluate:: peeking at key status" << endl;
200                 const SCA_InputEvent & inevent = inputdev->GetEventValue(
201                         (SCA_IInputDevice::KX_EnumInputs) m_hotkey);
202         
203         //              cerr << "======= SCA_KeyboardSensor::Evaluate:: status: " << inevent.m_status << endl;
204
205                 if (inevent.m_status == SCA_InputEvent::KX_NO_INPUTSTATUS)
206                 {
207                         if (m_val == 1)
208                         {
209                                 // this situation may occur after a scene suspend: the keyboard release 
210                                 // event was not captured, produce now the event off
211                                 m_val = 0;
212                                 result = true;
213                         }
214                 } else
215                 {
216                         if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
217                         {
218                                 m_val=1;
219                                 result = true;
220                         } else
221                         {
222                                 if (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)
223                                 {
224                                         m_val = 0;
225                                         result = true;
226                                 } else 
227                                 {
228                                         if (inevent.m_status == SCA_InputEvent::KX_ACTIVE)
229                                         {
230                                                 if (m_val == 0)
231                                                 {
232                                                         //hmm, this abnormal situation may occur in the following cases:
233                                                         //- the key was pressed while the scene was suspended
234                                                         //- this is a new scene and the key is active from the start
235                                                         //In the second case, it's dangerous to activate the sensor
236                                                         //(think of a key to go to next scene)
237                                                         //What we really need is a edge/level flag in the key sensor
238                                                         //m_val = 1;
239                                                         //result = true;
240                                                         ;
241                                                 }
242                                         }
243                                 }
244                         }
245                 }
246         }
247
248         return result;
249
250 }
251
252 void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
253 {
254         if (IsPrintable(keyIndex)) {
255                 CValue* tprop = GetParent()->GetProperty(m_targetprop);
256                 
257                 if (tprop) {
258                         /* overwrite the old property */
259                         if (IsDelete(keyIndex)) {
260                                 /* strip one char, if possible */
261                                 STR_String newprop = tprop->GetText();
262                                 int oldlength = newprop.Length();
263                                 if (oldlength >= 1 ) {
264                                         newprop.SetLength(oldlength - 1);
265                                         CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
266                                         GetParent()->SetProperty(m_targetprop, newstringprop);
267                                         newstringprop->Release();
268                                 }                               
269                         } else {
270                                 /* append */
271                                 char pchar = ToCharacter(keyIndex, IsShifted());
272                                 STR_String newprop = tprop->GetText() + pchar;
273                                 CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);                 
274                                 GetParent()->SetProperty(m_targetprop, newstringprop);
275                                 newstringprop->Release();
276                         }
277                 } else {
278                         if (!IsDelete(keyIndex)) {
279                                 /* Make a new property. Deletes can be ignored. */
280                                 char pchar = ToCharacter(keyIndex, IsShifted());
281                                 STR_String newprop = pchar;
282                                 CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);                 
283                                 GetParent()->SetProperty(m_targetprop, newstringprop);
284                                 newstringprop->Release();
285                         }
286                 }
287         }
288         
289 }
290
291 /**
292  * Determine whether this character can be printed. We cannot use
293  * the library functions here, because we need to test our own
294  * keycodes. */
295 bool SCA_KeyboardSensor::IsPrintable(int keyIndex)
296 {
297         /* only print 
298          * - numerals: KX_ZEROKEY to KX_NINEKEY
299          * - alphas:   KX_AKEY to KX_ZKEY. 
300          * - specials: KX_RETKEY, KX_PADASTERKEY, KX_PADCOMMAKEY to KX_PERIODKEY,
301          *             KX_TABKEY , KX_SEMICOLONKEY to KX_RIGHTBRACKETKEY, 
302          *             KX_PAD2 to KX_PADPLUSKEY
303          * - delete and backspace: also printable in the sense that they modify 
304          *                         the string
305          * - retkey: should this be printable?
306          * - virgule: prints a space... don't know which key that's supposed
307          *   to be...
308          */
309         if ( ((keyIndex >= SCA_IInputDevice::KX_ZEROKEY) 
310                   && (keyIndex <= SCA_IInputDevice::KX_NINEKEY))
311                  || ((keyIndex >= SCA_IInputDevice::KX_AKEY) 
312                          && (keyIndex <= SCA_IInputDevice::KX_ZKEY)) 
313                  || (keyIndex == SCA_IInputDevice::KX_SPACEKEY) 
314 /*                       || (keyIndex == KX_RETKEY)  */
315                  || (keyIndex == SCA_IInputDevice::KX_PADASTERKEY) 
316                  || (keyIndex == SCA_IInputDevice::KX_TABKEY) 
317                  || ((keyIndex >= SCA_IInputDevice::KX_COMMAKEY) 
318                          && (keyIndex <= SCA_IInputDevice::KX_PERIODKEY)) 
319                  || ((keyIndex >= SCA_IInputDevice::KX_SEMICOLONKEY) 
320                          && (keyIndex <= SCA_IInputDevice::KX_RIGHTBRACKETKEY)) 
321                  || ((keyIndex >= SCA_IInputDevice::KX_PAD2) 
322                          && (keyIndex <= SCA_IInputDevice::KX_PADPLUSKEY)) 
323                  || (keyIndex == SCA_IInputDevice::KX_DELKEY)
324                  || (keyIndex == SCA_IInputDevice::KX_BACKSPACEKEY)                              
325                 )
326         {
327                 return true;
328         } else {
329                 return false;
330         }
331 }
332
333 // this code looks ugly, please use an ordinary hashtable
334
335 char SCA_KeyboardSensor::ToCharacter(int keyIndex, bool shifted)
336 {
337         /* numerals */
338         if ( (keyIndex >= SCA_IInputDevice::KX_ZEROKEY) 
339                  && (keyIndex <= SCA_IInputDevice::KX_NINEKEY) ) {
340                 if (shifted) {
341                         char numshift[] = ")!@#$%^&*(";
342                         return numshift[keyIndex - '0']; 
343                 } else {
344                         return keyIndex - SCA_IInputDevice::KX_ZEROKEY + '0'; 
345                 }
346         }
347         
348         /* letters... always lowercase... is that desirable? */
349         if ( (keyIndex >= SCA_IInputDevice::KX_AKEY) 
350                  && (keyIndex <= SCA_IInputDevice::KX_ZKEY) ) {
351                 if (shifted) {
352                         return keyIndex - SCA_IInputDevice::KX_AKEY + 'A'; 
353                 } else {
354                         return keyIndex - SCA_IInputDevice::KX_AKEY + 'a'; 
355                 }
356         }
357         
358         if (keyIndex == SCA_IInputDevice::KX_SPACEKEY) {
359                 return ' ';
360         }
361         
362 /*                       || (keyIndex == SCA_IInputDevice::KX_RETKEY)  */
363         
364         if (keyIndex == SCA_IInputDevice::KX_PADASTERKEY) {
365                 return '*';
366         }
367         
368         if (keyIndex == SCA_IInputDevice::KX_TABKEY) {
369                 return '\t';
370         }
371         
372         /* comma to period */
373         char commatoperiod[] = ",-.";
374         char commatoperiodshifted[] = "<_>";
375         if (keyIndex == SCA_IInputDevice::KX_COMMAKEY) {
376                 if (shifted) {
377                         return commatoperiodshifted[0];
378                 } else {
379                         return commatoperiod[0];
380                 }
381         }
382         if (keyIndex == SCA_IInputDevice::KX_MINUSKEY) {
383                 if (shifted) {
384                         return commatoperiodshifted[1];
385                 } else {
386                         return commatoperiod[1];
387                 }
388         }
389         if (keyIndex == SCA_IInputDevice::KX_PERIODKEY) {
390                 if (shifted) {
391                         return commatoperiodshifted[2];
392                 } else {
393                         return commatoperiod[2];
394                 }
395         }
396         
397         /* semicolon to rightbracket */
398         char semicolontorightbracket[] = ";\'` /\\=[]";
399         char semicolontorightbracketshifted[] = ":\"~ \?|+{}";
400         if ((keyIndex >= SCA_IInputDevice::KX_SEMICOLONKEY) 
401                 && (keyIndex <= SCA_IInputDevice::KX_RIGHTBRACKETKEY)) {
402                 if (shifted) {
403                         return semicolontorightbracketshifted[keyIndex - SCA_IInputDevice::KX_SEMICOLONKEY];
404                 } else {
405                         return semicolontorightbracket[keyIndex - SCA_IInputDevice::KX_SEMICOLONKEY];
406                 }
407         }
408         
409         /* keypad2 to padplus */
410         char pad2topadplus[] = "246813579. 0- +";
411         if ((keyIndex >= SCA_IInputDevice::KX_PAD2) 
412                 && (keyIndex <= SCA_IInputDevice::KX_PADPLUSKEY)) { 
413                 return pad2topadplus[keyIndex - SCA_IInputDevice::KX_PAD2];
414         }
415
416         return '!';
417 }
418         
419 /**
420  * Tests whether this is a delete key.
421  */     
422 bool SCA_KeyboardSensor::IsDelete(int keyIndex)
423 {
424         if ( (keyIndex == SCA_IInputDevice::KX_DELKEY)
425                  || (keyIndex == SCA_IInputDevice::KX_BACKSPACEKEY) ) {
426                 return true;
427         } else {
428                 return false;
429         }
430 }
431
432 /**
433  * Tests whether shift is pressed
434  */     
435 bool SCA_KeyboardSensor::IsShifted(void)
436 {
437         SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
438         
439         if ( (inputdev->GetEventValue(SCA_IInputDevice::KX_RIGHTSHIFTKEY).m_status 
440                   == SCA_InputEvent::KX_ACTIVE)
441                  || (inputdev->GetEventValue(SCA_IInputDevice::KX_RIGHTSHIFTKEY).m_status 
442                          == SCA_InputEvent::KX_JUSTACTIVATED)
443                  || (inputdev->GetEventValue(SCA_IInputDevice::KX_LEFTSHIFTKEY).m_status 
444                          == SCA_InputEvent::KX_ACTIVE)
445                  || (inputdev->GetEventValue(SCA_IInputDevice::KX_LEFTSHIFTKEY).m_status 
446                          == SCA_InputEvent::KX_JUSTACTIVATED)
447                 ) {
448                 return true;
449         } else {
450                 return false;
451         }       
452 }
453
454 void SCA_KeyboardSensor::LogKeystrokes(void) 
455 {
456         SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
457         int num = inputdev->GetNumActiveEvents();
458
459         /* weird loop, this one... */
460         if (num > 0)
461         {
462                 
463                 int index = 0;
464                 /* Check on all keys whether they were pushed. This does not
465          * untangle the ordering, so don't type too fast :) */
466                 for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
467                 {
468                         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
469                         if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED) //NO_INPUTSTATUS)
470                         {
471                                 if (index < num)
472                                 {
473                                         AddToTargetProp(i);
474                                         index++;
475                                 }
476                         }
477                 }
478         }
479 }
480
481
482 /* ------------------------------------------------------------------------- */
483 /* Python functions : specific                                               */
484 /* ------------------------------------------------------------------------- */
485
486
487 PyObject* SCA_KeyboardSensor::PySetAllMode(PyObject* self, 
488                                PyObject* args, 
489                                PyObject* kwds)
490 {
491         bool allkeys;
492
493         if (!PyArg_ParseTuple(args, "i", &allkeys))
494         {
495           return NULL;
496         }
497         
498         m_bAllKeys = allkeys;
499         Py_Return
500 }
501
502
503
504 PyObject* SCA_KeyboardSensor::sPySetAllMode(PyObject* self, 
505                                        PyObject* args, 
506                                        PyObject* kwds)
507 {
508 //      printf("sPyIsPositive\n");
509     return ((SCA_KeyboardSensor*) self)->PyIsPositive(self, args, kwds);
510 }
511
512
513 /** 1. GetKey : check which key this sensor looks at */
514 char SCA_KeyboardSensor::GetKey_doc[] = 
515 "getKey()\n"
516 "\tReturn the code of the key this sensor is listening to.\n" ;
517 PyObject* SCA_KeyboardSensor::PyGetKey(PyObject* self, PyObject* args, PyObject* kwds)
518 {
519         return PyInt_FromLong(m_hotkey);
520 }
521
522 /** 2. SetKey: change the key to look at */
523 char SCA_KeyboardSensor::SetKey_doc[] = 
524 "setKey(keycode)\n"
525 "\t- keycode: any code from GameKeys\n"
526 "\tSet the key this sensor should listen to.\n" ;
527 PyObject* SCA_KeyboardSensor::PySetKey(PyObject* self, PyObject* args, PyObject* kwds)
528 {
529         int keyCode;
530         
531         if(!PyArg_ParseTuple(args, "i", &keyCode)) {
532                 return NULL;
533         }
534
535         /* Since we have symbolic constants for this in Python, we don't guard   */
536         /* anything. It's up to the user to provide a sensible number.           */
537         m_hotkey = keyCode;
538
539         Py_Return;
540 }
541
542 /** 3. GetHold1 : set the first bucky bit */
543 char SCA_KeyboardSensor::GetHold1_doc[] = 
544 "getHold1()\n"
545 "\tReturn the code of the first key modifier to the key this \n"
546 "\tsensor is listening to.\n" ;
547 PyObject* SCA_KeyboardSensor::PyGetHold1(PyObject* self, PyObject* args, PyObject* kwds)
548 {
549         return PyInt_FromLong(m_qual);
550 }
551
552 /** 4. SetHold1: change the first bucky bit */
553 char SCA_KeyboardSensor::SetHold1_doc[] = 
554 "setHold1(keycode)\n"
555 "\t- keycode: any code from GameKeys\n"
556 "\tSet the first modifier to the key this sensor should listen to.\n" ;
557 PyObject* SCA_KeyboardSensor::PySetHold1(PyObject* self, PyObject* args, PyObject* kwds)
558 {
559         int keyCode;
560
561         if(!PyArg_ParseTuple(args, "i", &keyCode)) {
562                 return NULL;
563         }
564         
565         /* Since we have symbolic constants for this in Python, we don't guard   */
566         /* anything. It's up to the user to provide a sensible number.           */
567         m_qual = keyCode;
568
569         Py_Return;
570 }
571         
572 /** 5. GetHold2 : get the second bucky bit */
573 char SCA_KeyboardSensor::GetHold2_doc[] = 
574 "getHold2()\n"
575 "\tReturn the code of the second key modifier to the key this \n"
576 "\tsensor is listening to.\n" ;
577 PyObject* SCA_KeyboardSensor::PyGetHold2(PyObject* self, PyObject* args, PyObject* kwds)
578 {
579         return PyInt_FromLong(m_qual2);
580 }
581
582 /** 6. SetHold2: change the second bucky bit */
583 char SCA_KeyboardSensor::SetHold2_doc[] = 
584 "setHold2(keycode)\n"
585 "\t- keycode: any code from GameKeys\n"
586 "\tSet the first modifier to the key this sensor should listen to.\n" ;
587 PyObject* SCA_KeyboardSensor::PySetHold2(PyObject* self, PyObject* args, PyObject* kwds)
588 {
589         int keyCode;
590
591         if(!PyArg_ParseTuple(args, "i", &keyCode)) {
592                 return NULL;
593         }
594         
595         /* Since we have symbolic constants for this in Python, we don't guard   */
596         /* anything. It's up to the user to provide a sensible number.           */
597         m_qual2 = keyCode;
598
599         Py_Return;
600 }
601
602         
603 char SCA_KeyboardSensor::GetPressedKeys_doc[] = 
604 "getPressedKeys()\n"
605 "\tGet a list of pressed keys that have either been pressed, or just released this frame.\n" ;
606
607 PyObject* SCA_KeyboardSensor::PyGetPressedKeys(PyObject* self, PyObject* args, PyObject* kwds)
608 {
609         SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
610
611         int num = inputdev->GetNumJustEvents();
612         PyObject* resultlist = PyList_New(num);
613
614         if (num > 0)
615         {
616                 
617                 int index = 0;
618                 
619                 for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
620                 {
621                         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
622                         if ((inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
623                                 || (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED))
624                         {
625                                 if (index < num)
626                                 {
627                                         PyObject* keypair = PyList_New(2);
628                                         PyList_SetItem(keypair,0,PyInt_FromLong(i));
629                                         PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status));
630                                         PyList_SetItem(resultlist,index,keypair);
631                                         index++;
632                                 }
633                         }
634                 }       
635                 if (index>0) return resultlist;
636         }
637         
638         Py_Return;
639 }
640
641
642
643 char SCA_KeyboardSensor::GetCurrentlyPressedKeys_doc[] = 
644 "getCurrentlyPressedKeys()\n"
645 "\tGet a list of keys that are currently pressed.\n" ;
646
647 PyObject* SCA_KeyboardSensor::PyGetCurrentlyPressedKeys(PyObject* self, PyObject* args, PyObject* kwds)
648 {
649 SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
650
651         int num = inputdev->GetNumActiveEvents();
652         PyObject* resultlist = PyList_New(num);
653
654         if (num > 0)
655         {
656                 int index = 0;
657                 
658                 for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
659                 {
660                         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
661                         if ( (inevent.m_status == SCA_InputEvent::KX_ACTIVE)
662                                  || (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED))
663                         {
664                                 if (index < num)
665                                 {
666                                         PyObject* keypair = PyList_New(2);
667                                         PyList_SetItem(keypair,0,PyInt_FromLong(i));
668                                         PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status));
669                                         PyList_SetItem(resultlist,index,keypair);
670                                         index++;
671                                 }
672                         }
673                 }
674
675                 /* why?*/
676                 if (index > 0) return resultlist;
677         }
678
679         Py_Return;
680 }
681
682 /* ------------------------------------------------------------------------- */
683 /* Python functions : integration hooks                                      */
684 /* ------------------------------------------------------------------------- */
685
686 PyTypeObject SCA_KeyboardSensor::Type = {
687         PyObject_HEAD_INIT(&PyType_Type)
688         0,
689         "SCA_KeyboardSensor",
690         sizeof(SCA_KeyboardSensor),
691         0,
692         PyDestructor,
693         0,
694         __getattr,
695         __setattr,
696         0, //&MyPyCompare,
697         __repr,
698         0, //&cvalue_as_number,
699         0,
700         0,
701         0,
702         0
703 };
704
705 PyParentObject SCA_KeyboardSensor::Parents[] = {
706         &SCA_KeyboardSensor::Type,
707         &SCA_ISensor::Type,
708         &SCA_ILogicBrick::Type,
709         &CValue::Type,
710         NULL
711 };
712
713 PyMethodDef SCA_KeyboardSensor::Methods[] = {
714   {"getKey", (PyCFunction) SCA_KeyboardSensor::sPyGetKey, METH_VARARGS, GetKey_doc},
715   {"setKey", (PyCFunction) SCA_KeyboardSensor::sPySetKey, METH_VARARGS, SetKey_doc},
716   {"getHold1", (PyCFunction) SCA_KeyboardSensor::sPyGetHold1, METH_VARARGS, GetHold1_doc},
717   {"setHold1", (PyCFunction) SCA_KeyboardSensor::sPySetHold1, METH_VARARGS, SetHold1_doc},
718   {"getHold2", (PyCFunction) SCA_KeyboardSensor::sPyGetHold2, METH_VARARGS, GetHold2_doc},
719   {"setHold2", (PyCFunction) SCA_KeyboardSensor::sPySetHold2, METH_VARARGS, SetHold2_doc},
720 //  {"getUseAllKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetUseAllKeys, METH_VARARGS, GetUseAllKeys_doc},
721 //  {"setUseAllKeys", (PyCFunction) SCA_KeyboardSensor::sPySetUseAllKeys, METH_VARARGS, SetUseAllKeys_doc},
722   {"getPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetPressedKeys, METH_VARARGS, GetPressedKeys_doc},
723   {"getCurrentlyPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetCurrentlyPressedKeys, METH_VARARGS, GetCurrentlyPressedKeys_doc},
724 //  {"getKeyEvents", (PyCFunction) SCA_KeyboardSensor::sPyGetKeyEvents, METH_VARARGS, GetKeyEvents_doc},
725   {NULL,NULL} //Sentinel
726 };
727
728 PyObject*
729 SCA_KeyboardSensor::_getattr(const STR_String& attr)
730 {
731   _getattr_up(SCA_ISensor);
732 }
733