home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / gui / x / xfig.lha / src / x11 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-26  |  26.2 KB  |  798 lines

  1. /*
  2.  * FIG : Facility for Interactive Generation of figures
  3.  * Copyright (c) 1985 by Supoj Sutanthavibul
  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 "version.h"
  16. #include "patchlevel.h"
  17. #include "resources.h"
  18. #include "object.h"
  19. #include "mode.h"
  20. #include "u_fonts.h"
  21. #include "w_drawprim.h"
  22. #include "w_mousefun.h"
  23. #include "w_setup.h"
  24. #include "w_util.h"
  25.  
  26. /************** EXTERNAL functions **************/
  27.  
  28. extern void    quit(), undo(), paste(), redisplay_canvas(), delete_all_cmd();
  29. extern void    popup_print_panel(), popup_file_panel(), popup_export_panel();
  30. extern void    do_load(), do_save(), popup_unit_panel();
  31.  
  32. extern void    setup_cmd_panel();
  33. extern        X_error_handler();
  34. extern void    error_handler();
  35. extern void    my_quit();
  36. extern int    ignore_exp_cnt;
  37. extern int    psfontnum();
  38. extern int    latexfontnum();
  39.  
  40. #include "fig.icon.X"
  41. Pixmap        fig_icon;
  42.  
  43. static char    tool_name[100];
  44. static        sigwinched();
  45.  
  46. /************** FIG options ******************/
  47.  
  48. static char    *filename = NULL;
  49.  
  50. static Boolean    true = True;
  51. static Boolean    false = False;
  52. static int    zero = 0;
  53. static float    one = 1.0;
  54.  
  55. /* actions so that we may install accelerators at the top level */
  56. static XtActionsRec    main_actions[] =
  57. {
  58.     {"Quit", (XtActionProc) quit},
  59.     {"Delete_all", (XtActionProc) delete_all_cmd},
  60.     {"Undo", (XtActionProc) undo},
  61.     {"Redraw", (XtActionProc) redisplay_canvas},
  62.     {"Paste", (XtActionProc) paste},
  63.     {"File", (XtActionProc) popup_file_panel},
  64.       {"LoadFile", (XtActionProc) do_load},
  65.       {"SaveFile", (XtActionProc) do_save},
  66.     {"Export", (XtActionProc) popup_export_panel},
  67.     {"Print", (XtActionProc) popup_print_panel},
  68.     {"Units", (XtActionProc) popup_unit_panel},
  69. };
  70.  
  71. static XtResource application_resources[] = {
  72.     {"iconGeometry",  "IconGeometry",  XtRString,  sizeof(char *),
  73.     XtOffset(appresPtr,iconGeometry), XtRString, (caddr_t) NULL},
  74.     {"showallbuttons", "ShowAllButtons", XtRBoolean, sizeof(Boolean),
  75.     XtOffset(appresPtr, ShowAllButtons), XtRBoolean, (caddr_t) & false},
  76.     {XtNjustify, XtCJustify, XtRBoolean, sizeof(Boolean),
  77.     XtOffset(appresPtr, RHS_PANEL), XtRBoolean, (caddr_t) & false},
  78.     {"landscape", XtCOrientation, XtRBoolean, sizeof(Boolean),
  79.     XtOffset(appresPtr, landscape), XtRBoolean, (caddr_t) & true},
  80.     {"debug", "Debug", XtRBoolean, sizeof(Boolean),
  81.     XtOffset(appresPtr, DEBUG), XtRBoolean, (caddr_t) & false},
  82.     {"pwidth", XtCWidth, XtRFloat, sizeof(float),
  83.     XtOffset(appresPtr, tmp_width), XtRInt, (caddr_t) & zero},
  84.     {"pheight", XtCHeight, XtRFloat, sizeof(float),
  85.     XtOffset(appresPtr, tmp_height), XtRInt, (caddr_t) & zero},
  86.     {XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof(Boolean),
  87.     XtOffset(appresPtr, INVERSE), XtRBoolean, (caddr_t) & false},
  88.     {"trackCursor", "Track", XtRBoolean, sizeof(Boolean),
  89.     XtOffset(appresPtr, TRACKING), XtRBoolean, (caddr_t) & true},
  90.     {"inches", "Inches", XtRBoolean, sizeof(Boolean),
  91.     XtOffset(appresPtr, INCHES), XtRBoolean, (caddr_t) & true},
  92.     {"boldFont", "Font", XtRString, sizeof(char *),
  93.     XtOffset(appresPtr, boldFont), XtRString, (caddr_t) NULL},
  94.     {"normalFont", "Font", XtRString, sizeof(char *),
  95.     XtOffset(appresPtr, normalFont), XtRString, (caddr_t) NULL},
  96.     {"buttonFont", "Font", XtRString, sizeof(char *),
  97.     XtOffset(appresPtr, buttonFont), XtRString, (caddr_t) NULL},
  98.     {"startlatexFont", "StartlatexFont", XtRString, sizeof(char *),
  99.     XtOffset(appresPtr, startlatexFont), XtRString, (caddr_t) NULL},
  100.     {"startpsFont", "StartpsFont", XtRString, sizeof(char *),
  101.     XtOffset(appresPtr, startpsFont), XtRString, (caddr_t) NULL},
  102.     {"startfontsize", "StartFontSize", XtRInt, sizeof(int),
  103.     XtOffset(appresPtr, startfontsize), XtRInt, (caddr_t) & zero},
  104.     {"internalborderwidth", "InternalBorderWidth", XtRInt, sizeof(int),
  105.     XtOffset(appresPtr, internalborderwidth), XtRInt, (caddr_t) & zero},
  106.     {"latexfonts", "Latexfonts", XtRBoolean, sizeof(Boolean),
  107.     XtOffset(appresPtr, latexfonts), XtRBoolean, (caddr_t) & false},
  108.     {"specialtext", "SpecialText", XtRBoolean, sizeof(Boolean),
  109.     XtOffset(appresPtr, specialtext), XtRBoolean, (caddr_t) & false},
  110.     {"scalablefonts", "ScalableFonts", XtRBoolean, sizeof(Boolean),
  111.     XtOffset(appresPtr, SCALABLEFONTS), XtRBoolean, (caddr_t) & false},
  112.     {"color0", "Color0", XtRPixel, sizeof(Pixel),
  113.     XtOffset(appresPtr, color[0]), XtRString, (caddr_t) "black"},
  114.     {"color1", "Color1", XtRPixel, sizeof(Pixel),
  115.     XtOffset(appresPtr, color[1]), XtRString, (caddr_t) "blue"},
  116.     {"color2", "Color2", XtRPixel, sizeof(Pixel),
  117.     XtOffset(appresPtr, color[2]), XtRString, (caddr_t) "green"},
  118.     {"color3", "Color3", XtRPixel, sizeof(Pixel),
  119.     XtOffset(appresPtr, color[3]), XtRString, (caddr_t) "cyan"},
  120.     {"color4", "Color4", XtRPixel, sizeof(Pixel),
  121.     XtOffset(appresPtr, color[4]), XtRString, (caddr_t) "red"},
  122.     {"color5", "Color5", XtRPixel, sizeof(Pixel),
  123.     XtOffset(appresPtr, color[5]), XtRString, (caddr_t) "magenta"},
  124.     {"color6", "Color6", XtRPixel, sizeof(Pixel),
  125.     XtOffset(appresPtr, color[6]), XtRString, (caddr_t) "yellow"},
  126.     {"color7", "Color7", XtRPixel, sizeof(Pixel),
  127.     XtOffset(appresPtr, color[7]), XtRString, (caddr_t) "white"},
  128.     {"monochrome", "Monochrome", XtRBoolean, sizeof(Boolean),
  129.     XtOffset(appresPtr, monochrome), XtRBoolean, (caddr_t) & false},
  130.     {"latexfonts", "Latexfonts", XtRBoolean, sizeof(Boolean),
  131.     XtOffset(appresPtr, latexfonts), XtRBoolean, (caddr_t) & false},
  132.     {"keyFile", "KeyFile", XtRString, sizeof(char *),
  133.     XtOffset(appresPtr, keyFile), XtRString, (caddr_t) "CompKeyDB"},
  134.     {"exportLanguage", "ExportLanguage", XtRString, sizeof(char *),
  135.     XtOffset(appresPtr, exportLanguage), XtRString, (caddr_t) "eps"},
  136.     {"flushleft", "FlushLeft", XtRBoolean, sizeof(Boolean),
  137.     XtOffset(appresPtr, flushleft), XtRBoolean, (caddr_t) & false},
  138.     {"textoutline", "TextOutline", XtRBoolean, sizeof(Boolean),
  139.     XtOffset(appresPtr, textoutline), XtRBoolean, (caddr_t) & false},
  140.     {"userscale", "UserScale", XtRFloat, sizeof(float),
  141.     XtOffset(appresPtr, user_scale), XtRFloat, (caddr_t) & one},
  142.     {"userunit", "UserUnit", XtRString, sizeof(char *),
  143.     XtOffset(appresPtr, user_unit), XtRString, (caddr_t) ""},
  144. };
  145.  
  146. static XrmOptionDescRec options[] =
  147. {
  148.     {"-iconGeometry", ".iconGeometry", XrmoptionSepArg, (caddr_t) NULL},
  149.     {"-showallbuttons", ".showallbuttons", XrmoptionNoArg, "True"},
  150.     {"-right", ".justify", XrmoptionNoArg, "True"},
  151.     {"-left", ".justify", XrmoptionNoArg, "False"},
  152.     {"-debug", ".debug", XrmoptionNoArg, "True"},
  153.     {"-landscape", ".landscape", XrmoptionNoArg, "True"},
  154.     {"-Landscape", ".landscape", XrmoptionNoArg, "True"},
  155.     {"-portrait", ".landscape", XrmoptionNoArg, "False"},
  156.     {"-Portrait", ".landscape", XrmoptionNoArg, "False"},
  157.     {"-pwidth", ".pwidth", XrmoptionSepArg, 0},
  158.     {"-pheight", ".pheight", XrmoptionSepArg, 0},
  159.     {"-inverse", ".reverseVideo", XrmoptionNoArg, "True"},
  160.     {"-notrack", ".trackCursor", XrmoptionNoArg, "False"},
  161.     {"-track", ".trackCursor", XrmoptionNoArg, "True"},
  162.     {"-inches", ".inches", XrmoptionNoArg, "True"},
  163.     {"-imperial", ".inches", XrmoptionNoArg, "True"},
  164.     {"-centimeters", ".inches", XrmoptionNoArg, "False"},
  165.     {"-metric", ".inches", XrmoptionNoArg, "False"},
  166.     {"-boldFont", ".boldFont", XrmoptionSepArg, 0},
  167.     {"-normalFont", ".normalFont", XrmoptionSepArg, 0},
  168.     {"-buttonFont", ".buttonFont", XrmoptionSepArg, 0},
  169.     {"-startpsFont", ".startpsFont", XrmoptionSepArg, 0},
  170.     {"-startlatexFont", ".startlatexFont", XrmoptionSepArg, 0},
  171.     {"-startFontSize", ".startfontsize", XrmoptionSepArg, 0},
  172.     {"-startfontsize", ".startfontsize", XrmoptionSepArg, 0},
  173.     {"-latexfonts", ".latexfonts", XrmoptionNoArg, "True"},
  174.     {"-specialtext", ".specialtext", XrmoptionNoArg, "True"},
  175.     {"-scalablefonts", ".scalablefonts", XrmoptionNoArg, "True"},
  176.     {"-noscalablefonts", ".scalablefonts", XrmoptionNoArg, "False"},
  177.     {"-monochrome", ".monochrome", XrmoptionNoArg, "True"},
  178.     {"-internalBW", ".internalborderwidth", XrmoptionSepArg, 0},
  179.     {"-internalBorderWidth", ".internalborderwidth", XrmoptionSepArg, 0},
  180.     {"-keyFile", ".keyFile", XrmoptionSepArg, 0},
  181.     {"-exportLanguage", ".exportLanguage", XrmoptionSepArg, 0},
  182.     {"-flushleft", ".flushleft", XrmoptionNoArg, "True"},
  183.     {"-textoutline", ".textoutline", XrmoptionNoArg, "True"},
  184.     {"-userscale", ".userscale", XrmoptionSepArg, 0},
  185.     {"-userunit", ".userunit", XrmoptionSepArg, 0},
  186. };
  187.  
  188. Atom wm_delete_window;
  189.  
  190. static XtCallbackRec callbacks[] =
  191. {
  192.     {NULL, NULL},
  193. };
  194.  
  195. static Arg    form_args[] =
  196. {
  197.     {XtNcallback, (XtArgVal) callbacks},
  198.     {XtNinput, (XtArgVal) True},
  199.     {XtNdefaultDistance, (XtArgVal) 0},
  200.     {XtNresizable, (XtArgVal) False},
  201. };
  202.  
  203. static void    check_for_resize();
  204. static void    check_colors();
  205. XtActionsRec    form_actions[] =
  206. {
  207.     {"ResizeForm", (XtActionProc) check_for_resize},
  208.     {"Quit", (XtActionProc) my_quit},
  209. };
  210.  
  211. extern void clear_text_key();
  212. extern void paste_panel_key();
  213. static XtActionsRec text_panel_actions[] =
  214. {
  215.     {"PastePanelKey", (XtActionProc) paste_panel_key} ,
  216.     {"EmptyTextKey", (XtActionProc) clear_text_key} ,
  217. };
  218.  
  219. static String    form_translations =
  220.             "<ConfigureNotify>:ResizeForm()\n";
  221. static String    tool_translations =
  222.             "<Message>WM_PROTOCOLS:Quit()\n";
  223.  
  224. #define NCHILDREN    9
  225. static TOOL    form;
  226.  
  227. main(argc, argv)
  228.     int            argc;
  229.     char       *argv[];
  230.  
  231. {
  232.     TOOL        children[NCHILDREN];
  233.     int            ichild;
  234.     int            init_canv_wd, init_canv_ht;
  235.     XWMHints       *wmhints;
  236.     char        i;
  237.     char       *userhome;
  238.     Dimension        w, h;
  239.  
  240.     DeclareArgs(5);
  241.  
  242.     /* we are not writing the figure to the bitmap */
  243.     writing_bitmap = False;
  244.  
  245.     /* get the TMPDIR environment variable for temporary files */
  246.     if ((TMPDIR = getenv("XFIGTMPDIR"))==NULL)
  247.     TMPDIR = "/tmp";
  248.  
  249.     (void) sprintf(tool_name, " XFIG %s(.%s) (Protocol %s)",
  250.            FIG_VERSION, PATCHLEVEL, PROTOCOL_VERSION);
  251.     (void) strcat(file_header, PROTOCOL_VERSION);
  252.     tool = XtAppInitialize(&tool_app, (String) "Fig", (XrmOptionDescList) options,
  253.                (Cardinal) XtNumber(options),
  254. #if XtSpecificationRelease < 5
  255.                (Cardinal *) & argc,
  256.                (String *) argv,
  257. #else
  258.                &argc,
  259.                argv,
  260. #endif
  261.                (String *) NULL,
  262. #if XtSpecificationRelease < 5
  263.                (String *) NULL, 
  264. #else
  265.                (ArgList) NULL,
  266. #endif
  267.                (Cardinal) 0);
  268.  
  269.  
  270.     /* install actions to get to the functions with accelerators */
  271.     XtAppAddActions(tool_app, main_actions, XtNumber(main_actions));
  272.  
  273.     fix_converters();
  274.     XtGetApplicationResources(tool, &appres, application_resources,
  275.                   XtNumber(application_resources), NULL, 0);
  276.  
  277.     i = 1;
  278.     while (argc-- > 1) {
  279.     if (*argv[i] != '-') {    /* search for non - name */
  280.         filename = argv[i];
  281.         break;
  282.     }
  283.     i++;
  284.     }
  285.  
  286.     tool_d = XtDisplay(tool);
  287.     tool_s = XtScreen(tool);
  288.     tool_sn = DefaultScreen(tool_d);
  289.  
  290.     if (appres.iconGeometry != (char *) 0) {
  291.         int scr, x, y, junk;
  292.         Arg args[2];
  293.  
  294.         for(scr = 0;
  295.             tool_s != ScreenOfDisplay(tool_d, scr);
  296.             scr++);
  297.  
  298.         XGeometry(tool_d, scr, appres.iconGeometry,
  299.                   "", 0, 0, 0, 0, 0, &x, &y, &junk, &junk);
  300.         XtSetArg(args[0], XtNiconX, x);
  301.         XtSetArg(args[1], XtNiconY, y);
  302.         XtSetValues(tool, args, XtNumber(args));
  303.     }
  304.  
  305.     print_flushleft = export_flushleft = appres.flushleft;    /* set both resources */
  306.     print_landscape = appres.landscape; /* match print and screen format to start */
  307.  
  308.     /* turn off PSFONT_TEXT flag if user specified -latexfonts */
  309.     if (appres.latexfonts)
  310.     cur_textflags = cur_textflags & (~PSFONT_TEXT);
  311.     if (appres.specialtext)
  312.     cur_textflags = cur_textflags | SPECIAL_TEXT;
  313.  
  314.     /* turn off PSFONT_TEXT flag if user specified -latexfonts */
  315.     if (appres.latexfonts)
  316.     cur_textflags = cur_textflags & (~PSFONT_TEXT);
  317.  
  318.     if (appres.user_unit)
  319.     strncpy(cur_fig_units, appres.user_unit, sizeof(cur_fig_units));
  320.     else
  321.     cur_fig_units[0] = '\0';
  322.  
  323.     if (CellsOfScreen(tool_s) == 2 && appres.INVERSE) {
  324.     XrmValue    value;
  325.     XrmDatabase    newdb = (XrmDatabase) 0, old;
  326.  
  327.     value.size = sizeof("White");
  328.     value.addr = "White";
  329.     XrmPutResource(&newdb, "xfig*borderColor", "String",
  330.                &value);
  331.     value.size = sizeof("White");
  332.     value.addr = "White";
  333.     XrmPutResource(&newdb, "xfig*foreground", "String",
  334.                &value);
  335.     value.size = sizeof("Black");
  336.     value.addr = "Black";
  337.     XrmPutResource(&newdb, "xfig*background", "String",
  338.                &value);
  339.     old = XtDatabase(tool_d);
  340.     XrmMergeDatabases(newdb, &old);
  341.  
  342.     /* now set the tool part, since its already created */
  343.     FirstArg(XtNborderColor, WhitePixelOfScreen(tool_s));
  344.     NextArg(XtNforeground, WhitePixelOfScreen(tool_s));
  345.     NextArg(XtNbackground, BlackPixelOfScreen(tool_s));
  346.     SetValues(tool);
  347.     }
  348.     init_font();
  349.  
  350.     gc = DefaultGC(tool_d, tool_sn);
  351.     bold_gc = DefaultGC(tool_d, tool_sn);
  352.     button_gc = DefaultGC(tool_d, tool_sn);
  353.  
  354.     /* set the roman and bold fonts for the message windows */
  355.     XSetFont(tool_d, gc, roman_font->fid);
  356.     XSetFont(tool_d, bold_gc, bold_font->fid);
  357.     XSetFont(tool_d, button_gc, button_font->fid);
  358.  
  359.     /*
  360.      * check if the NUMCOLORS drawing colors could be allocated and have
  361.      * different palette entries
  362.      */
  363.     check_colors();
  364.  
  365.     init_cursor();
  366.     form = XtCreateManagedWidget("form", formWidgetClass, tool,
  367.                  form_args, XtNumber(form_args));
  368.  
  369.     if (cur_fontsize == 0)
  370.     cur_fontsize = (int) appres.startfontsize;
  371.     if (cur_fontsize == 0)
  372.     cur_fontsize = DEF_FONTSIZE;
  373.  
  374.     if (cur_latex_font == 0)
  375.     cur_latex_font = latexfontnum (appres.startlatexFont);
  376.  
  377.     if (cur_ps_font == 0)
  378.     cur_ps_font = psfontnum (appres.startpsFont);
  379.  
  380.     if (INTERNAL_BW == 0)
  381.     INTERNAL_BW = (int) appres.internalborderwidth;
  382.     if (INTERNAL_BW <= 0)
  383.     INTERNAL_BW = DEF_INTERNAL_BW;
  384.  
  385.     SW_PER_ROW = SW_PER_ROW_PORT;
  386.     SW_PER_COL = SW_PER_COL_PORT;
  387.     init_canv_wd = appres.tmp_width *
  388.     (appres.INCHES ? PIX_PER_INCH : PIX_PER_CM);
  389.     init_canv_ht = appres.tmp_height *
  390.     (appres.INCHES ? PIX_PER_INCH : PIX_PER_CM);
  391.  
  392.     if (init_canv_wd == 0)
  393.     init_canv_wd = appres.landscape ? DEF_CANVAS_WD_LAND :
  394.         DEF_CANVAS_WD_PORT;
  395.  
  396.     if (init_canv_ht == 0)
  397.     init_canv_ht = appres.landscape ? DEF_CANVAS_HT_LAND :
  398.         DEF_CANVAS_HT_PORT;
  399.  
  400.     if ((init_canv_ht < DEF_CANVAS_HT_PORT) ||
  401.     (HeightOfScreen(tool_s) < DEF_CANVAS_HT_PORT)) {
  402.     SW_PER_ROW = SW_PER_ROW_LAND;
  403.     SW_PER_COL = SW_PER_COL_LAND;
  404.     }
  405.     setup_sizes(init_canv_wd, init_canv_ht);
  406.     (void) init_cmd_panel(form);
  407.     (void) init_msg(form,filename);
  408.     (void) init_mousefun(form);
  409.     (void) init_mode_panel(form);
  410.     (void) init_topruler(form);
  411.     (void) init_canvas(form);
  412.     (void) init_fontmenu(form); /* printer font menu */
  413.     (void) init_unitbox(form);
  414.     (void) init_sideruler(form);
  415.     (void) init_ind_panel(form);
  416.  
  417.     ichild = 0;
  418.     children[ichild++] = cmd_panel;    /* command buttons */
  419.     children[ichild++] = mousefun;    /* labels for mouse fns */
  420.     children[ichild++] = msg_form;    /* message window form */
  421.     children[ichild++] = mode_panel;    /* current mode */
  422.     children[ichild++] = topruler_sw;    /* top ruler */
  423.     children[ichild++] = unitbox_sw;    /* box containing units */
  424.     children[ichild++] = sideruler_sw;    /* side ruler */
  425.     children[ichild++] = canvas_sw;    /* main drawing canvas */
  426.     children[ichild++] = ind_viewp;    /* current settings indicators */
  427.  
  428.     /*
  429.      * until the following XtRealizeWidget() is called, there are NO windows
  430.      * in existence
  431.      */
  432.  
  433.     XtManageChildren(children, NCHILDREN);
  434.     XtRealizeWidget(tool);
  435.  
  436.     wm_delete_window = XInternAtom(XtDisplay(tool), "WM_DELETE_WINDOW", False);
  437.     (void) XSetWMProtocols(XtDisplay(tool), XtWindow(tool),
  438.                &wm_delete_window, 1);
  439.  
  440.     fig_icon = XCreateBitmapFromData(tool_d, XtWindow(tool),
  441.                      (char *) fig_bits, fig_width, fig_height);
  442.  
  443.     FirstArg(XtNtitle, tool_name);
  444.     NextArg(XtNiconPixmap, fig_icon);
  445.     SetValues(tool);
  446.     /* Set the input field to true to allow keyboard input */
  447.     wmhints = XGetWMHints(tool_d, XtWindow(tool));
  448.     wmhints->flags |= InputHint;/* add in input hint */
  449.     wmhints->input = True;
  450.     XSetWMHints(tool_d, XtWindow(tool), wmhints);
  451.     XFree((char *) wmhints);
  452.  
  453.     if (appres.RHS_PANEL) {    /* side button panel is on right size */
  454.     FirstArg(XtNfromHoriz, 0);
  455.     NextArg(XtNhorizDistance, SIDERULER_WD + INTERNAL_BW);
  456.     SetValues(topruler_sw);
  457.  
  458.     FirstArg(XtNfromHoriz, 0);
  459.     NextArg(XtNhorizDistance, 0);
  460.     NextArg(XtNfromVert, topruler_sw);
  461.     NextArg(XtNleft, XtChainLeft);    /* chain to left of form */
  462.     NextArg(XtNright, XtChainLeft);
  463.     SetValues(sideruler_sw);
  464.  
  465.     FirstArg(XtNfromHoriz, 0);
  466.     NextArg(XtNhorizDistance, 0);
  467.     NextArg(XtNfromVert, msg_form);
  468.     NextArg(XtNleft, XtChainLeft);    /* chain to left of form */
  469.     NextArg(XtNright, XtChainLeft);
  470.     SetValues(unitbox_sw);
  471.  
  472.     /* relocate the side button panel */
  473.     XtUnmanageChild(mode_panel);
  474.     XtUnmanageChild(canvas_sw);
  475.     FirstArg(XtNfromHoriz, canvas_sw);    /* panel right of canvas */
  476.     NextArg(XtNhorizDistance, -INTERNAL_BW);
  477.     NextArg(XtNfromVert, mousefun);
  478.     NextArg(XtNleft, XtChainRight);
  479.     NextArg(XtNright, XtChainRight);
  480.     SetValues(mode_panel);
  481.     FirstArg(XtNfromHoriz, sideruler_sw);    /* panel right of canvas */
  482.     SetValues(canvas_sw);
  483.     XtManageChild(canvas_sw);
  484.     XtManageChild(mode_panel);
  485.     }
  486.  
  487.     init_gc();
  488.     setup_cmd_panel();
  489.     setup_msg();
  490.     setup_canvas();
  491.     setup_rulers();
  492.     setup_mode_panel();
  493.     setup_mousefun();
  494.     setup_fontmenu();        /* setup bitmaps in printer font menu */
  495.     setup_ind_panel();
  496.     get_directory(cur_dir);
  497.  
  498.     /* parse the export language resource */
  499.     for (i=0; i<NUM_EXP_LANG; i++)
  500.     if (strcmp(appres.exportLanguage, lang_items[i])==0)
  501.         break;
  502.     /* found it set the language number */
  503.     if (i < NUM_EXP_LANG)
  504.     cur_exp_lang = i;
  505.     else
  506.     file_msg("Unknown export language: %s, using default: %s",
  507.         appres.exportLanguage, lang_items[cur_exp_lang]);
  508.  
  509.     /* install the accelerators - cmd_panel, ind_panel and mode_panel
  510.     accelerators are installed in their respective setup_xxx procedures */
  511.     XtInstallAllAccelerators(canvas_sw, tool);
  512.     XtInstallAllAccelerators(mousefun, tool);
  513.     XtInstallAllAccelerators(msg_form, tool);
  514.     XtInstallAllAccelerators(topruler_sw, tool);
  515.     XtInstallAllAccelerators(sideruler_sw, tool);
  516.     XtInstallAllAccelerators(unitbox_sw, tool);
  517.  
  518.     FirstArg(XtNwidth, &w);
  519.     NextArg(XtNheight, &h);
  520.     GetValues(tool);
  521.     TOOL_WD = (int) w;
  522.     TOOL_HT = (int) h;
  523.     XtAppAddActions(tool_app, form_actions, XtNumber(form_actions));
  524.     XtAppAddActions(tool_app, text_panel_actions, XtNumber(text_panel_actions));
  525.     XtOverrideTranslations(tool, XtParseTranslationTable(tool_translations));
  526.     XtOverrideTranslations(form, XtParseTranslationTable(form_translations));
  527.  
  528.     XSetErrorHandler(X_error_handler);
  529.     XSetIOErrorHandler((XIOErrorHandler) X_error_handler);
  530.     (void) signal(SIGHUP, error_handler);
  531.     (void) signal(SIGFPE, error_handler);
  532. #ifndef NO_SIBGUS
  533.     (void) signal(SIGBUS, error_handler);
  534. #endif
  535.     (void) signal(SIGSEGV, error_handler);
  536.     (void) signal(SIGINT, SIG_IGN);    /* in case user accidentally types
  537.                      * ctrl-c */
  538.  
  539.     put_msg("READY, please select a mode or load a file");
  540.  
  541.     /*
  542.      * decide on filename for cut buffer: first try users HOME directory to
  543.      * allow cutting and pasting between sessions, if this fails create
  544.      * unique filename in /tmp dir
  545.      */
  546.  
  547.     userhome = getenv("HOME");
  548.     if (userhome != NULL && *strcpy(cut_buf_name, userhome) != '\0') {
  549.     strcat(cut_buf_name, "/.xfig");
  550.     } else {
  551.     sprintf(cut_buf_name, "%s%06d", "/tmp/xfig", getpid());
  552.     }
  553.  
  554.     if (filename == NULL)
  555.     strcpy(cur_filename, DEF_NAME);
  556.     else
  557.     load_file(filename);
  558.     update_cur_filename(cur_filename);
  559.  
  560.     app_flush();
  561.  
  562.     XtAppMainLoop(tool_app);
  563. }
  564.  
  565. static void
  566. check_for_resize(tool, event, params, nparams)
  567.     TOOL        tool;
  568.     XButtonEvent   *event;
  569.     String       *params;
  570.     Cardinal       *nparams;
  571. {
  572.     XConfigureEvent *xc = (XConfigureEvent *) event;
  573.     Dimension        b;
  574.     int            dx, dy;
  575.  
  576.     DeclareArgs(3);
  577.  
  578.     if (xc->width == TOOL_WD && xc->height == TOOL_HT)
  579.     return;            /* no size change */
  580.     dx = xc->width - TOOL_WD;
  581.     dy = xc->height - TOOL_HT;
  582.     TOOL_WD = xc->width;
  583.     TOOL_HT = xc->height;
  584.     setup_sizes(CANVAS_WD + dx, CANVAS_HT + dy);
  585.  
  586.     XawFormDoLayout(form, False);
  587.     ignore_exp_cnt++;        /* canvas is resized twice - redraw only once */
  588.  
  589.     FirstArg(XtNborderWidth, &b);
  590.     /* first redo the top panels */
  591.     GetValues(cmd_panel);
  592.     XtResizeWidget(cmd_panel, CMDPANEL_WD, CMDPANEL_HT, b);
  593.     GetValues(mousefun);
  594.     XtResizeWidget(mousefun, MOUSEFUN_WD, MOUSEFUN_HT, b);
  595.     XtUnmanageChild(mousefun);
  596.     resize_mousefun();
  597.     XtManageChild(mousefun);    /* so that it shifts with msg_panel */
  598.     /* resize the message form by setting the current filename */
  599.     update_cur_filename(cur_filename);
  600.  
  601.     /* now redo the center area */
  602.     XtUnmanageChild(mode_panel);
  603.     FirstArg(XtNheight, (MODEPANEL_SPACE + 1) / 2);
  604.     SetValues(d_label);
  605.     FirstArg(XtNheight, (MODEPANEL_SPACE) / 2);
  606.     SetValues(e_label);
  607.     XtManageChild(mode_panel);    /* so that it adjusts properly */
  608.  
  609.     FirstArg(XtNborderWidth, &b);
  610.     GetValues(canvas_sw);
  611.     XtResizeWidget(canvas_sw, CANVAS_WD, CANVAS_HT, b);
  612.     GetValues(topruler_sw);
  613.     XtResizeWidget(topruler_sw, TOPRULER_WD, TOPRULER_HT, b);
  614.     resize_topruler();
  615.     GetValues(sideruler_sw);
  616.     XtResizeWidget(sideruler_sw, SIDERULER_WD, SIDERULER_HT, b);
  617.     resize_sideruler();
  618.     XtUnmanageChild(sideruler_sw);
  619.     XtManageChild(sideruler_sw);/* so that it shifts with canvas */
  620.     XtUnmanageChild(unitbox_sw);
  621.     XtManageChild(unitbox_sw);    /* so that it shifts with canvas */
  622.  
  623.     XawFormDoLayout(form, True);
  624. }
  625.  
  626.  
  627. static void
  628. check_colors()
  629. {
  630.     int            i, j;
  631.  
  632.     /* if monochrome resource is set, do not even check for colors */
  633.     if (appres.monochrome) {
  634.     all_colors_available = false;
  635.     return;
  636.     }
  637.     all_colors_available = true;
  638.  
  639.     /* check if the drawing colors have different palette entries */
  640.     for (i = 0; i < NUMCOLORS - 1; i++) {
  641.     for (j = i + 1; j < NUMCOLORS; j++) {
  642.         if (appres.color[i] == appres.color[j]) {
  643.         all_colors_available = false;
  644.         break;
  645.         }
  646.     }
  647.     if (!all_colors_available)
  648.         break;
  649.     }
  650. }
  651.  
  652. /* useful when using ups */
  653. XSyncOn()
  654. {
  655.     XSynchronize(tool_d, True);
  656.     XFlush(tool_d);
  657. }
  658.  
  659. XSyncOff()
  660. {
  661.     XSynchronize(tool_d, False);
  662.     XFlush(tool_d);
  663. }
  664.  
  665. #ifdef NOSTRSTR
  666.  
  667. char *strstr(s1, s2)
  668.     char *s1, *s2;
  669. {
  670.     int len2;
  671.     char *stmp;
  672.  
  673.     len2 = strlen(s2);
  674.     for (stmp = s1; *stmp != NULL; stmp++)
  675.     if (strncmp(stmp, s2, len2)==0)
  676.         return stmp;
  677.     return NULL;
  678. }
  679. #endif
  680.  
  681. #ifdef NOSTRTOL
  682. /*-
  683.  * Copyright (c) 1990 The Regents of the University of California.
  684.  * All rights reserved.
  685.  *
  686.  * Redistribution and use in source and binary forms are permitted
  687.  * provided that: (1) source distributions retain this entire copyright
  688.  * notice and comment, and (2) distributions including binaries display
  689.  * the following acknowledgement:  ``This product includes software
  690.  * developed by the University of California, Berkeley and its contributors''
  691.  * in the documentation or other materials provided with the distribution
  692.  * and in all advertising materials mentioning features or use of this
  693.  * software. Neither the name of the University nor the names of its
  694.  * contributors may be used to endorse or promote products derived
  695.  * from this software without specific prior written permission.
  696.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  697.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  698.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  699.  */
  700.  
  701. #if defined(LIBC_SCCS) && !defined(lint)
  702. static char sccsid[] = "@(#)strtol.c    5.3 (Berkeley) 5/17/90";
  703. #endif /* LIBC_SCCS and not lint */
  704.  
  705. #include <ctype.h>
  706. #include <errno.h>
  707.  
  708. #define    ULONG_MAX    0xffffffff    /* max value for an unsigned long */
  709. #define    LONG_MAX    0x7fffffff    /* max value for a long */
  710. #define    LONG_MIN    0x80000000    /* min value for a long */
  711.  
  712. /*
  713.  * Convert a string to a long integer.
  714.  *
  715.  * Ignores `locale' stuff.  Assumes that the upper and lower case
  716.  * alphabets and digits are each contiguous.
  717.  */
  718. long
  719. strtol(nptr, endptr, base)
  720.     char *nptr, **endptr;
  721.     register int base;
  722. {
  723.     register char *s = nptr;
  724.     register unsigned long acc;
  725.     register int c;
  726.     register unsigned long cutoff;
  727.     register int neg = 0, any, cutlim;
  728.  
  729.     /*
  730.      * Skip white space and pick up leading +/- sign if any.
  731.      * If base is 0, allow 0x for hex and 0 for octal, else
  732.      * assume decimal; if base is already 16, allow 0x.
  733.      */
  734.     do {
  735.         c = *s++;
  736.     } while (isspace(c));
  737.     if (c == '-') {
  738.         neg = 1;
  739.         c = *s++;
  740.     } else if (c == '+')
  741.         c = *s++;
  742.     if ((base == 0 || base == 16) &&
  743.         c == '0' && (*s == 'x' || *s == 'X')) {
  744.         c = s[1];
  745.         s += 2;
  746.         base = 16;
  747.     }
  748.     if (base == 0)
  749.         base = c == '0' ? 8 : 10;
  750.  
  751.     /*
  752.      * Compute the cutoff value between legal numbers and illegal
  753.      * numbers.  That is the largest legal value, divided by the
  754.      * base.  An input number that is greater than this value, if
  755.      * followed by a legal input character, is too big.  One that
  756.      * is equal to this value may be valid or not; the limit
  757.      * between valid and invalid numbers is then based on the last
  758.      * digit.  For instance, if the range for longs is
  759.      * [-2147483648..2147483647] and the input base is 10,
  760.      * cutoff will be set to 214748364 and cutlim to either
  761.      * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
  762.      * a value > 214748364, or equal but the next digit is > 7 (or 8),
  763.      * the number is too big, and we will return a range error.
  764.      *
  765.      * Set any if any `digits' consumed; make it negative to indicate
  766.      * overflow.
  767.      */
  768.     cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
  769.     cutlim = cutoff % (unsigned long)base;
  770.     cutoff /= (unsigned long)base;
  771.     for (acc = 0, any = 0; c = *s++) {
  772.         if (isdigit(c))
  773.             c -= '0';
  774.         else if (isalpha(c))
  775.             c -= isupper(c) ? 'A' - 10 : 'a' - 10;
  776.         else
  777.             break;
  778.         if (c >= base)
  779.             break;
  780.         if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
  781.             any = -1;
  782.         else {
  783.             any = 1;
  784.             acc *= base;
  785.             acc += c;
  786.         }
  787.     }
  788.     if (any < 0) {
  789.         acc = neg ? LONG_MIN : LONG_MAX;
  790.         errno = ERANGE;
  791.     } else if (neg)
  792.         acc = -acc;
  793.     if (endptr != 0)
  794.         *endptr = any ? s - 1 : nptr;
  795.     return (acc);
  796. }
  797. #endif
  798.