/* QuickReq V2.0 (c) 1990,1991 by Markus Aalto QuickReq.c : 14.12.90 - 09.01.91 */ #include "exec/types.h" #include "exec/memory.h" #include "intuition/intuition.h" #include "intuition/screens.h" #include "intuition/intuitionbase.h" #include "graphics/text.h" #include "graphics/gfxbase.h" #include "graphics/gfx.h" #include "stdio.h" #include "string.h" #include "stdlib.h" #include "ctype.h" #include "proto/intuition.h" #include "proto/exec.h" #include "proto/dos.h" /* No CTRL-C checking */ #ifdef LATTICE int CXBRK(VOID) {return(0);} #endif /* Protos for my own functions */ int ParseCommands(int, register char *, char **), ReadNumber(char **); char *AllocNormMem(int); VOID main(int, char **), Print(char *), ReadRedirFile(char **); VOID CleanUp(BOOL , char *,ULONG ), PrintUsage(VOID); USHORT CheckParameters(int , char **), TestWidth(struct IntuiText *); struct IntuiText *MakeIntuText(char *, USHORT, USHORT); #define MINWINDOWWIDTH 86 #define MINWINDOWHEIGHT 54 #define INTUILIB "intuition.library" #define GFXLIB "graphics.library" #define IPOINT ((struct IntuiText *)-1) #define MAXARG 32 /* maximum command line arguments */ #define QUOTE '"' struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct Remember *RememberKey; char *text[3]; USHORT ForceWidth, ForceHeight, PenNumber; ULONG MaxCols; BOOL CENTER_ON = FALSE; BOOL BEEP_ON = FALSE; BOOL LARGE_ON = FALSE; BOOL FWIDTH_ON = FALSE; BOOL FHEIGHT_ON = FALSE; BOOL OWNPEN_ON = FALSE; /* Well, This is very important */ char UsageString[] = { 'Q','u','i','c','k','R','e','q',' ','V','2','.','0',' ',169,' ','1','9', '9','1',' ','b','y',' ',0x9b,'1','m','M','a','r','k','u','s',' ','A','a', 'l','t','o',0x9b,'0','m','\n',0 }; /* This is something I may choose not to be defined here because of KS2.0 and it's switchable and scalable fonts, but for now I just do it in easy way. */ struct TextAttr MyTopaz8 = { "topaz.font", 8, FS_NORMAL, FPF_ROMFONT }; VOID main(int argc, char *argv[]) { struct Screen Buffer, *MyScreen; struct IntuiText *TempI, *Intu1, *Intu2, *Intu3; ULONG ScreenSuccess, Success, error, IntuLock; USHORT Width, MaxHeight, MaxWidth, text1width, text2width, text3width, textheight, i; /* Just for sure */ error = 0; RememberKey = NULL; MaxCols = 1; IntuitionBase = (struct IntuitionBase *)OpenLibrary(INTUILIB,33L); if(IntuitionBase == NULL) { CleanUp(FALSE,"Sorry, Can't open intuition.library V33 or later!\n",20); } GfxBase = (struct GfxBase *)OpenLibrary(GFXLIB,33L); if(GfxBase == NULL) { CleanUp(FALSE,"Sorry, Can't open graphics.library V33 or later!\n",20); } ScreenSuccess = GetScreenData((char *)&Buffer,sizeof(struct Screen), WBENCHSCREEN,NULL); if(ScreenSuccess == 0L) { CleanUp(FALSE,"Can't get Screen information!\n",20); } for(i=0; i < ((&(Buffer.BitMap))->Depth); i++) MaxCols *= 2; error = CheckParameters(argc, argv); if(error != 0) { CleanUp(TRUE,NULL,error); } if(text[0] == NULL) { CleanUp(FALSE,NULL,0); } else if(text[1] == NULL) { ReadRedirFile(argv); if(text[0] == NULL) { CleanUp(FALSE,NULL,0); } else if(text[1] == NULL) { CleanUp(FALSE,"Can't open redirection file!\n",10); } else if(text[2] == NULL) { text[2] = text[1]; text[1] = NULL; } } else if(text[2] == NULL) { text[2] = text[1]; text[1] = NULL; } MaxHeight = Buffer.Height; MaxWidth = Buffer.Width; if(!LARGE_ON) { if(MaxHeight > GfxBase->NormalDisplayRows) { MaxHeight = GfxBase->NormalDisplayRows; } if(MaxWidth > GfxBase->NormalDisplayColumns) { MaxWidth = GfxBase->NormalDisplayColumns; } } if(FWIDTH_ON) { if((ForceWidth > MINWINDOWWIDTH) && (ForceWidth <= MaxWidth)) { MaxWidth = ForceWidth; } else { Print("Illegal window size!\n"); FWIDTH_ON = FALSE; } } if(FHEIGHT_ON) { if((ForceHeight > MINWINDOWHEIGHT) && (ForceHeight <= MaxHeight)) { MaxHeight = ForceHeight; } else { FHEIGHT_ON = FALSE; Print("Illegal window size!\n"); } } MaxHeight -= 46; MaxWidth -= 38; Intu1 = MakeIntuText(text[0],(USHORT)(MaxHeight/9),(USHORT)(MaxWidth/8)); Intu2 = MakeIntuText(text[1],1,(USHORT)((MaxWidth-48)/16)); Intu3 = MakeIntuText(text[2],1,(USHORT)((MaxWidth-48)/16)); if((Intu1 == IPOINT) || (Intu2 == IPOINT) || (Intu3 == IPOINT)) { CleanUp(FALSE,"Out of memory!\n",20); } if(FWIDTH_ON) { Width = ForceWidth; } else { text1width = TestWidth(Intu1); text2width = TestWidth(Intu2)+3; text3width = TestWidth(Intu3)+3; Width = text2width+text3width; if(text1width > Width) Width = text1width; Width = Width*8+38; } textheight = 0; TempI = Intu1; while(TempI != NULL) { textheight++; if(CENTER_ON) { TempI->LeftEdge += (Width - 38 - strlen(TempI->IText)*8)/2; } TempI = TempI->NextText; } if(FHEIGHT_ON) { textheight = ForceHeight; } else { textheight = textheight*9+46; } if(BEEP_ON) { IntuLock = LockIBase(0); MyScreen = IntuitionBase->ActiveScreen; UnlockIBase(IntuLock); DisplayBeep(MyScreen); /* Flash the Active Screen, before activating AutoRequest */ } Success = (USHORT)AutoRequest(NULL,Intu1,Intu2,Intu3,0,0,Width,textheight); if(Success == 0) error = 5; CleanUp(TRUE, NULL, error); } VOID CleanUp(BOOL SUCCESS, char *Text,ULONG Error) { if(!SUCCESS) { PrintUsage(); Print(Text); } FreeRemember(&RememberKey,TRUE); if(GfxBase) CloseLibrary((struct Library *)GfxBase); if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase); XCEXIT(Error); } VOID PrintUsage() { Print(UsageString); Print("USAGE: QuickReq\t [] [OPTIONS] or\n"); Print("\t\t [OPTIONS]\n"); Print("OPTIONS:\n\t-C = Text centering\n"); Print("\t-B = DisplayBeep\n"); Print("\t-L = Large view\n"); Print("\t-W# = Width\n"); Print("\t-H# = Height\n"); Print("\t-P# = Pen color\n\n"); } VOID ReadRedirFile(char *argv[]) { ULONG MyLock, FileSize, Success, error; char *line; struct FileInfoBlock *FIB; int argc; MyLock = Lock(text[0],ACCESS_READ); if(MyLock == NULL) { CleanUp(FALSE,"Can't open redirection file!\n",IoErr()); } FIB = (struct FileInfoBlock *)AllocNormMem(sizeof(struct FileInfoBlock)); if(FIB == NULL) { CleanUp(FALSE,"Out of memory!\n",10); } Success = Examine(MyLock,FIB); error = IoErr(); UnLock(MyLock); if(Success == 0) { CleanUp(FALSE,"File error!\n",error); } else if(FIB->fib_DirEntryType > 0) { CleanUp(FALSE,"Object wrong type!\n",ERROR_OBJECT_WRONG_TYPE); } FileSize = FIB->fib_Size; if(FileSize != 0) { line = (char *)AllocNormMem(FileSize); if(line == NULL) { CleanUp(FALSE,"Out of memory!\n",10); } MyLock = Open(text[0],MODE_OLDFILE); if(MyLock == NULL) { CleanUp(FALSE,"File error!\n",IoErr()); } Success = Read(MyLock,line,FileSize); if(Success == -1) { error = IoErr(); Close(MyLock); CleanUp(FALSE,"File error!\n",error); } Close(MyLock); } else line = NULL; argc = ParseCommands(1, line, argv); if(argc > MAXARG) { CleanUp(FALSE,NULL,1); } error = CheckParameters(argc, argv); if(error != 0) { CleanUp(TRUE,NULL,error); } } USHORT TestWidth(struct IntuiText *MyIText) { USHORT width, widest = 0; while(MyIText != NULL) { width = strlen(MyIText->IText); if(width > widest) widest = width; MyIText = MyIText->NextText; } return(widest); } VOID Print(char *String) { ULONG output; output = Output(); if(output != NULL) { Write(output,String,strlen(String)); } } USHORT CheckParameters(int argc, char *argv[]) { char *NextStr = NULL; int count, textcount; char Currentchar; count = 0; textcount = 0; while(count < argc-1) { NextStr = argv[count+1]; if(*NextStr == '-') { NextStr++; while((*NextStr != '\0') && (!isspace((char)*NextStr))) { Currentchar = toupper(*NextStr); if(Currentchar == 'C') { CENTER_ON = TRUE; } else if(Currentchar == 'B') { BEEP_ON = TRUE; } else if(Currentchar == 'L') { LARGE_ON = TRUE; } else if(Currentchar == 'W') { NextStr++; ForceWidth = ReadNumber(&NextStr); FWIDTH_ON = TRUE; } else if(Currentchar == 'H') { NextStr++; ForceHeight = ReadNumber(&NextStr); FHEIGHT_ON = TRUE; } else if(Currentchar == 'P') { NextStr++; PenNumber = ReadNumber(&NextStr); OWNPEN_ON = TRUE; } else { PrintUsage(); Print("Unknown option "); Print(argv[count+1]); Print(" !\n"); return(10); } NextStr++; } } else if((textcount == 0) && (*NextStr == '?')) { PrintUsage(); return(1); } else if(textcount <= 2) { text[textcount] = NextStr; textcount++; } else { PrintUsage(); Print("Too many arguments!\n"); return(10); } count++; } return(0L); } int ReadNumber(char *line[]) { char *temp; USHORT Number = 0; temp = line[0]; while((*temp != ' ') && (*temp != '\0') && (isdigit(*temp))) { Number = Number*10+(*temp - '0'); temp++; } line[0] = temp-1; return(Number); } struct IntuiText *MakeIntuText(char *text, USHORT height, USHORT width) { struct IntuiText *FirstText, *CurrentText, *OldText = 0; USHORT curheight = 0, curwidth, i; char *writechar, *readchar, *oldreadchar; if(text == NULL) return(NULL); FirstText = (struct IntuiText *)AllocNormMem(sizeof(struct IntuiText)); if(FirstText == NULL) { return(IPOINT); } writechar = (char *)AllocNormMem(height*(width+1)); if(writechar == NULL) { return(IPOINT); } CurrentText = FirstText; readchar = text; while((CurrentText != NULL) && (curheight < height)) { if(OldText != NULL) { OldText->NextText = CurrentText; } if(OWNPEN_ON) { CurrentText->FrontPen = PenNumber % MaxCols; } else { CurrentText->FrontPen = AUTOFRONTPEN; } if(CurrentText->FrontPen == AUTOBACKPEN) { CurrentText->BackPen = (PenNumber+1) % MaxCols; } else { CurrentText->BackPen = AUTOBACKPEN; } CurrentText->DrawMode = AUTODRAWMODE; CurrentText->LeftEdge = AUTOLEFTEDGE; CurrentText->TopEdge = AUTOTOPEDGE + (curheight * 9); CurrentText->ITextFont = &MyTopaz8; CurrentText->IText = (UBYTE *)writechar; oldreadchar = readchar; curwidth = 0; while((*readchar != '\\') && (curwidth < width)) { if((*readchar == 0x0a) || (*readchar == 0x09)) { *readchar = ' '; } *writechar++ = *readchar; if(*readchar++ == '\0') return(FirstText); curwidth++; } if(*readchar == '\\') { *writechar++ = '\0'; readchar++; } else if(curwidth >= width) { i = 0; while((*readchar != ' ') && (readchar != oldreadchar)) { --readchar; i++; } if(*readchar == ' ') { writechar -= i; *writechar++ = '\0'; readchar++; } else { readchar += i; *writechar++ = '\0'; } } curheight++; OldText = CurrentText; CurrentText = (struct IntuiText *)AllocNormMem(sizeof(struct IntuiText)); if(CurrentText == NULL) { return(IPOINT); } } return(FirstText); } char *AllocNormMem(int Size) { char *MemPointer; MemPointer = (char *)AllocRemember(&RememberKey, Size,MEMF_PUBLIC|MEMF_CLEAR); return(MemPointer); } /* ------------------------------------------ */ /* These are my modified startup routines */ /* ------------------------------------------ */ VOID _main(line) register char *line; { int argc = 0; /* arg count */ char *argv[MAXARG]; /* arg pointers */ argc = ParseCommands(0, line, argv); if(argc > MAXARG) { PrintUsage(); XCEXIT(1); } main(argc, argv); XCEXIT(0); } /* I have separated this to own routine, because I also use this to parse redirection file. */ int ParseCommands(int Start, register char *line, char *args[]) { register char **pargv; int argc; argc = Start; while (argc < MAXARG) { while (isspace(*line)) line++; if (*line == '\0') break; pargv = &args[argc++]; if (*line == QUOTE) { *pargv = ++line; /* ptr inside quoted string */ while ((*line != '\0') && (*line != QUOTE)) line++; if (*line == '\0') { return(MAXARG+1); } else *line++ = '\0'; /* terminate arg */ } else /* non-quoted arg */ { *pargv = line; while ((*line != '\0') && (!isspace(*line))) line++; if (*line == '\0') break; else *line++ = '\0'; /* terminate arg */ } } /* while */ return(argc); }