FreeWRL/FreeX3D  3.0.0
Component_KeyDevice.c
1 /*
2 
3 
4 X3D Key Device Component
5 
6 */
7 
8 
9 /****************************************************************************
10  This file is part of the FreeWRL/FreeX3D Distribution.
11 
12  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
13 
14  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
15  it under the terms of the GNU Lesser Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  GNU General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
26 ****************************************************************************/
27 
28 
29 
30 #include <config.h>
31 #include <system.h>
32 #include <display.h>
33 #include <internal.h>
34 
35 #include <libFreeWRL.h>
36 
37 #include "../vrml_parser/Structs.h"
38 #include "../main/headers.h"
39 #include "../input/EAIHelpers.h" /* for newASCIIString() */
40 #include "../vrml_parser/CRoutes.h"
41 
42 #include "Component_KeyDevice.h"
43 #include "ui/common.h" // for ppcommon
44 /*
45 I'll leave off comments about the validity of this part of the spec - it does
46 not seem well thought out. I'll leave off my comments on what I really think
47 about this part of the X3D Spec, because I'm nice, and I don't want to
48 put other people's ideas down, especially in public, in source code, that
49 will outlive me.
50 
51 So, if there is a KeyDevice node present, DO NOT use keys for FreeWRL navigation
52 but instead, send any along that the Operating System GUI does not capture,
53 and hope that they are not too badly mangled by intervening layers.
54 
55 Lets just hope that this part of the spec dies a convenient (and speedy)
56 death!
57 
58 Anyway, with that, lets blindly forge along...
59 
60 *********************************************************************/
61 
62 // OLD_IPHONE_AQUA #ifndef AQUA
63 int shiftPressed = 0;
64 int ctrlPressed = 0;
65 // OLD_IPHONE_AQUA #endif
66 
67 /* mapped from my Apple OSX keyboard, canadian setup, so here goes... */
68 #if defined (_MSC_VER)
69 /* values from WinUser.h */
70 #define PHOME_KEY 0x24
71 #define PPGDN_KEY 0x22
72 #define PLEFT_KEY 0x25
73 #define PEND_KEY 0x23
74 #define PUP_KEY 0x26
75 #define PRIGHT_KEY 0x27
76 #define PPGUP_KEY 0x21
77 #define PDOWN_KEY 0x28
78 #define PF1_KEY 0x70
79 #define PF12_KEY 0x7b
80 #define PALT_KEY 0x12
81 #define PCTL_KEY 0x11
82 #define PSFT_KEY 0x10
83 #define PDEL_KEY 0x2E //2E is DELETE 0x08 is backspace. Problem '.' is ascii 2E.
84 #define PRTN_KEY 13
85 #define KEYPRESS 1
86 #define KEYDOWN 2
87 #define KEYUP 3
88 
89 #else
90 
91 #define PHOME_KEY 80
92 #define PPGDN_KEY 86
93 #define PLEFT_KEY 106
94 #define PEND_KEY 87
95 #define PUP_KEY 112
96 #define PRIGHT_KEY 108
97 #define PPGUP_KEY 85
98 #define PDOWN_KEY 59
99 #define PF1_KEY 0xFFBE
100 #define PF12_KEY 0XFFC9
101 #define PALT_KEY 0XFFE9 //left, and 0XFFEA //0XFFE7
102 #define PCTL_KEY 0XFFE3 //left, and 0XFFE4 on right
103 #define PSFT_KEY 0XFFE1 //left, and 0XFFE2 on right
104 #define PDEL_KEY 0XFF9F //on numpad, and 0XFFFF near Insert //0x08
105 #define KEYPRESS 1
106 #define KEYDOWN 2
107 #define KEYUP 3
108 
109 #endif
110 // http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/keyboard.html
112 //section 21.4.1
113 //Key Value
114 //Home 13
115 //End 14
116 //PGUP 15
117 //PGDN 16
118 //UP 17
119 //DOWN 18
120 //LEFT 19
121 //RIGHT 20
122 //F1-F12 1 to 12
123 //ALT,CTRL,SHIFT true/false
124 //*/
125 //#define F1_KEY 1
126 //#define F2_KEY 2
127 //#define F3_KEY 3
128 //#define F4_KEY 4
129 //#define F5_KEY 5
130 //#define F6_KEY 6
131 //#define F7_KEY 7
132 //#define F8_KEY 8
133 //#define F9_KEY 9
134 //#define F10_KEY 10
135 //#define F11_KEY 11
136 //#define F12_KEY 12
137 //#define HOME_KEY 13
138 //#define END_KEY 14
139 //#define PGUP_KEY 15
140 //#define PGDN_KEY 16
141 //#define UP_KEY 17
142 //#define DOWN_KEY 18
143 //#define LEFT_KEY 19
144 //#define RIGHT_KEY 20
145 //#define ALT_KEY 30 /* not available on OSX */
146 //#define CTL_KEY 31 /* not available on OSX */
147 //#define SFT_KEY 32 /* not available on OSX */
148 //#define DEL_KEY 0XFFFF /* problem: I'm insterting this back into the translated char stream so 0XFFFF too high to clash with a latin? */
149 //#define RTN_KEY 13 //what about 10 newline?
150 //#define NUM0 40
151 //#define NUM1 41
152 //#define NUM2 42
153 //#define NUM3 43
154 //#define NUM4 44
155 //#define NUM5 45
156 //#define NUM6 46
157 //#define NUM7 47
158 //#define NUM8 48
159 //#define NUM9 49
160 //#define NUMDEC 50
161 
162 
163 int platform2web3dActionKey(int platformKey)
164 {
165  int key;
166 
167  key = 0; //platformKey;
168  if(platformKey >= PF1_KEY && platformKey <= PF12_KEY)
169  key = platformKey - PF1_KEY + F1_KEY;
170  else
171  switch(platformKey)
172  {
173  case PHOME_KEY:
174  key = HOME_KEY; break;
175  case PEND_KEY:
176  key = END_KEY; break;
177  case PPGDN_KEY:
178  key = PGDN_KEY; break;
179  case PPGUP_KEY:
180  key = PGUP_KEY; break;
181  case PUP_KEY:
182  key = UP_KEY; break;
183  case PDOWN_KEY:
184  key = DOWN_KEY; break;
185  case PLEFT_KEY:
186  key = LEFT_KEY; break;
187  case PRIGHT_KEY:
188  key = RIGHT_KEY; break;
189  case PDEL_KEY:
190  key = DEL_KEY; break;
191  case PALT_KEY:
192  key = ALT_KEY; break;
193  case PCTL_KEY:
194  key = CTL_KEY; break;
195  case PSFT_KEY:
196  key = SFT_KEY; break;
197  default:
198  key = 0;
199  }
200  return key;
201 }
202 
203 
204 /* only keep 1 keyDevice node around; we can make a list if that is eventually
205 required by the spec. From what I can see, the spec is silent on this regard */
206 
207 //static struct X3D_Node **keySink = NULL;
208 //static int keySyncMallocLen = 0;
209 //static int keySinkCurMax = 0;
210 
211 typedef struct pComponent_KeyDevice{
212  //struct X3D_Node **keySink;// = NULL;
213  //int keySyncMallocLen;// = 0;
214  //int keySinkCurMax;// = 0;
215  struct Vector *keySink;
217 void *Component_KeyDevice_constructor(){
218  void *v = MALLOCV(sizeof(struct pComponent_KeyDevice));
219  memset(v,0,sizeof(struct pComponent_KeyDevice));
220  return v;
221 }
222 void Component_KeyDevice_init(struct tComponent_KeyDevice *t){
223  //public
224  //private
225  t->prv = Component_KeyDevice_constructor();
226  {
228  p->keySink = NULL;
229  //p->keySyncMallocLen = 0;
230  //p->keySinkCurMax = 0;
231 
232  }
233 }
234 //ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
235 
236 static void sendToSS(struct X3D_Node *wsk, int key, int upDown);
237 static void sendToKS(struct X3D_Node* wsk, int key, int upDown);
238 
239 //static void incrementKeySinkList() {
240 // ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
241 // if (p->keySinkCurMax >= p->keySyncMallocLen) {
242 // p->keySyncMallocLen += 10; /* arbitrary number */
243 // p->keySink = REALLOC(p->keySink, sizeof (struct X3D_Node *) * p->keySyncMallocLen);
244 // }
245 //}
246 
247 int KeySensorNodePresent() {
248  int count;
249  struct X3D_Node *node;
250  ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
251 
252  /* no KeyDevice node present */
253  if (p->keySink == NULL) return FALSE;
254 
255  for (count=0; count < vectorSize(p->keySink); count++) {
256  /* hmmm, there is one, but is it enabled? */
257  /* printf ("ks, checking %d\n",p->keySink[count]); */
258  node = vector_get(struct X3D_Node*,p->keySink,count);
259  if(node && node->_nodeType == NODE_KeySensor)
260  if (X3D_KEYSENSOR(node)->enabled) return TRUE;
261  if(node && node->_nodeType == NODE_StringSensor)
262  if (X3D_STRINGSENSOR(node)->enabled) return TRUE;
263  }
264 
265  return FALSE;
266 }
267 
268 
269 void addNodeToKeySensorList(struct X3D_Node* node) {
270  if ((node->_nodeType == NODE_KeySensor) || (node->_nodeType == NODE_StringSensor)) {
271  ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
272  //incrementKeySinkList();
273  if(!p->keySink)
274  p->keySink = newVector(struct X3D_Node*,4);
275  vector_pushBack(struct X3D_Node*,p->keySink,node);
276  //p->keySink[p->keySinkCurMax] = node;
277  //p->keySinkCurMax ++;
278  }
279 }
280 int removeNodeFromVector(int iaction, struct Vector *v, struct X3D_Node *node);
281 void removeNodeFromKeySensorList(struct X3D_Node* node) {
282  if ((node->_nodeType == NODE_KeySensor) || (node->_nodeType == NODE_StringSensor)) {
283  ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
284 
285  if(p->keySink && node)
286  removeNodeFromVector(0, p->keySink, node);
287  }
288 }
289 
290 void killKeySensorNodeList() {
291  ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
292  FREE_IF_NZ(p->keySink);
293  //p->keySyncMallocLen = 0;
294  //p->keySinkCurMax = 0;
295  if(p->keySink)
296  deleteVector(struct X3D_Node*, p->keySink);
297  // OLD_IPHONE_AQUA #ifndef AQUA
298  shiftPressed = 0;
299  ctrlPressed = 0;
300  // OLD_IPHONE_AQUA #endif
301 }
302 
303 void sendKeyToKeySensor(const char key, int upDown) {
304  int count;
305  struct X3D_Node *node;
306  ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
307  if (p->keySink == NULL) return;
308 
309  for (count=0; count < vectorSize(p->keySink); count++) {
310  #ifdef VERBOSE
311  printf ("sendKeyToKeySensor, sending key %d to %d of %d\n",key,count,p->keySinkCurMax);
312  #endif
313  node = vector_get(struct X3D_Node*,p->keySink,count);
314  /* make sure this has not been deleted - we should really re-create list, but
315  so few keySensor X3D nodes are in use, who cares? */
316  if (checkNode(node,__FILE__,__LINE__)) {
317  if(upDown%10 == KEYDOWN || upDown%10 == KEYUP) //2 down, or 3 up
318  if (node->_nodeType == NODE_KeySensor ) sendToKS(node, (int)key&0xFFFF, upDown);
319  if(upDown == KEYPRESS) //LINUX,WIN32 PRESS=1, aqua apple PRESS=2
320  if (node->_nodeType == NODE_StringSensor ) sendToSS(node, (int)key&0xFFFF, upDown);
321  }
322  }
323 }
324 
325 /*******************************************************/
326 
327 static void sendToKS(struct X3D_Node* wsk, int key, int upDown) {
328  int actionKey;
329  int isDown;
330  int isActionKey;
331  #define MYN X3D_KEYSENSOR(wsk)
332  /* printf ("sending key %x %u upDown %d (down %d) to keySenors\n",key,key,upDown,KEYDOWN); */
333 
334  /* if not enabled, do nothing */
335  if (!MYN)
336  return;
337  if (MYN->__oldEnabled != MYN->enabled) {
338  MYN->__oldEnabled = MYN->enabled;
339  MARK_EVENT(X3D_NODE(MYN),offsetof (struct X3D_KeySensor, enabled));
340  }
341  if (!MYN->enabled)
342  return;
343 
344  /* is this an ACTION (tm) key press or release? */
345  isDown = upDown%10 == KeyPress;
346  isActionKey = upDown / 10;
347  if(isActionKey)
348  {
349  actionKey = key;
350  switch (actionKey) {
351  case HOME_KEY:
352  case PGDN_KEY:
353  case LEFT_KEY:
354  case END_KEY:
355  case UP_KEY:
356  case RIGHT_KEY:
357  case PGUP_KEY:
358  case DOWN_KEY:
359  case F1_KEY:
360  case F2_KEY:
361  case F3_KEY:
362  case F4_KEY:
363  case F5_KEY:
364  case F6_KEY:
365  case F7_KEY:
366  case F8_KEY:
367  case F9_KEY:
368  case F10_KEY:
369  case F11_KEY:
370  case F12_KEY:
371  /* no DEL key here*/
372  if (isDown) {
373  MYN->actionKeyPress = actionKey; //TRUE;
374  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, actionKeyPress));
375  } else {
376  MYN->actionKeyRelease = actionKey; //TRUE;
377  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, actionKeyRelease));
378  }
379  break;
380  case ALT_KEY:
381  /* now, for some of the other keys, the ones that are modifiers, not ACTION (tm) keys. */
382  MYN->altKey = isDown;
383  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, altKey));
384  break;
385  case CTL_KEY:
386  MYN->controlKey = isDown;
387  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, controlKey));
388  break;
389  case SFT_KEY:
390  MYN->shiftKey = isDown;
391  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, shiftKey));
392  break;
393  default:
394  break;
395  }/*end switch */
396  } else {
397  /* regular key including RTN */
398  if ((MYN->keyPress->len != 2) || (MYN->keyRelease->len != 2)) {
399  FREE_IF_NZ(MYN->keyPress->strptr);
400  FREE_IF_NZ(MYN->keyRelease->strptr);
401  MYN->keyPress = newASCIIString ("a");
402  MYN->keyRelease = newASCIIString ("a");
403  }
404 
405  if (isDown) {
406  MYN->keyPress->strptr[0] = (char) (key&0xFF);
407  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, keyPress));
408  } else {
409  MYN->keyRelease->strptr[0] = (char) (key&0xFF);
410  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, keyRelease));
411  }
412  }
413 
414  /* now, presumably "isActive" means that the key is down... */
415  MYN->isActive = isDown;
416  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, isActive));
417  #undef MYN
418 
419 }
420 static void sendToSS(struct X3D_Node *wsk, int key, int upDown) {
421  //int actionKey;
422  #define MYN X3D_STRINGSENSOR(wsk)
423  #define MAXSTRINGLEN 512
424 
425  /* printf ("SS, %u enabled %d\n",wsk, MYN->enabled); */
426  /* printf ("sendToSS, key %x, upDown %d\n",key,upDown); */
427 
428  /* if not enabled, do nothing */
429  if (!MYN) return;
430  if (MYN->__oldEnabled != MYN->enabled) {
431  MYN->__oldEnabled = MYN->enabled;
432  MARK_EVENT(X3D_NODE(MYN),offsetof (struct X3D_StringSensor, enabled));
433  }
434  if (!MYN->enabled) return;
435  /* printf ("sending key %x %u upDown %d to keySenors\n",key,key,upDown); */
436 
437  //actionKey = platform2web3dActionKey(key);
438  //translation moved to handle_XEvents
439  //#if !defined(AQUA) && !defined(_MSC_VER) // OLD_IPHONE_AQUA
440 
442  // by itself */
443  //if (actionKey == SFT_KEY) {
444  // shiftPressed = (upDown == KEYDOWN);
445  // return;
446  //}
447 
449  //if ((key >= 'a') && (key<='z'))
450  // if (shiftPressed)
451  // key=key-'a'+'A';
452  //#endif
453 
454  /* ignore the control key here. OSX will not event let one come this far... */
455  //if (actionKey == CTL_KEY) return;
456 
457  /* we only care about key presses here */
458  if (upDown != KEYPRESS) return;
459 
460 
461  /* is this initialized? */
462  if (!MYN->_initialized) {
463  FREE_IF_NZ(MYN->enteredText->strptr);
464  FREE_IF_NZ(MYN->finalText->strptr);
465  MYN->enteredText->strptr = MALLOC(char *, MAXSTRINGLEN+1);
466  MYN->finalText->strptr = MALLOC(char *, MAXSTRINGLEN+1);
467  MYN->enteredText->len=1;
468  MYN->finalText->len=1;
469  MYN->enteredText->strptr[0] = '\0';
470  MYN->finalText->strptr[0] = '\0';
471  MYN->_initialized = TRUE;
472  MYN->isActive = FALSE;
473  }
474 
475  /* enteredText */
476  if ((MYN->deletionAllowed) && (key==DEL_KEY)) {
477  if (MYN->enteredText->len > 1) {
478  MYN->enteredText->len--;
479  MYN->enteredText->strptr[MYN->enteredText->len-1] = '\0';
480  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, enteredText));
481  }
482  } else {
483  if ((key != RTN_KEY) && (key != DEL_KEY) && (MYN->enteredText->len < MAXSTRINGLEN-1)) {
484  MYN->enteredText->strptr[MYN->enteredText->len-1] = (char)key;
485  MYN->enteredText->strptr[MYN->enteredText->len] = '\0';
486  MYN->enteredText->len++;
487  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, enteredText));
488 
489  if (!MYN->isActive) {
490  MYN->isActive = TRUE;
491  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, isActive));
492  }
493 
494  }
495  }
496 
497 
498  /* finalText */
499  if (key==RTN_KEY) {
500  #ifdef VERBOSE
501  printf ("found return!\n");
502  printf ("current enteredText :%s:\n",MYN->enteredText->strptr);
503  printf ("current finalText :%s:\n",MYN->finalText->strptr);
504  #endif
505 
506  memcpy(MYN->finalText->strptr, MYN->enteredText->strptr, MAXSTRINGLEN);
507  MYN->finalText->len = MYN->enteredText->len;
508  MYN->enteredText->len=1;
509  MYN->enteredText->strptr[0] = '\0';
510  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, finalText));
511  /* MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, enteredText)); specs say don't gen an event here*/
512 
513  MYN->isActive = FALSE;
514  MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, isActive));
515 
516  #ifdef VERBOSE
517  printf ("finalText:%s:\n",MYN->finalText->strptr);
518  #endif
519  }
520 }
Definition: Vector.h:36
Definition: Viewer.h:174