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 / ntconio.c < prev    next >
Text File  |  1996-04-25  |  19KB  |  777 lines

  1. /*      NTCONIO.C       Operating specific video & keyboard functions
  2.  *                      for the Window NT operating system (console mode)
  3.  *                      for MicroEMACS 4.00
  4.  *                      (C)Copyright 1995 by Daniel M. Lawrence
  5.  *                      Windows NT version by Walter Warniaha
  6.  *
  7.  * The routines in this file provide video and keyboard support using the
  8.  * Windows NT console functions.
  9.  *
  10.  */
  11.  
  12. #define termdef 1                       /* don't define "term" external */
  13.  
  14. #undef  PASCAL
  15. #undef  NEAR
  16. #undef  HIBYTE
  17.  
  18. #include        "estruct.h"
  19. #include        "eproto.h"
  20. #include        "edef.h"
  21. #include        "elang.h"
  22.  
  23. #if     NTCON
  24. #define NROW    80              /* Screen size.                 */
  25. #define NCOL    132             /* Edit if you want to.         */
  26. #define MARGIN  8               /* size of minimim margin and   */
  27. #define SCRSIZ  64              /* scroll size for extended lines */
  28. #define NPAUSE  5               /* # times thru update to pause */
  29.  
  30. /* Forward references.          */
  31.  
  32. PASCAL NEAR ntmove();
  33. PASCAL NEAR nteeol();
  34. PASCAL NEAR nteeop();
  35. PASCAL NEAR ntbeep();
  36. PASCAL NEAR ntopen();
  37. PASCAL NEAR ntclose();
  38. PASCAL NEAR ntgetc();
  39. PASCAL NEAR ntputc();
  40. PASCAL NEAR ntflush();
  41. PASCAL NEAR ntrev();
  42. PASCAL NEAR ntkclose();
  43. PASCAL NEAR ntkopen();
  44. PASCAL NEAR ntcres();
  45. PASCAL NEAR ntparm();
  46. #if     COLOR
  47. PASCAL NEAR ntfcol();
  48. PASCAL NEAR ntbcol();
  49. #endif
  50. PASCAL NEAR fnclabel();
  51. static WORD near ntAttribute(void);
  52.  
  53. /* Screen buffer to write to. */
  54. static CHAR_INFO ciScreenBuffer[NROW * NCOL];
  55. static int      cfcolor = 0;    /* current foreground color     */
  56. static int      cbcolor = 15;   /* current background color     */
  57. static int      ctrans[] =      /* ansi to ibm color translation table  */
  58.         { 0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15 };
  59.  
  60. static WORD ntrow = 0;         /* current cursor row   */
  61. static WORD ntcol = 0;         /* current cursor col   */
  62. static WORD ntMax = 0;
  63. static WORD ntMin = (WORD)-1;
  64. static WORD ntColMax = 0;
  65. static WORD ntColMin = (WORD)-1;
  66.  
  67. int revflag = FALSE;                    /* are we currently in rev video? */
  68.  
  69. /* Windows NT Console screen buffer handle.  All I/O is done through this
  70.  * handle.
  71.  */
  72. static HANDLE hInput, hOutput;
  73. static char chConsoleTitle[256];    // Preserve the title of the console.
  74. static long ConsoleMode, OldConsoleMode;
  75.  
  76. static INPUT_RECORD ir;
  77. static WORD wKeyEvent;
  78.  
  79. /*
  80.  * Standard terminal interface dispatch table.
  81.  */
  82. TERM    term    = {
  83.         NROW-1,
  84.         NROW-1,
  85.         NCOL,
  86.         NCOL,
  87.         0, 0,
  88.         MARGIN,
  89.         SCRSIZ,
  90.         NPAUSE,
  91.         ntopen,
  92.         ntclose,
  93.         ntkopen,
  94.         ntkclose,
  95.         ntgetc,
  96.         ntputc,
  97.         ntflush,
  98.         ntmove,
  99.         nteeol,
  100.         nteeop,
  101.         nteeop,
  102.         ntbeep,
  103.         ntrev,
  104.         ntcres
  105. #if     COLOR
  106.         , ntfcol,
  107.         ntbcol
  108. #endif
  109. };
  110.  
  111. /*    Mousing global variable    */
  112. static int mexist;    /* is the mouse driver installed? */
  113. static int nbuttons;    /* number of buttons on the mouse */
  114. static int oldbut;    /* Previous state of mouse buttons */
  115. static int oldcol;    /* previous x position of mouse */
  116. static int oldrow;    /* previous y position of mouse */
  117.  
  118. /*    input buffers and pointers    */
  119.  
  120. #define    IBUFSIZE    64    /* this must be a power of 2 */
  121.  
  122. unsigned char in_buf[IBUFSIZE];    /* input character buffer */
  123. int in_next = 0;        /* pos to retrieve next input character */
  124. int in_last = 0;        /* pos to place most recent input character */
  125.  
  126. void in_init()    /* initialize the input buffer */
  127.  
  128. {
  129.     in_next = in_last = 0;
  130. }
  131.  
  132. int in_check()    /* is the input buffer non-empty? */
  133.  
  134. {
  135.     if (in_next == in_last)
  136.         return(FALSE);
  137.     else
  138.         return(TRUE);
  139. }
  140.  
  141. void in_put(event)
  142.  
  143. int event;    /* event to enter into the input buffer */
  144.  
  145. {
  146.     in_buf[in_last++] = event;
  147.     in_last &= (IBUFSIZE - 1);
  148. }
  149.  
  150. int in_get()    /* get an event from the input buffer */
  151.  
  152. {
  153.     register int event;    /* event to return */
  154.  
  155.     event = in_buf[in_next++];
  156.     in_next &= (IBUFSIZE - 1);
  157.     return(event);
  158. }
  159.  
  160. #if COLOR
  161. /*----------------------------------------------------------------------*/
  162. /*    ntfcol()                            */
  163. /* Set the current foreground color.                    */
  164. /*----------------------------------------------------------------------*/
  165.  
  166. PASCAL NEAR ntfcol(
  167.     int color)            /* color to set */
  168. {
  169.     cfcolor = ctrans[color];
  170. }
  171.  
  172. /*----------------------------------------------------------------------*/
  173. /*    ntbcol()                            */
  174. /* Set the current background color.                    */
  175. /*----------------------------------------------------------------------*/
  176.  
  177. PASCAL NEAR ntbcol(
  178.     int color)        /* color to set */
  179. {
  180.     cbcolor = ctrans[color];
  181. }
  182. #endif
  183.  
  184. static void near ntSetUpdateValues(void)
  185. {
  186.     if (ntrow < ntMin)
  187.         ntMin = ntrow;
  188.     if (ntrow > ntMax)
  189.         ntMax = ntrow;
  190.     if (ntMax == ntMin) {
  191.         if (ntcol < ntColMin)
  192.             ntColMin = ntcol;
  193.         if (ntcol > ntColMax)
  194.             ntColMax = ntcol;
  195.     }
  196. }
  197.  
  198. /*----------------------------------------------------------------------*/
  199. /*    ntmove()                            */
  200. /* Move the cursor.                         */
  201. /*----------------------------------------------------------------------*/
  202.  
  203. PASCAL NEAR ntmove(
  204.     int row,
  205.     int col)
  206. {
  207.     COORD dwCursorPosition;
  208.  
  209.     ntcol = dwCursorPosition.X = col;
  210.     ntrow = dwCursorPosition.Y = row;
  211.     SetConsoleCursorPosition(hOutput, dwCursorPosition);
  212. }
  213.  
  214.  
  215. /*----------------------------------------------------------------------*/
  216. /*    ntflush()                            */
  217. /* Update the physical video buffer from the logical video buffer.    */
  218. /*----------------------------------------------------------------------*/
  219.  
  220. PASCAL NEAR ntflush(void)
  221. {
  222.     SMALL_RECT srWriteRegion;
  223.     COORD coordUpdateBegin, coordBufferSize;
  224.  
  225.     if (ntMin <= ntMax) {
  226.  
  227.         if (ntMin == ntMax) {
  228.  
  229.             /* Fri Feb 14 1992 WaltW - Same fuckin' line bud. */
  230.             srWriteRegion.Right = ntColMax;
  231.             srWriteRegion.Left = 0; //ntColMin;
  232.  
  233.             coordUpdateBegin.X = 0; //ntColMin;
  234.             coordUpdateBegin.Y = ntMin;
  235.         } else {
  236.             srWriteRegion.Right = term.t_ncol - 1;
  237.             srWriteRegion.Left = 0;
  238.  
  239.             coordUpdateBegin.X = 0;
  240.             coordUpdateBegin.Y = ntMin;
  241.         }
  242.  
  243.         srWriteRegion.Bottom = ntMax;
  244.         srWriteRegion.Top = ntMin;
  245.  
  246.         coordBufferSize.X = term.t_ncol;
  247.         coordBufferSize.Y = term.t_nrow + 1;
  248.  
  249.         WriteConsoleOutput(hOutput, (PCHAR_INFO)ciScreenBuffer,
  250.             coordBufferSize, coordUpdateBegin, &srWriteRegion);
  251.         ntColMax = ntMax = 0;
  252.         ntColMin = ntMin = (WORD) -1;
  253.     }
  254.     ntmove(ttrow, ttcol);
  255.     return(TRUE);
  256. }
  257.  
  258. static void near MouseEvent(void)
  259.  
  260. {
  261.     MOUSE_EVENT_RECORD *m_event;    /* mouse event to decode */
  262.     register int k;        /* current bit/button of mouse */
  263.     register int event;    /* encoded mouse event */
  264.     register int etype;    /* event type byte */
  265.     int mousecol;        /* current mouse column */
  266.     int mouserow;        /* current mouse row */
  267.     int sstate;        /* current shift key status */
  268.     int newbut;        /* new state of the mouse buttons */
  269.  
  270.     m_event = &(ir.Event.MouseEvent);
  271.  
  272.     /* check to see if any mouse buttons are different */
  273.     newbut = m_event->dwButtonState;
  274.     mousecol = m_event->dwMousePosition.X;
  275.     mouserow = m_event->dwMousePosition.Y;
  276.  
  277.     /* only notice changes */
  278.     if ((oldbut == newbut) && (mousecol == oldcol)
  279.         && (mouserow == oldrow))
  280.         return(FALSE);
  281.  
  282. #if    0
  283.     printf("<%d,%d> B%d C%d F%d O%d N%d\n", m_event->dwMousePosition.Y,
  284.         m_event->dwMousePosition.Y, m_event->dwButtonState,
  285.         m_event->dwControlKeyState, m_event->dwEventFlags,
  286.         oldbut, newbut);
  287. #endif
  288.  
  289.     /* get the shift key status as well */
  290.     etype = MOUS >> 8;
  291.     sstate = m_event->dwControlKeyState;
  292.     if (sstate & SHIFT_PRESSED)        /* shifted? */
  293.         etype |= (SHFT >> 8);
  294.     if ((sstate & RIGHT_CTRL_PRESSED) ||
  295.         (sstate & LEFT_CTRL_PRESSED))    /* controled? */
  296.         etype |= (CTRL >> 8);
  297.  
  298.     /* no buttons changes */
  299.     if (oldbut == newbut) {
  300.  
  301.         /* generate a mouse movement */
  302.         if (((mouse_move == 1) && (mmove_flag == TRUE)) ||
  303.             (mouse_move == 2)) {
  304.             in_put(0);
  305.             in_put(etype);
  306.             in_put(mousecol);
  307.             in_put(mouserow);
  308.             in_put('m');
  309.         }
  310.         oldcol = mousecol;
  311.         oldrow = mouserow;
  312.         return(TRUE);
  313.     }
  314.  
  315.     for (k=1; k != (1 << nbuttons); k = k<<1) {
  316.  
  317.         /* For each button on the mouse */
  318.         if ((oldbut&k) != (newbut&k)) {
  319.             /* This button changed, generate an event */
  320.             in_put(0);
  321.             in_put(etype);
  322.             in_put(mousecol);
  323.             in_put(mouserow);
  324.  
  325.             event = ((newbut&k) ? 0 : 1);    /* up or down? */
  326.             if (k == 2)            /* center button? */
  327.                 event += 4;
  328.             if (k == 4)            /* right button? */
  329.                 event += 2;
  330.             event += 'a';
  331.             in_put(event);
  332.             oldbut = newbut;
  333.             oldcol = mousecol;
  334.             oldrow = mouserow;
  335.             return(TRUE);
  336.         }
  337.     }
  338.     return(FALSE);
  339. }
  340.  
  341. static void near WindowSizeEvent(void)
  342. {
  343.     term.t_nrow = ir.Event.WindowBufferSizeEvent.dwSize.Y - 1;
  344.     term.t_ncol = ir.Event.WindowBufferSizeEvent.dwSize.X;
  345.     ntflush();
  346.     SetConsoleTitle("WindowSizeEvent");
  347. }
  348.  
  349. /* handle the current keyboard event */
  350.  
  351. static void near KeyboardEvent()
  352.  
  353. {
  354.     int c;        /* ascii character to examine */
  355.     int vscan;    /* virtual scan code */
  356.     int prefix;    /* character prefix */
  357.     int state;    /* control key state from console device */
  358.  
  359.     /* ignore key up events */
  360.     if (ir.Event.KeyEvent.bKeyDown == FALSE)
  361.         return(FALSE);
  362.  
  363.     /* If this is an extended character, process it */
  364.     c = ir.Event.KeyEvent.uChar.AsciiChar;
  365.     state = ir.Event.KeyEvent.dwControlKeyState;
  366.     prefix = 0;
  367.  
  368.     if (c == 0) {
  369.  
  370.         /* grab the virtual scan code */
  371.         vscan = ir.Event.KeyEvent.wVirtualScanCode;
  372.  
  373.         /* function keys are special! */
  374.         if (vscan > 58 && vscan < 68) {
  375.             c = '1' + vscan - 59;
  376.             prefix = SPEC;
  377.             goto pastothers;
  378.         }
  379.  
  380.         /* interpret code by keyscan */
  381.         switch (vscan) {
  382.  
  383.             /* ignore these key down events */
  384.             case 29:    /* control */
  385.             case 42:    /* left shift */
  386.             case 54:    /* left shift */
  387.             case 56:    /* ALT key */
  388.                 return;
  389.  
  390.             case 68:    /* F10 */
  391.                 prefix = SPEC; c = '0'; break;
  392.  
  393.             case 69:    /* PAUSE */
  394.                 prefix = SPEC; c = ':'; break;
  395.  
  396.             case 70:    /* SCROLL LOCK */
  397.                 return;
  398.  
  399.             case 71:    /* HOME */
  400.                 prefix = SPEC; c = '<'; break;
  401.  
  402.             case 72:    /* Cursor Up */
  403.                 prefix = SPEC; c = 'P'; break;
  404.  
  405.             case 73:    /* Page Up */
  406.                 prefix = SPEC; c = 'Z'; break;
  407.  
  408.             case 75:    /* Cursor left */
  409.                 prefix = SPEC; c = 'B'; break;
  410.  
  411.             case 76:    /* keypad 5 */
  412.                 prefix = SPEC; c = 'L'; break;
  413.  
  414.             case 77:    /* Cursor Right */
  415.                 prefix = SPEC; c = 'F'; break;
  416.  
  417.             case 79:    /* END */
  418.                 prefix = SPEC; c = '>'; break;
  419.  
  420.             case 80:    /* Cursor Down */
  421.                 prefix = SPEC; c = 'N'; break;
  422.  
  423.             case 81:    /* Page Down */
  424.                 prefix = SPEC; c = 'V'; break;
  425.  
  426.             case 82:    /* insert key */
  427.                 prefix = SPEC; c = 'C'; break;
  428.  
  429.             case 83:    /* delete key */
  430.                 prefix = SPEC; c = 'D'; break;
  431.  
  432.             case 87:    /* F11 */
  433.                 prefix = SPEC; c = '-'; break;
  434.  
  435.             case 88:    /* F12 */
  436.                 prefix = SPEC; c = '='; break;
  437.  
  438.             default:
  439.                 printf("<%d:%d/%d> ", ir.EventType,
  440.                     ir.Event.KeyEvent.uChar.AsciiChar,
  441.                       ir.Event.KeyEvent.wVirtualScanCode);
  442.                 return;
  443.         }
  444.  
  445. pastothers:    /* shifted special key? */
  446.         if (state & SHIFT_PRESSED)
  447.             prefix |= SHFT;
  448.     }
  449.  
  450.     /* decode the various modifiers to the character */
  451.     if (state & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
  452.         prefix |= ALTD;
  453.     if ((state & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) && c > 31)
  454.         prefix |= CTRL;
  455.  
  456.     /* if there is a prefix, insert it in the input stream */
  457.     if (prefix != 0) {
  458.         in_put(0);
  459.         in_put(prefix >> 8);
  460.     }
  461.  
  462.     /* place the ascii character in the input queue */
  463.     in_put(c);
  464.     return;
  465.  
  466. }
  467.  
  468. /*----------------------------------------------------------------------*/
  469. /*    ntgetc()                            */
  470. /* Get a character from the keyboard.                    */
  471. /*----------------------------------------------------------------------*/
  472.  
  473. PASCAL NEAR ntgetc()
  474. {
  475.  
  476.     long dw;
  477.  
  478. ttc:    ntflush();
  479.  
  480.     /* return any keystrokes waiting in the
  481.        type ahead buffer */
  482.     if (in_check())
  483.         return(in_get());
  484.  
  485.     /* get the next keyboard/mouse/resize event */
  486.     ReadConsoleInput(hInput, &ir, 1, &dw);
  487.  
  488.     /* let the proper event handler field this event */
  489.     switch (ir.EventType) {
  490.  
  491.         case KEY_EVENT:
  492.             KeyboardEvent();
  493.             goto ttc;
  494.  
  495.         case MOUSE_EVENT:
  496.             MouseEvent();
  497.             goto ttc;
  498.  
  499.         case WINDOW_BUFFER_SIZE_EVENT:
  500.             WindowSizeEvent();
  501.             goto ttc;
  502.     }
  503.  
  504.     /* we should never arrive here, ignore this event */
  505.     goto ttc;
  506. }
  507.  
  508. #if TYPEAH
  509. /*----------------------------------------------------------------------*/
  510. /*    typahead()                            */
  511. /* Returns true if a key has been pressed.                */
  512. /*----------------------------------------------------------------------*/
  513.  
  514. PASCAL NEAR typahead()
  515.  
  516. {
  517.     DWORD dwCount;        /* number of pending keyboard events */
  518.  
  519. return(FALSE); /* temp KLUGE */
  520.     /* anything waiting in the input queue? */
  521.     if (in_check())
  522.         return(TRUE);
  523.  
  524.     /* leek ahead to see if there are any keyboard/mouse events ready */
  525.     if (PeekConsoleInput(hInput, &ir, 1, &dwCount) == FALSE)
  526.         return(FALSE);
  527.  
  528.     return(dwCount ? TRUE : FALSE);
  529. }
  530. #endif
  531.  
  532. static WORD near ntAttribute(void)
  533. {
  534.     return(revflag ? (cbcolor | (cfcolor << 4)) : ((cbcolor << 4) | cfcolor));
  535. }
  536.  
  537. /*----------------------------------------------------------------------*/
  538. /*    ntputc()                            */
  539. /* Put a character at the current position in the current colors.    */
  540. /* Note that this does not behave the same as putc() or VioWrtTTy().    */
  541. /* This routine does nothing with returns and linefeeds.  For backspace */
  542. /* it puts a space in the previous column and moves the cursor to the    */
  543. /* previous column.  For all other characters, it will display the    */
  544. /* graphic representation of the character and put the cursor in the    */
  545. /* next column (even if that is off the screen.  In practice this isn't */
  546. /* a problem.                                */
  547. /*----------------------------------------------------------------------*/
  548.  
  549. PASCAL NEAR ntputc(int c)
  550. {
  551.     WORD wScreenPos;
  552.  
  553.     if (c == '\n' || c == '\r') {         /* returns and linefeeds */
  554.         ntrow++;
  555.         ntcol = 0;
  556.         return;
  557.     }
  558.  
  559.     if (c == '\b') {            /* backspace */
  560.         --ntcol;
  561.         ntputc(' ');
  562.         --ntcol;
  563.         return;
  564.     }
  565.  
  566.     wScreenPos = (ntrow * term.t_ncol) + ntcol++;
  567.     ciScreenBuffer[wScreenPos].Char.AsciiChar = c;
  568.     ciScreenBuffer[wScreenPos].Attributes = ntAttribute();
  569.     ntSetUpdateValues();
  570. }
  571.  
  572.  
  573. /*----------------------------------------------------------------------*/
  574. /*    nteeol()                            */
  575. /* Erase to end of line.                        */
  576. /*----------------------------------------------------------------------*/
  577.  
  578. PASCAL NEAR nteeol()
  579. {
  580.     WORD wNum;
  581.     WORD wScreenPos;
  582.     WORD wAttribute;
  583.  
  584.     wNum = term.t_ncol - ntcol;
  585.     wScreenPos = ntrow * term.t_ncol + ntcol;
  586.     wAttribute = ntAttribute();
  587.     for (; wNum; wNum--) {
  588.         ciScreenBuffer[wScreenPos].Char.AsciiChar = ' ';
  589.         ciScreenBuffer[wScreenPos].Attributes = wAttribute;
  590.         wScreenPos++, ntcol++;
  591.     }
  592.     ntSetUpdateValues();
  593. }
  594.  
  595.  
  596. /*----------------------------------------------------------------------*/
  597. /*    nteeop()                            */
  598. /* Erase to end of page.                        */
  599. /*----------------------------------------------------------------------*/
  600.  
  601. PASCAL NEAR nteeop()
  602. {
  603.     WORD wNum;
  604.     WORD wScreenPos;
  605.     WORD wAttribute;
  606.  
  607.     wNum = (term.t_ncol - ntcol) + ((term.t_ncol * term.t_nrow) - ntrow);
  608.     wScreenPos = ntrow * term.t_ncol + ntcol;
  609.     wAttribute = ntAttribute();
  610.     for (; wNum; wNum--) {
  611.         ciScreenBuffer[wScreenPos].Char.AsciiChar = ' ';
  612.         ciScreenBuffer[wScreenPos].Attributes = wAttribute;
  613.         wScreenPos++, ntcol++;
  614.     }
  615.     ntSetUpdateValues();
  616. }
  617.  
  618. /*----------------------------------------------------------------------*/
  619. /*    ntrev()                         */
  620. /* Change reverse video state.                        */
  621. /*----------------------------------------------------------------------*/
  622.  
  623. PASCAL NEAR ntrev(state)
  624.  
  625. int state;    /* TRUE = reverse, FALSE = normal */
  626.  
  627. {
  628.     revflag = state;
  629. }
  630.  
  631. /*----------------------------------------------------------------------*/
  632. /*    ntcres()                            */
  633. /* Change the screen resolution.                    */
  634. /*----------------------------------------------------------------------*/
  635.  
  636. PASCAL NEAR ntcres(char *res)        /* name of desired video mode    */
  637. {
  638.     return TRUE;
  639. }
  640.  
  641.  
  642. /*----------------------------------------------------------------------*/
  643. /*    spal()                                */
  644. /* Change pallette settings.  (Does nothing.)                */
  645. /*----------------------------------------------------------------------*/
  646.  
  647. PASCAL NEAR spal(char *dummy)
  648. {
  649.     return(TRUE);
  650. }
  651.  
  652.  
  653. /*----------------------------------------------------------------------*/
  654. /*    ntbeep()                            */
  655. /*----------------------------------------------------------------------*/
  656.  
  657. PASCAL NEAR ntbeep()
  658. {
  659. //      _beep(1200, 80);
  660.     return(TRUE);
  661. }
  662.  
  663. /*----------------------------------------------------------------------*/
  664. /*    ntopen()                            */
  665. /*----------------------------------------------------------------------*/
  666.  
  667. PASCAL NEAR ntopen()
  668. {
  669.     CONSOLE_SCREEN_BUFFER_INFO Console;
  670.  
  671.     /* initialize the input queue */
  672.     in_init();
  673.     strcpy(os, "WINNT");
  674.  
  675.     /* This will allocate a console if started from
  676.      * the windows NT program manager. */
  677.     AllocConsole();
  678.  
  679.     /* Save the titlebar of the window so we can
  680.      * restore it when we leave. */
  681.     GetConsoleTitle(chConsoleTitle, sizeof(chConsoleTitle));
  682.  
  683.     /* Set Window Title to MicroEMACS */
  684.     SetConsoleTitle(PROGNAME);
  685.  
  686.     /* Get our standard handles */
  687.     hInput = GetStdHandle(STD_INPUT_HANDLE);
  688.     hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  689.  
  690.     /* get a ptr to the output screen buffer */
  691.     GetConsoleScreenBufferInfo(hOutput, &Console);
  692.     SetConsoleMode(hInput, ENABLE_WINDOW_INPUT);
  693.  
  694.     /* let MicroEMACS know our starting screen size */
  695.     term.t_nrow = Console.dwSize.Y - 1;
  696.     term.t_ncol = Console.dwSize.X;
  697.  
  698.     ntColMin = ntMin = (WORD)-1;
  699.     ntColMax = ntMax = 0;
  700.  
  701.     /* we always have a mouse under NT */
  702.     mexist = GetNumberOfConsoleMouseButtons(&nbuttons);
  703.     oldcol = -1;
  704.     oldrow = -1;
  705.     oldbut = 0;
  706.  
  707.     /* initialize some attributes about the output screen */
  708.     revexist = TRUE;
  709.     revflag = FALSE;
  710.     eolexist = TRUE;
  711.     gfcolor = 15;
  712.     gbcolor = 0;
  713.     cfcolor = 7;
  714.     cbcolor = 0;
  715.  
  716.     return(TRUE);
  717. }
  718.  
  719. /*----------------------------------------------------------------------*/
  720. /*    ntclose()                            */
  721. /* Restore the original video settings.                 */
  722. /*----------------------------------------------------------------------*/
  723.  
  724. PASCAL NEAR ntclose()
  725. {
  726.     /* reset the title on the window */
  727.     SetConsoleTitle(chConsoleTitle);
  728.  
  729.     FreeConsole();
  730.     return(TRUE);
  731. }
  732.  
  733. /*----------------------------------------------------------------------*/
  734. /*    ntkopen()                            */
  735. /* Open the keyboard.                            */
  736. /*----------------------------------------------------------------------*/
  737.  
  738. PASCAL NEAR ntkopen()
  739. {
  740.     /* save the original console mode to restore on exit */
  741.     GetConsoleMode(hInput, &OldConsoleMode);
  742.  
  743.     /* and reset this to what MicroEMACS needs */
  744.     ConsoleMode = OldConsoleMode;
  745.     ConsoleMode &= ~(ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
  746.         ENABLE_ECHO_INPUT | ENABLE_WINDOW_INPUT);
  747.     ConsoleMode |= ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
  748.     SetConsoleMode(hInput, ConsoleMode);
  749.  
  750.     return(TRUE);
  751. }
  752.  
  753.  
  754. /*----------------------------------------------------------------------*/
  755. /*    ntkclose()                            */
  756. /* Close the keyboard.                            */
  757. /*----------------------------------------------------------------------*/
  758.  
  759. PASCAL NEAR ntkclose()
  760. {
  761.     /* restore the console mode from entry */
  762.     SetConsoleMode(hInput, OldConsoleMode);
  763.     return(TRUE);
  764. }
  765.  
  766. #if FLABEL
  767. PASCAL NEAR fnclabel(f, n)    /* label a function key */
  768.  
  769. int f,n;    /* default flag, numeric argument [unused] */
  770.  
  771. {
  772.     /* on machines with no function keys...don't bother */
  773.     return(TRUE);
  774. }
  775. #endif
  776. #endif
  777.