icculus quake2 doxygen  1.0 dev
conproc.c
Go to the documentation of this file.
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 */
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;
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 
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 
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 
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 
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 
CCOM_WRITE_TEXT
#define CCOM_WRITE_TEXT
Definition: conproc.c:26
ReleaseMappedBuffer
void ReleaseMappedBuffer(LPVOID pBuffer)
Definition: conproc.c:234
hStdin
HANDLE hStdin
Definition: conproc.c:45
GetMappedBuffer
LPVOID GetMappedBuffer(HANDLE hfileBuffer)
Definition: conproc.c:223
CCheckParm
int CCheckParm(char *parm)
Definition: conproc.c:68
CharToCode
int CharToCode(char c)
Definition: conproc.c:331
ReadText
BOOL ReadText(LPTSTR pszText, int iBeginLine, int iEndLine)
Definition: conproc.c:261
heventParentSend
HANDLE heventParentSend
Definition: conproc.c:43
i
int i
Definition: q_shared.c:305
argv
char * argv[MAX_NUM_ARGVS]
Definition: sys_win.c:55
argc
int argc
Definition: sys_win.c:54
ccom_argv
char ** ccom_argv
Definition: conproc.c:58
SetConsoleCXCY
BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy)
Definition: conproc.c:356
RequestProc
unsigned _stdcall RequestProc(void *arg)
Definition: conproc.c:160
ccom_argc
int ccom_argc
Definition: conproc.c:57
CCOM_GET_SCR_LINES
#define CCOM_GET_SCR_LINES
Definition: conproc.c:33
BOOL
CONST COLORREF COLORREF BOOL
Definition: qgl_win.c:60
t
GLdouble t
Definition: qgl_win.c:328
NULL
#define NULL
Definition: q_shared.h:60
GetScreenBufferLines
BOOL GetScreenBufferLines(int *piLines)
Definition: conproc.c:240
heventDone
HANDLE heventDone
Definition: conproc.c:40
SetScreenBufferLines
BOOL SetScreenBufferLines(int iLines)
Definition: conproc.c:254
CCOM_GET_TEXT
#define CCOM_GET_TEXT
Definition: conproc.c:29
InitConProc
void InitConProc(int argc, char **argv)
Definition: conproc.c:84
heventChildSend
HANDLE heventChildSend
Definition: conproc.c:42
conproc.h
hStdout
HANDLE hStdout
Definition: conproc.c:44
CCOM_SET_SCR_LINES
#define CCOM_SET_SCR_LINES
Definition: conproc.c:36
DWORD
DWORD
Definition: qgl_win.c:49
WriteText
BOOL WriteText(LPCTSTR szText)
Definition: conproc.c:285
DeinitConProc
void DeinitConProc(void)
Definition: conproc.c:153
hfileBuffer
HANDLE hfileBuffer
Definition: conproc.c:41