1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10 #include "../base/defines.h"
11
12
13 #include "ErrorDialogManager.h"
14 #include "DXApplication.h"
15 #include "DXVersion.h"
16 #include "DXWindow.h"
17 #include "Command.h"
18 #include "DXExecCtl.h"
19 #include "List.h"
20 #include "ListIterator.h"
21 #include "Network.h"
22 #include "Node.h"
23 #include "SequencerNode.h"
24 #include "ImageNode.h"
25 #include "ColormapNode.h"
26 #include "DisplayNode.h"
27 #include "ImageWindow.h"
28 #include "EditorWindow.h"
29 #include "ProbeNode.h"
30 #include "PickNode.h"
31 #include "DXLInputNode.h"
32 #include "CmdEntry.h"
33 #include "ControlPanel.h"
34 #include "MacroDefinition.h"
35 #include "ViewControlDialog.h"
36 #include "DXLinkHandler.h"
37 #include <ctype.h>
38 #include <stdarg.h>
39
40 /*
41 * What follows is a set of routines to handle the DX Application commands.
42 * It's essentially unchanged.
43 */
44
45 #define QUALIFIER_NONE 0
46 #define QUALIFIER_LABEL 1
47 #define QUALIFIER_TITLE 2
48
MakeQualifiedNodeList(const char * classname,char * p,boolean includeSubclasses)49 static List *MakeQualifiedNodeList(const char *classname, char *p,
50 boolean includeSubclasses)
51 {
52 int qualifierType;
53 char *qualifier=NULL;
54 List *result = NUL(List *);
55
56 if (!p || !*p)
57 qualifierType = QUALIFIER_NONE;
58
59 else if (EqualSubstring(p, "title=", 6))
60 {
61 qualifierType = QUALIFIER_TITLE;
62 qualifier = p+6;
63 }
64 else if (EqualSubstring(p, "label=", 6))
65 {
66 qualifierType = QUALIFIER_LABEL;
67 qualifier = p+6;
68 }
69 else
70 {
71 qualifierType = QUALIFIER_LABEL;
72 qualifier = p;
73 }
74
75 if (qualifierType == QUALIFIER_NONE)
76 {
77 result =
78 theDXApplication->network->makeClassifiedNodeList(classname,
79 includeSubclasses);
80 }
81 else if (qualifierType == QUALIFIER_LABEL)
82 {
83 Node *node;
84 #if 00
85 List *list =
86 theDXApplication->network->makeLabelledNodeList(qualifier);
87
88
89 result = new List;
90
91 if (list)
92 {
93 ListIterator it(*list);
94 while (NULL != (node = (Node *)it.getNext()))
95 if (node->isA(classname))
96 result->appendElement((const void *)node);
97
98 delete list;
99 }
100 #else
101 List *list =
102 theDXApplication->network->makeClassifiedNodeList(classname,
103 includeSubclasses);
104
105 if (list)
106 {
107 ListIterator it(*list);
108 while ( (node = (Node *)it.getNext()) )
109 if (EqualString(node->getLabelString(),qualifier)) {
110 if (!result)
111 result = new List;
112 result->appendElement((const void *)node);
113 }
114
115 delete list;
116 }
117
118 #endif
119 }
120 else
121 {
122
123 List *list =
124 theDXApplication->network->makeClassifiedNodeList(classname,
125 includeSubclasses);
126
127 if (list)
128 {
129 Node *node;
130 ListIterator it(*list);
131 while (NULL != (node = (Node *)it.getNext()))
132 if (EqualString(qualifier, node->getTitle())) {
133 if (!result)
134 result = new List;
135 result->appendElement((const void *)node);
136 }
137
138 delete list;
139 }
140
141 }
142
143 return result;
144 }
145
OpenColormapEditor(const char * c,int id,void * va)146 boolean DXLinkHandler::OpenColormapEditor(const char *c, int id, void *va)
147 {
148 char *p;
149
150 for (p = (char *)c; p && *p && isspace(*p); p++);
151
152 List *list = MakeQualifiedNodeList(ClassColormapNode, p, FALSE);
153
154 if (!list)
155 {
156 DXLinkHandler *a = (DXLinkHandler*)va;
157 char buffer[1024];
158 sprintf(buffer,"OpenColormapEditor: invalid qualifier (%s)", p);
159 a->sendPacket(DXPacketIF::PKTERROR,id,buffer);
160 return FALSE;
161 }
162
163 ListIterator it(*list);
164 ColormapNode *cnode;
165
166 while (NULL != (cnode = (ColormapNode *)it.getNext())) {
167 DXWindow *win = cnode->getDXWindow();;
168 if (!win)
169 cnode->openDefaultWindow(NULL);
170 else if (!win->isManaged())
171 win->manage();
172 }
173
174 delete list;
175
176 return TRUE;
177 }
178
CloseColormapEditor(const char * c,int id,void * va)179 boolean DXLinkHandler::CloseColormapEditor(const char *c, int id, void *va)
180 {
181 char *p;
182
183 for (p = (char *)c; p && *p && isspace(*p); p++);
184
185 List *list = MakeQualifiedNodeList(ClassColormapNode, p, FALSE);
186
187 if (!list)
188 {
189 DXLinkHandler *a = (DXLinkHandler*)va;
190 char buffer[1024];
191 sprintf(buffer,"CloseColormapEditor: invalid qualifier (%s)", p);
192 a->sendPacket(DXPacketIF::PKTERROR,id,buffer);
193 return FALSE;
194 }
195
196 ListIterator it(*list);
197 ColormapNode *cnode;
198
199 while (NULL != (cnode = (ColormapNode *)it.getNext()))
200 {
201 DXWindow *win = cnode->getDXWindow();
202 if (win)
203 win->unmanage();
204 }
205
206 delete list;
207
208 return TRUE;
209 }
210
SetHWRendering(const char * c,int id,void * va)211 boolean DXLinkHandler::SetHWRendering(const char *c, int id, void *va)
212 {
213 DXLinkHandler *dxlh = (DXLinkHandler*)va;
214 return dxlh->setRenderMode(c, id,FALSE);
215 }
SetSWRendering(const char * c,int id,void * va)216 boolean DXLinkHandler::SetSWRendering(const char *c, int id, void *va)
217 {
218 DXLinkHandler *dxlh = (DXLinkHandler*)va;
219 return dxlh->setRenderMode(c, id, TRUE);
220 }
setRenderMode(const char * msg,int id,boolean swmode)221 boolean DXLinkHandler::setRenderMode(const char *msg, int id, boolean swmode)
222 {
223 char *p;
224 ImageNode *node;
225
226 for (p = (char *)msg; p && *p && isspace(*p); p++);
227
228 List *list = MakeQualifiedNodeList(ClassImageNode, p, FALSE);
229
230 if (! list)
231 {
232 char buffer[1024];
233 sprintf(buffer, "SetRenderMode: "
234 "unable to set Image render mode (%s)", msg);
235 this->sendPacket(DXPacketIF::PKTERROR,id,buffer);
236 return FALSE;
237 }
238
239 ListIterator it(*list);
240 while (NULL != (node = (ImageNode *)it.getNext()))
241 {
242 ImageWindow *win = (ImageWindow*)node->getDXWindow();
243 if (win)
244 win->setSoftware(swmode);
245 }
246 delete list;
247 return TRUE;
248
249 }
250
OpenImage(const char * c,int id,void * va)251 boolean DXLinkHandler::OpenImage(const char *c, int id, void *va)
252 {
253 char *p;
254 Node *node;
255
256 for (p = (char *)c; p && *p && isspace(*p); p++);
257
258 List *list = MakeQualifiedNodeList(ClassDisplayNode, p, TRUE);
259
260 if (! list)
261 {
262 DXLinkHandler *a = (DXLinkHandler*)va;
263 char buffer[1024];
264 sprintf(buffer, "OpenImage: unable to open image (%s)", c);
265 a->sendPacket(DXPacketIF::PKTERROR,id,buffer);
266 return FALSE;
267 }
268
269 ListIterator it(*list);
270
271 while (NULL != (node = (Node *)it.getNext()))
272 {
273 DXWindow *win = node->getDXWindow();
274 if (!win)
275 ((DisplayNode*)node)->openImageWindow();
276 else
277 win->manage();
278 }
279
280 delete list;
281
282 return TRUE;
283 }
284
CloseImage(const char * c,int id,void * va)285 boolean DXLinkHandler::CloseImage(const char *c, int id, void *va)
286 {
287 char *p;
288 Node *node;
289
290 for (p = (char *)c; p && *p && isspace(*p); p++);
291
292 List *list = MakeQualifiedNodeList(ClassDisplayNode, p, TRUE);
293
294 if (! list)
295 {
296 DXLinkHandler *a = (DXLinkHandler*)va;
297 char buffer[1024];
298 sprintf(buffer, "OpenImage: unable to open image (%s)", c);
299 a->sendPacket(DXPacketIF::PKTERROR,id, buffer);
300 return FALSE;
301 }
302
303 ListIterator it(*list);
304
305 while (NULL != (node = (Node *)it.getNext()))
306 {
307 DXWindow *win = node->getDXWindow();
308 if (win)
309 win->unmanage();
310 }
311
312 delete list;
313
314 return TRUE;
315 }
316
OpenSequencer(const char * c,int id,void * va)317 boolean DXLinkHandler::OpenSequencer(const char *c, int id, void *va)
318 {
319 SequencerNode *seq = theDXApplication->network->sequencer;
320
321 if (seq) {
322 DXWindow *win = seq->getDXWindow();
323 if (!win)
324 seq->openDefaultWindow(theDXApplication->getRootWidget());
325 else if (!win->isManaged())
326 win->manage();
327 }
328
329 return TRUE;
330 }
331
CloseSequencer(const char * c,int id,void * va)332 boolean DXLinkHandler::CloseSequencer(const char *c, int id, void *va)
333 {
334 SequencerNode *seq = theDXApplication->network->sequencer;
335
336 if (seq)
337 {
338 DXWindow *win = seq->getDXWindow();
339 if (win)
340 win->unmanage();
341 }
342
343 return TRUE;
344 }
345
346
OpenVPE(const char * c,int id,void * va)347 boolean DXLinkHandler::OpenVPE(const char *c, int id, void *va)
348 {
349 EditorWindow *editor = theDXApplication->network->getEditor();
350
351 if (! editor)
352 editor = theDXApplication->newNetworkEditor(theDXApplication->network);
353
354 if (! editor)
355 {
356 DXLinkHandler *a = (DXLinkHandler*)va;
357 a->sendPacket(DXPacketIF::PKTERROR, id,
358 "cannot create editor");
359 return FALSE;
360 }
361
362 if (!editor->isManaged()) {
363 editor->manage();
364
365 XMapRaised(XtDisplay(editor->getRootWidget()),
366 XtWindow(editor->getRootWidget()));
367 }
368
369 return TRUE;
370
371 }
372
CloseVPE(const char * c,int id,void * va)373 boolean DXLinkHandler::CloseVPE(const char *c, int id, void *va)
374 {
375 EditorWindow *editor = theDXApplication->network->getEditor();
376
377 if (! editor)
378 return TRUE;
379
380 editor->unmanage();
381
382 return TRUE;
383
384 }
385
386 /*
387 This call is apparently written to accomodate a file string
388 of the form "Myprog.net Mycfg.cfg" rather than just "Myprog.net"
389 Thus it looks for 2 strings separated by a space. This causes
390 a problem for the PC since directories may have a space in them.
391 Fortunately this ability to specify the .cfg file isn't included
392 in the docs for the DXLLoadVisualProgram call, so removing this feature
393 from the PC version shouldn't cause any problems - but I'll leave it
394 in the Unix code. F Suits 5/97
395 Oh - it appears it always had a bug because the line that says *d = '\0';
396 used to say *d = '0';
397
398 I believe this to be a problem. UN*X machines can also send paths
399 with spaces for file names. MacOS X users will commonly do this; thus
400 I will rewrite it to look to see if two files are being passed in (for
401 a .net and a .cfg); if not, then just remove leading and trailing spaces.
402 */
OpenNetwork(const char * c,int id,void * va)403 boolean DXLinkHandler::OpenNetwork(const char *c, int id, void *va)
404 {
405 char *buf = new char[strlen(c)+1];
406 char *d, *e, *cfg, *net;
407 int len=0;
408
409 if( !c )
410 return TRUE;
411
412 e = buf;
413 strcpy(buf, c);
414 /* remove leading spaces */
415
416 if (isspace(*e))
417 while (isspace(*e++));
418
419 if(! *e)
420 return TRUE;
421
422 /* remove trailing spaces */
423
424 len = strlen(e);
425 d = (len<=0?e:e+len-1);
426
427 if (isspace(*d)) {
428 while(isspace(*d--));
429 d++; *d = '\0';
430 }
431
432 d = net = buf;
433
434 /* Now determine if there are two filenames passed in */
435
436 if (strstr(buf, "net") != NULL && strstr(buf, "cfg") != NULL) {
437
438 /* Use old routine to get filenames for both net and cfg. File
439 names cannot contain spaces.
440 */
441
442 do {
443 d++;
444 } while (*d && !isspace(*d));
445
446 *d++ = '\0';
447 e=d;
448
449 if (*e && isspace(*e))
450 while (isspace(*e++));
451
452 if (! *e)
453 cfg = NULL;
454 else
455 {
456 cfg = e;
457 }
458 } else {
459 cfg = NULL;
460 }
461
462 theDXApplication->setBusyCursor(TRUE);
463
464 boolean r;
465 if (!theDXApplication->openFile(net, cfg))
466 {
467 DXLinkHandler *a = (DXLinkHandler*)va;
468 char buffer[1024];
469 sprintf(buffer, "Error opening network file %s", c);
470 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
471 r = FALSE;
472 }
473 else
474 {
475 r = TRUE;
476 }
477 theDXApplication->setBusyCursor(FALSE);
478
479 delete buf;
480 return r;
481 }
482
SaveNetwork(const char * c,int id,void * va)483 boolean DXLinkHandler::SaveNetwork(const char *c, int id, void *va)
484 {
485 char *buf = new char[strlen(c)+1];
486 char *d, *net;
487
488 if (isspace(*c))
489 while (isspace(*c++));
490
491 if (! *c)
492 net = NULL;
493 else
494 {
495 d = net = buf;
496 do {
497 *d++ = *c++;
498 } while (*c && !isspace(*c));
499
500 *d++ = '\0';
501
502 if (*c && isspace(*c))
503 while (isspace(*c++));
504
505 if (*c)
506 {
507 /*cfg = d;*/
508 do {
509 *d++ = *c++;
510 } while (*c && !isspace(*c));
511
512 *d = '0';
513 }
514 /*else
515 cfg = NULL;*/
516 }
517
518 theDXApplication->setBusyCursor(TRUE);
519 boolean r;
520 if (!theDXApplication->saveFile(net, FALSE))
521 {
522 DXLinkHandler *a = (DXLinkHandler*)va;
523 char buffer[1024];
524 if (net)
525 sprintf(buffer, "Error saving network file %s", net);
526 else
527 sprintf(buffer, "Error saving network file %s",
528 theDXApplication->network->getFileName());
529 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
530 r = FALSE;
531 }
532 else
533 {
534 r = TRUE;
535 }
536 theDXApplication->setBusyCursor(FALSE);
537
538 delete buf;
539 return r;
540 }
541
OpenNetworkNoReset(const char * c,int id,void * va)542 boolean DXLinkHandler::OpenNetworkNoReset(const char *c, int id, void *va)
543 {
544 char *buf = new char[strlen(c)+1];
545 char *d, *cfg, *net;
546
547 if (isspace(*c))
548 while (isspace(*c++));
549
550 if (! *c)
551 return TRUE;
552
553 d = net = buf;
554 do {
555 *d++ = *c++;
556 } while (*c && !isspace(*c));
557
558 *d++ = '\0';
559
560 if (*c && isspace(*c))
561 while (isspace(*c++));
562
563 if (! *c)
564 cfg = NULL;
565 else
566 {
567 cfg = d;
568 do {
569 *d++ = *c++;
570 } while (*c && !isspace(*c));
571
572 *d = '0';
573 }
574
575 boolean r;
576 if (!theDXApplication->openFile(net, cfg, 0))
577 {
578 DXLinkHandler *a = (DXLinkHandler*)va;
579 char buffer[1024];
580 sprintf(buffer, "Error opening network file %s", c);
581 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
582 r = FALSE;
583 }
584 else
585 {
586 r = TRUE;
587 }
588
589 delete buf;
590 return r;
591 }
592
OpenConfig(const char * c,int id,void * va)593 boolean DXLinkHandler::OpenConfig(const char *c, int id, void *va)
594 {
595 boolean r;
596
597 theDXApplication->setBusyCursor(TRUE);
598 if (!theDXApplication->network->openCfgFile(c, TRUE))
599 {
600 DXLinkHandler *a = (DXLinkHandler*)va;
601 char buffer[1024];
602 sprintf(buffer, "Error openning configuration file %s", c);
603 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
604 r = FALSE;
605 }
606 else
607 r = TRUE;
608 theDXApplication->setBusyCursor(FALSE);
609
610 return r;
611 }
612
StallUntil(const char * c,int id,void * va)613 boolean DXLinkHandler::StallUntil(const char *c, int id, void *va)
614 {
615 DXLinkHandler *a = (DXLinkHandler*)va;
616 PacketIF *pif = a->getPacketIF();
617
618 if (getenv("DX_STALL") != NULL)
619 return FALSE;
620
621 if (pif->isPacketHandlingStalled())
622 return FALSE;
623
624 if (strstr(c, "idle")) {
625 pif->stallPacketHandling(DXLinkHandler::DestallOnNoExecution,
626 theDXApplication->getExecCtl());
627 } else if (strstr(c,"count")) {
628 int count = 0;
629 if (sscanf(c,"count %d",&count) == 1) {
630 a->stallCount = count;
631 pif->stallPacketHandling(DXLinkHandler::StallNTimes,a);
632 }
633 }
634 return TRUE;
635 }
636
StallNTimes(void * data)637 boolean DXLinkHandler::StallNTimes(void *data)
638 {
639 DXLinkHandler *dlh = (DXLinkHandler*)data;
640
641 if (getenv("DX_STALL") != NULL)
642 return TRUE;
643
644 ASSERT(dlh->stallCount > 0);
645 dlh->stallCount--;
646 return dlh->stallCount == 0;
647 }
648
DestallOnNoExecution(void * data)649 boolean DXLinkHandler::DestallOnNoExecution(void *data)
650 {
651 DXExecCtl *ctl = (DXExecCtl*)data;
652
653 if (getenv("DX_STALL") != NULL)
654 return TRUE;
655
656 return !ctl->isExecuting();
657 }
658
659 //
660 // Don't handle packets of the packet interface associated with this
661 // LinkHandler until a packet comes across the primary packet interface
662 // (to the exec) that says it is done executing.
663 //
stallForExecutionIfRequired()664 void DXLinkHandler::stallForExecutionIfRequired()
665 {
666 PacketIF *pif = this->getPacketIF();
667
668 if (getenv("DX_STALL") != NULL)
669 return;
670
671 if ((pif != theDXApplication->getPacketIF()) &&
672 !pif->isPacketHandlingStalled())
673 pif->stallPacketHandling(DestallOnNoExecution,
674 theDXApplication->getExecCtl());
675 }
676
677
SaveConfig(const char * c,int id,void * va)678 boolean DXLinkHandler::SaveConfig(const char *c, int id, void *va)
679 {
680 boolean r;
681 theDXApplication->setBusyCursor(TRUE);
682 if (!theDXApplication->network->saveCfgFile(c))
683 {
684 DXLinkHandler *a = (DXLinkHandler*)va;
685 char buffer[1024];
686 sprintf(buffer, "Error saving configuration file %s", c);
687 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
688 r = FALSE;
689 }
690 else
691 r = TRUE;
692 theDXApplication->setBusyCursor(FALSE);
693 return r;
694 }
695 //
696 // Expect in c a string with 'var = value' format. The var is used to
697 // find a DXLInputNode in the main network. If one is found with the
698 // same label, then set its input (and send it), otherwise, just send
699 // the assigment to the executive.
700 //
SetGlobalValue(const char * c,int id,void * va)701 boolean DXLinkHandler::SetGlobalValue(const char *c, int id, void *va)
702 {
703 Network *n = theDXApplication->network;
704 Node *node = NULL;
705 char label[128];
706 int length;
707
708 sscanf(c, "%s = %n", label, &length);
709 const char *value = c+length;
710
711 //
712 // Look for a DXLInput tool that matches the given label. If found,
713 // then set its 1st input (which is passed to its output).
714 //
715 List *l;
716 if ( (l = n->makeClassifiedNodeList(ClassDXLInputNode,FALSE)) ) {
717 ListIterator iter(*l);
718 while ( (node = (Node*)iter.getNext()) ) {
719 if (EqualString(node->getLabelString(),label)) {
720 node->setInputValue(1,value);
721 break;
722 }
723 }
724 delete l;
725 }
726
727 //
728 // If we didn't find a DXLInput tool, then we just send the assignment
729 // to the executive. NOTE, that this handles the case where the user
730 // has used Receivers instead of DXLInput nodes, with the exception
731 // that connection to the server must exist for the assigment to take
732 // effect (i.e. DXLInputs save the value for a later connection).
733 //
734 if (!node) {
735 DXPacketIF *pif = theDXApplication->getPacketIF();
736 if (pif) {
737 char *s = new char[STRLEN(value) + STRLEN(label) + 8];
738 sprintf(s,"%s = %s;",label,value);
739 pif->send(DXPacketIF::FOREGROUND, s);
740 delete s;
741 }
742 }
743
744 #if 0 // For now we will take this out so that DXLink apps can throw values at
745 // the exec the same way dxui does, with the exec handling them as
746 // fast as it can. 11/16/95 - dawood
747
748 //
749 // If we were in exec-on-change, then we just caused an execution,
750 // lets be sure to wait until it is completed, before handling
751 // packets from the dxlink application.
752 //
753 DXLinkHandler *a = (DXLinkHandler*)va;
754 if (theDXApplication->getExecCtl()->inExecOnChange())
755 a->stallForExecutionIfRequired();
756 #endif
757
758 return TRUE;
759
760 }
761
762 //
763 // This method is probably never used, as it is not required by the
764 // currently exposed functions in libDXL.a.
765 //
SetTabValue(const char * c,int id,void * va)766 boolean DXLinkHandler::SetTabValue(const char *c, int id, void *va)
767 {
768 char macro[100];
769 char module[100];
770 int inst;
771 int paramInd;
772 int length;
773 DXLinkHandler *a = (DXLinkHandler*)va;
774 char inout[10];
775 char buffer[1024];
776
777 sscanf(c, "%[^_]_%[^_]_%d_%[^_]_%d = %n",
778 macro, module, &inst, inout, ¶mInd, &length);
779 const char *value = c+length;
780
781 Network *n = theDXApplication->network;
782 ListIterator li(theDXApplication->macroList);
783 for (; n && !EqualString(n->getNameString(), macro);
784 n = (Network*)li.getNext())
785 ;
786 if (!n)
787 {
788 sprintf(buffer, "Macro %s not found", macro);
789 ErrorMessage(buffer);
790 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
791 return FALSE;
792 }
793
794 Node *node = n->getNode(module, inst);
795 if (node == NULL)
796 {
797 sprintf(buffer,"Module %s:%d not found", module, inst);
798 ErrorMessage(buffer);
799 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
800 return FALSE;
801 }
802 if ((EqualString(inout, "in") &&
803 node->setInputValue(paramInd, value) == DXType::UndefinedType) ||
804 (EqualString(inout, "out") &&
805 node->setOutputValue(paramInd, value) == DXType::UndefinedType))
806 {
807 sprintf(buffer,"Value \"%s\" not valid for %sput %d of %s",
808 value, inout, paramInd, module);
809 ErrorMessage(buffer);
810 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
811 return FALSE;
812 }
813
814 //
815 // If we were in exec-on-change, then we just caused an execution,
816 // lets be sure to wait until it is completed, before handling
817 // packets from the dxlink application.
818 //
819 if (theDXApplication->getExecCtl()->inExecOnChange())
820 a->stallForExecutionIfRequired();
821
822 return TRUE;
823 }
824
Terminate(const char *,int,void *)825 boolean DXLinkHandler::Terminate(const char *, int, void *)
826 {
827 theDXApplication->disconnectFromApplication(TRUE);
828
829 return TRUE;
830 }
831
Disconnect(const char *,int,void *)832 boolean DXLinkHandler::Disconnect(const char *, int , void *)
833 {
834 theDXApplication->disconnectFromApplication(FALSE);
835
836 return TRUE;
837 }
838
QueryValue(const char * c,int id,void * va)839 boolean DXLinkHandler::QueryValue(const char *c, int id, void *va)
840 {
841 char macro[100];
842 char module[100];
843 int inst;
844 int paramInd;
845 DXLinkHandler *a = (DXLinkHandler*)va;
846 char inout[10];
847 char buffer[1024];
848
849 sscanf(c, "%[^_]_%[^_]_%d_%[^_]_%d",
850 macro, module, &inst, inout, ¶mInd);
851
852 Network *n = theDXApplication->network;
853 ListIterator li(theDXApplication->macroList);
854 for (; n && !EqualString(n->getNameString(), macro);
855 n = (Network*)li.getNext())
856 ;
857 if (!n)
858 {
859 sprintf(buffer,"Macro %s not found", macro);
860 ErrorMessage(buffer);
861 a->sendPacket(DXPacketIF::PKTERROR,id, buffer);
862 return FALSE;
863 }
864
865 Node *node = n->getNode(module, inst);
866 if (node == NULL)
867 {
868 sprintf(buffer,"Module %s:%d not found", module, inst);
869 ErrorMessage(buffer);
870 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
871 return FALSE;
872 }
873 const char *value;
874 if (EqualString(inout, "in"))
875 {
876 if (node->isInputDefaulting(paramInd))
877 value = node->getInputDefaultValueString(paramInd);
878 else
879 value = node->getInputValueString(paramInd);
880 }
881 else
882 value = node->getOutputValueString(paramInd);
883
884 a->sendPacket(DXPacketIF::LRESPONSE, id, value);
885 return TRUE;
886 }
887
ConnectToServer(const char * c,int id,void * va)888 boolean DXLinkHandler::ConnectToServer(const char *c, int id, void *va)
889 {
890 int port;
891
892 sscanf(c, "%d", &port);
893 theDXApplication->connectToServer(port);
894
895 return TRUE;
896 }
897
StartServer(const char * c,int id,void * va)898 boolean DXLinkHandler::StartServer(const char *c, int id, void *va)
899 {
900 theDXApplication->setBusyCursor(TRUE);
901 theDXApplication->startServer();
902 theDXApplication->setBusyCursor(FALSE);
903 return TRUE;
904 }
905
Sync(const char * c,int id,void * va)906 boolean DXLinkHandler::Sync(const char *c, int id, void *va)
907 {
908 DXLinkHandler *a = (DXLinkHandler*)va;
909 a->sendPacket(DXPacketIF::LRESPONSE,id);
910 return TRUE;
911 }
912 class SyncData {
913 public:
914 int id;
915 DXLinkHandler *dxlh;
916 };
917
SyncCB(void * clientData,int id,void * line)918 void DXLinkHandler::SyncCB(void *clientData, int id, void *line)
919 {
920 SyncData *sd = (SyncData*)clientData;
921 sd->dxlh->sendPacket(DXPacketIF::LRESPONSE,sd->id);
922 delete sd;
923 }
924
SyncExec(const char *,int id,void * va)925 boolean DXLinkHandler::SyncExec(const char *, int id, void *va)
926 {
927 DXPacketIF *pif = theDXApplication->getPacketIF();
928 DXLinkHandler *a = (DXLinkHandler*)va;
929
930 if (pif) {
931 SyncData *sd = new SyncData;
932 sd->id = id;
933 sd->dxlh = a;
934 pif->send(DXPacketIF::FOREGROUND, "Executive(\"nop\");",
935 SyncCB,
936 (void*)sd);
937 } else
938 a->sendPacket(DXPacketIF::PKTERROR, id, "no ui-executive connection");
939
940 return TRUE;
941 }
942
OpenControlPanel(const char * c,int id,void * va)943 boolean DXLinkHandler::OpenControlPanel(const char *c, int id, void *va)
944 {
945 List *l;
946
947 l = theDXApplication->network->makeNamedControlPanelList(c);
948
949 if (l)
950 {
951 ControlPanel *cp;
952 ListIterator it(*l);
953
954 while (NULL != (cp = (ControlPanel *)it.getNext()))
955 if (!cp->isManaged())
956 cp->manage();
957 delete l;
958 }
959
960
961 return TRUE;
962 }
963
CloseControlPanel(const char * c,int id,void * va)964 boolean DXLinkHandler::CloseControlPanel(const char *c, int id, void *va)
965 {
966 List *l;
967
968 l = theDXApplication->network->makeNamedControlPanelList(c);
969
970 if (l)
971 {
972 ControlPanel *cp;
973 ListIterator it(*l);
974
975 while (NULL != (cp = (ControlPanel *)it.getNext()))
976 if (cp->getRootWidget())
977 cp->unmanage();
978 }
979
980 delete l;
981
982 return TRUE;
983 }
984
ResetServer(const char * c,int id,void * va)985 boolean DXLinkHandler::ResetServer(const char *c, int id, void *va)
986 {
987 // DXLinkHandler *a = (DXLinkHandler*)va;
988 theDXApplication->resetServer();
989 return TRUE;
990 }
Version(const char * c,int id,void * va)991 boolean DXLinkHandler::Version(const char *c, int id, void *va)
992 {
993 DXLinkHandler *a = (DXLinkHandler*)va;
994 char buffer[1024];
995 sprintf(buffer,"UI version: %d %d %d\n",
996 DX_MAJOR_VERSION, DX_MINOR_VERSION, DX_MICRO_VERSION);
997 a->sendPacket(DXPacketIF::INFORMATION, id, buffer);
998 return TRUE;
999 }
ResendParameters(const char * c,int id,void * va)1000 boolean DXLinkHandler::ResendParameters(const char *c, int id, void *va)
1001 {
1002 List *l;
1003 DXLinkHandler *a = (DXLinkHandler*)va;
1004
1005 l = theDXApplication->network->makeClassifiedNodeList(NULL);
1006 if (! l)
1007 {
1008 a->sendPacket(DXPacketIF::PKTERROR, id, "no network?");
1009 return FALSE;
1010 }
1011
1012 Node *node;
1013 ListIterator it(*l);
1014 int found = 0;
1015
1016 while (NULL != (node = (Node *)it.getNext()))
1017 if (EqualString(c, node->getLabelString()))
1018 {
1019 found = 1;
1020
1021 for (int i = 1; i <= node->getInputCount(); i++)
1022 node->setInputDirty(i);
1023 }
1024
1025 if (! found)
1026 {
1027 char buffer[1024];
1028 sprintf(buffer, "no nodes with label %s found", c);
1029 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
1030 return FALSE;
1031 }
1032
1033 theDXApplication->network->setDirty();
1034
1035 return TRUE;
1036 }
1037
SetProbePoint(const char * c,int id,void * va)1038 boolean DXLinkHandler::SetProbePoint(const char *c, int id, void *va)
1039 {
1040 List *l;
1041 DXLinkHandler *a = (DXLinkHandler*)va;
1042 char probeName[100];
1043 float x, y, z;
1044 int n;
1045
1046 l = theDXApplication->network->makeClassifiedNodeList(ClassProbeNode,FALSE);
1047 if (! l)
1048 {
1049 a->sendPacket(DXPacketIF::PKTERROR, id, "no probes?");
1050 return FALSE;
1051 }
1052
1053 sscanf(c, "%s %d [%f, %f, %f]", probeName, &n, &x, &y, &z);
1054
1055 n = n == 1 ? -1 : 0;
1056
1057 ListIterator it(*l);
1058 ProbeNode *pn;
1059
1060 while (NULL != (pn = (ProbeNode *)it.getNext()))
1061 if (EqualString(probeName, pn->getLabelString()))
1062 {
1063 pn->setCursorValue(n, (double)x, (double)y, (double)z);
1064 break;
1065 }
1066
1067 //
1068 // If we were in exec-on-change, then we just caused an execution,
1069 // lets be sure to wait until it is completed, before handling
1070 // packets from the dxlink application.
1071 //
1072 if (theDXApplication->getExecCtl()->inExecOnChange())
1073 a->stallForExecutionIfRequired();
1074
1075 return TRUE;
1076 }
1077
SelectProbe(const char * c,int id,void * va)1078 boolean DXLinkHandler::SelectProbe(const char *c, int id, void *va)
1079 {
1080 List *images = NUL(List *);
1081 List *probes = NUL(List *);
1082 char arg0[256], arg1[256];
1083 int n;
1084 DXLinkHandler *a = (DXLinkHandler*)va;
1085
1086 n = sscanf(c, "%s %s", arg0, arg1);
1087
1088 if (n == 0)
1089 {
1090 a->sendPacket(DXPacketIF::PKTERROR,
1091 id, "missing probe name");
1092 return FALSE;
1093 }
1094
1095 if (EqualSubstring(arg0, "probe=", 6))
1096 probes = MakeQualifiedNodeList(ClassProbeNode, arg0+6, FALSE);
1097 else
1098 probes = MakeQualifiedNodeList(ClassProbeNode, arg0, FALSE);
1099
1100 if (! probes || 0 == probes->getSize())
1101 {
1102 a->sendPacket(DXPacketIF::PKTERROR, id,
1103 "SelectProbe: no probes in network");
1104 if (probes) delete probes;
1105 return FALSE;
1106 }
1107
1108 if (n == 2)
1109 {
1110 if (EqualSubstring(arg0, "image", 5))
1111 images = MakeQualifiedNodeList(ClassImageNode, arg1+6, FALSE);
1112 else
1113 images = MakeQualifiedNodeList(ClassImageNode, arg1, FALSE);
1114 }
1115 else
1116 images =
1117 theDXApplication->network->makeClassifiedNodeList(ClassImageNode);
1118
1119 if (! images || 0 == images->getSize())
1120 {
1121 char buffer[1024];
1122 if (n == 1) {
1123 a->sendPacket(DXPacketIF::PKTERROR, id,
1124 "SelectProbe: no images in network");
1125 } else {
1126 sprintf(buffer,
1127 "SelectProbe: no images matching %s in network", arg1);
1128 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
1129 }
1130 if (images) delete images;
1131 if (probes) delete probes;
1132 return FALSE;
1133 }
1134
1135 ListIterator itp(*probes);
1136 ProbeNode *pn;
1137
1138 while (NULL != (pn = (ProbeNode *)itp.getNext()))
1139 {
1140 int pi = pn->getInstanceNumber();
1141 ListIterator iti(*images);
1142 ImageNode *in;
1143
1144 while (NULL != (in = (ImageNode *)iti.getNext()))
1145 {
1146 ImageWindow *iw = (ImageWindow *)in->getDXWindow();
1147 iw->selectProbeByInstance(pi);
1148 }
1149 }
1150
1151 if (images) delete images;
1152 if (probes) delete probes;
1153
1154 //
1155 // If we were in exec-on-change, then we just caused an execution,
1156 // lets be sure to wait until it is completed, before handling
1157 // packets from the dxlink application.
1158 //
1159 if (theDXApplication->getExecCtl()->inExecOnChange())
1160 a->stallForExecutionIfRequired();
1161
1162 return TRUE;
1163 }
1164
SetInteractionMode(const char * c,int id,void * va)1165 boolean DXLinkHandler::SetInteractionMode(const char *c, int id, void *va)
1166 {
1167 List *l = NUL(List *);
1168 char qualifier0[256];
1169 char qualifier1[256];
1170 char mode[256];
1171 int n;
1172 DXLinkHandler *a = (DXLinkHandler*)va;
1173
1174 n = sscanf(c, "%s %s %s", mode, qualifier0, qualifier1);
1175
1176 if (n >= 2)
1177 {
1178 if (EqualSubstring(qualifier0, "image", 5))
1179 l = MakeQualifiedNodeList(ClassImageNode, qualifier0+6, FALSE);
1180 else
1181 l = MakeQualifiedNodeList(ClassImageNode, qualifier0, FALSE);
1182
1183 if (!l || l->getSize() == 0)
1184 {
1185 char buffer[1024];
1186 sprintf(buffer,
1187 "SetInteractionMode: no images matching %sin network",
1188 qualifier0);
1189 a->sendPacket(DXPacketIF::PKTERROR,id, buffer);
1190 if (l) delete l;
1191 return FALSE;
1192 }
1193 }
1194 else
1195 {
1196 l =
1197 theDXApplication->network->makeClassifiedNodeList(ClassImageNode);
1198
1199 if (!l || l->getSize() == 0)
1200 {
1201 a->sendPacket(DXPacketIF::PKTERROR,id,
1202 "SetInteractionMode: no images in network");
1203 if (l) delete l;
1204 return FALSE;
1205 }
1206 }
1207
1208 ListIterator it(*l);
1209 ImageNode *in;
1210 DirectInteractionMode dim;
1211
1212 if (EqualString(mode, "camera")) dim = CAMERA;
1213 else if (EqualString(mode, "cursors")) dim = CURSORS;
1214 else if (EqualString(mode, "pick")) dim = PICK;
1215 else if (EqualString(mode, "navigate")) dim = NAVIGATE;
1216 else if (EqualString(mode, "panzoom")) dim = PANZOOM;
1217 else if (EqualString(mode, "roam")) dim = ROAM;
1218 else if (EqualString(mode, "rotate")) dim = ROTATE;
1219 else if (EqualString(mode, "zoom")) dim = ZOOM;
1220 else dim = NONE;
1221
1222 while (NULL != (in = (ImageNode *)it.getNext()))
1223 {
1224 ImageWindow *iw = (ImageWindow*)in->getDXWindow();
1225 if (!iw->setInteractionMode(dim)) {
1226 char buffer[1024];
1227 sprintf(buffer, "SetInteractionMode: could not set '%s' mode",mode);
1228 a->sendPacket(DXPacketIF::PKTERROR,id, buffer);
1229 }
1230 }
1231
1232 if ((dim == CURSORS || dim == PICK) && n >= 3)
1233 {
1234 List *pl;
1235 char *q;
1236 int instance = -1;
1237 const char *clss = (dim == PICK) ? ClassPickNode : ClassProbeNode;
1238
1239 it.setPosition(1);
1240
1241 if (EqualSubstring(qualifier1, "probelist", 9))
1242 q = qualifier1 + 10;
1243 else if (EqualSubstring(qualifier1, "probe", 5))
1244 q = qualifier1 + 6;
1245 else if (EqualSubstring(qualifier1, "pick", 4))
1246 q = qualifier1 + 5;
1247 else
1248 q = qualifier1;
1249
1250 pl = MakeQualifiedNodeList(clss, q, FALSE);
1251
1252 if (!pl || pl->getSize() == 0)
1253 {
1254 char buffer[1024];
1255 sprintf(buffer,
1256 "SetInteractionMode: no %s named %s in network",
1257 (dim == PICK) ? "pick node" : "probe or probe list node", q);
1258 a->sendPacket(DXPacketIF::PKTERROR,id, buffer);
1259 if (l) delete l;
1260 return FALSE;
1261 }
1262
1263 ListIterator plit(*pl);
1264 Node *nd = (Node *)plit.getNext();
1265 instance = nd->getInstanceNumber();
1266
1267 while (NULL != (in = (ImageNode *)it.getNext()))
1268 {
1269 ImageWindow *iw = (ImageWindow*)in->getDXWindow();
1270 if (((dim == PICK) && !iw->selectProbeByInstance(instance)) ||
1271 ((dim == PICK) && !iw->selectPickByInstance(instance)))
1272 {
1273 char buffer[1024];
1274 sprintf(buffer,
1275 "SetInteractionMode: could not current %s to '%s'",
1276 (dim == PICK) ? "pick" : "probe or probe list", q);
1277 a->sendPacket(DXPacketIF::PKTERROR,id, buffer);
1278 }
1279 }
1280
1281 delete pl;
1282 }
1283
1284 delete l;
1285 //
1286 // If we were in exec-on-change, then we just caused an execution,
1287 // lets be sure to wait until it is completed, before handling
1288 // packets from the dxlink application.
1289 //
1290 if (theDXApplication->getExecCtl()->inExecOnChange())
1291 a->stallForExecutionIfRequired();
1292 return TRUE;
1293 }
1294
LoadMacroFile(const char * c,int id,void * va)1295 boolean DXLinkHandler::LoadMacroFile(const char *c, int id, void *va)
1296 {
1297 char *msg;
1298
1299 if (! MacroDefinition::LoadMacro(c, &msg))
1300 {
1301 DXLinkHandler *a = (DXLinkHandler*)va;
1302 char buffer[1024];
1303 sprintf(buffer, "LoadMacroFile: %s", msg);
1304 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
1305 delete msg;
1306 return FALSE;
1307 }
1308
1309 return TRUE;
1310 }
1311
1312
LoadMacroDirectory(const char * c,int id,void * va)1313 boolean DXLinkHandler::LoadMacroDirectory(const char *c, int id, void *va)
1314 {
1315 char *msg;
1316
1317 if (! MacroDefinition::LoadMacroDirectories(c, TRUE, &msg))
1318 {
1319 DXLinkHandler *a = (DXLinkHandler*)va;
1320 char buffer[1024];
1321 sprintf(buffer, "LoadMacroDirectory: %s", msg);
1322 a->sendPacket(DXPacketIF::PKTERROR, id, buffer);
1323 delete msg;
1324 return FALSE;
1325 }
1326
1327 return TRUE;
1328 }
1329
ExecOnce(const char * c,int id,void * va)1330 boolean DXLinkHandler::ExecOnce(const char *c, int id, void *va)
1331 {
1332 theDXApplication->getExecCtl()->executeOnce();
1333 DXLinkHandler *a = (DXLinkHandler*)va;
1334 a->stallForExecutionIfRequired();
1335 return TRUE;
1336 }
1337
ExecOnChange(const char * c,int id,void * va)1338 boolean DXLinkHandler::ExecOnChange(const char *c, int id, void *va)
1339 {
1340 theDXApplication->getExecCtl()->enableExecOnChange();
1341 DXLinkHandler *a = (DXLinkHandler*)va;
1342 a->stallForExecutionIfRequired();
1343 return TRUE;
1344 }
1345
EndExecution(const char * c,int id,void * va)1346 boolean DXLinkHandler::EndExecution(const char *c, int id, void *va)
1347 {
1348 DXExecCtl *ctl = theDXApplication->getExecCtl();
1349 DXLinkHandler *a = (DXLinkHandler*)va;
1350
1351 // this kills the current graph after the next module finishes
1352 ctl->terminateExecution();
1353 a->stallForExecutionIfRequired();
1354
1355 return TRUE;
1356 }
1357
EndExecOnChange(const char * c,int id,void * va)1358 boolean DXLinkHandler::EndExecOnChange(const char *c, int id, void *va)
1359 {
1360 DXExecCtl *ctl = theDXApplication->getExecCtl();
1361 DXLinkHandler *a = (DXLinkHandler*)va;
1362
1363 // this just takes the exec out of EOC mode, and lets the current
1364 // graph complete.
1365 ctl->endExecOnChange();
1366 a->stallForExecutionIfRequired();
1367
1368 return TRUE;
1369 }
1370
QueryExecution(const char * c,int id,void * va)1371 boolean DXLinkHandler::QueryExecution(const char *c, int id, void *va)
1372 {
1373 int execState;
1374 DXLinkHandler *a = (DXLinkHandler*)va;
1375 char buffer[1024];
1376
1377 if (theDXApplication->getExecCtl()->isExecuting())
1378 execState = 1;
1379 else
1380 execState = 0;
1381
1382 sprintf(buffer, "execution state: %d", execState);
1383 a->sendPacket(DXPacketIF::LRESPONSE, id, buffer);
1384
1385 return TRUE;
1386 }
1387
1388
PopupVCR(const char * c,int id,void * va)1389 boolean DXLinkHandler::PopupVCR(const char *c, int id, void *va)
1390 {
1391 fprintf(stderr, "PopupVCR not implemented\n");
1392 return TRUE;
1393 }
1394
1395
SequencerPlay(const char * line,int id,void * va)1396 boolean DXLinkHandler::SequencerPlay(const char *line, int id, void *va)
1397 {
1398 SequencerNode *s = theDXApplication->network->sequencer;
1399 if (s) {
1400 DXLinkHandler *a = (DXLinkHandler*)va;
1401 DXExecCtl *ctl = theDXApplication->getExecCtl();
1402 boolean forward = strstr(line,"forward") != NULL;
1403 ctl->vcrExecute(forward);
1404 if (!s->isLoopMode())
1405 a->stallForExecutionIfRequired();
1406 }
1407 return TRUE;
1408 }
SequencerPause(const char * line,int id,void * va)1409 boolean DXLinkHandler::SequencerPause(const char *line, int id, void *va)
1410 {
1411 SequencerNode *s = theDXApplication->network->sequencer;
1412 if (s) {
1413 DXLinkHandler *a = (DXLinkHandler*)va;
1414 DXExecCtl *ctl = theDXApplication->getExecCtl();
1415 ctl->vcrCommand(VCR_PAUSE, FALSE);
1416 a->stallForExecutionIfRequired();
1417 }
1418 return TRUE;
1419 }
SequencerStep(const char * line,int id,void * va)1420 boolean DXLinkHandler::SequencerStep(const char *line, int id, void *va)
1421 {
1422 SequencerNode *s = theDXApplication->network->sequencer;
1423 if (s) {
1424 DXLinkHandler *a = (DXLinkHandler*)va;
1425 DXExecCtl *ctl = theDXApplication->getExecCtl();
1426 ctl->vcrCommand(VCR_STEP, FALSE);
1427 a->stallForExecutionIfRequired();
1428 }
1429 return TRUE;
1430 }
SequencerStop(const char * line,int id,void * va)1431 boolean DXLinkHandler::SequencerStop(const char *line, int id, void *va)
1432 {
1433 SequencerNode *s = theDXApplication->network->sequencer;
1434 if (s) {
1435 DXLinkHandler *a = (DXLinkHandler*)va;
1436 DXExecCtl *ctl = theDXApplication->getExecCtl();
1437 ctl->vcrCommand(VCR_STOP, FALSE);
1438 a->stallForExecutionIfRequired();
1439 }
1440 return TRUE;
1441 }
SequencerPalindrome(const char * line,int id,void * va)1442 boolean DXLinkHandler::SequencerPalindrome(const char *line, int id, void *va)
1443 {
1444 SequencerNode *s = theDXApplication->network->sequencer;
1445 if (s) {
1446 DXLinkHandler *a = (DXLinkHandler*)va;
1447 DXExecCtl *ctl = theDXApplication->getExecCtl();
1448 boolean set = strstr(line,"off") == NULL;
1449 ctl->vcrCommand(VCR_PALINDROME, set);
1450 a->stallForExecutionIfRequired();
1451 }
1452 return TRUE;
1453 }
SequencerLoop(const char * line,int id,void * va)1454 boolean DXLinkHandler::SequencerLoop(const char *line, int id, void *va)
1455 {
1456 SequencerNode *s = theDXApplication->network->sequencer;
1457 if (s) {
1458 DXExecCtl *ctl = theDXApplication->getExecCtl();
1459 DXLinkHandler *a = (DXLinkHandler*)va;
1460 boolean set = strstr(line,"off") == NULL;
1461 ctl->vcrCommand(VCR_LOOP, set);
1462 a->stallForExecutionIfRequired();
1463 }
1464 return TRUE;
1465 }
1466
1467
1468
DXLinkHandler(PacketIF * pif)1469 DXLinkHandler::DXLinkHandler(PacketIF *pif) : LinkHandler(pif)
1470 {
1471 this->addCommand("set", (Command *)NULL);
1472 this->addSubCommand("set", "tab", SetTabValue);
1473 this->addSubCommand("set", "value", SetGlobalValue);
1474 this->addSubCommand("set", "probevalue", SetProbePoint);
1475 this->addSubCommand("set", "activeprobe", SelectProbe);
1476
1477
1478 this->addCommand("execute", (Command *)NULL);
1479 this->addSubCommand("execute", "once",
1480 DXLinkHandler::ExecOnce);
1481 this->addSubCommand("execute", "onchange",
1482 DXLinkHandler::ExecOnChange);
1483 this->addSubCommand("execute", "end",
1484 DXLinkHandler::EndExecution);
1485 this->addSubCommand("execute", "endEOC",
1486 DXLinkHandler::EndExecOnChange);
1487
1488 this->addCommand("StartServer", DXLinkHandler::StartServer);
1489 this->addCommand("ConnectToServer", DXLinkHandler::ConnectToServer);
1490 this->addCommand("disconnect", DXLinkHandler::Disconnect);
1491 this->addCommand("exit", DXLinkHandler::Terminate);
1492 this->addCommand("quit", DXLinkHandler::Terminate);
1493
1494 this->addCommand("save", (Command *)NULL);
1495 this->addSubCommand("save", "network",
1496 DXLinkHandler::SaveNetwork);
1497
1498 this->addCommand("open", (Command *)NULL);
1499 this->addSubCommand("open", "networkNoReset",
1500 DXLinkHandler::OpenNetworkNoReset);
1501 this->addSubCommand("open", "network",
1502 DXLinkHandler::OpenNetwork);
1503 this->addSubCommand("open", "config",
1504 DXLinkHandler::OpenConfig);
1505 this->addSubCommand("open", "controlpanel",
1506 DXLinkHandler::OpenControlPanel);
1507 this->addSubCommand("open", "VPE",
1508 DXLinkHandler::OpenVPE);
1509 this->addSubCommand("open", "sequencer",
1510 DXLinkHandler::OpenSequencer);
1511 this->addSubCommand("open", "image",
1512 DXLinkHandler::OpenImage);
1513 this->addSubCommand("open", "colormapEditor",
1514 DXLinkHandler::OpenColormapEditor);
1515
1516 this->addCommand("query", (Command *)NULL);
1517 this->addSubCommand("query", "value", DXLinkHandler::QueryValue);
1518 this->addSubCommand("query", "sync", DXLinkHandler::Sync);
1519 this->addSubCommand("query", "sync-exec", DXLinkHandler::SyncExec);
1520 this->addSubCommand("query", "execution", DXLinkHandler::QueryExecution);
1521
1522 this->addCommand("close", (Command *)NULL);
1523 this->addSubCommand("close", "controlpanel",
1524 DXLinkHandler::CloseControlPanel);
1525 this->addSubCommand("close", "VPE",
1526 DXLinkHandler::CloseVPE);
1527 this->addSubCommand("close", "colormapEditor",
1528 DXLinkHandler::CloseColormapEditor);
1529 this->addSubCommand("close", "image",
1530 DXLinkHandler::CloseImage);
1531 this->addSubCommand("close", "sequencer",
1532 DXLinkHandler::CloseSequencer);
1533
1534 this->addCommand("sequencer", (Command *)NULL);
1535 this->addSubCommand("sequencer", "play", DXLinkHandler::SequencerPlay);
1536 this->addSubCommand("sequencer", "pause", DXLinkHandler::SequencerPause);
1537 this->addSubCommand("sequencer", "step", DXLinkHandler::SequencerStep);
1538 this->addSubCommand("sequencer", "stop", DXLinkHandler::SequencerStop);
1539 this->addSubCommand("sequencer", "palindrome",
1540 DXLinkHandler::SequencerPalindrome);
1541 this->addSubCommand("sequencer", "loop", DXLinkHandler::SequencerLoop);
1542
1543 this->addCommand("load", (Command *)NULL);
1544 this->addSubCommand("load", "macroFile",
1545 DXLinkHandler::LoadMacroFile);
1546 this->addSubCommand("load", "macroDirectory",
1547 DXLinkHandler::LoadMacroDirectory);
1548
1549 this->addCommand("$version", DXLinkHandler::Version);
1550 this->addCommand("resend", DXLinkHandler::ResendParameters);
1551 this->addCommand("interactionMode", DXLinkHandler::SetInteractionMode);
1552 this->addCommand("reset", DXLinkHandler::ResetServer);
1553
1554 this->addCommand("save", (Command *)NULL);
1555 this->addSubCommand("save", "config", DXLinkHandler::SaveConfig);
1556
1557 this->addCommand("render-mode", (Command *)NULL);
1558 this->addSubCommand("render-mode", "hw", DXLinkHandler::SetHWRendering);
1559 this->addSubCommand("render-mode", "sw", DXLinkHandler::SetSWRendering);
1560
1561 //
1562 // As of 6/12/95, we aren't using this in DXLink, but it may come in
1563 // handy for fixing bugs and may be of general utility.
1564 //
1565 this->addCommand("stall", (Command *)NULL);
1566 this->addSubCommand("stall", "until", DXLinkHandler::StallUntil);
1567 }
1568
1569