action.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  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)
  10. * any later version.
  11. *
  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
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* @(#)$XConsortium: action.c /main/3 1996/05/07 13:57:56 drk $ */
  24. #include <Xm/Xm.h>
  25. #include <Dt/Dt.h>
  26. #include <Dt/Action.h>
  27. #include "xims.h"
  28. static void DbReloadProc(/* cd */);
  29. static bool init_action_env(/* */);
  30. static void action_cb(long unsigned id, XtPointer cd,
  31. DtActionArg *args, int argcnt, DtActionStatus status);
  32. static void wait_action_done(/* */);
  33. static bool actionEnabled = False;
  34. static int actionDone = True;
  35. static int actionErr = NoError;
  36. static DtActionInvocationID actionId = 0;
  37. /* ***** DtAction functions ***** */
  38. static void DbReloadProc(XtPointer cd)
  39. {
  40. DPR(("DbReloadProc(): action database updated\n"));
  41. DtDbLoad(); /* Pick up any dynamic changes to the database files */
  42. }
  43. static bool init_action_env(void)
  44. {
  45. init_window_env();
  46. if (actionEnabled != True) {
  47. if (DtAppInitialize(appC, Dpy, TopW, Wargv[0], DTIMS_CLASS) == False) {
  48. /* DtInitialize() has already logged an appropriate error msg */
  49. return False;
  50. }
  51. DtDbLoad(); /* Load the filetype/action databases */
  52. DtDbReloadNotify(DbReloadProc, NULL);
  53. actionEnabled = True;
  54. }
  55. return actionEnabled;
  56. }
  57. static void action_cb(long unsigned id, XtPointer cd /* unused */,
  58. DtActionArg *args, int argcnt, DtActionStatus status)
  59. {
  60. if (actionId == 0) {
  61. DPR(("action_cb(): invalid id %d != %d\n", id, actionId));
  62. return;
  63. }
  64. if (id != actionId) {
  65. DPR(("action_cb(): invalid id %d != %d\n", id, actionId));
  66. return;
  67. }
  68. switch ((DtActionStatus) status) {
  69. case DtACTION_INVOKED:
  70. DPR((" ACTION_INVOKED\n"));
  71. break;
  72. case DtACTION_DONE:
  73. DPR((" ACTION_DONE\n"));
  74. actionId = 0;
  75. actionDone = True;
  76. break;
  77. case DtACTION_CANCELED:
  78. case DtACTION_FAILED:
  79. DPR((" ACTION_%sED\n",
  80. (status == DtACTION_CANCELED) ? "CANCEL" : "FAIL"));
  81. if (args && argcnt > 0) {
  82. int i;
  83. for (i = 0; i < argcnt; i++) {
  84. if (args[i].argClass == DtACTION_FILE) {
  85. XtFree(args[i].u.file.name);
  86. } else if (args[i].argClass == DtACTION_BUFFER) {
  87. XtFree(args[i].u.buffer.bp);
  88. XtFree(args[i].u.buffer.type);
  89. XtFree(args[i].u.buffer.name);
  90. }
  91. }
  92. XtFree((void *)args);
  93. }
  94. actionId = 0;
  95. actionDone = False;
  96. break;
  97. case DtACTION_STATUS_UPDATE:
  98. DPR((" ACTION_STATUS_UPDATE\n"));
  99. actionDone = False;
  100. break;
  101. default: /* ignore */
  102. DPR((" unknown status (%d)\n", status));
  103. break;
  104. }
  105. if (actionId == 0) { /* action done */
  106. send_dtims_msg(WIN_ST_ACTION_DONE, actionDone ? NoError : ErrRemoteAction);
  107. }
  108. return;
  109. }
  110. static void wait_action_done(void)
  111. {
  112. XEvent event;
  113. DPR(("wait_action_done(): Begin\n"));
  114. if (actionId == 0) return;
  115. XtSetSensitive(TopW, False);
  116. XtAddEventHandler(TopW, NoEventMask, True, dtims_msg_proc, 0);
  117. while (actionId != 0 || actionErr != NoError) {
  118. XtAppNextEvent(appC, &event);
  119. XtDispatchEvent(&event);
  120. }
  121. XtRemoveEventHandler(TopW, XtAllEvents, True, dtims_msg_proc, 0);
  122. XtSetSensitive(TopW, True);
  123. DPR(("wait_action_done(): End\n"));
  124. return;
  125. }
  126. int invoke_action(char *action, char *host)
  127. {
  128. if (init_action_env() != True) return ErrInternal;
  129. DPR(("invoke_action(%s): host=%s\n", action, host));
  130. if (!action || !*action) return ErrInternal;
  131. if (host && !*host) host = NULL;
  132. setErrFunc(action);
  133. #ifdef DEBUG
  134. if (DtActionExists(action) != True) {
  135. DPR(("invoke_action(%s): action not exists\n", action));
  136. }
  137. #endif
  138. /* Invoke the specified action */
  139. actionId = DtActionInvoke(TopW, action, NULL, 0,
  140. NULL, host, NULL, False, action_cb, NULL);
  141. DPR(("invoke_action(%s): actionId=%d\n", actionId));
  142. wait_action_done();
  143. return actionErr;
  144. }
  145. void send_dtims_msg(int msg, int errcode)
  146. {
  147. XEvent ev;
  148. ev.xclient.type = ClientMessage;
  149. ev.xclient.window = winEnv.atom_owner;
  150. ev.xclient.message_type = winEnv.atom_status;
  151. ev.xclient.format = 32;
  152. ev.xclient.data.l[0] = msg;
  153. ev.xclient.data.l[1] = errcode;
  154. ev.xclient.data.l[2] = ev.xclient.data.l[3] = ev.xclient.data.l[4] = 0L;
  155. XSendEvent(Dpy, XtWindow(TopW), False, NoEventMask, &ev);
  156. }
  157. void dtims_msg_proc(Widget w, XtPointer cd, XEvent *event,
  158. Boolean *continue_dispatch /* never changed */)
  159. {
  160. XClientMessageEvent *ev = &event->xclient;
  161. int msg, errcode;
  162. DPR(("dtimsMessageProc()\n"));
  163. if (event->type != ClientMessage) return;
  164. if (ev->message_type != winEnv.atom_status && ev->format != 32) {
  165. DPR(("\tinvalid type([%d]%s) or format(%d) -- ignored\n",
  166. ev->message_type, XGetAtomName(Dpy, ev->message_type), ev->format));
  167. return;
  168. }
  169. msg = (int)ev->data.l[0];
  170. errcode = (int)ev->data.l[1];
  171. switch (msg) {
  172. case WIN_ST_REMOTE_CONF:
  173. case WIN_ST_REMOTE_RUN:
  174. actionId = 0;
  175. case WIN_ST_ACTION_DONE:
  176. DPR(("\tmsg=%d errcode=%d\n", msg, errcode));
  177. actionErr = errcode;
  178. break;
  179. default:
  180. DPR(("\tunknown msg value (%d) -- ignored\n", msg));
  181. break;
  182. }
  183. return;
  184. }