home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / xfig / part23 / w_indpanel.c
Encoding:
C/C++ Source or Header  |  1993-05-27  |  57.5 KB  |  2,100 lines

  1. /*
  2.  * FIG : Facility for Interactive Generation of figures
  3.  * Copyright (c) 1991 by Paul King
  4.  *
  5.  * "Permission to use, copy, modify, distribute, and sell this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both the copyright
  8.  * notice and this permission notice appear in supporting documentation. 
  9.  * No representations are made about the suitability of this software for 
  10.  * any purpose.  It is provided "as is" without express or implied warranty."
  11.  */
  12.  
  13. #include "fig.h"
  14. #include "figx.h"
  15. #include "resources.h"
  16. #include "object.h"
  17. #include "mode.h"
  18. #include "paintop.h"
  19. #include "u_fonts.h"
  20. #include "w_drawprim.h"
  21. #include "w_icons.h"
  22. #include "w_indpanel.h"
  23. #include "w_mousefun.h"
  24. #include "w_setup.h"
  25. #include "w_util.h"
  26. #include "w_zoom.h"
  27.  
  28. extern Pixmap    psfont_menu_bitmaps[], latexfont_menu_bitmaps[];
  29. extern Atom    wm_delete_window;
  30. extern struct    _fstruct ps_fontinfo[], latex_fontinfo[];
  31. extern char    *panel_get_value();
  32. extern int    show_zoom();
  33. extern int    show_depth();
  34. extern int    cur_updatemask;
  35. extern Widget    make_popup_menu();
  36.  
  37. /**************        local variables and routines   **************/
  38.  
  39. static int    cur_anglegeom = L_UNCONSTRAINED;
  40. static int    cur_indmask = I_MIN1;
  41. static int    cur_flagshown = 0;
  42. #define MAX_FLAGS 2 /* maximum value for cur_flagshown */
  43.  
  44. static String    set_translations = 
  45.     "<Key>Return: SetValue()";
  46. static void    nval_panel_set();
  47. static XtActionsRec set_actions[] =
  48. {
  49.     {"SetValue", (XtActionProc) nval_panel_set},
  50. };
  51. static String   nval_translations =
  52.         "<Message>WM_PROTOCOLS: QuitNval()\n";
  53. static void    nval_panel_cancel();
  54. static XtActionsRec     nval_actions[] =
  55. {
  56.     {"QuitNval", (XtActionProc) nval_panel_cancel},
  57. };
  58. static String   choice_translations =
  59.         "<Message>WM_PROTOCOLS: QuitChoice()\n";
  60. static void     choice_panel_cancel();
  61. static XtActionsRec     choice_actions[] =
  62. {
  63.     {"QuitChoice", (XtActionProc) choice_panel_cancel},
  64. };
  65.  
  66. DeclareStaticArgs(15);
  67.  
  68. /* declarations for choice buttons */
  69. static int    inc_choice(), dec_choice();
  70. static int    show_valign(), show_halign(), show_textjust();
  71. static int    show_arrowmode(), show_linestyle(), show_anglegeom();
  72. static int    show_pointposn(), show_gridmode(), show_linkmode();
  73.  
  74. /* declarations for value buttons */
  75. static int    show_linewidth(), inc_linewidth(), dec_linewidth();
  76. static int    show_boxradius(), inc_boxradius(), dec_boxradius();
  77. static int    show_fillstyle(), darken_fill(), lighten_fill();
  78. static int    show_color(), next_color(), prev_color();
  79. static int    show_font(), inc_font(), dec_font();
  80. static int    show_flags(), inc_flags(), dec_flags();
  81. static int    show_fontsize(), inc_fontsize(), dec_fontsize();
  82. static int    show_textstep(), inc_textstep(), dec_textstep();
  83. static int    inc_zoom(), dec_zoom();
  84. static int    show_rotnangle(), inc_rotnangle(), dec_rotnangle();
  85. static int    show_elltextangle(), inc_elltextangle(), dec_elltextangle();
  86. static int    show_numsides(), inc_numsides(), dec_numsides();
  87. static int    inc_depth(), dec_depth();
  88.  
  89. static int    popup_fonts();
  90. static void    note_state();
  91.  
  92. static char    indbuf[12];
  93. static float    old_zoomscale = -1.0;
  94. static int    old_rotnangle = -1;
  95. static float    old_elltextangle = -1.0;
  96.  
  97. #define        DEF_IND_SW_HT        32
  98. #define        DEF_IND_SW_WD        64
  99. #define        FONT_IND_SW_WD        (40+PS_FONTPANE_WD)
  100. #define        NARROW_IND_SW_WD    56
  101. #define        WIDE_IND_SW_WD        76
  102. #define        XWIDE_IND_SW_WD        86
  103.  
  104. /* indicator switch definitions */
  105.  
  106. static choice_info anglegeom_choices[] = {
  107.     {L_UNCONSTRAINED, &unconstrained_ic,},
  108.     {L_LATEXLINE, &latexline_ic,},
  109.     {L_LATEXARROW, &latexarrow_ic,},
  110.     {L_MOUNTHATTAN, &mounthattan_ic,},
  111.     {L_MANHATTAN, &manhattan_ic,},
  112.     {L_MOUNTAIN, &mountain_ic,},
  113. };
  114.  
  115. #define NUM_ANGLEGEOM_CHOICES (sizeof(anglegeom_choices)/sizeof(choice_info))
  116.  
  117. static choice_info valign_choices[] = {
  118.     {NONE, &none_ic,},
  119.     {TOP, &valignt_ic,},
  120.     {CENTER, &valignc_ic,},
  121.     {BOTTOM, &valignb_ic,},
  122. };
  123.  
  124. #define NUM_VALIGN_CHOICES (sizeof(valign_choices)/sizeof(choice_info))
  125.  
  126. static choice_info halign_choices[] = {
  127.     {NONE, &none_ic,},
  128.     {LEFT, &halignl_ic,},
  129.     {CENTER, &halignc_ic,},
  130.     {RIGHT, &halignr_ic,},
  131. };
  132.  
  133. #define NUM_HALIGN_CHOICES (sizeof(halign_choices)/sizeof(choice_info))
  134.  
  135. static choice_info gridmode_choices[] = {
  136.     {GRID_0, &none_ic,},
  137.     {GRID_1, &grid1_ic,},
  138.     {GRID_2, &grid2_ic,},
  139. };
  140.  
  141. #define NUM_GRIDMODE_CHOICES (sizeof(gridmode_choices)/sizeof(choice_info))
  142.  
  143. static choice_info pointposn_choices[] = {
  144.     {P_ANY, &any_ic,},
  145.     {P_MAGNET, &fine_grid_ic,},
  146.     {P_GRID1, &grid1_ic,},
  147.     {P_GRID2, &grid2_ic,},
  148. };
  149.  
  150. #define NUM_POINTPOSN_CHOICES (sizeof(pointposn_choices)/sizeof(choice_info))
  151.  
  152. static choice_info arrowmode_choices[] = {
  153.     {L_NOARROWS, &noarrows_ic,},
  154.     {L_FARROWS, &farrows_ic,},
  155.     {L_FBARROWS, &fbarrows_ic,},
  156.     {L_BARROWS, &barrows_ic,},
  157. };
  158.  
  159. #define NUM_ARROWMODE_CHOICES (sizeof(arrowmode_choices)/sizeof(choice_info))
  160.  
  161. static choice_info textjust_choices[] = {
  162.     {T_LEFT_JUSTIFIED, &textL_ic,},
  163.     {T_CENTER_JUSTIFIED, &textC_ic,},
  164.     {T_RIGHT_JUSTIFIED, &textR_ic,},
  165. };
  166.  
  167. #define NUM_TEXTJUST_CHOICES (sizeof(textjust_choices)/sizeof(choice_info))
  168.  
  169. static choice_info linestyle_choices[] = {
  170.     {SOLID_LINE, &solidline_ic,},
  171.     {DASH_LINE, &dashline_ic,},
  172.     {DOTTED_LINE, &dottedline_ic,},
  173. };
  174.  
  175. #define NUM_LINESTYLE_CHOICES (sizeof(linestyle_choices)/sizeof(choice_info))
  176.  
  177. static choice_info linkmode_choices[] = {
  178.     {SMART_OFF, &smartoff_ic,},
  179.     {SMART_MOVE, &smartmove_ic,},
  180.     {SMART_SLIDE, &smartslide_ic,},
  181. };
  182.  
  183. #define NUM_LINKMODE_CHOICES (sizeof(linkmode_choices)/sizeof(choice_info))
  184.  
  185. choice_info    fillstyle_choices[NUMFILLPATS + 1];
  186.  
  187. choice_info    color_choices[NUMCOLORS + 1];
  188. static ind_sw_info *fill_style_sw;
  189.  
  190. #define I_CHOICE    0
  191. #define I_IVAL        1
  192. #define I_FVAL        2
  193.  
  194. #define        inc_action(z)    (z->inc_func)(z)
  195. #define        dec_action(z)    (z->dec_func)(z)
  196. #define        show_action(z)    (z->show_func)(z)
  197.  
  198. ind_sw_info    ind_switches[] = {
  199.     {I_FVAL, I_ZOOM, "Zoom", "Scale", NARROW_IND_SW_WD,
  200.     NULL, &zoomscale, inc_zoom, dec_zoom, show_zoom,},
  201.     {I_CHOICE, I_GRIDMODE, "Grid", "Mode", DEF_IND_SW_WD,
  202.     &cur_gridmode, NULL, inc_choice, dec_choice, show_gridmode,
  203.     gridmode_choices, NUM_GRIDMODE_CHOICES, NUM_GRIDMODE_CHOICES,},
  204.     {I_CHOICE, I_POINTPOSN, "Point", "Posn", DEF_IND_SW_WD,
  205.     &cur_pointposn, NULL, inc_choice, dec_choice, show_pointposn,
  206.     pointposn_choices, NUM_POINTPOSN_CHOICES, NUM_POINTPOSN_CHOICES,},
  207.     {I_IVAL, I_DEPTH, "Depth", "", NARROW_IND_SW_WD,
  208.     &cur_depth, NULL, inc_depth, dec_depth, show_depth,},
  209.     {I_IVAL, I_ROTNANGLE, "Rotn", "Angle", NARROW_IND_SW_WD,
  210.     &cur_rotnangle, NULL, inc_rotnangle, dec_rotnangle, show_rotnangle,},
  211.     {I_IVAL, I_NUMSIDES, "Num", "Sides", NARROW_IND_SW_WD,
  212.     &cur_numsides, NULL, inc_numsides, dec_numsides, show_numsides,},
  213.     {I_CHOICE, I_VALIGN, "Vert", "Align", DEF_IND_SW_WD,
  214.     &cur_valign, NULL, inc_choice, dec_choice, show_valign,
  215.     valign_choices, NUM_VALIGN_CHOICES, NUM_VALIGN_CHOICES,},
  216.     {I_CHOICE, I_HALIGN, "Horiz", "Align", DEF_IND_SW_WD,
  217.     &cur_halign, NULL, inc_choice, dec_choice, show_halign,
  218.     halign_choices, NUM_HALIGN_CHOICES, NUM_HALIGN_CHOICES,},
  219.     {I_CHOICE, I_ANGLEGEOM, "Angle", "Geom", DEF_IND_SW_WD,
  220.     &cur_anglegeom, NULL, inc_choice, dec_choice, show_anglegeom,
  221.     anglegeom_choices, NUM_ANGLEGEOM_CHOICES, NUM_ANGLEGEOM_CHOICES / 2,},
  222.     {I_CHOICE, I_FILLSTYLE, "Fill", "Style", DEF_IND_SW_WD,
  223.     &cur_fillstyle, NULL, darken_fill, lighten_fill, show_fillstyle,
  224.     fillstyle_choices, NUMFILLPATS + 1, (NUMFILLPATS + 1) / 2},
  225.     {I_CHOICE, I_COLOR, "Color", "", WIDE_IND_SW_WD,
  226.     (int *) &cur_color, NULL, next_color, prev_color, show_color,
  227.     color_choices, NUMCOLORS + 1, (NUMCOLORS + 1) / 2},
  228.     {I_CHOICE, I_LINKMODE, "Smart", "Links", DEF_IND_SW_WD,
  229.     &cur_linkmode, NULL, inc_choice, dec_choice, show_linkmode,
  230.     linkmode_choices, NUM_LINKMODE_CHOICES, NUM_LINKMODE_CHOICES},
  231.     {I_IVAL, I_LINEWIDTH, "Line", "Width", NARROW_IND_SW_WD,
  232.     &cur_linewidth, NULL, inc_linewidth, dec_linewidth, show_linewidth,},
  233.     {I_CHOICE, I_LINESTYLE, "Line", "Style", DEF_IND_SW_WD,
  234.     &cur_linestyle, NULL, inc_choice, dec_choice, show_linestyle,
  235.     linestyle_choices, NUM_LINESTYLE_CHOICES, NUM_LINESTYLE_CHOICES,},
  236.     {I_IVAL, I_BOXRADIUS, "Box", "Curve", DEF_IND_SW_WD,
  237.     &cur_boxradius, NULL, inc_boxradius, dec_boxradius, show_boxradius,},
  238.     {I_CHOICE, I_ARROWMODE, "Arrow", "Mode", DEF_IND_SW_WD,
  239.     &cur_arrowmode, NULL, inc_choice, dec_choice, show_arrowmode,
  240.     arrowmode_choices, NUM_ARROWMODE_CHOICES, NUM_ARROWMODE_CHOICES,},
  241.     {I_CHOICE, I_TEXTJUST, "Text", "Just", DEF_IND_SW_WD,
  242.     &cur_textjust, NULL, inc_choice, dec_choice, show_textjust,
  243.     textjust_choices, NUM_TEXTJUST_CHOICES, NUM_TEXTJUST_CHOICES,},
  244.     {I_FVAL, I_ELLTEXTANGLE, "Text/Ellipse", "Angle", XWIDE_IND_SW_WD,
  245.     NULL, &cur_elltextangle, inc_elltextangle, dec_elltextangle, 
  246.     show_elltextangle,},
  247.     {I_IVAL, I_TEXTFLAGS, "Text Flags", "", WIDE_IND_SW_WD,
  248.     &cur_fontsize, NULL, inc_flags, dec_flags, show_flags,},
  249.     {I_IVAL, I_FONTSIZE, "Text", "Size", NARROW_IND_SW_WD,
  250.     &cur_fontsize, NULL, inc_fontsize, dec_fontsize, show_fontsize,},
  251.     {I_FVAL, I_TEXTSTEP, "Text", "Step", NARROW_IND_SW_WD,
  252.     NULL, &cur_textstep, inc_textstep, dec_textstep, show_textstep,},
  253.     {I_IVAL, I_FONT, "Text", "Font", FONT_IND_SW_WD,
  254.     &cur_ps_font, NULL, inc_font, dec_font, show_font,},
  255. };
  256.  
  257. #define        NUM_IND_SW    (sizeof(ind_switches) / sizeof(ind_sw_info))
  258.  
  259. static Arg    button_args[] =
  260. {
  261.      /* 0 */ {XtNlabel, (XtArgVal) "        "},
  262.      /* 1 */ {XtNwidth, (XtArgVal) 0},
  263.      /* 2 */ {XtNheight, (XtArgVal) 0},
  264.      /* 3 */ {XtNresizable, (XtArgVal) False},
  265.      /* 4 */ {XtNborderWidth, (XtArgVal) 0},
  266.      /* 5 */ {XtNresize, (XtArgVal) False},    /* keeps buttons from being
  267.                          * resized when there are not
  268.                          * a multiple of three of
  269.                          * them */
  270.      /* 6 */ {XtNbackgroundPixmap, (XtArgVal) NULL},
  271. };
  272.  
  273. /* button selection event handler */
  274. static void    sel_ind_but();
  275.  
  276. /* arguments for the update indicator boxes in the indicator buttons */
  277.  
  278. static Arg    upd_args[] = 
  279. {
  280.     /* 0 */ {XtNwidth, (XtArgVal) 8},
  281.     /* 1 */ {XtNheight, (XtArgVal) 8},
  282.     /* 2 */ {XtNborderWidth, (XtArgVal) 1},
  283.     /* 3 */ {XtNtop, XtChainTop},
  284.     /* 4 */ {XtNright, XtChainRight},
  285.     /* 5 */ {XtNstate, (XtArgVal) True},
  286.     /* 6 */ {XtNvertDistance, (XtArgVal) 0},
  287.     /* 7 */ {XtNhorizDistance, (XtArgVal) 0},
  288.     /* 8 */ {XtNlabel, (XtArgVal) " "},
  289.     /* 9 */ {XtNhighlightThickness, (XtArgVal) 0},
  290. };
  291.  
  292. static XtActionsRec ind_actions[] =
  293. {
  294.     {"EnterIndSw", (XtActionProc) draw_mousefun_ind},
  295.     {"LeaveIndSw", (XtActionProc) clear_mousefun},
  296. };
  297.  
  298. static String    ind_translations =
  299. "<EnterWindow>:EnterIndSw()highlight()\n\
  300.     <LeaveWindow>:LeaveIndSw()unhighlight()\n";
  301.  
  302. init_ind_panel(tool)
  303.     TOOL        tool;
  304. {
  305.     int        i;
  306.     ind_sw_info    *sw;
  307.  
  308.     /* does he want to always see ALL of the indicator buttons? */
  309.     if (appres.ShowAllButtons) {
  310.     cur_indmask = I_ALL;    /* yes */
  311.     i = 2*DEF_IND_SW_HT+2*INTERNAL_BW+6;  /* two rows high when showing all buttons */
  312.     } else {
  313.     i = DEF_IND_SW_HT+4*INTERNAL_BW+14;   /* allow for thickness of scrollbar */
  314.     }
  315.  
  316.     /* make a scrollable viewport in case all the buttons don't fit */
  317.     FirstArg(XtNallowHoriz, True);
  318.     NextArg(XtNwidth, INDPANEL_WD);
  319.     NextArg(XtNheight, i);
  320.     NextArg(XtNborderWidth, 0);
  321.     NextArg(XtNresizable, False);
  322.     NextArg(XtNfromVert, canvas_sw);
  323.     NextArg(XtNvertDistance, -INTERNAL_BW);
  324.     NextArg(XtNtop, XtChainBottom);
  325.     NextArg(XtNbottom, XtChainBottom);
  326.     NextArg(XtNleft, XtChainLeft);
  327.     NextArg(XtNright, XtChainRight);
  328.     NextArg(XtNuseBottom, True);
  329.  
  330.     ind_viewp = XtCreateWidget("ind_viewport", viewportWidgetClass, tool,
  331.             Args, ArgCount);
  332.  
  333.     FirstArg(XtNwidth, INDPANEL_WD);
  334.     NextArg(XtNheight, i);
  335.     NextArg(XtNhSpace, 0);
  336.     NextArg(XtNvSpace, 0);
  337.     NextArg(XtNresizable, True);
  338.     NextArg(XtNborderWidth, 0);
  339.     if (appres.ShowAllButtons) {
  340.     NextArg(XtNorientation, XtorientVertical);    /* use two rows */
  341.     } else {
  342.     NextArg(XtNorientation, XtorientHorizontal);    /* expand horizontally */
  343.     }
  344.  
  345.     ind_panel = XtCreateManagedWidget("ind_panel", boxWidgetClass, ind_viewp,
  346.                    Args, ArgCount);
  347.  
  348.     /* start with all components affected by update */
  349.     cur_updatemask = I_UPDATEMASK;
  350.  
  351.     XtAppAddActions(tool_app, ind_actions, XtNumber(ind_actions));
  352.  
  353.     for (i = 0; i < NUM_IND_SW; ++i) {
  354.     sw = &ind_switches[i];
  355.  
  356.     FirstArg(XtNwidth, sw->sw_width);
  357.     NextArg(XtNheight, DEF_IND_SW_HT);
  358.     NextArg(XtNdefaultDistance, 0);
  359.     NextArg(XtNborderWidth, INTERNAL_BW);
  360.     sw->formw = XtCreateWidget("button_form", formWidgetClass,
  361.                  ind_panel, Args, ArgCount);
  362.  
  363.     /* make an update button in the upper-right corner of the main button */
  364.     if (sw->func & I_UPDATEMASK)
  365.         {
  366.         upd_args[7].value = sw->sw_width
  367.                     - upd_args[0].value
  368.                     - 2*upd_args[2].value;
  369.         sw->updbut = XtCreateWidget("update", toggleWidgetClass,
  370.                  sw->formw, upd_args, XtNumber(upd_args));
  371.         sw->update = True;
  372.         XtAddEventHandler(sw->updbut, ButtonReleaseMask, (Boolean) 0,
  373.                  note_state, (XtPointer) sw);
  374.         }
  375.  
  376.     /* now create the command button */
  377.     button_args[1].value = sw->sw_width;
  378.     button_args[2].value = DEF_IND_SW_HT;
  379.     sw->button = XtCreateManagedWidget("button", commandWidgetClass,
  380.                  sw->formw, button_args, XtNumber(button_args));
  381.     /* map this button if it is needed */
  382.     if (sw->func & cur_indmask)
  383.         XtManageChild(sw->formw);
  384.  
  385.     /* allow left & right buttons */
  386.     /* (callbacks pass same data for ANY button) */
  387.     XtAddEventHandler(sw->button, ButtonReleaseMask, (Boolean) 0,
  388.               sel_ind_but, (XtPointer) sw);
  389.     XtOverrideTranslations(sw->button,
  390.                    XtParseTranslationTable(ind_translations));
  391.     }
  392.     update_indpanel(cur_indmask);
  393. }
  394.  
  395. static void
  396. note_state(w, closure, ev, continue_to_dispatch)
  397.     Widget        w;
  398.     XtPointer        closure;
  399.     XEvent         *ev;
  400.     Boolean        *continue_to_dispatch;
  401.  
  402. {
  403.     ind_sw_info *sw = (ind_sw_info *) closure;
  404.     XButtonEvent *event = &ev->xbutton;
  405.  
  406.     if (event->button != Button1)
  407.     return;
  408.  
  409.     /* toggle update status of this indicator */
  410.     sw->update = !sw->update;
  411.     if (sw->update)
  412.     cur_updatemask |= sw->func;    /* turn on update status */
  413.     else
  414.     cur_updatemask &= ~sw->func;    /* turn off update status */
  415. }
  416.  
  417. manage_update_buts()
  418. {
  419.     int            i;
  420.     for (i = 0; i < NUM_IND_SW; ++i)
  421.     if (ind_switches[i].func & I_UPDATEMASK)
  422.         XtManageChild(ind_switches[i].updbut);
  423. }
  424.         
  425. unmanage_update_buts()
  426. {
  427.     int            i;
  428.     for (i = 0; i < NUM_IND_SW; ++i)
  429.     if (ind_switches[i].func & I_UPDATEMASK)
  430.         XtUnmanageChild(ind_switches[i].updbut);
  431. }
  432.         
  433. setup_ind_panel()
  434. {
  435.     int            i;
  436.     ind_sw_info       *isw;
  437.     Display       *d = tool_d;
  438.     Screen       *s = tool_s;
  439.     Pixmap        p;
  440.  
  441.     /* get the foreground and background from the indicator widget */
  442.     /* and create a gc with those values */
  443.     ind_button_gc = XCreateGC(tool_d, XtWindow(ind_panel), (unsigned long) 0, NULL);
  444.     FirstArg(XtNforeground, &ind_but_fg);
  445.     NextArg(XtNbackground, &ind_but_bg);
  446.     GetValues(ind_switches[0].button);
  447.     XSetBackground(tool_d, ind_button_gc, ind_but_bg);
  448.     XSetForeground(tool_d, ind_button_gc, ind_but_fg);
  449.     XSetFont(tool_d, ind_button_gc, button_font->fid);
  450.  
  451.     /* also create gc with fore=background for blanking areas */
  452.     ind_blank_gc = XCreateGC(tool_d, XtWindow(ind_panel), (unsigned long) 0, NULL);
  453.     XSetBackground(tool_d, ind_blank_gc, ind_but_bg);
  454.     XSetForeground(tool_d, ind_blank_gc, ind_but_bg);
  455.  
  456.     /* create a gc for the color 'palette' */
  457.     color_gc = XCreateGC(tool_d, XtWindow(ind_panel), (unsigned long) 0, NULL);
  458.  
  459.     /* initialize the fill style gc and pixmaps */
  460.     init_fill_pm();
  461.     init_fill_gc();
  462.  
  463.     FirstArg(XtNbackgroundPixmap, fillstyle_choices[NUMFILLPATS].blackPM);
  464.     SetValues(ind_viewp);
  465.  
  466.     for (i = 0; i < NUM_IND_SW; ++i) {
  467.     isw = &ind_switches[i];
  468.     if (ind_switches[i].func == I_FILLSTYLE)
  469.         fill_style_sw = isw;
  470.  
  471.     p = XCreatePixmap(d, XtWindow(isw->button), isw->sw_width,
  472.               DEF_IND_SW_HT, DefaultDepthOfScreen(s));
  473.     XFillRectangle(d, p, ind_blank_gc, 0, 0,
  474.                isw->sw_width, DEF_IND_SW_HT);
  475.     XDrawImageString(d, p, ind_button_gc, 3, 12, isw->line1, strlen(isw->line1));
  476.     XDrawImageString(d, p, ind_button_gc, 3, 25, isw->line2, strlen(isw->line2));
  477.  
  478.     isw->normalPM = button_args[6].value = (XtArgVal) p;
  479.     XtSetValues(isw->button, &button_args[6], 1);
  480.     XtInstallAllAccelerators(isw->button, tool);
  481.     }
  482.     XtInstallAllAccelerators(ind_panel, tool);
  483.  
  484.     XDefineCursor(d, XtWindow(ind_panel), arrow_cursor);
  485.     update_current_settings();
  486.  
  487.     FirstArg(XtNmappedWhenManaged, True);
  488.     SetValues(ind_panel);
  489. }
  490.  
  491. update_indpanel(mask)
  492.     int            mask;
  493. {
  494.     register int    i;
  495.     register ind_sw_info *isw;
  496.  
  497.     /* only update current mask if user wants to see relevant ind buttons */
  498.     if (appres.ShowAllButtons)
  499.     return;
  500.  
  501.     cur_indmask = mask;
  502.     XtUnmanageChild(ind_panel);
  503.     for (isw = ind_switches, i = 0; i < NUM_IND_SW; isw++, i++) {
  504.     if (isw->func & cur_indmask) {
  505.         XtManageChild(isw->formw);
  506.     } else {
  507.         XtUnmanageChild(isw->formw);
  508.     }
  509.     }
  510.     XtManageChild(ind_panel);
  511. }
  512.  
  513. /* come here when a button is pressed in the indicator panel */
  514.  
  515. static void
  516. sel_ind_but(widget, closure, event, continue_to_dispatch)
  517.     Widget        widget;
  518.     XtPointer        closure;
  519.     XEvent*        event;
  520.     Boolean*        continue_to_dispatch;
  521. {
  522.     XButtonEvent xbutton;
  523.     ind_sw_info *isw = (ind_sw_info *) closure;
  524.     xbutton = event->xbutton;
  525.     if ((xbutton.button == Button2)  ||
  526.               (xbutton.button == Button3 && xbutton.state & Mod1Mask)) { /* middle button */
  527.     dec_action(isw);
  528.     } else if (xbutton.button == Button3) {    /* right button */
  529.     inc_action(isw);
  530.     } else {            /* left button */
  531.     if (isw->func == I_FONT)
  532.         popup_fonts(isw);
  533.     else if (isw->func == I_TEXTFLAGS)
  534.         popup_flags_panel(isw);
  535.     else if (isw->type == I_IVAL || isw->type == I_FVAL)
  536.         popup_nval_panel(isw);
  537.     else if (isw->type == I_CHOICE)
  538.         popup_choice_panel(isw);
  539.     }
  540. }
  541.  
  542. static
  543. update_string_pixmap(isw, buf, xpos, ypos)
  544.     ind_sw_info       *isw;
  545.     char       *buf;
  546.     int            xpos, ypos;
  547. {
  548.     XDrawImageString(tool_d, isw->normalPM, ind_button_gc,
  549.              xpos, ypos, buf, strlen(buf));
  550.     /*
  551.      * Fool the toolkit by changing the background pixmap to 0 then giving it
  552.      * the modified one again.    Otherwise, it sees that the pixmap ID is not
  553.      * changed and doesn't actually draw it into the widget window
  554.      */
  555.     button_args[6].value = 0;
  556.     XtSetValues(isw->button, &button_args[6], 1);
  557.  
  558.     /* put the pixmap in the widget background */
  559.     button_args[6].value = isw->normalPM;
  560.     XtSetValues(isw->button, &button_args[6], 1);
  561. }
  562.  
  563. static
  564. update_choice_pixmap(isw, mode)
  565.     ind_sw_info       *isw;
  566.     int            mode;
  567. {
  568.     choice_info       *tmp_choice;
  569.     register Pixmap p;
  570.  
  571.     /* put the pixmap in the widget background */
  572.     p = isw->normalPM;
  573.     tmp_choice = isw->choices + mode;
  574.     XPutImage(tool_d, p, ind_button_gc, tmp_choice->icon, 0, 0, 32, 0, 32, 32);
  575.     /*
  576.      * Fool the toolkit by changing the background pixmap to 0 then giving it
  577.      * the modified one again.    Otherwise, it sees that the pixmap ID is not
  578.      * changed and doesn't actually draw it into the widget window
  579.      */
  580.     button_args[6].value = 0;
  581.     XtSetValues(isw->button, &button_args[6], 1);
  582.     button_args[6].value = p;
  583.     XtSetValues(isw->button, &button_args[6], 1);
  584. }
  585.  
  586. /********************************************************
  587.  
  588.     auxiliary functions
  589.  
  590. ********************************************************/
  591.  
  592. static Widget    choice_popup;
  593. static ind_sw_info *choice_i;
  594. static Widget    nval_popup, form, cancel, set, beside, below, newvalue,
  595.         label;
  596. static Widget    dash_length, dot_gap;
  597. static ind_sw_info *nval_i;
  598.  
  599. /* handle choice settings */
  600.  
  601. static void
  602. choice_panel_dismiss()
  603. {
  604.     XtDestroyWidget(choice_popup);
  605.     XtSetSensitive(choice_i->button, True);
  606. }
  607.  
  608. static void
  609. choice_panel_cancel(w, ev)
  610.     Widget        w;
  611.     XButtonEvent   *ev;
  612. {
  613.     choice_panel_dismiss();
  614. }
  615.  
  616. static void
  617. choice_panel_set(w, sel_choice, ev)
  618.     Widget        w;
  619.     choice_info       *sel_choice;
  620.     XButtonEvent   *ev;
  621. {
  622.     (*choice_i->i_varadr) = sel_choice->value;
  623.     show_action(choice_i);
  624.  
  625.     /* auxiliary info */
  626.     switch (choice_i->func) {
  627.     case I_LINESTYLE:
  628.     /* dash length */
  629.     cur_dashlength = (float) atof(panel_get_value(dash_length));
  630.     if (cur_dashlength <= 0.0)
  631.         cur_dashlength = DEF_DASHLENGTH;
  632.     /* dot gap */
  633.     cur_dotgap = (float) atof(panel_get_value(dot_gap));
  634.     if (cur_dotgap <= 0.0)
  635.         cur_dotgap = DEF_DOTGAP;
  636.     break;
  637.     }
  638.  
  639.     choice_panel_dismiss();
  640. }
  641.  
  642. popup_choice_panel(isw)
  643.     ind_sw_info       *isw;
  644. {
  645.     Position        x_val, y_val;
  646.     Dimension        width, height;
  647.     char        buf[32];
  648.     choice_info       *tmp_choice;
  649.     Pixmap        p;
  650.     Pixel        form_fg;
  651.     register int    i;
  652.     static int      actions_added=0;
  653.  
  654.     choice_i = isw;
  655.     XtSetSensitive(choice_i->button, False);
  656.  
  657.     FirstArg(XtNwidth, &width);
  658.     NextArg(XtNheight, &height);
  659.     GetValues(tool);
  660.     /* position the popup 1/3 in from left and 2/3 down from top */
  661.     XtTranslateCoords(tool, (Position) (width / 3), (Position) (2 * height / 3),
  662.               &x_val, &y_val);
  663.  
  664.     FirstArg(XtNx, x_val);
  665.     NextArg(XtNy, y_val);
  666.     NextArg(XtNresize, False);
  667.     NextArg(XtNresizable, False);
  668.     NextArg(XtNtitle, "Xfig: Set indicator panel");
  669.  
  670.     choice_popup = XtCreatePopupShell("xfig_set_indicator_panel",
  671.                       transientShellWidgetClass, tool,
  672.                       Args, ArgCount);
  673.     XtOverrideTranslations(choice_popup,
  674.                        XtParseTranslationTable(choice_translations));
  675.     if (!actions_added) {
  676.         XtAppAddActions(tool_app, choice_actions, XtNumber(choice_actions));
  677.     actions_added = 1;
  678.     }
  679.  
  680.     form = XtCreateManagedWidget("form", formWidgetClass, choice_popup, NULL, 0);
  681.  
  682.     FirstArg(XtNborderWidth, 0);
  683.     sprintf(buf, "%s %s", isw->line1, isw->line2);
  684.     label = XtCreateManagedWidget(buf, labelWidgetClass, form, Args, ArgCount);
  685.  
  686.     FirstArg(XtNlabel, "cancel");
  687.     NextArg(XtNfromVert, label);
  688.     NextArg(XtNresize, False);
  689.     NextArg(XtNresizable, False);
  690.     NextArg(XtNheight, 32);
  691.     NextArg(XtNborderWidth, INTERNAL_BW);
  692.     cancel = XtCreateManagedWidget("cancel", commandWidgetClass,
  693.                    form, Args, ArgCount);
  694.     XtAddEventHandler(cancel, ButtonReleaseMask, (Boolean) 0,
  695.               (XtEventHandler)choice_panel_cancel, (XtPointer) NULL);
  696.  
  697.     tmp_choice = isw->choices;
  698.  
  699.     for (i = 0; i < isw->numchoices; tmp_choice++, i++) {
  700.     if (isw->func == I_FILLSTYLE)
  701.         p = ((cur_color==BLACK || cur_color==DEFAULT_COLOR ||
  702.          (!all_colors_available && cur_color!=WHITE))?
  703.         fillstyle_choices[i].blackPM :fillstyle_choices[i].normalPM);
  704.     else if (isw->func == I_COLOR) {
  705.         p = 0;
  706.         tmp_choice->value = (i >= NUMCOLORS ? DEFAULT_COLOR : i);
  707.     } else
  708.         p = XCreatePixmapFromBitmapData(tool_d, XtWindow(ind_panel),
  709.                 (char *) tmp_choice->icon->data, tmp_choice->icon->width,
  710.                tmp_choice->icon->height, ind_but_fg, ind_but_bg,
  711.                         DefaultDepthOfScreen(tool_s));
  712.     if (i % isw->sw_per_row == 0) {
  713.         if (i == 0)
  714.         below = label;
  715.         else
  716.         below = beside;
  717.         beside = cancel;
  718.     }
  719.     FirstArg(XtNfromVert, below);
  720.     NextArg(XtNfromHoriz, beside);
  721.     if (isw->func != I_COLOR) {
  722.         NextArg(XtNbackgroundPixmap, p);
  723.         NextArg(XtNwidth, tmp_choice->icon->width);
  724.         NextArg(XtNheight, tmp_choice->icon->height);
  725.     } else {        /* Color popup menu */
  726.         NextArg(XtNheight, 32);
  727.         NextArg(XtNwidth, 64);
  728.         if (i < NUMCOLORS && i >= 0) {    /* it's a proper color */
  729.         if (all_colors_available) {
  730.             XColor        col;
  731.  
  732.             col.pixel = appres.color[i];
  733.             XQueryColor(tool_d, DefaultColormapOfScreen(tool_s), &col);
  734.             if ((0.3 * col.red + 0.59 * col.green + 0.11 * col.blue) < 0.5 * (255 << 8))
  735.             form_fg = appres.color[WHITE];
  736.             else
  737.             form_fg = appres.color[BLACK];
  738.             NextArg(XtNforeground, form_fg);
  739.             NextArg(XtNbackground, appres.color[i]);
  740.         }
  741.         NextArg(XtNlabel, colorNames[i + 1]);
  742.         } else {        /* it's the default color */
  743.         NextArg(XtNforeground, x_fg_color.pixel);
  744.         NextArg(XtNlabel, colorNames[0]);
  745.         }
  746.     }
  747.     NextArg(XtNresize, False);
  748.     NextArg(XtNresizable, False);
  749.     NextArg(XtNborderWidth, INTERNAL_BW);
  750.     beside = XtCreateManagedWidget(" ", commandWidgetClass,
  751.                        form, Args, ArgCount);
  752.     XtAddEventHandler(beside, ButtonReleaseMask, (Boolean) 0,
  753.               (XtEventHandler)choice_panel_set, (XtPointer) tmp_choice);
  754.     }
  755.  
  756.     /* auxiliary info */
  757.     switch (isw->func) {
  758.     case I_LINESTYLE:
  759.     /* dash length */
  760.     FirstArg(XtNfromVert, beside);
  761.     NextArg(XtNborderWidth, 0);
  762.     NextArg(XtNlabel, "Default dash length =");
  763.     label = XtCreateManagedWidget("default_dash_length",
  764.                     labelWidgetClass, form, Args, ArgCount);
  765.     sprintf(buf, "%1.1f", cur_dashlength);
  766.     FirstArg(XtNfromVert, beside);
  767.     NextArg(XtNborderWidth, INTERNAL_BW);
  768.     NextArg(XtNfromHoriz, label);
  769.     NextArg(XtNstring, buf);
  770.     NextArg(XtNinsertPosition, strlen(buf));
  771.     NextArg(XtNeditType, "append");
  772.     NextArg(XtNwidth, 40);
  773.     dash_length = XtCreateManagedWidget(buf, asciiTextWidgetClass,
  774.                         form, Args, ArgCount);
  775.     /* dot gap */
  776.     FirstArg(XtNfromVert, dash_length);
  777.     NextArg(XtNborderWidth, 0);
  778.     NextArg(XtNlabel, "    Default dot gap =");
  779.     label = XtCreateManagedWidget("default_dot_gap",
  780.                     labelWidgetClass, form, Args, ArgCount);
  781.     sprintf(buf, "%1.1f", cur_dotgap);
  782.     FirstArg(XtNfromVert, dash_length);
  783.     NextArg(XtNborderWidth, INTERNAL_BW);
  784.     NextArg(XtNfromHoriz, label);
  785.     NextArg(XtNstring, buf);
  786.     NextArg(XtNinsertPosition, strlen(buf));
  787.     NextArg(XtNeditType, "append");
  788.     NextArg(XtNwidth, 40);
  789.     dot_gap = XtCreateManagedWidget(buf, asciiTextWidgetClass,
  790.                     form, Args, ArgCount);
  791.     break;
  792.     }
  793.  
  794.     XtPopup(choice_popup, XtGrabExclusive);
  795.     (void) XSetWMProtocols(XtDisplay(choice_popup), XtWindow(choice_popup),
  796.                            &wm_delete_window, 1);
  797.  
  798. }
  799.  
  800. /* handle text flag settings */
  801.  
  802. static int      hidden_text_flag, special_text_flag, rigid_text_flag;
  803. static Widget   hidden_text_panel, rigid_text_panel, special_text_panel;
  804. static Widget   hidden_text_menu, special_text_menu, rigid_text_menu;
  805.  
  806. static void
  807. flags_panel_dismiss()
  808. {
  809.     XtDestroyWidget(nval_popup);
  810.     XtSetSensitive(nval_i->button, True);
  811. }
  812.  
  813. static void
  814. flags_panel_cancel(w, ev)
  815.     Widget        w;
  816.     XButtonEvent   *ev;
  817. {
  818.     flags_panel_dismiss();
  819. }
  820.  
  821. static void
  822. flags_panel_set(w, ev)
  823.     Widget        w;
  824.     XButtonEvent   *ev;
  825. {
  826.     int            new_i_value;
  827.     float        new_f_value;
  828.  
  829.     if (hidden_text_flag)
  830.     cur_textflags |= HIDDEN_TEXT;
  831.     else
  832.     cur_textflags &= ~HIDDEN_TEXT;
  833.     if (special_text_flag)
  834.     cur_textflags |= SPECIAL_TEXT;
  835.     else
  836.     cur_textflags &= ~SPECIAL_TEXT;
  837.     if (rigid_text_flag)
  838.     cur_textflags |= RIGID_TEXT;
  839.     else
  840.     cur_textflags &= ~RIGID_TEXT;
  841.     flags_panel_dismiss();
  842.     show_action(nval_i);
  843. }
  844.  
  845. static void
  846. hidden_text_select(w, new_hidden_text, garbage)
  847.     Widget          w;
  848.     XtPointer       new_hidden_text, garbage;
  849. {
  850.     FirstArg(XtNlabel, XtName(w));
  851.     SetValues(hidden_text_panel);
  852.     hidden_text_flag = (int) new_hidden_text;
  853.     if (hidden_text_flag)
  854.     put_msg("Text will be displayed as hidden");
  855.     else
  856.     put_msg("Text will be displayed normally");
  857. }
  858.  
  859. static void
  860. rigid_text_select(w, new_rigid_text, garbage)
  861.     Widget          w;
  862.     XtPointer       new_rigid_text, garbage;
  863. {
  864.     FirstArg(XtNlabel, XtName(w));
  865.     SetValues(rigid_text_panel);
  866.     rigid_text_flag = (int) new_rigid_text;
  867.     if (rigid_text_flag)
  868.     put_msg("Text in compound group will not scale with compound");
  869.     else
  870.     put_msg("Text in compound group will scale with compound");
  871. }
  872.  
  873. static void
  874. special_text_select(w, new_special_text, garbage)
  875.     Widget          w;
  876.     XtPointer       new_special_text, garbage;
  877. {
  878.     FirstArg(XtNlabel, XtName(w));
  879.     SetValues(special_text_panel);
  880.     special_text_flag = (int) new_special_text;
  881.     if (special_text_flag)
  882.     put_msg("Text will be printed as special during print/export");
  883.     else
  884.     put_msg("Text will be printed as normal during print/export");
  885. }
  886.  
  887. popup_flags_panel(isw)
  888.     ind_sw_info       *isw;
  889. {
  890.     Position        x_val, y_val;
  891.     Dimension        width, height;
  892.     char        buf[32];
  893.     static int      actions_added=0;
  894.     static char    *hidden_text_items[] = {
  895.     "Normal ", "Hidden "};
  896.     static char    *rigid_text_items[] = {
  897.     "Normal ", "Rigid  "};
  898.     static char    *special_text_items[] = {
  899.     "Normal ", "Special"};
  900.  
  901.     nval_i = isw;
  902.     XtSetSensitive(nval_i->button, False);
  903.     rigid_text_flag = (cur_textflags & RIGID_TEXT) ? 1 : 0;
  904.     special_text_flag = (cur_textflags & SPECIAL_TEXT) ? 1 : 0;
  905.     hidden_text_flag = (cur_textflags & HIDDEN_TEXT) ? 1 : 0;
  906.  
  907.     FirstArg(XtNwidth, &width);
  908.     NextArg(XtNheight, &height);
  909.     GetValues(tool);
  910.     /* position the popup 1/3 in from left and 2/3 down from top */
  911.     XtTranslateCoords(tool, (Position) (width / 3), (Position) (2 * height / 3),
  912.               &x_val, &y_val);
  913.  
  914.     FirstArg(XtNx, x_val);
  915.     NextArg(XtNy, y_val);
  916.     NextArg(XtNwidth, 240);
  917.  
  918.     nval_popup = XtCreatePopupShell("xfig_set_indicator_panel",
  919.                     transientShellWidgetClass, tool,
  920.                     Args, ArgCount);
  921.     XtOverrideTranslations(nval_popup,
  922.                        XtParseTranslationTable(nval_translations));
  923.     if (!actions_added) {
  924.         XtAppAddActions(tool_app, nval_actions, XtNumber(nval_actions));
  925.     actions_added = 1;
  926.     }
  927.  
  928.     form = XtCreateManagedWidget("form", formWidgetClass, nval_popup, NULL, 0);
  929.  
  930.     FirstArg(XtNborderWidth, 0);
  931.     sprintf(buf, "%s %s", isw->line1, isw->line2);
  932.     label = XtCreateManagedWidget(buf, labelWidgetClass, form, Args, ArgCount);
  933.  
  934.     /* make hidden text menu */
  935.  
  936.     FirstArg(XtNfromVert, label);
  937.     NextArg(XtNborderWidth, 0);
  938.     beside = XtCreateManagedWidget(" Hidden Flag     =", labelWidgetClass,
  939.                                    form, Args, ArgCount);
  940.  
  941.     FirstArg(XtNfromVert, label);
  942.     NextArg(XtNfromHoriz, beside);
  943.     hidden_text_panel = XtCreateManagedWidget(
  944.                  hidden_text_items[hidden_text_flag], menuButtonWidgetClass,
  945.                                               form, Args, ArgCount);
  946.     below = hidden_text_panel;
  947.     hidden_text_menu = make_popup_menu(hidden_text_items,
  948.                                        XtNumber(hidden_text_items),
  949.                                      hidden_text_panel, hidden_text_select);
  950.  
  951.     /* make rigid text menu */
  952.  
  953.     FirstArg(XtNfromVert, below);
  954.     NextArg(XtNborderWidth, 0);
  955.     beside = XtCreateManagedWidget(" Rigid Flag      =", labelWidgetClass,
  956.                                    form, Args, ArgCount);
  957.  
  958.     FirstArg(XtNfromVert, below);
  959.     NextArg(XtNfromHoriz, beside);
  960.     rigid_text_panel = XtCreateManagedWidget(
  961.                    rigid_text_items[rigid_text_flag], menuButtonWidgetClass,
  962.                                              form, Args, ArgCount);
  963.     below = rigid_text_panel;
  964.     rigid_text_menu = make_popup_menu(rigid_text_items,
  965.                                       XtNumber(rigid_text_items),
  966.                                       rigid_text_panel, rigid_text_select);
  967.  
  968.     /* make special text menu */
  969.  
  970.     FirstArg(XtNfromVert, below);
  971.     NextArg(XtNborderWidth, 0);
  972.     beside = XtCreateManagedWidget(" Special Flag    =", labelWidgetClass,
  973.                                    form, Args, ArgCount);
  974.  
  975.     FirstArg(XtNfromVert, below);
  976.     NextArg(XtNfromHoriz, beside);
  977.     special_text_panel = XtCreateManagedWidget(
  978.                                       special_text_items[special_text_flag],
  979.                                menuButtonWidgetClass, form, Args, ArgCount);
  980.     below = special_text_panel;
  981.     special_text_menu = make_popup_menu(special_text_items,
  982.                                         XtNumber(special_text_items),
  983.                                    special_text_panel, special_text_select);
  984.  
  985.     FirstArg(XtNlabel, "cancel");
  986.     NextArg(XtNfromVert, below);
  987.     NextArg(XtNborderWidth, INTERNAL_BW);
  988.     cancel = XtCreateManagedWidget("cancel", commandWidgetClass,
  989.                    form, Args, ArgCount);
  990.     XtAddEventHandler(cancel, ButtonReleaseMask, (Boolean) 0,
  991.               (XtEventHandler)flags_panel_cancel, (XtPointer) NULL);
  992.  
  993.     FirstArg(XtNlabel, "set");
  994.     NextArg(XtNfromVert, below);
  995.     NextArg(XtNfromHoriz, cancel);
  996.     NextArg(XtNborderWidth, INTERNAL_BW);
  997.     set = XtCreateManagedWidget("set", commandWidgetClass,
  998.                 form, Args, ArgCount);
  999.     XtAddEventHandler(set, ButtonReleaseMask, (Boolean) 0,
  1000.               (XtEventHandler)flags_panel_set, (XtPointer) NULL);
  1001.  
  1002.     XtPopup(nval_popup, XtGrabExclusive);
  1003.     (void) XSetWMProtocols(XtDisplay(nval_popup), XtWindow(nval_popup),
  1004.                            &wm_delete_window, 1);
  1005. }
  1006.  
  1007. /* handle integer and floating point settings */
  1008.  
  1009. static void
  1010. nval_panel_dismiss()
  1011. {
  1012.     XtDestroyWidget(nval_popup);
  1013.     XtSetSensitive(nval_i->button, True);
  1014. }
  1015.  
  1016. static void
  1017. nval_panel_cancel(w, ev)
  1018.     Widget        w;
  1019.     XButtonEvent   *ev;
  1020. {
  1021.     nval_panel_dismiss();
  1022. }
  1023.  
  1024. static void
  1025. nval_panel_set(w, ev)
  1026.     Widget        w;
  1027.     XButtonEvent   *ev;
  1028. {
  1029.     int            new_i_value;
  1030.     float        new_f_value;
  1031.  
  1032.  
  1033.     if (nval_i->type == I_IVAL)
  1034.         {
  1035.         new_i_value = atoi(panel_get_value(newvalue));
  1036.         (*nval_i->i_varadr) = new_i_value;
  1037.         }
  1038.     else
  1039.         {
  1040.         new_f_value = atof(panel_get_value(newvalue));
  1041.         (*nval_i->f_varadr) = new_f_value;
  1042.         }
  1043.     nval_panel_dismiss();
  1044.     show_action(nval_i);
  1045. }
  1046.  
  1047. popup_nval_panel(isw)
  1048.     ind_sw_info       *isw;
  1049. {
  1050.     Position        x_val, y_val;
  1051.     Dimension        width, height;
  1052.     char        buf[32];
  1053.     static int      actions_added=0;
  1054.  
  1055.     nval_i = isw;
  1056.     XtSetSensitive(nval_i->button, False);
  1057.  
  1058.     FirstArg(XtNwidth, &width);
  1059.     NextArg(XtNheight, &height);
  1060.     GetValues(tool);
  1061.     /* position the popup 1/3 in from left and 2/3 down from top */
  1062.     XtTranslateCoords(tool, (Position) (width / 3), (Position) (2 * height / 3),
  1063.               &x_val, &y_val);
  1064.  
  1065.     FirstArg(XtNx, x_val);
  1066.     NextArg(XtNy, y_val);
  1067.     NextArg(XtNwidth, 240);
  1068.  
  1069.     nval_popup = XtCreatePopupShell("xfig_set_indicator_panel",
  1070.                     transientShellWidgetClass, tool,
  1071.                     Args, ArgCount);
  1072.     XtOverrideTranslations(nval_popup,
  1073.                        XtParseTranslationTable(nval_translations));
  1074.     if (!actions_added) {
  1075.         XtAppAddActions(tool_app, nval_actions, XtNumber(nval_actions));
  1076.     actions_added = 1;
  1077.     }
  1078.  
  1079.     form = XtCreateManagedWidget("form", formWidgetClass, nval_popup, NULL, 0);
  1080.  
  1081.     FirstArg(XtNborderWidth, 0);
  1082.     sprintf(buf, "%s %s", isw->line1, isw->line2);
  1083.     label = XtCreateManagedWidget(buf, labelWidgetClass, form, Args, ArgCount);
  1084.  
  1085.     FirstArg(XtNfromVert, label);
  1086.     NextArg(XtNborderWidth, 0);
  1087.     NextArg(XtNlabel, "Value =");
  1088.     newvalue = XtCreateManagedWidget("value", labelWidgetClass,
  1089.                      form, Args, ArgCount);
  1090.     /* int or float? */
  1091.     if (isw->type == I_IVAL)
  1092.         sprintf(buf, "%d", (*isw->i_varadr));
  1093.     else
  1094.         sprintf(buf, "%4.2lf", (*isw->f_varadr));
  1095.     FirstArg(XtNfromVert, label);
  1096.     NextArg(XtNborderWidth, INTERNAL_BW);
  1097.     NextArg(XtNfromHoriz, newvalue);
  1098.     NextArg(XtNstring, buf);
  1099.     NextArg(XtNinsertPosition, strlen(buf));
  1100.     NextArg(XtNeditType, "append");
  1101.     NextArg(XtNwidth, 40);
  1102.     newvalue = XtCreateManagedWidget(buf, asciiTextWidgetClass,
  1103.                      form, Args, ArgCount);
  1104.  
  1105.     /* add translation and action to set value on carriage return */
  1106.     XtAppAddActions(tool_app, set_actions, XtNumber(set_actions));
  1107.     XtOverrideTranslations(newvalue, XtParseTranslationTable(set_translations));
  1108.  
  1109.     FirstArg(XtNlabel, "cancel");
  1110.     NextArg(XtNfromVert, newvalue);
  1111.     NextArg(XtNborderWidth, INTERNAL_BW);
  1112.     cancel = XtCreateManagedWidget("cancel", commandWidgetClass,
  1113.                    form, Args, ArgCount);
  1114.     XtAddEventHandler(cancel, ButtonReleaseMask, (Boolean) 0,
  1115.               (XtEventHandler)nval_panel_cancel, (XtPointer) NULL);
  1116.  
  1117.     FirstArg(XtNlabel, "set");
  1118.     NextArg(XtNfromVert, newvalue);
  1119.     NextArg(XtNfromHoriz, cancel);
  1120.     NextArg(XtNborderWidth, INTERNAL_BW);
  1121.     set = XtCreateManagedWidget("set", commandWidgetClass,
  1122.                 form, Args, ArgCount);
  1123.     XtAddEventHandler(set, ButtonReleaseMask, (Boolean) 0,
  1124.               (XtEventHandler)nval_panel_set, (XtPointer) NULL);
  1125.  
  1126.     XtPopup(nval_popup, XtGrabExclusive);
  1127.     (void) XSetWMProtocols(XtDisplay(nval_popup), XtWindow(nval_popup),
  1128.                            &wm_delete_window, 1);
  1129. }
  1130.  
  1131. /********************************************************
  1132.  
  1133.     commands to change indicator settings
  1134.  
  1135. ********************************************************/
  1136.  
  1137. update_current_settings()
  1138. {
  1139.     int            i;
  1140.     ind_sw_info       *isw;
  1141.  
  1142.     for (i = 0; i < NUM_IND_SW; ++i) {
  1143.     isw = &ind_switches[i];
  1144.     show_action(isw);
  1145.     }
  1146. }
  1147.  
  1148. static
  1149. dec_choice(sw)
  1150.     ind_sw_info       *sw;
  1151. {
  1152.     if (--(*sw->i_varadr) < 0)
  1153.     (*sw->i_varadr) = sw->numchoices - 1;
  1154.     show_action(sw);
  1155. }
  1156.  
  1157. static
  1158. inc_choice(sw)
  1159.     ind_sw_info       *sw;
  1160. {
  1161.     if (++(*sw->i_varadr) > sw->numchoices - 1)
  1162.     (*sw->i_varadr) = 0;
  1163.     show_action(sw);
  1164. }
  1165.  
  1166. /* ARROW MODE         */
  1167.  
  1168. static
  1169. show_arrowmode(sw)
  1170.     ind_sw_info       *sw;
  1171. {
  1172.     update_choice_pixmap(sw, cur_arrowmode);
  1173.     switch (cur_arrowmode) {
  1174.     case L_NOARROWS:
  1175.     autobackwardarrow_mode = 0;
  1176.     autoforwardarrow_mode = 0;
  1177.     put_msg("NO ARROWS");
  1178.     break;
  1179.     case L_FARROWS:
  1180.     autobackwardarrow_mode = 0;
  1181.     autoforwardarrow_mode = 1;
  1182.     put_msg("Auto FORWARD ARROWS (for ARC, POLYLINE and SPLINE)");
  1183.     break;
  1184.     case L_FBARROWS:
  1185.     autobackwardarrow_mode = 1;
  1186.     autoforwardarrow_mode = 1;
  1187.     put_msg("Auto FORWARD and BACKWARD ARROWS (for ARC, POLYLINE and SPLINE)");
  1188.     break;
  1189.     case L_BARROWS:
  1190.     autobackwardarrow_mode = 1;
  1191.     autoforwardarrow_mode = 0;
  1192.     put_msg("Auto BACKWARD ARROWS (for ARC, POLYLINE and SPLINE)");
  1193.     break;
  1194.     }
  1195. }
  1196.  
  1197. /* LINE WIDTH         */
  1198.  
  1199. #define MAXLINEWIDTH 200
  1200.  
  1201. static
  1202. dec_linewidth(sw)
  1203.     ind_sw_info       *sw;
  1204. {
  1205.     --cur_linewidth;
  1206.     show_linewidth(sw);
  1207. }
  1208.  
  1209. static
  1210. inc_linewidth(sw)
  1211.     ind_sw_info       *sw;
  1212. {
  1213.     ++cur_linewidth;
  1214.     show_linewidth(sw);
  1215. }
  1216.  
  1217. static
  1218. show_linewidth(sw)
  1219.     ind_sw_info       *sw;
  1220. {
  1221.     if (cur_linewidth > MAXLINEWIDTH)
  1222.     cur_linewidth = MAXLINEWIDTH;
  1223.     else if (cur_linewidth < 0)
  1224.     cur_linewidth = 0;
  1225.  
  1226.     /* erase by drawing wide, inverted (white) line */
  1227.     pw_vector(sw->normalPM, DEF_IND_SW_WD / 2 + 2, DEF_IND_SW_HT / 2,
  1228.           sw->sw_width - 2, DEF_IND_SW_HT / 2, ERASE,
  1229.           DEF_IND_SW_HT, PANEL_LINE, 0.0, DEFAULT_COLOR);
  1230.     /* draw current line thickness into pixmap */
  1231.     if (cur_linewidth > 0)    /* don't draw line for zero-thickness */
  1232.     pw_vector(sw->normalPM, DEF_IND_SW_WD / 2 + 2, DEF_IND_SW_HT / 2,
  1233.           sw->sw_width - 2, DEF_IND_SW_HT / 2, PAINT,
  1234.           cur_linewidth, PANEL_LINE, 0.0, DEFAULT_COLOR);
  1235.  
  1236.     /*
  1237.      * Fool the toolkit by changing the background pixmap to 0 then giving it
  1238.      * the modified one again.    Otherwise, it sees that the pixmap ID is not
  1239.      * changed and doesn't actually draw it into the widget window
  1240.      */
  1241.     button_args[6].value = 0;
  1242.     XtSetValues(sw->button, &button_args[6], 1);
  1243.     /* put the pixmap in the widget background */
  1244.     button_args[6].value = (XtArgVal) sw->normalPM;
  1245.     XtSetValues(sw->button, &button_args[6], 1);
  1246.     put_msg("LINE Thickness = %d", cur_linewidth);
  1247. }
  1248.  
  1249. /* ANGLE GEOMETRY         */
  1250.  
  1251. static
  1252. show_anglegeom(sw)
  1253.     ind_sw_info       *sw;
  1254. {
  1255.     update_choice_pixmap(sw, cur_anglegeom);
  1256.     switch (cur_anglegeom) {
  1257.     case L_UNCONSTRAINED:
  1258.     manhattan_mode = 0;
  1259.     mountain_mode = 0;
  1260.     latexline_mode = 0;
  1261.     latexarrow_mode = 0;
  1262.     put_msg("UNCONSTRAINED geometry (for POLYLINE and SPLINE)");
  1263.     break;
  1264.     case L_MOUNTHATTAN:
  1265.     mountain_mode = 1;
  1266.     manhattan_mode = 1;
  1267.     latexline_mode = 0;
  1268.     latexarrow_mode = 0;
  1269.     put_msg("MOUNT-HATTAN geometry (for POLYLINE and SPLINE)");
  1270.     break;
  1271.     case L_MANHATTAN:
  1272.     manhattan_mode = 1;
  1273.     mountain_mode = 0;
  1274.     latexline_mode = 0;
  1275.     latexarrow_mode = 0;
  1276.     put_msg("MANHATTAN geometry (for POLYLINE and SPLINE)");
  1277.     break;
  1278.     case L_MOUNTAIN:
  1279.     mountain_mode = 1;
  1280.     manhattan_mode = 0;
  1281.     latexline_mode = 0;
  1282.     latexarrow_mode = 0;
  1283.     put_msg("MOUNTAIN geometry (for POLYLINE and SPLINE)");
  1284.     break;
  1285.     case L_LATEXLINE:
  1286.     latexline_mode = 1;
  1287.     manhattan_mode = 0;
  1288.     mountain_mode = 0;
  1289.     latexarrow_mode = 0;
  1290.     put_msg("LATEX LINE geometry: allow only LaTeX line slopes");
  1291.     break;
  1292.     case L_LATEXARROW:
  1293.     latexarrow_mode = 1;
  1294.     manhattan_mode = 0;
  1295.     mountain_mode = 0;
  1296.     latexline_mode = 0;
  1297.     put_msg("LATEX ARROW geometry: allow only LaTeX arrow slopes");
  1298.     break;
  1299.     }
  1300. }
  1301.  
  1302. /* LINE STYLE         */
  1303.  
  1304. static
  1305. show_linestyle(sw)
  1306.     ind_sw_info       *sw;
  1307. {
  1308.     update_choice_pixmap(sw, cur_linestyle);
  1309.     switch (cur_linestyle) {
  1310.     case SOLID_LINE:
  1311.     cur_styleval = 0.0;
  1312.     put_msg("SOLID LINE STYLE (for BOX, POLYGON and POLYLINE)");
  1313.     break;
  1314.     case DASH_LINE:
  1315.     cur_styleval = cur_dashlength;
  1316.     put_msg("DASH LINE STYLE (for BOX, POLYGON and POLYLINE)");
  1317.     break;
  1318.     case DOTTED_LINE:
  1319.     cur_styleval = cur_dotgap;
  1320.     put_msg("DOTTED LINE STYLE (for BOX, POLYGON and POLYLINE)");
  1321.     break;
  1322.     }
  1323. }
  1324.  
  1325. /* VERTICAL ALIGNMENT     */
  1326.  
  1327. static
  1328. show_valign(sw)
  1329.     ind_sw_info       *sw;
  1330. {
  1331.     update_choice_pixmap(sw, cur_valign);
  1332.     switch (cur_valign) {
  1333.     case NONE:
  1334.     put_msg("No vertical alignment");
  1335.     break;
  1336.     case TOP:
  1337.     put_msg("Vertically align to TOP");
  1338.     break;
  1339.     case CENTER:
  1340.     put_msg("Center vertically when aligning");
  1341.     break;
  1342.     case BOTTOM:
  1343.     put_msg("Vertically align to BOTTOM");
  1344.     break;
  1345.     }
  1346. }
  1347.  
  1348. /* HORIZ ALIGNMENT     */
  1349.  
  1350. static
  1351. show_halign(sw)
  1352.     ind_sw_info       *sw;
  1353. {
  1354.     update_choice_pixmap(sw, cur_halign);
  1355.     switch (cur_halign) {
  1356.     case NONE:
  1357.     put_msg("No horizontal alignment");
  1358.     break;
  1359.     case LEFT:
  1360.     put_msg("Horizontally align to LEFT");
  1361.     break;
  1362.     case CENTER:
  1363.     put_msg("Center horizontally when aligning");
  1364.     break;
  1365.     case RIGHT:
  1366.     put_msg("Horizontally align to RIGHT");
  1367.     break;
  1368.     }
  1369. }
  1370.  
  1371. /* GRID MODE     */
  1372.  
  1373. static
  1374. show_gridmode(sw)
  1375.     ind_sw_info       *sw;
  1376. {
  1377.     static int        prev_gridmode = -1;
  1378.  
  1379.     update_choice_pixmap(sw, cur_gridmode);
  1380.     switch (cur_gridmode) {
  1381.     case GRID_0:
  1382.     put_msg("No grid");
  1383.     break;
  1384.     case GRID_1:
  1385.     put_msg("Small grid");
  1386.     break;
  1387.     case GRID_2:
  1388.     put_msg("Large grid");
  1389.     break;
  1390.     }
  1391.     if (cur_gridmode != prev_gridmode)
  1392.     setup_grid(cur_gridmode);
  1393.     prev_gridmode = cur_gridmode;
  1394. }
  1395.  
  1396. /* POINT POSITION     */
  1397.  
  1398. static
  1399. show_pointposn(sw)
  1400.     ind_sw_info       *sw;
  1401. {
  1402.     char        buf[80];
  1403.  
  1404.     update_choice_pixmap(sw, cur_pointposn);
  1405.     switch (cur_pointposn) {
  1406.     case P_ANY:
  1407.     put_msg("Arbitrary Positioning of Points");
  1408.     break;
  1409.     case P_MAGNET:
  1410.     case P_GRID1:
  1411.     case P_GRID2:
  1412.     sprintf(buf,
  1413.       "MAGNET MODE: entered points rounded to the nearest %s increment",
  1414.         grid_name[cur_pointposn]);
  1415.     put_msg(buf);
  1416.     break;
  1417.     }
  1418. }
  1419.  
  1420. /* SMART LINK MODE */
  1421.  
  1422. static
  1423. show_linkmode(sw)
  1424.     ind_sw_info       *sw;
  1425. {
  1426.     update_choice_pixmap(sw, cur_linkmode);
  1427.     switch (cur_linkmode) {
  1428.     case SMART_OFF:
  1429.     put_msg("Do not adjust links automatically");
  1430.     break;
  1431.     case SMART_MOVE:
  1432.     put_msg("Adjust links automatically by moving endpoint");
  1433.     break;
  1434.     case SMART_SLIDE:
  1435.     put_msg("Adjust links automatically by sliding endlink");
  1436.     break;
  1437.     }
  1438. }
  1439.  
  1440. /* TEXT JUSTIFICATION     */
  1441.  
  1442. static
  1443. show_textjust(sw)
  1444.     ind_sw_info       *sw;
  1445. {
  1446.     update_choice_pixmap(sw, cur_textjust);
  1447.     switch (cur_textjust) {
  1448.     case T_LEFT_JUSTIFIED:
  1449.     put_msg("Left justify text");
  1450.     break;
  1451.     case T_CENTER_JUSTIFIED:
  1452.     put_msg("Center text");
  1453.     break;
  1454.     case T_RIGHT_JUSTIFIED:
  1455.     put_msg("Right justify text");
  1456.     break;
  1457.     }
  1458. }
  1459.  
  1460. /* BOX RADIUS     */
  1461.  
  1462. static
  1463. dec_boxradius(sw)
  1464.     ind_sw_info       *sw;
  1465. {
  1466.     --cur_boxradius;
  1467.     show_boxradius(sw);
  1468. }
  1469.  
  1470. static
  1471. inc_boxradius(sw)
  1472.     ind_sw_info       *sw;
  1473. {
  1474.     ++cur_boxradius;
  1475.     show_boxradius(sw);
  1476. }
  1477.  
  1478. #define MAXRADIUS 30
  1479. static
  1480. show_boxradius(sw)
  1481.     ind_sw_info       *sw;
  1482. {
  1483.     if (cur_boxradius > MAXRADIUS)
  1484.     cur_boxradius = MAXRADIUS;
  1485.     else if (cur_boxradius < 3)
  1486.     cur_boxradius = 3;
  1487.     /* erase by drawing wide, inverted (white) line */
  1488.     pw_vector(sw->normalPM, DEF_IND_SW_WD / 2, DEF_IND_SW_HT / 2,
  1489.           DEF_IND_SW_WD, DEF_IND_SW_HT / 2, ERASE,
  1490.           DEF_IND_SW_HT, PANEL_LINE, 0.0, DEFAULT_COLOR);
  1491.     /* draw current radius into pixmap */
  1492.     curve(sw->normalPM, 0, cur_boxradius, -cur_boxradius, 0, 1,
  1493.       cur_boxradius, cur_boxradius, DEF_IND_SW_WD - 2, DEF_IND_SW_HT - 2,
  1494.       PAINT, 1, PANEL_LINE, 0.0, 0, DEFAULT_COLOR);
  1495.  
  1496.     /*
  1497.      * Fool the toolkit by changing the background pixmap to 0 then giving it
  1498.      * the modified one again.    Otherwise, it sees that the pixmap ID is not
  1499.      * changed and doesn't actually draw it into the widget window
  1500.      */
  1501.     button_args[6].value = 0;
  1502.     XtSetValues(sw->button, &button_args[6], 1);
  1503.     /* put the pixmap in the widget background */
  1504.     button_args[6].value = (XtArgVal) sw->normalPM;
  1505.     XtSetValues(sw->button, &button_args[6], 1);
  1506.     put_msg("ROUNDED-CORNER BOX Radius = %d", cur_boxradius);
  1507. }
  1508.  
  1509. /* FILL STYLE */
  1510.  
  1511. static
  1512. darken_fill(sw)
  1513.     ind_sw_info       *sw;
  1514. {
  1515.     if (++cur_fillstyle > NUMFILLPATS)
  1516.     cur_fillstyle = 0;
  1517.     show_fillstyle(sw);
  1518. }
  1519.  
  1520. static
  1521. lighten_fill(sw)
  1522.     ind_sw_info       *sw;
  1523. {
  1524.     if (--cur_fillstyle < 0)
  1525.     cur_fillstyle = NUMFILLPATS;
  1526.     show_fillstyle(sw);
  1527. }
  1528.  
  1529. static
  1530. show_fillstyle(sw)
  1531.     ind_sw_info       *sw;
  1532. {
  1533.     if (cur_fillstyle == 0) {
  1534.     XCopyArea(tool_d, ((cur_color==BLACK ||
  1535.            (cur_color==DEFAULT_COLOR && x_fg_color.pixel==appres.color[BLACK]) ||
  1536.             (!all_colors_available && cur_color!=WHITE))? 
  1537.             fillstyle_choices[0].blackPM: fillstyle_choices[0].normalPM),
  1538.             sw->normalPM,
  1539.             ind_button_gc, 0, 0, 32, 32, 32, 0);
  1540.     put_msg("NO-FILL MODE");
  1541.     } else {
  1542.     /* put the pixmap in the widget background */
  1543.     XCopyArea(tool_d, ((cur_color==BLACK ||
  1544.            (cur_color==DEFAULT_COLOR && x_fg_color.pixel==appres.color[BLACK]) ||
  1545.             (!all_colors_available && cur_color!=WHITE))? 
  1546.                 fillstyle_choices[cur_fillstyle].blackPM:
  1547.                 fillstyle_choices[cur_fillstyle].normalPM),
  1548.             sw->normalPM,
  1549.             ind_button_gc, 0, 0, 26, 24, 35, 4);
  1550.     put_msg("FILL MODE (black density/color intensity = %d%%)",
  1551.         ((cur_fillstyle - 1) * 100) / (NUMFILLPATS - 1));
  1552.     }
  1553.     button_args[6].value = 0;
  1554.     XtSetValues(sw->button, &button_args[6], 1);
  1555.     button_args[6].value = (XtArgVal) sw->normalPM;
  1556.     XtSetValues(sw->button, &button_args[6], 1);
  1557. }
  1558.  
  1559. /* COLOR */
  1560.  
  1561. static
  1562. next_color(sw)
  1563.     ind_sw_info       *sw;
  1564. {
  1565.     if (++cur_color >= NUMCOLORS)
  1566.     cur_color = DEFAULT_COLOR;
  1567.     show_color(sw);
  1568. }
  1569.  
  1570. static
  1571. prev_color(sw)
  1572.     ind_sw_info       *sw;
  1573. {
  1574.     if (--cur_color < DEFAULT_COLOR)
  1575.     cur_color = NUMCOLORS - 1;
  1576.     show_color(sw);
  1577. }
  1578.  
  1579. static
  1580. show_color(sw)
  1581.     ind_sw_info       *sw;
  1582. {
  1583.     int            color;
  1584.  
  1585.     if (cur_color < 0 || cur_color >= NUMCOLORS) {
  1586.     cur_color == DEFAULT_COLOR;
  1587.     color = x_fg_color.pixel;
  1588.     } else
  1589.     color = all_colors_available ? appres.color[cur_color] : x_fg_color.pixel;
  1590.  
  1591.     show_fillstyle(fill_style_sw);
  1592.     put_msg("Color set to %s", colorNames[cur_color + 1]);
  1593.     XSetForeground(tool_d, color_gc, color);
  1594.     /* now fill the color rectangle with the new color */
  1595.     XFillRectangle(tool_d, sw->normalPM, color_gc, sw->sw_width - 29, 4, 26, 24);
  1596.     /*
  1597.      * write the widget background over old color name before writing new
  1598.      * name
  1599.      */
  1600.     /* first set the foreground color to the background for the fill */
  1601.     XSetForeground(tool_d, ind_button_gc, ind_but_bg);
  1602.     XFillRectangle(tool_d, sw->normalPM, ind_button_gc, 0, DEF_IND_SW_HT / 2,
  1603.            sw->sw_width - 29, DEF_IND_SW_HT / 2);
  1604.     /* now restore the foreground in the gc */
  1605.     XSetForeground(tool_d, ind_button_gc, ind_but_fg);
  1606.     XDrawImageString(tool_d, sw->normalPM, ind_button_gc, 3, 25,
  1607.           colorNames[cur_color + 1], strlen(colorNames[cur_color + 1]));
  1608.     button_args[6].value = 0;
  1609.     XtSetValues(sw->button, &button_args[6], 1);
  1610.     button_args[6].value = (XtArgVal) sw->normalPM;
  1611.     XtSetValues(sw->button, &button_args[6], 1);
  1612. }
  1613.  
  1614. /* TEXT FLAGS */
  1615.  
  1616. static
  1617. inc_flags(sw)
  1618.     ind_sw_info       *sw;
  1619. {
  1620.     if (++cur_flagshown > MAX_FLAGS)
  1621.     cur_flagshown = 0;
  1622.     show_flags(sw);
  1623. }
  1624.  
  1625. static
  1626. dec_flags(sw)
  1627.     ind_sw_info       *sw;
  1628. {
  1629.     if (--cur_flagshown < 0)
  1630.     cur_flagshown = MAX_FLAGS;
  1631.     show_flags(sw);
  1632. }
  1633.  
  1634. static
  1635. show_flags(sw)
  1636.     ind_sw_info       *sw;
  1637. {
  1638.     put_msg("Text flags: Hidden=%s, Special=%s, Rigid=%s (Button 1 to change)",
  1639.         (cur_textflags & HIDDEN_TEXT) ? "on" : "off",
  1640.         (cur_textflags & SPECIAL_TEXT) ? "on" : "off",
  1641.         (cur_textflags & RIGID_TEXT) ? "on" : "off");
  1642.  
  1643.     /* write the text/ellipse angle in the background pixmap */
  1644.     switch(cur_flagshown) {
  1645.     case 0:
  1646.         sprintf(indbuf, "hidden=%s",
  1647.             (cur_textflags & HIDDEN_TEXT) ? "on  " : "off ");
  1648.         break;
  1649.     case 1:
  1650.         sprintf(indbuf, "special=%s",
  1651.             (cur_textflags & SPECIAL_TEXT) ? "on " : "off");
  1652.         break;
  1653.     default:
  1654.         sprintf(indbuf, "rigid=%s",
  1655.             (cur_textflags & RIGID_TEXT) ? "on   " : "off  ");
  1656.     }
  1657.     update_string_pixmap(sw, indbuf, 6, 26);
  1658. }
  1659.  
  1660. /* FONT */
  1661.  
  1662. static
  1663. inc_font(sw)
  1664.     ind_sw_info       *sw;
  1665. {
  1666.     if (using_ps)
  1667.     cur_ps_font++;
  1668.     else
  1669.     cur_latex_font++;
  1670.     show_font(sw);
  1671. }
  1672.  
  1673. static
  1674. dec_font(sw)
  1675.     ind_sw_info       *sw;
  1676. {
  1677.     if (using_ps)
  1678.     cur_ps_font--;
  1679.     else
  1680.     cur_latex_font--;
  1681.     show_font(sw);
  1682. }
  1683.  
  1684. static
  1685. show_font(sw)
  1686.     ind_sw_info       *sw;
  1687. {
  1688.     if (using_ps) {
  1689.     if (cur_ps_font >= NUM_PS_FONTS)
  1690.         cur_ps_font = DEFAULT;
  1691.     else if (cur_ps_font < DEFAULT)
  1692.         cur_ps_font = NUM_PS_FONTS - 1;
  1693.     } else {
  1694.     if (cur_latex_font >= NUM_LATEX_FONTS)
  1695.         cur_latex_font = 0;
  1696.     else if (cur_latex_font < 0)
  1697.         cur_latex_font = NUM_LATEX_FONTS - 1;
  1698.     }
  1699.  
  1700.     /* erase larger fontpane bits if we switched to smaller (Latex) */
  1701.     XFillRectangle(tool_d, sw->normalPM, ind_blank_gc, 0, 0,
  1702.            32 + max2(PS_FONTPANE_WD, LATEX_FONTPANE_WD), DEF_IND_SW_HT);
  1703.     /* and redraw info */
  1704.     XDrawImageString(tool_d, sw->normalPM, ind_button_gc, 3, 12, sw->line1,
  1705.              strlen(sw->line1));
  1706.     XDrawImageString(tool_d, sw->normalPM, ind_button_gc, 3, 25, sw->line2, 
  1707.              strlen(sw->line2));
  1708.  
  1709.     XCopyArea(tool_d, using_ps ? psfont_menu_bitmaps[cur_ps_font + 1] :
  1710.           latexfont_menu_bitmaps[cur_latex_font],
  1711.           sw->normalPM, ind_button_gc, 0, 0,
  1712.           using_ps ? PS_FONTPANE_WD : LATEX_FONTPANE_WD,
  1713.           using_ps ? PS_FONTPANE_HT : LATEX_FONTPANE_HT,
  1714.       using_ps ? 32 : 32 + (PS_FONTPANE_WD - LATEX_FONTPANE_WD) / 2, 6);
  1715.  
  1716.     button_args[6].value = 0;
  1717.     XtSetValues(sw->button, &button_args[6], 1);
  1718.     /* put the pixmap in the widget background */
  1719.     button_args[6].value = (XtArgVal) sw->normalPM;
  1720.     XtSetValues(sw->button, &button_args[6], 1);
  1721.     put_msg("Font: %s", using_ps ? ps_fontinfo[cur_ps_font + 1].name :
  1722.         latex_fontinfo[cur_latex_font].name);
  1723. }
  1724.  
  1725. /* popup menu of printer fonts */
  1726.  
  1727. static int    psflag;
  1728. static ind_sw_info *return_sw;
  1729.  
  1730. int        show_font_return();
  1731.  
  1732. static
  1733. popup_fonts(sw)
  1734.     ind_sw_info       *sw;
  1735. {
  1736.     return_sw = sw;
  1737.     psflag = using_ps ? 1 : 0;
  1738.     fontpane_popup(&cur_ps_font, &cur_latex_font, &psflag,
  1739.            show_font_return, sw->button);
  1740. }
  1741.  
  1742. show_font_return(w)
  1743.     Widget        w;
  1744. {
  1745.     if (psflag)
  1746.     cur_textflags = cur_textflags | PSFONT_TEXT;
  1747.     else
  1748.     cur_textflags = cur_textflags & (~PSFONT_TEXT);
  1749.     show_font(return_sw);
  1750. }
  1751.  
  1752. /* FONT SIZE */
  1753.  
  1754. static
  1755. inc_fontsize(sw)
  1756.     ind_sw_info       *sw;
  1757. {
  1758.     if (cur_fontsize >= 100) {
  1759.     cur_fontsize = (cur_fontsize / 10) * 10;    /* round first */
  1760.     cur_fontsize += 10;
  1761.     } else if (cur_fontsize >= 50) {
  1762.     cur_fontsize = (cur_fontsize / 5) * 5;
  1763.     cur_fontsize += 5;
  1764.     } else if (cur_fontsize >= 20) {
  1765.     cur_fontsize = (cur_fontsize / 2) * 2;
  1766.     cur_fontsize += 2;
  1767.     } else
  1768.     cur_fontsize++;
  1769.     show_fontsize(sw);
  1770. }
  1771.  
  1772. static
  1773. dec_fontsize(sw)
  1774.     ind_sw_info       *sw;
  1775. {
  1776.     if (cur_fontsize > 100) {
  1777.     cur_fontsize = (cur_fontsize / 10) * 10;    /* round first */
  1778.     cur_fontsize -= 10;
  1779.     } else if (cur_fontsize > 50) {
  1780.     cur_fontsize = (cur_fontsize / 5) * 5;
  1781.     cur_fontsize -= 5;
  1782.     } else if (cur_fontsize > 20) {
  1783.     cur_fontsize = (cur_fontsize / 2) * 2;
  1784.     cur_fontsize -= 2;
  1785.     } else if (cur_fontsize > 4)
  1786.     cur_fontsize--;
  1787.     show_fontsize(sw);
  1788. }
  1789.  
  1790. static
  1791. show_fontsize(sw)
  1792.     ind_sw_info       *sw;
  1793. {
  1794.     if (cur_fontsize < 4)
  1795.     cur_fontsize = 4;
  1796.     else if (cur_fontsize > 1000)
  1797.     cur_fontsize = 1000;
  1798.  
  1799.     put_msg("Font size %d", cur_fontsize);
  1800.     /* write the font size in the background pixmap */
  1801.     indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
  1802.     sprintf(indbuf, "%4d", cur_fontsize);
  1803.     update_string_pixmap(sw, indbuf, sw->sw_width - 28, 20);
  1804. }
  1805.  
  1806. /* ELLIPSE/TEXT ANGLE */
  1807.  
  1808. static
  1809. inc_elltextangle(sw)
  1810.     ind_sw_info       *sw;
  1811. {
  1812.  
  1813.     if (cur_elltextangle < 0.0)
  1814.     cur_elltextangle = ((int) ((cur_elltextangle-14.999)/15.0))*15.0;
  1815.     else
  1816.     cur_elltextangle = ((int) (cur_elltextangle/15.0))*15.0;
  1817.     cur_elltextangle += 15.0;
  1818.     show_elltextangle(sw);
  1819. }
  1820.  
  1821. static
  1822. dec_elltextangle(sw)
  1823.     ind_sw_info       *sw;
  1824. {
  1825.     if (cur_elltextangle < 0.0)
  1826.     cur_elltextangle = ((int) (cur_elltextangle/15.0))*15.0;
  1827.     else
  1828.     cur_elltextangle = ((int) ((cur_elltextangle+14.999)/15.0))*15.0;
  1829.     cur_elltextangle -= 15.0;
  1830.     show_elltextangle(sw);
  1831. }
  1832.  
  1833. static
  1834. show_elltextangle(sw)
  1835.     ind_sw_info       *sw;
  1836. {
  1837.     cur_elltextangle = round(cur_elltextangle*10.0)/10.0;
  1838.     if (cur_elltextangle <= -360.0 || cur_elltextangle >= 360)
  1839.     cur_elltextangle = 0.0;
  1840.  
  1841.     put_msg("Text/Ellipse angle %.1f", cur_elltextangle);
  1842.     if (cur_elltextangle == old_elltextangle)
  1843.     return;
  1844.  
  1845.     /* write the text/ellipse angle in the background pixmap */
  1846.     indbuf[0]=indbuf[1]=indbuf[2]=indbuf[3]=indbuf[4]=indbuf[5]=' ';
  1847.     sprintf(indbuf, "%5.1f", cur_elltextangle);
  1848.     update_string_pixmap(sw, indbuf, sw->sw_width - 40, 26);
  1849.     old_elltextangle = cur_elltextangle;
  1850. }
  1851.  
  1852. /* ROTATION ANGLE */
  1853.  
  1854. static
  1855. inc_rotnangle(sw)
  1856.     ind_sw_info       *sw;
  1857. {
  1858.     if (cur_rotnangle < 30 || cur_rotnangle >= 120)
  1859.     cur_rotnangle = 30;
  1860.     else if (cur_rotnangle < 45)
  1861.     cur_rotnangle = 45;
  1862.     else if (cur_rotnangle < 60)
  1863.     cur_rotnangle = 60;
  1864.     else if (cur_rotnangle < 90)
  1865.     cur_rotnangle = 90;
  1866.     else if (cur_rotnangle < 120)
  1867.     cur_rotnangle = 120;
  1868.     show_rotnangle(sw);
  1869. }
  1870.  
  1871. static
  1872. dec_rotnangle(sw)
  1873.     ind_sw_info       *sw;
  1874. {
  1875.     if (cur_rotnangle > 120 || cur_rotnangle <= 30)
  1876.     cur_rotnangle = 120;
  1877.     else if (cur_rotnangle > 90)
  1878.     cur_rotnangle = 90;
  1879.     else if (cur_rotnangle > 60)
  1880.     cur_rotnangle = 60;
  1881.     else if (cur_rotnangle > 45)
  1882.     cur_rotnangle = 45;
  1883.     else if (cur_rotnangle > 30)
  1884.     cur_rotnangle = 30;
  1885.     show_rotnangle(sw);
  1886. }
  1887.  
  1888. static
  1889. show_rotnangle(sw)
  1890.     ind_sw_info       *sw;
  1891. {
  1892.     if (cur_rotnangle < 1)
  1893.     cur_rotnangle = 1;
  1894.     else if (cur_rotnangle > 180)
  1895.     cur_rotnangle = 180;
  1896.  
  1897.     put_msg("Angle of rotation %d", cur_rotnangle);
  1898.     if (cur_rotnangle == old_rotnangle)
  1899.     return;
  1900.  
  1901.     /* write the rotation angle in the background pixmap */
  1902.     indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
  1903.     sprintf(indbuf, "%3d", cur_rotnangle);
  1904.     update_string_pixmap(sw, indbuf, sw->sw_width - 22, 20);
  1905.  
  1906.     /* change markers if we changed to or from 90 degrees (except at start) */
  1907.     if (old_rotnangle != -1) {
  1908.     if (cur_rotnangle == 90)
  1909.         update_markers(M_ALL);
  1910.     else if (old_rotnangle == 90)
  1911.         update_markers(M_ROTATE_ANGLE);
  1912.     }
  1913.     old_rotnangle = cur_rotnangle;
  1914. }
  1915.  
  1916. /* NUMSIDES */
  1917.  
  1918. static
  1919. inc_numsides(sw)
  1920.     ind_sw_info       *sw;
  1921. {
  1922.     cur_numsides++;
  1923.     show_numsides(sw);
  1924. }
  1925.  
  1926. static
  1927. dec_numsides(sw)
  1928.     ind_sw_info       *sw;
  1929. {
  1930.     cur_numsides--;
  1931.     show_numsides(sw);
  1932. }
  1933.  
  1934. static
  1935. show_numsides(sw)
  1936.     ind_sw_info       *sw;
  1937. {
  1938.     if (cur_numsides < 3)
  1939.     cur_numsides = 3;
  1940.     else if (cur_numsides > 99)
  1941.     cur_numsides = 99;
  1942.  
  1943.     put_msg("Number of sides %2d", cur_numsides);
  1944.     /* write the font size in the background pixmap */
  1945.     indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
  1946.     sprintf(indbuf, "%2d", cur_numsides);
  1947.     update_string_pixmap(sw, indbuf, sw->sw_width - 18, 20);
  1948. }
  1949.  
  1950. /* ZOOM */
  1951.  
  1952. static
  1953. inc_zoom(sw)
  1954.     ind_sw_info       *sw;
  1955. {
  1956.     if (zoomscale < 1.0)
  1957.     {
  1958.     zoomscale = (int)(zoomscale*4.0)/4.0 + 0.25;
  1959.     if (zoomscale > 1.0)
  1960.         zoomscale = 1.0;
  1961.     }
  1962.     else
  1963.     zoomscale = (int)zoomscale + 1.0;
  1964.     show_zoom(sw);
  1965. }
  1966.  
  1967. static
  1968. dec_zoom(sw)
  1969.     ind_sw_info       *sw;
  1970. {
  1971.     if (zoomscale <= 1.0)    /* keep to 0.25 increments */
  1972.     zoomscale = (int)((zoomscale+0.23)*4.0)/4.0 - 0.25;
  1973.     else
  1974.     {
  1975.     zoomscale = (int)zoomscale - 1.0;
  1976.     if (zoomscale < 1.0)
  1977.         zoomscale = 1.0;
  1978.     }
  1979.     show_zoom(sw);
  1980. }
  1981.  
  1982. show_zoom(sw)
  1983.     ind_sw_info       *sw;
  1984. {
  1985.     if (zoomscale < 0.1)
  1986.     zoomscale = 0.1;
  1987.     else if (zoomscale > 10.0)
  1988.     zoomscale = 10.0;
  1989.  
  1990.     put_msg("Zoom scale %.2f", zoomscale);
  1991.     if (zoomscale == old_zoomscale)
  1992.     return;
  1993.  
  1994.     /* write the font size in the background pixmap */
  1995.     indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
  1996.     if (zoomscale == (int) zoomscale)
  1997.     sprintf(indbuf, " %.0f  ", zoomscale);
  1998.     else
  1999.     sprintf(indbuf, "%.2f", zoomscale);
  2000.     update_string_pixmap(sw, indbuf, sw->sw_width - 24, 14);
  2001.  
  2002.     /* fix up the rulers and grid */
  2003.     reset_rulers();
  2004.     redisplay_rulers();
  2005.     /* reload text objects' font structures since we need 
  2006.     to load larger/smaller fonts */
  2007.     reload_text_fstructs();
  2008.     setup_grid(cur_gridmode);
  2009.     old_zoomscale = zoomscale;
  2010. }
  2011.  
  2012. /* DEPTH */
  2013.  
  2014. static
  2015. inc_depth(sw)
  2016.     ind_sw_info       *sw;
  2017. {
  2018.     cur_depth++;
  2019.     show_depth(sw);
  2020. }
  2021.  
  2022. static
  2023. dec_depth(sw)
  2024.     ind_sw_info       *sw;
  2025. {
  2026.     cur_depth--;
  2027.     show_depth(sw);
  2028. }
  2029.  
  2030. show_depth(sw)
  2031.     ind_sw_info       *sw;
  2032. {
  2033.     if (cur_depth < 0)
  2034.     cur_depth = 0;
  2035.     else if (cur_depth > MAXDEPTH)
  2036.     cur_depth = MAXDEPTH;
  2037.  
  2038.     put_msg("Depth %3d", cur_depth);
  2039.  
  2040.     /* write the font size in the background pixmap */
  2041.     indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
  2042.     sprintf(indbuf, "%3d", cur_depth);
  2043.     update_string_pixmap(sw, indbuf, sw->sw_width - 22, 20);
  2044. }
  2045.  
  2046. /* TEXTSTEP */
  2047.  
  2048. static
  2049. inc_textstep(sw)
  2050.     ind_sw_info       *sw;
  2051. {
  2052.     if (cur_textstep >= 10.0) {
  2053.     cur_textstep = (int) cur_textstep;    /* round first */
  2054.     cur_textstep += 1.0;
  2055.     } else if (cur_textstep >= 5.0) {
  2056.     cur_textstep = ((int)(cur_textstep*2.0+0.01))/2.0;
  2057.     cur_textstep += 0.5;
  2058.     } else if (cur_textstep >= 2.0) {
  2059.     cur_textstep = ((int)(cur_textstep*5.0+0.01))/5.0;
  2060.     cur_textstep += 0.2;
  2061.     } else
  2062.     cur_textstep += 0.1;
  2063.     show_textstep(sw);
  2064. }
  2065.  
  2066. static
  2067. dec_textstep(sw)
  2068.     ind_sw_info       *sw;
  2069. {
  2070.     if (cur_textstep > 10.0) {
  2071.     cur_textstep = (int)cur_textstep;    /* round first */
  2072.     cur_textstep -= 1.0;
  2073.     } else if (cur_textstep > 5.0) {
  2074.     cur_textstep = ((int)(cur_textstep*2.0+0.01))/2.0;
  2075.     cur_textstep -= 0.5;
  2076.     } else if (cur_textstep > 2.0) {
  2077.     cur_textstep = ((int)(cur_textstep*5.0+0.01))/5.0;
  2078.     cur_textstep -= 0.2;
  2079.     } else if (cur_textstep > 0.4)
  2080.     cur_textstep -= 0.1;
  2081.     show_textstep(sw);
  2082. }
  2083.  
  2084. /* could make this more generic - but a copy will do for font set JNT */
  2085. static
  2086. show_textstep(sw)
  2087.     ind_sw_info       *sw;
  2088. {
  2089.     if (cur_textstep < 0)
  2090.     cur_textstep = 0;
  2091.     else if (cur_textstep > 99.0)
  2092.     cur_textstep = 99.0;
  2093.  
  2094.     put_msg("Text step %.1f", cur_textstep);
  2095.     /* write the font size in the background pixmap */
  2096.     indbuf[0] = indbuf[1] = indbuf[2] = indbuf[3] = indbuf[4] = '\0';
  2097.     sprintf(indbuf, "%4.1f", cur_textstep);
  2098.     update_string_pixmap(sw, indbuf, sw->sw_width - 28, 20);
  2099. }
  2100.