home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / clib / progs / haswinlib / c / iconbuild < prev    next >
Encoding:
Text File  |  1991-02-04  |  24.1 KB  |  514 lines

  1. /* > $.CLIB.C.iconbuild
  2.  *
  3.  *      HASWIN Graphics Library
  4.  *     =========================
  5.  *
  6.  *      Copyright (C) H.A.Shaw 1990.
  7.  *              Howard A. Shaw.
  8.  *              The Unit for Space Sciences,
  9.  *              Room 165,
  10.  *              Physics Building,
  11.  *              University of Kent at Canterbury.
  12.  *              Canterbury.
  13.  *              Kent.  CT2 7NJ
  14.  *      You may use and distribute this code freely, however please leave
  15.  *      it alone.  If you find bugs (and there will be many) please contact
  16.  *      me and the master source can be modified.  If you keep me informed
  17.  *      of who you give copies of this to then I can get release upgrades
  18.  *      to them.
  19.  *
  20.  *      These routines deal with making and deleting icons.
  21.  */
  22. #include "includes.h"
  23.  
  24. /*
  25.  *      build an icon.
  26.  *
  27.  *      An icon is built from a string of the following form...
  28.  *
  29.  *      [opts]:item ...
  30.  *
  31.  *      item  - item name.
  32.  *
  33.  *      opts  - one of:
  34.  *            <sp>,   - spacer, ignored.
  35.  *            T       - Text icon (default).
  36.  *            S       - Sprite icon, can be combined with T.
  37.  *            B       - icon has border.
  38.  *            PNN     - button type NN (<sp>, ends). (default is 10)
  39.  *            ENN     - button ESG, 0 to 31, (<sp> ends).  (default is 0)
  40.  *            <       - left adjust text.
  41.  *            >       - right adjust text.
  42.  *            F       - filled background.
  43.  *            h       - display any sprite 1/2 size.
  44.  *            ?       - icon needs help to redraw.
  45.  *            !       - do not select.
  46.  *            *       - force selection.
  47.  *            +NN     - make icon writable, buffer length NN (<sp>, ends).
  48.  *            ^       - vertical centering.
  49.  *            ~       - don't cancel on selection of another in ESG.
  50.  *            &NN     - background colour (<sp>, ends).
  51.  *            @NN     - foreground colour (<sp>, ends).
  52.  *            {str}   - validation string "str".
  53.  *            [blk]   - sprite area control block "blk".
  54.  *            :       - everything after is item name.
  55.  *            `font`  - use antialiased font called "font".
  56.  *            $NN     - use antialiased font NN (<sp>, ends).
  57.  *            XNN     - antialiased font X size is NN (<sp>, ends).
  58.  *            YNN     - antialiased font Y size is NN (<sp>, ends).
  59.  *            ""      - dont use replacement inside here.
  60.  *            ()      - comment, ignored (can be nested).
  61.  *            all others are ignored, but placed in the "unknown" array.
  62.  *
  63.  *      NOTE: items in '...' quotes are ignored.  The ' marks are removed
  64.  *            however.
  65.  *
  66.  *      "fc" and "bc" are the icon's colours.
  67.  *      "esg" is the esg number.
  68.  *      "*res" is a pointer to an array of at least 4 integers.
  69.  *      res[0] is the icon flags word.
  70.  *      res[1] is a pointer to the text buffer.
  71.  *      res[2] is a pointer to the validation string, or Sprite CB.
  72.  *      res[3] is the length of the text buffer.
  73.  *      unknown options are placed in the buffer "unknown", which is
  74.  *      "unlen" long.
  75.  */
  76. int haswin_buildiconflags(char *list, int fc, int bc, int esg, int *res, char *unknown, int unlen) {
  77.  
  78.         static char       *str = 0;
  79.         char              *ptr, *ptr1, *font, *valid, *area, *name;
  80.         int               quoted, numstate, i, flags, adjmode, writable;
  81.         int               esgnum, fcnum, bcnum, wrnum, btype, sarea;
  82.         int               fontnum, fontx, fonty;
  83.  
  84.         str = haswin_realloc(str, asciilen(list)+1, "haswin_buildiconflags", "temp buffer");
  85.         strcpy(str, list);
  86. /*
  87.  *      first scan the string, building the icon flags, font, sprite area,
  88.  *      validation string, writeable buffer length, colours, esg etc.
  89.  */
  90.         numstate = adjmode = 0;
  91.         quoted = fontnum = fcnum = bcnum = wrnum = writable = 0;
  92.         btype = sarea = fontx = fonty = esgnum = -1;
  93.         font = valid = area = (char *)0;
  94. /* initialise flag, force indirected bit */
  95.         flags = 0x00000100;
  96.         ptr=str;
  97.         while ((*ptr) && (*ptr != ':')) {
  98.                 if (quoted) {
  99.                         if (*ptr == '\'')
  100.                                 quoted = HASWIN_FALSE;
  101.                 } else {
  102.                         switch (*ptr) {
  103.                         case '\'':
  104.                                 quoted = HASWIN_TRUE;
  105.                                 break;
  106.                         case ' ':
  107.                         case ',':
  108.                                 numstate = 0;
  109.                                 break;
  110.                         case '(': /* comment (can be nested) */
  111.                                 numstate = 0;
  112.                                 i=0;
  113.                                 ptr1 = ptr;
  114.                                 while (*ptr) {
  115.                                         if (*ptr == '(')
  116.                                                 i++;
  117.                                         else if (*ptr == ')') {
  118.                                                 i--;
  119.                                                 if (i == 0)
  120.                                                         break;
  121.                                         }
  122.                                         ptr++;
  123.                                 }
  124.                                 if (*ptr == '\0') {
  125.                                         haswin_interrorprintf("haswin_buildiconflags: invalid comment string %s in %s", ptr1, list);
  126.                                 }
  127.                                 break;
  128.                         case '{': /* validation string */
  129.                                 numstate = 0;
  130.                                 valid = ++ptr;
  131.                                 while ((*ptr) && (*ptr != '}'))
  132.                                         ptr++;
  133.                                 if (*ptr == '\0') {
  134.                                         haswin_interrorprintf("haswin_buildiconflags: invalid validation string %s in %s", valid, list);
  135.                                 }
  136.                                 *ptr = '\0';
  137.                                 break;
  138.                         case '[': /* sprite area string */
  139.                                 numstate = 0;
  140.                                 area = ++ptr;
  141.                                 while ((*ptr) && (*ptr != ']'))
  142.                                         ptr++;
  143.                                 if (*ptr == '\0') {
  144.                                         haswin_interrorprintf("haswin_buildiconflags: invalid sprite area string %s in %s", valid, list);
  145.                                 }
  146.                                 *ptr = '\0';
  147.                                 break;
  148.                         case '`': /* font name string */
  149.                                 numstate = 0;
  150.                                 font = ++ptr;
  151.                                 while ((*ptr) && (*ptr != '`'))
  152.                                         ptr++;
  153.                                 if (*ptr == '\0') {
  154.                                         haswin_interrorprintf("haswin_buildiconflags: invalid font name string %s in %s", valid, list);
  155.                                 }
  156.                                 *ptr = '\0';
  157.                                 break;
  158.                         case 'T': /* text */
  159.                                 flags |= 0x00000001;
  160.                                 break;
  161.                         case 'S': /* sprite */
  162.                                 flags |= 0x00000002;
  163.                                 break;
  164.                         case 'B': /* border */
  165.                                 flags |= 0x00000004;
  166.                                 break;
  167.                         case '^': /* vertical centring */
  168.                                 flags |= 0x00000010;
  169.                                 break;
  170.                         case 'F': /* filled */
  171.                                 flags |= 0x00000020;
  172.                                 break;
  173.                         case '?': /* needs help to redraw */
  174.                                 flags |= 0x00000080;
  175.                                 break;
  176.                         case '~': /* don't cancel on ESG */
  177.                                 flags |= 0x00000400;
  178.                                 break;
  179.                         case 'h': /* half size */
  180.                                 flags |= 0x00000800;
  181.                                 break;
  182.                         case '*': /* force selection */
  183.                                 flags |= 0x00200000;
  184.                                 break;
  185.                         case '!': /* can't select */
  186.                                 flags |= 0x00400000;
  187.                                 break;
  188.                         case '<': /* left adjust */
  189.                                 adjmode |= 2;
  190.                                 break;
  191.                         case '>': /* right adjust */
  192.                                 adjmode |= 1;
  193.                                 break;
  194.                         case ':': /* rest is icon name */
  195.                                 numstate = 0;
  196.                                 break;
  197.                         case 'Y': /* font Y size */
  198.                                 numstate = 7;
  199.                                 fonty = 0;
  200.                                 break;
  201.                         case 'X': /* font X size */
  202.                                 numstate = 6;
  203.                                 fontx = 0;
  204.                                 break;
  205.                         case 'P': /* button press type */
  206.                                 numstate = 5;
  207.                                 btype = 0;
  208.                                 break;
  209.                         case 'E': /* button ESG type */
  210.                                 numstate = 8;
  211.                                 esgnum = 0;
  212.                                 break;
  213.                         case '+': /* writable icon */
  214.                                 writable++;
  215.                                 numstate = 4;
  216.                                 wrnum = 0;
  217.                                 break;
  218.                         case '&': /* background colour */
  219.                                 numstate = 3;
  220.                                 bcnum = 0;
  221.                                 break;
  222.                         case '@': /* foreground colour */
  223.                                 numstate = 2;
  224.                                 fcnum = 0;
  225.                                 break;
  226.                         case '$': /* font number */
  227.                                 numstate = 1;
  228.                                 fontnum = 0;
  229.                                 break;
  230.                         case '0':
  231.                         case '1':
  232.                         case '2':
  233.                         case '3':
  234.                         case '4':
  235.                         case '5':
  236.                         case '6':
  237.                         case '7':
  238.                         case '8':
  239.                         case '9':
  240.                                 if (numstate) {
  241.                                         switch (numstate) {
  242.                                         case 1:
  243.                                                 fontnum=fontnum*10+ *ptr-'0';
  244.                                                 break;
  245.                                         case 2:
  246.                                                 fcnum = fcnum*10 + *ptr-'0';
  247.                                                 break;
  248.                                         case 3:
  249.                                                 bcnum = bcnum*10 + *ptr-'0';
  250.                                                 break;
  251.                                         case 4:
  252.                                                 wrnum = wrnum*10 + *ptr-'0';
  253.                                                 break;
  254.                                         case 5:
  255.                                                 btype = btype*10 + *ptr-'0';
  256.                                                 break;
  257.                                         case 6:
  258.                                                 fontx = fontx*10 + *ptr-'0';
  259.                                                 break;
  260.                                         case 7:
  261.                                                 fonty = fonty*10 + *ptr-'0';
  262.                                                 break;
  263.                                         case 8:
  264.                                                 esgnum= esgnum*10 + *ptr-'0';
  265.                                                 break;
  266.                                         }
  267.                                         break;
  268.                                 }
  269.                                 /* FALL THRU */
  270.                         default:
  271.                                 if (unknown == 0) {
  272.                                         haswin_interrorprintf("haswin_buildiconflags: unknown option %c in %s", *ptr, list);
  273.                                 } else if (unlen <= 0) {
  274.                                         haswin_interrorprintf("haswin_buildiconflags: too many unknown options in %s, %c is last handled", list, *ptr);
  275.                                         unlen--;
  276.                                 } else
  277.                                         *(unknown++) = *ptr;
  278.                                 break;
  279.                         }
  280.                 }
  281.                 ptr++;
  282.         }
  283.         if (quoted) {
  284.                 haswin_interrorprintf("haswin_buildiconflags: no terminating \' quote in icon options %s", str);
  285.                 if (unknown)
  286.                         *unknown = '\0';
  287.                 return(HASWIN_FALSE);
  288.         }
  289.         if (esgnum != -1) {
  290.                 if ((esgnum < 0) || (esgnum > 31)) {
  291.                         haswin_interrorprintf("haswin_buildiconflags: bad ESG in %s", str);
  292.                         if (unknown)
  293.                                 *unknown = '\0';
  294.                         return(HASWIN_FALSE);
  295.                 }
  296.                 flags |= (esgnum&0x1F)<<16;
  297.         } else {
  298.                 if ((esg < 0) || (esg > 31)) {
  299.                         haswin_interrorprintf("haswin_buildiconflags: bad ESG passed to '%s'", str);
  300.                         if (unknown)
  301.                                 *unknown = '\0';
  302.                         return(HASWIN_FALSE);
  303.                 }
  304.                 flags |= (esg&0x1F)<<16;
  305.         }
  306.         if (*ptr == ':')
  307.                 ptr++;
  308. /*
  309.  *      ptr points to the end of the string (name of icon) or \0
  310.  *      if no name.
  311.  *
  312.  *      cross check some of the options and flags to prevent illegal
  313.  *      combinations.
  314.  */
  315.         switch (flags & 0x00000003) {
  316.         case 0: /* assume text by default */
  317.                 flags |= 0x00000001;
  318.                 /* FALL THRU */
  319.         case 1: /* text icon */
  320.                 if (area) {
  321.                         haswin_interrorprintf("haswin_buildiconflags: can't have a text icon with a sprite area pointer in %s", list);
  322.                         if (unknown)
  323.                                 *unknown = '\0';
  324.                         return(HASWIN_FALSE);
  325.                 }
  326.                 if (flags & 0x00000800) {
  327.                         haswin_interrorprintf("haswin_buildiconflags: can't have a text icon with a 1/2 size sprite flag in %s", list);
  328.                         if (unknown)
  329.                                 *unknown = '\0';
  330.                         return(HASWIN_FALSE);
  331.                 }
  332.                 if (adjmode == 3) {
  333.                         haswin_interrorprintf("haswin_buildiconflags: can't have left and right adjust in a text icon in %s", list);
  334.                         if (unknown)
  335.                                 *unknown = '\0';
  336.                         return(HASWIN_FALSE);
  337.                 }
  338.                 break;
  339.         case 2: /* sprite icon */
  340.                 if (valid) {
  341.                         haswin_interrorprintf("haswin_buildiconflags: can't have a sprite icon with a validation string in %s", list);
  342.                         if (unknown)
  343.                                 *unknown = '\0';
  344.                         return(HASWIN_FALSE);
  345.                 }
  346.                 if ((font) || (fontnum)) {
  347.                         haswin_interrorprintf("haswin_buildiconflags: can't have a sprite icon in an antialiased font in %s", list);
  348.                         if (unknown)
  349.                                 *unknown = '\0';
  350.                         return(HASWIN_FALSE);
  351.                 }
  352.                 if (writable) {
  353.                         haswin_interrorprintf("haswin_buildiconflags: can't have a writable sprite icon in %s", list);
  354.                         if (unknown)
  355.                                 *unknown = '\0';
  356.                         return(HASWIN_FALSE);
  357.                 }
  358.                 break;
  359.         case 3: /* sprite+text icon */
  360.                 if (area) {
  361.                         haswin_interrorprintf("haswin_buildiconflags: can't have a text+sprite icon with a sprite area pointer in %s", list);
  362.                         if (unknown)
  363.                                 *unknown = '\0';
  364.                         return(HASWIN_FALSE);
  365.                 }
  366.                 if ((font) || (fontnum)) {
  367.                         haswin_interrorprintf("haswin_buildiconflags: can't have a sprite+text icon in an antialiased font in %s", list);
  368.                         if (unknown)
  369.                                 *unknown = '\0';
  370.                         return(HASWIN_FALSE);
  371.                 }
  372.                 if (writable) {
  373.                         haswin_interrorprintf("haswin_buildiconflags: can't have a writable text+sprite icon in %s", list);
  374.                         if (unknown)
  375.                                 *unknown = '\0';
  376.                         return(HASWIN_FALSE);
  377.                 }
  378.                 break;
  379.         }
  380.         if ((fontnum) && (font)) {
  381.                 haswin_interrorprintf("haswin_buildiconflags:  can't have both $%d and `%s` in %s", fontnum, font, list);
  382.                 if (unknown)
  383.                         *unknown = '\0';
  384.                 return(HASWIN_FALSE);
  385.         }
  386. /* setup colours */
  387.         if (!fcnum)
  388.                 fcnum = fc;
  389.         if (!bcnum)
  390.                 bcnum = bc;
  391.         if ((!fontnum) && (!font)) {
  392.                 if (fontx != -1) {
  393.                         haswin_interrorprintf("haswin_buildiconflags:  ignoring X%d in system font in %s", fontx, list);
  394.                 }
  395.                 if (fonty != -1) {
  396.                         haswin_interrorprintf("haswin_buildiconflags:  ignoring Y%d in system font in %s", fonty, list);
  397.                 }
  398.                 /* not got a font number or name, so system font icon */
  399.                 flags |= (fcnum&0x0F)<<24;
  400.                 flags |= (bcnum&0x0F)<<28;
  401.                 if (valid) {
  402.                         sarea = (int)haswin_malloc(asciilen(valid)+1, "haswin_buildiconflags", "validation string buffer");
  403.                         strcpy((char *)sarea, valid);
  404.                 } else if (area)
  405.                         sarea = atoint(area);
  406.                 else if (flags & 0x00000002) {
  407.                 /* we havn't been given a sprite area, so look for one */
  408.                         if ((sarea=haswin_findsprite(ptr)) == HASWIN_UNKNOWN) {
  409.                                 haswin_interrorprintf("haswin_buildiconflags: can't find area for sprite %s in %s", ptr, list);
  410.                                 sarea = 0;
  411.                         }
  412.                 }
  413.         } else if (fontnum) {
  414.                 if (fontx != -1) {
  415.                         haswin_interrorprintf("haswin_buildiconflags:  ignoring X%d in font number $%d in %s", fontx, fontnum, list);
  416.                 }
  417.                 if (fonty != -1) {
  418.                         haswin_interrorprintf("haswin_buildiconflags:  ignoring Y%d in font number $%d in %s", fonty, fontnum, list);
  419.                 }
  420.                 flags |= 0x00000040 | (fontnum&0xFF)<<24;
  421.                 if (valid) {
  422.                         /* add font colours to validation string */
  423.                         sarea = (int)haswin_malloc(asciilen(valid)+5, "haswin_buildiconflags", "validation string buffer");
  424.                         sprintf((char *)sarea, "%s;F%1.1X%1.1X", valid, fcnum, bcnum);
  425.                 } else {
  426.                         sarea = (int)haswin_malloc(5, "haswin_buildiconflags", "validation string buffer");
  427.                         sprintf((char *)sarea, "F%1.1X%1.1X", fcnum, bcnum);
  428.                 }
  429.         } else {
  430.                 if (fontx == -1)
  431.                         fontx = 14;  /* default 14 point */
  432.                 if (fonty == -1)
  433.                         fonty = 14;  /* default 14 point */
  434.                 fontnum = haswin_findfont(font, fontx, fonty, 0, 0);
  435.                 if (!fontnum) {
  436.                         haswin_interrorprintf("haswin_buildiconflags: font name `%s` not found, using system font", font);
  437.                         flags |= (fcnum&0x0F)<<24;
  438.                         flags |= (bcnum&0x0F)<<28;
  439.                         if (valid) {
  440.                                 sarea = (int)haswin_malloc(asciilen(valid)+1, "haswin_buildiconflags", "validation string buffer");
  441.                                 strcpy((char *)sarea, valid);
  442.                         } else if (area)
  443.                                 sarea = atoint(area);
  444.                         else if (flags & 0x00000002) {
  445.                         /* we havn't been given a sprite area, so look for one */
  446.                                 if ((sarea=haswin_findsprite(ptr)) == HASWIN_UNKNOWN) {
  447.                                         haswin_interrorprintf("haswin_buildiconflags: can't find area for sprite %s in %s", ptr, list);
  448.                                         sarea = 0;
  449.                                 }
  450.                         }
  451.                 } else {
  452.                         flags |= 0x00000040 | (fontnum&0xFF)<<24;
  453.                         if (valid) {
  454.                                 /* add font colours to validation string */
  455.                                 sarea = (int)haswin_malloc(asciilen(valid)+5, "haswin_buildiconflags", "validation string buffer");
  456.                                 sprintf((char *)sarea, "%s;F%1.1X%1.1X", valid, fcnum, bcnum);
  457.                         } else {
  458.                                 sarea = (int)haswin_malloc(5, "haswin_buildiconflags", "validation string buffer");
  459.                                 sprintf((char *)sarea, "F%1.1X%1.1X", fcnum, bcnum);
  460.                         }
  461.                 }
  462.         }
  463.         switch (adjmode) {
  464.         case 0: /* no adjustment, centre */
  465.                 flags |= 0x00000008;
  466.                 break;
  467.         case 1: /* right adjust */
  468.                 flags |= 0x00000200;
  469.                 break;
  470.         case 2: /* left  adjust */
  471.                 break;
  472.         case 3: /* both adjustments for text+sprite */
  473.                 flags |= 0x00000208;
  474.                 break;
  475.         }
  476.         if (writable) {
  477.                 if ((btype != -1) && (btype != 14) && (btype != 15)) {
  478.                         haswin_interrorprintf("haswin_buildiconflags: can't have a writable icon with button type [%d] in %s", btype, list);
  479.                 }
  480.                 name = haswin_malloc(wrnum+1, "haswin_buildiconflags", "writable icon buffer");
  481.                 i=0;
  482.                 strnqcpy(name, ptr, wrnum);
  483.                 if ((btype == 14) || (btype == 15))
  484.                         flags |= btype<<12;    /* set button type */
  485.                 else
  486.                         flags |= 0x0000F000;   /* set button type writable */
  487.                 res[0] = flags;
  488.                 res[1] = (int)name;
  489.                 res[2] = (int)sarea;
  490.                 res[3] = wrnum;
  491.         } else {
  492.                 name = haswin_malloc(asciilen(ptr)+1, "haswin_buildiconflags", "icon name buffer");
  493.                 strqcpy(name, ptr);
  494.                 if (btype == -1)
  495.                         flags |= 0x0000A000; /* button type for click/drag */
  496.                 else if ((btype < 0) || (btype > 13)) {
  497.                         haswin_interrorprintf("haswin_buildiconflags: bad button type in %s", list);
  498.                         flags |= 0x0000A000; /* button type for click/drag */
  499.                 } else if ((btype == 14) || (btype == 15)) {
  500.                         haswin_interrorprintf("haswin_buildiconflags: can't have a writable button type in non writable icon in %s", list);
  501.                         flags |= 0x0000A000; /* button type for click/drag */
  502.                 } else
  503.                         flags |= btype<<12; /* set button type */
  504.                 res[0] = flags;
  505.                 res[1] = (int)name;
  506.                 res[2] = (int)sarea;
  507.                 res[3] = asciilen(name);
  508.         }
  509.         if (unknown)
  510.                 *unknown = '\0';
  511.         return(HASWIN_TRUE);
  512. }
  513.  
  514.