home *** CD-ROM | disk | FTP | other *** search
- /* RULER
- *
- * Opens a borderless WorkBench window in which is contained a ruler for
- * the purpose of aligning or constraining text; the default ruler is 30
- * characters intended to help prevent entering too-long filenames.
- *
- * Usage:
- *
- * CLI> RUN RULER [ size ] [ scale ]
- *
- * where "size" must be between 12 and your maximum screen columns
- * inclusive and defaults to 30, and "scale" is the size of the font to
- * enter, and is limited depending on the size of your screen.
- *
- * The window, of course, can be moved to any convenient location on the
- * screen, and resized with an invisible resizing gadget found in the
- * lower right corner.
- *
- * Version 3.0 06-Dec-1988 (c)1988 Chad Netzer and Thad Floryan
- *
- * Based upon code, idea, and logic from:
- *
- * Version 1.0 7-Nov-1988 (c)1988 Thad Floryan
- *
- * Revision history:
- * 06-Dec-1988 - (Ver. 3.0) - Added support for measuring fonts of
- * varying widths (selectable scale).
- *
- * 22-Nov-1988 - (Ver. 2.2) - More adjustments to code, No major
- * changes. Program size is slightly smaller. (CFN)
- *
- * 14-Nov-1988 - (Ver. 2.1) - Fixed a few minor (harmless) bugs. The
- * right edge of the ruler is now always redrawn after resizing.
- * I got rid of that GOTO statement (which in 'C', is considered a
- * bug. :-) Version 2.1 now lets you open a ruler to be as low as
- * 12 characters wide, which 2.0 only advertised. (CFN)
- *
- * 13-Nov-1988 - (Ver. 2.0) - I added minor enhancements, most
- * noteably, the ability to resize the window, and support for
- * overscanned screens. (CFN)
- *
- *
- * Feel welcome to use this program for any non-commercial purposes or
- * for your personal learning. Commercial users are requested to contact
- * Thad at either:
- *
- * UUCP: thad@cup.portal.com (OR) ..!sun!portal!cup.portal.com!thad
- * BBS: BBS-JC, 415/961-7250 (300/1200/2400), "Thad Floryan" | "SYSOP"
- *
- * Building instructions (Manx Aztec C):
- *
- * cc ruler
- * ln ruler -lc
- */
-
- #include <exec/types.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
-
- #define NEW(typ) AllocMem((ULONG)sizeof(typ),MEMF_CLEAR)
- #define FREE(p,typ) FreeMem(p,(ULONG)sizeof(typ))
-
- #define ever (;;) /* used for infinite loops */
-
- #define FATAL 20 /* exit code */
- #define WARN 10 /* exit code */
- #define NORMAL 0 /* exit code */
-
- extern void *OpenLibrary();
- extern void *OpenWindow();
- extern void *GetMsg();
- extern void *AllocMem();
- extern void ReplyMsg();
- extern long atol();
- void release_resources();
- void error_exit();
-
- struct NewWindow window_def =
- {
- 240, 0, /* Initial LeftEdge, TopEdge */
- 241, 25, /* Default pixel-width, pixel-height */
- 0, 1, /* DetailPen, BlockPen */
- CLOSEWINDOW | /* IDCMP flags */
- NEWSIZE,
- WINDOWDRAG | /* window flags */
- WINDOWDEPTH |
- WINDOWCLOSE |
- WINDOWSIZING |
- SMART_REFRESH |
- NOCAREREFRESH |
- BORDERLESS |
- RMBTRAP,
- NULL, /* Gadget list */
- NULL, /* checkmark stuff */
- (UBYTE *)"", /* window title (to be filled in later) */
- NULL, /* custom screen pointer */
- NULL, /* bitmap pointer */
- 97, 0, /* no Minwidth, MinHeight */
- -1, 0, /* no MaxWidth, MaxHeight */
- WBENCHSCREEN /* screen type */
- };
-
- struct Window *window;
- struct RastPort *rp;
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct Screen *screen;
- struct IntuiMessage *sys_message;
- ULONG class;
- int resource_state;
-
- char *version =
- "Text Ruler V3.0 06-Dec-88 \xA91988 Thad Floryan and Chad Netzer"
- " "; /* padding for "nice" title */
-
- /**********************************************************************/
-
- main (argc, argv)
- int argc;
- char *argv[];
- {
-
- long fivec; /* pixel size of five chars */
- long fsize; /* The font size of ruler scale */
- long max_scale; /* The max scale size possible */
- long max_width; /* maximum width of window */
- long w; /* character width of ruler */
- long w_lim; /* pixel width per w * 8 */
- long x; /* present window x coordinate */
- long y; /* present window y coordinate */
- char buf[5];
-
- long success; /* indicates bad return values */
-
- resource_state = 0;
-
- /*
- * Open Intuition so we can get the screen size limits.
- */
- IntuitionBase = OpenLibrary ("intuition.library", 0L);
- if (IntuitionBase == 0L)
- {
- error_exit("?Cannot open intuition.library\n");
- }
- ++resource_state;
-
- /*
- * Get WorkBench screen information
- */
- screen = NEW(struct Screen); /* Allocate a buffer for screen data */
- if (screen == 0L)
- {
- release_resources();
- error_exit("?ran out of available memory\n");
- }
- ++resource_state;
- success = GetScreenData(screen, (ULONG) sizeof (struct Screen),
- WBENCHSCREEN, 0L);
- if (success == FALSE)
- {
- error_exit();
- }
- /*
- * Set up defaults...
- */
- w = 30L; /* default ruler is 30 chars for a filename */
- fsize = 8L; /* default font scale is 8 pixels per char */
-
- /*
- * Parse command line to obtain requested parameters.
- */
- if (argc > 3)
- {
- printf("?Too many arguments, ``%s ?'' for help\n", argv[0]);
- release_resources();
- exit (WARN);
- }
- if (argc == 3)
- {
- fsize = atoi(argv[2]);
- }
-
- /*
- * find maximum width in pixels, and convert to characters.
- */
- max_width = screen->Width;
- max_scale = (screen->Width - 2) / 12;
- if (fsize > max_scale)
- {
- printf("?Font size can be NO larger than %ld!", max_scale);
- release_resources();
- exit (WARN);
- }
- max_width /= fsize;
- if (argc == 2)
- {
- if (*argv[1] == '?' ||
- *argv[1] == '-' ||
- *argv[1] == 'h' ||
- *argv[1] == 'H' )
- {
- printf( "%40s\n"
- "Opens a borderless WorkBench window in which is "
- "contained a ruler for the\npurpose of aligning or "
- "constraining text; the default ruler is 30 "
- "characters\nof an 8 pixel scale intended to help "
- "prevent entering too-long filenames.\n "
- "Usage:\n\n\t"
- "CLI> RUN %s [ size ] [ scale ]\n\nwhere `size'"
- "must be between 12 and %ld inclusive, at 8 pixel"
- "scale, and defaults\nto 30, and `scale' is the size "
- "of the font to measure, in pixels, and must\nbe less "
- "than %ld.\n", version, argv[0], max_width, max_scale);
- release_resources();
- exit (NORMAL);
- }
- else
- {
- w = atol(argv[1]);
- if ( w < 12L || w > max_width )
- {
- printf("?Value must be >= 12 and <= %ld\n", max_width);
- release_resources();
- exit (WARN);
- }
- }
- }
- /*
- * Now calculate window sizing and placement parameters and setup title.
- */
- w_lim = w * fsize;
- window_def.Width = w_lim + 1;
- window_def.LeftEdge = (window_def.Width > 300L) ? 0 : 240;
- window_def.Title = (UBYTE *)version;
- fivec = 5L * fsize;
- /*
- * Bomb out if requested ruler size would be larger than the screen.
- */
- if (window_def.Width > screen -> Width )
- {
- error_exit("?Ruler too large for WorkBench screen\n");
- }
- /*
- * Open up the graphics library.
- */
- GfxBase = OpenLibrary ("graphics.library", 0L);
- if (GfxBase == 0L)
- {
- error_exit("?Cannot open graphics.library\n");
- }
- ++resource_state;
- /*
- * Open the ruler display window.
- */
- window = OpenWindow (&window_def);
- if (window == 0L)
- {
- error_exit("?Cannot open window\n");
- }
- ++resource_state;
- /*
- * Get pointer to raster port.
- */
- rp = window -> RPort;
- SetAPen (rp, 0L);
- /*
- * Use RectFill to blank the window area and set pen for drawing.
- */
- for ever
- {
- SetAPen (rp, 0L);
- RectFill (rp, 0L, 10L, w_lim, 24L);
- /*
- * Now set pen to draw.
- */
- SetAPen (rp, 1L);
- /*
- * Because we've used a BORDERLESS window, must fill in some of the
- * title-/drag-bar space near the lower left where the text starts.
- */
- Move(rp, 28L, 8L);
- Draw(rp, 31L, 8L);
- /*
- * Because we've used a BORDERLESS window, must draw our own line beneath
- * the title bar to make the bar the same height as the window gadgets.
- * The `28' is the pixel position just to the right of the close gadget.
- * The `53' is the pixel width of the depth-arranging gadgets in the upper
- * right corner of the window.
- */
- Move(rp, 28L, 9L);
- Draw(rp, (w_lim - 53L), 9L);
- /*
- * Draw ruler and text
- */
- for (x = 0L; x < (w_lim + fsize); x += fsize)
- {
- if (x >= w_lim) /* right edge */
- {
- x = w_lim;
- y = 10L;
- }
- else if (x == 0L) y = 10L; /* left edge */
- else if ((x % fivec) == 0L) y = 19L; /* big tic every 5 chars */
- else y = 22L; /* small tic every char */
- Move (rp, x, y);
- Draw (rp, x, 24L);
- /*
- * Label ruler.
- * The test for position 40 (in the Move()) is for centering ``5''
- * differently than the centering for two-digit numbers.
- */
- if ((x > 0L) && (x < w_lim) && ((x % fivec) == 0L))
- {
- sprintf (buf, "%2ld", (x / fsize));
- Move (rp, (x == fivec) ? (x - 12L) : (x - 8L), 17L);
- Text (rp, buf, (long) strlen (buf));
- }
- }
- /*
- * Wait for gadget activation. No busy-/spin-/wait-loops here!
- */
- Wait (1L << window -> UserPort -> mp_SigBit);
- /*
- * Retrieve LAST message in Message Port
- */
- sys_message = GetMsg(window -> UserPort);
- class = sys_message -> Class;
- ReplyMsg(sys_message);
- /*
- * Dump uneeded messages (respond only to the last on LIFO queue).
- */
- while (sys_message = GetMsg(window -> UserPort))
- {
- ReplyMsg(sys_message);
- }
-
- if (class == CLOSEWINDOW)
- {
- release_resources();
- exit (NORMAL);
- }
-
- if (class == NEWSIZE)
- {
- w_lim = (window -> Width) - 1;
- }
- }
- }
-
- /**********************************************************************
- *
- * cleanup routine
- *
- * The ``switch'' on resource_state is to assure we don't attempt to
- * free something we don't have. Items are released in the reverse
- * order they were obtained (by "falling thru" the cases).
- */
- void release_resources()
- {
- switch (resource_state)
- {
- case 4: CloseWindow (window);
- case 3: CloseLibrary(GfxBase);
- case 2: FREE (screen, struct Screen);
- case 1: CloseLibrary(IntuitionBase);
- }
- }
-
- /**********************************************************************
- *
- * error handler
- */
- void error_exit(message)
- char *message;
- {
- if (message == 0L)
- {
- printf("Internal failure, exiting gracefully...\n");
- }
- else
- {
- printf(message);
- }
- release_resources();
- exit (FATAL);
- }
-