"Fossies" - the Fresh Open Source Software Archive

Member "PDCurses-3.9/wincon/pdcscrn.c" (4 Sep 2019, 18778 Bytes) of package /linux/misc/PDCurses-3.9.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pdcscrn.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.8_vs_3.9.

    1 /* PDCurses */
    2 
    3 #include "pdcwin.h"
    4 
    5 #include <stdlib.h>
    6 
    7 /* COLOR_PAIR to attribute encoding table. */
    8 
    9 static struct {short f, b;} atrtab[PDC_COLOR_PAIRS];
   10 
   11 /* Color component table */
   12 
   13 PDCCOLOR pdc_color[PDC_MAXCOL];
   14 
   15 HANDLE std_con_out = INVALID_HANDLE_VALUE;
   16 HANDLE pdc_con_out = INVALID_HANDLE_VALUE;
   17 HANDLE pdc_con_in = INVALID_HANDLE_VALUE;
   18 
   19 DWORD pdc_quick_edit;
   20 
   21 static short realtocurs[16] =
   22 {
   23     COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_RED,
   24     COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE, COLOR_BLACK + 8,
   25     COLOR_BLUE + 8, COLOR_GREEN + 8, COLOR_CYAN + 8, COLOR_RED + 8,
   26     COLOR_MAGENTA + 8, COLOR_YELLOW + 8, COLOR_WHITE + 8
   27 };
   28 
   29 static short ansitocurs[16] =
   30 {
   31     COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE,
   32     COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE, COLOR_BLACK + 8,
   33     COLOR_RED + 8, COLOR_GREEN + 8, COLOR_YELLOW + 8, COLOR_BLUE + 8,
   34     COLOR_MAGENTA + 8, COLOR_CYAN + 8, COLOR_WHITE + 8
   35 };
   36 
   37 short pdc_curstoreal[16], pdc_curstoansi[16];
   38 short pdc_oldf, pdc_oldb, pdc_oldu;
   39 bool pdc_conemu, pdc_ansi;
   40 
   41 enum { PDC_RESTORE_NONE, PDC_RESTORE_BUFFER };
   42 
   43 /* Struct for storing console registry keys, and for use with the
   44    undocumented WM_SETCONSOLEINFO message. Originally by James Brown,
   45    www.catch22.net. */
   46 
   47 static struct
   48 {
   49     ULONG    Length;
   50     COORD    ScreenBufferSize;
   51     COORD    WindowSize;
   52     ULONG    WindowPosX;
   53     ULONG    WindowPosY;
   54 
   55     COORD    FontSize;
   56     ULONG    FontFamily;
   57     ULONG    FontWeight;
   58     WCHAR    FaceName[32];
   59 
   60     ULONG    CursorSize;
   61     ULONG    FullScreen;
   62     ULONG    QuickEdit;
   63     ULONG    AutoPosition;
   64     ULONG    InsertMode;
   65 
   66     USHORT   ScreenColors;
   67     USHORT   PopupColors;
   68     ULONG    HistoryNoDup;
   69     ULONG    HistoryBufferSize;
   70     ULONG    NumberOfHistoryBuffers;
   71 
   72     COLORREF ColorTable[16];
   73 
   74     ULONG    CodePage;
   75     HWND     Hwnd;
   76 
   77     WCHAR    ConsoleTitle[0x100];
   78 } console_info;
   79 
   80 #ifdef HAVE_NO_INFOEX
   81 /* Console screen buffer information (extended version) */
   82 typedef struct _CONSOLE_SCREEN_BUFFER_INFOEX {
   83     ULONG       cbSize;
   84     COORD       dwSize;
   85     COORD       dwCursorPosition;
   86     WORD        wAttributes;
   87     SMALL_RECT  srWindow;
   88     COORD       dwMaximumWindowSize;
   89     WORD        wPopupAttributes;
   90     BOOL        bFullscreenSupported;
   91     COLORREF    ColorTable[16];
   92 } CONSOLE_SCREEN_BUFFER_INFOEX;
   93 typedef CONSOLE_SCREEN_BUFFER_INFOEX    *PCONSOLE_SCREEN_BUFFER_INFOEX;
   94 #endif
   95 
   96 typedef BOOL (WINAPI *SetConsoleScreenBufferInfoExFn)(HANDLE hConsoleOutput,
   97     PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx);
   98 typedef BOOL (WINAPI *GetConsoleScreenBufferInfoExFn)(HANDLE hConsoleOutput,
   99     PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx);
  100 
  101 static SetConsoleScreenBufferInfoExFn pSetConsoleScreenBufferInfoEx = NULL;
  102 static GetConsoleScreenBufferInfoExFn pGetConsoleScreenBufferInfoEx = NULL;
  103 
  104 static CONSOLE_SCREEN_BUFFER_INFO orig_scr;
  105 static CONSOLE_SCREEN_BUFFER_INFOEX console_infoex;
  106 
  107 static LPTOP_LEVEL_EXCEPTION_FILTER xcpt_filter;
  108 
  109 static DWORD old_console_mode = 0;
  110 
  111 static bool is_nt;
  112 
  113 static void _reset_old_colors(void)
  114 {
  115     pdc_oldf = -1;
  116     pdc_oldb = -1;
  117     pdc_oldu = 0;
  118 }
  119 
  120 static HWND _find_console_handle(void)
  121 {
  122     TCHAR orgtitle[1024], temptitle[1024];
  123     HWND wnd;
  124 
  125     GetConsoleTitle(orgtitle, 1024);
  126 
  127     wsprintf(temptitle, TEXT("%d/%d"), GetTickCount(), GetCurrentProcessId());
  128     SetConsoleTitle(temptitle);
  129 
  130     Sleep(40);
  131 
  132     wnd = FindWindow(NULL, temptitle);
  133 
  134     SetConsoleTitle(orgtitle);
  135 
  136     return wnd;
  137 }
  138 
  139 /* Undocumented console message */
  140 
  141 #define WM_SETCONSOLEINFO (WM_USER + 201)
  142 
  143 /* Wrapper around WM_SETCONSOLEINFO. We need to create the necessary
  144    section (file-mapping) object in the context of the process which
  145    owns the console, before posting the message. Originally by JB. */
  146 
  147 static void _set_console_info(void)
  148 {
  149     CONSOLE_SCREEN_BUFFER_INFO csbi;
  150     CONSOLE_CURSOR_INFO cci;
  151     DWORD dwConsoleOwnerPid;
  152     HANDLE hProcess;
  153     HANDLE hSection, hDupSection;
  154     PVOID ptrView;
  155 
  156     /* Each-time initialization for console_info */
  157 
  158     GetConsoleCursorInfo(pdc_con_out, &cci);
  159     console_info.CursorSize = cci.dwSize;
  160 
  161     GetConsoleScreenBufferInfo(pdc_con_out, &csbi);
  162     console_info.ScreenBufferSize = csbi.dwSize;
  163 
  164     console_info.WindowSize.X = csbi.srWindow.Right - csbi.srWindow.Left + 1;
  165     console_info.WindowSize.Y = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
  166 
  167     console_info.WindowPosX = csbi.srWindow.Left;
  168     console_info.WindowPosY = csbi.srWindow.Top;
  169 
  170     /* Open the process which "owns" the console */
  171 
  172     GetWindowThreadProcessId(console_info.Hwnd, &dwConsoleOwnerPid);
  173 
  174     hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwConsoleOwnerPid);
  175 
  176     /* Create a SECTION object backed by page-file, then map a view of
  177        this section into the owner process so we can write the contents
  178        of the CONSOLE_INFO buffer into it */
  179 
  180     hSection = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE,
  181                                  0, sizeof(console_info), 0);
  182 
  183     /* Copy our console structure into the section-object */
  184 
  185     ptrView = MapViewOfFile(hSection, FILE_MAP_WRITE|FILE_MAP_READ,
  186                             0, 0, sizeof(console_info));
  187 
  188     memcpy(ptrView, &console_info, sizeof(console_info));
  189 
  190     UnmapViewOfFile(ptrView);
  191 
  192     /* Map the memory into owner process */
  193 
  194     DuplicateHandle(GetCurrentProcess(), hSection, hProcess, &hDupSection,
  195                     0, FALSE, DUPLICATE_SAME_ACCESS);
  196 
  197     /* Send console window the "update" message */
  198 
  199     SendMessage(console_info.Hwnd, WM_SETCONSOLEINFO, (WPARAM)hDupSection, 0);
  200 
  201     CloseHandle(hSection);
  202     CloseHandle(hProcess);
  203 }
  204 
  205 static int _set_console_infoex(void)
  206 {
  207     if (!pSetConsoleScreenBufferInfoEx(pdc_con_out, &console_infoex))
  208         return ERR;
  209 
  210     return OK;
  211 }
  212 
  213 static int _set_colors(void)
  214 {
  215     SetConsoleTextAttribute(pdc_con_out, 7);
  216     _reset_old_colors();
  217 
  218     if (pSetConsoleScreenBufferInfoEx)
  219         return _set_console_infoex();
  220     else
  221     {
  222         _set_console_info();
  223         return OK;
  224     }
  225 }
  226 
  227 /* One-time initialization for console_info -- color table and font info
  228    from the registry; other values from functions. */
  229 
  230 static void _init_console_info(void)
  231 {
  232     DWORD scrnmode, len;
  233     HKEY reghnd;
  234     int i;
  235 
  236     console_info.Hwnd = _find_console_handle();
  237     console_info.Length = sizeof(console_info);
  238 
  239     GetConsoleMode(pdc_con_in, &scrnmode);
  240     console_info.QuickEdit = !!(scrnmode & 0x0040);
  241     console_info.InsertMode = !!(scrnmode & 0x0020);
  242 
  243     console_info.FullScreen = FALSE;
  244     console_info.AutoPosition = 0x10000;
  245     console_info.ScreenColors = SP->orig_back << 4 | SP->orig_fore;
  246     console_info.PopupColors = 0xf5;
  247 
  248     console_info.HistoryNoDup = FALSE;
  249     console_info.HistoryBufferSize = 50;
  250     console_info.NumberOfHistoryBuffers = 4;
  251 
  252     console_info.CodePage = GetConsoleOutputCP();
  253 
  254     RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Console"), 0,
  255                  KEY_QUERY_VALUE, &reghnd);
  256 
  257     len = sizeof(DWORD);
  258 
  259     /* Default color table */
  260 
  261     for (i = 0; i < 16; i++)
  262     {
  263         char tname[13];
  264 
  265         sprintf(tname, "ColorTable%02d", i);
  266         RegQueryValueExA(reghnd, tname, NULL, NULL,
  267                          (LPBYTE)(&(console_info.ColorTable[i])), &len);
  268     }
  269 
  270     /* Font info */
  271 
  272     RegQueryValueEx(reghnd, TEXT("FontSize"), NULL, NULL,
  273                     (LPBYTE)(&console_info.FontSize), &len);
  274     RegQueryValueEx(reghnd, TEXT("FontFamily"), NULL, NULL,
  275                     (LPBYTE)(&console_info.FontFamily), &len);
  276     RegQueryValueEx(reghnd, TEXT("FontWeight"), NULL, NULL,
  277                     (LPBYTE)(&console_info.FontWeight), &len);
  278 
  279     len = sizeof(WCHAR) * 32;
  280     RegQueryValueExW(reghnd, L"FaceName", NULL, NULL,
  281                      (LPBYTE)(console_info.FaceName), &len);
  282 
  283     RegCloseKey(reghnd);
  284 }
  285 
  286 static int _init_console_infoex(void)
  287 {
  288     console_infoex.cbSize = sizeof(console_infoex);
  289 
  290     if (!pGetConsoleScreenBufferInfoEx(pdc_con_out, &console_infoex))
  291         return ERR;
  292 
  293     console_infoex.srWindow.Right++;
  294     console_infoex.srWindow.Bottom++;
  295 
  296     return OK;
  297 }
  298 
  299 static COLORREF *_get_colors(void)
  300 {
  301     if (pGetConsoleScreenBufferInfoEx)
  302     {
  303         int status = OK;
  304         if (!console_infoex.cbSize)
  305             status = _init_console_infoex();
  306         return (status == ERR) ? NULL :
  307             (COLORREF *)(&(console_infoex.ColorTable));
  308     }
  309     else
  310     {
  311         if (!console_info.Hwnd)
  312             _init_console_info();
  313         return (COLORREF *)(&(console_info.ColorTable));
  314     }
  315 }
  316 
  317 /* restore the original console buffer in the event of a crash */
  318 
  319 static LONG WINAPI _restore_console(LPEXCEPTION_POINTERS ep)
  320 {
  321     PDC_scr_close();
  322 
  323     return EXCEPTION_CONTINUE_SEARCH;
  324 }
  325 
  326 /* restore the original console buffer on Ctrl+Break (or Ctrl+C,
  327    if it gets re-enabled) */
  328 
  329 static BOOL WINAPI _ctrl_break(DWORD dwCtrlType)
  330 {
  331     if (dwCtrlType == CTRL_BREAK_EVENT || dwCtrlType == CTRL_C_EVENT)
  332         PDC_scr_close();
  333 
  334     return FALSE;
  335 }
  336 
  337 /* close the physical screen -- may restore the screen to its state
  338    before PDC_scr_open(); miscellaneous cleanup */
  339 
  340 void PDC_scr_close(void)
  341 {
  342     PDC_LOG(("PDC_scr_close() - called\n"));
  343 
  344     if (SP->visibility != 1)
  345         curs_set(1);
  346 
  347     PDC_reset_shell_mode();
  348 
  349     /* Position cursor to the bottom left of the screen. */
  350 
  351     if (SP->_restore == PDC_RESTORE_NONE)
  352     {
  353         SMALL_RECT win;
  354 
  355         win.Left = orig_scr.srWindow.Left;
  356         win.Right = orig_scr.srWindow.Right;
  357         win.Top = 0;
  358         win.Bottom = orig_scr.srWindow.Bottom - orig_scr.srWindow.Top;
  359         SetConsoleWindowInfo(pdc_con_out, TRUE, &win);
  360         PDC_gotoyx(win.Bottom, 0);
  361     }
  362 }
  363 
  364 void PDC_scr_free(void)
  365 {
  366     if (SP)
  367         free(SP);
  368 
  369     if (pdc_con_out != std_con_out)
  370     {
  371         CloseHandle(pdc_con_out);
  372         pdc_con_out = std_con_out;
  373     }
  374 
  375     SetUnhandledExceptionFilter(xcpt_filter);
  376     SetConsoleCtrlHandler(_ctrl_break, FALSE);
  377 }
  378 
  379 /* open the physical screen -- allocate SP, miscellaneous intialization,
  380    and may save the existing screen for later restoration */
  381 
  382 int PDC_scr_open(int argc, char **argv)
  383 {
  384     const char *str;
  385     CONSOLE_SCREEN_BUFFER_INFO csbi;
  386     HMODULE h_kernel;
  387     BOOL result;
  388     int i;
  389 
  390     PDC_LOG(("PDC_scr_open() - called\n"));
  391 
  392     SP = calloc(1, sizeof(SCREEN));
  393 
  394     if (!SP)
  395         return ERR;
  396 
  397     for (i = 0; i < 16; i++)
  398     {
  399         pdc_curstoreal[realtocurs[i]] = i;
  400         pdc_curstoansi[ansitocurs[i]] = i;
  401     }
  402     _reset_old_colors();
  403 
  404     std_con_out =
  405     pdc_con_out = GetStdHandle(STD_OUTPUT_HANDLE);
  406     pdc_con_in = GetStdHandle(STD_INPUT_HANDLE);
  407 
  408     if (GetFileType(pdc_con_in) != FILE_TYPE_CHAR)
  409     {
  410         fprintf(stderr, "\nRedirection is not supported.\n");
  411         exit(1);
  412     }
  413 
  414     is_nt = !(GetVersion() & 0x80000000);
  415 
  416     str = getenv("ConEmuANSI");
  417     pdc_conemu = !!str;
  418     pdc_ansi = pdc_conemu ? !strcmp(str, "ON") : FALSE;
  419 
  420     GetConsoleScreenBufferInfo(pdc_con_out, &csbi);
  421     GetConsoleScreenBufferInfo(pdc_con_out, &orig_scr);
  422     GetConsoleMode(pdc_con_in, &old_console_mode);
  423 
  424     /* preserve QuickEdit Mode setting for use in PDC_mouse_set() when
  425        the mouse is not enabled -- other console input settings are
  426        cleared */
  427 
  428     pdc_quick_edit = old_console_mode & 0x0040;
  429 
  430     SP->lines = (str = getenv("LINES")) ? atoi(str) : PDC_get_rows();
  431     SP->cols = (str = getenv("COLS")) ? atoi(str) : PDC_get_columns();
  432 
  433     SP->mouse_wait = PDC_CLICK_PERIOD;
  434     SP->audible = TRUE;
  435 
  436     SP->termattrs = A_COLOR | A_REVERSE;
  437     if (pdc_ansi)
  438         SP->termattrs |= A_UNDERLINE | A_ITALIC;
  439 
  440     if (SP->lines < 2 || SP->lines > csbi.dwMaximumWindowSize.Y)
  441     {
  442         fprintf(stderr, "LINES value must be >= 2 and <= %d: got %d\n",
  443                 csbi.dwMaximumWindowSize.Y, SP->lines);
  444 
  445         return ERR;
  446     }
  447 
  448     if (SP->cols < 2 || SP->cols > csbi.dwMaximumWindowSize.X)
  449     {
  450         fprintf(stderr, "COLS value must be >= 2 and <= %d: got %d\n",
  451                 csbi.dwMaximumWindowSize.X, SP->cols);
  452 
  453         return ERR;
  454     }
  455 
  456     SP->orig_fore = csbi.wAttributes & 0x0f;
  457     SP->orig_back = (csbi.wAttributes & 0xf0) >> 4;
  458 
  459     SP->orig_attr = TRUE;
  460 
  461     SP->_restore = PDC_RESTORE_NONE;
  462 
  463     if ((str = getenv("PDC_RESTORE_SCREEN")) == NULL || *str != '0')
  464     {
  465         /* Create a new console buffer */
  466 
  467         pdc_con_out =
  468             CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
  469                                       FILE_SHARE_READ | FILE_SHARE_WRITE,
  470                                       NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
  471 
  472         if (pdc_con_out == INVALID_HANDLE_VALUE)
  473         {
  474             PDC_LOG(("PDC_scr_open() - screen buffer failure\n"));
  475 
  476             pdc_con_out = std_con_out;
  477         }
  478         else
  479             SP->_restore = PDC_RESTORE_BUFFER;
  480     }
  481 
  482     xcpt_filter = SetUnhandledExceptionFilter(_restore_console);
  483     SetConsoleCtrlHandler(_ctrl_break, TRUE);
  484 
  485     SP->_preserve = (getenv("PDC_PRESERVE_SCREEN") != NULL);
  486 
  487     /* ENABLE_LVB_GRID_WORLDWIDE */
  488     result = SetConsoleMode(pdc_con_out, 0x0010);
  489     if (result)
  490         SP->termattrs |= A_UNDERLINE | A_LEFT | A_RIGHT;
  491 
  492     PDC_reset_prog_mode();
  493 
  494     SP->mono = FALSE;
  495 
  496     h_kernel = GetModuleHandleA("kernel32.dll");
  497     pGetConsoleScreenBufferInfoEx =
  498         (GetConsoleScreenBufferInfoExFn)GetProcAddress(h_kernel,
  499         "GetConsoleScreenBufferInfoEx");
  500     pSetConsoleScreenBufferInfoEx =
  501         (SetConsoleScreenBufferInfoExFn)GetProcAddress(h_kernel,
  502         "SetConsoleScreenBufferInfoEx");
  503 
  504     return OK;
  505 }
  506 
  507  /* Calls SetConsoleWindowInfo with the given parameters, but fits them
  508     if a scoll bar shrinks the maximum possible value. The rectangle
  509     must at least fit in a half-sized window. */
  510 
  511 static BOOL _fit_console_window(HANDLE con_out, CONST SMALL_RECT *rect)
  512 {
  513     SMALL_RECT run;
  514     SHORT mx, my;
  515 
  516     if (SetConsoleWindowInfo(con_out, TRUE, rect))
  517         return TRUE;
  518 
  519     run = *rect;
  520     run.Right /= 2;
  521     run.Bottom /= 2;
  522 
  523     mx = run.Right;
  524     my = run.Bottom;
  525 
  526     if (!SetConsoleWindowInfo(con_out, TRUE, &run))
  527         return FALSE;
  528 
  529     for (run.Right = rect->Right; run.Right >= mx; run.Right--)
  530         if (SetConsoleWindowInfo(con_out, TRUE, &run))
  531             break;
  532 
  533     if (run.Right < mx)
  534         return FALSE;
  535 
  536     for (run.Bottom = rect->Bottom; run.Bottom >= my; run.Bottom--)
  537         if (SetConsoleWindowInfo(con_out, TRUE, &run))
  538             return TRUE;
  539 
  540     return FALSE;
  541 }
  542 
  543 /* the core of resize_term() */
  544 
  545 int PDC_resize_screen(int nlines, int ncols)
  546 {
  547     SMALL_RECT rect;
  548     COORD size, max;
  549 
  550     bool prog_resize = nlines || ncols;
  551 
  552     if (!prog_resize)
  553     {
  554         nlines = PDC_get_rows();
  555         ncols = PDC_get_columns();
  556     }
  557 
  558     if (nlines < 2 || ncols < 2)
  559         return ERR;
  560 
  561     max = GetLargestConsoleWindowSize(pdc_con_out);
  562 
  563     rect.Left = rect.Top = 0;
  564     rect.Right = ncols - 1;
  565 
  566     if (rect.Right > max.X)
  567         rect.Right = max.X;
  568 
  569     rect.Bottom = nlines - 1;
  570 
  571     if (rect.Bottom > max.Y)
  572         rect.Bottom = max.Y;
  573 
  574     size.X = rect.Right + 1;
  575     size.Y = rect.Bottom + 1;
  576 
  577     _fit_console_window(pdc_con_out, &rect);
  578     SetConsoleScreenBufferSize(pdc_con_out, size);
  579 
  580     if (prog_resize)
  581     {
  582         _fit_console_window(pdc_con_out, &rect);
  583         SetConsoleScreenBufferSize(pdc_con_out, size);
  584     }
  585     SetConsoleActiveScreenBuffer(pdc_con_out);
  586 
  587     PDC_flushinp();
  588 
  589     SP->resized = FALSE;
  590     SP->cursrow = SP->curscol = 0;
  591 
  592     return OK;
  593 }
  594 
  595 void PDC_reset_prog_mode(void)
  596 {
  597     PDC_LOG(("PDC_reset_prog_mode() - called.\n"));
  598 
  599     if (pdc_con_out != std_con_out)
  600         SetConsoleActiveScreenBuffer(pdc_con_out);
  601     else if (is_nt)
  602     {
  603         COORD bufsize;
  604         SMALL_RECT rect;
  605 
  606         bufsize.X = orig_scr.srWindow.Right - orig_scr.srWindow.Left + 1;
  607         bufsize.Y = orig_scr.srWindow.Bottom - orig_scr.srWindow.Top + 1;
  608 
  609         rect.Top = rect.Left = 0;
  610         rect.Bottom = bufsize.Y - 1;
  611         rect.Right = bufsize.X - 1;
  612 
  613         SetConsoleScreenBufferSize(pdc_con_out, bufsize);
  614         SetConsoleWindowInfo(pdc_con_out, TRUE, &rect);
  615         SetConsoleScreenBufferSize(pdc_con_out, bufsize);
  616         SetConsoleActiveScreenBuffer(pdc_con_out);
  617     }
  618 
  619     PDC_mouse_set();
  620 }
  621 
  622 void PDC_reset_shell_mode(void)
  623 {
  624     PDC_LOG(("PDC_reset_shell_mode() - called.\n"));
  625 
  626     if (pdc_con_out != std_con_out)
  627         SetConsoleActiveScreenBuffer(std_con_out);
  628     else if (is_nt)
  629     {
  630         SetConsoleScreenBufferSize(pdc_con_out, orig_scr.dwSize);
  631         SetConsoleWindowInfo(pdc_con_out, TRUE, &orig_scr.srWindow);
  632         SetConsoleScreenBufferSize(pdc_con_out, orig_scr.dwSize);
  633         SetConsoleWindowInfo(pdc_con_out, TRUE, &orig_scr.srWindow);
  634         SetConsoleActiveScreenBuffer(pdc_con_out);
  635     }
  636 
  637     SetConsoleMode(pdc_con_in, old_console_mode | 0x0080);
  638 }
  639 
  640 void PDC_restore_screen_mode(int i)
  641 {
  642 }
  643 
  644 void PDC_save_screen_mode(int i)
  645 {
  646 }
  647 
  648 void PDC_init_pair(short pair, short fg, short bg)
  649 {
  650     atrtab[pair].f = fg;
  651     atrtab[pair].b = bg;
  652 }
  653 
  654 int PDC_pair_content(short pair, short *fg, short *bg)
  655 {
  656     *fg = atrtab[pair].f;
  657     *bg = atrtab[pair].b;
  658 
  659     return OK;
  660 }
  661 
  662 bool PDC_can_change_color(void)
  663 {
  664     return is_nt;
  665 }
  666 
  667 int PDC_color_content(short color, short *red, short *green, short *blue)
  668 {
  669     if (color < 16 && !pdc_conemu)
  670     {
  671         COLORREF *color_table = _get_colors();
  672 
  673         if (color_table)
  674         {
  675             DWORD col = color_table[pdc_curstoreal[color]];
  676 
  677             *red = DIVROUND(GetRValue(col) * 1000, 255);
  678             *green = DIVROUND(GetGValue(col) * 1000, 255);
  679             *blue = DIVROUND(GetBValue(col) * 1000, 255);
  680         }
  681         else
  682             return ERR;
  683     }
  684     else
  685     {
  686         if (!pdc_color[color].mapped)
  687         {
  688             *red = *green = *blue = -1;
  689             return ERR;
  690         }
  691 
  692         *red = pdc_color[color].r;
  693         *green = pdc_color[color].g;
  694         *blue = pdc_color[color].b;
  695     }
  696 
  697     return OK;
  698 }
  699 
  700 int PDC_init_color(short color, short red, short green, short blue)
  701 {
  702     if (red == -1 && green == -1 && blue == -1)
  703     {
  704         pdc_color[color].mapped = FALSE;
  705         return OK;
  706     }
  707 
  708     if (color < 16 && !pdc_conemu)
  709     {
  710         COLORREF *color_table = _get_colors();
  711 
  712         if (color_table)
  713         {
  714             color_table[pdc_curstoreal[color]] =
  715                 RGB(DIVROUND(red * 255, 1000),
  716                     DIVROUND(green * 255, 1000),
  717                     DIVROUND(blue * 255, 1000));
  718 
  719             return _set_colors();
  720         }
  721 
  722         return ERR;
  723     }
  724     else
  725     {
  726         pdc_color[color].r = red;
  727         pdc_color[color].g = green;
  728         pdc_color[color].b = blue;
  729         pdc_color[color].mapped = TRUE;
  730     }
  731 
  732     return OK;
  733 }