home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / xephem / part21 / msgmenu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-15  |  6.8 KB  |  291 lines

  1. /* this file contains the code to put up misc messages: xe_msg().
  2.  * everything goes to stdout and into the message dialog.
  3.  * the latter can be toggled on/off from the main menu.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <math.h>
  9. #if defined(__STDC__)
  10. #include <stdlib.h>
  11. #endif
  12. #include <X11/Xlib.h>
  13. #include <Xm/Xm.h>
  14. #include <Xm/Form.h>
  15. #include <Xm/PushB.h>
  16. #include <Xm/Text.h>
  17. #include <Xm/MessageB.h>
  18.  
  19. #if defined(__STDC__) || defined(__cplusplus)
  20. #define P_(s) s
  21. #else
  22. #define P_(s) ()
  23. #endif
  24.  
  25. extern void prompt_map_cb P_((Widget w, XtPointer client, XtPointer call));
  26. extern void set_something P_((Widget w, char *resource, char *value));
  27. extern void set_xmstring P_((Widget w, char *resource, char *txt));
  28.  
  29. void msg_manage P_((void));
  30. void xe_msg P_((char *msg, int app_modal));
  31. void msg_cursor P_((Cursor c));
  32. static void msg_on_top P_((void));
  33. static void msg_create_w P_((void));
  34. static void msg_erase_cb P_((Widget w, XtPointer client, XtPointer call));
  35. static void msg_close_cb P_((Widget w, XtPointer client, XtPointer call));
  36. static void msg_add P_((char *msg));
  37. static void msg_scroll_down P_((void));
  38. static void msg_stdout P_((char *msg));
  39. static void xe_msg_modal P_((char *p));
  40.  
  41. #undef P_
  42.  
  43. extern Widget toplevel_w;
  44.  
  45. static Widget msg_w;        /* main form dialog widget */
  46. static Widget txt_w;        /* scrolled text widget */
  47. static int txtl;        /* current length of text in txt_w */
  48.  
  49. /* called to force the scrolling message window to be up.
  50.  * bring it down if it already is.
  51.  */
  52. void
  53. msg_manage()
  54. {
  55.     if (!msg_w)
  56.         msg_create_w();
  57.  
  58.     if (!XtIsManaged(msg_w))
  59.         XtManageChild (msg_w);
  60.     else
  61.         XtUnmanageChild (msg_w);
  62. }
  63.  
  64. /* if app_modal != 0
  65.  *   make an application modal info box,
  66.  * else
  67.  *   create dialog if not already made.
  68.  *   add message to the scrolling text window.
  69.  *   also write message to stdout.
  70.  */
  71. void
  72. xe_msg (msg, app_modal)
  73. char *msg;
  74. int app_modal;
  75. {
  76.     if (app_modal) {
  77.         xe_msg_modal (msg);
  78.         return;
  79.     }
  80.  
  81.     if (!msg_w)
  82.         msg_create_w();
  83.     msg_add (msg);
  84.  
  85.     /* if we are managed we bully right under the cursor. */
  86.     if (XtIsManaged(msg_w))
  87.         msg_on_top();
  88.  
  89.     msg_stdout (msg);
  90. }
  91.  
  92. /* called to put up or remove the watch cursor.  */
  93. void
  94. msg_cursor (c)
  95. Cursor c;
  96. {
  97.     Window win;
  98.  
  99.     if (msg_w && (win = XtWindow(msg_w))) {
  100.         Display *dsp = XtDisplay(msg_w);
  101.         if (c)
  102.         XDefineCursor (dsp, win, c);
  103.         else
  104.         XUndefineCursor (dsp, win);
  105.     }
  106. }
  107.  
  108. /* do everything we can to make sure the message dialog is visible.
  109.  */
  110. static void
  111. msg_on_top()
  112. {
  113.     Window win;
  114.  
  115.     /* bring to the top right under the cursor
  116.      * N.B. we can't if this is the first time but don't need to in that
  117.      *   case anyway because that means nothing is on top of us yet.
  118.      */
  119.     win = XtWindow(XtParent(msg_w));
  120.     if (win) {
  121.         XRaiseWindow(XtDisplay(XtParent(msg_w)), win);
  122.         XtCallCallbacks (msg_w, XmNmapCallback, NULL);
  123.     }
  124.  
  125.     XFlush (XtDisplay(msg_w));
  126. }
  127.  
  128. /* create the message dialog */
  129. static void
  130. msg_create_w()
  131. {
  132.     static struct {
  133.         char *name;
  134.         void (*cb)();
  135.     } cb[] = {
  136.         {"Erase", msg_erase_cb},
  137.         {"Close", msg_close_cb},
  138.     };
  139.     Widget w;
  140.     Arg args[20];
  141.     int i, n;
  142.  
  143.     /* make the help shell form-dialog widget */
  144.  
  145.     n = 0;
  146.     XtSetArg (args[n], XmNdefaultPosition, False); n++;
  147.     XtSetArg (args[n], XmNautoUnmanage, False); n++;
  148.     XtSetArg (args[n], XmNfractionBase, 9); n++;
  149.     msg_w = XmCreateFormDialog (toplevel_w, "Message", args, n);
  150.     XtAddCallback (msg_w, XmNmapCallback, prompt_map_cb, NULL);
  151.     set_something (XtParent(msg_w), XmNtitle, "xephem Message");
  152.  
  153.     /* make the control buttons */
  154.  
  155.     for (i = 0; i < XtNumber(cb); i++) {
  156.         n = 0;
  157.         XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  158.         XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  159.         XtSetArg (args[n], XmNleftPosition, 1 + 5*i); n++;
  160.         XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  161.         XtSetArg (args[n], XmNrightPosition, 3 + 5*i); n++;
  162.         w = XmCreatePushButton (msg_w, cb[i].name, args, n);
  163.         XtAddCallback (w, XmNactivateCallback, cb[i].cb, NULL);
  164.         XtManageChild (w);
  165.     }
  166.  
  167.     /* make the scrolled text area to hold the messages */
  168.  
  169.     n = 0;
  170.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  171.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  172.     XtSetArg (args[n], XmNbottomWidget, w); n++;
  173.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  174.     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  175.     XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
  176.     XtSetArg (args[n], XmNeditable, False); n++;
  177.     XtSetArg (args[n], XmNcursorPositionVisible, False); n++;
  178.     txt_w = XmCreateScrolledText (msg_w, "ScrolledText", args, n);
  179.     XtManageChild (txt_w);
  180. }
  181.  
  182. /* callback from the erase pushbutton */
  183. /* ARGSUSED */
  184. static void
  185. msg_erase_cb (w, client, call)
  186. Widget w;
  187. XtPointer client;
  188. XtPointer call;
  189. {
  190.     XmTextReplace (txt_w, 0, txtl, "");
  191.     txtl = 0;
  192.     XFlush (XtDisplay(msg_w));
  193. }
  194.  
  195. /* callback from the close pushbutton */
  196. /* ARGSUSED */
  197. static void
  198. msg_close_cb (w, client, call)
  199. Widget w;
  200. XtPointer client;
  201. XtPointer call;
  202. {
  203.     XtUnmanageChild (msg_w);
  204. }
  205.  
  206. /* add msg to the txt_w widget.
  207.  * Always set the vertical scroll bar to the extreme bottom.
  208.  */
  209. static void
  210. msg_add (msg)
  211. char *msg;
  212. {
  213.     int l;
  214.  
  215.     l = strlen(msg);
  216.     if (l == 0)
  217.         return;
  218.  
  219.     XmTextReplace (txt_w, txtl, txtl, msg);
  220.     txtl += l;
  221.  
  222.     if (msg[l-1] != '\n')
  223.         msg_add ("\n");
  224.     else
  225.         msg_scroll_down();
  226. }
  227.  
  228. /* make sure the text is scrolled to the bottom */
  229. static void
  230. msg_scroll_down()
  231. {
  232.     XmTextSetInsertionPosition (txt_w, txtl);
  233. }
  234.  
  235. /* write msg to stdout. 
  236.  * add newline if one is not already at the end of msg[].
  237.  */
  238. static void
  239. msg_stdout (msg)
  240. char *msg;
  241. {
  242.     int l = strlen(msg);
  243.  
  244.     printf ("%s", msg);
  245.     if (l > 0 && msg[l-1] != '\n')
  246.         (void) putchar ('\n');
  247.     (void) fflush (stdout);
  248. }
  249.  
  250. /* print a message, p, in an app-modal dialog. */
  251. static void
  252. xe_msg_modal (p)
  253. char *p;
  254. {
  255.     static Widget apmsg_w;
  256.     Arg args[20];
  257.     int n;
  258.  
  259.     if (!apmsg_w) {
  260.         XmString button_string;
  261.         XmString title_string;
  262.         Widget w;
  263.  
  264.         button_string = XmStringCreate("Ok", XmSTRING_DEFAULT_CHARSET);
  265.         title_string = XmStringCreate ("xephem Modal Message",
  266.                         XmSTRING_DEFAULT_CHARSET);
  267.  
  268.         /* Create MessageBox dialog. */
  269.         n = 0;
  270.         XtSetArg (args[n], XmNdefaultPosition, False);  n++;
  271.         XtSetArg (args[n], XmNtitle, "xephem Modal Message");  n++;
  272.         XtSetArg (args[n], XmNokLabelString, button_string);  n++;
  273.         XtSetArg (args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++;
  274.         apmsg_w = XmCreateWarningDialog (toplevel_w, "message", args, n);
  275.         XtAddCallback (apmsg_w, XmNmapCallback, prompt_map_cb, NULL);
  276.  
  277.         XmStringFree (title_string);
  278.         XmStringFree (button_string);
  279.  
  280.         w = XmMessageBoxGetChild (apmsg_w, XmDIALOG_CANCEL_BUTTON);
  281.         XtUnmanageChild (w);
  282.         w = XmMessageBoxGetChild (apmsg_w, XmDIALOG_HELP_BUTTON);
  283.         XtUnmanageChild (w);
  284.     }
  285.  
  286.     set_xmstring (apmsg_w, XmNmessageString, p);
  287.  
  288.     /* Display help window. rely on autoUnmanage to bring back down. */
  289.     XtManageChild (apmsg_w);
  290. }
  291.