home *** CD-ROM | disk | FTP | other *** search
- /* > $.CLIB.C.iconbuild
- *
- * HASWIN Graphics Library
- * =========================
- *
- * Copyright (C) H.A.Shaw 1990.
- * Howard A. Shaw.
- * The Unit for Space Sciences,
- * Room 165,
- * Physics Building,
- * University of Kent at Canterbury.
- * Canterbury.
- * Kent. CT2 7NJ
- * You may use and distribute this code freely, however please leave
- * it alone. If you find bugs (and there will be many) please contact
- * me and the master source can be modified. If you keep me informed
- * of who you give copies of this to then I can get release upgrades
- * to them.
- *
- * These routines deal with making and deleting icons.
- */
- #include "includes.h"
-
- /*
- * build an icon.
- *
- * An icon is built from a string of the following form...
- *
- * [opts]:item ...
- *
- * item - item name.
- *
- * opts - one of:
- * <sp>, - spacer, ignored.
- * T - Text icon (default).
- * S - Sprite icon, can be combined with T.
- * B - icon has border.
- * PNN - button type NN (<sp>, ends). (default is 10)
- * ENN - button ESG, 0 to 31, (<sp> ends). (default is 0)
- * < - left adjust text.
- * > - right adjust text.
- * F - filled background.
- * h - display any sprite 1/2 size.
- * ? - icon needs help to redraw.
- * ! - do not select.
- * * - force selection.
- * +NN - make icon writable, buffer length NN (<sp>, ends).
- * ^ - vertical centering.
- * ~ - don't cancel on selection of another in ESG.
- * &NN - background colour (<sp>, ends).
- * @NN - foreground colour (<sp>, ends).
- * {str} - validation string "str".
- * [blk] - sprite area control block "blk".
- * : - everything after is item name.
- * `font` - use antialiased font called "font".
- * $NN - use antialiased font NN (<sp>, ends).
- * XNN - antialiased font X size is NN (<sp>, ends).
- * YNN - antialiased font Y size is NN (<sp>, ends).
- * "" - dont use replacement inside here.
- * () - comment, ignored (can be nested).
- * all others are ignored, but placed in the "unknown" array.
- *
- * NOTE: items in '...' quotes are ignored. The ' marks are removed
- * however.
- *
- * "fc" and "bc" are the icon's colours.
- * "esg" is the esg number.
- * "*res" is a pointer to an array of at least 4 integers.
- * res[0] is the icon flags word.
- * res[1] is a pointer to the text buffer.
- * res[2] is a pointer to the validation string, or Sprite CB.
- * res[3] is the length of the text buffer.
- * unknown options are placed in the buffer "unknown", which is
- * "unlen" long.
- */
- int haswin_buildiconflags(char *list, int fc, int bc, int esg, int *res, char *unknown, int unlen) {
-
- static char *str = 0;
- char *ptr, *ptr1, *font, *valid, *area, *name;
- int quoted, numstate, i, flags, adjmode, writable;
- int esgnum, fcnum, bcnum, wrnum, btype, sarea;
- int fontnum, fontx, fonty;
-
- str = haswin_realloc(str, asciilen(list)+1, "haswin_buildiconflags", "temp buffer");
- strcpy(str, list);
- /*
- * first scan the string, building the icon flags, font, sprite area,
- * validation string, writeable buffer length, colours, esg etc.
- */
- numstate = adjmode = 0;
- quoted = fontnum = fcnum = bcnum = wrnum = writable = 0;
- btype = sarea = fontx = fonty = esgnum = -1;
- font = valid = area = (char *)0;
- /* initialise flag, force indirected bit */
- flags = 0x00000100;
- ptr=str;
- while ((*ptr) && (*ptr != ':')) {
- if (quoted) {
- if (*ptr == '\'')
- quoted = HASWIN_FALSE;
- } else {
- switch (*ptr) {
- case '\'':
- quoted = HASWIN_TRUE;
- break;
- case ' ':
- case ',':
- numstate = 0;
- break;
- case '(': /* comment (can be nested) */
- numstate = 0;
- i=0;
- ptr1 = ptr;
- while (*ptr) {
- if (*ptr == '(')
- i++;
- else if (*ptr == ')') {
- i--;
- if (i == 0)
- break;
- }
- ptr++;
- }
- if (*ptr == '\0') {
- haswin_interrorprintf("haswin_buildiconflags: invalid comment string %s in %s", ptr1, list);
- }
- break;
- case '{': /* validation string */
- numstate = 0;
- valid = ++ptr;
- while ((*ptr) && (*ptr != '}'))
- ptr++;
- if (*ptr == '\0') {
- haswin_interrorprintf("haswin_buildiconflags: invalid validation string %s in %s", valid, list);
- }
- *ptr = '\0';
- break;
- case '[': /* sprite area string */
- numstate = 0;
- area = ++ptr;
- while ((*ptr) && (*ptr != ']'))
- ptr++;
- if (*ptr == '\0') {
- haswin_interrorprintf("haswin_buildiconflags: invalid sprite area string %s in %s", valid, list);
- }
- *ptr = '\0';
- break;
- case '`': /* font name string */
- numstate = 0;
- font = ++ptr;
- while ((*ptr) && (*ptr != '`'))
- ptr++;
- if (*ptr == '\0') {
- haswin_interrorprintf("haswin_buildiconflags: invalid font name string %s in %s", valid, list);
- }
- *ptr = '\0';
- break;
- case 'T': /* text */
- flags |= 0x00000001;
- break;
- case 'S': /* sprite */
- flags |= 0x00000002;
- break;
- case 'B': /* border */
- flags |= 0x00000004;
- break;
- case '^': /* vertical centring */
- flags |= 0x00000010;
- break;
- case 'F': /* filled */
- flags |= 0x00000020;
- break;
- case '?': /* needs help to redraw */
- flags |= 0x00000080;
- break;
- case '~': /* don't cancel on ESG */
- flags |= 0x00000400;
- break;
- case 'h': /* half size */
- flags |= 0x00000800;
- break;
- case '*': /* force selection */
- flags |= 0x00200000;
- break;
- case '!': /* can't select */
- flags |= 0x00400000;
- break;
- case '<': /* left adjust */
- adjmode |= 2;
- break;
- case '>': /* right adjust */
- adjmode |= 1;
- break;
- case ':': /* rest is icon name */
- numstate = 0;
- break;
- case 'Y': /* font Y size */
- numstate = 7;
- fonty = 0;
- break;
- case 'X': /* font X size */
- numstate = 6;
- fontx = 0;
- break;
- case 'P': /* button press type */
- numstate = 5;
- btype = 0;
- break;
- case 'E': /* button ESG type */
- numstate = 8;
- esgnum = 0;
- break;
- case '+': /* writable icon */
- writable++;
- numstate = 4;
- wrnum = 0;
- break;
- case '&': /* background colour */
- numstate = 3;
- bcnum = 0;
- break;
- case '@': /* foreground colour */
- numstate = 2;
- fcnum = 0;
- break;
- case '$': /* font number */
- numstate = 1;
- fontnum = 0;
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (numstate) {
- switch (numstate) {
- case 1:
- fontnum=fontnum*10+ *ptr-'0';
- break;
- case 2:
- fcnum = fcnum*10 + *ptr-'0';
- break;
- case 3:
- bcnum = bcnum*10 + *ptr-'0';
- break;
- case 4:
- wrnum = wrnum*10 + *ptr-'0';
- break;
- case 5:
- btype = btype*10 + *ptr-'0';
- break;
- case 6:
- fontx = fontx*10 + *ptr-'0';
- break;
- case 7:
- fonty = fonty*10 + *ptr-'0';
- break;
- case 8:
- esgnum= esgnum*10 + *ptr-'0';
- break;
- }
- break;
- }
- /* FALL THRU */
- default:
- if (unknown == 0) {
- haswin_interrorprintf("haswin_buildiconflags: unknown option %c in %s", *ptr, list);
- } else if (unlen <= 0) {
- haswin_interrorprintf("haswin_buildiconflags: too many unknown options in %s, %c is last handled", list, *ptr);
- unlen--;
- } else
- *(unknown++) = *ptr;
- break;
- }
- }
- ptr++;
- }
- if (quoted) {
- haswin_interrorprintf("haswin_buildiconflags: no terminating \' quote in icon options %s", str);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- if (esgnum != -1) {
- if ((esgnum < 0) || (esgnum > 31)) {
- haswin_interrorprintf("haswin_buildiconflags: bad ESG in %s", str);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- flags |= (esgnum&0x1F)<<16;
- } else {
- if ((esg < 0) || (esg > 31)) {
- haswin_interrorprintf("haswin_buildiconflags: bad ESG passed to '%s'", str);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- flags |= (esg&0x1F)<<16;
- }
- if (*ptr == ':')
- ptr++;
- /*
- * ptr points to the end of the string (name of icon) or \0
- * if no name.
- *
- * cross check some of the options and flags to prevent illegal
- * combinations.
- */
- switch (flags & 0x00000003) {
- case 0: /* assume text by default */
- flags |= 0x00000001;
- /* FALL THRU */
- case 1: /* text icon */
- if (area) {
- haswin_interrorprintf("haswin_buildiconflags: can't have a text icon with a sprite area pointer in %s", list);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- if (flags & 0x00000800) {
- haswin_interrorprintf("haswin_buildiconflags: can't have a text icon with a 1/2 size sprite flag in %s", list);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- if (adjmode == 3) {
- haswin_interrorprintf("haswin_buildiconflags: can't have left and right adjust in a text icon in %s", list);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- break;
- case 2: /* sprite icon */
- if (valid) {
- haswin_interrorprintf("haswin_buildiconflags: can't have a sprite icon with a validation string in %s", list);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- if ((font) || (fontnum)) {
- haswin_interrorprintf("haswin_buildiconflags: can't have a sprite icon in an antialiased font in %s", list);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- if (writable) {
- haswin_interrorprintf("haswin_buildiconflags: can't have a writable sprite icon in %s", list);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- break;
- case 3: /* sprite+text icon */
- if (area) {
- haswin_interrorprintf("haswin_buildiconflags: can't have a text+sprite icon with a sprite area pointer in %s", list);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- if ((font) || (fontnum)) {
- haswin_interrorprintf("haswin_buildiconflags: can't have a sprite+text icon in an antialiased font in %s", list);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- if (writable) {
- haswin_interrorprintf("haswin_buildiconflags: can't have a writable text+sprite icon in %s", list);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- break;
- }
- if ((fontnum) && (font)) {
- haswin_interrorprintf("haswin_buildiconflags: can't have both $%d and `%s` in %s", fontnum, font, list);
- if (unknown)
- *unknown = '\0';
- return(HASWIN_FALSE);
- }
- /* setup colours */
- if (!fcnum)
- fcnum = fc;
- if (!bcnum)
- bcnum = bc;
- if ((!fontnum) && (!font)) {
- if (fontx != -1) {
- haswin_interrorprintf("haswin_buildiconflags: ignoring X%d in system font in %s", fontx, list);
- }
- if (fonty != -1) {
- haswin_interrorprintf("haswin_buildiconflags: ignoring Y%d in system font in %s", fonty, list);
- }
- /* not got a font number or name, so system font icon */
- flags |= (fcnum&0x0F)<<24;
- flags |= (bcnum&0x0F)<<28;
- if (valid) {
- sarea = (int)haswin_malloc(asciilen(valid)+1, "haswin_buildiconflags", "validation string buffer");
- strcpy((char *)sarea, valid);
- } else if (area)
- sarea = atoint(area);
- else if (flags & 0x00000002) {
- /* we havn't been given a sprite area, so look for one */
- if ((sarea=haswin_findsprite(ptr)) == HASWIN_UNKNOWN) {
- haswin_interrorprintf("haswin_buildiconflags: can't find area for sprite %s in %s", ptr, list);
- sarea = 0;
- }
- }
- } else if (fontnum) {
- if (fontx != -1) {
- haswin_interrorprintf("haswin_buildiconflags: ignoring X%d in font number $%d in %s", fontx, fontnum, list);
- }
- if (fonty != -1) {
- haswin_interrorprintf("haswin_buildiconflags: ignoring Y%d in font number $%d in %s", fonty, fontnum, list);
- }
- flags |= 0x00000040 | (fontnum&0xFF)<<24;
- if (valid) {
- /* add font colours to validation string */
- sarea = (int)haswin_malloc(asciilen(valid)+5, "haswin_buildiconflags", "validation string buffer");
- sprintf((char *)sarea, "%s;F%1.1X%1.1X", valid, fcnum, bcnum);
- } else {
- sarea = (int)haswin_malloc(5, "haswin_buildiconflags", "validation string buffer");
- sprintf((char *)sarea, "F%1.1X%1.1X", fcnum, bcnum);
- }
- } else {
- if (fontx == -1)
- fontx = 14; /* default 14 point */
- if (fonty == -1)
- fonty = 14; /* default 14 point */
- fontnum = haswin_findfont(font, fontx, fonty, 0, 0);
- if (!fontnum) {
- haswin_interrorprintf("haswin_buildiconflags: font name `%s` not found, using system font", font);
- flags |= (fcnum&0x0F)<<24;
- flags |= (bcnum&0x0F)<<28;
- if (valid) {
- sarea = (int)haswin_malloc(asciilen(valid)+1, "haswin_buildiconflags", "validation string buffer");
- strcpy((char *)sarea, valid);
- } else if (area)
- sarea = atoint(area);
- else if (flags & 0x00000002) {
- /* we havn't been given a sprite area, so look for one */
- if ((sarea=haswin_findsprite(ptr)) == HASWIN_UNKNOWN) {
- haswin_interrorprintf("haswin_buildiconflags: can't find area for sprite %s in %s", ptr, list);
- sarea = 0;
- }
- }
- } else {
- flags |= 0x00000040 | (fontnum&0xFF)<<24;
- if (valid) {
- /* add font colours to validation string */
- sarea = (int)haswin_malloc(asciilen(valid)+5, "haswin_buildiconflags", "validation string buffer");
- sprintf((char *)sarea, "%s;F%1.1X%1.1X", valid, fcnum, bcnum);
- } else {
- sarea = (int)haswin_malloc(5, "haswin_buildiconflags", "validation string buffer");
- sprintf((char *)sarea, "F%1.1X%1.1X", fcnum, bcnum);
- }
- }
- }
- switch (adjmode) {
- case 0: /* no adjustment, centre */
- flags |= 0x00000008;
- break;
- case 1: /* right adjust */
- flags |= 0x00000200;
- break;
- case 2: /* left adjust */
- break;
- case 3: /* both adjustments for text+sprite */
- flags |= 0x00000208;
- break;
- }
- if (writable) {
- if ((btype != -1) && (btype != 14) && (btype != 15)) {
- haswin_interrorprintf("haswin_buildiconflags: can't have a writable icon with button type [%d] in %s", btype, list);
- }
- name = haswin_malloc(wrnum+1, "haswin_buildiconflags", "writable icon buffer");
- i=0;
- strnqcpy(name, ptr, wrnum);
- if ((btype == 14) || (btype == 15))
- flags |= btype<<12; /* set button type */
- else
- flags |= 0x0000F000; /* set button type writable */
- res[0] = flags;
- res[1] = (int)name;
- res[2] = (int)sarea;
- res[3] = wrnum;
- } else {
- name = haswin_malloc(asciilen(ptr)+1, "haswin_buildiconflags", "icon name buffer");
- strqcpy(name, ptr);
- if (btype == -1)
- flags |= 0x0000A000; /* button type for click/drag */
- else if ((btype < 0) || (btype > 13)) {
- haswin_interrorprintf("haswin_buildiconflags: bad button type in %s", list);
- flags |= 0x0000A000; /* button type for click/drag */
- } else if ((btype == 14) || (btype == 15)) {
- haswin_interrorprintf("haswin_buildiconflags: can't have a writable button type in non writable icon in %s", list);
- flags |= 0x0000A000; /* button type for click/drag */
- } else
- flags |= btype<<12; /* set button type */
- res[0] = flags;
- res[1] = (int)name;
- res[2] = (int)sarea;
- res[3] = asciilen(name);
- }
- if (unknown)
- *unknown = '\0';
- return(HASWIN_TRUE);
- }
-
-