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