home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / memacs400_src.lzh / MEMACS400 / SRC / xvt.c < prev    next >
Text File  |  1996-04-25  |  16KB  |  718 lines

  1. /*
  2.  *    MicroEMACS 4.00     XVT.C
  3.  *        written by Daniel M. Lawrence
  4.  *
  5.  *    (C)Copyright 1995 by Daniel M. Lawrence
  6.  *    MicroEMACS 4.00 can be copied and distributed freely for any
  7.  *    non-commercial purposes. MicroEMACS 4.00 can only be incorporated
  8.  *    into commercial software with the permission of the current author.
  9.  *
  10.  *    The routines in this file provide support for the XVT windowing system
  11.  *
  12.  *    Notice that the xvt header files force stdlib.h into the compile
  13.  *    even though it conflicts with some of our declarations......
  14.  *    This forced us to use the standard definitions and ditch ours.
  15.  */
  16.  
  17. #define termdef 1            /* don't define term external */
  18. #define XVTDRIVER    1        /* this is the XVT driver */
  19. #define DXVT(a) xvt_dbg(a); xvt_dbg(NULL)
  20.  
  21. #include    <stdio.h>
  22. #include    <stdlib.h>
  23. #include    "estruct.h"
  24. #include    "eproto.h"
  25. #include    "edef.h"
  26. #include    "elang.h"
  27.  
  28. #if    XVT
  29. #undef    COLOR
  30.  
  31. #include    <xvt.h>
  32. #include    <xvtmenu.h>
  33. #include    "uemacs.h"
  34.  
  35. int PASCAL NEAR fnclabel(int f, int n);
  36.  
  37. #define NROW    25            /* Screen size.         */
  38. #define NCOL    80            /* Edit if you want to.     */
  39. #define NPAUSE    100            /* # times thru update to pause */
  40. #define MARGIN    8            /* size of minimim margin and    */
  41. #define SCRSIZ    64            /* scroll size for extended lines */
  42. #define BEL    0x07            /* BEL character.        */
  43. #define ESC    0x1B            /* ESC character.        */
  44.  
  45. /* Forward references.        */
  46. extern int PASCAL NEAR xvtmove();
  47. extern int PASCAL NEAR xvteeol();
  48. extern int PASCAL NEAR xvteeop();
  49. extern int PASCAL NEAR xvtbeep();
  50. extern int PASCAL NEAR xvtopen();
  51. extern int PASCAL NEAR xvtrev();
  52. extern int PASCAL NEAR xvtclose();
  53. extern int PASCAL NEAR xvtkopen();
  54. extern int PASCAL NEAR xvtkclose();
  55. extern int PASCAL NEAR xvtcres();
  56. extern int PASCAL NEAR xvtgetc();
  57. extern int PASCAL NEAR xvtputc();
  58. extern int PASCAL NEAR xvtflush();
  59. extern int PASCAL NEAR xvtfcol();
  60. extern int PASCAL NEAR xvtbcol();
  61. static int rev_state = FALSE;
  62.  
  63. static int cfcolor = -1;    /* current foreground color */
  64. static int cbcolor = -1;    /* current background color */
  65.  
  66. /* mouse status information */
  67. static int oldcol;    /* previous x position of mouse */
  68. static int oldrow;    /* previous y position of mouse */
  69.  
  70. /* Info held for XVT! */
  71.  
  72. #define    MAXOBUF    256    /* maximum number of output characters buffered */
  73.  
  74. WINDOW xvt_win;        /* current window being displayed by XVT */
  75. WINDOW init_win;    /* the initial window we are to toss */
  76. int xvt_char_width;    /* width of characters in pixels */
  77. int xvt_char_height;    /* height of characters in pixels */
  78. int xvt_descent;    /* height of descenders (character offset) */
  79. int xvt_row = 0;    /* current output row in window */
  80. int xvt_col = 0;    /* current column in window */
  81. int xvt_fcolor = COLOR_WHITE;    /* current xvt forground color */
  82. int xvt_bcolor = COLOR_BLACK;    /* current xvt background color */
  83. COLOR xvt_colors[] = {    /* xvt color translation table */
  84.     COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE,
  85.     COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE,
  86.     COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE,
  87.     COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE
  88. };
  89. char xvt_obuf[MAXOBUF];        /* output characters buffer */
  90. char *xvt_next = xvt_obuf;    /* next output character position */
  91. char *xvt_end = &xvt_obuf[MAXOBUF-1];    /* end of the buffer */
  92.  
  93. /*
  94.  * Standard terminal interface dispatch table. Most of the fields point into
  95.  * "termio" code.
  96.  */
  97. NOSHARE TERM term = {
  98.     NROW-1,
  99.     NROW-1,
  100.     NCOL,
  101.     NCOL,
  102.     0, 0,
  103.     MARGIN,
  104.     SCRSIZ,
  105.     NPAUSE,
  106.     xvtopen,
  107.     xvtclose,
  108.     xvtkopen,
  109.     xvtkclose,
  110.     xvtgetc,
  111.     xvtputc,
  112.     xvtflush,
  113.     xvtmove,
  114.     xvteeol,
  115.     xvteeop,
  116.     xvteeop,
  117.     xvtbeep,
  118.     xvtrev,
  119.     xvtcres,
  120.     xvtfcol,
  121.     xvtbcol
  122. };
  123.  
  124. /*    Some XVT specific globals    */
  125.  
  126. int xvt_argc;        /* save the command line arguments to */
  127. char **xvt_argv;    /* pass to the emacs mainline */
  128.  
  129. dump_event(char *typ, EVENT *ep)
  130.  
  131. {
  132.     char m[128];    /* message buffer */
  133.  
  134.     DXVT(typ);
  135.     switch (ep->type) {
  136.         case E_CREATE:
  137.             DXVT("E_CREATE:");
  138.             break;
  139.         case E_FOCUS:
  140.             DXVT("E_FOCUS:");
  141.             break;
  142.         case E_CLOSE:
  143.             DXVT("E_CLOSE:");
  144.             break;
  145.         case E_DESTROY:
  146.             DXVT("E_DESTROY:");
  147.             break;
  148.         case E_UPDATE:
  149.             DXVT("E_UPDATE:");
  150.             break;
  151.         case E_COMMAND:
  152.             DXVT("E_COMMAND:");
  153.             break;
  154.         case E_SIZE:
  155.             DXVT("E_SIZE:");
  156.             break;
  157.         case E_CHAR:
  158.             sprintf(m, "E_CHAR: %d S%d C%d", ep->v.chr.ch,
  159.                 ep->v.chr.shift, ep->v.chr.control);
  160.             DXVT(m);
  161.             break;
  162.         case E_MOUSE_DOWN:
  163.             sprintf(m, "E_MOUSE_DOWN: [%d] %d/%d S%d C%d",
  164.                 ep->v.mouse.button,
  165.                 ep->v.mouse.where.v,ep->v.mouse.where.h,
  166.                 ep->v.mouse.shift, ep->v.mouse.control);
  167.             DXVT(m);
  168.             break;
  169.         case E_MOUSE_UP:
  170.             sprintf(m, "E_MOUSE_UP: [%d] %d/%d S%d C%d",
  171.                 ep->v.mouse.button,
  172.                 ep->v.mouse.where.v,ep->v.mouse.where.h,
  173.                 ep->v.mouse.shift, ep->v.mouse.control);
  174.             DXVT(m);
  175.             break;
  176.         case E_MOUSE_MOVE:
  177.             sprintf(m, "E_MOUSE_MOVE: [%d] %d/%d S%d C%d",
  178.                 ep->v.mouse.button,
  179.                 ep->v.mouse.where.v,ep->v.mouse.where.h,
  180.                 ep->v.mouse.shift, ep->v.mouse.control);
  181.             DXVT(m);
  182.             break;
  183.         default:
  184.             sprintf(m, "E_UNKNOWN: %d", ep->type);
  185.             DXVT(m);
  186.             break;
  187.     }
  188. }
  189.  
  190. static long windowHandler(WINDOW win, EVENT *ep)
  191.  
  192. {
  193.     register int etype;    /* event type byte */
  194.     register int event;    /* encoded mouse event */
  195.     int mouserow, mousecol;    /* mouse row/column position */
  196.  
  197. /*dump_event("win", ep);*/
  198.  
  199.     switch (ep->type) {
  200.         case E_CREATE:
  201.             clear_window(win, COLOR_RED);
  202.  
  203.         case E_CHAR:    /* a character has been typed */
  204.  
  205.             /* if it was a simple one */
  206.             if (ep->v.chr.ch < UCHAR_MAX) {
  207.                 in_put(ep->v.chr.ch);
  208.                 break;
  209.             }
  210.  
  211.             /* otherwise, its a function key! */
  212.             in_fkey(ep->v.chr.ch);
  213.             break;
  214.  
  215.         case E_FOCUS:
  216.             break;
  217.         case E_UPDATE:
  218. /*            sgarbf = TRUE;*/
  219.             break;
  220.  
  221.         case E_MOUSE_MOVE:    /* the mouse has moved */
  222.         case E_MOUSE_DOWN:    /* a button has gone down */
  223.         case E_MOUSE_UP:    /* a button has been released */
  224.  
  225.             /* locate the new charactor position */
  226.             mouserow = ep->v.mouse.where.v / xvt_char_height;
  227.             mousecol = ep->v.mouse.where.h / xvt_char_width;
  228.  
  229.             /* if its in the same character cell... ignore it */
  230.             if ((ep->type == E_MOUSE_MOVE) &&
  231.                 (mouserow == oldrow) && (mousecol == oldcol))
  232.                 return;
  233.  
  234.             /* get the event type */
  235.             etype = MOUS >> 8;
  236.             if (ep->v.mouse.shift == TRUE)
  237.                 etype |= (SHFT >> 8);
  238.             if (ep->v.mouse.control == TRUE)
  239.                 etype |= (CTRL >> 8);
  240.  
  241.             /* no buttons changes */
  242.             if (ep->type == E_MOUSE_MOVE) {
  243.         
  244.                 /* generate a mouse movement */
  245.                 if (((mouse_move == 1) && (mmove_flag == TRUE)) ||
  246.                     (mouse_move == 2)) {
  247.                     in_put(0);
  248.                     in_put(etype);
  249.                     in_put(mousecol);
  250.                     in_put(mouserow);
  251.                     in_put('m');
  252.                 }
  253.  
  254.                 /* save the new mouse location */
  255.                 oldcol = mousecol;
  256.                 oldrow = mouserow;
  257.                 break;
  258.             }
  259.  
  260.  
  261.             /* encode the mouse button press */
  262.             in_put(0);
  263.             in_put(etype);
  264.             in_put(mousecol);
  265.             in_put(mouserow);
  266.             
  267.             /* direction of the button press */
  268.             event = ((ep->type == E_MOUSE_DOWN) ? 0 : 1);
  269.             if (ep->v.mouse.button == 1)    /* right button */
  270.                 event += 4;
  271.             if (ep->v.mouse.button == 2)    /* center button */
  272.                 event += 2;
  273.             event += 'a';
  274.             in_put(event);
  275.  
  276.             /* save the new mouse location */
  277.             oldcol = mousecol;
  278.             oldrow = mouserow;
  279.             break;            
  280.  
  281.         case E_CLOSE:
  282.             xvt_terminate();
  283.     }
  284.     return(0L);
  285. }
  286.  
  287. in_fkey(xvt_code)    /* input an xvt key code into the MicroEMACS
  288.                input stream */
  289.  
  290. int xvt_code;
  291.  
  292. {
  293.     unsigned int code;    /* resulting MicroEMACS extended key code */
  294.  
  295.     switch (xvt_code) {
  296.         case K_F1:     /* function key 1 */
  297.             code = SPEC | '1'; break;
  298.         case K_F2:
  299.             code = SPEC | '2'; break;
  300.         case K_F3:
  301.             code = SPEC | '3'; break;
  302.         case K_F4:
  303.             code = SPEC | '4'; break;
  304.         case K_F5:
  305.             code = SPEC | '5'; break;
  306.         case K_F6:
  307.             code = SPEC | '6'; break;
  308.         case K_F7:
  309.             code = SPEC | '7'; break;
  310.         case K_F8:
  311.             code = SPEC | '8'; break;
  312.         case K_F9:
  313.             code = SPEC | '9'; break;
  314.         case K_F10:
  315.             code = SPEC | '0'; break;
  316.         case K_F11:
  317.             code = SPEC | '-'; break;
  318.         case K_F12:
  319.             code = SPEC | '='; break;
  320. #if    0
  321.         case K_F13:
  322.             code = SPEC | ''; break;
  323.         case K_F14:
  324.             code = SPEC | ''; break;
  325.         case K_F15:    /* function key 15 */
  326.             code = SPEC | ''; break;
  327. #endif
  328.         case K_UP:     /* up arrow */
  329.             code = SPEC | 'P'; break;
  330.         case K_DOWN:   /* down arrow */
  331.             code = SPEC | 'N'; break;
  332.         case K_RIGHT:  /* right arrow */
  333.             code = SPEC | 'F'; break;
  334.         case K_LEFT:   /* left arrow */
  335.             code = SPEC | 'B'; break;
  336.         case K_PREV:   /* previous screen */
  337.             code = SPEC | 'Z'; break;
  338.         case K_NEXT:   /* next screen */
  339.             code = SPEC | 'V'; break;
  340.         case K_LHOME:  /* line home */
  341.             code = SPEC | '<'; break;
  342.         case K_LEND:   /* line end */
  343.             code = SPEC | '>'; break;
  344.         case K_HOME:   /* home */
  345.             code = SPEC | SHFT | 'B'; break;
  346.         case K_END:    /* end */
  347.             code = SPEC | SHFT | 'F'; break;
  348.         case K_INS:    /* insert */
  349.             code = SPEC | 'C'; break;
  350.         case K_WLEFT:  /* word left */
  351.             code = SPEC | CTRL | 'B'; break;
  352.         case K_WRIGHT: /* word right */
  353.             code = SPEC | CTRL | 'F'; break;
  354.         case K_BTAB:   /* back tab */
  355.             code = SPEC | CTRL | 'I'; break;
  356.         case K_HELP:   /* help */
  357.             code = SPEC | CTRL | '>'; break;
  358.         case K_CLEAR:  /* clear */
  359.             code = SPEC | 'k'; break;
  360.     }
  361.  
  362.     /* put the key in the input stream */
  363.     in_put(0);
  364.     in_put(code >> 8);
  365.     in_put(code & 0xFF);
  366.  
  367. }
  368.  
  369. static long taskHandler(WINDOW win, EVENT *ep)
  370. {
  371.     RCT rct;
  372.     char aname[80];     /* application name */
  373.     DRAW_CTOOLS dtool;
  374.     CBRUSH brush;    /* brushed used for the clearing */
  375.     FONT fptr;    /* font to select */
  376.     int leading, ascent, descent;
  377.  
  378.  
  379. /* dump_event("tsk", ep); */
  380.  
  381.     switch (ep->type) {
  382.         case E_CREATE:
  383.  
  384.             /* set the drawing mode to opaque */
  385.             win_get_draw_ctools(win, &dtool);
  386.             dtool.opaque_text = TRUE;
  387.             win_set_draw_ctools(win, &dtool);
  388.         
  389.             /* select an appropriate non-proportional font */
  390.             select_font(FF_FIXED, 0, 10, &fptr);
  391.             win_set_font(win, &fptr, FALSE);
  392.         
  393.             /* set the current brush color! */
  394.             brush.pat = PAT_SOLID;
  395.             brush.color = xvt_colors[cbcolor];
  396.             win_set_cbrush(win, &brush);
  397.         
  398.             /* discover the size of the current font */
  399.             win_get_font_metrics(win, &leading, &ascent, &descent);
  400.             xvt_char_height = leading + ascent + descent;
  401.             xvt_descent = descent;
  402.             xvt_char_width  = win_get_text_width(win, "M", 1);
  403.         
  404.             /* hide the task window... we aren't going to use it */
  405.             show_window(win, FALSE);
  406.  
  407.             /* set up a rect to get an 25 x 80 window */
  408.             set_rect(&rct, xvt_char_width * 1, xvt_char_height * 2,
  409.                  xvt_char_width * 82, xvt_char_height * 27);
  410.             strcpy(aname, PROGNAME);
  411.             strcat(aname, " ");
  412.             strcat(aname, VERSION);
  413.  
  414.             /* create the first screen window */
  415.             xvt_win = create_window(W_DOC, &rct, aname, 0,
  416.                 SCREEN_WIN, WSF_SIZE|WSF_CLOSE|/*WSF_HSCROLL|
  417.                 WSF_VSCROLL|*/WSF_NO_MENUBAR,
  418.                 EM_ALL, windowHandler, 0L);
  419.             called_main(xvt_argc, xvt_argv);
  420.         case E_CLOSE:
  421.             close_window(win);
  422.             break;
  423.     }
  424.     return(0L);
  425. }
  426.  
  427. xvt_main(argc, argv)
  428.  
  429. int argc;
  430. char **argv;
  431.  
  432. {
  433.     XVT_CONFIG config;
  434.     char aname[80];     /* application name */
  435.  
  436.     /* save the command line arguments to pass to emacs */
  437.     xvt_argc = argc;
  438.     xvt_argv = argv;
  439.  
  440.     /* set up the structure to let XVT know how to start */
  441.     config.menu_bar_ID = MAIN_MENUBAR;
  442.     config.about_box_ID = 0;
  443.     config.base_appl_name = "uemacs";
  444.     strcpy(aname, PROGNAME);
  445.     strcat(aname, " ");
  446.     strcat(aname, VERSION);
  447.     config.appl_name = aname;
  448.     config.taskwin_title = aname;
  449.  
  450.     xvt_system(argc, argv, 0L, taskHandler, &config);
  451. }
  452.  
  453. PASCAL NEAR xvtfcol(color)        /* set the current output color */
  454.  
  455. int color;    /* color to set */
  456.  
  457. {
  458.     if (color == cfcolor)
  459.         return;
  460.     xvtflush();
  461.     win_set_fore_color(xvt_win, xvt_colors[color]);
  462.     cfcolor = color;
  463. }
  464.  
  465. PASCAL NEAR xvtbcol(color)        /* set the current background color */
  466.  
  467. int color;    /* color to set */
  468.  
  469. {
  470.     if (color == cbcolor)
  471.         return;
  472.     xvtflush();
  473.     win_set_back_color(xvt_win, xvt_colors[color]);
  474.     cbcolor = color;
  475. }
  476.  
  477. PASCAL NEAR xvtmove(row, col)
  478. {
  479.     xvtflush();
  480.     xvt_row = row;
  481.     xvt_col = col;
  482. }
  483.  
  484. PASCAL NEAR xvteeol()
  485. {
  486.     RCT rect;    /* rectangle to use to clear to end of this line */
  487.     CBRUSH brush;    /* brushed used for the clearing */
  488.  
  489.     xvtflush();
  490.  
  491.     /* set the rectangles limits */
  492.     set_rect(&rect, xvt_col * xvt_char_width,
  493.             xvt_row * xvt_char_height - 1,
  494.             term.t_ncol * xvt_char_width,
  495.             (xvt_row + 1) * xvt_char_height - 1);
  496.  
  497.     /* set the current brush color! */
  498.     brush.pat = PAT_SOLID;
  499.     brush.color = xvt_colors[cbcolor];
  500.     win_set_cbrush(xvt_win, &brush);
  501.     win_set_std_cpen(xvt_win, TL_PEN_HOLLOW);
  502.  
  503.     /* and clear it */
  504.     win_draw_rect(xvt_win, &rect);
  505. }
  506.  
  507. PASCAL NEAR xvteeop()
  508. {
  509.     RCT rect;    /* rectangle to use to clear to end of this line */
  510.     CBRUSH brush;    /* brushed used for the clearing */
  511.  
  512.     xvtflush();
  513.  
  514.     /* set the current brush color! */
  515.     brush.pat = PAT_SOLID;
  516.     brush.color = xvt_colors[gbcolor];
  517.     win_set_cbrush(xvt_win, &brush);
  518.     win_set_std_cpen(xvt_win, TL_PEN_HOLLOW);
  519.  
  520.     /* first erase to the end of this line... */
  521.     /* set the rectangles limits */
  522.     set_rect(&rect, xvt_col * xvt_char_width,
  523.             xvt_row * xvt_char_height - 1,
  524.             term.t_ncol * xvt_char_width,
  525.             (xvt_row + 1) * xvt_char_height + 1);
  526.  
  527.     /* and clear it */
  528.     win_draw_rect(xvt_win, &rect);
  529.  
  530.     /* and then the rest of the window downward */
  531.     /* set the rectangles limits */
  532.     set_rect(&rect, 0,
  533.             (xvt_row + 1) * xvt_char_height - 1,
  534.             term.t_ncol * xvt_char_width,
  535.             term.t_nrow * xvt_char_height);
  536.  
  537.     /* and clear it */
  538.     win_draw_rect(xvt_win, &rect);
  539. }
  540.  
  541. PASCAL NEAR xvtrev(state)        /* change reverse video state */
  542.  
  543. int state;    /* TRUE = reverse, FALSE = normal */
  544.  
  545. {
  546.     int ftmp, btmp;     /* temporaries for colors */
  547.  
  548.     if (state != rev_state) {
  549.         ftmp = cfcolor;
  550.         btmp = cbcolor;
  551.         cfcolor = -1;
  552.         cbcolor = -1;
  553.         xvtfcol(btmp);
  554.         xvtbcol(ftmp);
  555.         rev_state = state;
  556.     }
  557. }
  558.  
  559. PASCAL NEAR xvtcres()    /* change screen resolution */
  560.  
  561. {
  562.     return(TRUE);
  563. }
  564.  
  565. PASCAL NEAR spal(char *dummy)        /* change pallette settings */
  566.  
  567. {
  568.     /* none for now */
  569. }
  570.  
  571. PASCAL NEAR xvtbeep()
  572. {
  573.     xvt_beep();
  574. }
  575.  
  576. PASCAL NEAR xvtopen()
  577.  
  578. {
  579.     DRAW_CTOOLS dtool;
  580.     CBRUSH brush;    /* brushed used for the clearing */
  581.     FONT fptr;    /* font to select */
  582.     int leading, ascent, descent;
  583.  
  584.     /* set the drawing mode to opaque */
  585.     win_get_draw_ctools(xvt_win, &dtool);
  586.     dtool.opaque_text = TRUE;
  587.     win_set_draw_ctools(xvt_win, &dtool);
  588.  
  589.     /* select an appropriate non-proportional font */
  590.     select_font(FF_FIXED, 0, 10, &fptr);
  591.     win_set_font(xvt_win, &fptr, FALSE);
  592.  
  593.     /* set the current brush color! */
  594.     brush.pat = PAT_SOLID;
  595.     brush.color = xvt_colors[cbcolor];
  596.     win_set_cbrush(xvt_win, &brush);
  597.  
  598.     /* discover the size of the current font */
  599.     win_get_font_metrics(xvt_win, &leading, &ascent, &descent);
  600.     xvt_char_height = leading + ascent + descent;
  601.     xvt_descent = descent;
  602.     xvt_char_width  = win_get_text_width(xvt_win, "M", 1);
  603.  
  604.     /* initialize the mouse status */
  605.     oldcol = -1;
  606.     oldrow = -1;
  607.  
  608.     /* initialize the output character queue */
  609.     xvt_next = xvt_obuf;
  610.  
  611.     /* let emacs know the screen is open */
  612.     strcpy(sres, "XVT");
  613.     revexist = TRUE;
  614.     ttopen();
  615. }
  616.  
  617. PASCAL NEAR xvtclose()
  618.  
  619. {
  620.     xvtfcol(7);
  621.     xvtbcol(0);
  622.     ttclose();
  623. }
  624.  
  625. PASCAL NEAR xvtkopen()    /* open the keyboard (a noop here) */
  626.  
  627. {
  628.  
  629. }
  630.  
  631. PASCAL NEAR xvtkclose() /* close the keyboard (a noop here) */
  632.  
  633. {
  634.     xvtflush();
  635. }
  636.  
  637. /*
  638.  * Read a character from the terminal, performing no editing and doing no echo
  639.  * at all. Also mouse events are forced into the input stream here.
  640.  */
  641. int PASCAL NEAR xvtgetc()
  642.  
  643. {
  644.     xvtflush();
  645.  
  646.     /* try first.... */
  647.     if (in_check())
  648.         return(in_get());
  649.  
  650.     /* turn on the text cursor! */
  651.     caret_on(xvt_win, xvt_col * xvt_char_width, (xvt_row + 1) * xvt_char_height - 1);
  652.  
  653.     /* loop waiting for something to happen */
  654.     while (TRUE) {
  655.         process_events();
  656.         if (in_check()) {
  657.             /* turn off the text cursor */
  658.             caret_off(xvt_win);
  659.  
  660.             /* and return the event */
  661.             return(in_get());
  662.         }
  663.     }
  664. }
  665.  
  666. int PASCAL NEAR xvtflush()
  667.  
  668. {
  669.     /* if there's nothing to flush */
  670.     if (xvt_next == xvt_obuf)
  671.         return;
  672.  
  673.     /* draw the characters out */
  674.     win_draw_text(xvt_win, xvt_col * xvt_char_width,
  675.             (xvt_row + 1) * xvt_char_height - 1 - xvt_descent,
  676.             &xvt_obuf[0], (xvt_next - xvt_obuf));
  677.  
  678.     xvt_col += (xvt_next - xvt_obuf);
  679.     xvt_next = xvt_obuf;
  680. }
  681.  
  682. int PASCAL NEAR xvtputc(c)
  683.  
  684. char c;    /* character to write to the current xvt window */
  685.  
  686. {
  687.     /* backspaces just backup the pointers */
  688.     if (c == '\b') {
  689.         xvtflush();
  690.         xvt_col--;
  691.         if (xvt_col < 0)
  692.             xvt_col = 0;
  693.         return;
  694.     }
  695.  
  696.     /* don't go too far! */
  697.     if (xvt_next == xvt_end)
  698.         xvtflush();
  699.  
  700.     *xvt_next++ = c;
  701. }
  702.  
  703. #if    FLABEL
  704. int PASCAL NEAR fnclabel(f, n)        /* label a function key */
  705.  
  706. int f,n;    /* default flag, numeric argument [unused] */
  707.  
  708. {
  709.     /* on machines with no function keys...don't bother */
  710.     return(TRUE);
  711. }
  712. #endif
  713. #else
  714. xvthello()
  715. {
  716. }
  717. #endif
  718.