home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 126-150 / scopedisk138 / ruler / arpruler4.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-19  |  14.5 KB  |  453 lines

  1. /*     RULER
  2.  *
  3.  *      Opens a borderless WorkBench window in which is contained a ruler
  4.  *      for the purpose of aligning or constraining text; the default ruler
  5.  *      is 30 characters with an 8 pixel scale and is intended to help
  6.  *      prevent entering too-long filenames.
  7.  *      
  8.  *      Usage:
  9.  *      
  10.  *             CLI> RUN  RULER  [ size ] [ scale ]
  11.  *      
  12.  *      where `size' is the number of ruler markings, and `scale' is the
  13.  *      width between each marking (a particular font width for example).
  14.  *      
  15.  *     Evoking the command with an argument of "?", such as:
  16.  *
  17.  *             CLI> RULER ?
  18.  *
  19.  *     will print out a help message detailing what values are valid for
  20.  *     your particular Workbench environment.
  21.  *      
  22.  *
  23.  *     The window, of course, can be moved to any convenient location on the
  24.  *     screen, and resized with an invisible resizing gadget found in the
  25.  *     lower right corner.
  26.  *
  27.  *     Version 4.0   29-Dec-1989  (copyright)1989  Chad Netzer and Thad Floryan
  28.  *
  29.  *             Based upon code, idea, and logic from:
  30.  *
  31.  *     Version 1.0   7-Nov-1988   (copyright)1988 Thad Floryan
  32.  *
  33.  *     Revision history:
  34.  *         29-December-1989 - (Ver. 4.0) - Added an offset so that you can
  35.  *             just stick the window on the left edge of the workbench screen,
  36.  *             and it will automatically be lined up with the characters.
  37.  *             Fixed some more minor bugs and rearranged the code a bit.
  38.  *             Added ARP support for those who want it. (CFN)
  39.  *
  40.  *         09-March-1989 - (Ver. 3.1) - Fixed a visual bug so that scale can
  41.  *             no longer be less than eight. (CFN)
  42.  *
  43.  *         06-Dec-1988 - (Ver. 3.0) - Added support for measuring fonts of
  44.  *             varying widths (selectable scale). (CFN)
  45.  *
  46.  *         22-Nov-1988 - (Ver. 2.2) - More adjustments to code, No major
  47.  *             changes.  Program size is slightly smaller.  (CFN)
  48.  *
  49.  *         14-Nov-1988 - (Ver. 2.1) - Fixed a few minor (harmless) bugs.  The
  50.  *             right edge of the ruler is now always redrawn after resizing.
  51.  *             I got rid of that GOTO statement (which in 'C', is considered a
  52.  *             bug. :-)  Version 2.1 now lets you open a ruler to be as low as
  53.  *             12 characters wide, which 2.0 only advertised. (CFN)
  54.  *
  55.  *         13-Nov-1988 - (Ver. 2.0) - I added minor enhancements, most
  56.  *             noteably, the ability to resize the window, and support for 
  57.  *             overscanned screens.    (CFN)
  58.  *
  59.  *
  60.  *     Feel welcome to use this program for any non-commercial purposes or
  61.  *     for your personal learning.  Commercial users are requested to contact
  62.  *     Thad at either:
  63.  *
  64.  *     UUCP:   thad@cup.portal.com (OR) ..!sun!portal!cup.portal.com!thad
  65.  *     BBS:    BBS-JC, 415/961-7250 (300/1200/2400), "Thad Floryan" | "SYSOP"
  66.  *
  67.  *     or Chad at:
  68.  *
  69.  *     UUCP:   chad@ucscb.ucsc.edu     (during school term)
  70.  *     UUCP:   chad@cup.portal.com     (holidays, summer, etc.)
  71.  *     BBS:    BBS-JC, 415/961-7250 (300/1200/2400), "Chad Netzer"
  72.  *
  73.  *
  74.  *     Building instructions (Manx Aztec C):
  75.  *
  76.  *                     *******************
  77.  *                     *** ARP Version ***
  78.  *                     *******************
  79.  *
  80.  *                     cc arpruler4
  81.  *                     ln arpruler4 -la -lc
  82.  */
  83.  
  84. #include <exec/types.h>
  85. #include <exec/memory.h>
  86. #include <libraries/arpbase.h>
  87. #include <intuition/intuition.h>
  88. #include <intuition/intuitionbase.h>
  89. #include "arpfunctions.h"
  90.  
  91. #define NEW(typ)               AllocMem((ULONG)sizeof(typ), MEMF_CLEAR)
  92. #define FREE(p,typ)            FreeMem(p,(ULONG)sizeof(typ))
  93.  
  94. #define        ever (;;)       /* used for infinite loops */
  95.  
  96. #define FATAL 20       /* exit code */
  97. #define WARN  10       /* exit code */
  98. #define NORMAL 0       /* exit code */
  99.  
  100. #define LEFT_OFFSET 3L /* "dead space" on left side of ruler margin */
  101.  
  102. extern void    *OpenLibrary();
  103. extern void    *OpenWindow();
  104. extern void    *GetMsg();
  105. extern void    *AllocMem();
  106. extern void    ReplyMsg();
  107. void           release_resources();
  108. void           error_exit();
  109.  
  110. struct NewWindow window_def =
  111. {
  112.        240, 0,                 /* Initial LeftEdge, TopEdge */
  113.        241, 25,                /* Default pixel-width, pixel-height */
  114.        0, 1,                   /* DetailPen, BlockPen */
  115.        CLOSEWINDOW     |       /* IDCMP flags */
  116.        NEWSIZE,
  117.        WINDOWDRAG      |       /* window flags */
  118.        WINDOWDEPTH     |
  119.        WINDOWCLOSE     |
  120.        WINDOWSIZING    |
  121.        SMART_REFRESH   |
  122.        NOCAREREFRESH   |
  123.        BORDERLESS      |
  124.        RMBTRAP,
  125.        NULL,                   /* Gadget list */
  126.        NULL,                   /* checkmark stuff */
  127.        (UBYTE *)"",            /* window title (to be filled in later) */
  128.        NULL,                   /* custom screen pointer */
  129.        NULL,                   /* bitmap pointer */
  130.        97 + LEFT_OFFSET, 0,    /* Minwidth, no MinHeight */
  131.        -1, 0,                  /* no MaxWidth, MaxHeight */
  132.        WBENCHSCREEN            /* screen type */
  133. };
  134.  
  135. struct Window          *window;
  136. struct RastPort        *rp;
  137. struct ArpBase         *ArpBase;
  138. struct Library         *IntuitionBase;
  139. struct Library         *GfxBase;
  140. struct Screen          *screen;
  141. struct IntuiMessage    *sys_message;
  142. ULONG                  class;
  143. int                    resource_state;
  144.  
  145. char *version = 
  146.        "Text Ruler  Arp_V4.0   29-Dec-89 \xA91989 Thad Floryan and Chad Netzer"
  147.        "                              "; /* padding for "nice" title */
  148.  
  149. char *help_text =                              /* help message on startup */
  150.        "\n"
  151.        "%40s\n"
  152.        "Opens a borderless WorkBench window in which is contained a ruler\n"
  153.        "for the purpose of aligning or constraining text; the default ruler\n"
  154.        "is 30 characters with an 8 pixel scale and is intended to help\n"
  155.        "prevent entering too-long filenames.\n\n"
  156.        "Usage:\n\n\t"
  157.        "CLI> RUN  %s  [ size ] [ scale ]\n\n"
  158.        "where `size' is the number of ruler markings, and `scale' is the\n"
  159.        "width between each marking (a particular font width for example).\n\n"
  160.        "`size' must be between 12 and %ld inclusive, and defaults to 30.\n"
  161.        "`scale' cannot be greater than %ld or less than 8.  The default is 8."
  162.        "\n\n";
  163.  
  164. /**********************************************************************/
  165.  
  166. main (argc, argv)
  167.        int     argc;
  168.        char    *argv[];
  169. {
  170.  
  171.        long    fivec;          /* pixel size of five chars     */
  172.        long    fsize;          /* The font size of ruler scale */
  173.        long    max_scale;      /* The max scale size possible  */
  174.        long    max_width;      /* maximum size of ruler        */
  175.        long    w;              /* character width of ruler     */
  176.        long    w_lim;          /* pixel width (w * fsize)      */
  177.        long    x;              /* present window x coordinate  */
  178.        long    y;              /* present window y coordinate  */
  179.        char    buf[5];
  180.  
  181.        long    success;        /* indicates bad return values  */
  182.  
  183.        resource_state = 0;
  184.  
  185. /*
  186.  *     Open ARP_library, revision 39
  187.  */
  188.        ArpBase = OpenLibrary ("arp.library", ArpVersion);
  189.        if (ArpBase == 0L)
  190.        {
  191.            error_exit("?Cannot open arp.library\n");
  192.        }
  193.        ++resource_state;
  194.  
  195. /*
  196.  *     Get IntuitionBase from ArpBase so we can get the screen size limits.
  197.  */
  198.        IntuitionBase = ArpBase->IntuiBase;
  199.  
  200. /*
  201.  *     Get WorkBench screen information
  202.  */
  203.        screen = NEW(struct Screen);    /* Allocate a buffer for screen data */
  204.        if (screen == 0L)
  205.        {
  206.            release_resources();
  207.            error_exit("?ran out of available memory\n");
  208.        }
  209.        ++resource_state;
  210.        success = GetScreenData(screen, (ULONG) sizeof (struct Screen), 
  211.                                WBENCHSCREEN, 0L);
  212.        if (success == FALSE)
  213.        {
  214.            error_exit();
  215.        }
  216. /*
  217.  *     Set up defaults...
  218.  */
  219.        w = 30L;        /* default ruler is 30 chars for a filename */
  220.        fsize = 8L;     /* default font scale is 8 pixels per char  */
  221.  
  222. /*
  223.  *     find maximum values, adjusted for morerows
  224.  */
  225.        max_width = (screen->Width - LEFT_OFFSET) / 8;
  226.        max_scale = (screen->Width - 2) / 12;
  227.  
  228. /*
  229.  *     Parse command line to obtain requested parameters.
  230.  */
  231.        if (argc > 1)
  232.        {
  233.            if (*argv[1] == '?' ||
  234.                *argv[1] == '-' ||
  235.                *argv[1] == 'h' ||
  236.                *argv[1] == 'H'   )
  237.            {
  238.                Printf( help_text,
  239.                        version, argv[0], max_width, max_scale);
  240.  
  241.                release_resources();
  242.                exit (NORMAL);
  243.            }
  244.        }
  245.  
  246.        if (argc > 3)
  247.        {
  248.            Printf("?Too many arguments, ``%s ?'' for help\n", argv[0]);
  249.            release_resources();
  250.            exit (WARN);
  251.        }
  252.  
  253.        if ((argc >= 2) && (argc <= 3))
  254.        {
  255.            w = Atol(argv[1]);
  256.            if ( w < 12L  ||  w > max_width )
  257.            {
  258.                Printf("?`size' must be >= 12 and <= %ld\n", max_width);
  259.                release_resources();
  260.                exit (WARN);
  261.            }
  262.        }
  263.  
  264.        if (argc == 3)
  265.        { 
  266.            fsize = Atol(argv[2]);
  267.            if (fsize < 8)
  268.            {
  269.                Printf("?Font scale must be at least 8!\n");
  270.                release_resources();
  271.                exit (WARN);
  272.            }
  273.            if (fsize > max_scale)
  274.            {
  275.                Printf("?Font size can be NO larger than %ld!\n", max_scale);
  276.                release_resources();
  277.                exit (WARN);
  278.            }
  279.        }
  280.  
  281. /*
  282.  *     Now calculate window sizing and placement parameters and setup title.
  283.  */
  284.        w_lim               = w * fsize;
  285.        window_def.Width    = w_lim + LEFT_OFFSET + 1;
  286.        window_def.LeftEdge = (window_def.Width > 300L) ? 0 : 240;
  287.        window_def.Title    = (UBYTE *)version;
  288.        fivec               = 5L * fsize;
  289. /*
  290.  *     Bomb out if requested ruler size would be larger than the screen.
  291.  */
  292.        if (window_def.Width > screen -> Width )
  293.        {
  294.            error_exit("?Ruler too large for WorkBench screen\n");
  295.        }
  296.  
  297. /*
  298.  *     Set up GfxBase from ArpBase.
  299.  */
  300.        GfxBase = ArpBase->GfxBase;
  301.  
  302. /*
  303.  *     Open the ruler display window.
  304.  */
  305.        window = OpenWindow (&window_def);
  306.        if (window == 0L)
  307.        {
  308.            error_exit("?Cannot open window\n");
  309.        }
  310.        ++resource_state;
  311. /*
  312.  *     Get pointer to raster port.
  313.  */
  314.        rp = window -> RPort;
  315.        SetAPen (rp, 0L);
  316. /*
  317.  *     Use RectFill to blank the window area and set pen for drawing.
  318.  */
  319.        for ever
  320.        {
  321.            SetAPen(rp, 0L);
  322.            RectFill(rp, 0L, 10L, w_lim + LEFT_OFFSET, 24L);
  323. /*
  324.  *     Now set pen to draw.
  325.  */
  326.            SetAPen(rp, 1L);
  327. /*
  328.  *     Because we've used a BORDERLESS window, must fill in some of the
  329.  *     title-/drag-bar space near the lower left where the text starts.
  330.  */
  331.            Move(rp, 28L, 8L);
  332.            Draw(rp, 31L, 8L);
  333. /*
  334.  *     Because we've used a BORDERLESS window, must draw our own line beneath
  335.  *     the title bar to make the bar the same height as the window gadgets.
  336.  *     The `28' is the pixel position just to the right of the close gadget.
  337.  *     The `53' is the pixel width of the depth-arranging gadgets in the upper
  338.  *     right corner of the window.
  339.  */
  340.            Move(rp, 28L,           9L);
  341.            Draw(rp, (w_lim + LEFT_OFFSET - 53L), 9L);
  342.  
  343. /*
  344.  *     When I use the ruler, I like to jam it up against the left hand side of
  345.  *     my workbench screen, so that it to measure something on the CLI.
  346.  *     However, the CLI is offset by a small amount, so I compensate by
  347.  *     starting the "virtual" area of the ruler a little to the right...
  348.  *
  349.  *     Fill in the offset area that is unused.
  350.  */
  351.            RectFill(rp, 0L, 9L, LEFT_OFFSET, 24L);
  352.  
  353. /*
  354.  *     Shorten virtual ruler size by subtracting LEFT_OFFSET from w_lim.
  355.  */
  356. /*         w_lim -= LEFT_OFFSET;*/
  357.  
  358. /*
  359.  *     Draw ruler and text
  360.  */
  361.            for (x = 0L; x < (w_lim + fsize); x += fsize)
  362.            {
  363.                if (x >= w_lim)         /* right edge            */
  364.                    {
  365.                        x = w_lim;
  366.                        y = 10L;
  367.                    }
  368.                else if (x == 0L)          y = 10L;     /* left edge             */
  369.                else if ((x % fivec) == 0L)  y = 19L;   /* big tic every 5 chars */
  370.                else                       y = 22L;     /* small tic every char  */
  371.                Move (rp, x + LEFT_OFFSET, y);
  372.                Draw (rp, x + LEFT_OFFSET, 24L);
  373. /*
  374.  *     Label ruler.
  375.  *     The test for position `fivec' (in the Move()) is for centering ``5''
  376.  *     differently than the centering for two-digit numbers.
  377.  */
  378.                if ((x > 0L) && (x < w_lim) && ((x % fivec) == 0L))
  379.                {
  380.                    SPrintf (buf, "%2ld", (x / fsize));
  381.                    Move (rp, (x == fivec) ? (x - 12L + LEFT_OFFSET)
  382.                                           : (x -  8L + LEFT_OFFSET), 17L);
  383.                    Text (rp, buf, (long) strlen (buf));
  384.                }
  385.            }
  386. /*
  387.  *     Wait for gadget activation.  No busy-/spin-/wait-loops here!
  388.  */
  389.            Wait (1L << window -> UserPort -> mp_SigBit);
  390. /*
  391.  *     Retrieve LAST message in Message Port
  392.  */
  393.            sys_message = GetMsg(window -> UserPort);
  394.            class = sys_message -> Class;
  395.            ReplyMsg(sys_message);
  396. /*
  397.  *     Dump uneeded messages (respond only to the last on LIFO queue).
  398.  */
  399.            while (sys_message = GetMsg(window -> UserPort))
  400.            {
  401.                ReplyMsg(sys_message);
  402.            }
  403.  
  404.            if (class == CLOSEWINDOW)
  405.            {
  406.                release_resources();
  407.                exit (NORMAL);
  408.            }
  409.  
  410.            if (class == NEWSIZE)
  411.            {
  412.                w_lim = (window -> Width) - 1 - LEFT_OFFSET;
  413.            }
  414.        }
  415. }
  416.  
  417. /**********************************************************************
  418.  *
  419.  *     cleanup routine
  420.  *
  421.  *     The ``switch'' on resource_state is to assure we don't attempt to
  422.  *     free something we don't have.  Items are released in the reverse
  423.  *     order they were obtained (by "falling thru" the cases).
  424.  */
  425. void release_resources()
  426. {
  427.        switch (resource_state)
  428.        {
  429.            case 3: CloseWindow (window);
  430.            case 2: FREE (screen, struct Screen);
  431.            case 1: CloseLibrary(ArpBase);
  432.        }
  433. }
  434.  
  435. /**********************************************************************
  436.  *
  437.  *     error handler
  438.  */
  439. void error_exit(message)
  440.        char    *message;
  441. {
  442.        if (message == 0L)
  443.        {
  444.            Printf("Internal failure, exiting gracefully...\n");
  445.        }
  446.        else
  447.        {
  448.            Printf(message);
  449.        }
  450.        release_resources();
  451.        exit (FATAL);
  452. }
  453.