2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* @(#)$XConsortium: action.c /main/3 1996/05/07 13:57:56 drk $ */
27 #include <Dt/Action.h>
31 static void DbReloadProc(/* cd */);
32 static bool init_action_env(/* */);
33 static void action_cb(DtActionInvocationID id, XtPointer cd,
34 DtActionArg *args, int argcnt, int status);
35 static void wait_action_done(/* */);
37 static bool actionEnabled = False;
38 static int actionDone = True;
39 static int actionErr = NoError;
40 static DtActionInvocationID actionId = 0;
43 /* ***** DtAction functions ***** */
45 static void DbReloadProc(cd)
48 DPR(("DbReloadProc(): action database updated\n"));
49 DtDbLoad(); /* Pick up any dynamic changes to the database files */
52 static bool init_action_env()
56 if (actionEnabled != True) {
58 if (DtAppInitialize(appC, Dpy, TopW, Wargv[0], DTIMS_CLASS) == False) {
59 /* DtInitialize() has already logged an appropriate error msg */
62 DtDbLoad(); /* Load the filetype/action databases */
63 DtDbReloadNotify(DbReloadProc, NULL);
71 static void action_cb(id, cd, args, argcnt, status)
72 DtActionInvocationID id;
73 XtPointer cd; /* unused */
79 DPR(("action_cb(): invalid id %d != %d\n", id, actionId));
83 DPR(("action_cb(): invalid id %d != %d\n", id, actionId));
87 switch ((DtActionStatus) status) {
88 case DtACTION_INVOKED:
89 DPR((" ACTION_INVOKED\n"));
93 DPR((" ACTION_DONE\n"));
98 case DtACTION_CANCELED:
100 DPR((" ACTION_%sED\n",
101 (status == DtACTION_CANCELED) ? "CANCEL" : "FAIL"));
102 if (args && argcnt > 0) {
104 for (i = 0; i < argcnt; i++) {
105 if (args[i].argClass == DtACTION_FILE) {
106 XtFree(args[i].u.file.name);
107 } else if (args[i].argClass == DtACTION_BUFFER) {
108 XtFree(args[i].u.buffer.bp);
109 XtFree(args[i].u.buffer.type);
110 XtFree(args[i].u.buffer.name);
113 XtFree((void *)args);
119 case DtACTION_STATUS_UPDATE:
120 DPR((" ACTION_STATUS_UPDATE\n"));
124 default: /* ignore */
125 DPR((" unknown status (%d)\n", status));
129 if (actionId == 0) { /* action done */
130 send_dtims_msg(WIN_ST_ACTION_DONE, actionDone ? NoError : ErrRemoteAction);
137 static void wait_action_done()
141 DPR(("wait_action_done(): Begin\n"));
143 if (actionId == 0) return;
145 XtSetSensitive(TopW, False);
146 XtAddEventHandler(TopW, NoEventMask, True, dtims_msg_proc, 0);
148 while (actionId != 0 || actionErr != NoError) {
149 XtAppNextEvent(appC, &event);
150 XtDispatchEvent(&event);
153 XtRemoveEventHandler(TopW, XtAllEvents, True, dtims_msg_proc, 0);
154 XtSetSensitive(TopW, True);
156 DPR(("wait_action_done(): End\n"));
160 int invoke_action(action, host)
164 if (init_action_env() != True) return ErrInternal;
166 DPR(("invoke_action(%s): host=%s\n", action, host));
168 if (!action || !*action) return ErrInternal;
169 if (host && !*host) host = NULL;
174 if (DtActionExists(action) != True) {
175 DPR(("invoke_action(%s): action not exists\n", action));
179 /* Invoke the specified action */
180 actionId = DtActionInvoke(TopW, action, NULL, 0,
181 NULL, host, NULL, False, action_cb, NULL);
183 DPR(("invoke_action(%s): actionId=%d\n", actionId));
191 void send_dtims_msg(msg, errcode)
196 ev.xclient.type = ClientMessage;
197 ev.xclient.window = winEnv.atom_owner;
198 ev.xclient.message_type = winEnv.atom_status;
199 ev.xclient.format = 32;
200 ev.xclient.data.l[0] = msg;
201 ev.xclient.data.l[1] = errcode;
202 ev.xclient.data.l[2] = ev.xclient.data.l[3] = ev.xclient.data.l[4] = 0L;
204 XSendEvent(Dpy, XtWindow(TopW), False, NoEventMask, &ev);
207 void dtims_msg_proc(w, cd, event, continue_dispatch)
211 Boolean *continue_dispatch; /* never changed */
213 XClientMessageEvent *ev = &event->xclient;
216 DPR(("dtimsMessageProc()\n"));
218 if (event->type != ClientMessage) return;
219 if (ev->message_type != winEnv.atom_status && ev->format != 32) {
220 DPR(("\tinvalid type([%d]%s) or format(%d) -- ignored\n",
221 ev->message_type, XGetAtomName(Dpy, ev->message_type), ev->format));
224 msg = (int)ev->data.l[0];
225 errcode = (int)ev->data.l[1];
228 case WIN_ST_REMOTE_CONF:
229 case WIN_ST_REMOTE_RUN:
232 case WIN_ST_ACTION_DONE:
233 DPR(("\tmsg=%d errcode=%d\n", msg, errcode));
238 DPR(("\tunknown msg value (%d) -- ignored\n", msg));