home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / xfig2.8 / part18 / change.c
C/C++ Source or Header  |  1990-07-03  |  39KB  |  1,534 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Created March 1990 by Jon Tombs <jon@uk.ac.oxford.robots>
  5.  *    This is my first X program please excuse the  style, probably
  6.  *    only works with X11R4
  7.  *    Last Update 1st April 1989
  8.  *
  9.  *      %W%     %G%
  10.  *
  11.  *    Based on the file of the same name from the fig-fs distribution:
  12.  *
  13.  *      Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  14.  *      January 1985.
  15.  *      1st revision : Aug 1985.
  16.  *
  17.  *      Change function implemented by Frank Schmuck (schmuck@svax.cs.cornell.edu)
  18.  *      July 1988.
  19. */
  20.  
  21. #include "fig.h"
  22. #include "resources.h"
  23. #include "func.h"
  24. #include "object.h"
  25. #include "paintop.h"
  26. #include "font.h"
  27. #include "psfonts.h"
  28.  
  29. #define TOLERANCE 7
  30. #define min(a, b)    (((a) < (b)) ? (a) : (b))
  31. #define max(a, b)    (((a) > (b)) ? (a) : (b))
  32.  
  33. extern    char *panel_get_value();
  34. extern    Widget make_popup_menu();
  35. extern    void toggle();
  36.  
  37. extern    (*canvas_kbd_proc)();
  38. extern    (*canvas_locmove_proc)();
  39. extern    (*canvas_leftbut_proc)();
  40. extern    (*canvas_middlebut_proc)();
  41. extern    (*canvas_rightbut_proc)();
  42. extern    (*return_proc)();
  43. extern    null_proc();
  44. extern    set_popupmenu();
  45.  
  46. extern    F_text        *text_search();
  47.  
  48. extern    int        foreground_color, background_color;
  49. extern    Pixmap        font_menu_bitmaps[];
  50. extern    int    *font_sel;        /* pointer to store font selected from popup */
  51. extern    Widget    image_widget;        /* which widget to store image of font in */
  52. extern    Window    canvas_win;
  53.  
  54. extern    change_text();
  55. extern    change_item();
  56. extern    change_depth_up();
  57. extern    change_depth_down();
  58. extern    void    Quit();
  59. static    void    new_generic_values();
  60. static        generic_window();
  61. static        font_image_panel();
  62. static        int_panel();
  63. static        str_panel();
  64. static        toggle_panel();
  65. static        xy_panel();
  66. static        f_pos_panel();
  67. static        get_f_pos();
  68. static        points_panel();
  69. static        get_points();
  70. static    void    line_style_select();
  71. static    void    text_adjust_select();
  72. static    Widget    popup, form;
  73. static    Widget    below, beside;
  74.  
  75. extern    F_line        *line_search(),        *copy_line();
  76. extern    F_arc        *arc_search(),        *copy_arc();
  77. extern    F_ellipse    *ellipse_search(),    *copy_ellipse();
  78. extern    F_text        *text_search(),        *copy_text();
  79. extern    F_spline    *spline_search(),    *copy_spline();
  80. extern    F_compound    *compound_search();
  81. extern    F_arrow        *forward_arrow(),    *backward_arrow();
  82. extern    F_compound    objects;
  83.  
  84. #define    NUM_IMAGES    15
  85. extern    PIXRECT        cirrad_ic, cirdia_ic, ellrad_ic, elldia_ic,
  86.             c_spl_ic, spl_ic, c_intspl_ic, intspl_ic,
  87.             line_ic, polygon_ic, box_ic, arc_box_ic,
  88.             arc_ic, text_ic, blank_ic;
  89.  
  90. extern    int        SIDERULER_WIDTH, PANL_WID;
  91. extern    int        RHS_PANL;
  92. extern    float        cur_dashlength;
  93. extern    float        cur_dotgap;
  94.  
  95. /*    not use        init_change();*/
  96. static    int        done_compound();
  97. static    int        done_line();
  98. static    int        done_text();
  99. static    int        done_arc();
  100. static    int        done_ellipse();
  101. static    int        done_spline();
  102.  
  103. static    F_line        *new_line;
  104. static    F_ellipse    *new_ellipse;
  105. static    F_text        *new_text;
  106. static    F_spline    *new_spline;
  107. static    F_arc        *new_arc;
  108. static    F_compound    *new_compound;
  109.  
  110. static    Widget    label;
  111. static    Widget    thickness_panel;
  112. static    Widget    color_panel;
  113. static    Widget    depth_panel;
  114. static    Widget    angle_panel;
  115. static    Widget    adjust_panel;
  116. static    Widget    area_fill_panel;
  117. static    Widget    fill_pct_label;
  118. static    Widget    style_panel;
  119. static    Widget    style_val_panel;
  120. static    Widget    for_arrow_panel;
  121. static    Widget    back_arrow_panel;
  122. static    Widget    text_panel;
  123. static    Widget    x1_panel, y1_panel;
  124. static    Widget    x2_panel, y2_panel;
  125. static    Widget    x3_panel, y3_panel;
  126. static    Widget    font_panel;
  127. static    Widget    font_size_panel;
  128. static    Widget    filled_panel;
  129. static    Widget    radius;
  130. static    Widget    entry, menu, adjust_menu;
  131. static    Widget    but1;
  132.  
  133. Arg    args[12];
  134.  
  135.  
  136. #define    MAX_POINTS    100
  137. static    Widget        px_panel[MAX_POINTS];
  138. static    Widget        py_panel[MAX_POINTS];
  139.  
  140. static    int        ellipse_flag;
  141. static    int        no_fill_flag;
  142. static    int        (*done_proc)();
  143. static    int        button_result;
  144. static    int        text_adjust;
  145. static    int        new_font;
  146. #define    CANCEL        0
  147. #define    DONE        1
  148. #define    APPLY        2
  149.  
  150. static struct {
  151.     int    thickness;
  152.     int    color;
  153.     int    depth;
  154.     int    style;
  155.     float    style_val;
  156.     int    pen;
  157.     int    area_fill;
  158.     int    for_arrow;
  159.     int    back_arrow;
  160. } generic_vals;
  161.  
  162. #define put_generic_vals(x) \
  163.     generic_vals.thickness    = x->thickness; \
  164.     generic_vals.color    = x->color; \
  165.     generic_vals.depth    = x->depth; \
  166.     generic_vals.style    = x->style; \
  167.     generic_vals.style_val    = x->style_val; \
  168.     generic_vals.pen    = x->pen; \
  169.     generic_vals.area_fill    = x->area_fill
  170.  
  171. #define get_generic_vals(x) \
  172.     new_generic_values(NULL, NULL); \
  173.     x->thickness    = generic_vals.thickness; \
  174.     x->color    = generic_vals.color; \
  175.     x->depth    = generic_vals.depth; \
  176.     x->style    = generic_vals.style; \
  177.     x->style_val    = generic_vals.style_val; \
  178.     x->pen        = generic_vals.pen; \
  179.     x->area_fill    = generic_vals.area_fill
  180.  
  181. #define put_generic_arrows(x) \
  182.     generic_vals.for_arrow  = (x->for_arrow != NULL); \
  183.     generic_vals.back_arrow = (x->back_arrow != NULL)
  184.  
  185. #define get_generic_arrows(x) \
  186.     if (x->for_arrow) \
  187.         free((char*)x->for_arrow); \
  188.     if (x->back_arrow) \
  189.         free((char*)x->back_arrow); \
  190.     x->for_arrow  = (generic_vals.for_arrow)?  forward_arrow(): NULL; \
  191.     x->back_arrow = (generic_vals.back_arrow)? backward_arrow(): NULL
  192.  
  193.  
  194. change_item_selected()
  195. {
  196.     canvas_kbd_proc = null_proc;
  197.     canvas_locmove_proc = null_proc;
  198.     canvas_leftbut_proc = change_item;
  199.     canvas_middlebut_proc = null_proc;
  200.     canvas_rightbut_proc = set_popupmenu;
  201.     return_proc = change_item_selected;
  202.     set_cursor(&pick9_cursor);
  203.     reset_action_on();
  204. }
  205.  
  206.  
  207. change_item(x, y)
  208. int     x, y;
  209. {
  210.     extern F_line        *line_search();
  211.     extern F_arc        *arc_search();
  212.     extern F_ellipse    *ellipse_search();
  213.     extern F_text        *text_search();
  214.     extern F_spline        *spline_search();
  215.     extern F_compound    *compound_search();
  216.     F_line            *l;
  217.     F_arc            *a;
  218.     F_ellipse        *e;
  219.     F_text            *t;
  220.     F_spline        *s;
  221.     F_compound        *c;
  222.     int            dummy;
  223.  
  224.  
  225.         if ((l = line_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL) {
  226.         make_window_line(l);
  227.     }
  228.         else if ((t = text_search(x, y)) != NULL) {
  229.         make_window_text(t);
  230.     }
  231.         else if ((e = ellipse_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL){
  232.         make_window_ellipse(e);
  233.     }
  234.         else if ((a = arc_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL){
  235.         make_window_arc(a);
  236.     }
  237.         else if ((s = spline_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL) {
  238.         make_window_spline(s);
  239.     }
  240.     else     if ((c = compound_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL)
  241.         make_window_compound(c);
  242.     else
  243.         return;
  244.  
  245.     XtPopup(popup, XtGrabExclusive);
  246. }
  247.  
  248.  
  249. make_window_compound(c)
  250. F_compound *c;
  251. {
  252.     generic_window("COMPOUND", "Cannot be changed!", &blank_ic, 
  253.         done_compound, 0, 0);
  254.     }
  255.  
  256. static
  257. done_compound()
  258. {
  259.     if (button_result != APPLY) {
  260.         clean_up();
  261.         show_pointmarker();
  262.         }
  263.     }
  264.  
  265. make_window_line(l)
  266. F_line    *l;
  267. {
  268.     struct f_point    p1, p2;
  269.  
  270.     new_line = copy_line(l);
  271.     new_line->next = l;
  272.     put_generic_vals(new_line);
  273.     switch (new_line->type) {
  274.         case T_POLYLINE:
  275.         put_generic_arrows(new_line);
  276.         generic_window("POLYLINE", "Polyline", &line_ic, done_line, 1, 1);
  277.         points_panel(new_line->points, 0);
  278.         break;
  279.         case T_POLYGON:
  280.         put_generic_arrows(new_line);
  281.         generic_window("POLYLINE", "Polygon", &polygon_ic, done_line, 1, 1);
  282.         points_panel(new_line->points, 1);
  283.         break;
  284.         case T_BOX:
  285.         generic_window("POLYLINE", "Box", &box_ic, done_line, 1, 0);
  286.         p1 = *new_line->points;
  287.         p2 = *new_line->points->next->next;
  288.         xy_panel(p1.x, p1.y, "Top Left", &x1_panel, &y1_panel);
  289.         xy_panel(p2.x, p2.y, "Bottom Right", &x2_panel, &y2_panel);
  290.         break;
  291.         case T_ARC_BOX:
  292.         generic_window("POLYLINE", "ArcBox", &arc_box_ic, done_line, 1, 0);
  293.         p1 = *new_line->points;
  294.         p2 = *new_line->points->next->next;
  295.         xy_panel(p1.x, p1.y, "Top Left", &x1_panel, &y1_panel);
  296.         xy_panel(p2.x, p2.y, "Bottom Right", &x2_panel, &y2_panel);
  297.         int_panel(new_line->radius, "Radius:", &radius);
  298.         break;
  299.         }
  300.     }
  301.  
  302. static
  303. get_new_line_values()
  304. {
  305.     struct f_point    p1, p2, *p;
  306.  
  307.     get_generic_vals(new_line);
  308.     if ((new_line->type != T_BOX) && (new_line->type != T_ARC_BOX)) {
  309.         get_generic_arrows(new_line);
  310.         get_points(new_line->points, (new_line->type == T_POLYGON));
  311.         }
  312.     else {
  313.         p1.x = atoi(panel_get_value(x1_panel));
  314.         p1.y = atoi(panel_get_value(y1_panel));
  315.         p2.x = atoi(panel_get_value(x2_panel));
  316.         p2.y = atoi(panel_get_value(y2_panel));
  317.         p = new_line->points;
  318.         p->x = p1.x;  p->y = p1.y;  p = p->next;
  319.         p->x = p2.x;  p->y = p1.y;  p = p->next;
  320.         p->x = p2.x;  p->y = p2.y;  p = p->next;
  321.         p->x = p1.x;  p->y = p2.y;  p = p->next;
  322.         p->x = p1.x;  p->y = p1.y;
  323.         if (new_line->type == T_ARC_BOX)
  324.         new_line->radius = atoi(panel_get_value(radius));
  325.         }
  326.     }
  327.  
  328. static
  329. done_line()
  330. {
  331.     F_line    *old_line;
  332.  
  333.  
  334.     draw_line(new_line, ERASE);
  335.     old_line = new_line->next;
  336.     switch (button_result) {
  337.         case APPLY:
  338.         get_new_line_values();
  339.         draw_line(new_line, PAINT);
  340.         break;
  341.         case DONE:
  342.         clean_up();
  343.         get_new_line_values();
  344.         set_action_object(F_CHANGE, O_POLYLINE);
  345.         new_line->next = NULL;
  346.         delete_line(&objects.lines, old_line);
  347.         insert_line(&objects.lines, new_line);
  348.         set_latestline(old_line);
  349.         old_line->next = new_line;
  350.         draw_line(new_line, PAINT);
  351.         show_pointmarker();
  352.         set_modifiedflag();
  353.         break;
  354.         case CANCEL:
  355.         clean_up();
  356.         new_line->next = NULL;
  357.         free_line(&new_line);
  358.         draw_line(old_line, PAINT);
  359.         show_pointmarker();
  360.         break;
  361.         }
  362.  
  363.     }
  364.  
  365. #define     round(x)    ((int) ((x) + ((x >= 0)? 0.5: -0.5)))
  366.  
  367. make_window_text(t)
  368. F_text    *t;
  369. {
  370.     PIX_FONT temp_font;
  371.     int i,cw;
  372.     static char * adjust_item_names[] = {
  373.         "Left Justified ", "Centered       ", "Right Justified"};
  374.  
  375.     new_text = copy_text(t);
  376.     new_text->next = t;
  377.     generic_window("TEXT", "", &text_ic, done_text, 0, 0);
  378. #ifdef notdef
  379.     subtype_panel = panel_create_item(change_panel, PANEL_CYCLE,
  380.         PANEL_LABEL_X,        ATTR_COL(2),
  381.         PANEL_LABEL_Y,        ATTR_ROW(2),
  382.         PANEL_VALUE_X,        ATTR_COL(20),
  383.         PANEL_VALUE_Y,        ATTR_ROW(2),
  384.         PANEL_LABEL_STRING,        "Text alignment:",
  385.         PANEL_CHOICE_STRINGS,    "left justified", "center justified",
  386.                            "right justified", 0,
  387.         PANEL_VALUE,        new_text->type,
  388.         0);
  389.     font_panel = panel_create_item(change_panel, PANEL_CYCLE,
  390.         PANEL_LABEL_X,        ATTR_COL(2),
  391.         PANEL_LABEL_Y,        ATTR_ROW(3),
  392.         PANEL_VALUE_X,        ATTR_COL(20),
  393.         PANEL_VALUE_Y,        ATTR_ROW(3),
  394.         PANEL_LABEL_STRING,        "Font:",
  395.         PANEL_CHOICE_STRINGS,    "default", "roman",
  396.                            "bold", "italic",
  397.                               "modern", "typewriter", 0,
  398.         PANEL_VALUE,        new_text->font,
  399.         0);
  400. #endif
  401.  
  402.     text_adjust = new_text->type;    /* get current justification */
  403.     new_font = new_text->font;    /* get current font */
  404.  
  405.     int_panel(new_text->size,  "Size:", &font_size_panel);
  406.     int_panel(new_text->color, "Color:", &color_panel);
  407.     int_panel(new_text->depth, "Depth:", &depth_panel);
  408.     int_panel(round(180/M_PI * new_text->angle), "Angle:", &angle_panel);
  409.  
  410.     /* make text justification menu */
  411.  
  412.     XtSetArg(args[0], XtNfromVert, below);
  413.     adjust_panel = XtCreateManagedWidget(
  414.             adjust_item_names[text_adjust], menuButtonWidgetClass,
  415.                 form, args, ONE);
  416.     below = adjust_panel;
  417.     adjust_menu = make_popup_menu(adjust_item_names, XtNumber(adjust_item_names),
  418.                 adjust_panel, text_adjust_select);
  419.  
  420.     xy_panel(new_text->base_x,new_text->base_y, "Origin:", &x1_panel, &y1_panel);
  421.     font_image_panel(font_menu_bitmaps[new_text->font], "Font:", &font_panel);
  422.     str_panel(new_text->cstring, "Text:", &text_panel);
  423.     }
  424.  
  425. static
  426. get_new_text_values()
  427. {
  428.     char        *s;
  429.  
  430.     PR_SIZE        size;
  431.  
  432. #ifdef notdef
  433.     new_text->type =   atoi(panel_get_value(subtype_panel));
  434.     new_text->font =   atoi(panel_get_value(font_panel)); 
  435. #else
  436.     new_text->type =   text_adjust;
  437.     new_text->font =   new_font;
  438. #endif
  439.     new_text->size =   atoi(panel_get_value(font_size_panel));
  440.     if (new_text->size < 1)
  441.         {
  442.         new_text->size = 1;
  443.         panel_set_value(font_size_panel, "1");
  444.         }
  445.     new_text->color =  atoi(panel_get_value(color_panel));
  446.     new_text->depth =  atoi(panel_get_value(depth_panel));
  447.     new_text->angle =  M_PI/180*atoi(panel_get_value(angle_panel));
  448.     new_text->base_x = atoi(panel_get_value(x1_panel));
  449.     new_text->base_y = atoi(panel_get_value(y1_panel));
  450.     if (new_text->cstring)
  451.             cfree(new_text->cstring);
  452.     s = panel_get_value(text_panel);
  453.     new_text->cstring = (char *) calloc((unsigned)(strlen(s)+1), sizeof(char));
  454.     strcpy(new_text->cstring, s);
  455.     size = pf_textwidth(new_text->font, new_text->size, strlen(s), s);
  456.     new_text->height = size.y;
  457.     new_text->length = size.x;
  458.     }
  459.  
  460. static
  461. done_text()
  462. {
  463.     F_text    *old_text;
  464.  
  465.     draw_text(new_text, INV_PAINT);
  466.     old_text = new_text->next;
  467.     switch (button_result) {
  468.         case APPLY:
  469.         get_new_text_values();
  470.         break;
  471.         case DONE:
  472.         clean_up();
  473.         get_new_text_values();
  474.         set_action_object(F_CHANGE, O_TEXT);
  475.         new_text->next = NULL;
  476.         delete_text(&objects.texts, old_text);
  477.         insert_text(&objects.texts, new_text);
  478.         set_latesttext(old_text);
  479.         old_text->next = new_text;
  480.  
  481.         show_pointmarker();
  482.         set_modifiedflag();
  483.         break;
  484.         case CANCEL:
  485.         clean_up();
  486.         new_text->next = NULL;
  487.         free_text(&new_text);
  488.         new_text = old_text;
  489.  
  490.         show_pointmarker();
  491.         break;
  492.         }
  493.         draw_text(new_text, PAINT);
  494.     }
  495.  
  496. make_window_ellipse(e)
  497. F_ellipse *e;
  498. {
  499.     char    *s1, *s2;
  500.     PIXRECT    *image;
  501.  
  502.     new_ellipse = copy_ellipse(e);
  503.     new_ellipse->next = e;
  504.     switch (new_ellipse->type) {
  505.         case T_ELLIPSE_BY_RAD:
  506.         s1 = "ELLIPSE";
  507.         s2 = "specified by radius";
  508.         ellipse_flag = 1;
  509.         image = &ellrad_ic;
  510.         break;
  511.         case T_ELLIPSE_BY_DIA:
  512.         s1 = "ELLIPSE";
  513.         s2 = "specified by diameter";
  514.         ellipse_flag = 1;
  515.         image = &elldia_ic;
  516.         break;
  517.         case T_CIRCLE_BY_RAD:
  518.         s1 = "CIRCLE";
  519.         s2 = "specified by radius";
  520.         ellipse_flag = 0;
  521.         image = &cirrad_ic;
  522.         break;
  523.         case T_CIRCLE_BY_DIA:
  524.         s1 = "CIRCLE";
  525.         s2 = "specified by diameter";
  526.         ellipse_flag = 0;
  527.         image = &cirdia_ic;
  528.         break;
  529.         }
  530.     put_generic_vals(new_ellipse);
  531.     generic_window(s1, s2, image, done_ellipse, 1, 0);
  532.     int_panel(round(180/M_PI * new_ellipse->angle), "Angle:", &angle_panel);
  533.  
  534.     if (ellipse_flag) {
  535.         f_pos_panel(&new_ellipse->center,   "Center  ",
  536.           &x1_panel, &y1_panel);
  537.         f_pos_panel(&new_ellipse->radiuses, "Radiuses",
  538.           &x2_panel, &y2_panel);
  539.         }
  540.     else {
  541.         f_pos_panel(&new_ellipse->center,"Center", 
  542.           &x1_panel, &y1_panel);
  543.         int_panel(new_ellipse->radiuses.x, "Radius", 
  544.           &x2_panel);
  545.         }
  546.     }
  547.  
  548. static
  549. get_new_ellipse_values()
  550. {
  551.     F_pos    old_center;
  552.     F_pos    old_radiuses;
  553.  
  554. #    define    adjust_ref(s,f) \
  555.         s.f = new_ellipse->center.f + \
  556.         ((s.f - old_center.f)*new_ellipse->radiuses.f)/old_radiuses.f
  557.  
  558.     get_generic_vals(new_ellipse);
  559.     new_ellipse->angle =  M_PI/180*atoi(panel_get_value(angle_panel));
  560.     old_center =   new_ellipse->center;
  561.     old_radiuses = new_ellipse->radiuses;
  562.     get_f_pos(&new_ellipse->center,   x1_panel, y1_panel);
  563.     if (ellipse_flag) 
  564.         get_f_pos(&new_ellipse->radiuses, x2_panel, y2_panel);
  565.  
  566.     else
  567.         new_ellipse->radiuses.x = new_ellipse->radiuses.y =
  568.           atoi(panel_get_value(x2_panel)); 
  569.     
  570.     adjust_ref(new_ellipse->start, x);
  571.     adjust_ref(new_ellipse->start, y);
  572.     adjust_ref(new_ellipse->end, x);
  573.     adjust_ref(new_ellipse->end, y);
  574.     }
  575.  
  576. static
  577. done_ellipse()
  578. {
  579.     F_ellipse    *old_ellipse;
  580.  
  581.  
  582.     draw_ellipse(new_ellipse, background_color);
  583.     old_ellipse = new_ellipse->next;
  584.     switch (button_result) {
  585.         case APPLY:
  586.         get_new_ellipse_values();
  587.         draw_ellipse(new_ellipse, foreground_color);
  588.         break;
  589.         case DONE:
  590.         clean_up();
  591.         get_new_ellipse_values();
  592.         set_action_object(F_CHANGE, O_ELLIPSE);
  593.         new_ellipse->next = NULL;
  594.         delete_ellipse(&objects.ellipses, old_ellipse);
  595.         insert_ellipse(&objects.ellipses, new_ellipse);
  596.         set_latestellipse(old_ellipse);
  597.         old_ellipse->next = new_ellipse;
  598.         draw_ellipse(new_ellipse, foreground_color);
  599.         show_pointmarker();
  600.         set_modifiedflag();
  601.         break;
  602.         case CANCEL:
  603.         clean_up();
  604.         new_ellipse->next = NULL;
  605.         free_ellipse(&new_ellipse);
  606.         draw_ellipse(old_ellipse, foreground_color);
  607.         show_pointmarker();
  608.         break;
  609.         }
  610.  
  611.     }
  612.  
  613. make_window_arc(a)
  614. F_arc *a;
  615. {
  616.     new_arc = copy_arc(a);
  617.     new_arc->next = a;
  618.     put_generic_vals(new_arc);
  619.     put_generic_arrows(new_arc);
  620.     generic_window("ARC", "Specified by 3 points", &arc_ic, done_arc, 1, 1);
  621.     f_pos_panel(&new_arc->point[0], "p1",  &x1_panel, &y1_panel);
  622.     f_pos_panel(&new_arc->point[1], "p2",  &x2_panel, &y2_panel);
  623.     f_pos_panel(&new_arc->point[2], "p3",  &x3_panel, &y3_panel);
  624.     }
  625.  
  626. static
  627. get_new_arc_values()
  628. {
  629.     F_pos    p0, p1, p2;
  630.     float    cx, cy;
  631.  
  632.     get_generic_vals(new_arc);
  633.     get_generic_arrows(new_arc);
  634.     get_f_pos(&p0, x1_panel, y1_panel);
  635.     get_f_pos(&p1, x2_panel, y2_panel);
  636.     get_f_pos(&p2, x3_panel, y3_panel);
  637.     if (compute_arccenter(p0, p1, p2, &cx, &cy)) {
  638.         new_arc->point[0] = p0;
  639.         new_arc->point[1] = p1;
  640.         new_arc->point[2] = p2;
  641.         new_arc->center.x = cx;
  642.         new_arc->center.y = cy;
  643.         new_arc->direction = compute_direction(p0, p1, p2);
  644.         }
  645.     else
  646.         put_msg("Invalid ARC points!");
  647.     }
  648.  
  649. static
  650. done_arc()
  651. {
  652.     F_arc    *old_arc;
  653.  
  654.  
  655.     draw_arc(new_arc, background_color);
  656.     old_arc = new_arc->next;
  657.     switch (button_result) {
  658.         case APPLY:
  659.         get_new_arc_values();
  660.         draw_arc(new_arc, foreground_color);
  661.         break;
  662.         case DONE:
  663.         clean_up();
  664.         get_new_arc_values();
  665.         set_action_object(F_CHANGE, O_ARC);
  666.         new_arc->next = NULL;
  667.         delete_arc(&objects.arcs, old_arc);
  668.         insert_arc(&objects.arcs, new_arc);
  669.         set_latestarc(old_arc);
  670.         old_arc->next = new_arc;
  671.         draw_arc(new_arc, foreground_color);
  672.         show_pointmarker();
  673.         set_modifiedflag();
  674.         break;
  675.         case CANCEL:
  676.         clean_up();
  677.         new_arc->next = NULL;
  678.         free_arc(&new_arc);
  679.         draw_arc(old_arc, foreground_color);
  680.         show_pointmarker();
  681.         break;
  682.         }
  683.  
  684.     }
  685.  
  686. make_window_spline(s)
  687. F_spline *s;
  688. {
  689.     new_spline = copy_spline(s);
  690.     new_spline->next = s;
  691.     put_generic_vals(new_spline);
  692.     put_generic_arrows(new_spline);
  693.     switch (new_spline->type) {
  694.         case T_OPEN_NORMAL:
  695.         generic_window("SPLINE", "Normal open", &spl_ic, 
  696.                 done_spline, 1, 1);
  697.         points_panel(new_spline->points, 0);
  698.         break;
  699.         case T_CLOSED_NORMAL:
  700.         generic_window("SPLINE", "Normal closed", &c_spl_ic, 
  701.                 done_spline, 1, 1);
  702.         points_panel(new_spline->points, 1);
  703.         break;
  704.         case T_OPEN_INTERPOLATED:
  705.         generic_window("SPLINE", "Interpolated open", &intspl_ic, 
  706.                 done_spline, 1, 1);
  707.         points_panel(new_spline->points, 0);
  708.         break;
  709.         case T_CLOSED_INTERPOLATED:
  710.         generic_window("SPLINE","Interpolated closed", &c_intspl_ic, 
  711.                 done_spline, 1,1);
  712.         points_panel(new_spline->points, 1);
  713.         break;
  714.         }
  715.     }
  716.  
  717. static
  718. done_spline()
  719. {
  720.     F_spline    *old_spline;
  721.  
  722.     draw_spline(new_spline, ERASE);
  723.     old_spline = new_spline->next;
  724.     switch (button_result) {
  725.         case APPLY:
  726.         get_generic_vals(new_spline);
  727.         get_generic_arrows(new_spline);
  728.         get_points(new_spline->points, closed_spline(new_spline));
  729.         if (int_spline(new_spline))
  730.             remake_control_points(new_spline);
  731.         draw_spline(new_spline, PAINT);
  732.         break;
  733.         case DONE:
  734.         clean_up();
  735.         get_generic_vals(new_spline);
  736.         get_generic_arrows(new_spline);
  737.         get_points(new_spline->points, closed_spline(new_spline));
  738.         set_action_object(F_CHANGE, O_SPLINE);
  739.         if (int_spline(new_spline))
  740.             remake_control_points(new_spline);
  741.         new_spline->next = NULL;
  742.         delete_spline(&objects.splines, old_spline);
  743.         insert_spline(&objects.splines, new_spline);
  744.         set_latestspline(old_spline);
  745.         old_spline->next = new_spline;
  746.         draw_spline(new_spline, PAINT);
  747.         show_pointmarker();
  748.         set_modifiedflag();
  749.         break;
  750.         case CANCEL:
  751.         clean_up();
  752.         new_spline->next = NULL;
  753.         free_spline(&new_spline);
  754.         draw_spline(old_spline, PAINT);
  755.         show_pointmarker();
  756.         break;
  757.         }
  758.     }
  759.  
  760.  
  761. /*
  762.  *  The following routines
  763.  *    change_line, change_arc, change_ellipse, change_spline, 
  764.  *    change_text
  765.  *  are called by the UNDO function (undo.c).
  766.  *  saved_objects.xxxx contains a pointer to the original, unchanged version
  767.  *  of the object.  saved_objects.xxxx->next contains a pointer to the new,
  768.  *  changed version of the object.
  769.  */
  770.  
  771. change_line(lold, lnew)
  772. F_line    *lold, *lnew;
  773. {
  774.     lnew->next = NULL;
  775.     delete_line(&objects.lines, lold);
  776.     insert_line(&objects.lines, lnew);
  777.     set_latestline(lold);
  778.     lold->next = lnew;
  779.     draw_line(lold, ERASE);
  780.     draw_line(lnew, PAINT);
  781.     }
  782.     
  783. change_arc(aold, anew)
  784. F_arc    *aold, *anew;
  785. {
  786.     anew->next = NULL;
  787.     delete_arc(&objects.arcs, aold);
  788.     insert_arc(&objects.arcs, anew);
  789.     set_latestarc(aold);
  790.     aold->next = anew;
  791.     draw_arc(aold, background_color);
  792.     draw_arc(anew, foreground_color);
  793.     }
  794.  
  795. change_ellipse(eold, enew)
  796. F_ellipse    *eold, *enew;
  797. {
  798.     enew->next = NULL;
  799.     delete_ellipse(&objects.ellipses, eold);
  800.     insert_ellipse(&objects.ellipses, enew);
  801.     set_latestellipse(eold);
  802.     eold->next = enew;
  803.     draw_ellipse(eold, background_color);
  804.     draw_ellipse(enew, foreground_color);
  805.     }
  806.  
  807. change_spline(sold, snew)
  808. F_spline    *sold, *snew;
  809. {
  810.     snew->next = NULL;
  811.     delete_spline(&objects.splines, sold);
  812.     insert_spline(&objects.splines, snew);
  813.     set_latestspline(sold);
  814.     sold->next = snew;
  815.     draw_spline(sold, ERASE);
  816.     draw_spline(snew, PAINT);
  817.     }
  818.  
  819. change_text(told, tnew)
  820. F_text    *told, *tnew;
  821. {
  822.     tnew->next = NULL;
  823.     delete_text(&objects.texts, told);
  824.     insert_text(&objects.texts, tnew);
  825.     set_latesttext(told);
  826.     told->next = tnew;
  827.     draw_text(told, INV_PAINT);
  828.     draw_text(tnew, PAINT);
  829.     }
  830.  
  831.  
  832. static void
  833. new_generic_values()
  834. {
  835.     int fill;
  836.     char buf[5];
  837.     char *val;
  838.     
  839.     generic_vals.thickness = atoi(panel_get_value(thickness_panel));
  840.     generic_vals.color =     atoi(panel_get_value(color_panel));
  841.     generic_vals.depth =     atoi(panel_get_value(depth_panel));
  842.     if (!no_fill_flag)
  843.     {
  844.     val = panel_get_value(area_fill_panel);
  845.     if (*val >= ' ' && *val <= '9')
  846.         {
  847.         if ((fill = atoi(val)) > 100)
  848.         fill = 100;
  849.         generic_vals.area_fill = NUMFILLPATS - (fill / (100/(NUMFILLPATS-1)));
  850.         }
  851.     fill = (NUMFILLPATS - generic_vals.area_fill) * (100/(NUMFILLPATS-1));
  852.     sprintf(buf,"%d",fill);
  853.     panel_set_value(area_fill_panel,buf);
  854.     }
  855.     else
  856.     generic_vals.area_fill = 0;
  857. }
  858.  
  859. static
  860. new_arrow_values()
  861. {
  862.     generic_vals.for_arrow  = (int)panel_get_value(for_arrow_panel);
  863.     generic_vals.back_arrow = (int)panel_get_value(back_arrow_panel);
  864. }
  865.  
  866. static char *
  867. style_val_string(s, v)
  868. int   s;
  869. double v;
  870. {
  871.     static char buf[64];
  872.     switch(s) {
  873.     case SOLID_LINE:
  874.          sprintf(buf, " ");
  875.         return buf;
  876.      case DASH_LINE:
  877.         sprintf(buf, "dash length = %3.1f", v);
  878.         return buf;
  879.      case DOTTED_LINE:
  880.         sprintf(buf, "dot gap  =    %3.1f", v);
  881.         return buf;
  882.     }
  883.     return NULL;
  884.     }
  885.  
  886.  
  887. static
  888. done_button(panel_local,item, event)
  889. Widget        panel_local;
  890. Widget        *item;
  891. int        *event;
  892. {
  893.     button_result = DONE;
  894.     done_proc();
  895.     Quit();
  896. }
  897.  
  898. static
  899. apply_button(panel_local,item, event)
  900. Widget        panel_local;
  901. Widget        *item;
  902. int        *event;
  903. {
  904.     button_result = APPLY;
  905.     done_proc();
  906. }
  907.  
  908. static
  909. cancel_button(panel_local,item, event)
  910. Widget        panel_local;
  911. Widget        *item;
  912. int        *event;
  913. {
  914.     button_result = CANCEL;
  915.     done_proc();
  916.     Quit();
  917. }
  918.  
  919. /*
  920.    the following pix_table entries are guaranteed to be 
  921.    initialized to 0 by the compiler 
  922. */
  923.  
  924. static    struct {
  925.     PIXRECT    image;
  926.     Pixmap    image_pm;
  927.     } pix_table[NUM_IMAGES];
  928.  
  929. static
  930. generic_window(object_type, sub_type, icon, d_proc, generics, arrows)
  931. char    *object_type, *sub_type;
  932. PIXRECT    icon;
  933. int    (*d_proc)();
  934. int    generics, arrows;
  935. {
  936.     char        buf[64];
  937.     Position    x_val, y_val;
  938.     Dimension    width, height;
  939.     Dimension    label_height, image_height;
  940.     int        button_distance;
  941.     Cardinal    n;
  942.     int        i, fill, dist;
  943.     Widget        image;
  944.     Pixmap        image_pm;
  945.  
  946.     static char * menu_item_names[] = {
  947.         "Solid Line ", "Dashed Line", "Dotted Line"};
  948.  
  949.     XtSetArg(args[0], XtNwidth, &width);
  950.     XtSetArg(args[1], XtNheight, &height);
  951.     XtGetValues(tool, args, TWO);
  952.     XtTranslateCoords(tool, (Position) (width / 2), (Position) (height / 5),
  953.               &x_val, &y_val);
  954.  
  955.     n=0;
  956.     XtSetArg(args[n], XtNx, x_val); n++;
  957.     XtSetArg(args[n], XtNy, y_val); n++;
  958.  
  959.     popup = XtCreatePopupShell("change", transientShellWidgetClass, tool,
  960.                                args, n);
  961.  
  962.     form = XtCreateManagedWidget("form", formWidgetClass, popup,NULL, 0);
  963.  
  964.     done_proc = d_proc;
  965.  
  966.     sprintf(buf,"%s:%s",object_type, sub_type);
  967.     label = XtCreateManagedWidget(buf, labelWidgetClass, form, NULL, 0);
  968.  
  969.     /* put in the image */
  970.     /* search to see if that pixmap has already been created */
  971.     image_pm = NULL;
  972.     for (i=0; i<NUM_IMAGES; i++)
  973.         {
  974.         if (pix_table[i].image == 0)
  975.             break;
  976.         if (pix_table[i].image == icon)
  977.             {
  978.             image_pm = pix_table[i].image_pm;
  979.             break;
  980.             }
  981.         }
  982.     /* doesn't already exist, create a pixmap from the data (ala panel.c) */
  983.     if (!image_pm)
  984.         {
  985.         image_pm = XCreateBitmapFromData(tool_d, canvas_win,
  986.             icon->data, icon->width, icon->height);
  987.         pix_table[i].image_pm = image_pm;
  988.         pix_table[i].image = icon;
  989.         }
  990.     n=0;
  991.     XtSetArg(args[n], XtNbitmap, image_pm); n++;
  992.     XtSetArg(args[n], XtNfromHoriz, label); n++;
  993.     XtSetArg(args[n], XtNtop,    XtChainTop); n++;
  994.     XtSetArg(args[n], XtNbottom, XtChainTop); n++;
  995.     XtSetArg(args[n], XtNleft,   XtChainRight); n++;
  996.     XtSetArg(args[n], XtNright,  XtChainRight); n++;
  997.     image = XtCreateManagedWidget("image", labelWidgetClass, form, args, n);
  998.  
  999.     /* get height of label widget and distance between widgets */
  1000.     n = 0;
  1001.     XtSetArg(args[n], XtNheight, &label_height); n++;
  1002.     XtSetArg(args[n], XtNvertDistance, &button_distance); n++;
  1003.     XtGetValues(label, args, n);
  1004.     /* do the same for the image widget */
  1005.     n = 0;
  1006.     XtSetArg(args[n], XtNheight, &image_height); n++;
  1007.     XtGetValues(image, args, n);
  1008.  
  1009.     if (image_height > label_height)
  1010.         dist = image_height - label_height + button_distance;
  1011.     else
  1012.         dist = button_distance;
  1013.     n=0;
  1014.     XtSetArg(args[n], XtNfromVert, label); n++;
  1015.     XtSetArg(args[n], XtNvertDistance, dist); n++;
  1016.     but1= XtCreateManagedWidget("done", commandWidgetClass, form, args, n);
  1017.     XtAddCallback(but1, XtNcallback, done_button, NULL);
  1018.  
  1019.     below = but1;
  1020.     n=0;
  1021.     XtSetArg(args[n], XtNfromHoriz, but1); n++;
  1022.     XtSetArg(args[n], XtNfromVert,label); n++;
  1023.     XtSetArg(args[n], XtNvertDistance, dist); n++;
  1024.     but1= XtCreateManagedWidget("apply", commandWidgetClass, form, args, n);
  1025.     XtAddCallback(but1, XtNcallback, apply_button, NULL);
  1026.  
  1027.     n=0;
  1028.     XtSetArg(args[0], XtNfromHoriz, but1); n++;
  1029.     XtSetArg(args[1], XtNfromVert,label); n++;
  1030.     XtSetArg(args[n], XtNvertDistance, dist); n++;
  1031.     but1= XtCreateManagedWidget("cancel",commandWidgetClass, form, args, n);
  1032.     XtAddCallback(but1, XtNcallback, cancel_button, NULL);
  1033.      
  1034.     if (generics) {
  1035.         int_panel(generic_vals.thickness, "Width:", &thickness_panel);
  1036.         int_panel(generic_vals.color, "Color:", &color_panel);
  1037.         int_panel(generic_vals.depth, "Depth:", &depth_panel);
  1038.  
  1039.         if (generic_vals.area_fill == 0 ||
  1040.             strcmp(sub_type,"Polyline") == 0) /* no area fill for polyline */
  1041.         {
  1042.         fill = 100;
  1043.         no_fill_flag = TRUE;
  1044.         }
  1045.         else
  1046.         {
  1047.         fill = (NUMFILLPATS-generic_vals.area_fill) * (100/(NUMFILLPATS-1));
  1048.         no_fill_flag = FALSE;
  1049.         }
  1050.  
  1051.         if (strcmp(sub_type,"Polyline") != 0) /* no area fill for polyline */
  1052.         {
  1053.         toggle_panel(no_fill_flag, no_fill_flag? "Not Filled": "Filled    ",
  1054.                 &filled_panel);
  1055.         int_panel(fill,"Fill%:", &area_fill_panel);
  1056.         fill_pct_label = beside;    /* save pointer to Fill% label */
  1057.         XtSetArg(args[0], XtNsensitive, no_fill_flag? False: True);
  1058.         XtSetArg(args[1], XtNvertDistance, 2);
  1059.         XtSetValues(area_fill_panel, args, TWO);
  1060.         XtSetValues(fill_pct_label, args, TWO);
  1061.         if (no_fill_flag)
  1062.             sprintf(buf," ");
  1063.         else
  1064.             sprintf(buf,"%d",fill);
  1065.         panel_set_value(area_fill_panel,buf);
  1066.         }
  1067.  
  1068.         /* make popup line style menu */
  1069.  
  1070.         XtSetArg(args[0], XtNfromVert, below);
  1071.         style_panel = XtCreateManagedWidget(
  1072.         menu_item_names[generic_vals.style], menuButtonWidgetClass,
  1073.                     form, args, ONE);
  1074.         below = style_panel;
  1075.         menu = make_popup_menu(menu_item_names, XtNumber(menu_item_names),
  1076.                 style_panel, line_style_select);
  1077. #ifdef notdef
  1078.  
  1079.     }
  1080.     if (arrows) 
  1081.         {
  1082.         for_arrow_panel = panel_create_item(change_panel, PANEL_TOGGLE, 
  1083.         PANEL_LABEL_X,        ATTR_COL(2),
  1084.         PANEL_LABEL_Y,        ATTR_ROW(10),
  1085.         PANEL_VALUE_X,        ATTR_COL(20),
  1086.         PANEL_VALUE_Y,        ATTR_ROW(10),
  1087.         PANEL_LABEL_STRING,    "Forward arrow:",
  1088.         PANEL_VALUE,        generic_vals.for_arrow,
  1089.         PANEL_FEEDBACK,        PANEL_MARKED,
  1090.         PANEL_NOTIFY_PROC,    new_arrow_values,
  1091.         0);
  1092.         back_arrow_panel = panel_create_item(change_panel, PANEL_TOGGLE, 
  1093.         PANEL_LABEL_X,        ATTR_COL(2),
  1094.         PANEL_LABEL_Y,        ATTR_ROW(11),
  1095.         PANEL_VALUE_X,        ATTR_COL(20),
  1096.         PANEL_VALUE_Y,        ATTR_ROW(11),
  1097.         PANEL_LABEL_STRING,    "Backward arrow:",
  1098.         PANEL_VALUE,        generic_vals.back_arrow,
  1099.         PANEL_FEEDBACK,        PANEL_MARKED,
  1100.         PANEL_NOTIFY_PROC,    new_arrow_values,
  1101.         0);
  1102. #endif /* not def */
  1103.         }
  1104.  
  1105. }
  1106.  
  1107. /* make a button panel with the image 'pixmap' in it */
  1108. /* for the font selection */
  1109.  
  1110. void    f_menu_popup();
  1111.  
  1112. static XtCallbackRec f_sel_callback[] =
  1113. {
  1114.     { f_menu_popup, NULL },
  1115.     { NULL, NULL },
  1116. };
  1117.  
  1118. static
  1119. font_image_panel(pixmap, label,  pi_x)
  1120. Pixmap        pixmap;
  1121. char        *label;
  1122. Widget        *pi_x;
  1123.     {
  1124.     char buf[32];
  1125.  
  1126.     XtSetArg(args[0], XtNfromVert, below);
  1127.     XtSetArg(args[1], XtNlabel, label);
  1128.     below = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO);
  1129.  
  1130.     XtSetArg(args[0], XtNfromVert, below);
  1131.     XtSetArg(args[1], XtNvertDistance, 2);
  1132.     XtSetArg(args[2], XtNbitmap, pixmap);
  1133.     XtSetArg(args[3], XtNcallback, f_sel_callback);
  1134.     *pi_x = XtCreateManagedWidget(label, commandWidgetClass, form, args, FOUR);
  1135.     below = *pi_x;
  1136.     }
  1137.  
  1138. /* come here when user presses font image button */
  1139.  
  1140. void
  1141. f_menu_popup()
  1142.     {
  1143.     font_sel = &new_font;        /* store selected font number in new_font */
  1144.     image_widget = font_panel;    /* and image in this widget */
  1145.     XtPopup(fontmenu,XtGrabNonexclusive); /* popup the font menu */
  1146.     setup_fontmenu_cursor();    /* now define the cursor for the font menu */
  1147.     }
  1148.  
  1149. /*
  1150.    make a popup menu with "nent" button entries (labels) that call 
  1151.    "callback" when pressed
  1152. */
  1153.  
  1154. Widget
  1155. make_popup_menu(entries, nent, parent, callback)
  1156. char *entries[];
  1157. int nent;
  1158. Widget parent;
  1159. XtCallbackProc callback;
  1160.     {
  1161.     Widget    pop_menu,entry;
  1162.     int    i;
  1163.  
  1164.     pop_menu = XtCreatePopupShell("menu", simpleMenuWidgetClass, parent,
  1165.                   NULL, ZERO);
  1166.  
  1167.     for (i = 0; i < nent ; i++) 
  1168.         {
  1169.         entry = XtCreateManagedWidget(entries[i], smeBSBObjectClass, pop_menu,
  1170.                       NULL, ZERO);
  1171.         XtAddCallback(entry, XtNcallback, callback, (XtPointer) i);
  1172.         }
  1173.     return pop_menu;
  1174.     }
  1175.  
  1176. static
  1177. int_panel(x, label,  pi_x)
  1178. int        x;
  1179. char        *label;
  1180. Widget        *pi_x;
  1181. {
  1182.     char buf[32];
  1183.  
  1184.     XtSetArg(args[0], XtNfromVert, below);
  1185.     XtSetArg(args[1], XtNlabel, label);
  1186.     beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO);
  1187.     
  1188.     sprintf(buf, "%d", x);
  1189.     XtSetArg(args[1], XtNstring, buf);
  1190.         XtSetArg(args[2], XtNinsertPosition, strlen(buf));
  1191.     XtSetArg(args[3], XtNfromHoriz, beside);
  1192.     XtSetArg(args[4], XtNeditType, "append");
  1193.     XtSetArg(args[5], XtNwidth, 40);
  1194.     *pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args, SIX);
  1195.     below = *pi_x;
  1196.     }
  1197.  
  1198. /* don't allow newlines in text until we handle multiple line texts */
  1199.  
  1200. static String text_translations =
  1201.     "<Key>Return: no-op(RingBell)\n\
  1202.     Ctrl<Key>J: no-op(RingBell)\n\
  1203.     Ctrl<Key>M: no-op(RingBell)\n";
  1204.  
  1205. static
  1206. str_panel(string, label, pi_x)
  1207. char        *string;
  1208. char        *label;
  1209. Widget        *pi_x;
  1210. {
  1211.     int        width,nlines,i,n;
  1212.     Dimension    pwidth;
  1213.     PIX_FONT    temp_font;
  1214.  
  1215.     XtSetArg(args[0], XtNfromVert, below);
  1216.     XtSetArg(args[1], XtNlabel, label);
  1217.     beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO);
  1218.     
  1219.     /* get the font and width of above label widget */
  1220.     n=0;
  1221.     XtSetArg(args[n], XtNfont, &temp_font);    n++;
  1222.     XtSetArg(args[n], XtNwidth, &pwidth);    n++;
  1223.     XtGetValues(beside, args, n);
  1224.     /* make panel as wide as image pane above less the label widget's width */
  1225.     /* but at least 200 pixels wide */
  1226.     width = max(FONT_PANE_WIDTH-pwidth+2, 200);
  1227.  
  1228.     /* count number of lines in this text string */
  1229.     nlines=1;    /* number of lines in string */
  1230.     for (i=0; i<strlen(string); i++)
  1231.         {
  1232.         if (string[i]=='\n')
  1233.             {
  1234.             nlines++;
  1235.             }
  1236.         }
  1237.     if (nlines > 6)        /* limit to displaying 6 lines and show scrollbars */
  1238.         nlines=6;
  1239.     n=0;
  1240.     XtSetArg(args[n], XtNfromVert, below);        n++;
  1241.     XtSetArg(args[n], XtNstring,  string);        n++;
  1242.     XtSetArg(args[n], XtNinsertPosition, strlen(string));    n++;
  1243.     XtSetArg(args[n], XtNfromHoriz, beside);    n++;
  1244.     XtSetArg(args[n], XtNeditType, "edit");        n++;
  1245.     XtSetArg(args[n], XtNwidth, width);        n++;
  1246.     XtSetArg(args[n], XtNheight, char_height(temp_font)*nlines+4);    n++;
  1247.     XtSetArg(args[n], XtNscrollHorizontal, XawtextScrollWhenNeeded);n++;
  1248.     XtSetArg(args[n], XtNscrollVertical, XawtextScrollWhenNeeded);    n++;
  1249.     *pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args, n);
  1250.  
  1251.     /* make Newline do nothing for now */
  1252.     XtOverrideTranslations(*pi_x,XtParseTranslationTable(text_translations));
  1253.  
  1254.     below = *pi_x;
  1255.     }
  1256.  
  1257. static
  1258. toggle_panel(x, label, pi_x)
  1259. int        x;
  1260. char        *label;
  1261. Widget        *pi_x;
  1262. {
  1263.     XtSetArg(args[0], XtNfromVert, below);
  1264.     XtSetArg(args[1], XtNlabel, label);
  1265.     XtSetArg(args[2], XtNvalue, x);
  1266.     *pi_x = XtCreateManagedWidget(label, toggleWidgetClass, form, args, THREE);
  1267.     XtAddCallback(*pi_x, XtNcallback, toggle, NULL);
  1268.     below = *pi_x;
  1269.     }
  1270.  
  1271. static
  1272. xy_panel(x, y, label,  pi_x, pi_y)
  1273. int        x, y;
  1274. char        *label;
  1275. Widget        *pi_x, *pi_y;
  1276. {
  1277.     char buf[32];
  1278.  
  1279.     XtSetArg(args[0], XtNfromVert, below);
  1280.     XtSetArg(args[1], XtNlabel, label);
  1281.     below = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO);
  1282.     XtSetArg(args[0], XtNfromVert, below);
  1283.     XtSetArg(args[1], XtNvertDistance, 2);
  1284.     XtSetArg(args[2], XtNlabel, "X:");
  1285.     beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, THREE);
  1286.     
  1287.     sprintf(buf, "%d", x);
  1288.     XtSetArg(args[2], XtNstring, buf);
  1289.     XtSetArg(args[3], XtNinsertPosition, strlen(buf));
  1290.     XtSetArg(args[4], XtNfromHoriz, beside);
  1291.     XtSetArg(args[5], XtNeditType, "append");
  1292.     XtSetArg(args[6], XtNwidth, 40);
  1293.     *pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args, SEVEN);
  1294.  
  1295.     XtSetArg(args[2], XtNlabel, "Y:");
  1296.     XtSetArg(args[3], XtNfromHoriz, *pi_x);
  1297.     beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, FOUR);
  1298.  
  1299.     sprintf(buf, "%d", y);
  1300.     XtSetArg(args[2], XtNstring, buf);
  1301.     XtSetArg(args[3], XtNfromHoriz, beside);
  1302.     XtSetArg(args[4], XtNinsertPosition, strlen(buf));
  1303.     XtSetArg(args[5], XtNeditType, "append");
  1304.     XtSetArg(args[6], XtNwidth, 40);
  1305.     *pi_y = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args ,SEVEN);
  1306.  
  1307.     below = *pi_x;
  1308.     }
  1309.  
  1310. static
  1311. f_pos_panel(fp, label, pi_x, pi_y)
  1312. F_pos        *fp;
  1313. char        *label;
  1314. Widget    *pi_x, *pi_y;
  1315. {
  1316.     char buf[32];
  1317.  
  1318.     XtSetArg(args[0], XtNfromVert, below);
  1319.     below = XtCreateManagedWidget(label, labelWidgetClass, form, args, ONE);
  1320.     XtSetArg(args[0], XtNfromVert, below);
  1321.     XtSetArg(args[1], XtNlabel, "X:");
  1322.     beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO);
  1323.     sprintf(buf, "%d", fp->x);
  1324.     XtSetArg(args[1], XtNstring, buf);
  1325.     XtSetArg(args[2], XtNinsertPosition, strlen(buf));
  1326.     XtSetArg(args[3], XtNfromHoriz, beside);
  1327.     XtSetArg(args[4], XtNeditType, "append");
  1328.     XtSetArg(args[5], XtNwidth, 40);
  1329.     *pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args, SIX);
  1330.     XtSetArg(args[1], XtNlabel, "Y:");
  1331.     XtSetArg(args[2], XtNfromHoriz, *pi_x);
  1332.     beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, THREE);
  1333.     sprintf(buf, "%d", fp->y);
  1334.     XtSetArg(args[1], XtNstring, buf);
  1335.     XtSetArg(args[2], XtNinsertPosition, strlen(buf));
  1336.     XtSetArg(args[3], XtNfromHoriz, beside);
  1337.     XtSetArg(args[4], XtNeditType, "append");
  1338.     XtSetArg(args[5], XtNwidth, 40);
  1339.     *pi_y = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args ,SIX);
  1340.     below = *pi_x;
  1341.     }
  1342.  
  1343. static
  1344. get_f_pos(fp, pi_x, pi_y)
  1345. F_pos        *fp;
  1346. Widget    pi_x, pi_y;
  1347. {
  1348.     fp->x = (atoi(panel_get_value(pi_x)));
  1349.     fp->y = (atoi(panel_get_value(pi_y)));
  1350.     }
  1351.  
  1352. static
  1353. points_panel(p, closed)
  1354. struct f_point    *p;
  1355. int         closed;
  1356. {
  1357.     char buf[32];
  1358.     char bufxy[32];
  1359.     int  i;
  1360.  
  1361.     for (i = 0; p != NULL; i++) {
  1362.         if (i >= MAX_POINTS)
  1363.         break;
  1364.         XtSetArg(args[0], XtNfromVert,below);
  1365.             sprintf(buf,"X:%d",i);
  1366.         XtSetArg(args[1], XtNlabel, buf);
  1367.         beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO);
  1368.         sprintf(bufxy, "%d", p->x);
  1369.         XtSetArg(args[1], XtNstring, bufxy);
  1370.         XtSetArg(args[2], XtNinsertPosition, strlen(bufxy));
  1371.         XtSetArg(args[3], XtNfromHoriz, beside);
  1372.         XtSetArg(args[4], XtNeditType, "append");
  1373.         XtSetArg(args[5], XtNwidth, 40);        
  1374.         px_panel[i] = XtCreateManagedWidget("xy", asciiTextWidgetClass, 
  1375.                 form, args, SIX);
  1376.  
  1377.         sprintf(buf,"Y:%d",i);
  1378.         XtSetArg(args[1], XtNlabel, buf);
  1379.         XtSetArg(args[2], XtNfromHoriz, px_panel[i]);
  1380.         beside = XtCreateManagedWidget(label, labelWidgetClass, 
  1381.                 form, args, THREE);
  1382.     
  1383.         sprintf(bufxy, "%d", p->y);
  1384.         XtSetArg(args[1], XtNstring, bufxy);
  1385.         XtSetArg(args[2], XtNinsertPosition, strlen(bufxy));
  1386.         XtSetArg(args[3], XtNfromHoriz,beside);
  1387.         XtSetArg(args[4], XtNeditType, "append");
  1388.         XtSetArg(args[5], XtNwidth, 40);        
  1389.  
  1390.         py_panel[i] = XtCreateManagedWidget("xy", asciiTextWidgetClass, 
  1391.                 form, args, SIX);
  1392.         below = px_panel[i];
  1393.  
  1394.         p = p->next;
  1395.         if (closed  &&  (p == NULL  ||  p->next == NULL))
  1396.         break;
  1397.  
  1398.  
  1399.         }
  1400.     }
  1401.  
  1402. static
  1403. get_points(p, closed)
  1404. struct f_point    *p;
  1405. {
  1406.     struct f_point    *q;
  1407.     int  i;
  1408.  
  1409.     for (q = p, i = 0;  q != NULL;  i++) {
  1410.         if (i >= MAX_POINTS)
  1411.         break;
  1412.         q->x = (atoi(panel_get_value(px_panel[i])));
  1413.         q->y = (atoi(panel_get_value(py_panel[i])));
  1414.         q = q->next;
  1415.         if (closed) {
  1416.         if (q == NULL)
  1417.             break;
  1418.         else if (q->next == NULL) {
  1419.             q->x = p->x;
  1420.             q->y = p->y;
  1421.             break;
  1422.             }
  1423.         }
  1424.         }
  1425.     }
  1426.  
  1427.  
  1428. void
  1429. Quit(widget, client_data, call_data)
  1430. Widget  widget;
  1431. XtPointer client_data, call_data;
  1432. {
  1433.  
  1434.     XtDestroyWidget(popup);
  1435. }
  1436.  
  1437. char *
  1438. panel_get_value(widg)
  1439. Widget widg;
  1440. {
  1441.     char *val;
  1442.  
  1443.     XtSetArg(args[0], XtNstring, &val);
  1444.     XtGetValues(widg, args, ONE);
  1445.     if(atol(val) < 0)
  1446.     {
  1447.     panel_set_value(widg,"0");
  1448.     return "0";
  1449.     }
  1450.     return val;
  1451.     
  1452. }
  1453.  
  1454.  
  1455. panel_set_value(widg, val)
  1456. Widget widg;
  1457. char *val;
  1458. {
  1459.  
  1460.     XtSetArg(args[0], XtNstring, val);
  1461.     XtSetValues(widg, args, ONE);
  1462.     XtSetArg(args[0], XtNinsertPosition, strlen(val));    
  1463.     XtSetValues(widg, args, ONE);
  1464. }
  1465.  
  1466.  
  1467. static void
  1468. line_style_select(w, style, garbage)
  1469. Widget w;
  1470. XtPointer style, garbage;
  1471. {
  1472.  
  1473.     XtSetArg(args[0], XtNlabel, XtName(w));
  1474.     XtSetValues(style_panel, args, ONE);
  1475.  
  1476.     generic_vals.style = (int) style;
  1477.  
  1478.     switch(generic_vals.style)
  1479.     {
  1480.     case SOLID_LINE:
  1481.         generic_vals.style_val = 0.0;
  1482.         break;
  1483.     case DASH_LINE:
  1484.         generic_vals.style_val = cur_dashlength;
  1485.         break;
  1486.     case DOTTED_LINE:
  1487.         generic_vals.style_val = cur_dotgap;
  1488.             break;
  1489.     }
  1490. }
  1491.  
  1492. static void
  1493. text_adjust_select(w, adjust, garbage)
  1494. Widget w;
  1495. XtPointer adjust, garbage;
  1496. {
  1497.  
  1498.     XtSetArg(args[0], XtNlabel, XtName(w));
  1499.     XtSetValues(adjust_panel, args, ONE);
  1500.     text_adjust = (int) adjust;
  1501. }
  1502.  
  1503.  
  1504. void
  1505. toggle(w, clos, garbage)
  1506. Widget w;
  1507. XtPointer clos, garbage;
  1508. {
  1509.     char buf[5];
  1510.     int fill;
  1511.  
  1512.     if(no_fill_flag == TRUE)
  1513.         no_fill_flag = FALSE;
  1514.     else
  1515.         no_fill_flag = TRUE;
  1516.  
  1517.     /* set label to reflect fill flag */
  1518.     XtSetArg(args[0], XtNlabel, no_fill_flag? "Not Filled": "Filled    ");
  1519.     XtSetValues(w, args, ONE);
  1520.  
  1521.     /* make fill% panel sensitive or insensitive depending on fill flag */
  1522.     XtSetArg(args[0], XtNsensitive, no_fill_flag? False: True);
  1523.     XtSetValues(area_fill_panel, args, ONE);
  1524.     XtSetValues(fill_pct_label, args, ONE);
  1525.     fill = (NUMFILLPATS - generic_vals.area_fill) * (100/(NUMFILLPATS-1));
  1526.     if (fill > 100)
  1527.         fill = 100;
  1528.     if (no_fill_flag)
  1529.         sprintf(buf," ");
  1530.     else
  1531.         sprintf(buf,"%d",fill);
  1532.     panel_set_value(area_fill_panel,buf);
  1533. }
  1534.