home *** CD-ROM | disk | FTP | other *** search
- /*
- * WICONIFY A utility that allows you to iconify any Intuition window
- * on any screen, and to open WB windows on any screen.
- *
- * wFileRead.c Performs most of the structured file IO.
- *
- * Copyright 1990 by Davide P. Cervone, all rights reserved.
- * You may use this code, provided this copyright notice is kept intact.
- */
-
- #include "wFile.h"
- #include "wMenu.h"
-
-
- extern int ScreenType;
- extern UWORD ImageData[MAXWORDS][MAXHEIGHT][MAXDEPTH];
- extern short MaxWidth,MaxHeight,MaxWords;
- extern UBYTE Plane0,Plane1;
- extern int ImageType;
- extern int IconFileOpen;
- static int NoMaskError; /* FALSE if a mask error was reported */
- static short ErrorCount; /* number of error messages so far */
-
- #define MAXERROR 8 /* maximum number of errors in a line */
-
- /*
- * Macros for working with HEX and Color values
- */
-
- #define HEXCHAR(c) (((c)>='0'&&(c)<='9')||((c)>='A'&&(c)<='F'))
- #define VALIDCOLOR(w)\
- (HEXCHAR(w[0])&&HEXCHAR(w[1])&&HEXCHAR(w[2])&&w[3]==0)
-
- #define HEX(c) (((c)>'9')?(c)-'A'+10:(c)-'0')
- #define RGB(r,g,b) ((r<<8)|(g<<4)|b)
- #define COLOR(w) RGB(HEX(w[0]),HEX(w[1]),HEX(w[2]))
-
- /*
- * Allowable HEX codes
- */
-
- static char *ExtHex = "0123456789abcdef)!@#$%^&*(ABCDEF";
-
-
- /*
- * The initialization file command keywords
- */
-
- static char *MainCommand[] =
- {
- "", /* No command given */
- "Iconify_Key", /* Sets the key and quals that iconify a window */
- "Change_Refresh", /* Sets the quals that change refresh type */
- "Activation_Key", /* Sets the key and quals that activate wIconify */
- "Color_Map", /* Sets the default NewScreen color map */
- "Default_Flags", /* Sets the default icon's icon flags */
- "Screen_Flags", /* Sets the default screen icon's icon flags */
- "Menu_Keys", /* Sets the menu key equivalents */
- "Ignore_Screen", /* Adds screen titles to be ignored by wIconify */
- "Priority", /* Sets the wIconify process priority */
- "HiRes_CLICommand", /* Sets the HIRES NewCLI command string */
- "LoRes_CLICommand", /* Sets the LOWRES NewCLI command string */
- "Default_Image", /* Defines the default icon image */
- "Default_Select", /* Defines the default icon select image */
- "Default_Mask", /* Defines the default icon image mask */
- "Default_Icon", /* Reads the default icon from a file */
- "Screen_Image", /* Defines the default screen icon image */
- "Screen_Select", /* Defines the default screen icon select image */
- "Screen_Mask", /* Defines the default screen icon image mask */
- "Screen_Icon", /* Reads the default screen icon from a file */
- "Open_On", /* Sets the OpenOn window submenu entries */
- "Size_To_Fit", /* Sets or clears the SizeToFit option */
- "Command_Stack", /* Sets the size of the newCLI command stack */
- "Handler_Priority", /* Sets the Input Device handler priority */
- };
- #define MAXMAINCOM COM_LAST
-
-
- /*
- * The commands for within an icon file (for DEFAULT_ICON and SCREEN_ICON)
- */
-
- static char *IconCommand[] =
- {
- "Image", /* Sets the default icon image */
- "Select", /* Sets the default icon select image */
- "Mask" /* Sets the default icon image mask */
- };
- #define MAXICONCOM 2
-
- char **ComName = &MainCommand[0]; /* The current command set */
- static int ComOffset; /* Add this to get "real" command # */
- static int ComCount = MAXMAINCOM; /* Size of command array */
-
-
- /*
- * Icon Flags for DEFAULT_FLAGS command
- */
-
- static struct Flag IconFlag[] =
- {
- {"NOICONIFY", WI_NOICONIFY}, /* Window can not be iconified */
- {"NOSAVEPOS", WI_NOSAVEPOS}, /* Position not saved when openned */
- {"NOCLOSE", WI_NOCLOSE}, /* CLOSE menu not available */
- {"NOORGANIZE", WI_NOORGANIZE}, /* Icon not affected by ORGANIZE */
- {"NOMOVE", WI_NOMOVE}, /* Icon can not be moved */
- {"LOCKED", WI_LOCKED}, /* Never change icon X,Y */
- {"NOMULTISELECT",WI_NOMULTISELECT}, /* No more than one icon selectable */
- {"CHANGEREFRESH",WI_CHANGEREFRESH}, /* Automatically change refresh type */
- };
- #define MAXICONFLAG 8
-
-
- /*
- * Qualifier key names and flags for ReadKeyDefinition()
- */
-
- static struct Flag KeyFlag[] =
- {
- {"LSHIFT", IEQUALIFIER_LSHIFT},
- {"RSHIFT", IEQUALIFIER_RSHIFT},
- {"CAPSLOCK", IEQUALIFIER_CAPSLOCK},
- {"CONTROL", IEQUALIFIER_CONTROL},
- {"LALT", IEQUALIFIER_LALT},
- {"RALT", IEQUALIFIER_RALT},
- {"LCOMMAND", IEQUALIFIER_LCOMMAND},
- {"RCOMMAND", IEQUALIFIER_RCOMMAND},
- {"LAMIGA", IEQUALIFIER_LCOMMAND},
- {"RAMIGA", IEQUALIFIER_RCOMMAND},
- {"NUMERICPAD", IEQUALIFIER_NUMERICPAD},
- {"REPEAT", IEQUALIFIER_REPEAT},
- {"MBUTTON", IEQUALIFIER_MIDBUTTON},
- {"RBUTTON", IEQUALIFIER_RBUTTON},
- {"LBUTTON", IEQUALIFIER_LEFTBUTTON},
- };
- #define MAXKEYFLAG 15
-
- /*
- * Key names and numbers for ReadKeyDefinition()
- */
-
- #define KEY(x) (x|IECODE_UP_PREFIX)
- struct Flag KeyName[] =
- {
- {"RBUTTONPRESS", MENUUP},
- {"LBUTTONPRESS", SELECTUP},
- {"F1", KEY(0x50)},
- {"F2", KEY(0x51)},
- {"F3", KEY(0x52)},
- {"F4", KEY(0x53)},
- {"F5", KEY(0x54)},
- {"F6", KEY(0x55)},
- {"F7", KEY(0x56)},
- {"F8", KEY(0x57)},
- {"F9", KEY(0x58)},
- {"F10", KEY(0x59)},
- {"ESC", KEY(0x45)},
- {"ENTER", KEY(0x43)},
- {"RETURN", KEY(0x44)},
- {"BACKSPACE",KEY(0x41)},
- {"DELETE", KEY(0x46)},
- {"HELP", KEY(0x5F)},
- {"TAB", KEY(0x42)},
- {"SPACE", KEY(0x40)}
- };
- #define MAXKEYNAME 20
-
-
- /*
- * Menu names and IDs
- */
-
- struct Flag MenuName[] =
- {
- {"OPEN", MENUID(ICON_MENU,IM_OPEN,NOSUB)},
- {"CLOSE", MENUID(ICON_MENU,IM_CLOSE,NOSUB)},
- {"LOCK", MENUID(ICON_MENU,IM_LOCK,NOSUB)},
- {"UNLOCK", MENUID(ICON_MENU,IM_LOCK,NOSUB)},
- {"CLEAN_UP", MENUID(ICON_MENU,IM_CLEANUP,NOSUB)},
- {"ORGANIZE", MENUID(ICON_MENU,IM_ORGANIZE,NOSUB)},
- {"OPEN_ALL", MENUID(ICON_MENU,IM_OPENALL,NOSUB)},
- {"ABOUT", MENUID(ICON_MENU,IM_ABOUT,NOSUB)},
- {"END", MENUID(ICON_MENU,IM_END,NOSUB)},
- {"TO_FRONT", MENUID(SCREEN_MENU,SM_TOFRONT,NOSUB)},
- {"TO_BACK", MENUID(SCREEN_MENU,SM_TOBACK,NOSUB)},
- {"WB_TO_FRONT", MENUID(SCREEN_MENU,SM_WBTOFRONT,NOSUB)},
- {"TOGGLE_TITLE", MENUID(SCREEN_MENU,SM_TOGGLE,NOSUB)},
- {"ICONIFY", MENUID(SCREEN_MENU,SM_ICONIFY,NOSUB)},
- {"NEWCLI", MENUID(SCREEN_MENU,SM_NEWCLI,NOSUB)},
- {"MAKE_WB", MENUID(SCREEN_MENU,SM_MAKEWB,NOSUB)},
- {"ACTIVE_SCREEN", MENUID(SCREEN_MENU,SM_OPENWINDOW,OW_ACTIVESCRN)},
- {"CURRENT_WB", MENUID(SCREEN_MENU,SM_OPENWINDOW,OW_CURRENTWB)},
- {"REAL_WB", MENUID(SCREEN_MENU,SM_OPENWINDOW,OW_REALWB)},
- {"SIZE_TO_FIT", MENUID(SCREEN_MENU,SM_OPENWINDOW,OW_AUTORESIZE)},
- {"HIRES", MENUID(SCREEN_MENU,SM_NEWSCREEN,NS_HIRES)},
- {"LORES", MENUID(SCREEN_MENU,SM_NEWSCREEN,NS_LORES)},
- {"INTERLACE", MENUID(SCREEN_MENU,SM_NEWSCREEN,NS_INTERLACE)},
- {"HAM", MENUID(SCREEN_MENU,SM_NEWSCREEN,NS_HAM)},
- {"CLOSE_SCREEN", MENUID(SCREEN_MENU,SM_CLOSESCREEN,NOSUB)},
- };
- #define MAXMENU 25
-
-
-
- /*
- * ReadCommand()
- *
- * If we're at the end of the line, read the next line.
- * Get the next word on the line.
- * If we have readed the end of the file, use COM_EOF
- * Otherwise, if the character following the next word is not ':'
- * then we have not found a command, so use COM_NONE,
- * Otherwise,
- * Look for the command in the current command table, and skip the ':'
- * Return the number of the command found.
- */
-
- int ReadCommand()
- {
- int Command = COM_UNKNOWN;
- short i;
-
- if (NextChar == '\n' || NextChar == 0) ReadNextLine();
- ReadNextWord();
- if (EndOfFile) Command = COM_EOF; else
- if (NextChar != ':') Command = COM_NONE;
- else
- {
- for (i=0; i<=ComCount && Command == COM_UNKNOWN; i++)
- if (WORDMATCH(ComName[i])) Command = i + ComOffset;
- SkipChar();
- }
- return(Command);
- }
-
-
- /*
- * ReadKeyDef()
- *
- * Parse the next word as a qualifier or key name.
- * If theKey is NULL, no key name is allowed, if DisQual is NULL, no
- * disqualifiers are allowed.
- *
- * If the next character is '\' and we are accepting key names,
- * Go back to the start of the word and skip the '\'
- * If the next char is a HEX digit,
- * Get the HEX value of the next char and get the following char.
- * If the following char is a HEX digit,
- * Shift the old hex digit by 16 (10 HEX), add the next digit,
- * and get the next character
- * Skip any blanks.
- * Mark the code as a key-up event
- * Otherwise give an error message.
- * Indicate that this should be the end of the line.
- * Otherwise (not a '\')
- * If the word is '+' or '|', ie, a qualifier, then
- * If there were no qualifiers or disqualifiers given, give a message
- * Get the next word (the qualifier itself)
- * Otherwise, if the word is '-', ie, a disqualifier, then
- * Check to make sure disqualifiers are allowed; error if not.
- * Get the disqualifier.
- * Look through the qualifier flag names for a match.
- * If a match is found,
- * add the qualifier to the proper list and end the loop
- * If no qualifier was found,
- * If we are allowed to have a key name,
- * Go back to the beginning of the word, and re-read it allowing numbers
- * Look through the key name list
- * If a match is found,
- * Record the key number and end the loop.
- * Indicate that this should be the end of the line.
- * If no match found, give an error.
- * Otherwise (no key name allowed) give an error.
- * Return the end-of-line status.
- */
-
- int ReadKeyDef(theKey,theQual,DisQual)
- UBYTE *theKey;
- USHORT *theQual,*DisQual;
- {
- short i;
- int AddIt = TRUE;
- int EndOfLine = FALSE;
- int OpMissing;
-
- if (Word[0] == '\\' && theKey)
- {
- Reread(); GetNextChar();
- if (HEXCHAR(NextChar))
- {
- *theKey = HEX(NextChar);
- GetNextChar();
- if (HEXCHAR(NextChar))
- {
- *theKey = 16*(*theKey) + HEX(NextChar);
- GetNextChar();
- }
- SkipSpaces();
- *theKey |= IECODE_UP_PREFIX;
- } else Expected("HEX char");
- EndOfLine = TRUE;
- } else {
- if (Word[0] == '+' || Word[0] == '|')
- {
- if (*theQual == 0)
- {
- if (DisQual == NULL) OpMissing = TRUE; else
- if (*DisQual == 0) OpMissing = TRUE; else OpMissing = FALSE;
- if (OpMissing) ShowError("Missing Qualifier before '%c'",Word[0]);
- }
- ReadNextWord();
- } else if (Word[0] == '-') {
- if (DisQual) AddIt = FALSE; else
- ShowError("Disqualifiers not allowed");
- ReadNextWord();
- }
- for (i=0; i<MAXKEYFLAG; i++)
- {
- if (WORDMATCH(KeyFlag[i].Name))
- {
- if (AddIt) *theQual |= KeyFlag[i].Flag;
- else *DisQual |= KeyFlag[i].Flag;
- i = MAXKEYFLAG+1;
- }
- }
- if (i == MAXKEYFLAG)
- {
- if (theKey)
- {
- Reread(); ReadExtendedWord();
- for (i=0; i<MAXKEYNAME; i++)
- {
- if (WORDMATCH(KeyName[i].Name))
- {
- *theKey = KeyName[i].Flag;
- i = MAXKEYNAME+1;
- EndOfLine = TRUE;
- }
- }
- if (i == MAXKEYNAME) Expected("a Key-Name or Qualifier");
- } else Expected("a Qualifier");
- }
- }
- return(EndOfLine);
- }
-
-
- /*
- * ReadColor()
- *
- * If the color number is a valid one,
- * Go back to the beginning of the word and read it as a number.
- * Set it to upper case (for HEX check).
- * If the word is '=', set the color value to NOCOLOR
- * If the color is a valid color specification, get the color value
- * If the color is '*' leave the color alone,
- * Otherwise, give an error.
- * Otherwise give an error about how many colors are allowed.
- */
-
- void ReadColor(theID)
- short theID;
- {
- extern UWORD *ScreenColors;
-
- if (theID < 32)
- {
- Reread(); ReadExtendedWord(); WordToUpper();
- if (WORDMATCH("=")) ScreenColors[theID] = NOCOLOR; else
- if (VALIDCOLOR(Word)) ScreenColors[theID] = COLOR(Word); else
- if (WORDMATCH("*") == FALSE) Expected("an RGB Color");
- } else ShowError("Maximum of 32 colors exceeded");
- }
-
-
- /*
- * ReadIconFlags()
- *
- * If the word is '+' or '|', then
- * If there were no previous flags specified, give an error
- * The next word is the flag name
- * Look through the flag names
- * If one of them matches,
- * Add the flag to the default flags and end the loop
- * If no flag found, give an error.
- */
-
- void ReadIconFlags(Flags)
- long *Flags;
- {
- short i;
-
- if (Word[0] == '|' || Word[0] == '+')
- {
- if (*Flags == 0)
- ShowError("Missing Icon Flag before '%c'",Word[0]);
- ReadNextWord();
- }
- for (i=0; i<MAXICONFLAG; i++)
- {
- if (WORDMATCH(IconFlag[i].Name))
- (*Flags) |= IconFlag[i].Flag,
- i = MAXICONFLAG+1;
- }
- if (i == MAXICONFLAG) Expected("an Icon Flag");
- }
-
-
- /*
- * ReadMenuKey()
- *
- * Look through the menu names
- * If one of them matches,
- * Get the pointer to the specified item in the menu bar structure;
- * If there is no command key, clear the COMSEQ flag for the item,
- * Otherwise,
- * Get the next word and make it upper case
- * If it is a control character, report an error;
- * If it is more than one characterm report an error;
- * Otherwise, set the command key to the indicated one.
- * End the loop.
- * If no match was found, give an error, and skip the rest of the line.
- */
-
- void ReadMenuKey()
- {
- short i;
- struct MenuItem *theItem;
- extern struct MenuItem *ItemAddress();
- extern struct Menu *wMenuBar;
-
- for (i=0; i<MAXMENU; i++)
- {
- if (WORDMATCH(MenuName[i].Name))
- {
- theItem = ItemAddress(wMenuBar,MenuName[i].Flag);
- if (NextChar == '\n')
- {
- theItem->Flags &= ~COMMSEQ;
- theItem->Command = 0;
- } else {
- ReadNextWord(); WordToUpper();
- if (Word[0] < ' ') Expected("a Printable Character"); else
- if (Word[1] != 0) Expected("a Single Character");
- else theItem->Flags |= COMMSEQ, theItem->Command = Word[0];
- }
- i = MAXMENU+1;
- }
- }
- if (i == MAXMENU)
- {
- if (strlen(Word) > 1) ShowError("Unrecognized Menu '%s'",Word);
- else Expected("a Menu Item Name");
- SkipLine();
- }
- }
-
-
- /*
- * ReadBool()
- *
- * If the word is "TRUE", return TRUE.
- * If the word is "FALSE", return FALSE.
- * Otherwise, give an error.
- */
-
- void ReadBool(n)
- int *n;
- {
- if (WORDMATCH("TRUE")) *n = TRUE; else
- if (WORDMATCH("FALSE")) *n = FALSE; else
- Expected("TRUE or FALSE");
- }
-
-
- /*
- * ReadInteger()
- *
- * Parse the next word as an integer.
- * If the word is an integer, return it, otherwise give an error.
- */
-
- void ReadInteger(i)
- int *i;
- {
- ReadNextInteger();
- if (sscanf(Word,"%d",i) != 1) Expected("Integer value");
- }
-
-
- /*
- * ReadString()
- *
- * Get the whole line as the next word.
- * If the character string has already been read, free it.
- * Get enough space for the new string, and copy the value into it.
- * Of not enough space, give an error.
- */
-
- void ReadString(s)
- char **s;
- {
- ReadFullLine();
- if (*s) FREECHAR(*s);
- if (NEWCHAR(*s,strlen(Word))) strcpy(*s,Word); else
- ShowError("Can't get memory for character string");
- }
-
-
- /*
- * ReadIgnoreScreen()
- *
- * Get a new Ignore structure; if allocated OK,
- * Read the title of the screen.
- * If a title was found, add the screen to the ignored list,
- * Otherwise, free the Ignore structure.
- * Otherwise, give an error and skip the rest of the line.
- */
-
- void ReadIgnoreScreen()
- {
- struct Ignore *theScreen;
-
- if (NEWSTRUCT(Ignore,theScreen))
- {
- ReadString(&theScreen->Title);
- if (theScreen->Title)
- {
- theScreen->Next = IgnoreScreen;
- IgnoreScreen = theScreen;
- } else {
- FREESTRUCT(Ignore,theScreen);
- }
- } else {
- ShowError("Can't get memory to Ignore Screen");
- SkipLine();
- }
- }
-
-
- /*
- * GetPen()
- *
- * Look for the given HEX digit in the extended HEX list.
- * If not found,
- * Give an error message and count the number of errors.
- * If more than the maximum allowed, skip the rest of the line.
- * If the image type is a MASK, and the pen is not 0 or 1,
- * If there were no previous errors of this type, give one.
- * Mark that the user was warned about mask pen types.
- * Reduce the pen number to 0 or 1.
- * Return the pen color.
- */
-
- static UBYTE GetPen(c)
- char c;
- {
- UBYTE Pen = 0;
- short i;
-
- for (i=0; i<32; i++) if (c == ExtHex[i]) Pen = i, i = 33;
- if (i == 32)
- {
- Expected("HEX Digit"); ErrorCount++;
- if (ErrorCount > MAXERROR)
- printf("Maximum errors exceeded - skipping rest of line\n"),
- SkipLine();
- }
- if (Pen > 1 && (ImageType == COM_DEFAULTMASK || ImageType == COM_SCREENMASK))
- {
- if (NoMaskError) ShowError("Mask pixel values must be 0 or 1");
- NoMaskError = FALSE;
- Pen = Pen & 1;
- }
- return(Pen);
- }
-
-
- /*
- * ReadImageLine()
- *
- * If the current line is within the maximum image size,
- * Clear the error flags, and get back to the beginning of the line.
- * While we're not at the end of the line,
- * If the current column is within the maximum image size,
- * Get the pen number of the current pixel, and increment the column.
- * Update Plane0 and Plane1 (Plane0 has a zero wherever that plane
- * has at least one pixel that is zero; Plane1 has a 1 wherever
- * that plane has at least one pixel that is one).
- * If the bit mask has wrapped around, go on to the next image word.
- * For each 1 bit in the Pen color, add a 1 bit into the image data
- * Shift the image mask to the right.
- * Get the next pixel's pen color and skip any comments.
- * Skip trailing blanks (but not interior blanks).
- * Otherwise, indicate that the width is too large and skip to the
- * end of the line.
- * Update the current image size, if necessary.
- * Otherwise, indicate that the icon is too tall, and skip to the next line.
- */
-
- void ReadImageLine(y)
- short y;
- {
- short x = 0, w = 0;
- short d;
- UWORD mask = BIT(15);
- UBYTE Pen;
-
- if (y < MAXHEIGHT)
- {
- NoMaskError = TRUE; ErrorCount = 0;
- Reread();
- while (NextChar != '\n')
- {
- if (x < MAXWIDTH)
- {
- Pen = GetPen(NextChar); x++;
- Plane0 &= Pen; Plane1 |= Pen; d = 0;
- if (mask == 0) w++, mask = BIT(15);
- while (Pen)
- {
- if (Pen & 1) ImageData[w][y][d] |= mask;
- Pen >>= 1; d++;
- }
- mask >>= 1;
- GetNextChar(); SkipComments();
- if (NextChar == ' ')
- {
- SkipSpaces();
- if (NextChar != '\n') Reread();
- }
- } else {
- ReadFullLine();
- ShowError("Maximum Image Width of %d exceeded",MAXWIDTH);
- }
- }
- if (x > MaxWidth) MaxWidth = x, MaxWords = w+1;
- if (y+1 > MaxHeight) MaxHeight = y+1;
- if (MaxWidth > MAXWIDTH) MaxWidth = MAXWIDTH;
- } else {
- ReadFullLine();
- ShowError("Maxmimum Image Height of %d exceeded",MAXHEIGHT);
- }
- }
-
-
- /*
- * ReadIconFile()
- *
- * Get the rest of the line (it will be the file name to open)
- * Save the current file information.
- * Attempt to open the specified file.
- * If openned OK, then
- * Set the icon file flag,
- * Set the command list to the icon file command list and size.
- * Otherwise,
- * Put back the old file information,
- * Give an error about the icon file.
- */
-
- void ReadIconFile(Offset)
- int Offset;
- {
- ReadFullLine();
- SaveOpenFile();
- if (OpenFile(Word))
- {
- IconFileOpen = TRUE;
- ComName = &IconCommand[0];
- ComOffset = Offset;
- ComCount = MAXICONCOM;
- } else {
- RestoreFile();
- ShowError("Can't open Icon file '%s'",Word);
- }
- }
-
-
- /*
- * EndIconFile()
- *
- * Put back the old file information
- * Mark the file as closed, and restore the command list to the main list.
- */
-
- void EndIconFile()
- {
- RestoreFile();
- IconFileOpen = FALSE;
- ComName = &MainCommand[0];
- ComOffset = 0;
- ComCount = MAXMAINCOM;
- }
-
-
- /*
- * ReadOpenOn()
- *
- * Check if the word is one of "ACTIVE_SCREEN", "CURRENT_WB", or "REAL_WB",
- * and return the correct type, otherwise give an error.
- */
-
- void ReadOpenOn()
- {
- if (WORDMATCH("ACTIVE_SCREEN")) ScreenType = OW_ACTIVESCRN; else
- if (WORDMATCH("CURRENT_WB")) ScreenType = OW_CURRENTWB; else
- if (WORDMATCH("REAL_WB")) ScreenType = OW_REALWB; else
- Expected("ACTIVE_SCREEN, CURRENT_WB, or REAL_WB");
- }
-