home *** CD-ROM | disk | FTP | other *** search
- /* RULER - CLI version
- *
- * See Ruler.doc for operating instructions
- *
- * Revision History:
- * -----------------
- *
- * Version 5.0 21-Apr-1991 ©1991 Dave Schreiber, Chad Netzer, and
- * Thad Floryan
- * Based upon code from:
- *
- * Version 4.0 29-Dec-1989 ©1989 Chad Netzer and Thad Floryan
- *
- * Based upon code, idea, and logic from:
- *
- * Version 1.0 7-Nov-1988 ©1988 Thad Floryan
- *
- * Revision history:
- * 21-April-1991 - (Ver. 5.00) (DKS):
- * 1 Window is sized to make room for > 8 point fonts in the
- * title bar and main window (for compatibility with AmigaOS
- * 2.x)
- * 2 Added the ability to put Ruler's window on any screen at
- * will.
- * 3 Added the ability to get the font scale from any window.
- * 4 Added menus for:
- * * About
- * * Quit
- * * Change Screen (#2)
- * * Change Font (#3)
- * These menus are layed out by the 2.x function
- * LayoutMenusA(). This function is called only if Ruler
- * is running under 2.0 or later (i.e. Ruler is 1.3
- * compatible).
- *
- * 29-December-1989 - (Ver. 4.0) - Added an offset so that you can
- * just stick the window on the left edge of the workbench screen,
- * and it will automatically be lined up with the characters.
- * Fixed some more minor bugs and rearranged the code a bit.
- * Added ARP support for those who want it. (CFN)
- *
- * 09-March-1989 - (Ver. 3.1) - Fixed a visual bug so that scale can
- * no longer be less than eight. (CFN)
- *
- * 06-Dec-1988 - (Ver. 3.0) - Added support for measuring fonts of
- * varying widths (selectable scale). (CFN)
- *
- * 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"
- *
- * Chad at:
- *
- * UUCP: chad@ucscb.ucsc.edu (during school term)
- * UUCP: chad@cup.portal.com (holidays, summer, etc.)
- * BBS: BBS-JC, 415/961-7250 (300/1200/2400), "Chad Netzer"
- *
- * or Dave at:
- *
- * UUCP: davids@ucscb.ucsc.edu
- * BBS: BBS-JC, "Dave Schreiber"
- *
- *
- * Building instructions (SAS/C V5.10):
- *
- * lc -Lcd -v Ruler
- *
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <graphics/gfxbase.h>
-
- #define AMIGA_2.0 1 /*Delete if include files for 2.0 or later are*/
- /*not available*/
-
- #ifdef AMIGA_2.0
-
- #include <utility/tagitem.h>
-
- struct TagItem menuTag[] =
- {
- {TAG_DONE,NULL}
- };
-
- #endif
-
- #include "GUI.h"
-
- /*Some constants*/
- #define HEIGHT titleBarHeight+textHeight-2
- #define DEF_HEIGHT 12L+HEIGHT
- #define RULER_MARK_Y 11L+HEIGHT
- #define OFFSET_START_Y 2L+titleBarHeight
- #define BIG_TIC_Y 5L+HEIGHT
- #define SMALL_TIC_Y 9L+HEIGHT
- #define TEXT_Y 3L+HEIGHT
- #define DRAW_AREA_Y 3L+titleBarHeight
- #define DRAW_AREA_HEIGHT 24L+textHeight
-
- #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 */
-
- #define LEFT_OFFSET 3L /* "dead space" on left side of ruler margin */
-
- extern void *OpenLibrary();
- extern void *OpenWindow();
- extern void *GetMsg();
- extern void *AllocMem();
- extern void ReplyMsg();
-
- /* Prototypes for functions defined in ruler5.c */
- void __regargs release_resources(void);
- void __regargs error_exit(char *message);
- int __regargs handleMenu(USHORT NUM);
- void __regargs printAboutWindow(void);
- void __regargs changeFSize(void);
- void __regargs changeScreen(void);
- void __regargs readArg(int argc,
- char **argv,
- long *fsize,
- long *w);
-
- UWORD titleBarHeight,textHeight,textWidth,screenWidth;
-
- struct NewWindow window_def =
- {
- 0, 0, /* Initial LeftEdge, TopEdge */
- 241, 17, /* Default pixel-width, pixel-height */
- 0, 1, /* DetailPen, BlockPen */
- CLOSEWINDOW | /* IDCMP flags */
- MENUPICK |
- NEWSIZE,
- WINDOWDRAG | /* window flags */
- WINDOWDEPTH |
- WINDOWCLOSE |
- WINDOWSIZING |
- ACTIVATE |
- SMART_REFRESH |
- NOCAREREFRESH,
- NULL, /* Gadget list */
- NULL, /* checkmark stuff */
- NULL, /* window title (to be filled in later) */
- NULL, /* custom screen pointer */
- NULL, /* bitmap pointer */
- 97 + LEFT_OFFSET, 0, /* Minwidth, no MinHeight */
- -1, 0, /* no MaxWidth, MaxHeight */
- CUSTOMSCREEN /* screen type */
- };
-
- struct Window *window;
- struct RastPort *rp;
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct Library *GadToolsBase;
-
- struct Screen *screen;
- struct IntuiMessage *sys_message;
- ULONG class;
- USHORT code;
- int resource_state;
- long fsize; /* The font size of ruler scale */
-
- APTR visualInfo;
-
- char *version =
- "Text Ruler V5.00 (CLI) 21-Apr-91 ©1991 ";
-
- /**********************************************************************/
-
- main (argc, argv)
- int argc;
- char *argv[];
- {
-
- long fivec; /* pixel size of five chars */
- long w; /* character width of ruler */
- long w_lim; /* pixel width (w * fsize) */
- long x; /* present window x coordinate */
- long y; /* present window y coordinate */
-
- char buf[5];
-
- int redoWindow; /*Boolean flag*/
-
- resource_state = 0;
-
- /*
- * Open Intuition and Graphics so we can get screen size and
- * default font information.
- */
- if((IntuitionBase = OpenLibrary ("intuition.library", NULL))==NULL)
- error_exit("?Cannot open intuition.library\n");
- ++resource_state;
-
- if((GfxBase = OpenLibrary ("graphics.library", NULL))==NULL)
- error_exit("?Cannot open graphics.library\n");
- ++resource_state;
-
- GadToolsBase = OpenLibrary("gadtools.library",NULL);
- if(GadToolsBase)
- window_def.IDCMPFlags|=(ACTIVEWINDOW|INACTIVEWINDOW);
-
- /*
- * Get WorkBench screen information
- */
- screen=window_def.Screen=IntuitionBase->ActiveScreen;
-
- w = 30L; /* default ruler is 30 chars for a filename */
- /*Get default scale*/
- fsize=textWidth=GfxBase->DefaultFont->tf_XSize;
-
- /*
- * Parse command line to obtain requested parameters.
- */
- readArg(argc,argv,&fsize,&w);
- w_lim = w * fsize;
-
- /*
- * Main loop
- */
-
- for ever
- {
-
- /* Get width of screen
- */
- screenWidth=screen->Width;
-
- /* Determine spacing from current font information
- */
- titleBarHeight = screen->Font->ta_YSize;
- textHeight = GfxBase->DefaultFont->tf_YSize;
-
- /*
- * Now calculate window sizing and placement parameters and setup title.
- */
- window_def.Width = w_lim + LEFT_OFFSET + 1;
- window_def.Height = DEF_HEIGHT;
- window_def.Title = (UBYTE *)version;
- /*
- * Shorten the window if it would be wider than the screen
- */
- if (window_def.Width > screenWidth )
- {
- window_def.Width = screenWidth;
- w_lim = (window_def.Width) - 1 - LEFT_OFFSET;
- }
-
- /*
- * Open the ruler display window.
- */
- window = OpenWindow (&window_def);
-
- if (window == NULL)
- {
- error_exit("?Cannot open window\n");
- }
- ++resource_state;
-
- /*
- * Set screen and window titles
- */
- SetWindowTitles(window,version,"Text Ruler V5.00");
-
- /*
- * If running under 2.0 or later, adjust menu spacing information
- * to compensate for a non-8 point font size.
- */
- if(GadToolsBase != NULL)
- {
- visualInfo = (APTR)GetVisualInfoA(screen,menuTag);
- LayoutMenusA(&Menu1,visualInfo,menuTag);
- FreeVisualInfo(visualInfo);
- }
-
- /*
- * Install menus
- */
- SetMenuStrip(window,&Menu1);
- /*
- * Get pointer to raster port.
- */
- rp = window -> RPort;
-
- /*
- * Inner loop (loop until the window needs to be closed and another
- * opened).
- */
- redoWindow=FALSE;
-
- while(!redoWindow)
- {
- redoWindow=FALSE;
- fivec = 5L * fsize;
- /*
- * Use RectFill to blank the window area and set pen for drawing.
- */
- SetAPen(rp, NULL);
- RectFill(rp, LEFT_OFFSET+1, DRAW_AREA_Y, w_lim + LEFT_OFFSET,
- DRAW_AREA_Y+DRAW_AREA_HEIGHT);
-
- /*
- * Now set pen to draw.
- */
- SetAPen(rp, 1L);
- /*
- * When I use the ruler, I like to jam it up against the left hand side of
- * my workbench screen, so that it to measure something on the CLI.
- * However, the CLI is offset by a small amount, so I compensate by
- * starting the "virtual" area of the ruler a little to the right...
- *
- * Fill in the offset area that is unused.
- */
-
- RectFill(rp, NULL, OFFSET_START_Y, LEFT_OFFSET,
- DRAW_AREA_Y+DRAW_AREA_HEIGHT+1);
-
- /*
- * Draw ruler and text
- */
- for (x = NULL; x < (w_lim + fsize); x += fsize)
- {
- /*big tic every 5 chars*/
- if ((x % fivec) == NULL) y = BIG_TIC_Y;
- else y = SMALL_TIC_Y; /* small tic every char */
- Move (rp, x + LEFT_OFFSET, y);
- Draw (rp, x + LEFT_OFFSET, RULER_MARK_Y);
- /*
- * Label ruler.
- * The test for position `fivec' (in the Move()) is for centering ``5''
- * differently than the centering for two-digit numbers.
- */
- if ((x > NULL) && (x < w_lim) && ((x % fivec) == NULL))
- {
- stci_d(buf,x/fsize);
- Move (rp, (x == fivec)
- ? (x - textWidth + (textWidth/2) + LEFT_OFFSET)
- : (x - textWidth + LEFT_OFFSET),
- TEXT_Y);
- Text (rp, buf, (long) strlen (buf));
- }
- }
-
- SetAPen(rp,1);
- Move(rp,w_lim+LEFT_OFFSET,titleBarHeight);
- Draw(rp,w_lim+LEFT_OFFSET,DEF_HEIGHT);
-
- /*
- * 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;
- code = sys_message -> Code;
- ReplyMsg(sys_message);
- /*
- * Dump uneeded messages (respond only to the last on LIFO queue).
- */
- while (sys_message = GetMsg(window -> UserPort))
- {
- ReplyMsg(sys_message);
- }
-
- /*Handle various IDCMP events*/
- switch(class)
- {
- case CLOSEWINDOW:
- release_resources();
- exit (NORMAL);
-
- case NEWSIZE:
- w_lim = (window -> Width) - 1 - LEFT_OFFSET;
- break;
-
- case INACTIVEWINDOW:
- SetWindowTitles(window,version,"Text Ruler V5.00");
- break;
-
- case MENUPICK:
- redoWindow=handleMenu(code);
- }
- }
- }
- }
-
- /**********************************************************************
- *
- * 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 __regargs release_resources()
- {
- switch (resource_state)
- {
- case 3: ClearMenuStrip(window);
- CloseWindow (window);
- case 2: CloseLibrary(GfxBase);
- case 1: CloseLibrary(IntuitionBase);
- }
- if(GadToolsBase != NULL)
- CloseLibrary(GadToolsBase);
- }
-
- /**********************************************************************
- *
- * error handler
- */
- void __regargs error_exit(message)
- char *message;
- {
- if (message == NULL)
- {
- puts("Internal failure, exiting gracefully...\n");
- }
- else
- {
- puts(message);
- }
- release_resources();
- exit (FATAL);
- }
-
- /*
- * Decode menu choice
- */
-
- int __regargs handleMenu(USHORT NUM)
- {
- struct MenuItem *item;
- USHORT menuNum,itemNum;
-
- while(NUM != MENUNULL)
- {
- menuNum=MENUNUM(NUM);
- itemNum=ITEMNUM(NUM);
- item=(struct MenuItem *)ItemAddress(&Menu1,NUM);
-
- if(menuNum==0)
- if(itemNum==0)
- printAboutWindow(); /*About*/
- else
- {
- release_resources(); /*Quit*/
- exit(NORMAL);
- }
- else
- if(itemNum==0)
- {
- changeFSize(); /*Change Scale*/
- return(FALSE);
- }
- else
- {
- changeScreen(); /*Change Screen*/
- return(TRUE);
- }
-
- NUM=item->NextSelect;
- }
- return(0);
- }
-
- /*
- * Display the About window
- */
- void __regargs printAboutWindow()
- {
- struct Window *aboutWdw;
-
- if((NewAboutWindow.LeftEdge=(screenWidth-NewAboutWindow.Width)/2) > 200)
- NewAboutWindow.LeftEdge = 200;
-
- /*
- * Determine About window position
- */
- NewAboutWindow.TopEdge=(screen->Height-NewAboutWindow.Height)/5;
- NewAboutWindow.Height=titleBarHeight-15+ABOUT_WDW_HEIGHT;
-
- /*
- * Get the screen the about window will appear on (same as the
- * screen the main window is on).
- */
- NewAboutWindow.Screen = (struct Screen *) screen;
-
- /*
- * Open window
- */
-
- aboutWdw=(struct Window *)OpenWindow(&NewAboutWindow);
- if(aboutWdw==NULL)
- return;
-
- /*
- * Print window text
- */
-
- PrintIText(aboutWdw->RPort,&IText11,0,titleBarHeight-15);
-
- /*
- * Wait for input close gadget to be pressed, then close window and
- * return.
- */
- Wait(1<<aboutWdw->UserPort->mp_SigBit);
-
- CloseWindow(aboutWdw);
- return;
- }
-
- /*
- * Change scale
- */
- void __regargs changeFSize()
- {
- ULONG IDCMPFlags;
-
- IDCMPFlags=window_def.IDCMPFlags;
- ModifyIDCMP(window,INACTIVEWINDOW);
-
- for ever
- {
- /*Wait for IDCMP event*/
- Wait (1L << window -> UserPort -> mp_SigBit);
- sys_message = GetMsg(window -> UserPort);
- class = sys_message -> Class;
- ReplyMsg(sys_message);
-
- /*
- * If another window was clicked, get the horizontal font size of
- * the current font in that window
- */
-
- if(class==INACTIVEWINDOW)
- {
- if((IntuitionBase->ActiveWindow->RPort->Font->tf_Flags & FPF_PROPORTIONAL) == 0)
- fsize=IntuitionBase->ActiveWindow->RPort->Font->tf_XSize;
- else
- {
- /*If the window is using a proportional font, print an error*/
- SetWindowTitles(window,version,"Can't change scale: window font is proportional.");
- DisplayBeep(window->WScreen);
- }
- ModifyIDCMP(window,IDCMPFlags);
- return;
- }
- }
- }
-
- /*
- * Change the screen that the window is displayed on.
- */
-
- void __regargs changeScreen()
- {
- for ever
- {
- /*
- * Wait for user to click on another window (hopefully in another
- * screen).
- */
- ModifyIDCMP(window,INACTIVEWINDOW);
- Wait (1L << window -> UserPort -> mp_SigBit);
- sys_message = GetMsg(window -> UserPort);
- class = sys_message -> Class;
- ReplyMsg(sys_message);
- if(class==INACTIVEWINDOW)
- {
- /*Get active screen*/
- window_def.Screen=screen=IntuitionBase->ActiveScreen;
-
- /*Clear menu strip and close window*/
- ClearMenuStrip(window);
- CloseWindow(window);
- resource_state--;
-
- return;
- }
- }
- }
-
- /*
- * Read command line arguments, print help if requested
- */
-
- void __regargs readArg(int argc, char *argv[], long *fsize, long *w)
- {
- int argCounter;
- BYTE gotSize = FALSE;
-
- if(argc > 1 && argv[1][0]=='?')
- {
- /*
- * Print help and exit
- */
- puts("");
- puts("Text Ruler V5.00 ©1991 by Thad Floryan, Chad Netzer, and Dave Schreiber.");
- puts("");
- puts("Usage: Ruler5 [-z<size>][-s<scale>]");
- puts(" <size> - Number of 'ticks'");
- puts(" <scale> - Width between ruler 'ticks', in pixels.");
- puts("or: Ruler5 [<size> [<scale>]]");
- release_resources();
- exit(0);
- }
-
- /*
- * Otherwise, examine each argument
- */
- for(argCounter=1;argCounter < argc ; argCounter++)
- {
- if(isdigit(argv[argCounter][0])) /*Check if just a digit*/
- if(!gotSize)
- {
- gotSize=TRUE;
- *w=atol(argv[argCounter]);
- }
- else
- *fsize=atol(argv[argCounter]);
- else
- {
- if(argv[argCounter][0] != '-')
- {
- puts("I don't understand this argument:");
- puts(argv[argCounter]);
- error_exit("");
- }
- switch(argv[argCounter][1])
- {
- /*Each case checks for to see if there's a space between*/
- /*the switch and the argument*/
- case 's': /*Scale*/
- case 'S':
- if(argv[argCounter][2]!=NULL)
- *fsize=atol(&argv[argCounter][2]);
- else
- *fsize=atol(&argv[++argCounter][0]);
- if(*fsize < 5)
- error_exit("The scale must be at least 5");
- if(*fsize > 50)
- error_exit("The scale must be at most 50");
- break;
-
- case 'z': /*Size*/
- case 'Z':
- if(argv[argCounter][2]!=NULL)
- *w=atol(&argv[argCounter][2]);
- else
- *w=atol(&argv[++argCounter][0]);
- if(*w < 12)
- error_exit("The size must be at least 12");
- break;
- }
- }
- }
- return;
- }
-
-