home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / Telnet 2.5.src.ThinkC / source / vr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-14  |  19.5 KB  |  1,112 lines  |  [TEXT/MPS ]

  1. #ifndef lint
  2. static char *SCCSid = "%W%    (NCSA)    %G%";
  3. #endif lint
  4.  
  5. /*
  6. ** Raster Virtual Kernel
  7. */
  8.  
  9. #define RASTER_MASTER
  10. #define MASTERDEF
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14.  
  15. #include <Memory.h>
  16.  
  17. #include "rr.h"
  18. #include "vr.h"
  19. #include "RGrout.h"
  20. #include "rasmac.h"
  21.  
  22. /*
  23. ** global vars
  24. */
  25.  
  26. static int            VRstate = DONE;        /* current state */
  27. static int            VRcmdnum = -1;        /* current command */
  28. static int            VRargcount = 0;        /* number of args for command */
  29. static int            VRdatalen = 0;        /* length of expected data */
  30. static int            VRbufpos = 0;        /* current pointer in tempdata */
  31. static union arg    VRargs[MAXARGS];    /* argument vector */
  32. static char            VRtempdata[256];    /* temporary storage while parsing */
  33. static char         *VRspace;            /* storage for incoming data */
  34. static char         *VRsp2;                /* storage for pixel expansion */
  35. static char            *VRptr;                /* pointer for data buffer */
  36. static char            *VRptr2;            /* copy of above */
  37.  
  38. /***********************************************************************/
  39. /* decode0 and decode1
  40. *  start and continue the decoding.
  41. *
  42. *  Returns real characters, 0 if in the middle of an escape sequence.
  43. */
  44.  
  45. #define FRSKIP 0
  46. #define FRIN 1
  47. #define FRSPECIAL 2
  48. #define FROVER 3
  49. #define FRDONE 4
  50.  
  51. static int dstate=FRSKIP,dspec=0;
  52. /*
  53. *  set up receive
  54. */
  55. void decode0
  56.   (
  57.     void
  58.   )
  59.   {
  60.     dstate = FRIN;
  61.   }
  62.  
  63. decode1(c)
  64.     int c;
  65.     {
  66.     switch (dstate) {
  67.     case FRSKIP:
  68.         return(-1);
  69.  
  70.     case FRIN:                        /* decoding */
  71.         if (c > 31 && c < 123)
  72.             return(c);
  73.         else {
  74.             dspec = c;                /* save special character */
  75.             dstate = FRSPECIAL;        /* doing special character */
  76.         }
  77.         return(-1);
  78.     case FRSPECIAL:
  79.         switch (dspec) {
  80.         case 123:
  81.         case 124:
  82.         case 125:
  83.         case 126:            /* encoded character */
  84.             dstate = FRIN;
  85.             return(((dspec - 123)<< 6) - 32 + c);
  86.         default:            /* mistaken character in stream */
  87.             dstate = FRIN;  /* assume not special */
  88.             return(decode1(c));  /* check for sure */
  89.             break;
  90.         }
  91.         break;
  92.  
  93.     }
  94.  
  95. }
  96.  
  97. /*
  98. ** VRinit    -- initialize the VR system
  99. **
  100. ** Arguments:
  101. **
  102. **    None.
  103. **
  104. ** Returns:
  105. **
  106. **    int        -- status, 1 == succsessful, 0 == failed
  107. */
  108.  
  109. int VRinit
  110.   (
  111.     void
  112.   )
  113. {
  114.     VRhead.w_next = NULL;
  115.     VRsp2 = (char *)NewPtr(4*LINEMAX+10);
  116.     VRspace = (char *)NewPtr(LINEMAX+10);
  117.     if (VRspace)
  118.         return 1;
  119.     else
  120.         return 0;
  121. }
  122.  
  123. /*
  124. ** VRwrite -- parse a string of VR commands
  125. ** 
  126. ** Arguments:
  127. **
  128. **    char *b;    -- buffer pointer
  129. **    int    len;    -- buffer length
  130. **
  131. ** Returns:
  132. **
  133. **    int            -- Number of characters processed.  0 tells
  134. **                -- the upper level to switch out of raster mode;
  135. **                -- usually on error, but also at completion of
  136. **                -- command processing.
  137. **
  138. */
  139.  
  140. int VRwrite
  141.   (
  142.     char *b,
  143.     int len
  144.   )
  145. {
  146.  
  147.     int            count = 0;
  148.     char        *p = b;
  149.     char        c;
  150.     int            i;
  151.     extern char    *strcpy();
  152.     int            VRnextargstate();
  153.  
  154.     /*
  155.     ** loop 'til no more chars
  156.     */
  157.  
  158.     while (count < len) {
  159.         c = *p;
  160.  
  161.         switch (VRstate) {
  162.             case DONE:
  163.  
  164.                 if (c == ESC)
  165.                     VRstate = ESCFOUND;
  166.                 else
  167.                     return count;
  168.                 break;
  169.  
  170.             case ESCFOUND:
  171.  
  172.                 if (c == CMDTRM)
  173.                     VRstate = WANTCMD;
  174.                 else {
  175.                     VRstate = DONE;
  176.                     return count;
  177.                 }
  178.                 break;
  179.  
  180.             /*
  181.             ** looking for a valid command char
  182.             */
  183.  
  184.             case WANTCMD:
  185.  
  186.                 for (i = 0; i < NCMDS; i++) {
  187.                     if (cmdtab[i].c_name == c)
  188.                         break;
  189.                 }
  190.  
  191.                 VRcmdnum = i;
  192.  
  193.                 /*
  194.                 ** not a valid command, so later
  195.                 */
  196.  
  197.                 if (VRcmdnum == NCMDS) {
  198.                     VRstate = DONE;
  199.                     return 0;
  200.                 }
  201.  
  202.                 /*
  203.                 ** set up for this command
  204.                 */
  205.  
  206.                 VRargcount = 0;
  207.                 VRbufpos = 0;
  208.  
  209.                 VRstate = WANTDEL;
  210.                 break;
  211.  
  212.             /*
  213.             ** look for that first ;
  214.             */
  215.  
  216.             case WANTDEL:
  217.                 if (c == DELIM)
  218.                     VRstate = VRnextargstate(VRargcount, VRcmdnum);
  219.                 else {
  220.                     VRstate = DONE;
  221.                 }
  222.                 break;
  223.  
  224.             /*
  225.             ** looking for an integer arg
  226.             */
  227.  
  228.             case IARG:
  229.                 switch (c) {
  230.  
  231.                     /*
  232.                     ** we've found the end of the argument, so
  233.                     ** try to put into the vector for later use
  234.                     */
  235.  
  236.                     case DELIM:
  237.                     case CMDTRM:
  238.                         VRtempdata[VRbufpos] = '\0';
  239.  
  240.                         /*
  241.                         ** copy into argument union
  242.                         */
  243.  
  244.                         (void)sscanf(VRtempdata,"%d",&VRargs[VRargcount].a_num);
  245.                         VRbufpos = 0;
  246.  
  247.                         VRargcount++;
  248.                         if (c == DELIM)
  249.                             VRstate = VRnextargstate(VRargcount, VRcmdnum);
  250.                         else
  251.                             if (cmdtab[VRcmdnum].c_flags & FL_DATA)
  252.                                 VRstate = DATA;
  253.                             else {
  254.  
  255.                                 /*
  256.                                 ** run the command
  257.                                 */
  258.  
  259.                                 (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L);
  260.                                 VRstate = DONE;
  261.                             }
  262.  
  263.                         break;
  264.  
  265.                     /*
  266.                     ** copy over characters for later
  267.                     */
  268.  
  269.                     default:
  270.                         VRtempdata[VRbufpos++] = c;
  271.                 }
  272.                 break;
  273.  
  274.             /*
  275.             ** looking for string arg
  276.             */
  277.  
  278.             case SARG:
  279.                 switch (c) {
  280.  
  281.                     /*
  282.                     ** put string into argument vector
  283.                     */
  284.  
  285.                     case DELIM:
  286.                     case CMDTRM:
  287.                         
  288.                         VRtempdata[VRbufpos] = '\0';
  289. /*
  290.                         VRargs[VRargcount].a_ptr = NewPtr((unsigned)VRbufpos+1);
  291.                         
  292.                         if (VRargs[VRargcount].a_ptr == (char *)0L) {
  293.                             VRstate = DONE;
  294.                             break;
  295.                         }
  296. */
  297.  
  298.                         (void)strcpy(VRargs[VRargcount].a_ptr, VRtempdata);
  299.                         VRbufpos = 0;
  300.                         VRargcount++;
  301.                         if (c == DELIM)
  302.                             VRstate = VRnextargstate(VRargcount, VRcmdnum);
  303.                         else
  304.                             if (cmdtab[VRcmdnum].c_flags & FL_DATA)
  305.                                 VRstate = DATA;
  306.                             else {
  307.  
  308.                                 /*
  309.                                 ** run the command
  310.                                 */
  311.  
  312.                                 (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L);
  313.                                 VRstate = DONE;
  314.                             }
  315.  
  316.                         break;
  317.  
  318.                     /*
  319.                     ** save string for later
  320.                     */
  321.  
  322.                     default:
  323.                         VRtempdata[VRbufpos++] = c;
  324.  
  325.                 }
  326.                 break;
  327.  
  328.             /*
  329.             ** looking for a count argument
  330.             */
  331.  
  332.             case CARG:
  333.                 switch (c) {
  334.  
  335.                     /*
  336.                     ** we've found the end of the argument, so
  337.                     ** try to put into the vector for later use
  338.                     */
  339.  
  340.                     case DELIM:
  341.                     case CMDTRM:
  342.                         VRtempdata[VRbufpos] = '\0';
  343.  
  344.                         /*
  345.                         ** copy into argument union
  346.                         */
  347.  
  348.                         (void)sscanf(VRtempdata,"%d",&VRdatalen);
  349.                         (void)sscanf(VRtempdata,"%d",&VRargs[VRargcount].a_num);
  350.                         if (VRdatalen > LINEMAX)
  351.                             VRdatalen = LINEMAX;
  352.                         VRargcount++;
  353.                         VRbufpos = 0;
  354.  
  355.                         if (c == DELIM)
  356.                             VRstate = VRnextargstate(VRargcount, VRcmdnum);
  357.                         else
  358.                             if (cmdtab[VRcmdnum].c_flags & FL_DATA)
  359.                                 VRstate = DATA;
  360.                             else {
  361.  
  362.                                 /*
  363.                                 ** run the command
  364.                                 */
  365.  
  366.                                 (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L);
  367.                                 VRstate = DONE;
  368.                             }
  369.  
  370.                         /*
  371.                         ** allocate storage for data
  372.                         */
  373.  
  374.                         VRptr = VRspace;
  375.  
  376.                         if (VRptr == (char *)0L) {
  377.                             VRstate = DONE;
  378.                             return 0;
  379.                         }
  380.                         VRptr2 = VRptr;
  381.                         decode0();            /* reset decoder */
  382.  
  383.                         break;
  384.  
  385.                     /*
  386.                     ** copy over characters for later
  387.                     */
  388.  
  389.                     default:
  390.                         VRtempdata[VRbufpos++] = c;
  391.                 }
  392.                 break;
  393.  
  394.             /*
  395.             ** retrieve a line of data
  396.             */
  397.  
  398.             case DATA:
  399.                 
  400.                 /*
  401.                 ** store bytes until done
  402.                 */
  403.  
  404.                 if (0 <= (i = decode1(c))) {
  405.                     *VRptr2++ = i;
  406.                     --VRdatalen;
  407.                 }
  408.  
  409.                 if (!VRdatalen) {
  410.  
  411.                     /*
  412.                     ** we've got all of the data
  413.                     */
  414.  
  415.                     (*cmdtab[VRcmdnum].c_func)(VRargs, VRptr);
  416.                     VRstate = DONE;
  417.                 }
  418.  
  419.                 break;
  420.  
  421.         }        /* end switch(VRstate)*/
  422.  
  423.         p++;
  424.         count++;
  425.     }            /* end while loop */
  426.  
  427.     return count;
  428. }
  429.  
  430. /*
  431. ** VRnextargstate -- return the next state based on where we're
  432. **                  -- at already.
  433. **
  434. ** Arguments:
  435. **
  436. ** int ac         -- current argument count
  437. ** int state       -- current state
  438. ** int c          -- current command
  439. **
  440. ** Returns:
  441. **
  442. ** int             -- next state to move to
  443. **
  444. */
  445.  
  446. static int VRnextargstate(ac, c)
  447. int ac;
  448. int c;
  449. {
  450.  
  451.     switch (cmdtab[c].c_args[ac]) {
  452.         case INT:
  453.             return IARG;
  454.         case STRING:
  455.             return SARG;
  456.         case COUNT:
  457.             return CARG;
  458.         case 0:
  459.             return DATA;
  460.  
  461.         /*
  462.         ** in case of error
  463.         */
  464.  
  465.         default:
  466.             return DONE;
  467.     }
  468. }
  469.  
  470. /*
  471. ** VRwindow -- create a new raster window
  472. **
  473. ** Arguments:
  474. **
  475. **    union arg av[];    -- the argument vector
  476. **
  477. **    int        av[0, 1];     -- upper left;
  478. **    int        av[2, 3];     -- width, height
  479. **    int        av[4];         -- window hardware display number
  480. **    char    *av[5];       -- title
  481. **
  482. ** Returns:
  483. **
  484. **    None.  No provision has been made for error returns in any of
  485. **    these routines because I don't know what to do if an error
  486. **    occurs.  Perhaps a better man than I can figure out how to 
  487. **    deal with this.
  488. **    N.B -- these functions are declared as int, in the event
  489. **    that an error return is added.
  490. */
  491.  
  492. int VRwindow(av)
  493. union arg av[];
  494. {
  495.  
  496.     VRW    *w = VRhead.w_next;
  497.  
  498.     /*
  499.     ** search list, and if needed, NewPtr some space for a new window thing
  500.     */
  501.  
  502.     while (w) {
  503.         if (!strcmp(w->w_name,av[5].a_ptr)
  504.             && w->w_width == av[2].a_num 
  505.             && w->w_height == av[3].a_num)        /* don't re-allocate win */
  506.             return(1);
  507.         if (!strcmp(w->w_name,av[5].a_ptr))        /* duplicate, different size */
  508.             w->w_used = 1;
  509.         w = w->w_next;
  510.     }
  511.  
  512.     w = (VRW *)NewPtr(sizeof(VRW));                /* new element for list */
  513.     if (!w)
  514.         return(-1);
  515.         
  516.     w->w_next = VRhead.w_next;                    /* set next equal to current head */
  517.     VRhead.w_next = w;                            /* set head of list equal to me */
  518.     
  519.     /*
  520.     ** fill in the new window area
  521.     */
  522.  
  523.     w->w_left = av[0].a_num;
  524.     w->w_top = av[1].a_num;
  525.     w->w_width = av[2].a_num;
  526.     w->w_height = av[3].a_num;
  527.     w->w_display = av[4].a_num;
  528.     w->w_used = 0;
  529.     strncpy(w->w_name,av[5].a_ptr,100);
  530.  
  531.     if (w->w_width > LINEMAX)            /* have to be SOME limits */
  532.         w->w_width = LINEMAX;
  533.  
  534.     return RasWindow(w);
  535. }
  536.  
  537. /*
  538. ** VRdestroy -- destroy a window by name
  539. **
  540. ** Arguments:
  541. **
  542. **   union arg av[]; -- the argument vector
  543. **
  544. **   char *av[0] -- the name of the window
  545. **
  546. ** Returns:
  547. **
  548. **   None.
  549. **
  550. */
  551.  
  552. int VRdestroy
  553.   (
  554.     char *av        /* BYU LSC - was "union arg av[]" */
  555.   )
  556. {
  557.     VRW            *w,*ow;
  558.     extern int    strcmp();
  559.  
  560.     ow = &VRhead;
  561.     w = ow->w_next;
  562.  
  563.     while (w) {
  564.         if (!strcmp(w->w_name, av)) {        /* BYU LSC - was "av[0].a_ptr" */
  565.             RasDestroy(w);
  566.             ow->w_next = w->w_next;
  567.             DisposPtr((char *)w);
  568.         }
  569.         else
  570.             ow = ow->w_next;
  571.  
  572.         w = ow->w_next;
  573.     }
  574.  
  575.     return 0;
  576. }
  577.  
  578. /*
  579. ** VRmap -- take a color map command and set the palette
  580. **
  581. ** Arguments:
  582. **
  583. **   union arg av[]; -- the argument vector
  584. **
  585. **   int     av[0, 1];  -- start & length of map segment
  586. **     int    av[2];     -- count of data needed (info only)
  587. **     char    *av[3];    -- window name
  588. **   char    *data;     -- pointer to the data  
  589. **
  590. ** Returns:
  591. **
  592. **   None.
  593. **
  594. */
  595.  
  596. int VRmap(av,data)
  597. union arg    av[];
  598. char        *data;
  599. {
  600.     VRW            *w;
  601.     VRW            *VRlookup();
  602.  
  603.     w = VRlookup(av[3].a_ptr);
  604.  
  605.     if (!w)
  606.         return 0;
  607.  
  608.     return (*RGmap)(av[0].a_num, av[1].a_num, data);
  609. }
  610.  
  611. /*
  612. ** VRpixel -- display a line of pixel data
  613. ** 
  614. ** Arugments:
  615. **
  616. **    union arg av[]; -- the argument vector
  617. **
  618. **    int        av[0];  -- x coordinate
  619. **    int         av[1];  -- y coordinate
  620. **  int     av[2];  -- pixel expansion factor
  621. **    int         av[3];  -- length of data
  622. **    char    *av[4]; -- window name
  623. **    char    *data;  -- pointer to data
  624. **
  625. ** Returns:
  626. **
  627. **    None.
  628. **
  629. */
  630.  
  631. int VRpixel(av, data)
  632. union arg    av[];
  633. char        *data;
  634. {
  635.     VRW *w;
  636.     VRW *VRlookup();
  637.     int i,lim;
  638.     char *p,*q;
  639.  
  640.     /*
  641.     ** find the right window
  642.     */
  643.  
  644.     w = VRlookup(av[4].a_ptr);
  645.  
  646.     if (w == (VRW *)0L)
  647.         return 0;
  648.  
  649.     lim = av[3].a_num*av[2].a_num;        /* total number of expanded pixels */
  650.     if (lim > w->w_width)
  651.         lim = w->w_width;
  652.  
  653.     if (av[2].a_num > 1) {
  654.         p = data;
  655.         q = VRsp2;
  656.         for (i=0; i < lim; i++) {
  657.             *q++ = *p;
  658.             if (!((i+1) % av[2].a_num))
  659.                 p++;
  660.         }
  661.         for (i=0; i<av[2].a_num; i++)
  662.             (*RGraster)( VRsp2, av[0].a_num, av[1].a_num+i,
  663.                              av[0].a_num+lim, av[1].a_num+i,lim);
  664.  
  665.     }
  666.     else
  667.         return     (*RGraster)( data, av[0].a_num, av[1].a_num,
  668.                     av[0].a_num+av[3].a_num, av[1].a_num,lim);
  669.  
  670.     return 0;
  671. }
  672.  
  673. /*
  674. ** VRimp -- display a line of IMPCOMP encoded data
  675. **   One line of IMPCOMP data gives 4 lines output.
  676. ** 
  677. ** Arugments:
  678. **
  679. **    union arg av[]; -- the argument vector
  680. **
  681. **    int        av[0];  -- x coordinate
  682. **    int         av[1];  -- y coordinate
  683. **  int     av[2];  -- pixel expansion
  684. **    int         av[3];  -- length of data
  685. **    char    *av[4]; -- window name
  686. **    char    *data;  -- pointer to data
  687. **
  688. ** Returns:
  689. **
  690. **    None.
  691. **
  692. */
  693.  
  694. #if 1                /* BYU LSC */
  695. void unimcomp(unsigned char in[], unsigned char out[], int, int);
  696. #else                /* BYU LSC */
  697. void unimcomp();
  698. #endif                /* BYU LSC */
  699.  
  700. int VRimp(av, data)
  701. union arg    av[];
  702. char        *data;
  703. {
  704.     VRW *w;
  705.     VRW *VRlookup();
  706.     int i,lim,j;
  707.     char *p,*q;
  708.  
  709.     /*
  710.     ** find the right window
  711.     */
  712.  
  713.     w = VRlookup(av[4].a_ptr);
  714.  
  715.     if (w == (VRW *)0L)
  716.         return 0;
  717.  
  718.     unimcomp((unsigned char *) data,(unsigned char *) VRsp2,av[3].a_num,w->w_width);   /* BYU LSC - decompress it */
  719.     /* gives four lines in the VRsp2 buffer, now pixel expand */
  720.  
  721.     i = av[3].a_num;
  722.  
  723.     lim = i*av[2].a_num;        /* total number of expanded pixels on a line*/
  724.     if (lim > w->w_width)
  725.         lim = w->w_width;
  726.     if (i > w->w_width)
  727.         i = w->w_width;
  728.  
  729.     p = VRsp2;                                /* from this buffer */
  730.     for (j=0; j<4; j++) {
  731.         if (av[2].a_num > 1) {
  732.             q = VRspace;                    /* to here */
  733.             for (i=0; i < lim; i++) {
  734.                 *q++ = *p;
  735.                 if (!((i+1) % av[2].a_num))
  736.                     p++;
  737.             }
  738.             p++;
  739.             for (i=0; i<av[2].a_num; i++)
  740.                 (*RGraster)(VRspace, av[0].a_num, av[1].a_num+i+j*av[2].a_num,
  741.                     av[0].a_num + av[3].a_num,    av[1].a_num+i+j*av[2].a_num, lim );
  742.  
  743.         }
  744.         else {
  745.             (*RGraster)(p, av[0].a_num,        av[1].a_num+j,
  746.                     av[0].a_num + av[3].a_num, av[1].a_num+j, i);
  747.             p += av[3].a_num;            /* increment to next line */
  748.         }
  749.  
  750.     }
  751.  
  752.     return 0;
  753.  
  754. }
  755.  
  756. /************************************************************************/
  757. /*  Function    : unimcomp                        */
  758. /*  Purpose    : 'Decompresses' the compressed image            */
  759. /*  Parameter    :                            */
  760. /*    xdim       - x dimensions of image                */
  761. /*    lines      - number of lines of compressed image                  */
  762. /*    in, out    - Input buffer and output buffer. Size of input buffer */
  763. /*           is xdim*lines. Size of output buffer is 4 times      */
  764. /*           that. It 'restores' images into seq-type files       */
  765. /*  Returns      : none                            */
  766. /*  Called by   : External routines                    */
  767. /*  Calls       : none                            */
  768. /************************************************************************/
  769.  
  770. void unimcomp(in, out, xdim, xmax)
  771. int xdim, xmax;
  772. unsigned char in[], out[];
  773. {
  774.   int bitmap, temp, lines=1;
  775.   register int i, j, k, x;
  776.   unsigned char hi_color, lo_color;
  777.  
  778.     if (xmax < xdim)        /* don't go over */
  779.         xdim = xmax;
  780.  
  781.   /* go over the compressed image */
  782.     for (x=0; x<xdim; x=x+4)
  783.     {
  784.       k = x;
  785.       hi_color = in[k+2]; 
  786.       lo_color = in[k+3];
  787.  
  788.       bitmap = (in[k] << 8) | in[k+1];
  789.  
  790.       /* store in out buffer */
  791.       for (i=0; i<4; i++)
  792.       {
  793.         temp = bitmap >> (3 - i)*4;
  794.         for (j=x; j<(x+4); j++)
  795.         {
  796.        if ((temp & 8) == 8)
  797.         out[i*xdim+j] = hi_color;
  798.       else
  799.         out[i*xdim+j] = lo_color;
  800.       temp = temp << 1;
  801.     }
  802.       }
  803.     } /* end of for x */
  804. } /* end of unimcomp */
  805.  
  806. /*****************************************************************/
  807. /*  unrleit
  808. *  Decompress run length encoding.
  809. *  
  810. */
  811.  
  812. int unrleit
  813.   (
  814.     unsigned char *buf,
  815.     unsigned char *bufto,
  816.     int inlen,
  817.     int outlen
  818.   )
  819.   {
  820.     register int cnt;
  821.     register unsigned char *p,*q;
  822.     unsigned char *endp,*endq;
  823.     
  824.     p = buf;
  825.     endp = buf + inlen;
  826.     q = bufto;
  827.     endq = bufto + outlen;
  828.     while (p < endp && q < endq) /* go 'til p or q hits end */
  829.       {
  830.         cnt = *p++;            /* count field */
  831.         if (!(cnt & 128))/* is set of uniques */
  832.           {
  833.             while (cnt-- && q < endq)
  834.                 *q++ = *p++;    /* copy unmodified */
  835.           }
  836.         else
  837.           {
  838.             cnt &= 127;            /* strip high bit */
  839.             while (cnt-- && q < endq)
  840.                 *q++ = *p;        /* copy same character */
  841.             p++;                /* skip that character */
  842.           } /* if */
  843.       } /* while */
  844.     return((int)(q-bufto));
  845.   } /* unrleit */
  846.  
  847. /***************************************************************************/
  848. /*
  849. ** VRrle -- display a line of run-length encoded data
  850. ** 
  851. ** Arugments:
  852. **
  853. **    union arg av[]; -- the argument vector
  854. **
  855. **    int        av[0];  -- x coordinate
  856. **    int         av[1];  -- y coordinate
  857. **  int     av[2];  -- pixel expansion
  858. **    int         av[3];  -- length of data
  859. **    char    *av[4]; -- window name
  860. **    char    *data;  -- pointer to data
  861. **
  862. ** Returns:
  863. **
  864. **    None.
  865. **
  866. */
  867.  
  868. int VRrle(av, data)
  869. union arg    av[];
  870. char        *data;
  871. {
  872.     VRW *w;
  873.     VRW *VRlookup();
  874.     int i,lim;
  875.     char *p,*q;
  876.  
  877.     /*
  878.     ** find the right window
  879.     */
  880.  
  881.     w = VRlookup(av[4].a_ptr);
  882.  
  883.     if (w == (VRW *)0L)
  884.         return 0;
  885.  
  886.     i = unrleit((unsigned char *) data,(unsigned char *) VRsp2,av[3].a_num,w->w_width);   /* BYU LSC - decompress it */
  887.  
  888.  
  889.     lim = i*av[2].a_num;                /* total number of expanded pixels */
  890.     if (lim > w->w_width)
  891.         lim = w->w_width;
  892.  
  893.     if (av[2].a_num > 1) {
  894.         p = VRsp2;                        /* from this buffer */
  895.         q = VRspace;                    /* to here */
  896.         for (i=0; i < lim; i++) {
  897.             *q++ = *p;
  898.             if (!((i+1) % av[2].a_num))
  899.                 p++;
  900.         }
  901.         for (i=0; i<av[2].a_num; i++)
  902.             (*RGraster)( VRspace, av[0].a_num, av[1].a_num+i,
  903.                              av[0].a_num+lim, av[1].a_num+i,lim);
  904.  
  905.     }
  906.     else
  907.         return     (*RGraster)( VRsp2, av[0].a_num, av[1].a_num,
  908.                     av[0].a_num+i, av[1].a_num,i);
  909.  
  910.     return 0;
  911.  
  912. }
  913.  
  914. /*
  915. ** VRfile    -- cause the named window to be dumped to a file
  916. **
  917. ** Arguments:
  918. **
  919. **    union arg av[];        -- the argument vector
  920. **
  921. **    int        av[0];        -- start x coordinate
  922. **    int        av[1];        -- start y coordinate
  923. **    int        av[2];        -- width of region to dump
  924. **    int        av[3];        -- height of region to dump
  925. **    int        av[4];        -- format of file -- machine dependent
  926. **    char    *av[5];        -- file name to use
  927. **    char    *av[6];        -- window name to dump
  928. **
  929. ** Returns:
  930. **
  931. **    int;                -- 1 if success, 0 if failure
  932. **
  933. */
  934.  
  935. int VRfile(av)
  936. union arg av[];
  937. {
  938. #ifdef IMPLEMENTED
  939.     VRW    *w;
  940.     VRW    *VRlookup();
  941.  
  942.     /*
  943.     ** Look up the window
  944.     */
  945.  
  946.     w = VRlookup(av[6].a_ptr);
  947.  
  948.     if (w == (VRW *)0L)
  949.         return 0;
  950.  
  951.     /*
  952.     ** call the low level file routine
  953.     */
  954.  
  955.     return RRfile(w, av[0].a_num, av[1].a_num, av[2].a_num, av[3].a_num,
  956.         av[4].a_num, av[5].a_ptr);
  957. #else IMPLEMENTED
  958. #pragma unused(av)
  959.     return 0;
  960. #endif IMPLEMENTED
  961. }
  962.  
  963. /*
  964. ** VRclick    -- Click the Slide Camera -- very machine dependent
  965. **
  966. ** Arguments:
  967. **
  968. **    union arg    av[];        -- the argument vector
  969. **
  970. **    char    *av[0];            -- window name
  971. **
  972. ** Returns:
  973. **
  974. **    int;                    -- 1 if success, 0 if failure
  975. */
  976.  
  977. int VRclick(av)
  978. union arg av[];
  979. {
  980. #ifdef IMPLEMENTED
  981.     VRW    *w;
  982.     VRW    *VRlookup();
  983.  
  984.     /*
  985.     ** look up the window
  986.     */
  987.  
  988.     w = VRlookup(av[0].a_ptr);
  989.  
  990.     if (w == (VRW *)0L)
  991.         return 0;
  992.  
  993.     return RRclick(w);
  994. #else IMPLEMENTED
  995. #pragma unused(av)
  996.     return 0;
  997. #endif IMPLEMENTED
  998. }
  999.  
  1000. /*
  1001. ** VRmsave    -- Save the named colormap to the file -- saves the whole thing
  1002. **
  1003. ** Arguments:
  1004. **
  1005. **    union arg    av[];        -- the argument vector
  1006. **
  1007. **    char    *av[0];            -- file name
  1008. **    char    *av[1];            -- window name
  1009. **
  1010. ** Returns:
  1011. **
  1012. **    int;                    -- 1 if success, 0 if failure
  1013. */
  1014.  
  1015. int VRmsave(av)
  1016. union arg av[];
  1017. {
  1018. #ifdef IMPLEMENTED
  1019.     VRW    *w;
  1020.     VRW    *VRlookup();
  1021.  
  1022.     /*
  1023.     ** look up the window
  1024.     */
  1025.  
  1026.     w = VRlookup(av[1].a_ptr);
  1027.  
  1028.     if (w == (VRW *)0L)
  1029.         return 0;
  1030.  
  1031.     return RRmsave(w, av[0].a_ptr);
  1032. #else IMPLEMENTED
  1033. #pragma unused(av)
  1034.     return 0;
  1035. #endif IMPLEMENTED
  1036. }
  1037.  
  1038. /*
  1039. ** VRlookup            -- find an entry in the list by name
  1040. **
  1041. ** Arguments:
  1042. **
  1043. **    char    *name;    -- the name of the window
  1044. **
  1045. ** Returns:
  1046. **
  1047. **    VRW    *w;            -- pointer to window structure, (VRW *)0 if not found
  1048. **
  1049. */
  1050.  
  1051. VRW *VRlookup(name)
  1052. char *name;
  1053. {
  1054.     VRW    *w = VRhead.w_next;
  1055.  
  1056.     while (w) {
  1057.         if (!strcmp(w->w_name, name) && !w->w_used) {    /* same name, not old dup */
  1058.             if (RasSetwind(w))                            /* maybe window don't work */
  1059.                 return(NULL);
  1060.             return(w);
  1061.             }
  1062.         w = w->w_next;
  1063.     }
  1064.  
  1065.     return(NULL);
  1066. }
  1067.  
  1068. /*
  1069. ** VRcleanup -- remove all windows from the screen
  1070. **
  1071. ** Arguments:
  1072. **
  1073. **    None.
  1074. **
  1075. ** Returns:
  1076. **
  1077. **    int;    1    -- always successful, or there's nothing you can do
  1078. **                -- about it anyways...
  1079. **
  1080. */
  1081.  
  1082. int VRcleanup()
  1083. {
  1084.     VRW *w = VRhead.w_next;
  1085.     VRW *x;
  1086.  
  1087.     while (w != (VRW *)0L) {
  1088.         x = w->w_next;
  1089.         RasDestroy(w);
  1090.         w = x;
  1091.     }
  1092.  
  1093.     return 1;
  1094. }
  1095.  
  1096. /************************************************************************/
  1097. /*  decoding
  1098. *   handle the special ASCII printable character encoding of data bytes.
  1099. */
  1100.  
  1101. /***********************************************************************/
  1102. /*
  1103. *  123 precedes #'s 0-63 
  1104. *  124 precedes #'s 64-127
  1105. *  125 precedes #'s 128-191
  1106. *  126 precedes #'s 192-255
  1107. *  overall:  realchar = (specialchar - 123)*64 + (char-32) 
  1108. *            specialchar = r div 64 + 123
  1109. *            char = r mod 64 + 32
  1110. */
  1111. /***********************************************************************/
  1112.