1 /* $TOG: dtinfo_start.c /main/9 1999/09/20 13:26:59 mgreess $
3 * (c) Copyright 1996 Digital Equipment Corporation.
4 * (c) Copyright 1996 Hewlett-Packard Company.
5 * (c) Copyright 1996 International Business Machines Corp.
6 * (c) Copyright 1996 Sun Microsystems, Inc.
7 * (c) Copyright 1996 Novell, Inc.
8 * (c) Copyright 1996 FUJITSU LIMITED.
9 * (c) Copyright 1996 Hitachi.
11 * This file contains the main program for: dtinfo_start
17 #include <X11/Intrinsic.h>
22 #include <Dt/EnvControlP.h>
23 #include <Dt/Action.h>
24 #include <Dt/DtGetMessageP.h>
25 #include <Dt/MsgLog.h>
29 #include "dtinfo_start.h"
30 #include "dtinfo_start.opnums"
33 * Operation names, number of arguments and default action names
35 static const char * LOAD_INFO_LIB_STRING = "DtInfo_LoadInfoLib";
36 static const int LOAD_INFO_LIB_ARGS = 3;
37 static const char * LOAD_INFO_LIB_ACTION = "DtInfoStart";
39 static const char * SHOW_INFO_AT_LOC_STRING = "DtInfo_ShowInfoAtLoc";
40 static const int SHOW_INFO_AT_LOC_ARGS = 4;
41 static const char * SHOW_INFO_LIB_SECTION_ACTION = "DtInfoStartAtLoc";
46 static Widget top_level;
48 static XtAppContext app_context;
50 static const int time_out = 1000; /* milliseconds */
52 static const int SET_NUM = 1; /* message cat set number */
54 static const char * name = "DtInfo"; /* ptype name and Xt name */
57 * Forward declarations for static functions
59 static int InvokeAction (
62 const char * action_name,
67 static void ActionDoneCallback (
68 DtActionInvocationID id,
69 XtPointer client_data,
72 DtActionStatus status);
75 XtPointer client_data,
78 static Tt_status ConnectToMessageServer (
81 static void ReceiveMessage (
82 XtPointer client_data,
86 static void LogToolTalkError (
87 DtMsgLogType msg_type,
91 static void DieFromToolTalkError (
107 XtSetLanguageProc (NULL, NULL, NULL);
109 _DtEnvControl (DT_ENV_SET);
111 XtToolkitInitialize ();
113 app_context = XtCreateApplicationContext ();
115 if (!(display = XtOpenDisplay (app_context, NULL, NULL, name,
116 NULL, NULL, &argc, argv))) {
117 DtMsgLogMessage (argv[0], DtMsgLogError,
118 (char *) GETMESSAGE (SET_NUM, 7, "XtOpenDisplay() failed. Perhaps the DISPLAY environment\nvariable is not set or is invalid."));
123 * Create a minimalist application shell - needed by
126 XtSetArg (args[i], XtNallowShellResize, True); i++;
127 XtSetArg (args[i], XtNmappedWhenManaged, False); i++;
128 XtSetArg (args[i], XtNheight, 1); i++;
129 XtSetArg (args[i], XtNwidth, 1); i++;
131 top_level = XtAppCreateShell (argv[0],
133 topLevelShellWidgetClass,
138 XtRealizeWidget (top_level);
141 * Initialize the desktop
143 if (DtAppInitialize (app_context, display, top_level, argv[0], name)
145 DtMsgLogMessage (argv[0], DtMsgLogError,
146 (char *) GETMESSAGE (SET_NUM, 8, "DtAppInitialize() failed. Perhaps the desktop environment\nis not properly installed."));
151 * Connect to the message server
153 status = ConnectToMessageServer (argv[0]);
154 if (TT_OK != status) {
158 * An error Message has already been logged.
160 errfmt = GETMESSAGE (2, 2,
161 "Could not connect to ToolTalk:\n%s\nExiting ...");
162 DieFromToolTalkError (top_level, errfmt, status);
166 * Load the datatypes and actions
170 XtAppMainLoop (app_context);
178 const char * action_name,
185 DtActionInvocationID action_id;
187 if (op_num == SHOW_INFO_AT_LOC)
190 args = (DtActionArg *) XtCalloc (num_args, sizeof (DtActionArg));
192 DtMsgLogMessage (prog_name, DtMsgLogError,
193 (char *) GETMESSAGE (SET_NUM, 6,
194 "Cannot invoke an action because malloc(1) failed."));
198 args[0].argClass = DtACTION_FILE;
199 args[0].u.file.name = info_lib;
201 if (op_num == SHOW_INFO_AT_LOC) {
202 args[1].argClass = DtACTION_BUFFER;
203 args[1].u.buffer.name = topic;
204 args[1].u.buffer.size = strlen (topic) + 1;
205 args[1].u.buffer.writable = False;
208 action_id = DtActionInvoke (top_level,
209 (char *) action_name,
216 (DtActionCallbackProc) ActionDoneCallback,
220 DtMsgLogMessage (prog_name, DtMsgLogError, "Invoked %s\n", action_name);
224 * The following test, comment and code are from:
225 * $TOP/dtaction/Main.c
227 * "Set up a timer if we didn't get a valid procId --
228 * since there will be no invocation update in that case."
231 XtAppAddTimeOut (app_context,
233 (XtTimerCallbackProc) Exit,
244 DtActionInvocationID id,
245 XtPointer client_data,
248 DtActionStatus status)
255 status_name = "DtACTION_DONE";
258 status_name = "DtACTION_DONE";
260 case DtACTION_INVOKED:
261 status_name = "DtACTION_DONE";
263 case DtACTION_FAILED:
264 status_name = "DtACTION_DONE";
266 case DtACTION_CANCELED:
267 status_name = "DtACTION_DONE";
269 case DtACTION_INVALID_ID:
270 status_name = "DtACTION_DONE";
272 case DtACTION_STATUS_UPDATE:
273 status_name = "DtACTION_DONE";
276 status_name = "UNKNOWN";
284 DtMsgLogMessage ("dtinfo_start", DtMsgLogError,
285 "Action returned %s\n", status_name);
287 XtAppAddTimeOut(app_context, 10 * time_out,
288 (XtTimerCallbackProc) Exit,
291 case DtACTION_INVOKED:
292 case DtACTION_FAILED:
293 case DtACTION_CANCELED:
294 case DtACTION_INVALID_ID:
295 case DtACTION_STATUS_UPDATE:
298 DtMsgLogMessage ("dtinfo_start", DtMsgLogError,
299 "Action returned %s\n", status_name);
301 XtAppAddTimeOut(app_context, 10 * time_out,
302 (XtTimerCallbackProc) Exit,
309 ConnectToMessageServer (
320 status = tt_pointer_error (procid);
321 if (status != TT_OK) {
322 LogToolTalkError (DtMsgLogError, prog_name,
328 status = tt_ptype_declare (name);
329 if (status != TT_OK) {
330 LogToolTalkError (DtMsgLogError, prog_name,
331 "tt_ptype_declare", status);
337 if ((tt_int_error (ttfd)) != TT_OK) {
338 LogToolTalkError (DtMsgLogError, prog_name,
344 XtAppAddInput (app_context, ttfd, (XtPointer) XtInputReadMask,
345 ReceiveMessage, (char *) prog_name);
347 status = tt_session_join (tt_default_session());
348 if ((tt_int_error (ttfd)) != TT_OK) {
349 LogToolTalkError (DtMsgLogError, prog_name,
350 "tt_session_join", status);
364 XtPointer client_data,
368 static int last_op_num = 0;
373 const char * action_name;
377 char * prog_name = (char *) client_data;
378 static char lang[200];
379 const char * op_name;
380 char * info_lib = NULL;
382 message = tt_message_receive();
384 /* from tt_message_receive(3), and after examining other TT clients */
385 if (message == 0) return;
387 if (tt_pointer_error (message) != TT_OK) {
388 LogToolTalkError (DtMsgLogError, prog_name,
389 "tt_message_receive",
390 tt_pointer_error (message));
394 op_num = tt_message_opnum (message);
398 op_name = LOAD_INFO_LIB_STRING;
401 case SHOW_INFO_AT_LOC:
402 op_name = SHOW_INFO_AT_LOC_STRING;
407 * Don't know how I got this message
409 DtMsgLogMessage (prog_name, DtMsgLogError,
410 (char *) GETMESSAGE (SET_NUM, 11, "The message operation '%d' is not supported."),
413 tt_message_reject (message);
414 tt_message_destroy(message);
420 * Check the number of arguments
422 num_args = tt_message_args_count (message);
423 if ((op_num == LOAD_INFO_LIB && num_args != LOAD_INFO_LIB_ARGS) ||
424 (op_num == SHOW_INFO_AT_LOC && num_args != SHOW_INFO_AT_LOC_ARGS)) {
426 DtMsgLogMessage (prog_name, DtMsgLogError,
427 (char *) GETMESSAGE (SET_NUM, 12, "Message '%s' does not have the required\nnumber of arguments '%d'."),
429 (op_num == LOAD_INFO_LIB) ?
430 LOAD_INFO_LIB_ARGS : SHOW_INFO_AT_LOC_ARGS);
431 tt_message_reject (message);
432 tt_message_destroy(message);
437 * Check for an info lib
439 info_lib = tt_message_file (message);
440 if ((tt_ptr_error (info_lib) != TT_OK) || info_lib == NULL) {
442 * Use DTINFOLIBDEFAULT if it is defined
444 if ((info_lib = getenv ("DTINFOLIBDEFAULT")) == NULL) {
445 DtMsgLogMessage (prog_name, DtMsgLogError,
446 (char *) GETMESSAGE (SET_NUM, 10, "An InfoLib was not provided in the '%s' message\nand the environment variable DTINFOLIBDEFAULT was not defined."),
452 if ((action_name = tt_message_arg_val (message, 0)) == NULL) {
454 action_name = (op_num == LOAD_INFO_LIB) ?
455 LOAD_INFO_LIB_ACTION : SHOW_INFO_LIB_SECTION_ACTION;
457 DtMsgLogMessage (prog_name, DtMsgLogWarning,
458 (char *) GETMESSAGE (SET_NUM, 13, "Message '%s' specified a NULL action name.\nAction '%s' will be invoked."),
463 if ((exec_host = tt_message_arg_val (message, 1)) == NULL) {
465 DtMsgLogMessage (prog_name, DtMsgLogWarning,
466 (char *) GETMESSAGE (SET_NUM, 14, "Message '%s' specified a NULL execution host."),
470 if ((locale = tt_message_arg_val (message, 2)) == NULL) {
472 DtMsgLogMessage (prog_name, DtMsgLogWarning,
473 (char *) GETMESSAGE (SET_NUM, 15, "Message '%s' specified a NULL locale."),
478 * Put locale into the environment so that DtActionInvoke
479 * will propagate it to the dtinfo process.
481 (void) sprintf (lang, "LANG=%s", locale);
482 (void) putenv (lang);
485 if (op_num == SHOW_INFO_AT_LOC) {
486 if ((topic = tt_message_arg_val (message, 3)) == NULL) {
488 DtMsgLogMessage (prog_name, DtMsgLogError,
489 (char *) GETMESSAGE (SET_NUM, 16, "Message '%s' specified a NULL topic."),
495 if (op_num == last_op_num)
498 DtMsgLogMessage("dtinfo_start", DtMsgLogError,
499 "Received a duplicate tooltalk message: %s",
500 (op_num == LOAD_INFO_LIB) ?
501 "LOAD_INFO_LIB" : "SHOW_INFO_AT_LOC" );
508 "dtinfo_start", DtMsgLogError,
509 "Received a tooltalk message: %s\nInvoking action %s",
510 (op_num==LOAD_INFO_LIB) ? "LOAD_INFO_LIB" : "SHOW_INFO_AT_LOC",
513 last_op_num = op_num;
514 opstatus = InvokeAction (prog_name,
521 tt_message_fail (message);
526 tt_message_reply (message);
528 tt_message_destroy(message);
534 DtMsgLogType msg_type,
536 char * function_name,
540 message = tt_status_message(error_num);
541 DtMsgLogMessage (prog_name, msg_type, "%s: %s", function_name, message);
544 #define GETXMSTRING(s, m, d) XmStringCreateLocalized(GETMESSAGE(s,m,d))
547 ExitCB (Widget dialog, XtPointer client_data, XtPointer call_data)
549 exit((int) client_data);
553 DieFromToolTalkError(Widget parent, char *errfmt, Tt_status status)
556 Widget dialog, dialogShell;
557 char *errmsg, *statmsg, *title;
558 XmString xms_errmsg, xms_ok, xms_title;
561 if (! tt_is_err(status)) return;
563 statmsg = tt_status_message(status);
564 errmsg = XtMalloc(strlen(errfmt) + strlen(statmsg) + 2);
565 sprintf(errmsg, errfmt, statmsg);
567 xms_ok = GETXMSTRING(2, 3, "OK");
568 xms_errmsg = XmStringCreateLocalized(errmsg);
569 xms_title = GETXMSTRING(2, 1, "Dtinfo: Error");
572 XtSetArg(args[n], XmNautoUnmanage, False); n++;
573 XtSetArg(args[n], XmNokLabelString, xms_ok); n++;
574 XtSetArg(args[n], XmNdialogTitle, xms_title); n++;
575 XtSetArg(args[n], XmNmessageString, xms_errmsg); n++;
576 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
578 dialog = XmCreateErrorDialog(parent, "DtinfoStartError", args, n);
579 XtAddCallback(dialog, XmNokCallback, ExitCB, (XtPointer) status);
580 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
581 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
584 * Disable the frame menu from dialog since we don't want the user
585 * to be able to close dialogs with the frame menu
587 dialogShell = XtParent(dialog);
589 XtSetArg(args[n], XmNmwmDecorations, MWM_DECOR_ALL | MWM_DECOR_MENU); n++;
590 XtSetValues(dialogShell, args, n);
591 XtManageChild(dialog);
592 XtRealizeWidget(dialogShell);
595 XmStringFree(xms_ok);
596 XmStringFree(xms_errmsg);
597 XmStringFree(xms_title);
600 XtAppProcessEvent(XtWidgetToApplicationContext(dialog), XtIMAll);
606 XtPointer client_data,
610 * The following code to determine if DtActionInvoke
611 * resulted in the posting a dialog is from:
612 * $TOP/dtaction/Main.c
614 if (top_level->core.num_popups == 0)
617 XtAppAddTimeOut (app_context,
619 (XtTimerCallbackProc) Exit,