Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // conproc.c
  21.  
  22. #include <windows.h>
  23. #include "conproc.h"
  24. #include "quakedef.h"
  25.  
  26. HANDLE  heventDone;
  27. HANDLE  hfileBuffer;
  28. HANDLE  heventChildSend;
  29. HANDLE  heventParentSend;
  30. HANDLE  hStdout;
  31. HANDLE  hStdin;
  32.  
  33. DWORD RequestProc (DWORD dwNichts);
  34. LPVOID GetMappedBuffer (HANDLE hfileBuffer);
  35. void ReleaseMappedBuffer (LPVOID pBuffer);
  36. BOOL GetScreenBufferLines (int *piLines);
  37. BOOL SetScreenBufferLines (int iLines);
  38. BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine);
  39. BOOL WriteText (LPCTSTR szText);
  40. int CharToCode (char c);
  41. BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy);
  42.  
  43.  
  44. void InitConProc (HANDLE hFile, HANDLE heventParent, HANDLE heventChild)
  45. {
  46.         DWORD   dwID;
  47.         CONSOLE_SCREEN_BUFFER_INFO      info;
  48.         int             wheight, wwidth;
  49.  
  50. // ignore if we don't have all the events.
  51.         if (!hFile || !heventParent || !heventChild)
  52.                 return;
  53.  
  54.         hfileBuffer = hFile;
  55.         heventParentSend = heventParent;
  56.         heventChildSend = heventChild;
  57.  
  58. // so we'll know when to go away.
  59.         heventDone = CreateEvent (NULL, FALSE, FALSE, NULL);
  60.  
  61.         if (!heventDone)
  62.         {
  63.                 Con_SafePrintf ("Couldn't create heventDone\n");
  64.                 return;
  65.         }
  66.  
  67.         if (!CreateThread (NULL,
  68.                                            0,
  69.                                            (LPTHREAD_START_ROUTINE) RequestProc,
  70.                                            0,
  71.                                            0,
  72.                                            &dwID))
  73.         {
  74.                 CloseHandle (heventDone);
  75.                 Con_SafePrintf ("Couldn't create QHOST thread\n");
  76.                 return;
  77.         }
  78.  
  79. // save off the input/output handles.
  80.         hStdout = GetStdHandle (STD_OUTPUT_HANDLE);
  81.         hStdin = GetStdHandle (STD_INPUT_HANDLE);
  82.  
  83. // force 80 character width, at least 25 character height
  84.         SetConsoleCXCY (hStdout, 80, 25);
  85. }
  86.  
  87.  
  88. void DeinitConProc (void)
  89. {
  90.         if (heventDone)
  91.                 SetEvent (heventDone);
  92. }
  93.  
  94.  
  95. DWORD RequestProc (DWORD dwNichts)
  96. {
  97.         int             *pBuffer;
  98.         DWORD   dwRet;
  99.         HANDLE  heventWait[2];
  100.         int             iBeginLine, iEndLine;
  101.        
  102.         heventWait[0] = heventParentSend;
  103.         heventWait[1] = heventDone;
  104.  
  105.         while (1)
  106.         {
  107.                 dwRet = WaitForMultipleObjects (2, heventWait, FALSE, INFINITE);
  108.  
  109.         // heventDone fired, so we're exiting.
  110.                 if (dwRet == WAIT_OBJECT_0 + 1)
  111.                         break;
  112.  
  113.                 pBuffer = (int *) GetMappedBuffer (hfileBuffer);
  114.                
  115.         // hfileBuffer is invalid.  Just leave.
  116.                 if (!pBuffer)
  117.                 {
  118.                         Con_SafePrintf ("Invalid hfileBuffer\n");
  119.                         break;
  120.                 }
  121.  
  122.                 switch (pBuffer[0])
  123.                 {
  124.                         case CCOM_WRITE_TEXT:
  125.                         // Param1 : Text
  126.                                 pBuffer[0] = WriteText ((LPCTSTR) (pBuffer + 1));
  127.                                 break;
  128.  
  129.                         case CCOM_GET_TEXT:
  130.                         // Param1 : Begin line
  131.                         // Param2 : End line
  132.                                 iBeginLine = pBuffer[1];
  133.                                 iEndLine = pBuffer[2];
  134.                                 pBuffer[0] = ReadText ((LPTSTR) (pBuffer + 1), iBeginLine,
  135.                                                                            iEndLine);
  136.                                 break;
  137.  
  138.                         case CCOM_GET_SCR_LINES:
  139.                         // No params
  140.                                 pBuffer[0] = GetScreenBufferLines (&pBuffer[1]);
  141.                                 break;
  142.  
  143.                         case CCOM_SET_SCR_LINES:
  144.                         // Param1 : Number of lines
  145.                                 pBuffer[0] = SetScreenBufferLines (pBuffer[1]);
  146.                                 break;
  147.                 }
  148.  
  149.                 ReleaseMappedBuffer (pBuffer);
  150.                 SetEvent (heventChildSend);
  151.         }
  152.  
  153.         return 0;
  154. }
  155.  
  156.  
  157. LPVOID GetMappedBuffer (HANDLE hfileBuffer)
  158. {
  159.         LPVOID pBuffer;
  160.  
  161.         pBuffer = MapViewOfFile (hfileBuffer,
  162.                                                         FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
  163.  
  164.         return pBuffer;
  165. }
  166.  
  167.  
  168. void ReleaseMappedBuffer (LPVOID pBuffer)
  169. {
  170.         UnmapViewOfFile (pBuffer);
  171. }
  172.  
  173.  
  174. BOOL GetScreenBufferLines (int *piLines)
  175. {
  176.         CONSOLE_SCREEN_BUFFER_INFO      info;                                                    
  177.         BOOL                                            bRet;
  178.  
  179.         bRet = GetConsoleScreenBufferInfo (hStdout, &info);
  180.                
  181.         if (bRet)
  182.                 *piLines = info.dwSize.Y;
  183.  
  184.         return bRet;
  185. }
  186.  
  187.  
  188. BOOL SetScreenBufferLines (int iLines)
  189. {
  190.  
  191.         return SetConsoleCXCY (hStdout, 80, iLines);
  192. }
  193.  
  194.  
  195. BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine)
  196. {
  197.         COORD   coord;
  198.         DWORD   dwRead;
  199.         BOOL    bRet;
  200.  
  201.         coord.X = 0;
  202.         coord.Y = iBeginLine;
  203.  
  204.         bRet = ReadConsoleOutputCharacter(
  205.                 hStdout,
  206.                 pszText,
  207.                 80 * (iEndLine - iBeginLine + 1),
  208.                 coord,
  209.                 &dwRead);
  210.  
  211.         // Make sure it's null terminated.
  212.         if (bRet)
  213.                 pszText[dwRead] = '\0';
  214.  
  215.         return bRet;
  216. }
  217.  
  218.  
  219. BOOL WriteText (LPCTSTR szText)
  220. {
  221.         DWORD                   dwWritten;
  222.         INPUT_RECORD    rec;
  223.         char                    upper, *sz;
  224.  
  225.         sz = (LPTSTR) szText;
  226.  
  227.         while (*sz)
  228.         {
  229.         // 13 is the code for a carriage return (\n) instead of 10.
  230.                 if (*sz == 10)
  231.                         *sz = 13;
  232.  
  233.                 upper = toupper(*sz);
  234.  
  235.                 rec.EventType = KEY_EVENT;
  236.                 rec.Event.KeyEvent.bKeyDown = TRUE;
  237.                 rec.Event.KeyEvent.wRepeatCount = 1;
  238.                 rec.Event.KeyEvent.wVirtualKeyCode = upper;
  239.                 rec.Event.KeyEvent.wVirtualScanCode = CharToCode (*sz);
  240.                 rec.Event.KeyEvent.uChar.AsciiChar = *sz;
  241.                 rec.Event.KeyEvent.uChar.UnicodeChar = *sz;
  242.                 rec.Event.KeyEvent.dwControlKeyState = isupper(*sz) ? 0x80 : 0x0;
  243.  
  244.                 WriteConsoleInput(
  245.                         hStdin,
  246.                         &rec,
  247.                         1,
  248.                         &dwWritten);
  249.  
  250.                 rec.Event.KeyEvent.bKeyDown = FALSE;
  251.  
  252.                 WriteConsoleInput(
  253.                         hStdin,
  254.                         &rec,
  255.                         1,
  256.                         &dwWritten);
  257.  
  258.                 sz++;
  259.         }
  260.  
  261.         return TRUE;
  262. }
  263.  
  264.  
  265. int CharToCode (char c)
  266. {
  267.         char upper;
  268.                
  269.         upper = toupper(c);
  270.  
  271.         switch (c)
  272.         {
  273.                 case 13:
  274.                         return 28;
  275.  
  276.                 default:
  277.                         break;
  278.         }
  279.  
  280.         if (isalpha(c))
  281.                 return (30 + upper - 65);
  282.  
  283.         if (isdigit(c))
  284.                 return (1 + upper - 47);
  285.  
  286.         return c;
  287. }
  288.  
  289.  
  290. BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy)
  291. {
  292.         CONSOLE_SCREEN_BUFFER_INFO      info;
  293.         COORD                                           coordMax;
  294.  
  295.         coordMax = GetLargestConsoleWindowSize(hStdout);
  296.  
  297.         if (cy > coordMax.Y)
  298.                 cy = coordMax.Y;
  299.  
  300.         if (cx > coordMax.X)
  301.                 cx = coordMax.X;
  302.  
  303.         if (!GetConsoleScreenBufferInfo(hStdout, &info))
  304.                 return FALSE;
  305.  
  306. // height
  307.     info.srWindow.Left = 0;        
  308.     info.srWindow.Right = info.dwSize.X - 1;                
  309.     info.srWindow.Top = 0;
  310.     info.srWindow.Bottom = cy - 1;          
  311.  
  312.         if (cy < info.dwSize.Y)
  313.         {
  314.                 if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
  315.                         return FALSE;
  316.  
  317.                 info.dwSize.Y = cy;
  318.  
  319.                 if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
  320.                         return FALSE;
  321.     }
  322.     else if (cy > info.dwSize.Y)
  323.     {
  324.                 info.dwSize.Y = cy;
  325.  
  326.                 if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
  327.                         return FALSE;
  328.  
  329.                 if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
  330.                         return FALSE;
  331.     }
  332.  
  333.         if (!GetConsoleScreenBufferInfo(hStdout, &info))
  334.                 return FALSE;
  335.  
  336. // width
  337.         info.srWindow.Left = 0;        
  338.         info.srWindow.Right = cx - 1;
  339.         info.srWindow.Top = 0;
  340.         info.srWindow.Bottom = info.dwSize.Y - 1;              
  341.  
  342.         if (cx < info.dwSize.X)
  343.         {
  344.                 if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
  345.                         return FALSE;
  346.  
  347.                 info.dwSize.X = cx;
  348.    
  349.                 if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
  350.                         return FALSE;
  351.         }
  352.         else if (cx > info.dwSize.X)
  353.         {
  354.                 info.dwSize.X = cx;
  355.  
  356.                 if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
  357.                         return FALSE;
  358.  
  359.                 if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
  360.                         return FALSE;
  361.         }
  362.  
  363.         return TRUE;
  364. }
  365.      
  366.