|
|
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.