/* * browser - Rummage around on disks. * * copyright (c) 1986, Mike Meyer * * Permission is hereby granted to distribute this program, so long as this * source file is distributed with it, and this copyright notice is not * removed from the file. * * Hacked up to be used as file displayer within MandelVroom. By Kevin * Clague */ #include "mandp.h" #define INTUITION_REV 1L #define GRAPHICS_REV 1L #define LONGEST_NAME 80 /* Longest file name we can deal with */ #define LONGEST_LINE 256 /* Longest line we will deal with */ #define AVG_LINE_LENGTH 40 /* A guess, tune it if you need to */ #define UP_GADGET ((unsigned short) 0) #define DOWN_GADGET ((unsigned short) 1) #define SCROLL_GADGET ((unsigned short) 2) #define GWIDTH 16 /* Width of my two gadgets */ #define GHEIGHT 9 /* and their heights */ #define FIRST 18L /* * Pictures for the up and down arrows */ USHORT arrows[2][GHEIGHT] = { {0xFE7F, 0xFC3F, 0xF81F, 0xF00F, /* Up */ 0xFE7F, 0xFE7F, 0xFE7F, 0xFE7F, 0xFE7F },{ 0xFE7F, 0xFE7F, 0xFE7F, 0xFE7F, /* Down */ 0xFE7F, 0xF00F, 0xF81F, 0xFC3F, 0xFE7F} } ; /* * Now, the Image structures that use the arrows */ struct Image Arrow_Image[2] = { {0, 0, GWIDTH, GHEIGHT, 1, NULL, 1, 0, NULL}, /* Up */ {0, 0, GWIDTH, GHEIGHT, 1, NULL, 1, 0, NULL} /* Down */ }; /* * Now, my Gadget structures */ static struct PropInfo prop; static struct Image prop_img; static struct Gadget Scroll_Gadget = { /*(struct Gadget *)*/ NULL, /* End of Gadgets */ 0,10+GHEIGHT, /* Left, Top */ GWIDTH, -((GHEIGHT*2)+11), GRELHEIGHT | GADGHCOMP, GADGIMMEDIATE|FOLLOWMOUSE|RELVERIFY, /* Messages when released */ PROPGADGET, (APTR) &prop_img, (APTR) NULL, /* No rendering image, using HCOMP */ /*(struct IntuiText *)*/ NULL, 0L, /* No mutex */ (APTR) &prop, HELPSCROLL, /* Yes, this is the scroll gadget */ (APTR) NULL /* And nothing of mine */ }; static struct Gadget Up_Gadget = { &Scroll_Gadget, /* next gadget is scroll */ 0,10, /* Left, Top */ GWIDTH, GHEIGHT, GADGIMAGE | GADGHCOMP, GADGIMMEDIATE, /* Messages when released */ BOOLGADGET, /* These be boolean gadgets */ (APTR) &(Arrow_Image[UP_GADGET]), (APTR) NULL, /* No rendering image, using HCOMP */ /*(struct IntuiText *)*/ NULL, 0L, /* No mutex */ (APTR) NULL, /* Nothing special */ HELPUP, /* Yes, this is the up gadget */ (APTR) NULL /* And nothing of mine */ }; static struct Gadget Down_Gadget = { &Up_Gadget, /* Next gadget is Up_Gadget */ 0, -GHEIGHT, /* Left, Top */ GWIDTH, GHEIGHT, GRELBOTTOM | GADGIMAGE | /* Standard bottom border gadget */ GADGHCOMP, GADGIMMEDIATE | BOTTOMBORDER, /* Messages when released */ BOOLGADGET, /* These be boolean gadgets */ (APTR) &(Arrow_Image[DOWN_GADGET]), (APTR) NULL, /* No rendering image, using HCOMP */ /*(struct IntuiText *)*/ NULL, 0L, /* No mutex */ (APTR) NULL, /* Nothing special */ HELPDOWN, /* Yes, this is the up gadget */ (APTR) NULL /* And nothing of mine */ }; /* * Now, the window for it all */ static struct NewWindow New_Window = { #ifdef DEBUG 0, 0, 320, 150, /* smaller window to left printf's show up */ #else 0, 1, 320, 199, /* Full screen */ #endif -1L, -1L, /* Default pens */ NULL, /* Window closes and gadgets */ ACTIVATE /* Standard window */ | SMART_REFRESH | NOCAREREFRESH | SIZEBBOTTOM | WINDOWSIZING | WINDOWDEPTH | WINDOWCLOSE | WINDOWDRAG, &Down_Gadget, /* Add my gadgets */ /*(struct Image *)*/ NULL, (UBYTE *) "MandelVroom Help Window", /* Title */ /*(struct Screen *)*/NULL, /*(struct BitMap *)*/NULL, 100, 40, /* Minimum sizes */ -1, -1, /* Maximum sizes */ CUSTOMSCREEN } ; /* * My very own variables (mostly for done) */ struct Window *HelpWind = NULL ; static FILE *infile = NULL ; /* Current input file */ static void Page_File(); char HelpOpen; /* * Finally, declare the string twiddling functions as voids */ void strcat(), strcpy(), strncat(); AllocArrows() { extern USHORT *MakeChipSprite(); Arrow_Image[0].ImageData = MakeChipSprite( arrows[0], GHEIGHT ); Arrow_Image[1].ImageData = MakeChipSprite( arrows[1], GHEIGHT ); } FreeArrows() { USHORT *Temp; Temp = Arrow_Image[0].ImageData; if (Temp) FreeMem( (char *) Temp, (long) sizeof(arrows[0])); Arrow_Image[0].ImageData = NULL; Temp = Arrow_Image[1].ImageData; if (Temp) FreeMem( (char *) Temp, (long) sizeof(arrows[0])); Arrow_Image[1].ImageData = NULL; } /* * Display_File - given a directory path and file name, put the first page of * the file in the window. */ long aprox_lines, file_size; long Page_Length = 22L; static int old_off, new_off; static Display_File(dir, name) char *dir, *name; { static char File_Name[LONGEST_NAME]; FILE *fopen(); long ftell(); long i; if (HelpWind == NULL) return; old_off = -1; /* Get the file name */ strcpy(File_Name, dir); strcat(File_Name, name); if (infile != NULL) fclose(infile); if ((infile = fopen(File_Name, "r")) == NULL) { CloseHelpWind(20, "can't open file") ; return; } /* set up the prop gadget for scrolling */ fseek(infile, 0L, 2); file_size = ftell(infile); aprox_lines = file_size / AVG_LINE_LENGTH; prop.Flags = FREEVERT | AUTOKNOB; if (Page_Length >= aprox_lines) i = 0xAAAA; /* guess 66% for small files */ else i = (Page_Length * 0x10000) / aprox_lines; /* FFFF=100% - 0000=0% */ prop.VertBody = i; prop.VertPot = 0; /* always start at begin of file */ fseek(infile, 0L, 0); Page_File(HELPUP); /* Down from page 0 */ } /* * Page_File - move the file up or down one "page" */ void Page_File(direction) int direction; { register long where; static char buffer[LONGEST_LINE]; static char edited[84]; /* allow room for a tab at end */ int end_flag = 0; long tabs, size, Line_Length; int i,j; long new_pos; char *p; register struct Window *Window; Window = HelpWind; if (infile == NULL) return ; Page_Length = (Window -> Height - 20) / 8 ; Line_Length = (Window -> Width - (3+FIRST)) / 8; switch (direction) { case HELPUP: /* Seek back one page */ if (ftell(infile) < AVG_LINE_LENGTH * (Page_Length + 2)) fseek(infile, 0L, 0); else { fseek(infile, (long) -Page_Length * AVG_LINE_LENGTH, 1) ; fgets(buffer, LONGEST_LINE, infile) ; } break; case HELPDOWN: break; case HELPSCROLL: /* compute new position based on the users scroll bar pot */ new_pos = (file_size * prop.VertPot) / 0x10000; /* if at end of file, back up 1/2 page */ if (new_pos >= file_size) new_pos = file_size - ((Page_Length / 2) * AVG_LINE_LENGTH); fseek(infile, new_pos, 0); /* discard a partial line */ if (new_pos) fgets(buffer, LONGEST_LINE, infile); new_off = ftell(infile); if (new_off == old_off) return; old_off = new_off; break; default: CloseHelpWind(20, "Illegal argument to Page_File"); return; } SetAPen(Window->RPort, NORMALPEN); SetDrMd(Window->RPort, JAM1); RectFill(Window->RPort, GWIDTH, 10, Window->Width-2, Window->Height-10); RectFill(Window->RPort, GWIDTH, Window->Height-10, Window->Width-12-(YScale*4), Window->Height); BorderWindow( Window ); /* now put out one page's worth of the file's data */ for (where = 17, j = Page_Length; j--; where += 8) { /* blank the buffer first */ for (i = 0; i < 80; i++) edited[i] = ' '; if (!end_flag) { if (fgets(buffer, LONGEST_LINE, infile) == NULL) end_flag = TRUE; else { size = strlen(buffer); /* remove the newline */ buffer[size-1] = '\0'; size--; p = buffer; size = 0; /* edit the buffer for tabs and non-printables */ while(*p) { if (*p == '\t') { do { edited[size++] = ' '; } while(size&3); } else if (*p < ' ') { edited[size++] = '^'; edited[size++] = *p + '@'; } else edited[size++] = *p; p++; /* mark the line as longer than the window */ if (size >= Line_Length) { edited[size-1] = '>'; break; } } } } SetAPen(Window->RPort, SHADOWPEN); Move(Window -> RPort, FIRST+1, where+1) ; Text(Window -> RPort, edited, Line_Length); SetAPen(Window->RPort, HIGHLIGHTPEN); Move(Window -> RPort, FIRST, where) ; Text(Window -> RPort, edited, Line_Length); } /* for 1 to size of window */ } ShowHelp( DirName, FileName ) char *DirName, *FileName; { register struct IntuiMessage *message; register unsigned short class, code ; if (HelpWind == NULL) { /* set up the scroll bar */ prop.Flags = FREEVERT | AUTOKNOB; prop.VertBody = 0x1000; New_Window.Screen = screen; HelpWind = OpenMyWind(&New_Window,screen, NULL, 320, 200); if (HelpWind == NULL){ CloseHelpWind(20, "can't open the window") ; return; } if (HelpWind == NULL) return; AddGList( HelpWind, &Down_Gadget, -1, -1); RefreshGadgets( &Down_Gadget, HelpWind, NULL ); } SetAPen(HelpWind->RPort, NORMALPEN); SetDrMd(HelpWind->RPort, JAM1); RectFill(HelpWind->RPort, GWIDTH, 10, HelpWind->Width-2, HelpWind->Height-10); RectFill(HelpWind->RPort, GWIDTH, HelpWind->Height-10, HelpWind->Width-12-(YScale*4), HelpWind->Height); BorderWindow( HelpWind ); Display_File(DirName, FileName) ; } /* * done - just close everything that's open, and exit. */ CloseHelpWind(how, why) int how; char *why; { if (HelpWind) { CloseMyWind(HelpWind, NULL) ; HelpWind = NULL; if (infile) { fclose(infile) ; infile = NULL; } if (why) DispErrMsg(why,0); } }