home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1989 by David W. Trissel
- *
- * Not derived from licensed software.
- *
- * Permission is granted to freely use, copy, modify, and redistribute
- * this software, provided that no attempt is made to gain profit from it,
- * the author is not construed to be liable for any results of using the
- * software, alterations are clearly marked as such, and this notice is
- * not modified.
- *
- */
-
- #include <stdio.h>
- #include <signal.h>
- #include <errno.h>
- #include "layers.h"
-
- /* protocol.c - BSD MacLayers protocol driver */
-
- /* This module handles all interaction with the Macintosh MacLayers
- ** program. Services provided are:
- **
- ** InitLink() - initialize link to MacLayers
- **
- ** TopChannel() - return highest prority channel
- **
- ** SendNew() - request new layer channel of MacLayers
- **
- ** SendTitle() - change window title to given string (NOT IMPLENTED YET)
- **
- ** SendDelete()- tell MacLayers indicated layer has died
- **
- ** SendQuit() - order MacLayers to terminate layers mode
- **
- ** SendData() - send output to indicated channel's window
- **
- ** SendReshape() - send Shape structure to MacLayers
- **
- ** ProcessStreamin() - data is ready to be processed from MacLayers
- **
- */
-
- #define DUMPALL
- #undef DUMPALL
-
- /* C library calls */
- unsigned alarm(); /* alarm system call */
-
- static int GetData();
- static void Packet();
- static void Parse();
- static void AwaitInput();
- static void asciishape();
- static void fill4();
- static void fill2();
- static void fill1();
- static int parseshape();
- static unsigned get4();
- static unsigned get2();
- static unsigned get1();
-
- static char inbuff[IOSIZE]; /* input buffer from MacLayers */
- static char *inpos; /* current input position in buffer */
- static int insize = 0; /* characters left to process */
- static int Outstream = -1; /* current output stream channel */
- static int Instream = -1; /* current input stream channel */
-
- static struct Shape SNshape; /* SendNew() shape response */
- static int SNresp = 0; /* SendNew() reponse poll flag */
- static int SNchan = 0; /* SendNew() channel return */
- #define SN_WAITING -1000 /* SendNew() waiting response value */
-
- #define ATTRSIZE 15 /* size of window attribute string */
-
- #define FLUSH fflush(stdout)
-
-
- /* Initlink() - initialize link with MacLayers */
-
- /* Returns:
- ** 0 - linkup failed
- ** 1 - linkup successful, Maclayers now in protocol mode
- */
-
- int
- Initlink()
- {
- int Outstream = -1; /* no default stream yet */
- int Instream = -1; /* no default stream yet */
- int num1, num2, num3; /* scanf item result */
- int err; /* error code */
-
- #define WAITTIME 10 /* second wait response time */
- #define INITTIME 2 /* wait time after succesful startup */
-
- /* we must non-buffer input since all input must be immediate */
- setbuf(stdin, NULL); /* non-buffer all input */
-
- /* send intitial request for terminal type and version number */
- DO DEBUG("write: ESC [ c\n");
- if ((err=printf("\033[c")) < 0)
- {
- DO DEBUG(" printf() error code %d\n", err);
- return ( 0 ); /* problem with stdout */
- }
- FLUSH; /* force output buffer */
-
- /* attempt to read "ESC [ ? 8 ; typedigits ; versiondigits c" */
- num1 = num2 = num3 = -1; /* default to unsupplied values */
- (void) alarm(WAITTIME); /* set timeout */
- DO DEBUG(" doing first scanf\n");
- (void) scanf("\033[?%d;%d;%dc", &num1, &num2, &num3);
- (void) alarm(0); /* cancel alarm */
- DO DEBUG("read ESC [ ? %d ; %d; %d c\n", num1, num2, num3);
- if (num1 != 8 || num2 != 10)
- return ( 0 ); /* not correct response or layers term ID */
-
- /* ask terminal if ENC_ENABLE is to be forced */
- DO DEBUG("write: ESC [ F\n");
- (void) printf("\033[F");
- FLUSH; /* force output buffer */
- (void) alarm(WAITTIME); /* set timeout */
-
- /* attempt to read "ESC [ flag F" (flag indicates ENC_ENABLE status) */
- num1 = -1; /* default to invalid response */
- (void) scanf("\033[%dF", &num1);
- (void) alarm(0); /* cancel alarm */
- DO DEBUG("read ESC [ %d F\n", num1);
- if (num1 != 2 && num1 != 0)
- return ( 0 ); /* something's wrong */
-
- /* now startup packet mode in non ENC_ENABLE processing */
- DO DEBUG("write: ESC [ 2 ; 0 v\n");
- (void) printf("\033[2;0v"); /* "ESC [ 2 ; 0 v" */
- FLUSH; /* force output buffer */
-
- /* we are now in packet mode */
- sleep( INITTIME ); /* let Macintosh keep up with us */
- return ( 1 ); /* return successful startup */
-
- } /* Initlink() */
-
-
- /* TopChannel() - return highest prority channel */
-
- int
- TopChannel()
- {
- return ( Instream );
-
- } /* TopChannel() */
-
-
- /*
- ** WARNING: Most of the following functions may be recursively called
- ** as control commands are processed from the input stream
- */
-
-
- /* ProcessStreamin() - MacLayers has input to process */
-
- void
- ProcessStreamin()
- {
- int c; /* input character being processed */
-
- DO DEBUG("ProcessStreamin()\n");
-
- GetData(0); /* read some and don't timeout */
-
- while (insize > 0) /* while more data to process ... */
- Parse(); /* process next chuck of data */
-
- } /* ProcessStreamin() */
-
-
- /* SendNew() - request new layer channel from MacLayers */
-
- /* This command is unique in that it returns a response from MacLayers.
- ** To do this we continue processing the input stream until we get
- ** our return. (This leads to recursive conditions.) The variables
- ** 'SNresp', 'SNshape' and 'SNchan' are set when our reply is received.
- */
- int
- SendNew(shape)
- struct Shape *shape; /* shape to use for new window */
- {
- int i; /* attribute count variable */
- char astring[ATTRSIZE]; /* copy of attribute string */
-
- DO DEBUG("SendNew() new layer requested: '~%cA'\n", '1'+ATTRSIZE);
-
- /* check for a recursive call */
- if (SNresp == SN_WAITING)
- { DO DEBUG("return 0 - recursive call\n");
- return ( 0 ); /* return failure */
- }
-
- putchar(ESCAPE); /* send start of control packet char */
- putchar('1' + ATTRSIZE); /* send command size */
- putchar('A'); /* send command */
- asciishape(shape, astring); /* convert shape to string */
- for (i=0; i < ATTRSIZE; i++)
- putchar(astring[i]); /* send next attribute digit */
- FLUSH;
-
- /* now stay here and process the input stream until we see our response */
- /**** THIS SHOULD BE ENHANCED TO TIMEOUT WITH GetData() AND REISSUE REQUEST */
- SNresp = SN_WAITING; /* indicate we are waiting a response */
- while (SNresp == SN_WAITING)
- { DO DEBUG(" while (SNresp %d == %d)\n", SNresp, SN_WAITING);
- AwaitInput(); /* wait till input from MacLayers arrives */
- ProcessStreamin(); /* process available input */
- }
-
- if (SNresp == -1) /* if Maclayers rejected request */
- SNchan = 0; /* return failure channel of zero */
- else
- *shape = SNshape; /* else update shape structure */
-
- DO DEBUG("SendNew() returning channel %d\n", SNchan);
-
- return ( SNchan ); /* return the indicated channel */
-
- } /* SendNew() */
-
-
- /* SendReshape() - send to shape to MacLayers */
-
- void
- SendReshape(chan, shape)
- int chan; /* channel shape belongs to */
- struct Shape *shape; /* shape to use for new window */
- {
- int i; /* attribute count variable */
- char astring[ATTRSIZE]; /* copy of attribute string */
-
- DO DEBUG("SendReshape() reshape: '~%cA'\n", '2'+ATTRSIZE);
-
- if (chan <= 0 || chan > MAXPCHAN)
- { DO DEBUG("BAD CHANNEL!!!\n");
- return; /* ignore request */
- }
-
- putchar(ESCAPE); /* send start of control packet char */
- putchar('2' + ATTRSIZE); /* send command size */
- putchar('R'); /* send command */
- putchar(chan + '0'); /* send channel */
- asciishape(shape, astring); /* convert shape to string */
- DO DEBUG("shape: %.*s\n", ATTRSIZE, astring);
- for (i=0; i < ATTRSIZE; i++)
- putchar(astring[i]); /* send next attribute digit */
- FLUSH;
-
- } /* SendReshape() */
-
-
- /* SendTitle() - set layer's window title */
-
- void
- SendTitle(chan, buff, cnt)
- int chan; /* layer window ID */
- char *buff; /* new title string */
- int cnt; /* count of title length */
- {
- int i; /* work variable */
-
- DO DEBUG("SendTitle(chan%d, len %d, '%.*s')\n", chan, cnt, cnt, buff);
-
- if (chan <= 0 || chan > MAXPCHAN)
- { DO DEBUG("BAD CHANNEL!!!\n");
- return; /* ignore request */
- }
-
- if (cnt < 0)
- { DO DEBUG("BAD COUNT!!!\n");
- return; /* ignore request */
- }
-
- /* for now chop title size to 29 chars since that's MacLayer's limit */
- if (cnt > 29)
- cnt = 29; /* due to packet size limit */
-
- /* we must guarantee that the size will not appear to be another ESCAPE */
- if ('2' + cnt == ESCAPE)
- cnt--; /* truncate to avoid ESCAPE ESCAPE */
-
- putchar(ESCAPE); /* send start of control packet char */
- putchar('2' + cnt); /* send size of packet */
- putchar('T'); /* send command */
- putchar(chan + '0'); /* send channel ID */
- for (i=0; i<cnt; i++)
- putchar(buff[i]); /* send out title */
- FLUSH;
-
- } /* SendTitle() */
-
-
- /* SendDelete() - tell Maclayers layer died */
-
- void
- SendDelete(chan)
- int chan; /* dead channel ID */
- {
- DO DEBUG("SendDelete(%d) '~2D%d'\n", chan, chan);
-
- if (chan <= 0 || chan > MAXPCHAN) /* check channel ID */
- { DO DEBUG("BAD CHANNEL!!!\n");
- return; /* ignore request */
- }
-
- putchar(ESCAPE); /* send control packet start char */
- putchar('2'); /* send command size */
- putchar('D'); /* send command character */
- putchar(chan + '0'); /* channel ID in ascii */
- FLUSH;
-
- } /* SendDelete() */
-
-
- /* SendQuit() - order MacLayers to end layers mode */
-
- void
- SendQuit(chan)
- int chan; /* dead channel ID */
- {
- DO DEBUG("SendQuit() '~1E'\n");
-
- putchar(ESCAPE); /* send control packet start char */
- putchar('1'); /* send command size */
- putchar('E'); /* send command */
- FLUSH;
-
- } /* SendQuit() */
-
-
- /* SendData() - send output to layer's window */
-
- void
- SendData(chan, buff, cnt)
- int chan; /* layer window ID */
- unsigned char *buff; /* new title string */
- int cnt; /* count of title length */
- {
- unsigned c; /* output character being sent */
-
- DO
- { int dcnt;
-
- DEBUG("SendData(chan %d, len %d, '", chan, cnt, cnt, buff);
- for (dcnt=0; dcnt<cnt; dcnt++)
- DEBUG("%c", buff[dcnt]); /* dump each char so null doesn't stop */
- DEBUG("')\n");
- }
-
- if (chan <= 0 || chan > MAXPCHAN)
- { DO DEBUG("BAD CHANNEL!!!\n");
- return; /* ignore request */
- }
-
- /* if new output channel stream then prefix redirect command */
- if (chan != Outstream)
- { DO DEBUG("Redirecting output to %d '~2O%d'\n", chan, chan);
- putchar(ESCAPE); /* start of command sequence */
- putchar('2'); /* send command size */
- putchar('O'); /* send command */
- putchar(chan + '0'); /* put out channel in ASCII */
- Outstream = chan; /* new output stream set */
- }
-
- /* transmit the buffer converting the ESCAPE sequence to double ESCAPE */
- while (cnt--)
- { c = *buff++; /* get next output character */
- #ifdef DUMPALL
- DO DEBUG("outchar %c 0x%x\n", c, c);
- #endif
- if (c == ESCAPE || c == (ESCAPE + 0x80))
- { putchar(c); /* put it out twice */
- #ifdef DUMPALL
- DO DEBUG(" Doubled Escape!\n");
- #endif
- }
- putchar(c); /* write character out */
- }
-
- FLUSH; /* force out queued output characters */
-
- } /* SendData() */
-
-
- /* Parse() - process next chunk of input stream */
-
- static void
- Parse()
- {
- #define ST_NULL 0 /* not primed for next state yet */
- #define ST_STREAM 1 /* processing default stream input */
- #define ST_PKT 2 /* processing packet data */
-
- int c; /* input character being processed */
-
- static int state = ST_NULL; /* current input state */
- static int psize = 0; /* packet size */
- static int rempsize = 0; /* remembered packet size */
- static char pdata[MAXSTR]; /* area for packet data */
- static char *ppos; /* packet read insert position */
- static int escapemode = 0; /* processing escape character */
- static int escapechar; /* escape character being processed */
- static pchan = -1; /* packet input stream channel */
-
- while (insize-- > 0) /* while more data */
- { c = *inpos++; /* get next character */
- switch (state) /* process according to state */
- { case ST_NULL: /* prepare for new packet */
- DO DEBUG("ST_NULL\n");
- psize = 0; /* clear packet size */
- ppos = pdata; /* start fill at data position */
- pchan = Instream; /* packet channel is current input stream */
- state = ST_STREAM; /* default is stream processing */
-
- case ST_STREAM:
- /* stream keyboard input for layer */
- /* check for escape char with possible high bit on */
- #ifdef DUMPALL
- DO DEBUG("ST_STREAM %x/%x esc %d insz %d\n",
- c, c & 0x7f, escapemode, insize);
- #endif
- if (c == ESCAPE || c == (ESCAPE | 0x80))
- { if (escapemode && c == escapechar) /* previous was ESCAPE */
- /* this is really a single ESCAPE character */
- escapemode = 0; /* back out of ESCAPE mode */
- else
- /* what do we do with back to back esc esc+0x80 ? */
- { /* flag in escape mode */
- escapemode++;
- escapechar = c; /* remember character used for escape */
- continue; /* and continue scan */
- }
- }
- else
- if (escapemode)
- { /* this is the start of a control packet */
- if (psize) /* if we have previous data packet */
- Packet(pchan, psize, pdata); /* finish up previous pkt */
- /* process packet size */
- psize = (c & 0x7f) - '0'; /* save size byte */
- if (psize <= 0 || psize > MAXSTR)
- { /* bad size */
- DO DEBUG("Bad pkt size %d\n", psize);
- break; /* trash this packet */
- }
- rempsize = psize; /* remember this size for later */
- #if 0
- ptimo = rtimo; /* start receive timeout */
- #endif
- escapemode = 0; /* escape mode now off */
- ppos = pdata; /* initialize data store pointer */
- state = ST_PKT; /* expect packet data next */
- continue; /* continue scan */
- }
-
- /* process standard data output character for current stream */
-
- *ppos++ = c; /* save next data character */
-
- if (++psize >= MAXSTR) /* if packet full ... */
- { Packet(pchan, psize, pdata); /* process this packet */
- break; /* end packet processing */
- }
- continue; /* continue scan */
-
- case ST_PKT:
- /* process next paket data byte */
- *ppos++ = c & 0x7f; /* store next data byte */
- #ifdef DUMPALL
- DO DEBUG("ST_PKT: %x sz %d\n", c & 0x7f, psize);
- #endif
- if (--psize != 0)
- continue;
- #if 0
- if (crc((unsigned char *) &rpkt, rpkt.pkt.HEADER_DSIZE+2))
- STATS(Scrcerr); /* communications error */
- else
- #endif
- Packet(0, rempsize, pdata); /* process it */
-
- } /* end build packet switch */
-
- #if 0
- ptimo = 0; /* no more receive timeout */
- #endif
- state = ST_NULL; /* no more receive packet in progress */
-
- } /* end while (insize) */
-
- if (state == ST_STREAM && psize ) /* if we have some data ... */
- { Packet(Instream, psize, pdata); /* process this data */
- #if 0
- ptimo = 0; /* no more receive timeout */
- #endif
- state = ST_NULL; /* no more receive packet in progress */
- }
-
- } /* Parse() */
-
-
- /* Packet() - prcess next input data string or control packet */
- static void
- Packet(chan, size, buff)
- int chan; /* channel (0 if control packet) */
- int size; /* amount of data */
- char *buff; /* pointer to packet data */
- {
- static struct Shape shape; /* Shape structure */
-
- DO DEBUG("Packet(chan %d, size %d, '%.*s')\n", chan, size, size, buff);
-
- /* verify channel */
- if (chan < 0 || chan > MAXPCHAN)
- { DO DEBUG("BAD CHANNEL!!\n");
- return; /* ignore bad channel */
- }
-
- /* if data packet (chan>0) feed data to server */
- if (chan > 0)
- { ReceiveData(chan, buff, size);
- return; /* we are through */
- }
-
- /* control packet (channel 0) */
- chan = buff[1] - '0'; /* assume channel specified */
- if (chan < 0 || chan > MAXPCHAN) /* if invalid ... */
- chan = 0; /* set to zero */
-
- switch (buff[0])
- { case 'I': /* redirect stream */
- DO DEBUG("CMD 'I' redirect stream to %c\n", buff[1]);
- if (size != 2) /* verify size */
- break; /* break if bad */
- if (chan == 0) /* verify channel */
- break; /* break if bad */
- Instream = chan; /* new instream channel */
- return; /* we are through */
-
- case 'A': /* returned A_NEWLAYER packet */
- DO DEBUG("CMD 'A' A_NEWLAYER response %c newchan %c SNresp %d\n",
- buff[2], buff[1], SNresp);
- if (size != 3 + ATTRSIZE)
- break; /* break if bad */
-
- /* if SendNew() not waiting for a response this is invalid */
- if (SNresp != SN_WAITING)
- break; /* break if bad */
-
- if (buff[2] == '1') /* if response is "failed" ... */
- SNresp = -1; /* show -1 response */
- else
- if (buff[2] == '0') /* if response is "success" ... */
- { if (chan == 0) /* if invalid channel */
- break; /* break if bad */
- /* build shape structure for SendNew() */
- if (parseshape(&SNshape, &buff[3]) == -1)
- break; /* if invalid data then bad packet */
- SNresp = 0; /* show good response */
- SNchan = chan; /* indicate channel returned */
- }
- else
- break; /* break if bad */
-
- DO DEBUG("SNresp = %d, SNchan = %d\n", SNresp, SNchan);
- return; /* we are through */
-
- case 'N': /* new layer creation */
- DO DEBUG("CMD 'N' new layer creation newchan %c\n", buff[1]);
- if (size != 2 + ATTRSIZE) /* verify size */
- break; /* break if bad */
- if (chan == 0) /* verify channel */
- break; /* break if bad */
- /* build shape structure */
- if (parseshape(&shape, &buff[2]) == -1)
- break; /* if invalid data then bad packet */
- ReceiveNew(chan, &shape); /* pass to server */
- return; /* packet is done */
-
- case 'D': /* deleted layer */
- DO DEBUG("CMD 'D' deleted layer %c\n", buff[1]);
- if (size != 2) /* verify size */
- break; /* break if bad */
- if (chan == 0) /* verify channel */
- break; /* break if bad */
- ReceiveDelete(chan); /* pass on to server */
- return; /* packet is done */
-
- case 'E': /* exit - awaiting shutdown */
- DO DEBUG("CMD 'E' exit MacLayers awaiting shutdown msg\n");
- if (size != 1) /* verify size */
- break; /* break if bad */
- ReceiveQuit(); /* pass to server */
- /* NOT REACHED*/
- return; /* ?? should never reach here */
-
- case 'R': /* reshaped */
- DO DEBUG("CMD 'R' reshape chan %c\n", buff[1]);
-
- if (size != 2 + ATTRSIZE) /* verify size */
- break; /* break if bad */
-
- if (chan == 0) /* verify channel */
- break; /* break if bad */
-
- /* build shape structure */
- if (parseshape(&shape, &buff[2]) == -1)
- break; /* if invalid data then bad packet */
-
- ReceiveReshape(chan, &shape); /* tell server about shape */
- return; /* packet processed */
-
- case 'S': /* signal */
- DO DEBUG("CMD 'S' SIGNAL chan %c sig %c\n", buff[1], buff[2]);
- if (size != 3) /* verify size */
- break; /* break if bad */
- if (chan == 0)
- break; /* break if bad */
-
- if (buff[2] == '0') /* if SIGINT */
- size = SIGINT; /* yes */
- else
- if (buff[2] == '1') /* if SIGHUP */
- size = SIGHUP; /* yes */
- else
- break; /* invalid signal */
-
- ReceiveSignal(chan, size); /* pass to server */
- return; /* packet processed */
-
- default:
- DO DEBUG("ILLEGAL CONTROL PACKET!!!\n");
- return; /* ignore bad packet */
-
- } /* end command packet switch */
-
- /* switch falls out if bad size or channel for given command */
- DO DEBUG("Invalid size or channel!!!\n"); /* dump error */
- return; /* ignore packet */
-
- } /* Packet() */
-
-
- /* GetData() - read next input from MacLayers stream */
-
- /* An input timout parameter can indicate that we return if nothing
- ** is read within a certain amount of seconds. The return code is:
- **
- ** 0 - timeout occured and no data was read
- **
- ** 1 - no timeout occured, data read
- */
- static int
- GetData(timeout)
- int timeout; /* timeout in seconds (or zero) */
- {
- int result; /* return from read() */
-
- DO DEBUG("GetData(timout %d)\n", timeout);
-
- /* if buffer still has data simply return (SHOULD NOT OCCUR?) */
- if (insize > 0)
- return ( 1 ); /* act as through data read */
- inpos = inbuff; /* next get will start at beginning */
- insize = 0; /* default insize back to zero */
-
- /* set timeout if we are to do so */
- if (timeout)
- (void) alarm(timeout); /* set timeout in seconds */
-
- /* do the read from stdin */
- result = read(0, inbuff, IOSIZE);
-
- /* if alarm was set cancel it now */
- if (timeout)
- (void) alarm(0); /* cancel alarm */
-
- /* check for timeout or error */
- /* EWOULDBLOCK for no data avail -(but we should not see this) */
- /* EINTR if signal stopped the read -(rare but could happen) */
- if (result <= 0)
- return ( 0 ); /* return nothing read */
-
- /* return with fresh buffer data */
- insize = result;
- DO DEBUG("read %d bytes\n", insize);
- return ( 1 ); /* return OK code */
-
- } /* GetData() */
-
-
- /* AwaitInput() - wait for more input from MacLayers */
-
- static void
- AwaitInput()
- {
- int r; /* read descriptor bits */
-
- DO DEBUG("AwaitInput()\n");
-
- do
- { r = 1<<0; /* wait for read from input device */
- if (select(32, &r, NULL, NULL, NULL) == -1) /* if problem waiting ... */
- { if (errno != EINTR) /* if not simply signal taken ... */
- { /* SHOULD NOT OCCUR - shutdown layers */
- DO DEBUG("AwaitInput: select error %d\n", errno);
- printf("layers: AwaitInput: bad select %d\n", errno);
- FQuit(); /* shutdown layers */
- /* NOT REACHED */
- }
- }
- } while ((r & 1<<0) == 0);
-
- } /* AwaitInput() */
-
- /* asciishape() - convert Shape structure to ASCII */
- static void
- asciishape(shape, loc)
- struct Shape *shape; /* Shape structure for channel */
- char *loc; /* location to start filling result */
- {
- char *origloc; /* (for debuggin) */
-
- origloc = loc; /* remember start of string */
- fill4(&loc, shape->worigh); /* origin h */
- fill4(&loc, shape->worigv); /* origin v */
- fill2(&loc, shape->wlines); /* lines high */
- fill2(&loc, shape->wchars); /* chars wide */
- fill1(&loc, shape->wfont); /* font size */
- fill2(&loc, shape->wattr); /* attributes */
-
- DO DEBUG("asciishape(): %.*s\n", ATTRSIZE, origloc);
-
- } /* asciishape() */
-
-
- /* fill4() - convert parameter to ASCII */
-
- static void
- fill4(loc, valu)
- char **loc; /* pointer to fill area pointer */
- unsigned valu; /* value to use */
- {
- fill2(loc, valu>>8); /* fill high half word */
- fill2(loc, valu & 0xff); /* fill low half word */
-
- } /* fill4() */
-
-
- /* fill2() - convert parameter to ASCII */
-
- static void
- fill2(loc, valu)
- char **loc; /* pointer to fill area pointer */
- unsigned valu; /* value to use */
- {
- fill1(loc, valu>>4); /* fill high byte */
- fill1(loc, valu & 0xf); /* fill low byte */
-
- } /* fill2() */
-
-
- /* fill1() - convert parameter to ASCII */
-
- static void
- fill1(loc, valu)
- char **loc; /* pointer to fill area pointer */
- unsigned valu; /* value to use */
- {
- *(*loc)++ = "0123456789ABCDEF"[valu & 0xf]; /* return hex value */
-
- } /* fill1() */
-
-
- /* parseshape() - convert ASCII image to Shape structure */
-
- static int Badconvert; /* indicates bad conversion */
-
- static int
- parseshape(shape, loc)
- struct Shape *shape; /* Shape structure for channel */
- char *loc; /* location to start parsing */
- {
- Badconvert = 0; /* clear bad characters indicator */
- shape->worigh = get4(&loc); /* origin h */
- shape->worigv = get4(&loc); /* origin v */
- shape->wlines = get2(&loc); /* lines high */
- shape->wchars = get2(&loc); /* chars wide */
- shape->wfont = get1(&loc); /* font size */
- shape->wattr = get2(&loc); /* attributes */
-
- DO DEBUG("ParseShape(): origv %d, origh %d, lines %d, chars %d\n",
- shape->worigv, shape->worigh, shape->wlines, shape->wchars);
- DO DEBUG(" font %d, attr 0x%x, badconv %d\n",
- shape->wfont, shape->wattr, Badconvert);
-
- return ( Badconvert ? -1 : 0 ); /* return conversion code */
-
- } /* parseshape() */
-
-
- /* get4() - convert ASCII to parameter */
-
- static unsigned
- get4(loc)
- char **loc; /* pointer to fill area pointer */
- {
- unsigned hi; /* high portion */
- unsigned low; /* low portion */
-
- hi = get2(loc); /* get high byte */
- low = get2(loc); /* get low byte */
-
- return ( (hi<<8) + low ); /* return word value */
-
- } /* get4() */
-
-
- /* get2() - convert ASCII to parameter */
-
- static unsigned
- get2(loc)
- char **loc; /* pointer to fill area pointer */
- {
- unsigned hi; /* high portion */
- unsigned low; /* low portion */
-
- hi = get1(loc); /* get high half */
- low = get1(loc); /* get low half */
-
- return ( (hi<<4) + low ); /* return byte value */
-
- } /* get2() */
-
-
- /* get1() - convert ASCII to parameter */
-
- /* This function sets 'Badconvert' if an invalid character is detected */
-
- static unsigned
- get1(loc)
- char **loc; /* pointer to fill area pointer */
- {
- int c; /* character to convert */
-
- c = *(*loc)++; /* fetch character */
-
- if (c >= '0' && c <= '9')
- /* zero through nine */
- return ( c - '0' ); /* return it's binary value */
-
- if (c >= 'a' && c <= 'f')
- /* lower case hex */
- return ( c - 'a' + 10); /* return it's binary value */
-
- if (c >= 'A' && c <= 'F')
- /* upper case hex */
- return ( c - 'A' + 10); /* return it's binary value */
-
- /* invalid digit! */
- Badconvert++; /* set bad character flag */
- return ( 0 ); /* return a zero */
-
- } /* get1() */
-