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