doxygen: prevent GPL license block from being parsed as doxygen comment.
[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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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
31 #include <stddef.h>
32
33 #include "SCA_KeyboardSensor.h"
34 #include "SCA_KeyboardManager.h"
35 #include "SCA_LogicManager.h"
36 #include "StringValue.h"
37 #include "SCA_IInputDevice.h"
38
39 /* ------------------------------------------------------------------------- */
40 /* Native functions                                                          */
41 /* ------------------------------------------------------------------------- */
42
43 SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr,
44                                                                            short int hotkey,
45                                                                            short int qual,
46                                                                            short int qual2,
47                                                                            bool bAllKeys,
48                                                                            const STR_String& targetProp,
49                                                                            const STR_String& toggleProp,
50                                                                            SCA_IObject* gameobj)
51         :SCA_ISensor(gameobj,keybdmgr),
52          m_hotkey(hotkey),
53          m_qual(qual),
54          m_qual2(qual2),
55          m_bAllKeys(bAllKeys),
56          m_targetprop(targetProp),
57          m_toggleprop(toggleProp)
58 {
59         if (hotkey == SCA_IInputDevice::KX_ESCKEY)
60                 keybdmgr->GetInputDevice()->HookEscape();
61 //      SetDrawColor(0xff0000ff);
62         Init();
63 }
64
65
66
67 SCA_KeyboardSensor::~SCA_KeyboardSensor()
68 {
69 }
70
71 void SCA_KeyboardSensor::Init()
72 {
73         // this function is used when the sensor is disconnected from all controllers
74         // by the state engine. It reinitializes the sensor as if it was just created.
75         // However, if the target key is pressed when the sensor is reactivated, it
76         // will not generated an event (see remark in Evaluate()).
77         m_val = (m_invert)?1:0;
78         m_reset = true;
79 }
80
81 CValue* SCA_KeyboardSensor::GetReplica()
82 {
83         SCA_KeyboardSensor* replica = new SCA_KeyboardSensor(*this);
84         // this will copy properties and so on...
85         replica->ProcessReplica();
86         replica->Init();
87         return replica;
88 }
89
90
91
92 short int SCA_KeyboardSensor::GetHotkey()
93 {
94         return m_hotkey;
95 }
96
97
98
99 bool SCA_KeyboardSensor::IsPositiveTrigger()
100
101         bool result = (m_val != 0);
102
103         if (m_invert)
104                 result = !result;
105                 
106         return result;
107 }
108
109
110
111 bool SCA_KeyboardSensor::TriggerOnAllKeys()
112
113         return m_bAllKeys;
114 }
115
116
117
118 bool SCA_KeyboardSensor::Evaluate()
119 {
120         bool result    = false;
121         bool reset     = m_reset && m_level;
122         bool qual          = true;
123         bool qual_change = false;
124         short int m_val_orig = m_val;
125         
126         SCA_IInputDevice* inputdev = ((SCA_KeyboardManager *)m_eventmgr)->GetInputDevice();
127         //      cerr << "SCA_KeyboardSensor::Eval event, sensing for "<< m_hotkey << " at device " << inputdev << "\n";
128
129         /* See if we need to do logging: togPropState exists and is
130      * different from 0 */
131         CValue* myparent = GetParent();
132         CValue* togPropState = myparent->GetProperty(m_toggleprop);
133         if (togPropState &&
134                 (((int)togPropState->GetNumber()) != 0) )
135         {
136                 LogKeystrokes();
137         }
138
139         m_reset = false;
140
141         /* Now see whether events must be bounced. */
142         if (m_bAllKeys)
143         {
144                 bool justactivated = false;
145                 bool justreleased = false;
146                 bool active = false;
147
148                 for (int i=SCA_IInputDevice::KX_BEGINKEY ; i<= SCA_IInputDevice::KX_ENDKEY;i++)
149                 {
150                         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
151                         switch (inevent.m_status) 
152                         { 
153                         case SCA_InputEvent::KX_JUSTACTIVATED:
154                                 justactivated = true;
155                                 break;
156                         case SCA_InputEvent::KX_JUSTRELEASED:
157                                 justreleased = true;
158                                 break;
159                         case SCA_InputEvent::KX_ACTIVE:
160                                 active = true;
161                                 break;
162                         case SCA_InputEvent::KX_NO_INPUTSTATUS:
163                                 /* do nothing */
164                                 break;
165                         }
166                 }
167
168                 if (justactivated)
169                 {
170                         m_val=1;
171                         result = true;
172                 } else
173                 {
174                         if (justreleased)
175                         {
176                                 m_val=(active)?1:0;
177                                 result = true;
178                         } else
179                         {
180                                 if (active)
181                                 {
182                                         if (m_val == 0)
183                                         {
184                                                 m_val = 1;
185                                                 if (m_level) {
186                                                         result = true;
187                                                 }
188                                         }
189                                 } else
190                                 {
191                                         if (m_val == 1)
192                                         {
193                                                 m_val = 0;
194                                                 result = true;
195                                         }
196                                 }
197                         }
198                         if (m_tap)
199                                 // special case for tap mode: only generate event for new activation
200                                 result = false;
201                 }
202
203
204         } else
205         {
206
207         //              cerr << "======= SCA_KeyboardSensor::Evaluate:: peeking at key status" << endl;
208                 const SCA_InputEvent & inevent = inputdev->GetEventValue(
209                         (SCA_IInputDevice::KX_EnumInputs) m_hotkey);
210         
211         //              cerr << "======= SCA_KeyboardSensor::Evaluate:: status: " << inevent.m_status << endl;
212                 
213                 
214                 /* Check qualifier keys
215                  * - see if the qualifiers we request are pressed - 'qual' true/false
216                  * - see if the qualifiers we request changed their state - 'qual_change' true/false
217                  */
218                 if (m_qual > 0) {
219                         const SCA_InputEvent & qualevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_qual);
220                         switch(qualevent.m_status) {
221                         case SCA_InputEvent::KX_NO_INPUTSTATUS:
222                                 qual = false;
223                                 break;
224                         case SCA_InputEvent::KX_JUSTRELEASED:
225                                 qual_change = true;
226                                 qual = false;
227                                 break;
228                         case SCA_InputEvent::KX_JUSTACTIVATED:
229                                 qual_change = true;
230                         case SCA_InputEvent::KX_ACTIVE:
231                                 /* do nothing */
232                                 break;
233                         }
234                 }
235                 if (m_qual2 > 0 && qual==true) {
236                         const SCA_InputEvent & qualevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_qual2);
237                         /* copy of above */
238                         switch(qualevent.m_status) {
239                         case SCA_InputEvent::KX_NO_INPUTSTATUS:
240                                 qual = false;
241                                 break;
242                         case SCA_InputEvent::KX_JUSTRELEASED:
243                                 qual_change = true;
244                                 qual = false;
245                                 break;
246                         case SCA_InputEvent::KX_JUSTACTIVATED:
247                                 qual_change = true;
248                         case SCA_InputEvent::KX_ACTIVE:
249                                 /* do nothing */
250                                 break;
251                         }
252                 }
253                 /* done reading qualifiers */
254                 
255                 if (inevent.m_status == SCA_InputEvent::KX_NO_INPUTSTATUS)
256                 {
257                         if (m_val == 1)
258                         {
259                                 // this situation may occur after a scene suspend: the keyboard release 
260                                 // event was not captured, produce now the event off
261                                 m_val = 0;
262                                 result = true;
263                         }
264                 } else
265                 {
266                         if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
267                         {
268                                 m_val=1;
269                                 result = true;
270                         } else
271                         {
272                                 if (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)
273                                 {
274                                         m_val = 0;
275                                         result = true;
276                                 } else 
277                                 {
278                                         if (inevent.m_status == SCA_InputEvent::KX_ACTIVE)
279                                         {
280                                                 if (m_val == 0)
281                                                 {
282                                                         m_val = 1;
283                                                         if (m_level) 
284                                                         {
285                                                                 result = true;
286                                                         }
287                                                 }
288                                         }
289                                 }
290                         }
291                 }
292                 
293                 /* Modify the key state based on qual(s)
294                  * Tested carefuly. dont touch unless your really sure.
295                  * note, this will only change the results if key modifiers are set.
296                  *
297                  * When all modifiers and keys are positive
298                  *  - pulse true
299                  * 
300                  * When ANY of the modifiers or main key become inactive,
301                  *  - pulse false
302                  */
303                 if (qual==false) { /* one of the qualifiers are not pressed */
304                         if (m_val_orig && qual_change) { /* we were originally enabled, but a qualifier changed */
305                                 result = true;
306                         } else {
307                                 result = false;
308                         }
309                         m_val = 0; /* since one of the qualifiers is not on, set the state to false */
310                 } else {                                                /* we done have any qualifiers or they are all pressed */
311                         if (m_val && qual_change) {     /* the main key state is true and our qualifier just changed */
312                                 result = true;
313                         }
314                 }
315                 /* done with key quals */
316                 
317         }
318         
319         if (reset)
320                 // force an event
321                 result = true;
322         return result;
323
324 }
325
326 void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
327 {
328         if (IsPrintable(keyIndex)) {
329                 CValue* tprop = GetParent()->GetProperty(m_targetprop);
330                 
331                 if (tprop) {
332                         /* overwrite the old property */
333                         if (IsDelete(keyIndex)) {
334                                 /* strip one char, if possible */
335                                 STR_String newprop = tprop->GetText();
336                                 int oldlength = newprop.Length();
337                                 if (oldlength >= 1 ) {
338                                         newprop.SetLength(oldlength - 1);
339                                         CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
340                                         GetParent()->SetProperty(m_targetprop, newstringprop);
341                                         newstringprop->Release();
342                                 }                               
343                         } else {
344                                 /* append */
345                                 char pchar = ToCharacter(keyIndex, IsShifted());
346                                 STR_String newprop = tprop->GetText() + pchar;
347                                 CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);                 
348                                 GetParent()->SetProperty(m_targetprop, newstringprop);
349                                 newstringprop->Release();
350                         }
351                 } else {
352                         if (!IsDelete(keyIndex)) {
353                                 /* Make a new property. Deletes can be ignored. */
354                                 char pchar = ToCharacter(keyIndex, IsShifted());
355                                 STR_String newprop = pchar;
356                                 CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);                 
357                                 GetParent()->SetProperty(m_targetprop, newstringprop);
358                                 newstringprop->Release();
359                         }
360                 }
361         }
362         
363 }
364         
365 /**
366  * Tests whether shift is pressed
367  */     
368 bool SCA_KeyboardSensor::IsShifted(void)
369 {
370         SCA_IInputDevice* inputdev = ((SCA_KeyboardManager *)m_eventmgr)->GetInputDevice();
371         
372         if ( (inputdev->GetEventValue(SCA_IInputDevice::KX_RIGHTSHIFTKEY).m_status 
373                   == SCA_InputEvent::KX_ACTIVE)
374                  || (inputdev->GetEventValue(SCA_IInputDevice::KX_RIGHTSHIFTKEY).m_status 
375                          == SCA_InputEvent::KX_JUSTACTIVATED)
376                  || (inputdev->GetEventValue(SCA_IInputDevice::KX_LEFTSHIFTKEY).m_status 
377                          == SCA_InputEvent::KX_ACTIVE)
378                  || (inputdev->GetEventValue(SCA_IInputDevice::KX_LEFTSHIFTKEY).m_status 
379                          == SCA_InputEvent::KX_JUSTACTIVATED)
380                 ) {
381                 return true;
382         } else {
383                 return false;
384         }       
385 }
386
387 void SCA_KeyboardSensor::LogKeystrokes(void) 
388 {
389         SCA_IInputDevice* inputdev = ((SCA_KeyboardManager *)m_eventmgr)->GetInputDevice();
390         int num = inputdev->GetNumActiveEvents();
391
392         /* weird loop, this one... */
393         if (num > 0)
394         {
395                 
396                 int index = 0;
397                 /* Check on all keys whether they were pushed. This does not
398          * untangle the ordering, so don't type too fast :) */
399                 for (int i=SCA_IInputDevice::KX_BEGINKEY ; i<= SCA_IInputDevice::KX_ENDKEY;i++)
400                 {
401                         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
402                         if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED) //NO_INPUTSTATUS)
403                         {
404                                 if (index < num)
405                                 {
406                                         AddToTargetProp(i);
407                                         index++;
408                                 }
409                         }
410                 }
411         }
412 }
413
414 #ifdef WITH_PYTHON
415
416 /* ------------------------------------------------------------------------- */
417 /* Python Functions                                                    */
418 /* ------------------------------------------------------------------------- */
419
420 KX_PYMETHODDEF_DOC_O(SCA_KeyboardSensor, getKeyStatus,
421 "getKeyStatus(keycode)\n"
422 "\tGet the given key's status (KX_NO_INPUTSTATUS, KX_JUSTACTIVATED, KX_ACTIVE or KX_JUSTRELEASED).\n")
423 {
424         if (!PyLong_Check(value)) {
425                 PyErr_SetString(PyExc_ValueError, "sensor.getKeyStatus(int): Keyboard Sensor, expected an int");
426                 return NULL;
427         }
428         
429         int keycode = PyLong_AsSsize_t(value);
430         
431         if ((keycode < SCA_IInputDevice::KX_BEGINKEY)
432                 || (keycode > SCA_IInputDevice::KX_ENDKEY)){
433                 PyErr_SetString(PyExc_AttributeError, "sensor.getKeyStatus(int): Keyboard Sensor, invalid keycode specified!");
434                 return NULL;
435         }
436         
437         SCA_IInputDevice* inputdev = ((SCA_KeyboardManager *)m_eventmgr)->GetInputDevice();
438         const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) keycode);
439         return PyLong_FromSsize_t(inevent.m_status);
440 }
441
442 /* ------------------------------------------------------------------------- */
443 /* Python Integration Hooks                                            */
444 /* ------------------------------------------------------------------------- */
445
446 PyTypeObject SCA_KeyboardSensor::Type = {
447         PyVarObject_HEAD_INIT(NULL, 0)
448         "SCA_KeyboardSensor",
449         sizeof(PyObjectPlus_Proxy),
450         0,
451         py_base_dealloc,
452         0,
453         0,
454         0,
455         0,
456         py_base_repr,
457         0,0,0,0,0,0,0,0,0,
458         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
459         0,0,0,0,0,0,0,
460         Methods,
461         0,
462         0,
463         &SCA_ISensor::Type,
464         0,0,0,0,0,0,
465         py_base_new
466 };
467
468 PyMethodDef SCA_KeyboardSensor::Methods[] = {
469         KX_PYMETHODTABLE_O(SCA_KeyboardSensor, getKeyStatus),
470         {NULL,NULL} //Sentinel
471 };
472
473 PyAttributeDef SCA_KeyboardSensor::Attributes[] = {
474         KX_PYATTRIBUTE_RO_FUNCTION("events", SCA_KeyboardSensor, pyattr_get_events),
475         KX_PYATTRIBUTE_BOOL_RW("useAllKeys",SCA_KeyboardSensor,m_bAllKeys),
476         KX_PYATTRIBUTE_INT_RW("key",0,SCA_IInputDevice::KX_ENDKEY,true,SCA_KeyboardSensor,m_hotkey),
477         KX_PYATTRIBUTE_SHORT_RW("hold1",0,SCA_IInputDevice::KX_ENDKEY,true,SCA_KeyboardSensor,m_qual),
478         KX_PYATTRIBUTE_SHORT_RW("hold2",0,SCA_IInputDevice::KX_ENDKEY,true,SCA_KeyboardSensor,m_qual2),
479         KX_PYATTRIBUTE_STRING_RW("toggleProperty",0,100,false,SCA_KeyboardSensor,m_toggleprop),
480         KX_PYATTRIBUTE_STRING_RW("targetProperty",0,100,false,SCA_KeyboardSensor,m_targetprop),
481         { NULL }        //Sentinel
482 };
483
484
485 PyObject* SCA_KeyboardSensor::pyattr_get_events(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
486 {
487         SCA_KeyboardSensor* self= static_cast<SCA_KeyboardSensor*>(self_v);
488         
489         SCA_IInputDevice* inputdev = ((SCA_KeyboardManager *)self->m_eventmgr)->GetInputDevice();
490
491         PyObject* resultlist = PyList_New(0);
492         
493         for (int i=SCA_IInputDevice::KX_BEGINKEY ; i<= SCA_IInputDevice::KX_ENDKEY;i++)
494         {
495                 const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
496                 if (inevent.m_status != SCA_InputEvent::KX_NO_INPUTSTATUS)
497                 {
498                         PyObject* keypair = PyList_New(2);
499                         PyList_SET_ITEM(keypair,0,PyLong_FromSsize_t(i));
500                         PyList_SET_ITEM(keypair,1,PyLong_FromSsize_t(inevent.m_status));
501                         PyList_Append(resultlist,keypair);
502                 }
503         }       
504         return resultlist;
505 }
506
507 #endif // WITH_PYTHON
508
509 /* Accessed from python */
510
511 // this code looks ugly, please use an ordinary hashtable
512
513 char ToCharacter(int keyIndex, bool shifted)
514 {
515         /* numerals */
516         if ( (keyIndex >= SCA_IInputDevice::KX_ZEROKEY) 
517                  && (keyIndex <= SCA_IInputDevice::KX_NINEKEY) ) {
518                 if (shifted) {
519                         char numshift[] = ")!@#$%^&*(";
520                         return numshift[keyIndex - '0']; 
521                 } else {
522                         return keyIndex - SCA_IInputDevice::KX_ZEROKEY + '0'; 
523                 }
524         }
525         
526         /* letters... always lowercase... is that desirable? */
527         if ( (keyIndex >= SCA_IInputDevice::KX_AKEY) 
528                  && (keyIndex <= SCA_IInputDevice::KX_ZKEY) ) {
529                 if (shifted) {
530                         return keyIndex - SCA_IInputDevice::KX_AKEY + 'A'; 
531                 } else {
532                         return keyIndex - SCA_IInputDevice::KX_AKEY + 'a'; 
533                 }
534         }
535         
536         if (keyIndex == SCA_IInputDevice::KX_SPACEKEY) {
537                 return ' ';
538         }
539         if (keyIndex == SCA_IInputDevice::KX_RETKEY || keyIndex == SCA_IInputDevice::KX_PADENTER) {
540                 return '\n';
541         }
542         
543         
544         if (keyIndex == SCA_IInputDevice::KX_PADASTERKEY) {
545                 return '*';
546         }
547         
548         if (keyIndex == SCA_IInputDevice::KX_TABKEY) {
549                 return '\t';
550         }
551         
552         /* comma to period */
553         char commatoperiod[] = ",-.";
554         char commatoperiodshifted[] = "<_>";
555         if (keyIndex == SCA_IInputDevice::KX_COMMAKEY) {
556                 if (shifted) {
557                         return commatoperiodshifted[0];
558                 } else {
559                         return commatoperiod[0];
560                 }
561         }
562         if (keyIndex == SCA_IInputDevice::KX_MINUSKEY) {
563                 if (shifted) {
564                         return commatoperiodshifted[1];
565                 } else {
566                         return commatoperiod[1];
567                 }
568         }
569         if (keyIndex == SCA_IInputDevice::KX_PERIODKEY) {
570                 if (shifted) {
571                         return commatoperiodshifted[2];
572                 } else {
573                         return commatoperiod[2];
574                 }
575         }
576         
577         /* semicolon to rightbracket */
578         char semicolontorightbracket[] = ";\'`/\\=[]";
579         char semicolontorightbracketshifted[] = ":\"~\?|+{}";
580         if ((keyIndex >= SCA_IInputDevice::KX_SEMICOLONKEY) 
581                 && (keyIndex <= SCA_IInputDevice::KX_RIGHTBRACKETKEY)) {
582                 if (shifted) {
583                         return semicolontorightbracketshifted[keyIndex - SCA_IInputDevice::KX_SEMICOLONKEY];
584                 } else {
585                         return semicolontorightbracket[keyIndex - SCA_IInputDevice::KX_SEMICOLONKEY];
586                 }
587         }
588         
589         /* keypad2 to padplus */
590         char pad2topadplus[] = "246813579. 0- +";
591         if ((keyIndex >= SCA_IInputDevice::KX_PAD2) 
592                 && (keyIndex <= SCA_IInputDevice::KX_PADPLUSKEY)) { 
593                 return pad2topadplus[keyIndex - SCA_IInputDevice::KX_PAD2];
594         }
595
596         return '!';
597 }
598
599
600
601 /**
602  * Determine whether this character can be printed. We cannot use
603  * the library functions here, because we need to test our own
604  * keycodes. */
605 bool IsPrintable(int keyIndex)
606 {
607         /* only print 
608          * - numerals: KX_ZEROKEY to KX_NINEKEY
609          * - alphas:   KX_AKEY to KX_ZKEY. 
610          * - specials: KX_RETKEY, KX_PADASTERKEY, KX_PADCOMMAKEY to KX_PERIODKEY,
611          *             KX_TABKEY , KX_SEMICOLONKEY to KX_RIGHTBRACKETKEY, 
612          *             KX_PAD2 to KX_PADPLUSKEY
613          * - delete and backspace: also printable in the sense that they modify 
614          *                         the string
615          * - retkey: should this be printable?
616          * - virgule: prints a space... don't know which key that's supposed
617          *   to be...
618          */
619         if ( ((keyIndex >= SCA_IInputDevice::KX_ZEROKEY) 
620                   && (keyIndex <= SCA_IInputDevice::KX_NINEKEY))
621                  || ((keyIndex >= SCA_IInputDevice::KX_AKEY) 
622                          && (keyIndex <= SCA_IInputDevice::KX_ZKEY)) 
623                  || (keyIndex == SCA_IInputDevice::KX_SPACEKEY) 
624                  || (keyIndex == SCA_IInputDevice::KX_RETKEY)
625                  || (keyIndex == SCA_IInputDevice::KX_PADENTER)
626                  || (keyIndex == SCA_IInputDevice::KX_PADASTERKEY) 
627                  || (keyIndex == SCA_IInputDevice::KX_TABKEY) 
628                  || ((keyIndex >= SCA_IInputDevice::KX_COMMAKEY) 
629                          && (keyIndex <= SCA_IInputDevice::KX_PERIODKEY)) 
630                  || ((keyIndex >= SCA_IInputDevice::KX_SEMICOLONKEY) 
631                          && (keyIndex <= SCA_IInputDevice::KX_RIGHTBRACKETKEY)) 
632                  || ((keyIndex >= SCA_IInputDevice::KX_PAD2) 
633                          && (keyIndex <= SCA_IInputDevice::KX_PADPLUSKEY)) 
634                  || (keyIndex == SCA_IInputDevice::KX_DELKEY)
635                  || (keyIndex == SCA_IInputDevice::KX_BACKSPACEKEY)
636                 )
637         {
638                 return true;
639         } else {
640                 return false;
641         }
642 }
643
644 /**
645  * Tests whether this is a delete key.
646  */     
647 bool IsDelete(int keyIndex)
648 {
649         if ( (keyIndex == SCA_IInputDevice::KX_DELKEY)
650                  || (keyIndex == SCA_IInputDevice::KX_BACKSPACEKEY) ) {
651                 return true;
652         } else {
653                 return false;
654         }
655 }