|
|
1.1.1.2 ! root 1: /* ! 2: Copyright (C) 1997-2001 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: */ 1.1 root 20: // conproc.c -- support for qhost 21: #include <stdio.h> 22: #include <process.h> 23: #include <windows.h> 24: #include "conproc.h" 25: 26: #define CCOM_WRITE_TEXT 0x2 27: // Param1 : Text 28: 29: #define CCOM_GET_TEXT 0x3 30: // Param1 : Begin line 31: // Param2 : End line 32: 33: #define CCOM_GET_SCR_LINES 0x4 34: // No params 35: 36: #define CCOM_SET_SCR_LINES 0x5 37: // Param1 : Number of lines 38: 39: 40: HANDLE heventDone; 41: HANDLE hfileBuffer; 42: HANDLE heventChildSend; 43: HANDLE heventParentSend; 44: HANDLE hStdout; 45: HANDLE hStdin; 46: 47: unsigned _stdcall RequestProc (void *arg); 48: LPVOID GetMappedBuffer (HANDLE hfileBuffer); 49: void ReleaseMappedBuffer (LPVOID pBuffer); 50: BOOL GetScreenBufferLines (int *piLines); 51: BOOL SetScreenBufferLines (int iLines); 52: BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine); 53: BOOL WriteText (LPCTSTR szText); 54: int CharToCode (char c); 55: BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy); 56: 57: int ccom_argc; 58: char **ccom_argv; 59: 60: /* 61: ================ 62: CCheckParm 63: 64: Returns the position (1 to argc-1) in the program's argument list 65: where the given parameter apears, or 0 if not present 66: ================ 67: */ 68: int CCheckParm (char *parm) 69: { 70: int i; 71: 72: for (i=1 ; i<ccom_argc ; i++) 73: { 74: if (!ccom_argv[i]) 75: continue; 76: if (!strcmp (parm,ccom_argv[i])) 77: return i; 78: } 79: 80: return 0; 81: } 82: 83: 84: void InitConProc (int argc, char **argv) 85: { 86: unsigned threadAddr; 87: HANDLE hFile; 88: HANDLE heventParent; 89: HANDLE heventChild; 90: int t; 91: 92: ccom_argc = argc; 93: ccom_argv = argv; 94: 95: // give QHOST a chance to hook into the console 96: if ((t = CCheckParm ("-HFILE")) > 0) 97: { 98: if (t < argc) 99: hFile = (HANDLE)atoi (ccom_argv[t+1]); 100: } 101: 102: if ((t = CCheckParm ("-HPARENT")) > 0) 103: { 104: if (t < argc) 105: heventParent = (HANDLE)atoi (ccom_argv[t+1]); 106: } 107: 108: if ((t = CCheckParm ("-HCHILD")) > 0) 109: { 110: if (t < argc) 111: heventChild = (HANDLE)atoi (ccom_argv[t+1]); 112: } 113: 114: 115: // ignore if we don't have all the events. 116: if (!hFile || !heventParent || !heventChild) 117: { 118: printf ("Qhost not present.\n"); 119: return; 120: } 121: 122: printf ("Initializing for qhost.\n"); 123: 124: hfileBuffer = hFile; 125: heventParentSend = heventParent; 126: heventChildSend = heventChild; 127: 128: // so we'll know when to go away. 129: heventDone = CreateEvent (NULL, FALSE, FALSE, NULL); 130: 131: if (!heventDone) 132: { 133: printf ("Couldn't create heventDone\n"); 134: return; 135: } 136: 137: if (!_beginthreadex (NULL, 0, RequestProc, NULL, 0, &threadAddr)) 138: { 139: CloseHandle (heventDone); 140: printf ("Couldn't create QHOST thread\n"); 141: return; 142: } 143: 144: // save off the input/output handles. 145: hStdout = GetStdHandle (STD_OUTPUT_HANDLE); 146: hStdin = GetStdHandle (STD_INPUT_HANDLE); 147: 148: // force 80 character width, at least 25 character height 149: SetConsoleCXCY (hStdout, 80, 25); 150: } 151: 152: 153: void DeinitConProc (void) 154: { 155: if (heventDone) 156: SetEvent (heventDone); 157: } 158: 159: 160: unsigned _stdcall RequestProc (void *arg) 161: { 162: int *pBuffer; 163: DWORD dwRet; 164: HANDLE heventWait[2]; 165: int iBeginLine, iEndLine; 166: 167: heventWait[0] = heventParentSend; 168: heventWait[1] = heventDone; 169: 170: while (1) 171: { 172: dwRet = WaitForMultipleObjects (2, heventWait, FALSE, INFINITE); 173: 174: // heventDone fired, so we're exiting. 175: if (dwRet == WAIT_OBJECT_0 + 1) 176: break; 177: 178: pBuffer = (int *) GetMappedBuffer (hfileBuffer); 179: 180: // hfileBuffer is invalid. Just leave. 181: if (!pBuffer) 182: { 183: printf ("Invalid hfileBuffer\n"); 184: break; 185: } 186: 187: switch (pBuffer[0]) 188: { 189: case CCOM_WRITE_TEXT: 190: // Param1 : Text 191: pBuffer[0] = WriteText ((LPCTSTR) (pBuffer + 1)); 192: break; 193: 194: case CCOM_GET_TEXT: 195: // Param1 : Begin line 196: // Param2 : End line 197: iBeginLine = pBuffer[1]; 198: iEndLine = pBuffer[2]; 199: pBuffer[0] = ReadText ((LPTSTR) (pBuffer + 1), iBeginLine, 200: iEndLine); 201: break; 202: 203: case CCOM_GET_SCR_LINES: 204: // No params 205: pBuffer[0] = GetScreenBufferLines (&pBuffer[1]); 206: break; 207: 208: case CCOM_SET_SCR_LINES: 209: // Param1 : Number of lines 210: pBuffer[0] = SetScreenBufferLines (pBuffer[1]); 211: break; 212: } 213: 214: ReleaseMappedBuffer (pBuffer); 215: SetEvent (heventChildSend); 216: } 217: 218: _endthreadex (0); 219: return 0; 220: } 221: 222: 223: LPVOID GetMappedBuffer (HANDLE hfileBuffer) 224: { 225: LPVOID pBuffer; 226: 227: pBuffer = MapViewOfFile (hfileBuffer, 228: FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); 229: 230: return pBuffer; 231: } 232: 233: 234: void ReleaseMappedBuffer (LPVOID pBuffer) 235: { 236: UnmapViewOfFile (pBuffer); 237: } 238: 239: 240: BOOL GetScreenBufferLines (int *piLines) 241: { 242: CONSOLE_SCREEN_BUFFER_INFO info; 243: BOOL bRet; 244: 245: bRet = GetConsoleScreenBufferInfo (hStdout, &info); 246: 247: if (bRet) 248: *piLines = info.dwSize.Y; 249: 250: return bRet; 251: } 252: 253: 254: BOOL SetScreenBufferLines (int iLines) 255: { 256: 257: return SetConsoleCXCY (hStdout, 80, iLines); 258: } 259: 260: 261: BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine) 262: { 263: COORD coord; 264: DWORD dwRead; 265: BOOL bRet; 266: 267: coord.X = 0; 268: coord.Y = iBeginLine; 269: 270: bRet = ReadConsoleOutputCharacter( 271: hStdout, 272: pszText, 273: 80 * (iEndLine - iBeginLine + 1), 274: coord, 275: &dwRead); 276: 277: // Make sure it's null terminated. 278: if (bRet) 279: pszText[dwRead] = '\0'; 280: 281: return bRet; 282: } 283: 284: 285: BOOL WriteText (LPCTSTR szText) 286: { 287: DWORD dwWritten; 288: INPUT_RECORD rec; 289: char upper, *sz; 290: 291: sz = (LPTSTR) szText; 292: 293: while (*sz) 294: { 295: // 13 is the code for a carriage return (\n) instead of 10. 296: if (*sz == 10) 297: *sz = 13; 298: 299: upper = toupper(*sz); 300: 301: rec.EventType = KEY_EVENT; 302: rec.Event.KeyEvent.bKeyDown = TRUE; 303: rec.Event.KeyEvent.wRepeatCount = 1; 304: rec.Event.KeyEvent.wVirtualKeyCode = upper; 305: rec.Event.KeyEvent.wVirtualScanCode = CharToCode (*sz); 306: rec.Event.KeyEvent.uChar.AsciiChar = *sz; 307: rec.Event.KeyEvent.uChar.UnicodeChar = *sz; 308: rec.Event.KeyEvent.dwControlKeyState = isupper(*sz) ? 0x80 : 0x0; 309: 310: WriteConsoleInput( 311: hStdin, 312: &rec, 313: 1, 314: &dwWritten); 315: 316: rec.Event.KeyEvent.bKeyDown = FALSE; 317: 318: WriteConsoleInput( 319: hStdin, 320: &rec, 321: 1, 322: &dwWritten); 323: 324: sz++; 325: } 326: 327: return TRUE; 328: } 329: 330: 331: int CharToCode (char c) 332: { 333: char upper; 334: 335: upper = toupper(c); 336: 337: switch (c) 338: { 339: case 13: 340: return 28; 341: 342: default: 343: break; 344: } 345: 346: if (isalpha(c)) 347: return (30 + upper - 65); 348: 349: if (isdigit(c)) 350: return (1 + upper - 47); 351: 352: return c; 353: } 354: 355: 356: BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy) 357: { 358: CONSOLE_SCREEN_BUFFER_INFO info; 359: COORD coordMax; 360: 361: coordMax = GetLargestConsoleWindowSize(hStdout); 362: 363: if (cy > coordMax.Y) 364: cy = coordMax.Y; 365: 366: if (cx > coordMax.X) 367: cx = coordMax.X; 368: 369: if (!GetConsoleScreenBufferInfo(hStdout, &info)) 370: return FALSE; 371: 372: // height 373: info.srWindow.Left = 0; 374: info.srWindow.Right = info.dwSize.X - 1; 375: info.srWindow.Top = 0; 376: info.srWindow.Bottom = cy - 1; 377: 378: if (cy < info.dwSize.Y) 379: { 380: if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) 381: return FALSE; 382: 383: info.dwSize.Y = cy; 384: 385: if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) 386: return FALSE; 387: } 388: else if (cy > info.dwSize.Y) 389: { 390: info.dwSize.Y = cy; 391: 392: if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) 393: return FALSE; 394: 395: if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) 396: return FALSE; 397: } 398: 399: if (!GetConsoleScreenBufferInfo(hStdout, &info)) 400: return FALSE; 401: 402: // width 403: info.srWindow.Left = 0; 404: info.srWindow.Right = cx - 1; 405: info.srWindow.Top = 0; 406: info.srWindow.Bottom = info.dwSize.Y - 1; 407: 408: if (cx < info.dwSize.X) 409: { 410: if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) 411: return FALSE; 412: 413: info.dwSize.X = cx; 414: 415: if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) 416: return FALSE; 417: } 418: else if (cx > info.dwSize.X) 419: { 420: info.dwSize.X = cx; 421: 422: if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) 423: return FALSE; 424: 425: if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) 426: return FALSE; 427: } 428: 429: return TRUE; 430: } 431:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.