home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / ue312os2.zip / src / ntconio.c < prev    next >
C/C++ Source or Header  |  1994-08-26  |  20KB  |  761 lines

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