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