From c110d51c2f1df0407515223236ac1e5310b04097 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Tue, 19 Jun 2007 16:49:46 +0000 Subject: Handle terminal resize on Windows (brute force; Windows has fascinatingly stupid ideas of when the terminal is actually resized). git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1604 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/acr.cc | 5 +- crawl-ref/source/externs.h | 13 +- crawl-ref/source/libunix.cc | 2 +- crawl-ref/source/libw32c.cc | 950 +++++++++++++++++++++----------------------- 4 files changed, 471 insertions(+), 499 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 2c6ab89b92..022c264ec7 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -912,6 +912,7 @@ static void input() return; } + crawl_state.check_term_size(); if (crawl_state.terminal_resized) handle_terminal_resize(); @@ -921,9 +922,9 @@ static void input() // shouldn't need to turn it on explicitly. cursor_control con(true); - crawl_state.waiting_for_comand = true; + crawl_state.waiting_for_command = true; command_type cmd = get_next_cmd(); - crawl_state.waiting_for_comand = false; + crawl_state.waiting_for_command = false; // [dshaligram] If get_next_cmd encountered a Lua macro // binding, your turn may be ended by the first invoke of the diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 0ba69fd04d..9271c72dea 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -1185,7 +1185,7 @@ extern struct crawl_environment env; // Track various aspects of Crawl game state. struct game_state { - bool waiting_for_comand; // True when the game is waiting for a command. + bool waiting_for_command; // True when the game is waiting for a command. bool terminal_resized; // True if the term was resized and we need to // take action to handle it. @@ -1202,14 +1202,21 @@ struct game_state std::string (*glyph2strfn)(unsigned glyph); int (*multibyte_strlen)(const std::string &s); void (*terminal_resize_handler)(); + void (*terminal_resize_check)(); - game_state() : waiting_for_comand(false), terminal_resized(false), + game_state() : waiting_for_command(false), terminal_resized(false), io_inited(false), need_save(false), saving_game(false), updating_scores(false), shopping(false), seen_hups(0), unicode_ok(false), glyph2strfn(NULL), multibyte_strlen(NULL), - terminal_resize_handler(NULL) + terminal_resize_handler(NULL), terminal_resize_check(NULL) { } + + void check_term_size() const + { + if (terminal_resize_check) + (*terminal_resize_check)(); + } }; extern game_state crawl_state; diff --git a/crawl-ref/source/libunix.cc b/crawl-ref/source/libunix.cc index 27f6233cbc..7af2b38f3e 100644 --- a/crawl-ref/source/libunix.cc +++ b/crawl-ref/source/libunix.cc @@ -251,7 +251,7 @@ int getch_ck() static void handle_sigwinch(int) { - if (crawl_state.waiting_for_comand) + if (crawl_state.waiting_for_command) handle_terminal_resize(); } diff --git a/crawl-ref/source/libw32c.cc b/crawl-ref/source/libw32c.cc index b89e6cef28..015b2b7e34 100644 --- a/crawl-ref/source/libw32c.cc +++ b/crawl-ref/source/libw32c.cc @@ -128,128 +128,55 @@ static DWORD crawlColorData[16] = }; */ -//#define TIMING_INFO -#ifdef TIMING_INFO - -#include -#include "message.h" - -// TIMING info -static int ncalls[6] = { 0,0,0,0,0,0 }; -static double runavg[6] = { 0.0,0.0,0.0,0.0,0.0,0.0 }; -static int oob[6] = { 0,0,0,0,0,0 }; -static int dlen[6] = { 0,0,0,0,0,0 }; -static LARGE_INTEGER t1, t2; - -static void addcall(int i, LARGE_INTEGER &tm1, LARGE_INTEGER &tm2) +void writeChar(char c) { - double d = tm2.QuadPart - tm1.QuadPart; + bool noop = true; + PCHAR_INFO pci; - runavg[i] = (runavg[i] * ncalls[i] + d) / (ncalls[i] + 1); - ncalls[i] ++; + // check for CR: noop + if (c == 0x0D) + return; - // oob - if (ncalls[i] > 10) + // check for newline + if (c == 0x0A) { - if (d > 1.4*runavg[i]) - oob[i] ++; - } -} + // must flush current buffer + bFlush(); -#define CLOCKIN {QueryPerformanceCounter(&t1);} -#define CLOCKOUT(x) {QueryPerformanceCounter(&t2); \ - addcall((x), t1, t2);} + // reposition + gotoxy(1, cy+2); -static char *descrip[] = -{ - "bflush:WriteConsoleOutput", - "_setCursorType:SetConsoleCursorInfo", - "gotoxy:SetConsoleCursorPosition", - "textcolor:SetConsoleTextAttribute", - "cprintf:WriteConsole", - "getch:ReadConsoleInput" -}; + return; + } -void print_timings(void) -{ - int i; - char s[100]; + int tc = WIN32COLOR(current_color); + pci = &screen[SCREENINDEX(cx,cy)]; - LARGE_INTEGER cps; - QueryPerformanceFrequency(&cps); + // is this a no-op? + if (pci->Char.AsciiChar != c) + noop = false; + else if (pci->Attributes != tc) + noop = false; - sprintf(s, "Avg (#/oob), CpS = %.1lf", cps.QuadPart); - mpr(s); - for(i=0; i<3; i++) + if (!noop) { - int dl = 0; - if (ncalls[i] > 0) - dl = dlen[i] / ncalls[i]; - sprintf(s, "%-40s %.1f us (%d/%d), avg dlen = %d", descrip[i], - (1000000.0 * runavg[i]) / cps.QuadPart, ncalls[i], oob[i], dl); - mpr(s); + // write the info and update the dirty area + pci->Char.AsciiChar = c; + pci->Attributes = tc; + + if (chy < 0) + chsx = cx; + chy = cy; + chex = cx; + + // if we're not buffering, flush + if (!buffering) + bFlush(); } -} - -#else - -#define CLOCKIN -#define CLOCKOUT(x) - -void print_timings() -{ ; } - -#endif // TIMING INFO - -void writeChar(char c) -{ - bool noop = true; - PCHAR_INFO pci; - - // check for CR: noop - if (c == 0x0D) - return; - - // check for newline - if (c == 0x0A) - { - // must flush current buffer - bFlush(); - - // reposition - gotoxy(1, cy+2); - - return; - } - - int tc = WIN32COLOR(current_color); - pci = &screen[SCREENINDEX(cx,cy)]; - - // is this a no-op? - if (pci->Char.AsciiChar != c) - noop = false; - else if (pci->Attributes != tc) - noop = false; - - if (!noop) - { - // write the info and update the dirty area - pci->Char.AsciiChar = c; - pci->Attributes = tc; - - if (chy < 0) - chsx = cx; - chy = cy; - chex = cx; - - // if we're not buffering, flush - if (!buffering) - bFlush(); - } - // update x position - cx += 1; - if (cx >= screensize.X) cx = screensize.X; + // update x position + cx += 1; + if (cx >= screensize.X) cx = screensize.X; } void enable_smart_cursor(bool cursor) @@ -264,69 +191,68 @@ bool is_smart_cursor_enabled() void bFlush(void) { - COORD source; - SMALL_RECT target; + COORD source; + SMALL_RECT target; - // see if we have a dirty area - if (chy < 0) - return; + // see if we have a dirty area + if (chy < 0) + return; - // set up call - source.X = chsx; - source.Y = chy; + // set up call + source.X = chsx; + source.Y = chy; - target.Left = chsx; - target.Top = chy; - target.Right = chex; - target.Bottom = chy; + target.Left = chsx; + target.Top = chy; + target.Right = chex; + target.Bottom = chy; - CLOCKIN - WriteConsoleOutput(outbuf, screen, screensize, source, &target); - CLOCKOUT(0) + WriteConsoleOutput(outbuf, screen, screensize, source, &target); - chy = -1; + chy = -1; - // if cursor is not NOCURSOR, update screen - if (cursor_is_enabled) - { - COORD xy; - xy.X = cx; - xy.Y = cy; - CLOCKIN - SetConsoleCursorPosition(outbuf, xy); - CLOCKOUT(2) - } + // if cursor is not NOCURSOR, update screen + if (cursor_is_enabled) + { + COORD xy; + xy.X = cx; + xy.Y = cy; + SetConsoleCursorPosition(outbuf, xy); + } } void setStringInput(bool value) { - DWORD inmodes, outmodes; - if (value == TRUE) - { - inmodes = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT; - outmodes = ENABLE_PROCESSED_OUTPUT; - } - else - { - inmodes = 0; - outmodes = 0; - } - - if ( SetConsoleMode( inbuf, inmodes ) == 0) - { - fputs("Error initialising console input mode.", stderr); - exit(0); - } - - if ( SetConsoleMode( outbuf, outmodes ) == 0) - { - fputs("Error initialising console output mode.", stderr); - exit(0); - } - - // now flush it - FlushConsoleInputBuffer( inbuf ); + DWORD inmodes, outmodes; + if (value == TRUE) + { + inmodes = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT + | ENABLE_PROCESSED_INPUT + | ENABLE_MOUSE_INPUT + | ENABLE_WINDOW_INPUT; + outmodes = ENABLE_PROCESSED_OUTPUT; + } + else + { + inmodes = ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT; + outmodes = 0; + } + + if ( SetConsoleMode( inbuf, inmodes ) == 0) + { + fputs("Error initialising console input mode.", stderr); + exit(0); + } + + if ( SetConsoleMode( outbuf, outmodes ) == 0) + { + fputs("Error initialising console output mode.", stderr); + exit(0); + } + + // now flush it + FlushConsoleInputBuffer( inbuf ); } // this apparently only works for Win2K+ and ME+ @@ -350,103 +276,140 @@ static void install_sighandlers() } #endif +static void set_w32_screen_size() +{ + CONSOLE_SCREEN_BUFFER_INFO cinf; + if (::GetConsoleScreenBufferInfo(outbuf, &cinf)) + { + screensize.X = cinf.srWindow.Right - cinf.srWindow.Left + 1; + screensize.Y = cinf.srWindow.Bottom - cinf.srWindow.Top + 1; + } + else + { + screensize.X = 80; + screensize.Y = 25; + } + + if (screen) + { + delete [] screen; + screen = NULL; + } + + screen = new CHAR_INFO[screensize.X * screensize.Y]; + + COORD topleft; + SMALL_RECT used; + topleft.X = topleft.Y = 0; + ::ReadConsoleOutput(outbuf, screen, screensize, topleft, &used); +} + +static void w32_handle_resize_event() +{ + if (crawl_state.waiting_for_command) + handle_terminal_resize(true); + else + crawl_state.terminal_resized = true; +} + +static void w32_check_screen_resize() +{ + CONSOLE_SCREEN_BUFFER_INFO cinf; + if (::GetConsoleScreenBufferInfo(outbuf, &cinf)) + { + if (screensize.X != cinf.srWindow.Right - cinf.srWindow.Left + 1 + || screensize.Y != cinf.srWindow.Bottom - cinf.srWindow.Top + 1) + { + w32_handle_resize_event(); + } + } +} + +static void w32_term_resizer() +{ + set_w32_screen_size(); + crawl_view.init_geometry(); +} + void init_libw32c(void) { - inbuf = GetStdHandle( STD_INPUT_HANDLE ); - outbuf = GetStdHandle( STD_OUTPUT_HANDLE ); + inbuf = GetStdHandle( STD_INPUT_HANDLE ); + outbuf = GetStdHandle( STD_OUTPUT_HANDLE ); - if (inbuf == INVALID_HANDLE_VALUE || outbuf == INVALID_HANDLE_VALUE) - { - fputs("Could not initialise libw32c console support.", stderr); - exit(0); - } + if (inbuf == INVALID_HANDLE_VALUE || outbuf == INVALID_HANDLE_VALUE) + { + fputs("Could not initialise libw32c console support.", stderr); + exit(0); + } - GetConsoleTitle( oldTitle, 78 ); - SetConsoleTitle( CRAWL " " VERSION ); + GetConsoleTitle( oldTitle, 78 ); + SetConsoleTitle( CRAWL " " VERSION ); #ifdef __MINGW32__ - install_sighandlers(); + install_sighandlers(); #endif - init_colors(oldTitle); - - // by default, set string input to false: use char-input only - setStringInput( false ); - if (SetConsoleMode( outbuf, 0 ) == 0) - { - fputs("Error initialising console output mode.", stderr); - exit(0); - } - - // set up screen size - - CONSOLE_SCREEN_BUFFER_INFO cinf; - if (::GetConsoleScreenBufferInfo(outbuf, &cinf)) - { - screensize.X = cinf.srWindow.Right - cinf.srWindow.Left + 1; - screensize.Y = cinf.srWindow.Bottom - cinf.srWindow.Top + 1; - } - else - { - screensize.X = 80; - screensize.Y = 25; - } - - screen = new CHAR_INFO[screensize.X * screensize.Y]; - - // initialise text color - textcolor(DARKGREY); + init_colors(oldTitle); - // initialise cursor to NONE. - _setcursortype_internal(false); + // by default, set string input to false: use char-input only + setStringInput( false ); - // buffering defaults to ON -- very important! - setBuffering(true); + // set up screen size + set_w32_screen_size(); + + // initialise text color + textcolor(DARKGREY); - //DEBUG - //foo = fopen("debug.txt", "w"); + // initialise cursor to NONE. + _setcursortype_internal(false); - // JWM, 06/12/2004: Code page setting, as XP does not use ANSI 437 by - // default. - InputCP = GetConsoleCP(); - OutputCP = GetConsoleOutputCP(); + // buffering defaults to ON -- very important! + setBuffering(true); - // DS: Don't kill Crawl if we can't set the codepage. Windows 95/98/ME don't - // have support for setting the input and output codepage. I'm also not - // convinced we need to set the input codepage at all. - if (InputCP != PREFERRED_CODEPAGE) - SetConsoleCP(PREFERRED_CODEPAGE); + crawl_state.terminal_resize_handler = w32_term_resizer; + crawl_state.terminal_resize_check = w32_check_screen_resize; + + // JWM, 06/12/2004: Code page setting, as XP does not use ANSI 437 by + // default. + InputCP = GetConsoleCP(); + OutputCP = GetConsoleOutputCP(); - if (OutputCP != PREFERRED_CODEPAGE) - SetConsoleOutputCP(PREFERRED_CODEPAGE); + // Don't kill Crawl if we can't set the codepage. Windows 95/98/ME + // don't have support for setting the input and output codepage. + // I'm also not convinced we need to set the input codepage at all. + if (InputCP != PREFERRED_CODEPAGE) + SetConsoleCP(PREFERRED_CODEPAGE); + + if (OutputCP != PREFERRED_CODEPAGE) + SetConsoleOutputCP(PREFERRED_CODEPAGE); } void deinit_libw32c(void) { - // don't do anything if we were never initted - if (inbuf == NULL || outbuf == NULL) - return; + // don't do anything if we were never initted + if (inbuf == NULL || outbuf == NULL) + return; - // JWM, 06/12/2004: Code page stuff. If it was the preferred code page, it - // doesn't need restoring. Shouldn't be an error and too bad if there is. - if (InputCP && InputCP != PREFERRED_CODEPAGE) - SetConsoleCP(InputCP); + // JWM, 06/12/2004: Code page stuff. If it was the preferred code page, it + // doesn't need restoring. Shouldn't be an error and too bad if there is. + if (InputCP && InputCP != PREFERRED_CODEPAGE) + SetConsoleCP(InputCP); - if (OutputCP && OutputCP != PREFERRED_CODEPAGE) - SetConsoleOutputCP(OutputCP); - - // restore console attributes for normal function - setStringInput(true); + if (OutputCP && OutputCP != PREFERRED_CODEPAGE) + SetConsoleOutputCP(OutputCP); - // set cursor and normal textcolor - _setcursortype_internal(true); - textcolor(DARKGREY); + // restore console attributes for normal function + setStringInput(true); - delete [] screen; - screen = NULL; + // set cursor and normal textcolor + _setcursortype_internal(true); + textcolor(DARKGREY); + + delete [] screen; + screen = NULL; - // finally, restore title - SetConsoleTitle( oldTitle ); + // finally, restore title + SetConsoleTitle( oldTitle ); } void set_cursor_enabled(bool enabled) @@ -462,22 +425,20 @@ bool is_cursor_enabled() void _setcursortype_internal(bool curstype) { - CONSOLE_CURSOR_INFO cci; + CONSOLE_CURSOR_INFO cci; - if (curstype == cursor_is_enabled) - return; + if (curstype == cursor_is_enabled) + return; - cci.dwSize = 5; - cci.bVisible = curstype? TRUE : FALSE; - cursor_is_enabled = curstype; - CLOCKIN - SetConsoleCursorInfo( outbuf, &cci ); - CLOCKOUT(1) + cci.dwSize = 5; + cci.bVisible = curstype? TRUE : FALSE; + cursor_is_enabled = curstype; + SetConsoleCursorInfo( outbuf, &cci ); - // now, if we just changed from NOCURSOR to CURSOR, - // actually move screen cursor - if (cursor_is_enabled) - gotoxy(cx+1, cy+1); + // now, if we just changed from NOCURSOR to CURSOR, + // actually move screen cursor + if (cursor_is_enabled) + gotoxy(cx+1, cy+1); } // This will force the cursor down to the next line. @@ -491,65 +452,63 @@ void clear_to_end_of_line() void clrscr(void) { - int x,y; - COORD source; - SMALL_RECT target; + int x,y; + COORD source; + SMALL_RECT target; - PCHAR_INFO pci = screen; + PCHAR_INFO pci = screen; - for(x = 0; x < screensize.X; x++) - { - for(y = 0; y < screensize.Y; y++) - { - pci->Char.AsciiChar = ' '; - pci->Attributes = 0; - pci++; - } - } + for(x = 0; x < screensize.X; x++) + { + for(y = 0; y < screensize.Y; y++) + { + pci->Char.AsciiChar = ' '; + pci->Attributes = 0; + pci++; + } + } - source.X = 0; - source.Y = 0; - target.Left = 0; - target.Top = 0; - target.Right = screensize.X - 1; - target.Bottom = screensize.Y - 1; + source.X = 0; + source.Y = 0; + target.Left = 0; + target.Top = 0; + target.Right = screensize.X - 1; + target.Bottom = screensize.Y - 1; - WriteConsoleOutput(outbuf, screen, screensize, source, &target); + WriteConsoleOutput(outbuf, screen, screensize, source, &target); - // reset cursor to 1,1 for convenience - gotoxy(1,1); + // reset cursor to 1,1 for convenience + gotoxy(1,1); } void gotoxy(int x, int y) { - // always flush on goto - bFlush(); - - // bounds check - if (x < 1) - x = 1; - if (x > screensize.X) - x = screensize.X; - if (y < 1) - y = 1; - if (y > screensize.Y) - y = screensize.Y; - - // change current cursor - cx = x - 1; - cy = y - 1; - - // if cursor is not NOCURSOR, update screen - if (cursor_is_enabled) - { - COORD xy; - xy.X = cx; - xy.Y = cy; - CLOCKIN - if (SetConsoleCursorPosition(outbuf, xy) == 0) - fputs("SetConsoleCursorPosition() failed!", stderr); - CLOCKOUT(2) - } + // always flush on goto + bFlush(); + + // bounds check + if (x < 1) + x = 1; + if (x > screensize.X) + x = screensize.X; + if (y < 1) + y = 1; + if (y > screensize.Y) + y = screensize.Y; + + // change current cursor + cx = x - 1; + cy = y - 1; + + // if cursor is not NOCURSOR, update screen + if (cursor_is_enabled) + { + COORD xy; + xy.X = cx; + xy.Y = cy; + if (SetConsoleCursorPosition(outbuf, xy) == 0) + fputs("SetConsoleCursorPosition() failed!", stderr); + } } void textattr(int c) @@ -559,35 +518,35 @@ void textattr(int c) void textcolor(int c) { - // change current color used to stamp chars - current_color = c; + // change current color used to stamp chars + current_color = c; } void clear_message_window() { - PCHAR_INFO pci = screen + SCREENINDEX(crawl_view.msgp.x - 1, - crawl_view.msgp.y - 1); - for (int x = 0; x < screensize.X; x++) - { - for (int y = 0; y < crawl_view.msgsz.y; y++) - { - pci->Char.AsciiChar = ' '; - pci->Attributes = 0; - pci++; - } - } + PCHAR_INFO pci = screen + SCREENINDEX(crawl_view.msgp.x - 1, + crawl_view.msgp.y - 1); + for (int x = 0; x < screensize.X; x++) + { + for (int y = 0; y < crawl_view.msgsz.y; y++) + { + pci->Char.AsciiChar = ' '; + pci->Attributes = 0; + pci++; + } + } - COORD source; - SMALL_RECT target; + COORD source; + SMALL_RECT target; - source.X = crawl_view.msgp.x - 1; - source.Y = crawl_view.msgp.y - 1; - target.Left = crawl_view.msgp.x - 1; - target.Top = crawl_view.msgp.y - 1; - target.Right = screensize.X - 1; - target.Bottom = screensize.Y - 1; + source.X = crawl_view.msgp.x - 1; + source.Y = crawl_view.msgp.y - 1; + target.Left = crawl_view.msgp.x - 1; + target.Top = crawl_view.msgp.y - 1; + target.Right = screensize.X - 1; + target.Bottom = screensize.Y - 1; - WriteConsoleOutput(outbuf, screen, screensize, source, &target); + WriteConsoleOutput(outbuf, screen, screensize, source, &target); } static void scroll_message_buffer() @@ -645,70 +604,70 @@ void message_out(int which_line, int colour, const char *s, int firstcol, static void cprintf_aux(const char *s) { - // early out -- not initted yet - if (outbuf == NULL) - { - printf(s); - return; - } + // early out -- not initted yet + if (outbuf == NULL) + { + printf(s); + return; + } - // turn buffering ON (temporarily) - bool oldValue = buffering; - setBuffering(true); + // turn buffering ON (temporarily) + bool oldValue = buffering; + setBuffering(true); - // loop through string - char *p = (char *)s; - while(*p) - { - writeChar(*p++); - } + // loop through string + char *p = (char *)s; + while(*p) + { + writeChar(*p++); + } - // reset buffering - setBuffering(oldValue); + // reset buffering + setBuffering(oldValue); - // flush string - bFlush(); + // flush string + bFlush(); } void cprintf(const char *format, ...) { - va_list argp; - char buffer[4096]; // one could hope it's enough + va_list argp; + char buffer[4096]; // one could hope it's enough - va_start( argp, format ); + va_start( argp, format ); - vsprintf(buffer, format, argp); - cprintf_aux(buffer); + vsprintf(buffer, format, argp); + cprintf_aux(buffer); - va_end(argp); + va_end(argp); } void window(int x, int y, int lx, int ly) { - // do nothing - UNUSED( x ); - UNUSED( y ); - UNUSED( lx ); - UNUSED( ly ); + // do nothing + UNUSED( x ); + UNUSED( y ); + UNUSED( lx ); + UNUSED( ly ); } int wherex(void) { - return cx+1; + return cx+1; } int wherey(void) { - return cy+1; + return cy+1; } void putch(char c) { - // special case: check for '0' char: map to space - if (c==0) - c = ' '; + // special case: check for '0' char: map to space + if (c==0) + c = ' '; - writeChar(c); + writeChar(c); } void putwch(unsigned c) @@ -720,7 +679,7 @@ void putwch(unsigned c) #define VKEY_MAPPINGS 10 static int vk_tr[4][VKEY_MAPPINGS] = // virtual key, unmodified, shifted, control - { +{ { VK_END, VK_DOWN, VK_NEXT, VK_LEFT, VK_CLEAR, VK_RIGHT, VK_HOME, VK_UP, VK_PRIOR, VK_INSERT }, { CK_END, CK_DOWN, CK_PGDN, CK_LEFT, CK_CLEAR, CK_RIGHT, CK_HOME, CK_UP, CK_PGUP , CK_INSERT }, { CK_SHIFT_END, CK_SHIFT_DOWN, CK_SHIFT_PGDN, CK_SHIFT_LEFT, CK_SHIFT_CLEAR, CK_SHIFT_RIGHT, CK_SHIFT_HOME, CK_SHIFT_UP, CK_SHIFT_PGUP, CK_SHIFT_INSERT }, @@ -750,71 +709,68 @@ int key_to_command( int keyin ) int vk_translate( WORD VirtCode, CHAR c, DWORD cKeys) { - bool shftDown = false; - bool ctrlDown = false; - bool altDown = !!(cKeys & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)); - - // DEBUG - //fprintf(foo, "Received code %d (%c) with modifiers: %d\n", VirtCode, c, cKeys); - - // step 1 - we don't care about shift or control - if (VirtCode == VK_SHIFT || VirtCode == VK_CONTROL || - VirtCode == VK_MENU || VirtCode == VK_CAPITAL || - VirtCode == VK_NUMLOCK) - return 0; - - // step 2 - translate the key to 0x1b - if (VirtCode == VK_ESCAPE) - return 0x1b; // same as it ever was.. - - // step 3 - translate shifted or controlled numeric keypad keys - if (cKeys & SHIFT_PRESSED) - shftDown = true; - if (cKeys & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) - ctrlDown = true; // control takes precedence over shift - - // hack - translate ^P and ^Q since 16 and 17 are taken by CTRL and SHIFT - if ((VirtCode == 80 || VirtCode == 81) && ctrlDown) - return VirtCode & 0x003f; // shift back down - - if (VirtCode == VK_DELETE && !ctrlDown) // assume keypad '.' - return CK_DELETE; - - // see if we're a vkey - int mkey; - for(mkey = 0; mkey key to 0x1b + if (VirtCode == VK_ESCAPE) + return 0x1b; // same as it ever was.. + + // step 3 - translate shifted or controlled numeric keypad keys + if (cKeys & SHIFT_PRESSED) + shftDown = true; + if (cKeys & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) + ctrlDown = true; // control takes precedence over shift + + // hack - translate ^P and ^Q since 16 and 17 are taken by CTRL and SHIFT + if ((VirtCode == 80 || VirtCode == 81) && ctrlDown) + return VirtCode & 0x003f; // shift back down + + if (VirtCode == VK_DELETE && !ctrlDown) // assume keypad '.' + return CK_DELETE; + + // see if we're a vkey + int mkey; + for(mkey = 0; mkey 0) { - repeat_count -= 1; - return repeat_key; + repeat_count -= 1; + return repeat_key; } const bool oldValue = cursor_is_enabled; if (w32_smart_cursor) _setcursortype_internal(true); - while(1) + bool waiting_for_event = true; + while (waiting_for_event) { - CLOCKIN - if (ReadConsoleInput( inbuf, &ir, 1, &nread) == 0) - fputs("Error in ReadConsoleInput()!", stderr); - CLOCKOUT(5) - if (nread > 0) - { - // ignore if it isn't a keyboard event. - if (ir.EventType == KEY_EVENT) - { - kr = &(ir.Event.KeyEvent); - // ignore if it is a 'key up' - we only want 'key down' - if (kr->bKeyDown == true) - { - key = vk_translate( kr->wVirtualKeyCode, kr->uChar.AsciiChar, kr->dwControlKeyState ); - if (key > 0) + if (ReadConsoleInput( inbuf, &ir, 1, &nread) == 0) + fputs("Error in ReadConsoleInput()!", stderr); + if (nread > 0) + { + // ignore if it isn't a keyboard event. + switch (ir.EventType) + { + case KEY_EVENT: + kr = &(ir.Event.KeyEvent); + // ignore if it is a 'key up' - we only want 'key down' + if (kr->bKeyDown == true) { - repeat_count = kr->wRepeatCount - 1; - repeat_key = key; - break; + key = vk_translate( kr->wVirtualKeyCode, + kr->uChar.AsciiChar, + kr->dwControlKeyState ); + if (key > 0) + { + repeat_count = kr->wRepeatCount - 1; + repeat_key = key; + waiting_for_event = false; + break; + } } - } - } - } + break; + + case WINDOW_BUFFER_SIZE_EVENT: + w32_handle_resize_event(); + break; + } + } } if (w32_smart_cursor) @@ -879,19 +843,19 @@ int getch(void) int getche(void) { - // turn buffering off temporarily - const bool oldValue = buffering; - setBuffering(false); + // turn buffering off temporarily + const bool oldValue = buffering; + setBuffering(false); - int val = getch(); + int val = getch(); - if (val != 0) - putch(val); + if (val != 0) + putch(val); - // restore buffering value - setBuffering(oldValue); + // restore buffering value + setBuffering(oldValue); - return val; + return val; } int kbhit() @@ -916,54 +880,54 @@ int kbhit() void delay(int ms) { - Sleep((DWORD)ms); + Sleep((DWORD)ms); } void textbackground(int c) { - // do nothing - UNUSED( c ); + // do nothing + UNUSED( c ); } int getConsoleString(char *buf, int maxlen) { - DWORD nread; - // set console input to line mode - setStringInput( true ); + DWORD nread; + // set console input to line mode + setStringInput( true ); - // force cursor - const bool oldValue = cursor_is_enabled; + // force cursor + const bool oldValue = cursor_is_enabled; - if (w32_smart_cursor) - _setcursortype_internal(true); + if (w32_smart_cursor) + _setcursortype_internal(true); - // set actual screen color to current color - SetConsoleTextAttribute( outbuf, WIN32COLOR(current_color) ); + // set actual screen color to current color + SetConsoleTextAttribute( outbuf, WIN32COLOR(current_color) ); - if (ReadConsole( inbuf, buf, (DWORD)(maxlen-1), &nread, NULL) == 0) - fputs("Error in ReadConsole()!", stderr); + if (ReadConsole( inbuf, buf, (DWORD)(maxlen-1), &nread, NULL) == 0) + fputs("Error in ReadConsole()!", stderr); - // terminate string, then strip CRLF, replace with \0 - buf[maxlen-1] = 0; - for (unsigned i=(nread<3 ? 0 : nread-3); i