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