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