home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD2.img
/
d4xx
/
d496
/
ruler
/
cli
/
ruler.c
< prev
Wrap
C/C++ Source or Header
|
1991-06-06
|
17KB
|
689 lines
/* 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;
}