home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xtici.zip / xtici / message.c < prev    next >
C/C++ Source or Header  |  1991-08-28  |  13KB  |  447 lines

  1. /*
  2.  * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
  3.  *     All Rights Reserved
  4.  * 
  5.  * This file is a component of an X Window System client which uses the Xcms 
  6.  * Color Management System.  TekColor is a trademark of Tektronix, Inc.  The
  7.  * TekColor Editor is the subject of U.S. and foreign patents pending.  The
  8.  * term "TekHVC" designates a particular color space that is the subject of
  9.  * U.S. Patent No. 4,985,853 (equivalent foreign patents pending).
  10.  * Permission is hereby granted to use, copy, modify, sell, and otherwise
  11.  * distribute this software and its documentation for the X Window System
  12.  * environment, for any purpose and without fee, provided that:
  13.  * 
  14.  * 1.    The code and documentation are only used to implement a 
  15.  *      TekColor Editor in an X Window System environment; and
  16.  * 2.    This copyright and permission notice is reproduced in all copies
  17.  *     of the code and in supporting documentation.
  18.  * 
  19.  * Permission is granted to modify this code as required to allow it to
  20.  * be compiled on any host computer, provided that the functionality of
  21.  * the TekColor Editor is not modified in any way.  A description of any 
  22.  * modifications must be sent to Tektronix, Inc.  Contact 
  23.  * Tektronix Inc., P.O. Box 1000, Mail Station 60-850, 
  24.  * Network Displays Division Engineering, Wilsonville, OR 97070.
  25.  *
  26.  * Tektronix makes no representation about the suitability of this software
  27.  * for any purpose.  It is provided "as is" and with all faults.
  28.  * 
  29.  * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
  30.  * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  31.  * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
  32.  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  33.  * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
  34.  * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  35.  * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
  36.  * 
  37.  *    NAME
  38.  *        message - print messages to the user
  39.  *
  40.  *    DESCRIPTION
  41.  *        Display diagnostics to the user, sometimes wait for response.
  42.  *    There are a number of message types.
  43.  *    An error message is printed to stderr (on the host).  These
  44.  *    messages detect a problem in the commandline or in the environment.
  45.  *    These errors are placed on stderr because the windowed environment
  46.  *    is (usually) not yet established.
  47.  *    Info messages are popped when something happens the user may want
  48.  *    to know about.  They are not modal - the user can leave them up and
  49.  *    continue to run.
  50.  *    Warn is used when the user is about to perform a potentially dangerous
  51.  *    task, asking for confirmation before proceeding.  This includes actions
  52.  *    where the system is in a contradictory position, proceeding to resolve
  53.  *    the contradiction may have unusually side effects.  The dialog is
  54.  *    modal.
  55.  *    Ask is used when two choices are possible but there is no "default"
  56.  *    action.  The question is phrased so the user makes a binary choice.
  57.  *    This dialog is also modal.
  58.  */
  59. #ifndef LINT
  60. static char *copy_notice = "Copyright 1991 Tektronix, Inc.";
  61. #ifdef RCS_ID
  62. static char *rcsid=  "$Header: message.c,v 1.2 91/08/22 11:34:07 adamsc Exp $";
  63. #endif /* RCS_ID */
  64. #endif /* LINT */
  65.  
  66. /*
  67.  *      EXTERNAL INCLUDES
  68.  */
  69.  
  70.  
  71. /*
  72.  *      INTERNAL INCLUDES
  73.  */
  74. #include <stdio.h>
  75. #include <X11/StringDefs.h>
  76. #include <X11/Intrinsic.h>
  77. #include <X11/Shell.h>
  78. #include <X11/Xaw/Box.h>
  79. #include <X11/Xaw/Command.h>
  80. #include <X11/Xaw/Dialog.h>
  81. #include <X11/Xaw/Form.h>
  82.  
  83. #include "xtici.h"
  84. /*
  85.  *      EXTERNS
  86.  */
  87.  
  88. extern char *exeName;
  89.  
  90.  
  91. /*
  92.  *      GLOBALS
  93.  */
  94. #ifdef DEC
  95. #  define GLOBAL    global
  96. #else
  97. #  define GLOBAL
  98. #endif
  99.  
  100.  
  101. /*
  102.  *      LOCAL DEFINES
  103.  */
  104.  
  105.  
  106. /*
  107.  *      LOCAL TYPEDEFS
  108.  *
  109.  */
  110.  
  111.  
  112. /*
  113.  *      LOCALS VARIABLES
  114.  */
  115. #ifdef DEBUG
  116. #  define STATIC
  117. #else
  118. #  define STATIC        static
  119. #endif
  120.  
  121. STATIC int answer = -1;
  122.  
  123. STATIC Widget helpButton = NULL;
  124. STATIC Widget pshell = NULL;
  125. STATIC Widget ishell = NULL;
  126.  
  127. /************************************************************************
  128.  *                                    *
  129.  *            PRIVATE ROUTINES                *
  130.  *                                    *
  131.  ************************************************************************/
  132. /*
  133.  * Warning widget callback
  134.  */
  135. /* ARGSUSED */
  136. STATIC void Answer(w, data, call)
  137. Widget w;
  138. XtPointer data;
  139. XtPointer call;
  140. {
  141.     answer = (int)data;
  142. }
  143.  
  144. /*
  145.  * Spin our wheels here until the user responds.
  146.  */
  147. STATIC void BlockOnResponse(w1, w2, w3)
  148. Window w1, w2, w3;
  149. {
  150.     XtAppContext app = XtDisplayToApplicationContext(dpy);
  151.     XEvent ev;
  152.     XButtonEvent *ep = (XButtonEvent *)&ev;
  153.     Window h = 0;
  154.     XEvent cache;
  155.     int cached = 0;
  156.  
  157.     answer = -1;
  158.  
  159.     while (answer < 0) {
  160.     XtAppNextEvent(app, &ev);
  161.     /* 
  162.      * HACK!!  stop button events from all but dialog window
  163.      * This is necessary because there is no application modal dialog
  164.      * option, just modal with respect to tree.
  165.      * Just modifying the buttons is sufficient because this is the only
  166.      * input we respond to in the auxiliary window.
  167.      */
  168.     switch (ep->type) {
  169.     case ButtonPress:
  170.     case ButtonRelease:
  171.         if (!h && helpButton)
  172.         h = XtWindow(helpButton);
  173.         if ( (ep->window != w1) && (ep->window != w2) &&
  174.          (ep->window != w3) && (ep->window != h) ) {
  175.         /*
  176.          * But it is often necessary to not lose the first release.
  177.          */
  178.         if (!cached && (ep->type == ButtonRelease)) {
  179.             cached = 1;
  180.             cache = ev;
  181.         }
  182.         continue;
  183.         }
  184.         break;
  185.     default:
  186.         break;
  187.     }
  188.     XtDispatchEvent(&ev);
  189.     }
  190.  
  191.     if (cached)
  192.     XPutBackEvent(dpy, &cache);
  193. }
  194.  
  195.  
  196. /*
  197.  * Clean up the widget.
  198.  */
  199. /* ARGSUSED */
  200. STATIC void DestroyParent(w, pshellw, call)
  201. Widget w;
  202. XtPointer pshellw;
  203. XtPointer call;
  204. {
  205.     /*  This assumes that a button (w) lays on a form */
  206.     /*  and all that lays on the popup shell */
  207.     XtDestroyWidget (XtParent(w));
  208.     XtPopdown ((Widget)pshellw);
  209. }
  210.  
  211. /*
  212.  * Dynamically create a help dialog from the passed string,
  213.  * then map it.
  214.  */
  215. /* ARGSUSED */
  216. STATIC void HelpPop(w, pmsg, call)
  217. Widget w;
  218. XtPointer pmsg;
  219. XtPointer call;
  220. {
  221.     char *msg = (char *)pmsg;
  222.     Arg args[2];
  223.     Widget info, infom;
  224.     int n = 0;
  225.  
  226.     if (!ishell) {
  227.     XtSetArg(args[n], XtNx, 0);            n++;
  228.     XtSetArg(args[n], XtNy, 0);            n++;
  229.     ishell = XtCreatePopupShell("info", transientShellWidgetClass,
  230.                       primary, args, n);
  231.     } 
  232.  
  233.     n = 0;
  234.     info = XtCreateManagedWidget("helpbox", boxWidgetClass, ishell, args, n);
  235.  
  236.     n = 0;
  237.     XtSetArg(args[n], XtNlabel, msg);            n++;
  238.     infom = XtCreateManagedWidget("infom", labelWidgetClass, info, args, n);
  239.  
  240.     n = 0;
  241.     XtSetArg(args[n], XtNlabel, "OK");            n++;
  242.     helpButton = XtCreateManagedWidget("quit", commandWidgetClass, info,
  243.                        args, n);
  244.     XtAddCallback (helpButton, XtNcallback, DestroyParent, (XtPointer)ishell);
  245.  
  246.     XtPopup (ishell, XtGrabNonexclusive);
  247. }
  248.  
  249. /************************************************************************
  250.  *                                    *
  251.  *            PUBLIC ROUTINES                    *
  252.  *                                    *
  253.  ************************************************************************/
  254.  
  255. /*
  256.  * Put up an application modal question dialog.
  257.  * This means that we will spin here until the dialog is acknowledged.
  258.  * The difference between this routine and Warning is that here we are
  259.  * asking for guidance to do one thing or another; with Warning, we are
  260.  * allowing the user to back out of an operation.
  261.  */
  262. int Ask(msg, help)
  263. char *msg, *help;
  264. {
  265.     Widget ask, askmsg, button1, button2, button3;
  266.     Position x, y;
  267.     Arg args[5];
  268.     int n = 0;
  269.  
  270.     if (!pshell) {
  271.     XtTranslateCoords (primary, (Position)0, (Position)0, &x, &y);
  272.     XtSetArg(args[n], XtNx, x);            n++;
  273.     XtSetArg(args[n], XtNy, y);            n++;
  274.     pshell = XtCreatePopupShell("popup", transientShellWidgetClass,
  275.                     primary, args, n);
  276.     }
  277.     
  278.     n = 0;
  279.     ask = XtCreateWidget("ask", formWidgetClass, pshell, args, n);
  280.  
  281.     n = 0;
  282.     XtSetArg(args[n], XtNlabel, msg);            n++;
  283.     askmsg = XtCreateManagedWidget("askmsg", commandWidgetClass, ask, args, n);
  284.  
  285.     n = 0;
  286.     XtSetArg(args[n], XtNlabel, "Ok");            n++;
  287.     XtSetArg(args[n], XtNfromVert, askmsg);        n++;
  288.     button1 = XtCreateManagedWidget("ok", commandWidgetClass, ask, args, n);
  289.     XtAddCallback(button1, XtNcallback, Answer, (XtPointer)MessageOK);
  290.  
  291.     n = 0;
  292.     XtSetArg(args[n], XtNfromVert, askmsg);        n++;
  293.     XtSetArg(args[n], XtNfromHoriz, button1);        n++;
  294.     XtSetArg(args[n], XtNlabel, "Cancel");        n++;
  295.     button2 = XtCreateManagedWidget("cancel", commandWidgetClass, ask, args,n);
  296.     XtAddCallback(button2, XtNcallback, Answer, (XtPointer)MessageCancel);
  297.  
  298.     if (help) {
  299.     n = 0;
  300.         XtSetArg(args[n], XtNfromVert, askmsg);        n++;
  301.     XtSetArg(args[n], XtNfromHoriz, button2);    n++;
  302.     XtSetArg(args[n], XtNlabel, "Help");
  303.     button3 = XtCreateManagedWidget("help", commandWidgetClass, ask, 
  304.                     args, n);
  305.     XtAddCallback(button3, XtNcallback, HelpPop, (XtPointer)help);
  306.     }
  307.  
  308.     XtManageChild(ask);
  309.     XtPopup (pshell, XtGrabNonexclusive);
  310.     if (!help)
  311.     BlockOnResponse(XtWindow(button1), XtWindow(button2), None);
  312.     else 
  313.     BlockOnResponse(XtWindow(button1), XtWindow(button2),
  314.             XtWindow(button3));
  315.  
  316.     /* killing the dialog automatically kills the dialog shell */
  317.     XtDestroyWidget(ask);
  318.     XtPopdown (pshell);
  319.  
  320.     return(answer);
  321. }
  322.  
  323.  
  324. /*
  325.  * Report a system error; there is no recovery, so just return.
  326.  * Typically called during setup, so dialogs are not used.
  327.  */
  328. void Error(diag)
  329. char *diag;
  330. {
  331.     fprintf(stderr, "%s: %s\n", exeName, diag);
  332.     exit(1);
  333. }
  334.  
  335. /*
  336.  * Put up an information dialog.
  337.  * TODO: is there any way these things can be cached / reused ?
  338.  */
  339. void InformMsg(msg, help)
  340. char *msg, *help;
  341. {
  342.     Widget info, infomsg, button1, button2;
  343.     Position x, y;
  344.     Arg args[2];
  345.     int n = 0;
  346.  
  347.     if (!pshell) {
  348.     XtTranslateCoords (primary, (Position)0, (Position)0, &x, &y);
  349.     XtSetArg(args[n], XtNx, x);            n++;
  350.     XtSetArg(args[n], XtNy, y);            n++;
  351.     pshell = XtCreatePopupShell("popup", transientShellWidgetClass,
  352.                     primary, args, n);
  353.     }
  354.  
  355.     n = 0;
  356.     info = XtCreateWidget("info", formWidgetClass, pshell, args, n);
  357.     
  358.     n = 0;
  359.     XtSetArg(args[n], XtNlabel, msg);            n++;
  360.     infomsg = XtCreateManagedWidget("infomsg", labelWidgetClass, info, args,n);
  361.  
  362.     n = 0;
  363.     XtSetArg(args[n], XtNfromVert, infomsg);        n++;
  364.     XtSetArg(args[n], XtNlabel, "Ok");            n++;
  365.     button1 = XtCreateManagedWidget("ok", commandWidgetClass, info, args, n);
  366.     XtAddCallback(button1, XtNcallback, DestroyParent, (XtPointer)pshell);
  367.  
  368.     if (help) {
  369.     n = 0;
  370.     XtSetArg(args[n], XtNfromVert, infomsg);    n++;
  371.     XtSetArg(args[n], XtNfromHoriz, button1);   n++;
  372.     button2 = XtCreateManagedWidget("help", commandWidgetClass, info, 
  373.                     args, n);
  374.     XtAddCallback(button2, XtNcallback, HelpPop, (XtPointer)help);
  375.     }
  376.     XtManageChild(info);
  377.     XtPopup (pshell, XtGrabNonexclusive);
  378. }
  379.  
  380. /*
  381.  * Put up an application modal warning dialog.
  382.  * This means that we will spin here until the dialog is acknowledged.
  383.  */
  384. int Warning(msg, help)
  385. char *msg, *help;
  386. {
  387.     Widget warn, warnmsg, button1, button2, button3;
  388.     Position x, y;
  389.     Arg args[10];
  390.     int n = 0;
  391.  
  392.     if (!pshell) {
  393.     XtTranslateCoords (primary, (Position)0, (Position)0, &x, &y);
  394.     XtSetArg(args[n], XtNx, x);            n++;
  395.     XtSetArg(args[n], XtNy,    y);            n++;
  396.     pshell = XtCreatePopupShell("popup", transientShellWidgetClass,
  397.                     primary, args, n);
  398.     } 
  399.  
  400.     n = 0;
  401.     warn = XtCreateWidget("warn", formWidgetClass, pshell, args, n);
  402.     
  403.     n = 0;
  404.     XtSetArg(args[n], XtNlabel, msg);            n++;
  405.     warnmsg = XtCreateManagedWidget("warnmsg", labelWidgetClass, warn, 
  406.                     args, n);
  407.  
  408.     n = 0;
  409.     XtSetArg(args[n], XtNfromVert, warnmsg);        n++;
  410.     XtSetArg(args[n], XtNlabel, "Ok");            n++;
  411.     button1 = XtCreateManagedWidget("ok", commandWidgetClass, warn,
  412.                     args, n);
  413.     XtAddCallback(button1, XtNcallback, Answer, (XtPointer)MessageContinue);
  414.  
  415.     n = 0;
  416.     XtSetArg(args[n], XtNfromVert, warnmsg);        n++;
  417.     XtSetArg(args[n], XtNfromHoriz, button1);        n++;
  418.     XtSetArg(args[n], XtNlabel, "Cancel");        n++;
  419.     button2 = XtCreateManagedWidget("cancel", commandWidgetClass, warn, 
  420.                     args, n);
  421.     XtAddCallback(button2, XtNcallback, Answer, (XtPointer)MessageCancel);
  422.  
  423.     if (help) {
  424.     n = 0;
  425.     XtSetArg(args[n], XtNfromVert, warnmsg);    n++;
  426.     XtSetArg(args[n], XtNfromHoriz, button2);   n++;
  427.     XtSetArg(args[n], XtNlabel, "Help");        n++;
  428.     button3 = XtCreateManagedWidget("help", commandWidgetClass, warn, 
  429.                     args, n);
  430.     XtAddCallback(button3, XtNcallback, HelpPop, (XtPointer)help);
  431.     }
  432.  
  433.     XtManageChild(warn);
  434.     XtPopup (pshell, XtGrabNonexclusive);
  435.     if (!help)
  436.     BlockOnResponse(XtWindow(button1), XtWindow(button2), None);
  437.     else 
  438.     BlockOnResponse(XtWindow(button1), XtWindow(button2),
  439.             XtWindow(button3));
  440.  
  441.     /* killing the form automatically kills the children but not the shell */
  442.     XtDestroyWidget(warn);
  443.     XtPopdown (pshell);
  444.  
  445.     return(answer);
  446. }
  447.