|
|
1.1.1.2 ! root 1: /* $Id: win32cio.c,v 1.96 2009/08/21 08:54:34 deuce Exp $ */ 1.1 root 2: 3: /**************************************************************************** 4: * @format.tab-size 4 (Plain Text/Source Code File Header) * 5: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * 6: * * 7: * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html * 8: * * 9: * This library is free software; you can redistribute it and/or * 10: * modify it under the terms of the GNU Lesser General Public License * 11: * as published by the Free Software Foundation; either version 2 * 12: * of the License, or (at your option) any later version. * 13: * See the GNU Lesser General Public License for more details: lgpl.txt or * 14: * http://www.fsf.org/copyleft/lesser.html * 15: * * 16: * Anonymous FTP access to the most recent released source is available at * 17: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * 18: * * 19: * Anonymous CVS access to the development source and modification history * 20: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * 21: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * 22: * (just hit return, no password is necessary) * 23: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * 24: * * 25: * For Synchronet coding style and modification guidelines, see * 26: * http://www.synchro.net/source.html * 27: * * 28: * You are encouraged to submit any modifications (preferably in Unix diff * 29: * format) via e-mail to [email protected] * 30: * * 31: * Note: If this box doesn't appear square, then you need to fix your tabs. * 32: ****************************************************************************/ 33: 34: #include <windows.h> /* INPUT_RECORD, etc. */ 35: #include <genwrap.h> 36: #include <stdio.h> /* stdin */ 37: #if defined(_WIN32) 38: #include <malloc.h> /* alloca() on Win32 */ 39: #endif 40: 41: #if (defined CIOLIB_IMPORTS) 42: #undef CIOLIB_IMPORTS 43: #endif 44: #if (defined CIOLIB_EXPORTS) 45: #undef CIOLIB_EXPORTS 46: #endif 47: 48: #include "ciolib.h" 49: #include "keys.h" 50: #include "vidmodes.h" 51: #include "win32cio.h" 52: 53: struct keyvals { 54: int VirtualKeyCode 55: ,Key 56: ,Shift 57: ,CTRL 58: ,ALT; 59: }; 60: 61: const struct keyvals keyval[] = 62: { 63: {VK_BACK, 0x08, 0x08, 0x7f, 0x0e00}, 64: {VK_TAB, 0x09, 0x0f00, 0x9400, 0xa500}, 65: {VK_RETURN, 0x0d, 0x0d, 0x0a, 0xa600}, 66: {VK_ESCAPE, 0x1b, 0x1b, 0x1b, 0x0100}, 67: {VK_SPACE, 0x20, 0x20, 0x0300, 0x20,}, 68: {'0', '0', ')', 0, 0x8100}, 69: {'1', '1', '!', 0, 0x7800}, 70: {'2', '2', '@', 0x0300, 0x7900}, 71: {'3', '3', '#', 0, 0x7a00}, 72: {'4', '4', '$', 0, 0x7b00}, 73: {'5', '5', '%', 0, 0x7c00}, 74: {'6', '6', '^', 0x1e, 0x7d00}, 75: {'7', '7', '&', 0, 0x7e00}, 76: {'8', '8', '*', 0, 0x7f00}, 77: {'9', '9', '(', 0, 0x8000}, 78: {'A', 'a', 'A', 0x01, 0x1e00}, 79: {'B', 'b', 'B', 0x02, 0x3000}, 80: {'C', 'c', 'C', 0x03, 0x2e00}, 81: {'D', 'd', 'D', 0x04, 0x2000}, 82: {'E', 'e', 'E', 0x05, 0x1200}, 83: {'F', 'f', 'F', 0x06, 0x2100}, 84: {'G', 'g', 'G', 0x07, 0x2200}, 85: {'H', 'h', 'H', 0x08, 0x2300}, 86: {'I', 'i', 'I', 0x09, 0x1700}, 87: {'J', 'j', 'J', 0x0a, 0x2400}, 88: {'K', 'k', 'K', 0x0b, 0x2500}, 89: {'L', 'l', 'L', 0x0c, 0x2600}, 90: {'M', 'm', 'M', 0x0d, 0x3200}, 91: {'N', 'n', 'N', 0x0e, 0x3100}, 92: {'O', 'o', 'O', 0x0f, 0x1800}, 93: {'P', 'p', 'P', 0x10, 0x1900}, 94: {'Q', 'q', 'Q', 0x11, 0x1000}, 95: {'R', 'r', 'R', 0x12, 0x1300}, 96: {'S', 's', 'S', 0x13, 0x1f00}, 97: {'T', 't', 'T', 0x14, 0x1400}, 98: {'U', 'u', 'U', 0x15, 0x1600}, 99: {'V', 'v', 'V', 0x16, 0x2f00}, 100: {'W', 'w', 'W', 0x17, 0x1100}, 101: {'X', 'x', 'X', 0x18, 0x2d00}, 102: {'Y', 'y', 'Y', 0x19, 0x1500}, 103: {'Z', 'z', 'Z', 0x1a, 0x2c00}, 104: {VK_PRIOR, 0x4900, 0x4900, 0x8400, 0x9900}, 105: {VK_NEXT, 0x5100, 0x5100, 0x7600, 0xa100}, 106: {VK_END, 0x4f00, 0x4f00, 0x7500, 0x9f00}, 107: {VK_HOME, 0x4700, 0x4700, 0x7700, 0x9700}, 108: {VK_LEFT, 0x4b00, 0x4b00, 0x7300, 0x9b00}, 109: {VK_UP, 0x4800, 0x4800, 0x8d00, 0x9800}, 110: {VK_RIGHT, 0x4d00, 0x4d00, 0x7400, 0x9d00}, 111: {VK_DOWN, 0x5000, 0x5000, 0x9100, 0xa000}, 112: {VK_INSERT, 0x5200, 0x5200, 0x9200, 0xa200}, 113: {VK_DELETE, 0x5300, 0x5300, 0x9300, 0xa300}, 114: {VK_NUMPAD0, '0', 0x5200, 0x9200, 0}, 115: {VK_NUMPAD1, '1', 0x4f00, 0x7500, 0}, 116: {VK_NUMPAD2, '2', 0x5000, 0x9100, 0}, 117: {VK_NUMPAD3, '3', 0x5100, 0x7600, 0}, 118: {VK_NUMPAD4, '4', 0x4b00, 0x7300, 0}, 119: {VK_NUMPAD5, '5', 0x4c00, 0x8f00, 0}, 120: {VK_NUMPAD6, '6', 0x4d00, 0x7400, 0}, 121: {VK_NUMPAD7, '7', 0x4700, 0x7700, 0}, 122: {VK_NUMPAD8, '8', 0x4800, 0x8d00, 0}, 123: {VK_NUMPAD9, '9', 0x4900, 0x8400, 0}, 124: {VK_MULTIPLY, '*', '*', 0x9600, 0x3700}, 125: {VK_ADD, '+', '+', 0x9000, 0x4e00}, 126: {VK_SUBTRACT, '-', '-', 0x8e00, 0x4a00}, 127: {VK_DECIMAL, '.', '.', 0x5300, 0x9300}, 128: {VK_DIVIDE, '/', '/', 0x9500, 0xa400}, 129: {VK_F1, 0x3b00, 0x5400, 0x5e00, 0x6800}, 130: {VK_F2, 0x3c00, 0x5500, 0x5f00, 0x6900}, 131: {VK_F3, 0x3d00, 0x5600, 0x6000, 0x6a00}, 132: {VK_F4, 0x3e00, 0x5700, 0x6100, 0x6b00}, 133: {VK_F5, 0x3f00, 0x5800, 0x6200, 0x6c00}, 134: {VK_F6, 0x4000, 0x5900, 0x6300, 0x6d00}, 135: {VK_F7, 0x4100, 0x5a00, 0x6400, 0x6e00}, 136: {VK_F8, 0x4200, 0x5b00, 0x6500, 0x6f00}, 137: {VK_F9, 0x4300, 0x5c00, 0x6600, 0x7000}, 138: {VK_F10, 0x4400, 0x5d00, 0x6700, 0x7100}, 139: {VK_F11, 0x8500, 0x8700, 0x8900, 0x8b00}, 140: {VK_F12, 0x8600, 0x8800, 0x8a00, 0x8c00}, 141: {0xdc, '\\', '|', 0x1c, 0x2b00}, 142: {0xbf, '/', '?', 0, 0x3500}, 143: {0xbd, '-', '_', 0x1f, 0x8200}, 144: {0xbb, '=', '+', 0, 0x8300}, 145: {0xdb, '[', '{', 0x1b, 0x1a00}, 146: {0xdd, ']', '}', 0x1d, 0x1b00}, 147: {0xba, ';', ':', 0, 0x2700}, 148: {0xde, '\'', '"', 0, 0x2800}, 149: {0xbc, ',', '<', 0, 0x3300}, 150: {0xbe, '.', '>', 0, 0x3400}, 151: {0xc0, '`', '~', 0, 0x2900}, 152: {0, 0, 0, 0, 0} /** END **/ 153: }; 154: 1.1.1.2 ! root 155: /* Mouse related stuff */ 1.1 root 156: static int domouse=1; 157: static DWORD last_state=0; 158: static int LastX=-1, LastY=-1; 159: 160: static int modeidx=3; 161: 162: #if defined(_DEBUG) 163: static void dputs(const char* str) 164: { 165: char msg[1024]; 166: 167: SAFEPRINTF(msg,"%s\r\n",str); 168: OutputDebugString(msg); 169: } 170: #endif 171: 172: static void dprintf(const char* fmt, ...) 173: { 174: #if defined(_DEBUG) 175: va_list argptr; 176: char sbuf[1024]; 177: 178: va_start(argptr,fmt); 179: vsnprintf(sbuf,sizeof(sbuf),fmt,argptr); 180: sbuf[sizeof(sbuf)-1]=0; 181: va_end(argptr); 182: dputs(sbuf); 183: #endif /* _DEBUG */ 184: } 185: 1.1.1.2 ! root 186: static WORD DOStoWinAttr(int newattr) 1.1 root 187: { 188: WORD ret=0; 189: 190: if(newattr&0x01) 191: ret|=FOREGROUND_BLUE; 192: if(newattr&0x02) 193: ret|=FOREGROUND_GREEN; 194: if(newattr&0x04) 195: ret|=FOREGROUND_RED; 196: if(newattr&0x08) 197: ret|=FOREGROUND_INTENSITY; 198: if(newattr&0x10) 199: ret|=BACKGROUND_BLUE; 200: if(newattr&0x20) 201: ret|=BACKGROUND_GREEN; 202: if(newattr&0x40) 203: ret|=BACKGROUND_RED; 204: if(newattr&0x80) 205: ret|=BACKGROUND_INTENSITY; 206: return(ret); 207: } 208: 1.1.1.2 ! root 209: static unsigned char WintoDOSAttr(WORD newattr) 1.1 root 210: { 211: unsigned char ret=0; 212: 213: if(newattr&FOREGROUND_BLUE) 214: ret|=0x01; 215: if(newattr&FOREGROUND_GREEN) 216: ret|=0x02; 217: if(newattr&FOREGROUND_RED) 218: ret|=0x04; 219: if(newattr&FOREGROUND_INTENSITY) 220: ret|=0x08; 221: if(newattr&BACKGROUND_BLUE) 222: ret|=0x10; 223: if(newattr&BACKGROUND_GREEN) 224: ret|=0x20; 225: if(newattr&BACKGROUND_RED) 226: ret|=0x40; 227: if(newattr&BACKGROUND_INTENSITY) 228: ret|=0x80; 229: return(ret); 230: } 231: 1.1.1.2 ! root 232: static int win32_getchcode(WORD code, DWORD state) 1.1 root 233: { 234: int i; 235: 236: for(i=0;keyval[i].Key;i++) { 237: if(keyval[i].VirtualKeyCode==code) { 238: if(state & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED)) 239: return(keyval[i].ALT); 240: if(state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED)) 241: return(keyval[i].CTRL); 242: if((state & (CAPSLOCK_ON)) && isalpha(keyval[i].Key)) { 243: if(!(state & SHIFT_PRESSED)) 244: return(keyval[i].Shift); 245: } 246: else { 247: if(state & (SHIFT_PRESSED)) 248: return(keyval[i].Shift); 249: } 250: return(keyval[i].Key); 251: } 252: } 253: return(0); 254: } 255: 1.1.1.2 ! root 256: static int win32_keyboardio(int isgetch) 1.1 root 257: { 258: INPUT_RECORD input; 259: DWORD num=0; 260: HANDLE h; 261: static WORD lastch; 262: 263: if((h=GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) 264: return(0); 265: 266: while(1) { 267: if(lastch) { 268: if(isgetch) { 269: BYTE ch; 270: ch=lastch&0xff; 271: lastch>>=8; 272: return(ch); 273: } 274: else 275: return(TRUE); 276: } 277: 278: while(1) { 279: GetNumberOfConsoleInputEvents(h, &num); 280: if(num) 281: break; 282: if(mouse_trywait()) { 283: lastch=CIO_KEY_MOUSE; 284: break; 285: } 286: if(isgetch) 287: SLEEP(1); 288: else 289: return(FALSE); 290: } 291: 292: if(lastch) 293: continue; 294: 295: if(!ReadConsoleInput(h, &input, 1, &num) 296: || !num || (input.EventType!=KEY_EVENT && input.EventType!=MOUSE_EVENT)) 297: continue; 298: 299: switch(input.EventType) { 300: case KEY_EVENT: 301: 1.1.1.2 ! root 302: #ifdef DEBUG_KEY_EVENTS 1.1 root 303: dprintf("KEY_EVENT: KeyDown=%u" 304: ,input.Event.KeyEvent.bKeyDown); 305: dprintf(" RepeatCount=%u" 306: ,input.Event.KeyEvent.wRepeatCount); 307: dprintf(" VirtualKeyCode=0x%04hX" 308: ,input.Event.KeyEvent.wVirtualKeyCode); 309: dprintf(" VirtualScanCode=0x%04hX" 310: ,input.Event.KeyEvent.wVirtualScanCode); 311: dprintf(" uChar.AsciiChar=0x%02X (%u)" 312: ,(BYTE)input.Event.KeyEvent.uChar.AsciiChar 313: ,(BYTE)input.Event.KeyEvent.uChar.AsciiChar); 314: dprintf(" ControlKeyState=0x%08lX" 315: ,input.Event.KeyEvent.dwControlKeyState); 1.1.1.2 ! root 316: #endif 1.1 root 317: 318: if(input.Event.KeyEvent.bKeyDown) { 319: /* Is this an AltGr key? */ 320: if(((input.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_CTRL_PRESSED)) == (RIGHT_ALT_PRESSED|LEFT_CTRL_PRESSED)) 321: && (BYTE)input.Event.KeyEvent.uChar.AsciiChar) { 322: lastch=(BYTE)input.Event.KeyEvent.uChar.AsciiChar; 323: } 324: /* Is this a modified char? */ 325: else if((input.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED|RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED|ENHANCED_KEY)) 326: || (input.Event.KeyEvent.wVirtualKeyCode >= VK_F1 && input.Event.KeyEvent.wVirtualKeyCode <= VK_F24) 327: || !input.Event.KeyEvent.uChar.AsciiChar) { 328: lastch=win32_getchcode(input.Event.KeyEvent.wVirtualKeyCode, input.Event.KeyEvent.dwControlKeyState); 329: } 330: /* Must be a normal char then! */ 331: else { 332: lastch=(BYTE)input.Event.KeyEvent.uChar.AsciiChar; 333: } 334: } else if(input.Event.KeyEvent.wVirtualKeyCode == VK_MENU) 335: lastch=(BYTE)input.Event.KeyEvent.uChar.AsciiChar; 336: 337: break; 338: case MOUSE_EVENT: 339: if(domouse) { 340: if(input.Event.MouseEvent.dwMousePosition.X+1 != LastX || input.Event.MouseEvent.dwMousePosition.Y+1 != LastY) { 341: LastX=input.Event.MouseEvent.dwMousePosition.X+1; 342: LastY=input.Event.MouseEvent.dwMousePosition.Y+1; 343: ciomouse_gotevent(CIOLIB_MOUSE_MOVE,LastX,LastY); 344: } 345: if(last_state != input.Event.MouseEvent.dwButtonState) { 346: switch(input.Event.MouseEvent.dwButtonState ^ last_state) { 347: case FROM_LEFT_1ST_BUTTON_PRESSED: 348: if(input.Event.MouseEvent.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) 349: ciomouse_gotevent(CIOLIB_BUTTON_1_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); 350: else 351: ciomouse_gotevent(CIOLIB_BUTTON_1_RELEASE,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); 352: break; 353: case FROM_LEFT_2ND_BUTTON_PRESSED: 354: if(input.Event.MouseEvent.dwButtonState & FROM_LEFT_2ND_BUTTON_PRESSED) 355: ciomouse_gotevent(CIOLIB_BUTTON_2_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); 356: else 357: ciomouse_gotevent(CIOLIB_BUTTON_2_RELEASE,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); 358: break; 359: case RIGHTMOST_BUTTON_PRESSED: 360: if(input.Event.MouseEvent.dwButtonState & RIGHTMOST_BUTTON_PRESSED) 361: ciomouse_gotevent(CIOLIB_BUTTON_3_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); 362: else 363: ciomouse_gotevent(CIOLIB_BUTTON_3_RELEASE,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); 364: break; 365: } 366: last_state=input.Event.MouseEvent.dwButtonState; 367: } 368: } 369: } 370: } 371: } 372: 373: int win32_kbhit(void) 374: { 375: return(win32_keyboardio(FALSE)); 376: } 377: 378: int win32_getch(void) 379: { 380: int ret=win32_keyboardio(TRUE); 381: dprintf("win32_getch = 0x%02X (%u)", (BYTE)ret, (BYTE)ret); 382: return(ret); 383: } 384: 385: #ifndef ENABLE_EXTENDED_FLAGS 386: #define ENABLE_INSERT_MODE 0x0020 387: #define ENABLE_QUICK_EDIT_MODE 0x0040 388: #define ENABLE_EXTENDED_FLAGS 0x0080 389: #define ENABLE_AUTO_POSITION 0x0100 390: #endif 391: 392: static DWORD orig_in_conmode=0; 393: static DWORD orig_out_conmode=0; 394: static void * win32_suspendbuf=NULL; 395: 1.1.1.2 ! root 396: #ifndef CONSOLE_FULLSCREEN_MODE ! 397: /* SetConsoleDisplayMode parameter value */ ! 398: #define CONSOLE_FULLSCREEN_MODE 1 // Text is displayed in full-screen mode. ! 399: #define CONSOLE_WINDOWED_MODE 2 // Text is displayed in a console window. ! 400: #endif ! 401: ! 402: static DWORD orig_display_mode=0; ! 403: ! 404: /*----------------------------------------------------------------------------- ! 405: NT_SetConsoleDisplayMode - Set the console display to fullscreen or windowed. ! 406: ! 407: Parameters: ! 408: hOutputHandle - Output handle of cosole, usually ! 409: "GetStdHandle(STD_OUTPUT_HANDLE)" ! 410: dwNewMode - 0=windowed, 1=fullscreen ! 411: ! 412: Returns Values: ! 413: TRUE if successful, otherwise FALSE is returned. Call GetLastError() for ! 414: extened information. ! 415: ! 416: Remarks: ! 417: This only works on NT based versions of Windows. ! 418: ! 419: If dwNewMode is anything other than 0 or 1, FALSE is returned and ! 420: GetLastError() returns ERROR_INVALID_PARAMETER. ! 421: ! 422: If dwNewMode specfies the current mode, FALSE is returned and ! 423: GetLastError() returns ERROR_INVALID_PARAMETER. Use the (documented) ! 424: function GetConsoleDisplayMode() to determine the current display mode. ! 425: -----------------------------------------------------------------------------*/ ! 426: BOOL NT_SetConsoleDisplayMode(HANDLE hOutputHandle, DWORD dwNewMode) ! 427: { ! 428: typedef BOOL (WINAPI *SCDMProc_t) (HANDLE, DWORD, LPDWORD); ! 429: SCDMProc_t SetConsoleDisplayMode; ! 430: HMODULE hKernel32; ! 431: BOOL ret; ! 432: const char KERNEL32_NAME[] = "kernel32.dll"; ! 433: ! 434: hKernel32 = LoadLibrary(KERNEL32_NAME); ! 435: if (hKernel32 == NULL) ! 436: return FALSE; ! 437: ! 438: SetConsoleDisplayMode = ! 439: (SCDMProc_t)GetProcAddress(hKernel32, "SetConsoleDisplayMode"); ! 440: if (SetConsoleDisplayMode == NULL) ! 441: { ! 442: SetLastError(ERROR_CALL_NOT_IMPLEMENTED); ! 443: ret = FALSE; ! 444: } ! 445: else ! 446: { ! 447: DWORD dummy=0; ! 448: ret = SetConsoleDisplayMode(hOutputHandle, dwNewMode, &dummy); ! 449: dprintf("SetConsoleDisplayMode(%d) returned %d", dwNewMode, ret); ! 450: } ! 451: ! 452: FreeLibrary(hKernel32); ! 453: ! 454: return ret; ! 455: } ! 456: ! 457: BOOL NT_GetConsoleDisplayMode(DWORD* mode) ! 458: { ! 459: typedef BOOL (WINAPI *GCDMProc_t) (LPDWORD); ! 460: GCDMProc_t GetConsoleDisplayMode; ! 461: HMODULE hKernel32; ! 462: BOOL ret; ! 463: const char KERNEL32_NAME[] = "kernel32.dll"; ! 464: ! 465: hKernel32 = LoadLibrary(KERNEL32_NAME); ! 466: if (hKernel32 == NULL) ! 467: return FALSE; ! 468: ! 469: GetConsoleDisplayMode = ! 470: (GCDMProc_t)GetProcAddress(hKernel32, "GetConsoleDisplayMode"); ! 471: if (GetConsoleDisplayMode == NULL) ! 472: { ! 473: SetLastError(ERROR_CALL_NOT_IMPLEMENTED); ! 474: ret = FALSE; ! 475: } ! 476: else ! 477: { ! 478: ret = GetConsoleDisplayMode(mode); ! 479: dprintf("GetConsoleDisplayMode() returned %d (%d)", ret, *mode); ! 480: } ! 481: ! 482: FreeLibrary(hKernel32); ! 483: ! 484: return ret; ! 485: } ! 486: ! 487: ! 488: void RestoreDisplayMode(void) ! 489: { ! 490: if(orig_display_mode==0) ! 491: NT_SetConsoleDisplayMode(GetStdHandle(STD_OUTPUT_HANDLE),CONSOLE_WINDOWED_MODE); ! 492: } ! 493: 1.1 root 494: void win32_suspend(void) 495: { 496: HANDLE h; 497: 498: if((h=GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE) 499: SetConsoleMode(h, orig_out_conmode); 1.1.1.2 ! root 500: if((h=GetStdHandle(STD_INPUT_HANDLE)) != INVALID_HANDLE_VALUE) ! 501: SetConsoleMode(h, orig_in_conmode); 1.1 root 502: } 503: 504: void win32_resume(void) 505: { 506: DWORD conmode; 507: HANDLE h; 508: 1.1.1.2 ! root 509: conmode=ENABLE_MOUSE_INPUT|ENABLE_EXTENDED_FLAGS; 1.1 root 510: if((h=GetStdHandle(STD_INPUT_HANDLE)) != INVALID_HANDLE_VALUE) 511: SetConsoleMode(h, conmode); 512: 513: conmode=orig_out_conmode; 514: conmode&=~ENABLE_PROCESSED_OUTPUT; 515: conmode&=~ENABLE_WRAP_AT_EOL_OUTPUT; 516: if((h=GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE) 517: SetConsoleMode(h, conmode); 518: } 519: 1.1.1.2 ! root 520: static BOOL WINAPI ControlHandler(unsigned long CtrlType) ! 521: { ! 522: return TRUE; ! 523: } ! 524: 1.1 root 525: int win32_initciolib(long inmode) 526: { 527: DWORD conmode; 528: int i,j; 529: HANDLE h; 530: CONSOLE_SCREEN_BUFFER_INFO sbuff; 531: 1.1.1.2 ! root 532: dprintf("win32_initciolib(%u)", inmode); 1.1 root 533: if(!isatty(fileno(stdin))) { 534: if(!AllocConsole()) 535: return(0); 536: } 537: 1.1.1.2 ! root 538: SetConsoleCtrlHandler(ControlHandler,TRUE); 1.1 root 539: if((h=GetStdHandle(STD_INPUT_HANDLE))==INVALID_HANDLE_VALUE 540: || !GetConsoleMode(h, &orig_in_conmode)) 541: return(0); 1.1.1.2 ! root 542: conmode=ENABLE_MOUSE_INPUT|ENABLE_EXTENDED_FLAGS; 1.1 root 543: if(!SetConsoleMode(h, conmode)) 544: return(0); 545: 546: if((h=GetStdHandle(STD_OUTPUT_HANDLE))==INVALID_HANDLE_VALUE 547: || !GetConsoleMode(h, &orig_out_conmode)) 548: return(0); 549: conmode=orig_out_conmode; 550: conmode&=~ENABLE_PROCESSED_OUTPUT; 551: conmode&=~ENABLE_WRAP_AT_EOL_OUTPUT; 552: if(!SetConsoleMode(h, conmode)) 553: return(0); 554: 555: if(GetConsoleScreenBufferInfo(h, &sbuff)==0) { 556: win32_textmode(C80); 557: } 558: else { 559: /* Switch to closest mode to current screen size */ 560: i=sbuff.srWindow.Right-sbuff.srWindow.Left+1; 561: j=sbuff.srWindow.Bottom-sbuff.srWindow.Top+1; 1.1.1.2 ! root 562: if(i>=132) { ! 563: if(j<25) ! 564: win32_textmode(VESA_132X21); ! 565: else if(j<28) ! 566: win32_textmode(VESA_132X25); ! 567: else if(j<30) ! 568: win32_textmode(VESA_132X28); ! 569: else if(j<34) ! 570: win32_textmode(VESA_132X30); ! 571: else if(j<43) ! 572: win32_textmode(VESA_132X34); ! 573: else if(j<50) ! 574: win32_textmode(VESA_132X43); ! 575: else if(j<60) ! 576: win32_textmode(VESA_132X50); ! 577: else ! 578: win32_textmode(VESA_132X60); ! 579: } ! 580: else if(i>=80) { 1.1 root 581: if(j<21) 582: win32_textmode(C80X14); 583: else if(j<25) 584: win32_textmode(C80X21); 585: else if(j<28) 586: win32_textmode(C80); 587: else if(j<43) 588: win32_textmode(C80X28); 589: else if(j<50) 590: win32_textmode(C80X43); 591: else if(j<60) 592: win32_textmode(C80X50); 593: else 594: win32_textmode(C80X60); 595: } 596: else { 597: if(j<21) 598: win32_textmode(C40X14); 599: else if(j<25) 600: win32_textmode(C40X21); 601: else if(j<28) 602: win32_textmode(C40); 603: else if(j<43) 604: win32_textmode(C40X28); 605: else if(j<50) 606: win32_textmode(C40X43); 607: else if(j<60) 608: win32_textmode(C40X50); 609: else 610: win32_textmode(C40X60); 611: } 612: } 613: 1.1.1.2 ! root 614: NT_GetConsoleDisplayMode(&orig_display_mode); ! 615: if(inmode==CIOLIB_MODE_CONIO_FULLSCREEN) { ! 616: NT_SetConsoleDisplayMode(h,CONSOLE_FULLSCREEN_MODE); ! 617: atexit(RestoreDisplayMode); ! 618: } 1.1 root 619: cio_api.mouse=1; 620: return(1); 621: } 622: 623: int win32_hidemouse(void) 624: { 625: /* domouse=0; */ 626: return(0); 627: } 628: 629: int win32_showmouse(void) 630: { 631: /* domouse=1; */ 632: return(0); 633: } 634: 635: void win32_textmode(int mode) 636: { 637: int i; 638: HANDLE h; 639: COORD sz; 640: SMALL_RECT rc; 641: 642: for(i=0;i<NUMMODES;i++) { 643: if(vparams[i].mode==mode) 644: modeidx=i; 645: } 646: sz.X=vparams[modeidx].cols; 647: sz.Y=vparams[modeidx].rows; 648: rc.Left=0; 649: rc.Right=vparams[modeidx].cols-1; 650: rc.Top=0; 651: rc.Bottom=vparams[modeidx].rows-1; 652: 653: if((h=GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE) { 654: SetConsoleScreenBufferSize(h,sz); 655: SetConsoleWindowInfo(h,TRUE,&rc); 656: SetConsoleScreenBufferSize(h,sz); 657: } 1.1.1.2 ! root 658: ! 659: cio_textinfo.attribute=7; ! 660: cio_textinfo.normattr=7; ! 661: cio_textinfo.currmode=vparams[modeidx].mode; ! 662: cio_textinfo.screenheight=(unsigned char)sz.Y; ! 663: cio_textinfo.screenwidth=(unsigned char)sz.X; ! 664: cio_textinfo.curx=1; ! 665: cio_textinfo.cury=1; ! 666: cio_textinfo.winleft=1; ! 667: cio_textinfo.wintop=1; ! 668: cio_textinfo.winright=cio_textinfo.screenwidth; ! 669: cio_textinfo.winbottom=cio_textinfo.screenheight; 1.1 root 670: } 671: 672: int win32_gettext(int left, int top, int right, int bottom, void* buf) 673: { 674: CHAR_INFO *ci; 675: int x; 676: int y; 677: COORD bs; 678: COORD bc; 679: HANDLE h; 680: SMALL_RECT reg; 681: unsigned char *bu; 682: 683: bu=buf; 684: bs.X=right-left+1; 685: bs.Y=bottom-top+1; 686: bc.X=0; 687: bc.Y=0; 688: reg.Left=left-1; 689: reg.Right=right-1; 690: reg.Top=top-1; 691: reg.Bottom=bottom-1; 692: ci=(CHAR_INFO *)alloca(sizeof(CHAR_INFO)*(bs.X*bs.Y)); 693: if((h=GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE) 694: ReadConsoleOutput(h,ci,bs,bc,®); 695: for(y=0;y<=(bottom-top);y++) { 696: for(x=0;x<=(right-left);x++) { 697: bu[((y*bs.X)+x)*2]=ci[(y*bs.X)+x].Char.AsciiChar; 698: bu[(((y*bs.X)+x)*2)+1]=WintoDOSAttr(ci[(y*bs.X)+x].Attributes); 699: } 700: } 701: return 1; 702: } 703: 704: void win32_gotoxy(int x, int y) 705: { 706: COORD cp; 707: HANDLE h; 1.1.1.2 ! root 708: static int curx=-1; ! 709: static int cury=-1; 1.1 root 710: 1.1.1.2 ! root 711: cio_textinfo.curx=x; ! 712: cio_textinfo.cury=y; ! 713: cp.X=cio_textinfo.winleft+x-2; ! 714: cp.Y=cio_textinfo.wintop+y-2; ! 715: if(cp.X != curx || cp.Y != cury) { ! 716: if(!hold_update && (h=GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE) { ! 717: SetConsoleCursorPosition(h,cp); ! 718: curx=cp.X; ! 719: cury=cp.Y; ! 720: } ! 721: } 1.1 root 722: } 723: 724: int win32_puttext(int left, int top, int right, int bottom, void* buf) 725: { 726: CHAR_INFO *ci; 727: int x; 728: int y; 729: HANDLE h; 730: COORD bs; 731: COORD bc; 732: SMALL_RECT reg; 733: unsigned char *bu; 734: 735: bu=buf; 736: bs.X=right-left+1; 737: bs.Y=bottom-top+1; 738: bc.X=0; 739: bc.Y=0; 740: reg.Left=left-1; 741: reg.Right=right-1; 742: reg.Top=top-1; 743: reg.Bottom=bottom-1; 744: ci=(CHAR_INFO *)alloca(sizeof(CHAR_INFO)*(bs.X*bs.Y)); 745: for(y=0;y<bs.Y;y++) { 746: for(x=0;x<bs.X;x++) { 747: ci[(y*bs.X)+x].Char.AsciiChar=bu[((y*bs.X)+x)*2]; 748: ci[(y*bs.X)+x].Attributes=DOStoWinAttr(bu[(((y*bs.X)+x)*2)+1]); 749: } 750: } 751: if((h=GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE) 752: WriteConsoleOutput(h,ci,bs,bc,®); 753: return 1; 754: } 755: 756: void win32_setcursortype(int type) 757: { 758: HANDLE h; 759: CONSOLE_CURSOR_INFO ci; 760: 761: switch(type) { 762: case _NOCURSOR: 763: ci.bVisible=FALSE; 764: ci.dwSize=1; 765: break; 766: 767: case _SOLIDCURSOR: 768: ci.bVisible=TRUE; 769: ci.dwSize=99; 770: break; 771: 772: default: /* Normal cursor */ 773: ci.bVisible=TRUE; 774: ci.dwSize=13; 775: break; 776: } 777: if((h=GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE) 778: SetConsoleCursorInfo(h,&ci); 779: } 780: 781: void win32_settitle(const char *title) 782: { 783: SetConsoleTitle(title); 784: } 785: 786: void win32_copytext(const char *text, size_t buflen) 787: { 788: HGLOBAL clipbuf; 789: LPTSTR clip; 790: 791: if(!OpenClipboard(NULL)) 792: return; 793: EmptyClipboard(); 794: clipbuf=GlobalAlloc(GMEM_MOVEABLE, buflen+1); 795: if(clipbuf==NULL) { 796: CloseClipboard(); 797: return; 798: } 799: clip=GlobalLock(clipbuf); 800: memcpy(clip, text, buflen); 801: clip[buflen]=0; 802: GlobalUnlock(clipbuf); 803: SetClipboardData(CF_OEMTEXT, clipbuf); 804: CloseClipboard(); 805: } 806: 807: char *win32_getcliptext(void) 808: { 809: HGLOBAL clipbuf; 810: LPTSTR clip; 811: char *ret; 812: 813: if(!IsClipboardFormatAvailable(CF_OEMTEXT)) 814: return(NULL); 815: if(!OpenClipboard(NULL)) 816: return(NULL); 817: clipbuf=GetClipboardData(CF_OEMTEXT); 818: if(clipbuf!=NULL) { 819: clip=GlobalLock(clipbuf); 820: ret=(char *)malloc(strlen(clip)+1); 821: if(ret != NULL) 822: strcpy(ret, clip); 823: GlobalUnlock(clipbuf); 824: } 825: CloseClipboard(); 826: 827: return(ret); 828: } 829: 1.1.1.2 ! root 830: void win32_getcustomcursor(int *s, int *e, int *r, int *b, int *v) 1.1 root 831: { 1.1.1.2 ! root 832: CONSOLE_CURSOR_INFO ci; ! 833: HANDLE h; ! 834: ! 835: if((h=GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) ! 836: return; ! 837: ! 838: GetConsoleCursorInfo(h, &ci); ! 839: if(s) ! 840: *s=100-ci.dwSize; ! 841: if(e) ! 842: *e=99; ! 843: if(r) ! 844: *r=100; ! 845: if(b) ! 846: *b=1; ! 847: if(v) ! 848: *v=ci.bVisible?1:0; ! 849: } ! 850: ! 851: void win32_setcustomcursor(int s, int e, int r, int b, int v) ! 852: { ! 853: CONSOLE_CURSOR_INFO ci; ! 854: HANDLE h; ! 855: ! 856: if((h=GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) ! 857: return; ! 858: ! 859: ci.bVisible=v; ! 860: if(e>s) ! 861: ci.bVisible=0; ! 862: else { ! 863: if(r>0) ! 864: ci.dwSize=(1+e-s)/r; ! 865: else ! 866: ci.dwSize=100; ! 867: } ! 868: } ! 869: ! 870: int win32_getvideoflags(void) ! 871: { ! 872: DWORD mode; ! 873: ! 874: if(!NT_GetConsoleDisplayMode(&mode)) ! 875: return(CIOLIB_VIDEO_BGBRIGHT); ! 876: if(mode==CONSOLE_FULLSCREEN_MODE) ! 877: return(0); ! 878: return(CIOLIB_VIDEO_BGBRIGHT); 1.1 root 879: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.