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