Annotation of quake2/win32/conproc.c, revision 1.1.1.2

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:      

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.