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