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 <stdarg.h>
14 #include "dxlP.h"
15 #include "dxl.h"
16
17 enum DXLExecuteCtl {
18 DXLEXECUTEONCE,
19 DXLEXECUTEONCHANGE,
20 DXLENDEXECUTION,
21 DXLENDEXECUTEONCHANGE
22 };
23 typedef enum DXLExecuteCtl DXLExecuteCtlEnum;
24
25 #define BGbeginMSG "BG: begin"
26 #define BGendMSG "BG: end"
27 #define FGbeginMSG "begin "
28 #define FGendMSG NULL
29 #define INTRstopMSG "stop"
30
_dxl_EndBG(DXLConnection * c,const char * msg,void * data)31 static void _dxl_EndBG(DXLConnection *c, const char *msg, void *data)
32 {
33 c->isExecuting --;
34 }
35
_dxl_BeginBG(DXLConnection * c,const char * msg,void * data)36 static void _dxl_BeginBG(DXLConnection *c, const char *msg, void *data)
37 {
38 c->isExecuting ++;
39 }
40
_dxl_CompleteExecute(DXLConnection * c,const char * msg,void * data)41 static void _dxl_CompleteExecute(DXLConnection *c, const char *msg, void *data)
42 {
43 int packetId = (int)(long)data;
44 c->isExecuting--;
45 _dxl_RemoveSystemHandler(c,PACK_COMPLETE,packetId,
46 FGendMSG, _dxl_CompleteExecute);
47 }
48
_dxl_INTRstop(DXLConnection * c,const char * msg,void * data)49 static void _dxl_INTRstop(DXLConnection *c, const char *msg, void *data)
50 {
51 c->isExecuting = 0;
52 _dxl_RemoveSystemHandler(c,PACK_INTERRUPT,-1,INTRstopMSG, _dxl_INTRstop);
53 }
_dxl_ManageExecuteHandlers(DXLConnection * conn,int install,int foreground,int packetId)54 static DXLError _dxl_ManageExecuteHandlers(DXLConnection *conn, int install,
55 int foreground, int packetId)
56 {
57 if (conn->dxuiConnected)
58 return ERROR;
59
60 if (foreground) {
61 if (install) {
62 if (!_dxl_SetSystemHandler(conn, PACK_COMPLETE,packetId, FGendMSG,
63 (DXLMessageHandler)_dxl_CompleteExecute, (void*)packetId))
64 return ERROR;
65 } else {
66 /*
67 * FIXME: we should really use the correct packetId here
68 */
69 if (!_dxl_RemoveSystemHandler(conn,PACK_COMPLETE,-1, FGendMSG,
70 _dxl_CompleteExecute))
71 return ERROR;
72 }
73
74 } else {
75 if (install) {
76 if (!_dxl_SetSystemHandlerString(conn, PACK_INTERRUPT,INTRstopMSG,
77 (DXLMessageHandler)_dxl_INTRstop, (void*)0))
78 return ERROR;
79 } else {
80 ; /* Don't bother removing them.
81 * Re-installs don't cause memory to be used up
82 * and it doesn't hurt to leave them installed.
83 */
84 }
85
86 }
87 return OK;
88
89 }
90
91 static DXLError
DXLExecuteCtl(DXLConnection * conn,DXLExecuteCtlEnum ectl,char * name,char ** args)92 DXLExecuteCtl(DXLConnection *conn, DXLExecuteCtlEnum ectl, char *name, char **args)
93 {
94 int i, sts = ERROR;
95 const char *cmd = NULL;
96 char namestr[1024];
97
98 if (name)
99 sprintf(namestr, "%s(\n", name);
100 else
101 sprintf(namestr, "main(\n");
102
103 if (args)
104 {
105 for (i = 0; args[i]; i++)
106 {
107 strcat(namestr, args[i]);
108 if (args[i+1])
109 strcat(namestr, ",");
110 }
111 }
112
113 strcat(namestr, ");\n");
114
115 switch (ectl) {
116 case DXLEXECUTEONCE:
117 if (conn->dxuiConnected) {
118 cmd = "execute once";
119 } else {
120 int packetId;
121 /*
122 if (conn->debugMessaging && conn->isExecuting)
123 _DXLError(conn, "already executing");
124 */
125 /* FIXME: handle other program names */
126 packetId = DXLSendPacket(conn,PACK_FOREGROUND,namestr);
127 if (packetId >= 0)
128 sts = _dxl_ManageExecuteHandlers(conn,1,1,packetId);
129 conn->isExecuting++;
130 }
131 break;
132 case DXLEXECUTEONCHANGE:
133 if (conn->dxuiConnected) {
134 cmd = "execute onchange";
135 } else {
136 int packetId;
137 packetId = DXLSendPacket(conn,PACK_BACKGROUND,namestr);
138 sts = (packetId >= 0);
139 if (sts)
140 {
141 _dxl_SetSystemHandler(conn, PACK_INFO, -1, BGbeginMSG,
142 (DXLMessageHandler)_dxl_BeginBG, (void*) NULL);
143 _dxl_SetSystemHandler(conn, PACK_INFO, -1, BGendMSG,
144 (DXLMessageHandler)_dxl_EndBG, (void*) NULL);
145 if (sts)
146 DXLExecuteCtl(conn, DXLEXECUTEONCE,name,args);
147 if (sts)
148 sts = _dxl_ManageExecuteHandlers(conn,1,0,-1);
149 }
150 }
151 break;
152 case DXLENDEXECUTION:
153 if (conn->dxuiConnected) {
154 cmd = "execute end";
155 } else {
156 sts = DXLSendPacket(conn,PACK_INTERRUPT,NULL) >= 0;
157 if (sts)
158 sts = DXLSendImmediate(conn,"sync") >= 0;
159 _dxl_RemoveSystemHandler(conn, PACK_INFO, -1, FGbeginMSG, _dxl_BeginBG);
160 _dxl_RemoveSystemHandler(conn, PACK_INFO, -1, FGendMSG, _dxl_EndBG);
161 }
162 break;
163 case DXLENDEXECUTEONCHANGE:
164 if (conn->dxuiConnected) {
165 cmd = "execute endEOC";
166 } else {
167 _dxl_RemoveSystemHandler(conn, PACK_INFO, -1, FGbeginMSG, _dxl_BeginBG);
168 _dxl_RemoveSystemHandler(conn, PACK_INFO, -1, FGendMSG, _dxl_EndBG);
169 sts = DXLSendPacket(conn,PACK_INTERRUPT,NULL) >= 0;
170 if (sts)
171 sts = DXLSendImmediate(conn,"sync") >= 0;
172 }
173 break;
174 }
175
176 if (cmd)
177 return DXLSend(conn, cmd);
178 else
179 return sts;
180 }
181
182 DXLError
DXLExecuteOnce(DXLConnection * conn)183 DXLExecuteOnce(DXLConnection *conn)
184 {
185 return DXLExecuteCtl(conn, DXLEXECUTEONCE,NULL, NULL);
186 }
187
188 DXLError
DXLExecuteOnChange(DXLConnection * conn)189 DXLExecuteOnChange(DXLConnection *conn)
190 {
191 return DXLExecuteCtl(conn, DXLEXECUTEONCHANGE,NULL, NULL);
192 }
193
194 DXLError
exDXLExecuteOnceNamed(DXLConnection * conn,char * name)195 exDXLExecuteOnceNamed(DXLConnection *conn, char *name)
196 {
197 return DXLExecuteCtl(conn, DXLEXECUTEONCE, name, NULL);
198 }
199
200 DXLError
exDXLExecuteOnChangeNamed(DXLConnection * conn,char * name)201 exDXLExecuteOnChangeNamed(DXLConnection *conn, char *name)
202 {
203 return DXLExecuteCtl(conn, DXLEXECUTEONCHANGE, name, NULL);
204 }
205
206 DXLError
DXLEndExecution(DXLConnection * conn)207 DXLEndExecution(DXLConnection *conn)
208 {
209 return DXLExecuteCtl(conn, DXLENDEXECUTION, NULL, NULL);
210 }
211
212 DXLError
DXLEndExecuteOnChange(DXLConnection * conn)213 DXLEndExecuteOnChange(DXLConnection *conn)
214 {
215 return DXLExecuteCtl(conn, DXLENDEXECUTEONCHANGE, NULL, NULL);
216 }
217
218 DXLError
exDXLExecuteOnceNamedWithArgsV(DXLConnection * conn,char * name,char ** args)219 exDXLExecuteOnceNamedWithArgsV(DXLConnection *conn, char *name, char **args)
220 {
221 return DXLExecuteCtl(conn, DXLEXECUTEONCE, name, args);
222 }
223
224 DXLError
exDXLExecuteOnceNamedWithArgs(DXLConnection * conn,char * name,...)225 exDXLExecuteOnceNamedWithArgs(DXLConnection *conn, char *name, ...)
226 {
227 int i;
228 char *args[100];
229 va_list arg;
230
231 va_start(arg, name);
232 for (i = 0; i < 100; i++)
233 if ((args[i] = va_arg(arg, char *)) == NULL)
234 break;
235
236 return exDXLExecuteOnceNamedWithArgsV(conn, name, args);
237 }
238
239 DXLError
exDXLExecuteOnChangeNamedWithArgsV(DXLConnection * conn,char * name,char ** args)240 exDXLExecuteOnChangeNamedWithArgsV(DXLConnection *conn, char *name, char **args)
241 {
242 return DXLExecuteCtl(conn, DXLEXECUTEONCHANGE, name, args);
243 }
244
245 DXLError
exDXLExecuteOnChangeNamedWithArgs(DXLConnection * conn,char * name,...)246 exDXLExecuteOnChangeNamedWithArgs(DXLConnection *conn, char *name, ...)
247 {
248 int i;
249 char *args[100];
250 va_list arg;
251
252 va_start(arg, name);
253 for (i = 0; i < 100; i++)
254 if ((args[i] = va_arg(arg, char *)) == NULL)
255 break;
256
257 return exDXLExecuteOnChangeNamedWithArgsV(conn, name, args);
258 }
259
260 DXLError
DXLGetExecutionStatus(DXLConnection * conn,int * execStatus)261 DXLGetExecutionStatus(DXLConnection *conn, int *execStatus)
262 {
263 if (conn->dxuiConnected) {
264 char buf[100];
265 int sts = DXLQuery(conn, "query execution", sizeof(buf), buf);
266 if (! sts)
267 return ERROR;
268 if (1 != sscanf(buf, "execution state: %d", execStatus))
269 return ERROR;
270 } else {
271 /* FIXME: make sure the begin/end execution handlers are installed */
272 *execStatus = (conn->isExecuting != 0);
273 }
274 return OK;
275 }
276
277