home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / glquake_src / conproc.c < prev    next >
C/C++ Source or Header  |  1999-12-28  |  8KB  |  366 lines

  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.