dialog.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:27k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Xgraph Dialog Boxes
  3.  *
  4.  * This file constructs the hardcopy and error dialog
  5.  * boxes used by xgraph.  It uses the mini-toolbox given
  6.  * in toolbox.c.
  7.  */
  8. #include "copyright.h"
  9. #include "xgout.h"
  10. #include "xgraph.h"
  11. #include "hard_devices.h"
  12. #include "xtb.h"
  13. #include "params.h"
  14. #include <stdio.h>
  15. #include <X11/Xutil.h>
  16. void    do_error();
  17. #define MAXCHBUF 1024
  18. #ifdef SHADOW
  19. #define gray_width 16
  20. #define gray_height 16
  21. static short gray_bits[] =
  22. {
  23.     0x5555, 0xaaaa, 0x5555, 0xaaaa,
  24.     0x5555, 0xaaaa, 0x5555, 0xaaaa,
  25.     0x5555, 0xaaaa, 0x5555, 0xaaaa,
  26.     0x5555, 0xaaaa, 0x5555, 0xaaaa};
  27. #endif
  28. static void make_msg_box();
  29. static void del_msg_box();
  30. #define D_VPAD 2
  31. #define D_HPAD 2
  32. #define D_INT 4
  33. #define D_BRDR 2
  34. #define D_INP 35
  35. #define D_DSP 10
  36. #define D_FS 10
  37. struct d_info {
  38.     char   *prog; /* Program name              */
  39.     xtb_data cookie; /* Info used by do_harcopy   */
  40.     Window  choices; /* Output device choices     */
  41.     Window  fod; /* File or device flag       */
  42.     Window  fodspec; /* File or device spec       */
  43.     Window  docu_p; /* Document predicate        */
  44.     Window  dimspec; /* Maximum dimension spec    */
  45.     Window  tf_family; /* Title font family spec    */
  46.     Window  tf_size; /* Title font size spec      */
  47.     Window  af_family; /* Axis font family spec     */
  48.     Window  af_size; /* Axis font size spec       */
  49. };
  50. #define BACKSPACE 0010
  51. #define DELETE 0177
  52. #define CONTROL_U 0025
  53. #define CONTROL_X 0030
  54. /*ARGSUSED*/
  55. static xtb_hret 
  56. df_fun(win, ch, text, val)
  57. Window  win; /* Widget window   */
  58. int     ch; /* Typed character */
  59. char   *text; /* Copy of text    */
  60. xtb_data val; /* User info       */
  61. /*
  62.  * This is the handler function for the text widget for
  63.  * specifing the file or device name.  It supports simple
  64.  * line editing operations.
  65.  */
  66. {
  67.     if ((ch == BACKSPACE) || (ch == DELETE)) {
  68. if (!xtb_ti_dch(win))
  69.     XBell(disp, 0);
  70.     }
  71.     else if ((ch == CONTROL_U) || (ch == CONTROL_X)) {
  72. (void) xtb_ti_set(win, "", (xtb_data) 0);
  73.     }
  74.     else {
  75. /* Insert if printable - ascii dependent */
  76. if ((ch < ' ') || (ch >= DELETE) || !xtb_ti_ins(win, ch)) {
  77.     XBell(disp, 0);
  78. }
  79.     }
  80.     return XTB_HANDLED;
  81. }
  82. /*ARGSUSED*/
  83. static xtb_hret 
  84. ok_fun(win, bval, info)
  85. Window  win; /* Button window     */
  86. int     bval; /* Button value      */
  87. xtb_data info; /* Local button info */
  88. /*
  89.  * This is the handler function for when the `Ok' button
  90.  * is hit.  It sets the button,  does the hardcopy output,
  91.  * and turns the button off.  It returns a status which
  92.  * deactivates the dialog.
  93.  */
  94. {
  95.     struct d_info *real_info = (struct d_info *) info;
  96.     int     val,
  97.             dev_p,
  98.             doc_p;
  99.     char    file_or_dev[MAXCHBUF],
  100.             dim_spec[MAXCHBUF],
  101.            *dev_spec;
  102.     char    tfam[MAXCHBUF],
  103.             afam[MAXCHBUF];
  104.     char    tsizstr[MAXCHBUF],
  105.             asizstr[MAXCHBUF];
  106.     double  centimeters,
  107.             tsize,
  108.             asize;
  109.     xtb_hret rtn;
  110.     (void) xtb_bt_set(win, 1, (xtb_data) 0, 0);
  111.     val = xtb_br_get(real_info->choices);
  112.     if ((val >= 0) && (val < hard_count)) {
  113. dev_p = xtb_br_get(real_info->fod);
  114. if ((dev_p == 0) || (dev_p == 1)) {
  115.     xtb_ti_get(real_info->fodspec, file_or_dev, (xtb_data *) 0);
  116.     doc_p = xtb_bt_get(real_info->docu_p, (xtb_data *) 0, (int *) 0);
  117.     xtb_ti_get(real_info->dimspec, dim_spec, (xtb_data *) 0);
  118.     if (sscanf(dim_spec, "%lf", &centimeters) == 1) {
  119. xtb_ti_get(real_info->tf_family, tfam, (xtb_data *) 0);
  120. xtb_ti_get(real_info->af_family, afam, (xtb_data *) 0);
  121. xtb_ti_get(real_info->tf_size, tsizstr, (xtb_data *) 0);
  122. if (sscanf(tsizstr, "%lf", &tsize) == 1) {
  123.     xtb_ti_get(real_info->af_size, asizstr, (xtb_data *) 0);
  124.     if (sscanf(asizstr, "%lf", &asize) == 1) {
  125. /* Got all the info */
  126. if (dev_p) {
  127.     dev_spec = (char *) 0;
  128. }
  129. else {
  130.     dev_spec = hard_devices[val].dev_spec;
  131. }
  132. do_hardcopy(real_info->prog, real_info->cookie,
  133.     hard_devices[val].dev_init, dev_spec,
  134.     file_or_dev, centimeters,
  135.     tfam, tsize, afam, asize, doc_p);
  136. rtn = XTB_STOP;
  137.     }
  138.     else {
  139. /* Bad axis size */
  140. do_error("Bad axis font sizen");
  141. rtn = XTB_HANDLED;
  142.     }
  143. }
  144. else {
  145.     /* Bad title size */
  146.     do_error("Bad title font sizen");
  147.     rtn = XTB_HANDLED;
  148. }
  149.     }
  150.     else {
  151. /* Bad max dimension */
  152. do_error("Bad maximum dimensionn");
  153. rtn = XTB_HANDLED;
  154.     }
  155. }
  156. else {
  157.     /* Bad device spec */
  158.     do_error("Must specify `To File' or `To Device'n");
  159.     rtn = XTB_HANDLED;
  160. }
  161.     }
  162.     else {
  163. /* Bad value spec */
  164. do_error("Must specify an output devicen");
  165. rtn = XTB_HANDLED;
  166.     }
  167.     (void) xtb_bt_set(win, 0, (xtb_data) 0, 0);
  168.     return rtn;
  169. }
  170. /*ARGSUSED*/
  171. static xtb_hret 
  172. can_fun(win, val, info)
  173. Window  win; /* Button window     */
  174. int     val; /* Button value      */
  175. xtb_data info; /* Local button info */
  176. /*
  177.  * This is the handler function for the cancel button.  It
  178.  * turns itself on and off and then exits with a status
  179.  * which kills the dialog.
  180.  */
  181. {
  182.     (void) xtb_bt_set(win, 1, (xtb_data) 0, 0);
  183.     (void) xtb_bt_set(win, 0, (xtb_data) 0, 0);
  184.     return XTB_STOP;
  185. }
  186. /*ARGSUSED*/
  187. static xtb_hret 
  188. docu_fun(win, val, info)
  189. Window  win; /* Button window     */
  190. int     val; /* Button value      */
  191. xtb_data info; /* Local button info */
  192. /*
  193.  * This is the handler function for the document button.  It
  194.  * toggles it's state.
  195.  */
  196. {
  197.     int     state;
  198.     state = xtb_bt_get(win, (xtb_data *) 0, (int *) 0);
  199.     xtb_bt_set(win, (state == 0), (xtb_data) 0, 0);
  200.     return XTB_HANDLED;
  201. }
  202. /*ARGSUSED*/
  203. static xtb_hret 
  204. dev_fun(win, old, new, info)
  205. Window  win; /* Button row window */
  206. int     old; /* Previous button   */
  207. int     new; /* Current button    */
  208. xtb_data info; /* User data         */
  209. /*
  210.  * This routine swaps the device specific information
  211.  * in the dialog based on what device is selected.  The
  212.  * information passed is the information for the whole
  213.  * dialog.
  214.  */
  215. {
  216.     struct d_info *data = (struct d_info *) info;
  217.     char    text[MAXCHBUF];
  218.     int     fod_spot,
  219.             inactive;
  220.     fod_spot = xtb_br_get(data->fod);
  221.     if ((old >= 0) && (old < hard_count)) {
  222. /* Save old info */
  223. xtb_ti_get(data->fodspec, text, (xtb_data *) 0);
  224. if (fod_spot == 1) {
  225.     strncpy(hard_devices[old].dev_file, text, MFNAME - 1);
  226. }
  227. else if (fod_spot == 0) {
  228.     strncpy(hard_devices[old].dev_printer, text, MFNAME - 1);
  229. }
  230. if (xtb_bt_get(data->docu_p, (xtb_data *) 0, &inactive)) {
  231.     if (inactive)
  232. hard_devices[old].dev_docu = NONE;
  233.     else
  234. hard_devices[old].dev_docu = YES;
  235. }
  236. else if (inactive)
  237.     hard_devices[old].dev_docu = NONE;
  238. else
  239.     hard_devices[old].dev_docu = NO;
  240. xtb_ti_get(data->dimspec, text, (xtb_data *) 0);
  241. if (sscanf(text, "%lf", &hard_devices[old].dev_max_dim) != 1) {
  242.     do_error("Warning: can't read maximum dimension");
  243. }
  244. xtb_ti_get(data->tf_family, text, (xtb_data *) 0);
  245. strncpy(hard_devices[old].dev_title_font, text, MFNAME - 1);
  246. xtb_ti_get(data->tf_size, text, (xtb_data *) 0);
  247. if (sscanf(text, "%lf", &hard_devices[old].dev_title_size) != 1) {
  248.     do_error("Warning: can't read title font size");
  249. }
  250. xtb_ti_get(data->af_family, text, (xtb_data *) 0);
  251. strncpy(hard_devices[old].dev_axis_font, text, MFNAME - 1);
  252. xtb_ti_get(data->af_size, text, (xtb_data *) 0);
  253. if (sscanf(text, "%lf", &hard_devices[old].dev_axis_size) != 1) {
  254.     do_error("Warning: can't read axis font size");
  255. }
  256.     }
  257.     /* Insert new info */
  258.     if ((new >= 0) && (new < hard_count)) {
  259. if (fod_spot == 1) {
  260.     xtb_ti_set(data->fodspec, hard_devices[new].dev_file, (xtb_data) 0);
  261. }
  262. else if (fod_spot == 0) {
  263.     xtb_ti_set(data->fodspec, hard_devices[new].dev_printer,
  264.        (xtb_data) 0);
  265. }
  266. else {
  267.     xtb_ti_set(data->fodspec, "", (xtb_data) 0);
  268. }
  269. switch (hard_devices[new].dev_docu) {
  270. case NONE:
  271.     (void) xtb_bt_set(data->docu_p, 0, (xtb_data) 0, 1);
  272.     break;
  273. case NO:
  274.     (void) xtb_bt_set(data->docu_p, 0, (xtb_data) 0, 0);
  275.     break;
  276. case YES:
  277.     (void) xtb_bt_set(data->docu_p, 1, (xtb_data) 0, 0);
  278.     break;
  279. }
  280. (void) sprintf(text, "%lg", hard_devices[new].dev_max_dim);
  281. xtb_ti_set(data->dimspec, text, (xtb_data) 0);
  282. xtb_ti_set(data->tf_family, hard_devices[new].dev_title_font,
  283.    (xtb_data) 0);
  284. (void) sprintf(text, "%lg", hard_devices[new].dev_title_size);
  285. xtb_ti_set(data->tf_size, text, (xtb_data) 0);
  286. xtb_ti_set(data->af_family, hard_devices[new].dev_axis_font,
  287.    (xtb_data) 0);
  288. (void) sprintf(text, "%lg", hard_devices[new].dev_axis_size);
  289. xtb_ti_set(data->af_size, text, (xtb_data) 0);
  290.     }
  291.     return XTB_HANDLED;
  292. }
  293. /*ARGSUSED*/
  294. static xtb_hret 
  295. fd_fun(win, old, new, info)
  296. Window  win; /* Button row window */
  297. int     old; /* Previous button   */
  298. int     new; /* Current button    */
  299. xtb_data info; /* User data         */
  300. /*
  301.  * This routine swaps the default file or device names
  302.  * based on the state of the file or device buttons.
  303.  * The information passed is the information for the whole
  304.  * dialog.
  305.  */
  306. {
  307.     struct d_info *data = (struct d_info *) info;
  308.     char    text[MAXCHBUF];
  309.     int     which_one;
  310.     which_one = xtb_br_get(data->choices);
  311.     if ((which_one >= 0) && (which_one < hard_count)) {
  312. if (old == 0) {
  313.     /* Save into device space */
  314.     xtb_ti_get(data->fodspec, text, (xtb_data *) 0);
  315.     strncpy(hard_devices[which_one].dev_printer, text, MFNAME - 1);
  316. }
  317. else if (old == 1) {
  318.     /* Save into file space */
  319.     xtb_ti_get(data->fodspec, text, (xtb_data *) 0);
  320.     which_one = xtb_br_get(data->choices);
  321.     strncpy(hard_devices[which_one].dev_file, text, MFNAME - 1);
  322. }
  323. if (new == 0) {
  324.     /* Restore into device */
  325.     xtb_ti_set(data->fodspec, hard_devices[which_one].dev_printer,
  326.        (xtb_data *) 0);
  327. }
  328. else if (new == 1) {
  329.     xtb_ti_set(data->fodspec, hard_devices[which_one].dev_file,
  330.        (xtb_data *) 0);
  331. }
  332.     }
  333.     return XTB_HANDLED;
  334. }
  335. /* Indices for frames made in make_dialog */
  336. enum d_frames_defn {
  337.     TITLE_F, ODEVLBL_F, ODEVROW_F, DISPLBL_F, DISPROW_F, FDLBL_F,
  338.     FDINP_F, OPTLBL_F, DOCU_F, MDIMLBL_F, MDIMI_F, TFLBL_F, TFFAMLBL_F, TFFAM_F,
  339.     TFSIZLBL_F, TFSIZ_F, AFLBL_F, AFFAMLBL_F, AFFAM_F, AFSIZLBL_F, AFSIZ_F,
  340.     OK_F, CAN_F, BAR_F, LAST_F
  341. }       d_frames;
  342. #define AF(ix) af[(int) (ix)]
  343. #define BAR_SLACK 10
  344. static void 
  345. make_dialog(win, spawned, prog, cookie, okbtn, frame)
  346. Window  win; /* Parent window          */
  347. Window  spawned; /* Spawned from window    */
  348. char   *prog; /* Program name           */
  349. xtb_data cookie; /* Info for do_hardcopy  */
  350. xtb_frame *okbtn; /* Frame for OK button    */
  351. xtb_frame *frame; /* Returned window/size   */
  352. /*
  353.  * This routine constructs a new dialog for asking the user about
  354.  * hardcopy devices.  The dialog and its size is returned in
  355.  * `frame'.  The window of the `ok' button is returned in `btnwin'.
  356.  * This can be used to reset some of the button state to reuse the dialog.
  357.  */
  358. {
  359.     Window  overall;
  360.     xtb_frame AF(LAST_F);
  361.     xtb_fmt *def,
  362.            *cntrl,
  363.            *mindim,
  364.            *tfarea,
  365.            *afarea;
  366.     Cursor  diag_cursor;
  367.     XColor  fg_color,
  368.             bg_color;
  369.     XSizeHints hints;
  370.     unsigned long wamask;
  371.     XSetWindowAttributes wattr;
  372.     struct d_info *info;
  373.     int     i,
  374.             found,
  375.             max_width,
  376.             which_one,
  377.             fodi;
  378.     char  **names;
  379.     static char *fodstrs[] =
  380.     {"To Device", "To File"};
  381.     XFontStruct *bigFont = PM_FONT("TitleFont");
  382.     XFontStruct *medFont = PM_FONT("LabelFont");
  383.     char   *Odevice = PM_STR("Device");
  384.     char   *Odisp = PM_STR("Disposition");
  385.     char   *OfileDev = PM_STR("FileOrDev");
  386.     wamask = CWBackPixel | CWBorderPixel | CWOverrideRedirect |
  387. CWSaveUnder | CWColormap;
  388.     wattr.background_pixel = PM_PIXEL("Background");
  389.     wattr.border_pixel = PM_PIXEL("Border");
  390.     wattr.override_redirect = True;
  391.     wattr.save_under = True;
  392.     wattr.colormap = cmap;
  393.     overall = XCreateWindow(disp, win, 0, 0, 1, 1, D_BRDR,
  394.     depth, InputOutput, vis,
  395.     wamask, &wattr);
  396.     frame->win = overall;
  397.     frame->width = frame->height = frame->x_loc = frame->y_loc = 0;
  398.     XStoreName(disp, overall, "Hardcopy Dialog");
  399.     XSetTransientForHint(disp, spawned, overall);
  400.     info = (struct d_info *) Malloc(sizeof(struct d_info));
  401.     info->prog = prog;
  402.     info->cookie = cookie;
  403.     /* Make all frames */
  404.     xtb_to_new(overall, "Hardcopy Options", bigFont, &AF(TITLE_F));
  405.     xtb_to_new(overall, "Output device:", medFont, &AF(ODEVLBL_F));
  406.     found = -1;
  407.     names = (char **) Malloc((unsigned) (sizeof(char *) * hard_count));
  408.     for (i = 0; i < hard_count; i++) {
  409. names[i] = hard_devices[i].dev_name;
  410. if (strcmp(Odevice, names[i]) == 0) {
  411.     found = i;
  412. }
  413.     }
  414.     xtb_br_new(overall, hard_count, names, found,
  415.        dev_fun, (xtb_data) info, &AF(ODEVROW_F));
  416.     info->choices = AF(ODEVROW_F).win;
  417.     xtb_to_new(overall, "Disposition:", medFont, &AF(DISPLBL_F));
  418.     found = -1;
  419.     for (i = 0; i < 2; i++) {
  420. if (strcmp(Odisp, fodstrs[i]) == 0) {
  421.     found = i;
  422. }
  423.     }
  424.     xtb_br_new(overall, 2, fodstrs, found,
  425.        fd_fun, (xtb_data) info, &AF(DISPROW_F));
  426.     info->fod = AF(DISPROW_F).win;
  427.     xtb_to_new(overall, "File or Device Name:", medFont, &AF(FDLBL_F));
  428.     xtb_ti_new(overall, "", D_INP, df_fun, (xtb_data) 0, &AF(FDINP_F));
  429.     if (OfileDev && strlen(OfileDev)) {
  430. which_one = xtb_br_get(info->choices);
  431. if ((which_one >= 0) && (which_one < hard_count)) {
  432.     fodi = xtb_br_get(info->fod);
  433.     if (fodi == 0) {
  434. strncpy(hard_devices[which_one].dev_printer, OfileDev, MFNAME - 1);
  435.     }
  436.     else if (fodi == 1) {
  437. strncpy(hard_devices[which_one].dev_file, OfileDev, MFNAME - 1);
  438.     }
  439. }
  440.     }
  441.     info->fodspec = AF(FDINP_F).win;
  442.     xtb_to_new(overall, "Optional Parameters", bigFont, &AF(OPTLBL_F));
  443.     xtb_bt_new(overall, "Include in Document", docu_fun, (xtb_data) 0, &AF(DOCU_F));
  444.     info->docu_p = AF(DOCU_F).win;
  445.     xtb_to_new(overall, "Maximum Dimension (cm):", medFont, &AF(MDIMLBL_F));
  446.     xtb_ti_new(overall, "", D_DSP, df_fun, (xtb_data) 0, &AF(MDIMI_F));
  447.     info->dimspec = AF(MDIMI_F).win;
  448.     xtb_to_new(overall, "Title Font", medFont, &AF(TFLBL_F));
  449.     xtb_to_new(overall, "Family:", medFont, &AF(TFFAMLBL_F));
  450.     xtb_ti_new(overall, "", MFNAME, df_fun, (xtb_data) 0, &AF(TFFAM_F));
  451.     info->tf_family = AF(TFFAM_F).win;
  452.     xtb_to_new(overall, "Size (pnts):", medFont, &AF(TFSIZLBL_F));
  453.     xtb_ti_new(overall, "", D_FS, df_fun, (xtb_data) 0, &AF(TFSIZ_F));
  454.     info->tf_size = AF(TFSIZ_F).win;
  455.     xtb_to_new(overall, "Axis Font", medFont, &AF(AFLBL_F));
  456.     xtb_to_new(overall, "Family:", medFont, &AF(AFFAMLBL_F));
  457.     xtb_ti_new(overall, "", MFNAME, df_fun, (xtb_data) 0, &AF(AFFAM_F));
  458.     info->af_family = AF(AFFAM_F).win;
  459.     xtb_to_new(overall, "Size (pnts):", medFont, &AF(AFSIZLBL_F));
  460.     xtb_ti_new(overall, "", D_FS, df_fun, (xtb_data) 0, &AF(AFSIZ_F));
  461.     info->af_size = AF(AFSIZ_F).win;
  462.     xtb_bt_new(overall, "  Ok  ", ok_fun, (xtb_data) info, &AF(OK_F));
  463.     xtb_bt_new(overall, "Cancel", can_fun, (xtb_data) 0, &AF(CAN_F));
  464.     /* Dividing bar */
  465.     max_width = 0;
  466.     for (i = 0; i < ((int) BAR_F); i++) {
  467. if (AF(i).width > max_width)
  468.     max_width = AF(i).width;
  469.     }
  470.     xtb_bk_new(overall, max_width - BAR_SLACK, 1, &AF(BAR_F));
  471.     /* Set device specific info */
  472.     (void) dev_fun(info->choices, -1, xtb_br_get(info->choices), (xtb_data) info);
  473.     (void) fd_fun(info->fod, -1, xtb_br_get(info->fod), (xtb_data) info);
  474.     /*
  475.      * Now place elements - could make this one expression but pcc is too
  476.      * wimpy.
  477.      */
  478.     cntrl = xtb_vert(XTB_LEFT, D_VPAD, D_INT,
  479.      xtb_hort(XTB_CENTER, D_HPAD, D_INT,
  480.       xtb_w(&AF(ODEVLBL_F)),
  481.       xtb_w(&AF(ODEVROW_F)), NE),
  482.      xtb_hort(XTB_CENTER, D_HPAD, D_INT,
  483.       xtb_w(&AF(DISPLBL_F)),
  484.       xtb_w(&AF(DISPROW_F)), NE),
  485.      xtb_hort(XTB_CENTER, D_HPAD, D_INT,
  486.       xtb_w(&AF(FDLBL_F)),
  487.       xtb_w(&AF(FDINP_F)), NE),
  488.      NE);
  489.     mindim = xtb_vert(XTB_LEFT, D_VPAD, D_INT,
  490.       xtb_hort(XTB_CENTER, D_HPAD, D_INT,
  491.        xtb_w(&AF(MDIMLBL_F)),
  492.        xtb_w(&AF(MDIMI_F)),
  493.        NE),
  494.       NE);
  495.     tfarea = xtb_vert(XTB_LEFT, D_VPAD, D_INT,
  496.       xtb_hort(XTB_CENTER, D_HPAD, D_INT,
  497.        xtb_w(&AF(TFFAMLBL_F)),
  498.        xtb_w(&AF(TFFAM_F)),
  499.        xtb_w(&AF(TFSIZLBL_F)),
  500.        xtb_w(&AF(TFSIZ_F)), NE),
  501.       NE);
  502.     afarea = xtb_vert(XTB_LEFT, D_VPAD, D_INT,
  503.       xtb_hort(XTB_CENTER, D_HPAD, D_INT,
  504.        xtb_w(&AF(AFFAMLBL_F)),
  505.        xtb_w(&AF(AFFAM_F)),
  506.        xtb_w(&AF(AFSIZLBL_F)),
  507.        xtb_w(&AF(AFSIZ_F)), NE),
  508.       NE);
  509.     def = xtb_fmt_do
  510. (xtb_vert(XTB_CENTER, D_VPAD, D_INT,
  511.   xtb_w(&AF(TITLE_F)),
  512.   cntrl,
  513.   xtb_w(&AF(BAR_F)),
  514.   xtb_w(&AF(OPTLBL_F)),
  515.   mindim,
  516.   xtb_w(&AF(DOCU_F)),
  517.   xtb_w(&AF(TFLBL_F)),
  518.   tfarea,
  519.   xtb_w(&AF(AFLBL_F)),
  520.   afarea,
  521.   xtb_hort(XTB_CENTER, D_HPAD, D_INT,
  522.    xtb_w(&AF(OK_F)), xtb_w(&AF(CAN_F)), NE),
  523.   NE),
  524.  &frame->width, &frame->height);
  525.     xtb_mv_frames(LAST_F, af);
  526.     xtb_fmt_free(def);
  527.     /* Make window large enough to contain the info */
  528.     XResizeWindow(disp, overall, frame->width, frame->height);
  529.     hints.flags = PSize;
  530.     hints.width = frame->width;
  531.     hints.height = frame->height;
  532.     XSetNormalHints(disp, overall, &hints);
  533.     diag_cursor = XCreateFontCursor(disp, XC_dotbox);
  534.     fg_color.pixel = PM_PIXEL("Foreground");
  535.     XQueryColor(disp, cmap, &fg_color);
  536.     bg_color.pixel = PM_PIXEL("Background");
  537.     XQueryColor(disp, cmap, &bg_color);
  538.     XRecolorCursor(disp, diag_cursor, &fg_color, &bg_color);
  539.     XDefineCursor(disp, overall, diag_cursor);
  540.     frame->width += (2 * D_BRDR);
  541.     frame->height += (2 * D_BRDR);
  542.     *okbtn = AF(OK_F);
  543. }
  544. #ifdef SHADOW
  545. Window 
  546. make_shadow(w, h)
  547. int     w,
  548.         h;
  549. /*
  550.  * Makes a shadow window for a pop-up window of the specified size.
  551.  * Needs hint work as well.  Try no background window.
  552.  */
  553. {
  554.     Window  shadow;
  555.     Bitmap  gray_bm;
  556.     Pixmap  gray_pm;
  557.     gray_bm = XStoreBitmap(gray_width, gray_height, gray_bits);
  558.     gray_pm = XMakePixmap(gray_bm, PM_PIXEL("Foreground"), PM_PIXEL("Background"));
  559.     shadow = XCreateWindow(RootWindow, 0, 0, w, h, 0, BlackPixmap, gray_pm);
  560.     XFreePixmap(gray_pm);
  561.     XFreeBitmap(gray_bm);
  562.     return shadow;
  563. }
  564. #endif
  565. #define SH_W 5
  566. #define SH_H 5
  567. void 
  568. ho_dialog(parent, prog, cookie)
  569. Window  parent; /* Parent window              */
  570. char   *prog; /* Program name               */
  571. xtb_data cookie; /* Info passed to do_hardcopy */
  572. /*
  573.  * Asks the user about hardcopy devices.  A table of hardcopy
  574.  * device names and function pointers to their initialization
  575.  * functions is assumed to be in the global `hard_devices' and
  576.  * `hard_count'.  Returns a non-zero status if the dialog was
  577.  * sucessfully posted.  Calls do_hardcopy in xgraph to actually
  578.  * output information.
  579.  */
  580. {
  581. #ifdef SHADOW
  582.     static Window shadow;
  583. #endif
  584.     static Window dummy;
  585.     static xtb_frame overall =
  586.     {(Window) 0, 0, 0, 0, 0};
  587.     static xtb_frame okbtn;
  588.     XEvent  evt;
  589.     XWindowAttributes winInfo;
  590.     XSizeHints hints;
  591.     struct d_info *info;
  592.     if (!overall.win) {
  593. make_dialog(RootWindow(disp, screen), parent, prog, cookie,
  594.     &okbtn, &overall);
  595. #ifdef SHADOW
  596. shadow = make_shadow(d_w, d_h);
  597. #endif
  598.     }
  599.     else {
  600. /* Change the button information */
  601. (void) xtb_bt_get(okbtn.win, (xtb_data *) & info, (int *) 0);
  602. info->prog = prog;
  603. info->cookie = cookie;
  604.     }
  605.     XGetWindowAttributes(disp, parent, &winInfo);
  606.     XTranslateCoordinates(disp, parent, RootWindow(disp, screen),
  607.   0, 0, &winInfo.x, &winInfo.y, &dummy);
  608.     XMoveWindow(disp, overall.win,
  609. (int) (winInfo.x + winInfo.width / 2 - overall.width / 2),
  610. (int) (winInfo.y + winInfo.height / 2 - overall.height / 2));
  611.     hints.flags = PPosition;
  612.     hints.x = winInfo.x + winInfo.width / 2 - overall.width / 2;
  613.     hints.y = winInfo.y + winInfo.height / 2 - overall.height / 2;
  614.     XSetNormalHints(disp, overall.win, &hints);
  615. #ifdef SHADOW
  616.     XMoveWindow(disp, shadow, winInfo.x + winInfo.width / 2 - d_w / 2 + SH_W,
  617. winInfo.y + winInfo.height / 2 - d_h / 2 + SH_H);
  618.     hints.flags = PPosition;
  619.     hints.x = winInfo.x + winInfo.width / 2 - d_w / 2 + SH_W;
  620.     hints.y = winInfo.y + winInfo.height / 2 - d_h / 2 + SH_H;
  621.     XSetNormalHints(disp, shadow, &hints);
  622.     XRaiseWindow(disp, shadow);
  623.     XMapWindow(disp, shadow);
  624. #endif
  625.     XRaiseWindow(disp, overall.win);
  626.     XMapWindow(disp, overall.win);
  627.     do {
  628. XNextEvent(disp, &evt);
  629.     } while (xtb_dispatch(&evt) != XTB_STOP);
  630.     XUnmapWindow(disp, overall.win);
  631. #ifdef SHADOW
  632.     XUnmapWindow(disp, shadow);
  633. #endif
  634. }
  635. /*ARGSUSED*/
  636. static xtb_hret 
  637. err_func(win, bval, info)
  638. Window  win; /* Button window     */
  639. int     bval; /* Button value      */
  640. xtb_data info; /* Local button info */
  641. /*
  642.  * Handler function for button in error box.  Simply stops dialog.
  643.  */
  644. {
  645.     (void) xtb_bt_set(win, 1, (xtb_data) 0, 0);
  646.     (void) xtb_bt_set(win, 0, (xtb_data) 0, 0);
  647.     return XTB_STOP;
  648. }
  649. struct err_info {
  650.     Window  title;
  651.     Window  contbtn;
  652.     int     num_lines;
  653.     int     alloc_lines;
  654.     Window *lines;
  655. };
  656. #define E_LINES 2
  657. #define E_VPAD 3
  658. #define E_HPAD 3
  659. #define E_INTER 1
  660. #define ML 256
  661. static void 
  662. make_msg_box(text, title, frame)
  663. char   *text; /* Error text    */
  664. char   *title; /* Title text    */
  665. xtb_frame *frame; /* Returned frame */
  666. /*
  667.  * Makes an error box with a title.
  668.  */
  669. {
  670.     XSizeHints hints;
  671.     struct err_info *new_info;
  672.     xtb_frame tf,
  673.             cf,
  674.             lf;
  675.     char   *lineptr,
  676.             line[ML];
  677.     int     y,
  678.             i;
  679.     unsigned long wamask;
  680.     XSetWindowAttributes wattr;
  681.     XFontStruct *bigFont = PM_FONT("TitleFont");
  682.     XFontStruct *medFont = PM_FONT("LabelFont");
  683.     wamask = CWBackPixel | CWBorderPixel | CWOverrideRedirect |
  684. CWSaveUnder | CWColormap;
  685.     wattr.background_pixel = PM_PIXEL("Background");
  686.     wattr.border_pixel = PM_PIXEL("Border");
  687.     wattr.override_redirect = True;
  688.     wattr.save_under = True;
  689.     wattr.colormap = cmap;
  690.     frame->win = XCreateWindow(disp, RootWindow(disp, screen),
  691.        0, 0, 1, 1, D_BRDR,
  692.        depth, InputOutput, vis,
  693.        wamask, &wattr);
  694.     frame->x_loc = frame->y_loc = frame->width = frame->height = 0;
  695.     XStoreName(disp, frame->win, "Error Dialog");
  696.     XSetTransientForHint(disp, RootWindow(disp, screen), frame->win);
  697.     new_info = (struct err_info *) Malloc((unsigned) sizeof(struct err_info));
  698.     xtb_to_new(frame->win, title, bigFont, &tf);
  699.     new_info->title = tf.win;
  700.     if (tf.width > frame->width)
  701. frame->width = tf.width;
  702.     xtb_bt_new(frame->win, "Dismiss", err_func, (xtb_data) 0, &cf);
  703.     new_info->contbtn = cf.win;
  704.     if (cf.width > frame->width)
  705. frame->width = cf.width;
  706.     new_info->alloc_lines = E_LINES;
  707.     new_info->num_lines = 0;
  708.     new_info->lines = (Window *) Malloc((unsigned) (sizeof(Window) * E_LINES));
  709.     /* zero the memory out of paranoia */
  710.     memset(new_info->lines, 0, sizeof(Window) * E_LINES);
  711.     lineptr = text;
  712.     while (getline(&lineptr, line)) {
  713. if (new_info->num_lines >= new_info->alloc_lines) {
  714.     int old_alloc_lines_size = new_info->alloc_lines * sizeof(Window);
  715.     new_info->alloc_lines *= 2;
  716.     new_info->lines = (Window *) Realloc((char *) new_info->lines,
  717.  (unsigned)
  718.  (new_info->alloc_lines *
  719.   sizeof(Window)));
  720.             memset(((char*)new_info->lines) + old_alloc_lines_size,
  721.    0, old_alloc_lines_size);
  722. }
  723. xtb_to_new(frame->win, line, medFont, &lf);
  724. new_info->lines[new_info->num_lines] = lf.win;
  725. new_info->num_lines += 1;
  726. if (lf.width > frame->width)
  727.     frame->width = lf.width;
  728.     }
  729.     /* Placement */
  730.     frame->width += (2 * E_HPAD);
  731.     y = E_VPAD;
  732.     /* Title */
  733.     XMoveWindow(disp, new_info->title, (int) (frame->width / 2 - tf.width / 2), y);
  734.     y += (tf.height + E_INTER);
  735.     /* All lines */
  736.     for (i = 0; i < new_info->num_lines; i++) {
  737. XMoveWindow(disp, new_info->lines[i], E_HPAD, y);
  738. y += (lf.height + E_INTER);
  739.     }
  740.     /* Button */
  741.     XMoveWindow(disp, new_info->contbtn, (int) (frame->width / 2 - cf.width / 2), y);
  742.     y += (cf.height + E_INTER);
  743.     /* Make dialog the right size */
  744.     y += (E_VPAD - E_INTER);
  745.     XResizeWindow(disp, frame->win, frame->width, (unsigned int) y);
  746.     hints.flags = PSize;
  747.     hints.width = frame->width;
  748.     hints.height = (unsigned int) y;
  749.     XSetNormalHints(disp, frame->win, &hints);
  750.     frame->width += (2 * D_BRDR);
  751.     frame->height = y + (2 * D_BRDR);
  752.     xtb_register(frame->win, (xtb_hret(*) ()) 0, (xtb_data) new_info);
  753. }
  754. void 
  755. msg_box(title, text)
  756. char   *title,
  757.        *text;
  758. /*
  759.  * This posts a dialog that contains lines of text and a continue
  760.  * button.  The text may be multiple lines.  The dialog is remade
  761.  * each time.
  762.  */
  763. {
  764. #ifdef SHADOW
  765.     Window  shadow;
  766. #endif
  767.     XWindowAttributes info;
  768.     XEvent  evt;
  769.     XSizeHints hints;
  770.     xtb_frame text_frame;
  771.     make_msg_box(text, title, &text_frame);
  772. #ifdef SHADOW
  773.     shadow = make_shadow(w, h);
  774. #endif
  775.     XGetWindowAttributes(disp, RootWindow(disp, screen), &info);
  776.     XMoveWindow(disp, text_frame.win, (int) (info.width / 2 - text_frame.width / 2),
  777. (int) (info.height / 2 - text_frame.height / 2));
  778.     hints.flags = PPosition;
  779.     hints.x = info.width / 2 - text_frame.width / 2;
  780.     hints.y = info.height / 2 - text_frame.height / 2;
  781.     XSetNormalHints(disp, text_frame.win, &hints);
  782. #ifdef SHADOW
  783.     XMoveWindow(disp, shadow, info.width / 2 - w / 2 + SH_W,
  784. info.height / 2 - h / 2 + SH_H);
  785.     hints.flags = PPosition;
  786.     hints.x = info.width / 2 - w / 2 + SH_W;
  787.     hints.y = info.height / 2 - h / 2 + SH_H;
  788.     XSetNormalHints(disp, text_frame.win, &hints);
  789.     XRaiseWindow(disp, shadow);
  790.     XMapWindow(disp, shadow);
  791. #endif
  792.     XRaiseWindow(disp, text_frame.win);
  793.     XMapWindow(disp, text_frame.win);
  794.     do {
  795. XNextEvent(disp, &evt);
  796.     } while (xtb_dispatch(&evt) != XTB_STOP);
  797. #ifdef SHADOW
  798.     XDestroyWindow(disp, shadow);
  799. #endif
  800.     del_msg_box(text_frame.win);
  801. }
  802. void 
  803. do_error(err_text)
  804. char   *err_text;
  805. {
  806.     if (PM_INT("Output Device") == D_XWINDOWS)
  807. msg_box("Xgraph Error", err_text);
  808.     else
  809. fputs(err_text, stderr);
  810. }
  811. int 
  812. getline(tptr, lptr)
  813. char  **tptr;
  814. char   *lptr;
  815. /*
  816.  * Returns next line from tptr.  Assumes `lptr' is large enough to
  817.  * accept the line.
  818.  */
  819. {
  820.     char   *start;
  821.     start = *tptr;
  822.     while (*tptr && **tptr && (**tptr != 'n')) {
  823. (*tptr)++;
  824.     }
  825.     if (*tptr > start) {
  826. (void) strncpy(lptr, start, (*tptr - start));
  827. lptr[*tptr - start] = '';
  828. if (**tptr == 'n')
  829.     (*tptr)++;
  830. return 1;
  831.     }
  832.     else {
  833. return 0;
  834.     }
  835. }
  836. static void 
  837. del_msg_box(msg)
  838. Window  msg;
  839. /*
  840.  * Deletes all components of an msg box
  841.  */
  842. {
  843.     struct err_info *info;
  844.     char   *dummy;
  845.     int     i;
  846.     if (xtb_unregister(msg, (xtb_data *) & info)) {
  847. xtb_to_del(info->title);
  848. xtb_bt_del(info->contbtn, (xtb_data *) & dummy);
  849. for (i = 0; i < info->num_lines; i++) {
  850.     xtb_to_del(info->lines[i]);
  851. }
  852. Free((char *) info->lines);
  853. Free((char *) info);
  854. XDestroyWindow(disp, msg);
  855.     }
  856. }