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