home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff330.lzh / Vt100 / Src.lzh / Src / remote.c < prev    next >
C/C++ Source or Header  |  1990-03-01  |  12KB  |  447 lines

  1. static char rcsid[] = "$RCSfile: remote.c,v $ $Revision: 1.4 $";
  2.  
  3. /****************************************************
  4.  * vt100 emulator - remote character interpretation
  5.  *        :ts=8
  6.  *
  7.  * $Log:    remote.c,v $
  8.  * Revision 1.4  89/12/18  20:44:21  acs
  9.  * doremote() no longer needs to strip parity...the main loop in vt100.c
  10.  * takes care of it now.
  11.  * 
  12.  * Revision 1.3  89/11/02  10:13:38  acs
  13.  * doremote(): strip parity from data destined for display if user has
  14.  * requested it (p_strip is set).
  15.  * 
  16.  * Revision 1.2  89/11/01  20:28:42  acs
  17.  * 1) Correct use of Ysize in coordinate calculation.  Thanks to Sean
  18.  *    Hogan (sean2@garfield.mun.ca).
  19.  * 2) Add RCS id and change log.
  20.  * 
  21.  *    V2.9 ACS - CAN was not cancelling a control sequence (thanks
  22.  *           to Bill Kinnersly.
  23.  *    V2.8          Insert/delete character (@/P) by John Wang
  24.  *              (jwang@ATRP.MEDIA.MIT.EDU)
  25.  *    v2.7 870227 ACS - No changes to this routine.
  26.  *    v2.6 870227 DBW - bug fixes for all the stuff in v2.5
  27.  *    v2.5 870214 DBW - more additions (see readme file)
  28.  *    v2.4 861214 DBW - lots of fixes/additions (see readme file)
  29.  *    v2.3 861101 DBW - minor bug fixes
  30.  *    v2.2 861012 DBW - more of the same
  31.  *    v2.1 860915 DBW - new features (see README)
  32.  *         860823 DBW - Integrated and rewrote lots of code
  33.  *    v2.0 860803 DRB - Rewrote the control sequence parser
  34.  *    v1.1 860720 DBW    - Switches, 80 cols, colors, bug fixes
  35.  *    v1.0 860712 DBW    - First version released
  36.  *
  37.  ****************************************************/
  38.  
  39. #include "vt100.h"
  40.  
  41. static int    p[10];
  42. static int    numpar;
  43. static char   escseq[40];
  44.  
  45. static void doalt(), doline();
  46.  
  47. /************************************************
  48. *  function to handle remote characters
  49. *************************************************/
  50. void doremote(c)
  51. char c;
  52.     {
  53.     if (c == 24) { inesc = -1; inctrl = -1; return; }
  54.     if (c == 27 || (inesc >= 0 && c >= ' ')) { doesc(c); return; }
  55.     if (inctrl >= 0 && c >= ' ') { doctrl(c); return; }
  56.     if (c == 10 || c == 11 || c == 12) {
  57.     if (nlmode) doindex('E'); else doindex('D');
  58.     return;
  59.     }
  60.     if (c == 13) {
  61.     if (!nlmode) emit(c);
  62.     return;
  63.     }
  64.     if (c == 15) { alt = 0; return; }
  65.     if (c == 14) { alt = 1; return; }
  66.     if (a[alt] && c > 94 && c < 127) { doalt(c); return; }
  67.     emit(c);
  68.     }
  69.  
  70. void doesc(c)
  71. char c;
  72. {
  73.     if (inesc < 0) { inesc = 0; return; }
  74.     if (c == 27 || c == 24) { inesc = -1; return; }
  75.     if (c < ' ' || c == 127) return;      /* Ignore control chars */
  76.  
  77.     /* Collect intermediates */
  78.     if (c < '0') {escseq[inesc++] = c; return; }
  79.  
  80.     /* by process of elimination, we have a final character.
  81.        Put it in the buffer, and dispatch on the first character
  82.        in the buffer */
  83.  
  84.     escseq[inesc] = c;
  85.     inesc = -1;                /* No longer collecting a sequence */
  86.     switch (escseq[0])            /* Dispatch on the first received */
  87.     {
  88.       case '[':                /* Control sequence introducer */
  89.     numpar = 0;            /* No parameters yet */
  90.     private = 0;            /* Not a private sequence (yet?) */
  91.     badseq = 0;            /* Good until proven bad */
  92.     p[0] = p[1] = 0;        /* But default the first parameter */
  93.     inctrl = 0;            /* We are in a control sequence */
  94.     return;                /* All done for now ... */
  95.  
  96.       case 'D': case 'E': case 'M':    /* Some kind of index */
  97.     doindex (c);            /* Do the index */
  98.     return;                /* Return */
  99.  
  100.       case '7':                /* Save cursor position */
  101.     savx = x; savy = y; savmode = curmode; savalt = alt;
  102.     sa[0] = a[0]; sa[1] = a[1];
  103.     return;
  104.  
  105.       case '8':                /* Restore cursor position */
  106.     x = savx; y = savy; alt = savalt; curmode = savmode;
  107.     a[0] = sa[0]; a[1] = sa[1];
  108.     return;
  109.  
  110.       case 'c':                /* Reset */
  111.     top = MINY; bot = MAXY; savx = MINX; savy = MINY;
  112.     curmode = FS_NORMAL; p_keyapp = 0; p_curapp = 0;
  113.     inesc = -1;
  114.     a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
  115.     redoutil();
  116.     emit(12);
  117.     return;
  118.  
  119.       case '(':                /* Change character set */
  120.     if (c == '0' || c == '2') a[0] = 1; else a[0] = 0;
  121.     return;
  122.  
  123.       case ')':                /* Change the other character set */
  124.     if (c == '0' || c == '2') a[1] = 1; else a[1] = 0;
  125.     return;
  126.  
  127.       case '=':                /* set keypad application mode */
  128.     p_keyapp = 1;
  129.     redoutil();
  130.     return;
  131.  
  132.       case '>':                /* reset application mode */
  133.     p_keyapp = 0;
  134.     redoutil();
  135.     return;
  136.  
  137.       case 'Z':
  138.     sendchar(27); sendstring("[?1;7c"); return;
  139.  
  140.       /* If we didn't match anything, we can just return, happy in the
  141.      knowledge that we've at least eaten the whole sequence */
  142.  
  143.     }                    /* End of switch */
  144.     return;
  145. }
  146.  
  147. void doctrl(c)
  148. char c;
  149. {
  150.     int        i;
  151.  
  152.     if (c == 27 || c == 24) { inctrl = -1; return; }
  153.     if (c < ' ' || c == 127) return;          /* Ignore control chars */
  154.  
  155.     /* First, look for some parameter characters.  If the very first
  156.     parameter character isn't a digit, then we have a
  157.     private sequence */
  158.  
  159.     if (c >= '0' && c < '@')
  160.     {
  161.     /* can't have parameters after intermediates */
  162.     if (inctrl > 0) {badseq++ ; return; }
  163.     switch (c)
  164.     {
  165.       case '0': case '1': case '2': case '3': case '4':
  166.       case '5': case '6': case '7': case '8': case '9':
  167.         p[numpar] = p[numpar] * 10 + (c - '0');
  168.         return;
  169.  
  170.       case ';':
  171.         p[++numpar] = 0;        /* Start a new parameter */
  172.         return;
  173.  
  174.       case '<': case '=': case '>': case '?': /* Can only mean private */
  175.  
  176.         /* Only allowed BEFORE parameters */
  177.         if (inctrl == 0) private = c;
  178.         return;
  179.  
  180.     /* if we come here, it's a bad sequence */
  181.     }
  182.     badseq++;            /* Flag the bad sequence */
  183.     }
  184.  
  185.     if (c < '0')            /* Intermediate character */
  186.     {
  187.     escseq[inctrl++] = c;        /* Save the intermediate character */
  188.     return;
  189.     }
  190.  
  191.     /* if we get here, we have the final character.  Put it in the
  192.        escape sequence buffer, then dispatch the control sequence */
  193.  
  194.     numpar++;                /* Reflect the real number of parameters */
  195.     escseq[inctrl++] = c;        /* Store the final character */
  196.     escseq[inctrl] = '\000';        /* Tie off the buffer */
  197.     inctrl = -1;            /* End of the control sequence scan */
  198.  
  199.     /* Don't know how to do most private sequences right now,
  200.     so just punt them */
  201.  
  202.     if ((private != 0 && private != '?') || badseq != 0) return;
  203.     if (private == '?' && escseq[0] != 'h' &&
  204.     escseq[0] != 'l') return;
  205.  
  206.     switch (escseq[0])            /* Dispatch on first intermediate or final */
  207.     {
  208.       case 'A': if (p[0]<=0) p[0] = 1;
  209.         y -= Ysize*p[0]; if (y<top)  y = top;  return;
  210.       case 'B': if (p[0]<=0) p[0] = 1;
  211.         y += Ysize*p[0]; if (y>bot)  y = bot;  return;
  212.       case 'C': if (p[0]<=0) p[0] = 1;
  213.         x += Ysize*p[0]; if (x>MAXX) x = MAXX; return;
  214.       case 'D': if (p[0]<=0) p[0] = 1;
  215.         x -= Ysize*p[0]; if (x<MINX) x = MINX; return;
  216.  
  217.       case 'H': case 'f':        /* Cursor position */
  218.     if (p[0] <= 0) p[0] = 1;
  219.     if (p[1] <= 0) p[1] = 1;
  220.     y = (--p[0]*Ysize)+MINY; x = (--p[1]*Xsize)+MINX;
  221.     if (y > MAXY) y = MAXY;
  222.     if (x > MAXX) x = MAXX;
  223.     if (y < MINY) y = MINY;
  224.     if (x < MINX) x = MINX;
  225.     return;
  226.  
  227.       case 'L':                /* ANSI insert line */
  228.       case 'M':                /* ANSI delete line */
  229.     if (p[0] <= 0) p[0] = 1;
  230.     ScrollRaster(mywindow->RPort,
  231.         0L, (long)((escseq[0] == 'M' ? Ysize : -Ysize) * p[0]),
  232.         (long)MINX, (long)(y-BaseLine),
  233.         (long)(MAXX+Xsize-1), (long)bot+Ysize-BaseLine-1 );
  234.     return;
  235.  
  236.       case '@':                /* Insert characters */
  237.       case 'P':                /* Delete characters */
  238.     if (p[0] <= 0) p[0] = 1;
  239.     ScrollRaster(mywindow->RPort, 
  240.            (long) ((escseq[0] == 'P'? Ysize : -Ysize)) * p[0], 0L,
  241.         (long) x, (long)(y - BaseLine),
  242.         (long) MAXX+Xsize-1, (long)(y+Ysize-BaseLine-1) );
  243.     return;
  244.  
  245.       case 'r':                /* Set scroll region */
  246.     if (p[0] <= 0) p[0] = 1;
  247.     if (p[1] <= 0) p[1] = p_lines;
  248.     top = (--p[0]*Ysize)+MINY; bot = (--p[1]*Ysize)+MINY;
  249.     if (top < MINY) top = MINY;
  250.     if (bot > MAXY) bot = MAXY;
  251.     if (top > bot) { top = MINY; bot = MAXY; }
  252.     x = MINX; y = MINY;
  253.     return;
  254.  
  255.       case 'm':                /* Set graphic rendition */
  256.     for (i=0;i<numpar;i++) {
  257.         if (p[i] < 0) p[i] = 0;
  258.         switch (p[i]) {
  259.         case 0:
  260.         curmode  = FS_NORMAL;
  261.         break;
  262.  
  263.         case 1:
  264.         curmode |= FSF_BOLD;
  265.         break;
  266.  
  267.         case 4:
  268.         curmode |= FSF_UNDERLINED;
  269.         break;
  270.  
  271.         case 5:
  272.         curmode |= FSF_ITALIC;
  273.         break;
  274.  
  275.         default:
  276.         curmode |= FSF_REVERSE;
  277.         break;
  278.         }
  279.         }
  280.     return;
  281.  
  282.       case 'K':                /* Erase in line */
  283.     doerase();
  284.     return;
  285.  
  286.       case 'J':                /* Erase in display */
  287.     if (p[0] < 0) p[0] = 0;
  288.     SetAPen(mywindow->RPort,0L);
  289.     if (p[0] == 0) {
  290.         if (y < MAXY) RectFill(mywindow->RPort,
  291.         (long)MINX,(long)(y+(Ysize-BaseLine)),
  292.         (long)(MAXX+Xsize-1),
  293.         (long)(MAXY+(Ysize-BaseLine-1)));
  294.         }
  295.     else if (p[0] == 1) {
  296.         if (y > MINY) RectFill(mywindow->RPort,
  297.         (long)MINX,
  298.         (long)(MINY-BaseLine),
  299.         (long)(MAXX+Xsize-1),
  300.         (long)(y-BaseLine-1));
  301.         }
  302.     else RectFill(mywindow->RPort,
  303.         (long)MINX,
  304.         (long)(MINY-BaseLine),
  305.         (long)(MAXX+Xsize-1),
  306.         (long)(MAXY+(Ysize-BaseLine-1)));
  307.     SetAPen(mywindow->RPort,1L);
  308.     doerase(); return;
  309.  
  310.       case 'h':                /* Set parameter */
  311.     if (private == 0 && p[0] == 20)        nlmode = 1;
  312.     else if (private == '?') {
  313.         if      (p[0] == 7)    p_wrap   = 1;
  314.         else if (p[0] == 1)    p_curapp = 1;
  315.         redoutil();
  316.         }
  317.     return;
  318.  
  319.       case 'l':                /* Reset parameter */
  320.     if (private == 0 && p[0] == 20)        nlmode = 0;
  321.     else if (private == '?') {
  322.         if      (p[0] == 7)    p_wrap   = 0;
  323.         else if (p[0] == 1) p_curapp = 0;
  324.         redoutil();
  325.         }
  326.     return;
  327.  
  328.       case 'x':
  329.     sendchar(27); sendstring("[3;1;8;64;64;1;0x"); return;
  330.  
  331.       case 'n':
  332.     if (p[0] == 6) {
  333.         sendchar(27);
  334.         sprintf(escseq,"[%d;%dR",((y-MINY)/Ysize)+1,((x-MINX)/Xsize)+1);
  335.         sendstring(escseq); return;
  336.         }
  337.     sendchar(27); sendstring("[0n"); return;
  338.  
  339.       case 'c':
  340.     sendchar(27); sendstring("[?1;7c"); return;
  341.     }
  342.  
  343.     /* Don't know how to do this one, so punt it */
  344. }
  345.  
  346. void doindex(c)
  347. char c;
  348.     {
  349.     if (c != 'M') {
  350.     if (c == 'E') x = MINX;
  351.     if (y > bot) if (y < MAXY) y += 8;
  352.     if (y == bot)
  353.         ScrollRaster(mywindow->RPort,
  354.         0L, (long)Ysize,
  355.         (long)MINX, (long)(top-BaseLine),
  356.         (long)(MAXX+Xsize-1), (long)(bot+(Ysize-BaseLine-1)) );
  357.     if (y < bot) y += Ysize;
  358.     }
  359.     else {
  360.     if (y < top) if (y > MINY) y -= BaseLine;
  361.     if (y == top)
  362.         ScrollRaster(mywindow->RPort,0L,
  363.         (long)-Ysize,
  364.         (long)MINX,
  365.         (long)(top-BaseLine),
  366.         (long)(MAXX+Xsize-1),
  367.         (long)(bot+(Ysize-BaseLine-1)));
  368.     if (y > top) y -= Ysize;
  369.     }
  370.     return;
  371.     }
  372.  
  373. static void
  374. doalt(c)
  375. char c;
  376.     {
  377.     int oldx,newx;
  378.     inesc = -1;
  379.     oldx = x; emit(' '); newx = x;
  380.     x = oldx;
  381.     SetAPen(mywindow->RPort,1L);
  382.     switch (c) {
  383.     case 'a':
  384.     doline(0,-BaseLine,Xsize,1);
  385.     break;
  386.  
  387.     case 'j':
  388.     case 'm':
  389.     case 'v':   doline(Xsize/2,-BaseLine,Xsize/2,-(Ysize-BaseLine));
  390.     if      (c=='j')  doline(0,-(Ysize-BaseLine),Xsize/2,-(Ysize-BaseLine));
  391.     else if (c=='m')  doline(Xsize/2,-(Ysize-BaseLine),Xsize,-(Ysize-BaseLine));
  392.     else              doline(0,-(Ysize-BaseLine),Xsize,-(Ysize-BaseLine));
  393.     break;
  394.  
  395.     case 'k':
  396.     case 'l':
  397.     case 'w': doline(Xsize/2,-(Ysize-BaseLine),Xsize/2,1);
  398.     if      (c=='k')  doline(0,-(Ysize-BaseLine),Xsize/2,-(Ysize-BaseLine));
  399.     else if (c=='l')  doline(Xsize/2,-(Ysize-BaseLine),Xsize,-(Ysize-BaseLine));
  400.     else              doline(0,-(Ysize-BaseLine),Xsize,-(Ysize-BaseLine));
  401.     break;
  402.  
  403.     case 'n':
  404.     case 'q': doline(0,-(Ysize-BaseLine),Xsize,-(Ysize-BaseLine));
  405.     if      (c=='n')  doline(Xsize/2,-BaseLine,Xsize/2,Ysize-BaseLine);
  406.     break;
  407.  
  408.     case 't':
  409.     case 'u':
  410.     case 'x':   doline(Xsize/2,-BaseLine,Xsize/2,1);
  411.     if      (c=='t')  doline(Xsize/2,-(Ysize-BaseLine),Xsize,-(Ysize-BaseLine));
  412.     else if (c=='u')  doline(0,-(Ysize-BaseLine),Xsize/2,-(Ysize-BaseLine));
  413.     break;
  414.     }
  415.     x = newx;
  416. }
  417.  
  418. static void
  419. doline(x1,y1,x2,y2) {
  420.     RectFill(mywindow->RPort,(long)(x+x1),(long)(y+y1),
  421.     (long)(x+x2),(long)(y+y2));
  422. }
  423.  
  424. void doerase()
  425.     {
  426.     if (p[0] < 0) p[0] = 0;
  427.     SetAPen(mywindow->RPort,0L);
  428.     if (p[0] == 0) RectFill(mywindow->RPort,
  429.     (long)x,
  430.     (long)(y-BaseLine),
  431.     (long)(MAXX+Xsize-1),
  432.     (long)(y+(Ysize-BaseLine-1)));
  433.     else if (p[0] == 1) RectFill(mywindow->RPort,
  434.     (long)MINX,
  435.     (long)(y-BaseLine),
  436.     (long)(x+Xsize-1),
  437.     (long)(y+(Ysize-BaseLine-1)));
  438.     else RectFill(mywindow->RPort,
  439.     (long)MINX,
  440.     (long)(y-BaseLine),
  441.     (long)(MAXX+Xsize-1),
  442.     (long)(y+(Ysize-BaseLine-1)));
  443.     SetAPen(mywindow->RPort,1L);
  444.     return;
  445.     }
  446.  
  447.