687 lines
17 KiB
C
687 lines
17 KiB
C
/* PDCurses */
|
|
|
|
#include "pdcwin.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
/* Color component table */
|
|
|
|
PDCCOLOR pdc_color[PDC_MAXCOL];
|
|
|
|
HANDLE std_con_out = INVALID_HANDLE_VALUE;
|
|
HANDLE pdc_con_out = INVALID_HANDLE_VALUE;
|
|
HANDLE pdc_con_in = INVALID_HANDLE_VALUE;
|
|
|
|
DWORD pdc_quick_edit;
|
|
|
|
static short realtocurs[16] =
|
|
{
|
|
COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_RED,
|
|
COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE, COLOR_BLACK + 8,
|
|
COLOR_BLUE + 8, COLOR_GREEN + 8, COLOR_CYAN + 8, COLOR_RED + 8,
|
|
COLOR_MAGENTA + 8, COLOR_YELLOW + 8, COLOR_WHITE + 8
|
|
};
|
|
|
|
static short ansitocurs[16] =
|
|
{
|
|
COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE,
|
|
COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE, COLOR_BLACK + 8,
|
|
COLOR_RED + 8, COLOR_GREEN + 8, COLOR_YELLOW + 8, COLOR_BLUE + 8,
|
|
COLOR_MAGENTA + 8, COLOR_CYAN + 8, COLOR_WHITE + 8
|
|
};
|
|
|
|
short pdc_curstoreal[16], pdc_curstoansi[16];
|
|
short pdc_oldf, pdc_oldb, pdc_oldu;
|
|
bool pdc_conemu, pdc_wt, pdc_ansi;
|
|
|
|
enum { PDC_RESTORE_NONE, PDC_RESTORE_BUFFER };
|
|
|
|
/* Struct for storing console registry keys, and for use with the
|
|
undocumented WM_SETCONSOLEINFO message. Originally by James Brown,
|
|
www.catch22.net. */
|
|
|
|
static struct
|
|
{
|
|
ULONG Length;
|
|
COORD ScreenBufferSize;
|
|
COORD WindowSize;
|
|
ULONG WindowPosX;
|
|
ULONG WindowPosY;
|
|
|
|
COORD FontSize;
|
|
ULONG FontFamily;
|
|
ULONG FontWeight;
|
|
WCHAR FaceName[32];
|
|
|
|
ULONG CursorSize;
|
|
ULONG FullScreen;
|
|
ULONG QuickEdit;
|
|
ULONG AutoPosition;
|
|
ULONG InsertMode;
|
|
|
|
USHORT ScreenColors;
|
|
USHORT PopupColors;
|
|
ULONG HistoryNoDup;
|
|
ULONG HistoryBufferSize;
|
|
ULONG NumberOfHistoryBuffers;
|
|
|
|
COLORREF ColorTable[16];
|
|
|
|
ULONG CodePage;
|
|
HWND Hwnd;
|
|
|
|
WCHAR ConsoleTitle[0x100];
|
|
} console_info;
|
|
|
|
#ifdef HAVE_NO_INFOEX
|
|
/* Console screen buffer information (extended version) */
|
|
typedef struct _CONSOLE_SCREEN_BUFFER_INFOEX {
|
|
ULONG cbSize;
|
|
COORD dwSize;
|
|
COORD dwCursorPosition;
|
|
WORD wAttributes;
|
|
SMALL_RECT srWindow;
|
|
COORD dwMaximumWindowSize;
|
|
WORD wPopupAttributes;
|
|
BOOL bFullscreenSupported;
|
|
COLORREF ColorTable[16];
|
|
} CONSOLE_SCREEN_BUFFER_INFOEX;
|
|
typedef CONSOLE_SCREEN_BUFFER_INFOEX *PCONSOLE_SCREEN_BUFFER_INFOEX;
|
|
#endif
|
|
|
|
typedef BOOL (WINAPI *SetConsoleScreenBufferInfoExFn)(HANDLE hConsoleOutput,
|
|
PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx);
|
|
typedef BOOL (WINAPI *GetConsoleScreenBufferInfoExFn)(HANDLE hConsoleOutput,
|
|
PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx);
|
|
|
|
static SetConsoleScreenBufferInfoExFn pSetConsoleScreenBufferInfoEx = NULL;
|
|
static GetConsoleScreenBufferInfoExFn pGetConsoleScreenBufferInfoEx = NULL;
|
|
|
|
static CONSOLE_SCREEN_BUFFER_INFO orig_scr;
|
|
static CONSOLE_SCREEN_BUFFER_INFOEX console_infoex;
|
|
|
|
static LPTOP_LEVEL_EXCEPTION_FILTER xcpt_filter;
|
|
|
|
static DWORD old_console_mode = 0;
|
|
|
|
static bool is_nt;
|
|
|
|
static void _reset_old_colors(void)
|
|
{
|
|
pdc_oldf = -1;
|
|
pdc_oldb = -1;
|
|
pdc_oldu = 0;
|
|
}
|
|
|
|
static HWND _find_console_handle(void)
|
|
{
|
|
TCHAR orgtitle[1024], temptitle[1024];
|
|
HWND wnd;
|
|
|
|
GetConsoleTitle(orgtitle, 1024);
|
|
|
|
wsprintf(temptitle, TEXT("%d/%d"), GetTickCount(), GetCurrentProcessId());
|
|
SetConsoleTitle(temptitle);
|
|
|
|
Sleep(40);
|
|
|
|
wnd = FindWindow(NULL, temptitle);
|
|
|
|
SetConsoleTitle(orgtitle);
|
|
|
|
return wnd;
|
|
}
|
|
|
|
/* Undocumented console message */
|
|
|
|
#define WM_SETCONSOLEINFO (WM_USER + 201)
|
|
|
|
/* Wrapper around WM_SETCONSOLEINFO. We need to create the necessary
|
|
section (file-mapping) object in the context of the process which
|
|
owns the console, before posting the message. Originally by JB. */
|
|
|
|
static void _set_console_info(void)
|
|
{
|
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
|
CONSOLE_CURSOR_INFO cci;
|
|
DWORD dwConsoleOwnerPid;
|
|
HANDLE hProcess;
|
|
HANDLE hSection, hDupSection;
|
|
PVOID ptrView;
|
|
|
|
/* Each-time initialization for console_info */
|
|
|
|
GetConsoleCursorInfo(pdc_con_out, &cci);
|
|
console_info.CursorSize = cci.dwSize;
|
|
|
|
GetConsoleScreenBufferInfo(pdc_con_out, &csbi);
|
|
console_info.ScreenBufferSize = csbi.dwSize;
|
|
|
|
console_info.WindowSize.X = csbi.srWindow.Right - csbi.srWindow.Left + 1;
|
|
console_info.WindowSize.Y = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
|
|
|
|
console_info.WindowPosX = csbi.srWindow.Left;
|
|
console_info.WindowPosY = csbi.srWindow.Top;
|
|
|
|
/* Open the process which "owns" the console */
|
|
|
|
GetWindowThreadProcessId(console_info.Hwnd, &dwConsoleOwnerPid);
|
|
|
|
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwConsoleOwnerPid);
|
|
|
|
/* Create a SECTION object backed by page-file, then map a view of
|
|
this section into the owner process so we can write the contents
|
|
of the CONSOLE_INFO buffer into it */
|
|
|
|
hSection = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE,
|
|
0, sizeof(console_info), 0);
|
|
|
|
/* Copy our console structure into the section-object */
|
|
|
|
ptrView = MapViewOfFile(hSection, FILE_MAP_WRITE|FILE_MAP_READ,
|
|
0, 0, sizeof(console_info));
|
|
|
|
memcpy(ptrView, &console_info, sizeof(console_info));
|
|
|
|
UnmapViewOfFile(ptrView);
|
|
|
|
/* Map the memory into owner process */
|
|
|
|
DuplicateHandle(GetCurrentProcess(), hSection, hProcess, &hDupSection,
|
|
0, FALSE, DUPLICATE_SAME_ACCESS);
|
|
|
|
/* Send console window the "update" message */
|
|
|
|
SendMessage(console_info.Hwnd, WM_SETCONSOLEINFO, (WPARAM)hDupSection, 0);
|
|
|
|
CloseHandle(hSection);
|
|
CloseHandle(hProcess);
|
|
}
|
|
|
|
static int _set_console_infoex(void)
|
|
{
|
|
if (!pSetConsoleScreenBufferInfoEx(pdc_con_out, &console_infoex))
|
|
return ERR;
|
|
|
|
return OK;
|
|
}
|
|
|
|
static int _set_colors(void)
|
|
{
|
|
SetConsoleTextAttribute(pdc_con_out, 7);
|
|
_reset_old_colors();
|
|
|
|
if (pSetConsoleScreenBufferInfoEx)
|
|
return _set_console_infoex();
|
|
else
|
|
{
|
|
_set_console_info();
|
|
return OK;
|
|
}
|
|
}
|
|
|
|
/* One-time initialization for console_info -- color table and font info
|
|
from the registry; other values from functions. */
|
|
|
|
static void _init_console_info(void)
|
|
{
|
|
DWORD scrnmode, len;
|
|
HKEY reghnd;
|
|
int i;
|
|
|
|
console_info.Hwnd = _find_console_handle();
|
|
console_info.Length = sizeof(console_info);
|
|
|
|
GetConsoleMode(pdc_con_in, &scrnmode);
|
|
console_info.QuickEdit = !!(scrnmode & 0x0040);
|
|
console_info.InsertMode = !!(scrnmode & 0x0020);
|
|
|
|
console_info.FullScreen = FALSE;
|
|
console_info.AutoPosition = 0x10000;
|
|
console_info.ScreenColors = SP->orig_back << 4 | SP->orig_fore;
|
|
console_info.PopupColors = 0xf5;
|
|
|
|
console_info.HistoryNoDup = FALSE;
|
|
console_info.HistoryBufferSize = 50;
|
|
console_info.NumberOfHistoryBuffers = 4;
|
|
|
|
console_info.CodePage = GetConsoleOutputCP();
|
|
|
|
RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Console"), 0,
|
|
KEY_QUERY_VALUE, ®hnd);
|
|
|
|
len = sizeof(DWORD);
|
|
|
|
/* Default color table */
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
char tname[13];
|
|
|
|
sprintf(tname, "ColorTable%02d", i);
|
|
RegQueryValueExA(reghnd, tname, NULL, NULL,
|
|
(LPBYTE)(&(console_info.ColorTable[i])), &len);
|
|
}
|
|
|
|
/* Font info */
|
|
|
|
RegQueryValueEx(reghnd, TEXT("FontSize"), NULL, NULL,
|
|
(LPBYTE)(&console_info.FontSize), &len);
|
|
RegQueryValueEx(reghnd, TEXT("FontFamily"), NULL, NULL,
|
|
(LPBYTE)(&console_info.FontFamily), &len);
|
|
RegQueryValueEx(reghnd, TEXT("FontWeight"), NULL, NULL,
|
|
(LPBYTE)(&console_info.FontWeight), &len);
|
|
|
|
len = sizeof(WCHAR) * 32;
|
|
RegQueryValueExW(reghnd, L"FaceName", NULL, NULL,
|
|
(LPBYTE)(console_info.FaceName), &len);
|
|
|
|
RegCloseKey(reghnd);
|
|
}
|
|
|
|
static int _init_console_infoex(void)
|
|
{
|
|
console_infoex.cbSize = sizeof(console_infoex);
|
|
|
|
if (!pGetConsoleScreenBufferInfoEx(pdc_con_out, &console_infoex))
|
|
return ERR;
|
|
|
|
console_infoex.srWindow.Right++;
|
|
console_infoex.srWindow.Bottom++;
|
|
|
|
return OK;
|
|
}
|
|
|
|
static COLORREF *_get_colors(void)
|
|
{
|
|
if (pGetConsoleScreenBufferInfoEx)
|
|
{
|
|
int status = OK;
|
|
if (!console_infoex.cbSize)
|
|
status = _init_console_infoex();
|
|
return (status == ERR) ? NULL :
|
|
(COLORREF *)(&(console_infoex.ColorTable));
|
|
}
|
|
else
|
|
{
|
|
if (!console_info.Hwnd)
|
|
_init_console_info();
|
|
return (COLORREF *)(&(console_info.ColorTable));
|
|
}
|
|
}
|
|
|
|
/* restore the original console buffer in the event of a crash */
|
|
|
|
static LONG WINAPI _restore_console(LPEXCEPTION_POINTERS ep)
|
|
{
|
|
PDC_scr_close();
|
|
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
|
|
/* restore the original console buffer on Ctrl+Break (or Ctrl+C,
|
|
if it gets re-enabled) */
|
|
|
|
static BOOL WINAPI _ctrl_break(DWORD dwCtrlType)
|
|
{
|
|
if (dwCtrlType == CTRL_BREAK_EVENT || dwCtrlType == CTRL_C_EVENT)
|
|
PDC_scr_close();
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/* close the physical screen -- may restore the screen to its state
|
|
before PDC_scr_open(); miscellaneous cleanup */
|
|
|
|
void PDC_scr_close(void)
|
|
{
|
|
PDC_LOG(("PDC_scr_close() - called\n"));
|
|
|
|
if (SP->visibility != 1)
|
|
curs_set(1);
|
|
|
|
PDC_reset_shell_mode();
|
|
|
|
/* Position cursor to the bottom left of the screen. */
|
|
|
|
if (SP->_restore == PDC_RESTORE_NONE)
|
|
{
|
|
SMALL_RECT win;
|
|
|
|
win.Left = orig_scr.srWindow.Left;
|
|
win.Right = orig_scr.srWindow.Right;
|
|
win.Top = 0;
|
|
win.Bottom = orig_scr.srWindow.Bottom - orig_scr.srWindow.Top;
|
|
SetConsoleWindowInfo(pdc_con_out, TRUE, &win);
|
|
PDC_gotoyx(win.Bottom, 0);
|
|
}
|
|
}
|
|
|
|
void PDC_scr_free(void)
|
|
{
|
|
if (pdc_con_out != std_con_out)
|
|
{
|
|
CloseHandle(pdc_con_out);
|
|
pdc_con_out = std_con_out;
|
|
}
|
|
|
|
SetUnhandledExceptionFilter(xcpt_filter);
|
|
SetConsoleCtrlHandler(_ctrl_break, FALSE);
|
|
}
|
|
|
|
/* open the physical screen -- miscellaneous initialization, may save
|
|
the existing screen for later restoration */
|
|
|
|
int PDC_scr_open(void)
|
|
{
|
|
const char *str;
|
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
|
HMODULE h_kernel;
|
|
BOOL result;
|
|
int i;
|
|
|
|
PDC_LOG(("PDC_scr_open() - called\n"));
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
pdc_curstoreal[realtocurs[i]] = i;
|
|
pdc_curstoansi[ansitocurs[i]] = i;
|
|
}
|
|
_reset_old_colors();
|
|
|
|
std_con_out =
|
|
pdc_con_out = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
pdc_con_in = GetStdHandle(STD_INPUT_HANDLE);
|
|
|
|
if (GetFileType(pdc_con_in) != FILE_TYPE_CHAR)
|
|
{
|
|
fprintf(stderr, "\nRedirection is not supported.\n");
|
|
exit(1);
|
|
}
|
|
|
|
is_nt = !(GetVersion() & 0x80000000);
|
|
|
|
pdc_wt = !!getenv("WT_SESSION");
|
|
str = pdc_wt ? NULL : getenv("ConEmuANSI");
|
|
pdc_conemu = !!str;
|
|
pdc_ansi = pdc_wt ? TRUE : pdc_conemu ? !strcmp(str, "ON") : FALSE;
|
|
|
|
GetConsoleScreenBufferInfo(pdc_con_out, &csbi);
|
|
GetConsoleScreenBufferInfo(pdc_con_out, &orig_scr);
|
|
GetConsoleMode(pdc_con_in, &old_console_mode);
|
|
|
|
/* preserve QuickEdit Mode setting for use in PDC_mouse_set() when
|
|
the mouse is not enabled -- other console input settings are
|
|
cleared */
|
|
|
|
pdc_quick_edit = old_console_mode & 0x0040;
|
|
|
|
SP->mouse_wait = PDC_CLICK_PERIOD;
|
|
SP->audible = TRUE;
|
|
|
|
SP->termattrs = A_COLOR | A_REVERSE;
|
|
if (pdc_ansi)
|
|
SP->termattrs |= A_UNDERLINE | A_ITALIC;
|
|
|
|
SP->orig_fore = csbi.wAttributes & 0x0f;
|
|
SP->orig_back = (csbi.wAttributes & 0xf0) >> 4;
|
|
|
|
SP->orig_attr = TRUE;
|
|
|
|
SP->_restore = PDC_RESTORE_NONE;
|
|
|
|
if ((str = getenv("PDC_RESTORE_SCREEN")) == NULL || *str != '0')
|
|
{
|
|
/* Create a new console buffer */
|
|
|
|
pdc_con_out =
|
|
CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
|
|
|
|
if (pdc_con_out == INVALID_HANDLE_VALUE)
|
|
{
|
|
PDC_LOG(("PDC_scr_open() - screen buffer failure\n"));
|
|
|
|
pdc_con_out = std_con_out;
|
|
}
|
|
else
|
|
SP->_restore = PDC_RESTORE_BUFFER;
|
|
}
|
|
|
|
xcpt_filter = SetUnhandledExceptionFilter(_restore_console);
|
|
SetConsoleCtrlHandler(_ctrl_break, TRUE);
|
|
|
|
SP->_preserve = (getenv("PDC_PRESERVE_SCREEN") != NULL);
|
|
|
|
/* ENABLE_LVB_GRID_WORLDWIDE */
|
|
result = SetConsoleMode(pdc_con_out, 0x0010);
|
|
if (result)
|
|
SP->termattrs |= A_UNDERLINE | A_LEFT | A_RIGHT;
|
|
|
|
PDC_reset_prog_mode();
|
|
|
|
SP->mono = FALSE;
|
|
|
|
h_kernel = GetModuleHandleA("kernel32.dll");
|
|
pGetConsoleScreenBufferInfoEx =
|
|
(GetConsoleScreenBufferInfoExFn)GetProcAddress(h_kernel,
|
|
"GetConsoleScreenBufferInfoEx");
|
|
pSetConsoleScreenBufferInfoEx =
|
|
(SetConsoleScreenBufferInfoExFn)GetProcAddress(h_kernel,
|
|
"SetConsoleScreenBufferInfoEx");
|
|
|
|
return OK;
|
|
}
|
|
|
|
/* Calls SetConsoleWindowInfo with the given parameters, but fits them
|
|
if a scoll bar shrinks the maximum possible value. The rectangle
|
|
must at least fit in a half-sized window. */
|
|
|
|
static BOOL _fit_console_window(HANDLE con_out, CONST SMALL_RECT *rect)
|
|
{
|
|
SMALL_RECT run;
|
|
SHORT mx, my;
|
|
|
|
if (SetConsoleWindowInfo(con_out, TRUE, rect))
|
|
return TRUE;
|
|
|
|
run = *rect;
|
|
run.Right /= 2;
|
|
run.Bottom /= 2;
|
|
|
|
mx = run.Right;
|
|
my = run.Bottom;
|
|
|
|
if (!SetConsoleWindowInfo(con_out, TRUE, &run))
|
|
return FALSE;
|
|
|
|
for (run.Right = rect->Right; run.Right >= mx; run.Right--)
|
|
if (SetConsoleWindowInfo(con_out, TRUE, &run))
|
|
break;
|
|
|
|
if (run.Right < mx)
|
|
return FALSE;
|
|
|
|
for (run.Bottom = rect->Bottom; run.Bottom >= my; run.Bottom--)
|
|
if (SetConsoleWindowInfo(con_out, TRUE, &run))
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/* the core of resize_term() */
|
|
|
|
int PDC_resize_screen(int nlines, int ncols)
|
|
{
|
|
SMALL_RECT rect;
|
|
COORD size, max;
|
|
|
|
bool prog_resize = nlines || ncols;
|
|
|
|
if (!prog_resize)
|
|
{
|
|
nlines = PDC_get_rows();
|
|
ncols = PDC_get_columns();
|
|
}
|
|
|
|
if (nlines < 2 || ncols < 2)
|
|
return ERR;
|
|
|
|
max = GetLargestConsoleWindowSize(pdc_con_out);
|
|
|
|
rect.Left = rect.Top = 0;
|
|
rect.Right = ncols - 1;
|
|
|
|
if (rect.Right > max.X)
|
|
rect.Right = max.X;
|
|
|
|
rect.Bottom = nlines - 1;
|
|
|
|
if (rect.Bottom > max.Y)
|
|
rect.Bottom = max.Y;
|
|
|
|
size.X = rect.Right + 1;
|
|
size.Y = rect.Bottom + 1;
|
|
|
|
_fit_console_window(pdc_con_out, &rect);
|
|
SetConsoleScreenBufferSize(pdc_con_out, size);
|
|
|
|
if (prog_resize)
|
|
{
|
|
_fit_console_window(pdc_con_out, &rect);
|
|
SetConsoleScreenBufferSize(pdc_con_out, size);
|
|
}
|
|
SetConsoleActiveScreenBuffer(pdc_con_out);
|
|
|
|
PDC_flushinp();
|
|
|
|
return OK;
|
|
}
|
|
|
|
void PDC_reset_prog_mode(void)
|
|
{
|
|
PDC_LOG(("PDC_reset_prog_mode() - called.\n"));
|
|
|
|
if (pdc_con_out != std_con_out)
|
|
SetConsoleActiveScreenBuffer(pdc_con_out);
|
|
else if (is_nt)
|
|
{
|
|
COORD bufsize;
|
|
SMALL_RECT rect;
|
|
|
|
bufsize.X = orig_scr.srWindow.Right - orig_scr.srWindow.Left + 1;
|
|
bufsize.Y = orig_scr.srWindow.Bottom - orig_scr.srWindow.Top + 1;
|
|
|
|
rect.Top = rect.Left = 0;
|
|
rect.Bottom = bufsize.Y - 1;
|
|
rect.Right = bufsize.X - 1;
|
|
|
|
SetConsoleScreenBufferSize(pdc_con_out, bufsize);
|
|
SetConsoleWindowInfo(pdc_con_out, TRUE, &rect);
|
|
SetConsoleScreenBufferSize(pdc_con_out, bufsize);
|
|
SetConsoleActiveScreenBuffer(pdc_con_out);
|
|
}
|
|
|
|
PDC_mouse_set();
|
|
}
|
|
|
|
void PDC_reset_shell_mode(void)
|
|
{
|
|
PDC_LOG(("PDC_reset_shell_mode() - called.\n"));
|
|
|
|
if (pdc_con_out != std_con_out)
|
|
SetConsoleActiveScreenBuffer(std_con_out);
|
|
else if (is_nt)
|
|
{
|
|
SetConsoleScreenBufferSize(pdc_con_out, orig_scr.dwSize);
|
|
SetConsoleWindowInfo(pdc_con_out, TRUE, &orig_scr.srWindow);
|
|
SetConsoleScreenBufferSize(pdc_con_out, orig_scr.dwSize);
|
|
SetConsoleWindowInfo(pdc_con_out, TRUE, &orig_scr.srWindow);
|
|
SetConsoleActiveScreenBuffer(pdc_con_out);
|
|
}
|
|
|
|
SetConsoleMode(pdc_con_in, old_console_mode | 0x0080);
|
|
}
|
|
|
|
void PDC_restore_screen_mode(int i)
|
|
{
|
|
}
|
|
|
|
void PDC_save_screen_mode(int i)
|
|
{
|
|
}
|
|
|
|
bool PDC_can_change_color(void)
|
|
{
|
|
return is_nt;
|
|
}
|
|
|
|
int PDC_color_content(short color, short *red, short *green, short *blue)
|
|
{
|
|
if (color < 16 && !(pdc_conemu || pdc_wt))
|
|
{
|
|
COLORREF *color_table = _get_colors();
|
|
|
|
if (color_table)
|
|
{
|
|
DWORD col = color_table[pdc_curstoreal[color]];
|
|
|
|
*red = DIVROUND(GetRValue(col) * 1000, 255);
|
|
*green = DIVROUND(GetGValue(col) * 1000, 255);
|
|
*blue = DIVROUND(GetBValue(col) * 1000, 255);
|
|
}
|
|
else
|
|
return ERR;
|
|
}
|
|
else
|
|
{
|
|
if (!pdc_color[color].mapped)
|
|
{
|
|
*red = *green = *blue = -1;
|
|
return ERR;
|
|
}
|
|
|
|
*red = pdc_color[color].r;
|
|
*green = pdc_color[color].g;
|
|
*blue = pdc_color[color].b;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
int PDC_init_color(short color, short red, short green, short blue)
|
|
{
|
|
if (red == -1 && green == -1 && blue == -1)
|
|
{
|
|
pdc_color[color].mapped = FALSE;
|
|
return OK;
|
|
}
|
|
|
|
if (color < 16 && !(pdc_conemu || pdc_wt))
|
|
{
|
|
COLORREF *color_table = _get_colors();
|
|
|
|
if (color_table)
|
|
{
|
|
color_table[pdc_curstoreal[color]] =
|
|
RGB(DIVROUND(red * 255, 1000),
|
|
DIVROUND(green * 255, 1000),
|
|
DIVROUND(blue * 255, 1000));
|
|
|
|
return _set_colors();
|
|
}
|
|
|
|
return ERR;
|
|
}
|
|
else
|
|
{
|
|
pdc_color[color].r = red;
|
|
pdc_color[color].g = green;
|
|
pdc_color[color].b = blue;
|
|
pdc_color[color].mapped = TRUE;
|
|
}
|
|
|
|
return OK;
|
|
}
|