/* MikMod module player (c) 1999 Miodrag Vallat and others - see file AUTHORS for complete list. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*============================================================================== $Id: winvideo.inc,v 1.1.1.1 2004/01/16 02:07:45 raph Exp $ Windows console i/o routines ==============================================================================*/ #include struct SCREEN { WORD act_attr; char *changed; CHAR_INFO *text; SHORT minx,miny,maxx,maxy; } screen = {A_NORMAL, NULL, NULL, 0, 0, 0, 0}; static HANDLE WINAPI GetConHandle (const TCHAR *name) { SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; return CreateFile (name, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, OPEN_EXISTING, (DWORD) 0, (HANDLE) 0); } #define GetConOut() GetConHandle(TEXT("CONOUT$")) #define GetConIn() GetConHandle(TEXT("CONIN$")) static void console_store (BOOL restore) { HANDLE conOut; COORD bufSize, bufOrg; SMALL_RECT srSource; static int oldx = -1, oldy = -1; static CHAR_INFO *screen_content = NULL; if (!restore && (oldx!=winx || oldy!=winy)) { screen_content = (CHAR_INFO *) realloc(screen_content, sizeof(CHAR_INFO)*winx*winy); oldx = winx; oldy = winy; } if (!screen_content) return; conOut = GetConOut(); if (conOut == INVALID_HANDLE_VALUE) return; srSource.Left = screen.minx; srSource.Top = screen.miny; srSource.Right = screen.maxx; srSource.Bottom = screen.maxy; bufSize.X = srSource.Right - srSource.Left + 1; bufSize.Y = srSource.Bottom - srSource.Top + 1; bufOrg.X = 0; bufOrg.Y = 0; if (restore) WriteConsoleOutput (conOut, screen_content, bufSize, bufOrg, &srSource); else ReadConsoleOutput (conOut, screen_content, bufSize, bufOrg, &srSource); CloseHandle (conOut); } static void console_get_size (SHORT *minx, SHORT *miny, SHORT *maxx, SHORT *maxy) { HANDLE conOut; CONSOLE_SCREEN_BUFFER_INFO bufInfo; conOut = GetConOut(); if (conOut != INVALID_HANDLE_VALUE) { if (GetConsoleScreenBufferInfo (conOut, &bufInfo)) { *minx = bufInfo.srWindow.Left; *miny = bufInfo.srWindow.Top; *maxx = bufInfo.srWindow.Right; *maxy = bufInfo.srWindow.Bottom; } CloseHandle (conOut); } } static void screen_alloc (void) { int oldx = screen.maxx-screen.minx+1; int oldy = screen.maxy-screen.miny+1; int x, y; console_get_size (&screen.minx, &screen.miny, &screen.maxx, &screen.maxy); winx = screen.maxx-screen.minx+1; winy = screen.maxy-screen.miny+1; screen.changed = (char *) realloc (screen.changed, winx*winy); screen.text = (CHAR_INFO *) realloc(screen.text, sizeof(CHAR_INFO)*winx*winy); for (y=0; y=winy) return; if (x<0) { str -= x; len += x; x = 0; } d = y*winx+x; for (i=0; iwidth - x; if (len > 0) { memset(storage, ' ', len); mvaddnstr(win->y + y, win->x + x, storage, len); } } void gotoxy (int x, int y) { HANDLE conOut; COORD coord; conOut = GetConOut(); if (conOut != INVALID_HANDLE_VALUE) { coord.X = screen.minx + x; coord.Y = screen.miny + y; SetConsoleCursorPosition (conOut, coord); CloseHandle (conOut); } } void win_cursor_set(BOOL visible) { HANDLE conOut; CONSOLE_CURSOR_INFO cci; conOut = GetConOut(); if (conOut != INVALID_HANDLE_VALUE) { GetConsoleCursorInfo (conOut, &cci); cci.bVisible = visible; SetConsoleCursorInfo (conOut, &cci); CloseHandle (conOut); } } void win_refresh(void) { int x, y, d, start; HANDLE conOut; COORD bufSize, bufOrg; SMALL_RECT srDest; conOut = GetConOut(); if (conOut == INVALID_HANDLE_VALUE) return; for (y=0; y=winx) break; d--; x = start; while (screen.changed[++d] && x 0) { ReadConsoleInputA (conIn, &input, 1, &nread); if (input.EventType == KEY_EVENT && input.Event.KeyEvent.bKeyDown) { KEY_EVENT_RECORD *key = &input.Event.KeyEvent; if (key->uChar.AsciiChar > 0) { ch = key->uChar.AsciiChar; } else { DWORD control = key->dwControlKeyState & ~CAPSLOCK_ON; ch = 0x100 | key->wVirtualScanCode; if (control == SHIFT_PRESSED && (ch >= KEY_F(1) && ch <= KEY_F(10))) { ch = KEY_SF(1) + ch - KEY_F(1); } else if ((control & ENHANCED_KEY) || control == 0) { if (key->wVirtualScanCode == 83) ch = KEY_DC; } else ch = 0; } } else if (input.EventType == WINDOW_BUFFER_SIZE_EVENT) { /* new size: input.Event.WindowBufferSizeEvent.dwSize.{X|Y} */ resize_window(); } GetNumberOfConsoleInputEvents (conIn, &nevents); } CloseHandle (conIn); return ch; }