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