home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / ncsat.cpt / Telnet2.5 final / vr / vr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-23  |  19.2 KB  |  1,108 lines

  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.     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[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. void unimcomp();
  695.  
  696. int VRimp(av, data)
  697. union arg    av[];
  698. char        *data;
  699. {
  700.     VRW *w;
  701.     VRW *VRlookup();
  702.     int i,lim,j;
  703.     char *p,*q;
  704.  
  705.     /*
  706.     ** find the right window
  707.     */
  708.  
  709.     w = VRlookup(av[4].a_ptr);
  710.  
  711.     if (w == (VRW *)0L)
  712.         return 0;
  713.  
  714.     unimcomp(data,VRsp2,av[3].a_num,w->w_width);   /* decompress it */
  715.     /* gives four lines in the VRsp2 buffer, now pixel expand */
  716.  
  717.     i = av[3].a_num;
  718.  
  719.     lim = i*av[2].a_num;        /* total number of expanded pixels on a line*/
  720.     if (lim > w->w_width)
  721.         lim = w->w_width;
  722.     if (i > w->w_width)
  723.         i = w->w_width;
  724.  
  725.     p = VRsp2;                                /* from this buffer */
  726.     for (j=0; j<4; j++) {
  727.         if (av[2].a_num > 1) {
  728.             q = VRspace;                    /* to here */
  729.             for (i=0; i < lim; i++) {
  730.                 *q++ = *p;
  731.                 if (!((i+1) % av[2].a_num))
  732.                     p++;
  733.             }
  734.             p++;
  735.             for (i=0; i<av[2].a_num; i++)
  736.                 (*RGraster)(VRspace, av[0].a_num, av[1].a_num+i+j*av[2].a_num,
  737.                     av[0].a_num + av[3].a_num,    av[1].a_num+i+j*av[2].a_num, lim );
  738.  
  739.         }
  740.         else {
  741.             (*RGraster)(p, av[0].a_num,        av[1].a_num+j,
  742.                     av[0].a_num + av[3].a_num, av[1].a_num+j, i);
  743.             p += av[3].a_num;            /* increment to next line */
  744.         }
  745.  
  746.     }
  747.  
  748.     return 0;
  749.  
  750. }
  751.  
  752. /************************************************************************/
  753. /*  Function    : unimcomp                        */
  754. /*  Purpose    : 'Decompresses' the compressed image            */
  755. /*  Parameter    :                            */
  756. /*    xdim       - x dimensions of image                */
  757. /*    lines      - number of lines of compressed image                  */
  758. /*    in, out    - Input buffer and output buffer. Size of input buffer */
  759. /*           is xdim*lines. Size of output buffer is 4 times      */
  760. /*           that. It 'restores' images into seq-type files       */
  761. /*  Returns      : none                            */
  762. /*  Called by   : External routines                    */
  763. /*  Calls       : none                            */
  764. /************************************************************************/
  765.  
  766. void unimcomp(in, out, xdim, xmax)
  767. int xdim, xmax;
  768. unsigned char in[], out[];
  769. {
  770.   int bitmap, temp, lines=1;
  771.   register int i, j, k, x;
  772.   unsigned char hi_color, lo_color;
  773.  
  774.     if (xmax < xdim)        /* don't go over */
  775.         xdim = xmax;
  776.  
  777.   /* go over the compressed image */
  778.     for (x=0; x<xdim; x=x+4)
  779.     {
  780.       k = x;
  781.       hi_color = in[k+2]; 
  782.       lo_color = in[k+3];
  783.  
  784.       bitmap = (in[k] << 8) | in[k+1];
  785.  
  786.       /* store in out buffer */
  787.       for (i=0; i<4; i++)
  788.       {
  789.         temp = bitmap >> (3 - i)*4;
  790.         for (j=x; j<(x+4); j++)
  791.         {
  792.        if ((temp & 8) == 8)
  793.         out[i*xdim+j] = hi_color;
  794.       else
  795.         out[i*xdim+j] = lo_color;
  796.       temp = temp << 1;
  797.     }
  798.       }
  799.     } /* end of for x */
  800. } /* end of unimcomp */
  801.  
  802. /*****************************************************************/
  803. /*  unrleit
  804. *  Decompress run length encoding.
  805. *  
  806. */
  807.  
  808. int unrleit
  809.   (
  810.     unsigned char *buf,
  811.     unsigned char *bufto,
  812.     int inlen,
  813.     int outlen
  814.   )
  815.   {
  816.     register int cnt;
  817.     register unsigned char *p,*q;
  818.     unsigned char *endp,*endq;
  819.     
  820.     p = buf;
  821.     endp = buf + inlen;
  822.     q = bufto;
  823.     endq = bufto + outlen;
  824.     while (p < endp && q < endq) /* go 'til p or q hits end */
  825.       {
  826.         cnt = *p++;            /* count field */
  827.         if (!(cnt & 128))/* is set of uniques */
  828.           {
  829.             while (cnt-- && q < endq)
  830.                 *q++ = *p++;    /* copy unmodified */
  831.           }
  832.         else
  833.           {
  834.             cnt &= 127;            /* strip high bit */
  835.             while (cnt-- && q < endq)
  836.                 *q++ = *p;        /* copy same character */
  837.             p++;                /* skip that character */
  838.           } /* if */
  839.       } /* while */
  840.     return((int)(q-bufto));
  841.   } /* unrleit */
  842.  
  843. /***************************************************************************/
  844. /*
  845. ** VRrle -- display a line of run-length encoded data
  846. ** 
  847. ** Arugments:
  848. **
  849. **    union arg av[]; -- the argument vector
  850. **
  851. **    int        av[0];  -- x coordinate
  852. **    int         av[1];  -- y coordinate
  853. **  int     av[2];  -- pixel expansion
  854. **    int         av[3];  -- length of data
  855. **    char    *av[4]; -- window name
  856. **    char    *data;  -- pointer to data
  857. **
  858. ** Returns:
  859. **
  860. **    None.
  861. **
  862. */
  863.  
  864. int VRrle(av, data)
  865. union arg    av[];
  866. char        *data;
  867. {
  868.     VRW *w;
  869.     VRW *VRlookup();
  870.     int i,lim;
  871.     char *p,*q;
  872.  
  873.     /*
  874.     ** find the right window
  875.     */
  876.  
  877.     w = VRlookup(av[4].a_ptr);
  878.  
  879.     if (w == (VRW *)0L)
  880.         return 0;
  881.  
  882.     i = unrleit(data,VRsp2,av[3].a_num,w->w_width);   /* decompress it */
  883.  
  884.  
  885.     lim = i*av[2].a_num;                /* total number of expanded pixels */
  886.     if (lim > w->w_width)
  887.         lim = w->w_width;
  888.  
  889.     if (av[2].a_num > 1) {
  890.         p = VRsp2;                        /* from this buffer */
  891.         q = VRspace;                    /* to here */
  892.         for (i=0; i < lim; i++) {
  893.             *q++ = *p;
  894.             if (!((i+1) % av[2].a_num))
  895.                 p++;
  896.         }
  897.         for (i=0; i<av[2].a_num; i++)
  898.             (*RGraster)( VRspace, av[0].a_num, av[1].a_num+i,
  899.                              av[0].a_num+lim, av[1].a_num+i,lim);
  900.  
  901.     }
  902.     else
  903.         return     (*RGraster)( VRsp2, av[0].a_num, av[1].a_num,
  904.                     av[0].a_num+i, av[1].a_num,i);
  905.  
  906.     return 0;
  907.  
  908. }
  909.  
  910. /*
  911. ** VRfile    -- cause the named window to be dumped to a file
  912. **
  913. ** Arguments:
  914. **
  915. **    union arg av[];        -- the argument vector
  916. **
  917. **    int        av[0];        -- start x coordinate
  918. **    int        av[1];        -- start y coordinate
  919. **    int        av[2];        -- width of region to dump
  920. **    int        av[3];        -- height of region to dump
  921. **    int        av[4];        -- format of file -- machine dependent
  922. **    char    *av[5];        -- file name to use
  923. **    char    *av[6];        -- window name to dump
  924. **
  925. ** Returns:
  926. **
  927. **    int;                -- 1 if success, 0 if failure
  928. **
  929. */
  930.  
  931. int VRfile(av)
  932. union arg av[];
  933. {
  934. #ifdef IMPLEMENTED
  935.     VRW    *w;
  936.     VRW    *VRlookup();
  937.  
  938.     /*
  939.     ** Look up the window
  940.     */
  941.  
  942.     w = VRlookup(av[6].a_ptr);
  943.  
  944.     if (w == (VRW *)0L)
  945.         return 0;
  946.  
  947.     /*
  948.     ** call the low level file routine
  949.     */
  950.  
  951.     return RRfile(w, av[0].a_num, av[1].a_num, av[2].a_num, av[3].a_num,
  952.         av[4].a_num, av[5].a_ptr);
  953. #else IMPLEMENTED
  954. #pragma unused(av)
  955.     return 0;
  956. #endif IMPLEMENTED
  957. }
  958.  
  959. /*
  960. ** VRclick    -- Click the Slide Camera -- very machine dependent
  961. **
  962. ** Arguments:
  963. **
  964. **    union arg    av[];        -- the argument vector
  965. **
  966. **    char    *av[0];            -- window name
  967. **
  968. ** Returns:
  969. **
  970. **    int;                    -- 1 if success, 0 if failure
  971. */
  972.  
  973. int VRclick(av)
  974. union arg av[];
  975. {
  976. #ifdef IMPLEMENTED
  977.     VRW    *w;
  978.     VRW    *VRlookup();
  979.  
  980.     /*
  981.     ** look up the window
  982.     */
  983.  
  984.     w = VRlookup(av[0].a_ptr);
  985.  
  986.     if (w == (VRW *)0L)
  987.         return 0;
  988.  
  989.     return RRclick(w);
  990. #else IMPLEMENTED
  991. #pragma unused(av)
  992.     return 0;
  993. #endif IMPLEMENTED
  994. }
  995.  
  996. /*
  997. ** VRmsave    -- Save the named colormap to the file -- saves the whole thing
  998. **
  999. ** Arguments:
  1000. **
  1001. **    union arg    av[];        -- the argument vector
  1002. **
  1003. **    char    *av[0];            -- file name
  1004. **    char    *av[1];            -- window name
  1005. **
  1006. ** Returns:
  1007. **
  1008. **    int;                    -- 1 if success, 0 if failure
  1009. */
  1010.  
  1011. int VRmsave(av)
  1012. union arg av[];
  1013. {
  1014. #ifdef IMPLEMENTED
  1015.     VRW    *w;
  1016.     VRW    *VRlookup();
  1017.  
  1018.     /*
  1019.     ** look up the window
  1020.     */
  1021.  
  1022.     w = VRlookup(av[1].a_ptr);
  1023.  
  1024.     if (w == (VRW *)0L)
  1025.         return 0;
  1026.  
  1027.     return RRmsave(w, av[0].a_ptr);
  1028. #else IMPLEMENTED
  1029. #pragma unused(av)
  1030.     return 0;
  1031. #endif IMPLEMENTED
  1032. }
  1033.  
  1034. /*
  1035. ** VRlookup            -- find an entry in the list by name
  1036. **
  1037. ** Arguments:
  1038. **
  1039. **    char    *name;    -- the name of the window
  1040. **
  1041. ** Returns:
  1042. **
  1043. **    VRW    *w;            -- pointer to window structure, (VRW *)0 if not found
  1044. **
  1045. */
  1046.  
  1047. VRW *VRlookup(name)
  1048. char *name;
  1049. {
  1050.     VRW    *w = VRhead.w_next;
  1051.  
  1052.     while (w) {
  1053.         if (!strcmp(w->w_name, name) && !w->w_used) {    /* same name, not old dup */
  1054.             if (RasSetwind(w))                            /* maybe window don't work */
  1055.                 return(NULL);
  1056.             return(w);
  1057.             }
  1058.         w = w->w_next;
  1059.     }
  1060.  
  1061.     return(NULL);
  1062. }
  1063.  
  1064. /*
  1065. ** VRcleanup -- remove all windows from the screen
  1066. **
  1067. ** Arguments:
  1068. **
  1069. **    None.
  1070. **
  1071. ** Returns:
  1072. **
  1073. **    int;    1    -- always successful, or there's nothing you can do
  1074. **                -- about it anyways...
  1075. **
  1076. */
  1077.  
  1078. int VRcleanup()
  1079. {
  1080.     VRW *w = VRhead.w_next;
  1081.     VRW *x;
  1082.  
  1083.     while (w != (VRW *)0L) {
  1084.         x = w->w_next;
  1085.         RasDestroy(w);
  1086.         w = x;
  1087.     }
  1088.  
  1089.     return 1;
  1090. }
  1091.  
  1092. /************************************************************************/
  1093. /*  decoding
  1094. *   handle the special ASCII printable character encoding of data bytes.
  1095. */
  1096.  
  1097. /***********************************************************************/
  1098. /*
  1099. *  123 precedes #'s 0-63 
  1100. *  124 precedes #'s 64-127
  1101. *  125 precedes #'s 128-191
  1102. *  126 precedes #'s 192-255
  1103. *  overall:  realchar = (specialchar - 123)*64 + (char-32) 
  1104. *            specialchar = r div 64 + 123
  1105. *            char = r mod 64 + 32
  1106. */
  1107. /***********************************************************************/
  1108.