FreeWRL / FreeX3D 4.3.0
Component_KeyDevice.c
1/*
2
3
4X3D 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/*
45I'll leave off comments about the validity of this part of the spec - it does
46not seem well thought out. I'll leave off my comments on what I really think
47about this part of the X3D Spec, because I'm nice, and I don't want to
48put other people's ideas down, especially in public, in source code, that
49will outlive me.
50
51So, if there is a KeyDevice node present, DO NOT use keys for FreeWRL navigation
52but instead, send any along that the Operating System GUI does not capture,
53and hope that they are not too badly mangled by intervening layers.
54
55Lets just hope that this part of the spec dies a convenient (and speedy)
56death!
57
58Anyway, with that, lets blindly forge along...
59
60*********************************************************************/
61
62// OLD_IPHONE_AQUA #ifndef AQUA
63int shiftPressed = 0;
64int 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 PBCK_KEY 0x08
85#define PRTN_KEY 13
86#define KEYPRESS 1
87#define KEYDOWN 2
88#define KEYUP 3
89
90#else
91
92#define PHOME_KEY 80
93#define PPGDN_KEY 86
94#define PLEFT_KEY 106
95#define PEND_KEY 87
96#define PUP_KEY 112
97#define PRIGHT_KEY 108
98#define PPGUP_KEY 85
99#define PDOWN_KEY 59
100#define PF1_KEY 0xFFBE
101#define PF12_KEY 0XFFC9
102#define PALT_KEY 0XFFE9 //left, and 0XFFEA //0XFFE7
103#define PCTL_KEY 0XFFE3 //left, and 0XFFE4 on right
104#define PSFT_KEY 0XFFE1 //left, and 0XFFE2 on right
105#define PDEL_KEY 0XFF9F //on numpad, and 0XFFFF near Insert //0x08
106#define PBCK_KEY 0x08 //not varified, using ascii
107#define KEYPRESS 1
108#define KEYDOWN 2
109#define KEYUP 3
110
111#endif
113// http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/keyboard.html
114//section 21.4.1
115//Key Value
116//Home 13
117//End 14
118//PGUP 15
119//PGDN 16
120//UP 17
121//DOWN 18
122//LEFT 19
123//RIGHT 20
124//F1-F12 1 to 12
125//ALT,CTRL,SHIFT true/false
126//*/
127//#define F1_KEY 1
128//#define F2_KEY 2
129//#define F3_KEY 3
130//#define F4_KEY 4
131//#define F5_KEY 5
132//#define F6_KEY 6
133//#define F7_KEY 7
134//#define F8_KEY 8
135//#define F9_KEY 9
136//#define F10_KEY 10
137//#define F11_KEY 11
138//#define F12_KEY 12
139//#define HOME_KEY 13
140//#define END_KEY 14
141//#define PGUP_KEY 15
142//#define PGDN_KEY 16
143//#define UP_KEY 17
144//#define DOWN_KEY 18
145//#define LEFT_KEY 19
146//#define RIGHT_KEY 20
147//#define ALT_KEY 30 /* not available on OSX */
148//#define CTL_KEY 31 /* not available on OSX */
149//#define SFT_KEY 32 /* not available on OSX */
150//#define DEL_KEY 0XFFFF /* problem: I'm insterting this back into the translated char stream so 0XFFFF too high to clash with a latin? */
151//#define RTN_KEY 13 //what about 10 newline?
152//#define NUM0 40
153//#define NUM1 41
154//#define NUM2 42
155//#define NUM3 43
156//#define NUM4 44
157//#define NUM5 45
158//#define NUM6 46
159//#define NUM7 47
160//#define NUM8 48
161//#define NUM9 49
162//#define NUMDEC 50
163
164
165int platform2web3dActionKey(int platformKey)
166{
167 int key;
168
169 key = 0; //platformKey;
170 if(platformKey >= PF1_KEY && platformKey <= PF12_KEY)
171 key = platformKey - PF1_KEY + F1_KEY;
172 else
173 switch(platformKey)
174 {
175 case PHOME_KEY:
176 key = HOME_KEY; break;
177 case PEND_KEY:
178 key = END_KEY; break;
179 case PPGDN_KEY:
180 key = PGDN_KEY; break;
181 case PPGUP_KEY:
182 key = PGUP_KEY; break;
183 case PUP_KEY:
184 key = UP_KEY; break;
185 case PDOWN_KEY:
186 key = DOWN_KEY; break;
187 case PLEFT_KEY:
188 key = LEFT_KEY; break;
189 case PRIGHT_KEY:
190 key = RIGHT_KEY; break;
191 case PDEL_KEY:
192 key = DEL_KEY; break;
193 case PALT_KEY:
194 key = ALT_KEY; break;
195 case PCTL_KEY:
196 key = CTL_KEY; break;
197 case PSFT_KEY:
198 key = SFT_KEY; break;
199 default:
200 key = 0;
201 }
202 return key;
203}
204
205
206/* only keep 1 keyDevice node around; we can make a list if that is eventually
207required by the spec. From what I can see, the spec is silent on this regard */
208
209//static struct X3D_Node **keySink = NULL;
210//static int keySyncMallocLen = 0;
211//static int keySinkCurMax = 0;
212
213typedef struct pComponent_KeyDevice{
214 //struct X3D_Node **keySink;// = NULL;
215 //int keySyncMallocLen;// = 0;
216 //int keySinkCurMax;// = 0;
217 struct Vector *keySink;
219void *Component_KeyDevice_constructor(){
220 void *v = MALLOCV(sizeof(struct pComponent_KeyDevice));
221 memset(v,0,sizeof(struct pComponent_KeyDevice));
222 return v;
223}
224void Component_KeyDevice_init(struct tComponent_KeyDevice *t){
225 //public
226 //private
227 t->prv = Component_KeyDevice_constructor();
228 {
230 p->keySink = NULL;
231 //p->keySyncMallocLen = 0;
232 //p->keySinkCurMax = 0;
233
234 }
235}
236//ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
237
238static void sendToSS(struct X3D_Node *wsk, int key, int upDown);
239static void sendToKS(struct X3D_Node* wsk, int key, int upDown);
240
241//static void incrementKeySinkList() {
242// ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
243// if (p->keySinkCurMax >= p->keySyncMallocLen) {
244// p->keySyncMallocLen += 10; /* arbitrary number */
245// p->keySink = REALLOC(p->keySink, sizeof (struct X3D_Node *) * p->keySyncMallocLen);
246// }
247//}
248
249int KeySensorNodePresent() {
250 int count;
251 struct X3D_Node *node;
252 ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
253
254 /* no KeyDevice node present */
255 if (p->keySink == NULL) return FALSE;
256
257 for (count=0; count < vectorSize(p->keySink); count++) {
258 /* hmmm, there is one, but is it enabled? */
259 /* printf ("ks, checking %d\n",p->keySink[count]); */
260 node = vector_get(struct X3D_Node*,p->keySink,count);
261 if(node && node->_nodeType == NODE_KeySensor)
262 if (X3D_KEYSENSOR(node)->enabled) return TRUE;
263 if(node && node->_nodeType == NODE_StringSensor)
264 if (X3D_STRINGSENSOR(node)->enabled) return TRUE;
265 }
266
267 return FALSE;
268}
269
270
271void addNodeToKeySensorList(struct X3D_Node* node) {
272 if ((node->_nodeType == NODE_KeySensor) || (node->_nodeType == NODE_StringSensor)) {
273 ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
274 //incrementKeySinkList();
275 if(!p->keySink)
276 p->keySink = newVector(struct X3D_Node*,4);
277 vector_pushBack(struct X3D_Node*,p->keySink,node);
278 //p->keySink[p->keySinkCurMax] = node;
279 //p->keySinkCurMax ++;
280 }
281}
282int removeNodeFromVector(int iaction, struct Vector *v, struct X3D_Node *node);
283void removeNodeFromKeySensorList(struct X3D_Node* node) {
284 if ((node->_nodeType == NODE_KeySensor) || (node->_nodeType == NODE_StringSensor)) {
285 ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
286
287 if(p->keySink && node)
288 removeNodeFromVector(0, p->keySink, node);
289 }
290}
291
292void killKeySensorNodeList() {
293 ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
294 FREE_IF_NZ(p->keySink);
295 //p->keySyncMallocLen = 0;
296 //p->keySinkCurMax = 0;
297 if(p->keySink)
298 deleteVector(struct X3D_Node*, p->keySink);
299 // OLD_IPHONE_AQUA #ifndef AQUA
300 shiftPressed = 0;
301 ctrlPressed = 0;
302 // OLD_IPHONE_AQUA #endif
303}
304
305void updateSingletonStringSensor(){
306 //not part of specs, a dug9 initiiative to experiment
307 //with have a single stringsensor enabled at a time
308 //in here, if any SS went from disabled to enabled, then
309 //disable all the others.
310 int count;
311 struct X3D_Node *node;
312 struct X3D_StringSensor *singleton, *snode, *other;
313 ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
314 if (p->keySink == NULL) return;
315
316 singleton = snode = other = NULL;
317 for (count=0; count < vectorSize(p->keySink); count++) {
318 #ifdef VERBOSE
319 printf ("sendKeyToKeySensor, sending key %d to %d of %d\n",key,count,p->keySinkCurMax);
320 #endif
321 node = vector_get(struct X3D_Node*,p->keySink,count);
322 /* make sure this has not been deleted - we should really re-create list, but
323 so few keySensor X3D nodes are in use, who cares? */
324 if (checkNode(node,__FILE__,__LINE__)) {
325 if (node->_nodeType == NODE_StringSensor ){
326 struct X3D_StringSensor *snode = (struct X3D_StringSensor*)node;
327 if(snode->singleton == TRUE) //playing dug9 singleton game
328 if(snode->enabled == TRUE && snode->__oldEnabled == FALSE){
329 //this one just became the active one, disable all the others.
330 singleton = snode;
331 break;
332 }
333
334 }
335 }
336 }
337 if(!singleton) return;
338
339 for (count=0; count < vectorSize(p->keySink); count++) {
340 #ifdef VERBOSE
341 printf ("sendKeyToKeySensor, sending key %d to %d of %d\n",key,count,p->keySinkCurMax);
342 #endif
343 node = vector_get(struct X3D_Node*,p->keySink,count);
344 /* make sure this has not been deleted - we should really re-create list, but
345 so few keySensor X3D nodes are in use, who cares? */
346 if (checkNode(node,__FILE__,__LINE__)) {
347 if (node->_nodeType == NODE_StringSensor && node != X3D_NODE(singleton) ){
348 struct X3D_StringSensor *other = (struct X3D_StringSensor*)node;
349 if(other->singleton == TRUE) //playing dug9 singleton game
350 if(other->enabled == TRUE){
351 other->__oldEnabled = other->enabled;
352 other->enabled = FALSE;
353 MARK_EVENT(X3D_NODE(other),offsetof (struct X3D_StringSensor, enabled));
354 }
355 }
356 }
357 }
358
359}
360void sendKeyToKeySensor(const char key, int upDown) {
361 int count;
362 struct X3D_Node *node;
363 ppComponent_KeyDevice p = (ppComponent_KeyDevice)gglobal()->Component_KeyDevice.prv;
364 if (p->keySink == NULL) return;
365
366 updateSingletonStringSensor();
367 for (count=0; count < vectorSize(p->keySink); count++) {
368 #ifdef VERBOSE
369 printf ("sendKeyToKeySensor, sending key %d to %d of %d\n",key,count,p->keySinkCurMax);
370 #endif
371 node = vector_get(struct X3D_Node*,p->keySink,count);
372 /* make sure this has not been deleted - we should really re-create list, but
373 so few keySensor X3D nodes are in use, who cares? */
374 if (checkNode(node,__FILE__,__LINE__)) {
375 if(upDown%10 == KEYDOWN || upDown%10 == KEYUP) //2 down, or 3 up
376 if (node->_nodeType == NODE_KeySensor ) sendToKS(node, (int)key&0xFFFF, upDown);
377 if(upDown == KEYPRESS) //LINUX,WIN32 PRESS=1, aqua apple PRESS=2
378 if (node->_nodeType == NODE_StringSensor ) sendToSS(node, (int)key&0xFFFF, upDown);
379 }
380 }
381}
382
383
384/*******************************************************/
385
386static void sendToKS(struct X3D_Node* wsk, int key, int upDown) {
387 int actionKey;
388 int isDown;
389 int isActionKey;
390 #define MYN X3D_KEYSENSOR(wsk)
391 /* printf ("sending key %x %u upDown %d (down %d) to keySenors\n",key,key,upDown,KEYDOWN); */
392
393 /* if not enabled, do nothing */
394 if (!MYN)
395 return;
396 if (MYN->__oldEnabled != MYN->enabled) {
397 MYN->__oldEnabled = MYN->enabled;
398 MARK_EVENT(X3D_NODE(MYN),offsetof (struct X3D_KeySensor, enabled));
399 }
400 if (!MYN->enabled)
401 return;
402
403 /* is this an ACTION (tm) key press or release? */
404 isDown = upDown%10 == KeyPress;
405 isActionKey = upDown / 10;
406 if(isActionKey)
407 {
408 actionKey = key;
409 switch (actionKey) {
410 case HOME_KEY:
411 case PGDN_KEY:
412 case LEFT_KEY:
413 case END_KEY:
414 case UP_KEY:
415 case RIGHT_KEY:
416 case PGUP_KEY:
417 case DOWN_KEY:
418 case F1_KEY:
419 case F2_KEY:
420 case F3_KEY:
421 case F4_KEY:
422 case F5_KEY:
423 case F6_KEY:
424 case F7_KEY:
425 case F8_KEY:
426 case F9_KEY:
427 case F10_KEY:
428 case F11_KEY:
429 case F12_KEY:
430 /* no DEL key here*/
431 if (isDown) {
432 MYN->actionKeyPress = actionKey; //TRUE;
433 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, actionKeyPress));
434 } else {
435 MYN->actionKeyRelease = actionKey; //TRUE;
436 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, actionKeyRelease));
437 }
438 break;
439 case ALT_KEY:
440 /* now, for some of the other keys, the ones that are modifiers, not ACTION (tm) keys. */
441 MYN->altKey = isDown;
442 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, altKey));
443 break;
444 case CTL_KEY:
445 MYN->controlKey = isDown;
446 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, controlKey));
447 break;
448 case SFT_KEY:
449 MYN->shiftKey = isDown;
450 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, shiftKey));
451 break;
452 default:
453 break;
454 }/*end switch */
455 } else {
456 /* regular key including RTN */
457 if ((MYN->keyPress->len != 2) || (MYN->keyRelease->len != 2)) {
458 FREE_IF_NZ(MYN->keyPress->strptr);
459 FREE_IF_NZ(MYN->keyRelease->strptr);
460 MYN->keyPress = newASCIIString ("a");
461 MYN->keyRelease = newASCIIString ("a");
462 }
463
464 if (isDown) {
465 MYN->keyPress->strptr[0] = (char) (key&0xFF);
466 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, keyPress));
467 } else {
468 MYN->keyRelease->strptr[0] = (char) (key&0xFF);
469 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, keyRelease));
470 }
471 }
472
473 /* now, presumably "isActive" means that the key is down... */
474 MYN->isActive = isDown;
475 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_KeySensor, isActive));
476 #undef MYN
477
478}
479
480static void (*fwl_clipboard_copy)(char *str) = NULL;
481static void (*fwl_clipboard_paste)() = NULL;
482//if your front end can do clipboard copy&paste,
483//and you want to enable it for stringsensor
484//then call these fwl_set functions with your frontend functions
485//fwWindow32.c calls them for win32
486void fwl_set_clipboard_copy( void (*fn)(char *)){
487 fwl_clipboard_copy = fn;
488}
489void fwl_set_clipboard_paste( void (*fn)()){
490 fwl_clipboard_paste = fn;
491}
492static void sendToSS(struct X3D_Node *wsk, int key, int upDown) {
493 //int actionKey;
494 #define MYN X3D_STRINGSENSOR(wsk)
495 #define MAXSTRINGLEN 512
496
497 /* printf ("SS, %u enabled %d\n",wsk, MYN->enabled); */
498 /* printf ("sendToSS, key %x, upDown %d\n",key,upDown); */
499
500 /* if not enabled, do nothing */
501 if (!MYN) return;
502 if (MYN->__oldEnabled != MYN->enabled) {
503 MYN->__oldEnabled = MYN->enabled;
504 MARK_EVENT(X3D_NODE(MYN),offsetof (struct X3D_StringSensor, enabled));
505 }
506 if (!MYN->enabled) return;
507 /* printf ("sending key %x %u upDown %d to keySenors\n",key,key,upDown); */
508
509 //actionKey = platform2web3dActionKey(key);
510 //translation moved to handle_XEvents
511 //#if !defined(AQUA) && !defined(_MSC_VER) // OLD_IPHONE_AQUA
512
514 // by itself */
515 //if (actionKey == SFT_KEY) {
516 // shiftPressed = (upDown == KEYDOWN);
517 // return;
518 //}
519
521 //if ((key >= 'a') && (key<='z'))
522 // if (shiftPressed)
523 // key=key-'a'+'A';
524 //#endif
525
526 /* ignore the control key here. OSX will not event let one come this far... */
527 //if (actionKey == CTL_KEY) return;
528
529 /* we only care about key presses here */
530 if (upDown != KEYPRESS) return;
531
532
533 /* is this initialized? */
534 if (!MYN->_initialized) {
535 FREE_IF_NZ(MYN->enteredText->strptr);
536 FREE_IF_NZ(MYN->finalText->strptr);
537 MYN->enteredText->strptr = MALLOC(char *, MAXSTRINGLEN+1);
538 MYN->finalText->strptr = MALLOC(char *, MAXSTRINGLEN+1);
539 MYN->enteredText->len=1;
540 MYN->finalText->len=1;
541 MYN->enteredText->strptr[0] = '\0';
542 MYN->finalText->strptr[0] = '\0';
543 MYN->_initialized = TRUE;
544 MYN->isActive = FALSE;
545 }
546 if(key == 22){
547 //CTRL-V clipboard paste
548 if(fwl_clipboard_paste){
549 if (!MYN->isActive) {
550 MYN->isActive = TRUE;
551 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, isActive));
552 }
553 fwl_clipboard_paste(); //recurses in here, so clean any 22 and 3 from clip text
554 return;
555 }
556 }else if(key == 3){
557 //CTRL-C copy to clipboard
558 if(fwl_clipboard_copy){
559 //printf ("copying finalText :%s: len %d\n",MYN->finalText->strptr,strlen(MYN->finalText->strptr));
560 fwl_clipboard_copy(MYN->finalText->strptr);
561 return;
562 }
563 }
564 if ((MYN->deletionAllowed) && ((key==DEL_KEY) || (key == 8))) {
565 /* enteredText */
566 if(!MYN->isActive){
567 MYN->enteredText->len = 1;
568 MYN->enteredText->strptr[0] = '\0';
569 MYN->isActive = TRUE;
570 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, enteredText));
571 }
572 if (MYN->enteredText->len > 1) {
573 MYN->enteredText->len--;
574 MYN->enteredText->strptr[MYN->enteredText->len-1] = '\0';
575 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, enteredText));
576 }
577 } else {
578 if ((key != RTN_KEY) && !((key == DEL_KEY)||(key == 8)) && (MYN->enteredText->len < MAXSTRINGLEN-1)) {
579 MYN->enteredText->strptr[MYN->enteredText->len-1] = (char)key;
580 MYN->enteredText->strptr[MYN->enteredText->len] = '\0';
581 MYN->enteredText->len++;
582 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, enteredText));
583
584 if (!MYN->isActive) {
585 MYN->isActive = TRUE;
586 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, isActive));
587 }
588
589 }
590 }
591
592
593 /* finalText */
594 if (key==RTN_KEY) {
595 #ifdef VERBOSE
596 printf ("found return!\n");
597 printf ("current enteredText :%s: len %d\n",MYN->enteredText->strptr, strlen(MYN->enteredText->strptr));
598 printf ("current finalText :%s: len %d\n",MYN->finalText->strptr,strlen(MYN->finalText->strptr));
599 #endif
600
601
602 memcpy(MYN->finalText->strptr, MYN->enteredText->strptr, MAXSTRINGLEN);
603 MYN->finalText->len = MYN->enteredText->len;
604 #ifdef VERBOSE
605 printf ("final finalText :%s: len %d\n",MYN->finalText->strptr,strlen(MYN->finalText->strptr));
606 #endif
607
608 //MYN->enteredText->len=1;
609 //MYN->enteredText->strptr[0] = '\0';
610 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, finalText));
611 /* MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, enteredText)); specs say don't gen an event here*/
612
613 MYN->isActive = FALSE;
614 MARK_EVENT(X3D_NODE(MYN), offsetof (struct X3D_StringSensor, isActive));
615
616 #ifdef VERBOSE
617 printf ("finalText:%s:\n",MYN->finalText->strptr);
618 #endif
619 }
620}
Definition Viewer.h:139