diff options
Diffstat (limited to 'Utilities/cmpdcurses/wincon')
-rw-r--r-- | Utilities/cmpdcurses/wincon/README.md | 76 | ||||
-rw-r--r-- | Utilities/cmpdcurses/wincon/pdcclip.c | 149 | ||||
-rw-r--r-- | Utilities/cmpdcurses/wincon/pdcdisp.c | 329 | ||||
-rw-r--r-- | Utilities/cmpdcurses/wincon/pdcgetsc.c | 42 | ||||
-rw-r--r-- | Utilities/cmpdcurses/wincon/pdckbd.c | 699 | ||||
-rw-r--r-- | Utilities/cmpdcurses/wincon/pdcscrn.c | 686 | ||||
-rw-r--r-- | Utilities/cmpdcurses/wincon/pdcsetsc.c | 130 | ||||
-rw-r--r-- | Utilities/cmpdcurses/wincon/pdcutil.c | 26 | ||||
-rw-r--r-- | Utilities/cmpdcurses/wincon/pdcwin.h | 27 |
9 files changed, 2164 insertions, 0 deletions
diff --git a/Utilities/cmpdcurses/wincon/README.md b/Utilities/cmpdcurses/wincon/README.md new file mode 100644 index 0000000..6192afb --- /dev/null +++ b/Utilities/cmpdcurses/wincon/README.md @@ -0,0 +1,76 @@ +PDCurses for Windows console +============================ + +This directory contains PDCurses source code files specific to the +Microsoft Windows console. Although historically called "Win32", this +port can just as easily be built for 64-bit systems. Windows 95 through +Windows 10 are covered. (Some features require later versions.) + + +Building +-------- + +- Choose the appropriate makefile for your compiler: + + Makefile - GCC (MinGW or Cygnus) + Makefile.bcc - Borland C++ + Makefile.vc - Microsoft Visual C++ + Makefile.wcc - Watcom + +- Optionally, you can build in a different directory than the platform + directory by setting PDCURSES_SRCDIR to point to the directory where + you unpacked PDCurses, and changing to your target directory: + + set PDCURSES_SRCDIR=c:\pdcurses + +- Build it: + + make -f makefilename + + (For Watcom, use "wmake" instead of "make"; for MSVC, "nmake"; for + MinGW, "mingw32-make".) You'll get the library (pdcurses.lib or .a, + depending on your compiler) and a lot of object files. + + You can also give the optional parameter "WIDE=Y", to build the + library with wide-character (Unicode) support: + + wmake -f Makefile.wcc WIDE=Y + + When built this way, the library is not compatible with Windows 9x, + unless you also link with the Microsoft Layer for Unicode (not + tested). + + Another option, "UTF8=Y", makes PDCurses ignore the system locale, and + treat all narrow-character strings as UTF-8. This option has no effect + unless WIDE=Y is also set. Use it to get around the poor support for + UTF-8 in the Windows console: + + make -f Makefile.bcc WIDE=Y UTF8=Y + + You can also use the optional parameter "DLL=Y" with Visual C++, + MinGW or Cygwin, to build the library as a DLL: + + nmake -f Makefile.vc WIDE=Y DLL=Y + + When you build the library as a Windows DLL, you must always define + PDC_DLL_BUILD when linking against it. (Or, if you only want to use + the DLL, you could add this definition to your curses.h.) + + Add the target "demos" to build the sample programs. + +- If your build stops with errors about PCONSOLE_SCREEN_BUFFER_INFOEX, + add the parameter "INFOEX=N" to your make command line and try again. + (This will happen with older compile environments.) + + +Distribution Status +------------------- + +The files in this directory are released to the public domain. + + +Acknowledgements +---------------- + +Windows console port was originally provided by Chris Szurgot +<szurgot@itribe.net> diff --git a/Utilities/cmpdcurses/wincon/pdcclip.c b/Utilities/cmpdcurses/wincon/pdcclip.c new file mode 100644 index 0000000..7402212 --- /dev/null +++ b/Utilities/cmpdcurses/wincon/pdcclip.c @@ -0,0 +1,149 @@ +/* PDCurses */ + +#include "pdcwin.h" + +#include <string.h> + +/*man-start************************************************************** + +clipboard +--------- + +### Synopsis + + int PDC_getclipboard(char **contents, long *length); + int PDC_setclipboard(const char *contents, long length); + int PDC_freeclipboard(char *contents); + int PDC_clearclipboard(void); + +### Description + + PDC_getclipboard() gets the textual contents of the system's + clipboard. This function returns the contents of the clipboard in the + contents argument. It is the responsibility of the caller to free the + memory returned, via PDC_freeclipboard(). The length of the clipboard + contents is returned in the length argument. + + PDC_setclipboard copies the supplied text into the system's + clipboard, emptying the clipboard prior to the copy. + + PDC_clearclipboard() clears the internal clipboard. + +### Return Values + + indicator of success/failure of call. + PDC_CLIP_SUCCESS the call was successful + PDC_CLIP_MEMORY_ERROR unable to allocate sufficient memory for + the clipboard contents + PDC_CLIP_EMPTY the clipboard contains no text + PDC_CLIP_ACCESS_ERROR no clipboard support + +### Portability + X/Open ncurses NetBSD + PDC_getclipboard - - - + PDC_setclipboard - - - + PDC_freeclipboard - - - + PDC_clearclipboard - - - + +**man-end****************************************************************/ + +#ifdef PDC_WIDE +# define PDC_TEXT CF_UNICODETEXT +#else +# define PDC_TEXT CF_OEMTEXT +#endif + +int PDC_getclipboard(char **contents, long *length) +{ + HANDLE handle; + long len; + + PDC_LOG(("PDC_getclipboard() - called\n")); + + if (!OpenClipboard(NULL)) + return PDC_CLIP_ACCESS_ERROR; + + if ((handle = GetClipboardData(PDC_TEXT)) == NULL) + { + CloseClipboard(); + return PDC_CLIP_EMPTY; + } + +#ifdef PDC_WIDE + len = wcslen((wchar_t *)handle) * 3; +#else + len = strlen((char *)handle); +#endif + *contents = (char *)GlobalAlloc(GMEM_FIXED, len + 1); + + if (!*contents) + { + CloseClipboard(); + return PDC_CLIP_MEMORY_ERROR; + } + +#ifdef PDC_WIDE + len = PDC_wcstombs((char *)*contents, (wchar_t *)handle, len); +#else + strcpy((char *)*contents, (char *)handle); +#endif + *length = len; + CloseClipboard(); + + return PDC_CLIP_SUCCESS; +} + +int PDC_setclipboard(const char *contents, long length) +{ + HGLOBAL ptr1; + LPTSTR ptr2; + + PDC_LOG(("PDC_setclipboard() - called\n")); + + if (!OpenClipboard(NULL)) + return PDC_CLIP_ACCESS_ERROR; + + ptr1 = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, + (length + 1) * sizeof(TCHAR)); + + if (!ptr1) + return PDC_CLIP_MEMORY_ERROR; + + ptr2 = GlobalLock(ptr1); + +#ifdef PDC_WIDE + PDC_mbstowcs((wchar_t *)ptr2, contents, length); +#else + memcpy((char *)ptr2, contents, length + 1); +#endif + GlobalUnlock(ptr1); + EmptyClipboard(); + + if (!SetClipboardData(PDC_TEXT, ptr1)) + { + GlobalFree(ptr1); + return PDC_CLIP_ACCESS_ERROR; + } + + CloseClipboard(); + GlobalFree(ptr1); + + return PDC_CLIP_SUCCESS; +} + +int PDC_freeclipboard(char *contents) +{ + PDC_LOG(("PDC_freeclipboard() - called\n")); + + GlobalFree(contents); + return PDC_CLIP_SUCCESS; +} + +int PDC_clearclipboard(void) +{ + PDC_LOG(("PDC_clearclipboard() - called\n")); + + EmptyClipboard(); + + return PDC_CLIP_SUCCESS; +} diff --git a/Utilities/cmpdcurses/wincon/pdcdisp.c b/Utilities/cmpdcurses/wincon/pdcdisp.c new file mode 100644 index 0000000..fdaec76 --- /dev/null +++ b/Utilities/cmpdcurses/wincon/pdcdisp.c @@ -0,0 +1,329 @@ +/* PDCurses */ + +#include "pdcwin.h" + +#include <stdlib.h> +#include <string.h> + +#ifdef PDC_WIDE +# include "../common/acsuni.h" +#else +# include "../common/acs437.h" +#endif + +DWORD pdc_last_blink; +static bool blinked_off = FALSE; +static bool in_italic = FALSE; + +/* position hardware cursor at (y, x) */ + +void PDC_gotoyx(int row, int col) +{ + COORD coord; + + PDC_LOG(("PDC_gotoyx() - called: row %d col %d from row %d col %d\n", + row, col, SP->cursrow, SP->curscol)); + + coord.X = col; + coord.Y = row; + + SetConsoleCursorPosition(pdc_con_out, coord); +} + +void _set_ansi_color(short f, short b, attr_t attr) +{ + char esc[64], *p; + short tmp, underline; + bool italic; + + if (f < 16 && !pdc_color[f].mapped) + f = pdc_curstoansi[f]; + + if (b < 16 && !pdc_color[b].mapped) + b = pdc_curstoansi[b]; + + if (attr & A_REVERSE) + { + tmp = f; + f = b; + b = tmp; + } + attr &= SP->termattrs; + italic = !!(attr & A_ITALIC); + underline = !!(attr & A_UNDERLINE); + + p = esc + sprintf(esc, "\x1b["); + + if (f != pdc_oldf) + { + if (f < 8 && !pdc_color[f].mapped) + p += sprintf(p, "%d", f + 30); + else if (f < 16 && !pdc_color[f].mapped) + p += sprintf(p, "%d", f + 82); + else if (f < 256 && !pdc_color[f].mapped) + p += sprintf(p, "38;5;%d", f); + else + { + short red = DIVROUND(pdc_color[f].r * 255, 1000); + short green = DIVROUND(pdc_color[f].g * 255, 1000); + short blue = DIVROUND(pdc_color[f].b * 255, 1000); + + p += sprintf(p, "38;2;%d;%d;%d", red, green, blue); + } + + pdc_oldf = f; + } + + if (b != pdc_oldb) + { + if (strlen(esc) > 2) + p += sprintf(p, ";"); + + if (b < 8 && !pdc_color[b].mapped) + p += sprintf(p, "%d", b + 40); + else if (b < 16 && !pdc_color[b].mapped) + p += sprintf(p, "%d", b + 92); + else if (b < 256 && !pdc_color[b].mapped) + p += sprintf(p, "48;5;%d", b); + else + { + short red = DIVROUND(pdc_color[b].r * 255, 1000); + short green = DIVROUND(pdc_color[b].g * 255, 1000); + short blue = DIVROUND(pdc_color[b].b * 255, 1000); + + p += sprintf(p, "48;2;%d;%d;%d", red, green, blue); + } + + pdc_oldb = b; + } + + if (italic != in_italic) + { + if (strlen(esc) > 2) + p += sprintf(p, ";"); + + if (italic) + p += sprintf(p, "3"); + else + p += sprintf(p, "23"); + + in_italic = italic; + } + + if (underline != pdc_oldu) + { + if (strlen(esc) > 2) + p += sprintf(p, ";"); + + if (underline) + p += sprintf(p, "4"); + else + p += sprintf(p, "24"); + + pdc_oldu = underline; + } + + if (strlen(esc) > 2) + { + sprintf(p, "m"); + if (!pdc_conemu) + SetConsoleMode(pdc_con_out, 0x0015); + + WriteConsoleA(pdc_con_out, esc, strlen(esc), NULL, NULL); + + if (!pdc_conemu) + SetConsoleMode(pdc_con_out, 0x0010); + } +} + +void _new_packet(attr_t attr, int lineno, int x, int len, const chtype *srcp) +{ + int j; + short fore, back; + bool blink, ansi; + + if (pdc_ansi && (lineno == (SP->lines - 1)) && ((x + len) == SP->cols)) + { + len--; + if (len) + _new_packet(attr, lineno, x, len, srcp); + pdc_ansi = FALSE; + _new_packet(attr, lineno, x + len, 1, srcp + len); + pdc_ansi = TRUE; + return; + } + + pair_content(PAIR_NUMBER(attr), &fore, &back); + ansi = pdc_ansi || (fore >= 16 || back >= 16); + blink = (SP->termattrs & A_BLINK) && (attr & A_BLINK); + + if (blink) + { + attr &= ~A_BLINK; + if (blinked_off) + attr &= ~(A_UNDERLINE | A_RIGHT | A_LEFT); + } + + if (attr & A_BOLD) + fore |= 8; + if (attr & A_BLINK) + back |= 8; + + if (ansi) + { +#ifdef PDC_WIDE + WCHAR buffer[512]; +#else + char buffer[512]; +#endif + for (j = 0; j < len; j++) + { + chtype ch = srcp[j]; + + if (ch & A_ALTCHARSET && !(ch & 0xff80)) + { + ch = acs_map[ch & 0x7f]; + + if (pdc_wt && (ch & A_CHARTEXT) < ' ') + goto NONANSI; + } + + if (blink && blinked_off) + ch = ' '; + + buffer[j] = ch & A_CHARTEXT; + } + + PDC_gotoyx(lineno, x); + _set_ansi_color(fore, back, attr); +#ifdef PDC_WIDE + WriteConsoleW(pdc_con_out, buffer, len, NULL, NULL); +#else + WriteConsoleA(pdc_con_out, buffer, len, NULL, NULL); +#endif + } + else +NONANSI: + { + CHAR_INFO buffer[512]; + COORD bufSize, bufPos; + SMALL_RECT sr; + WORD mapped_attr; + + fore = pdc_curstoreal[fore]; + back = pdc_curstoreal[back]; + + if (attr & A_REVERSE) + mapped_attr = back | (fore << 4); + else + mapped_attr = fore | (back << 4); + + if (attr & A_UNDERLINE) + mapped_attr |= 0x8000; /* COMMON_LVB_UNDERSCORE */ + if (attr & A_LEFT) + mapped_attr |= 0x0800; /* COMMON_LVB_GRID_LVERTICAL */ + if (attr & A_RIGHT) + mapped_attr |= 0x1000; /* COMMON_LVB_GRID_RVERTICAL */ + + for (j = 0; j < len; j++) + { + chtype ch = srcp[j]; + + if (ch & A_ALTCHARSET && !(ch & 0xff80)) + ch = acs_map[ch & 0x7f]; + + if (blink && blinked_off) + ch = ' '; + + buffer[j].Attributes = mapped_attr; + buffer[j].Char.UnicodeChar = ch & A_CHARTEXT; + } + + bufPos.X = bufPos.Y = 0; + bufSize.X = len; + bufSize.Y = 1; + + sr.Top = sr.Bottom = lineno; + sr.Left = x; + sr.Right = x + len - 1; + + WriteConsoleOutput(pdc_con_out, buffer, bufSize, bufPos, &sr); + } +} + +/* update the given physical line to look like the corresponding line in + curscr */ + +void PDC_transform_line(int lineno, int x, int len, const chtype *srcp) +{ + attr_t old_attr, attr; + int i, j; + + PDC_LOG(("PDC_transform_line() - called: lineno=%d\n", lineno)); + + old_attr = *srcp & (A_ATTRIBUTES ^ A_ALTCHARSET); + + for (i = 1, j = 1; j < len; i++, j++) + { + attr = srcp[i] & (A_ATTRIBUTES ^ A_ALTCHARSET); + + if (attr != old_attr) + { + _new_packet(old_attr, lineno, x, i, srcp); + old_attr = attr; + srcp += i; + x += i; + i = 0; + } + } + + _new_packet(old_attr, lineno, x, i, srcp); +} + +void PDC_blink_text(void) +{ + CONSOLE_CURSOR_INFO cci; + int i, j, k; + bool oldvis; + + GetConsoleCursorInfo(pdc_con_out, &cci); + oldvis = cci.bVisible; + if (oldvis) + { + cci.bVisible = FALSE; + SetConsoleCursorInfo(pdc_con_out, &cci); + } + + if (!(SP->termattrs & A_BLINK)) + blinked_off = FALSE; + else + blinked_off = !blinked_off; + + for (i = 0; i < SP->lines; i++) + { + const chtype *srcp = curscr->_y[i]; + + for (j = 0; j < SP->cols; j++) + if (srcp[j] & A_BLINK) + { + k = j; + while (k < SP->cols && (srcp[k] & A_BLINK)) + k++; + PDC_transform_line(i, j, k - j, srcp + j); + j = k; + } + } + + PDC_gotoyx(SP->cursrow, SP->curscol); + if (oldvis) + { + cci.bVisible = TRUE; + SetConsoleCursorInfo(pdc_con_out, &cci); + } + + pdc_last_blink = GetTickCount(); +} + +void PDC_doupdate(void) +{ +} diff --git a/Utilities/cmpdcurses/wincon/pdcgetsc.c b/Utilities/cmpdcurses/wincon/pdcgetsc.c new file mode 100644 index 0000000..a8323eb --- /dev/null +++ b/Utilities/cmpdcurses/wincon/pdcgetsc.c @@ -0,0 +1,42 @@ +/* PDCurses */ + +#include "pdcwin.h" + +/* get the cursor size/shape */ + +int PDC_get_cursor_mode(void) +{ + CONSOLE_CURSOR_INFO ci; + + PDC_LOG(("PDC_get_cursor_mode() - called\n")); + + GetConsoleCursorInfo(pdc_con_out, &ci); + + return ci.dwSize; +} + +/* return number of screen rows */ + +int PDC_get_rows(void) +{ + CONSOLE_SCREEN_BUFFER_INFO scr; + + PDC_LOG(("PDC_get_rows() - called\n")); + + GetConsoleScreenBufferInfo(pdc_con_out, &scr); + + return scr.srWindow.Bottom - scr.srWindow.Top + 1; +} + +/* return width of screen/viewport */ + +int PDC_get_columns(void) +{ + CONSOLE_SCREEN_BUFFER_INFO scr; + + PDC_LOG(("PDC_get_columns() - called\n")); + + GetConsoleScreenBufferInfo(pdc_con_out, &scr); + + return scr.srWindow.Right - scr.srWindow.Left + 1; +} diff --git a/Utilities/cmpdcurses/wincon/pdckbd.c b/Utilities/cmpdcurses/wincon/pdckbd.c new file mode 100644 index 0000000..12f30f0 --- /dev/null +++ b/Utilities/cmpdcurses/wincon/pdckbd.c @@ -0,0 +1,699 @@ +/* PDCurses */ + +#include "pdcwin.h" + +/* These variables are used to store information about the next + Input Event. */ + +static INPUT_RECORD save_ip; +static MOUSE_STATUS old_mouse_status; +static DWORD event_count = 0; +static SHORT left_key; +static int key_count = 0; +static int save_press = 0; + +#define KEV save_ip.Event.KeyEvent +#define MEV save_ip.Event.MouseEvent +#define REV save_ip.Event.WindowBufferSizeEvent + +/************************************************************************ + * Table for key code translation of function keys in keypad mode * + * These values are for strict IBM keyboard compatibles only * + ************************************************************************/ + +typedef struct +{ + unsigned short normal; + unsigned short shift; + unsigned short control; + unsigned short alt; + unsigned short extended; +} KPTAB; + +static KPTAB kptab[] = +{ + {0, 0, 0, 0, 0 }, /* 0 */ + {0, 0, 0, 0, 0 }, /* 1 VK_LBUTTON */ + {0, 0, 0, 0, 0 }, /* 2 VK_RBUTTON */ + {0, 0, 0, 0, 0 }, /* 3 VK_CANCEL */ + {0, 0, 0, 0, 0 }, /* 4 VK_MBUTTON */ + {0, 0, 0, 0, 0 }, /* 5 */ + {0, 0, 0, 0, 0 }, /* 6 */ + {0, 0, 0, 0, 0 }, /* 7 */ + {0x08, 0x08, 0x7F, ALT_BKSP, 0 }, /* 8 VK_BACK */ + {0x09, KEY_BTAB, CTL_TAB, ALT_TAB, 999 }, /* 9 VK_TAB */ + {0, 0, 0, 0, 0 }, /* 10 */ + {0, 0, 0, 0, 0 }, /* 11 */ + {KEY_B2, 0x35, CTL_PAD5, ALT_PAD5, 0 }, /* 12 VK_CLEAR */ + {0x0D, 0x0D, CTL_ENTER, ALT_ENTER, 1 }, /* 13 VK_RETURN */ + {0, 0, 0, 0, 0 }, /* 14 */ + {0, 0, 0, 0, 0 }, /* 15 */ + {0, 0, 0, 0, 0 }, /* 16 VK_SHIFT HANDLED SEPARATELY */ + {0, 0, 0, 0, 0 }, /* 17 VK_CONTROL HANDLED SEPARATELY */ + {0, 0, 0, 0, 0 }, /* 18 VK_MENU HANDLED SEPARATELY */ + {0, 0, 0, 0, 0 }, /* 19 VK_PAUSE */ + {0, 0, 0, 0, 0 }, /* 20 VK_CAPITAL HANDLED SEPARATELY */ + {0, 0, 0, 0, 0 }, /* 21 VK_HANGUL */ + {0, 0, 0, 0, 0 }, /* 22 */ + {0, 0, 0, 0, 0 }, /* 23 VK_JUNJA */ + {0, 0, 0, 0, 0 }, /* 24 VK_FINAL */ + {0, 0, 0, 0, 0 }, /* 25 VK_HANJA */ + {0, 0, 0, 0, 0 }, /* 26 */ + {0x1B, 0x1B, 0x1B, ALT_ESC, 0 }, /* 27 VK_ESCAPE */ + {0, 0, 0, 0, 0 }, /* 28 VK_CONVERT */ + {0, 0, 0, 0, 0 }, /* 29 VK_NONCONVERT */ + {0, 0, 0, 0, 0 }, /* 30 VK_ACCEPT */ + {0, 0, 0, 0, 0 }, /* 31 VK_MODECHANGE */ + {0x20, 0x20, 0x20, 0x20, 0 }, /* 32 VK_SPACE */ + {KEY_A3, 0x39, CTL_PAD9, ALT_PAD9, 3 }, /* 33 VK_PRIOR */ + {KEY_C3, 0x33, CTL_PAD3, ALT_PAD3, 4 }, /* 34 VK_NEXT */ + {KEY_C1, 0x31, CTL_PAD1, ALT_PAD1, 5 }, /* 35 VK_END */ + {KEY_A1, 0x37, CTL_PAD7, ALT_PAD7, 6 }, /* 36 VK_HOME */ + {KEY_B1, 0x34, CTL_PAD4, ALT_PAD4, 7 }, /* 37 VK_LEFT */ + {KEY_A2, 0x38, CTL_PAD8, ALT_PAD8, 8 }, /* 38 VK_UP */ + {KEY_B3, 0x36, CTL_PAD6, ALT_PAD6, 9 }, /* 39 VK_RIGHT */ + {KEY_C2, 0x32, CTL_PAD2, ALT_PAD2, 10 }, /* 40 VK_DOWN */ + {0, 0, 0, 0, 0 }, /* 41 VK_SELECT */ + {0, 0, 0, 0, 0 }, /* 42 VK_PRINT */ + {0, 0, 0, 0, 0 }, /* 43 VK_EXECUTE */ + {0, 0, 0, 0, 0 }, /* 44 VK_SNAPSHOT*/ + {PAD0, 0x30, CTL_PAD0, ALT_PAD0, 11 }, /* 45 VK_INSERT */ + {PADSTOP, 0x2E, CTL_PADSTOP, ALT_PADSTOP,12 }, /* 46 VK_DELETE */ + {0, 0, 0, 0, 0 }, /* 47 VK_HELP */ + {0x30, 0x29, 0, ALT_0, 0 }, /* 48 */ + {0x31, 0x21, 0, ALT_1, 0 }, /* 49 */ + {0x32, 0x40, 0, ALT_2, 0 }, /* 50 */ + {0x33, 0x23, 0, ALT_3, 0 }, /* 51 */ + {0x34, 0x24, 0, ALT_4, 0 }, /* 52 */ + {0x35, 0x25, 0, ALT_5, 0 }, /* 53 */ + {0x36, 0x5E, 0, ALT_6, 0 }, /* 54 */ + {0x37, 0x26, 0, ALT_7, 0 }, /* 55 */ + {0x38, 0x2A, 0, ALT_8, 0 }, /* 56 */ + {0x39, 0x28, 0, ALT_9, 0 }, /* 57 */ + {0, 0, 0, 0, 0 }, /* 58 */ + {0, 0, 0, 0, 0 }, /* 59 */ + {0, 0, 0, 0, 0 }, /* 60 */ + {0, 0, 0, 0, 0 }, /* 61 */ + {0, 0, 0, 0, 0 }, /* 62 */ + {0, 0, 0, 0, 0 }, /* 63 */ + {0, 0, 0, 0, 0 }, /* 64 */ + {0x61, 0x41, 0x01, ALT_A, 0 }, /* 65 */ + {0x62, 0x42, 0x02, ALT_B, 0 }, /* 66 */ + {0x63, 0x43, 0x03, ALT_C, 0 }, /* 67 */ + {0x64, 0x44, 0x04, ALT_D, 0 }, /* 68 */ + {0x65, 0x45, 0x05, ALT_E, 0 }, /* 69 */ + {0x66, 0x46, 0x06, ALT_F, 0 }, /* 70 */ + {0x67, 0x47, 0x07, ALT_G, 0 }, /* 71 */ + {0x68, 0x48, 0x08, ALT_H, 0 }, /* 72 */ + {0x69, 0x49, 0x09, ALT_I, 0 }, /* 73 */ + {0x6A, 0x4A, 0x0A, ALT_J, 0 }, /* 74 */ + {0x6B, 0x4B, 0x0B, ALT_K, 0 }, /* 75 */ + {0x6C, 0x4C, 0x0C, ALT_L, 0 }, /* 76 */ + {0x6D, 0x4D, 0x0D, ALT_M, 0 }, /* 77 */ + {0x6E, 0x4E, 0x0E, ALT_N, 0 }, /* 78 */ + {0x6F, 0x4F, 0x0F, ALT_O, 0 }, /* 79 */ + {0x70, 0x50, 0x10, ALT_P, 0 }, /* 80 */ + {0x71, 0x51, 0x11, ALT_Q, 0 }, /* 81 */ + {0x72, 0x52, 0x12, ALT_R, 0 }, /* 82 */ + {0x73, 0x53, 0x13, ALT_S, 0 }, /* 83 */ + {0x74, 0x54, 0x14, ALT_T, 0 }, /* 84 */ + {0x75, 0x55, 0x15, ALT_U, 0 }, /* 85 */ + {0x76, 0x56, 0x16, ALT_V, 0 }, /* 86 */ + {0x77, 0x57, 0x17, ALT_W, 0 }, /* 87 */ + {0x78, 0x58, 0x18, ALT_X, 0 }, /* 88 */ + {0x79, 0x59, 0x19, ALT_Y, 0 }, /* 89 */ + {0x7A, 0x5A, 0x1A, ALT_Z, 0 }, /* 90 */ + {0, 0, 0, 0, 0 }, /* 91 VK_LWIN */ + {0, 0, 0, 0, 0 }, /* 92 VK_RWIN */ + {0, 0, 0, 0, 0 }, /* 93 VK_APPS */ + {0, 0, 0, 0, 0 }, /* 94 */ + {0, 0, 0, 0, 0 }, /* 95 */ + {0x30, 0, CTL_PAD0, ALT_PAD0, 0 }, /* 96 VK_NUMPAD0 */ + {0x31, 0, CTL_PAD1, ALT_PAD1, 0 }, /* 97 VK_NUMPAD1 */ + {0x32, 0, CTL_PAD2, ALT_PAD2, 0 }, /* 98 VK_NUMPAD2 */ + {0x33, 0, CTL_PAD3, ALT_PAD3, 0 }, /* 99 VK_NUMPAD3 */ + {0x34, 0, CTL_PAD4, ALT_PAD4, 0 }, /* 100 VK_NUMPAD4 */ + {0x35, 0, CTL_PAD5, ALT_PAD5, 0 }, /* 101 VK_NUMPAD5 */ + {0x36, 0, CTL_PAD6, ALT_PAD6, 0 }, /* 102 VK_NUMPAD6 */ + {0x37, 0, CTL_PAD7, ALT_PAD7, 0 }, /* 103 VK_NUMPAD7 */ + {0x38, 0, CTL_PAD8, ALT_PAD8, 0 }, /* 104 VK_NUMPAD8 */ + {0x39, 0, CTL_PAD9, ALT_PAD9, 0 }, /* 105 VK_NUMPAD9 */ + {PADSTAR, SHF_PADSTAR,CTL_PADSTAR, ALT_PADSTAR,999 }, /* 106 VK_MULTIPLY*/ + {PADPLUS, SHF_PADPLUS,CTL_PADPLUS, ALT_PADPLUS,999 }, /* 107 VK_ADD */ + {0, 0, 0, 0, 0 }, /* 108 VK_SEPARATOR */ + {PADMINUS, SHF_PADMINUS,CTL_PADMINUS,ALT_PADMINUS,999}, /* 109 VK_SUBTRACT*/ + {0x2E, 0, CTL_PADSTOP, ALT_PADSTOP,0 }, /* 110 VK_DECIMAL */ + {PADSLASH, SHF_PADSLASH,CTL_PADSLASH,ALT_PADSLASH,2 }, /* 111 VK_DIVIDE */ + {KEY_F(1), KEY_F(13), KEY_F(25), KEY_F(37), 0 }, /* 112 VK_F1 */ + {KEY_F(2), KEY_F(14), KEY_F(26), KEY_F(38), 0 }, /* 113 VK_F2 */ + {KEY_F(3), KEY_F(15), KEY_F(27), KEY_F(39), 0 }, /* 114 VK_F3 */ + {KEY_F(4), KEY_F(16), KEY_F(28), KEY_F(40), 0 }, /* 115 VK_F4 */ + {KEY_F(5), KEY_F(17), KEY_F(29), KEY_F(41), 0 }, /* 116 VK_F5 */ + {KEY_F(6), KEY_F(18), KEY_F(30), KEY_F(42), 0 }, /* 117 VK_F6 */ + {KEY_F(7), KEY_F(19), KEY_F(31), KEY_F(43), 0 }, /* 118 VK_F7 */ + {KEY_F(8), KEY_F(20), KEY_F(32), KEY_F(44), 0 }, /* 119 VK_F8 */ + {KEY_F(9), KEY_F(21), KEY_F(33), KEY_F(45), 0 }, /* 120 VK_F9 */ + {KEY_F(10), KEY_F(22), KEY_F(34), KEY_F(46), 0 }, /* 121 VK_F10 */ + {KEY_F(11), KEY_F(23), KEY_F(35), KEY_F(47), 0 }, /* 122 VK_F11 */ + {KEY_F(12), KEY_F(24), KEY_F(36), KEY_F(48), 0 }, /* 123 VK_F12 */ + + /* 124 through 218 */ + + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, + + {0x5B, 0x7B, 0x1B, ALT_LBRACKET,0 }, /* 219 */ + {0x5C, 0x7C, 0x1C, ALT_BSLASH, 0 }, /* 220 */ + {0x5D, 0x7D, 0x1D, ALT_RBRACKET,0 }, /* 221 */ + {0, 0, 0x27, ALT_FQUOTE, 0 }, /* 222 */ + {0, 0, 0, 0, 0 }, /* 223 */ + {0, 0, 0, 0, 0 }, /* 224 */ + {0, 0, 0, 0, 0 }, /* 225 */ + {0, 0, 0, 0, 0 }, /* 226 */ + {0, 0, 0, 0, 0 }, /* 227 */ + {0, 0, 0, 0, 0 }, /* 228 */ + {0, 0, 0, 0, 0 }, /* 229 */ + {0, 0, 0, 0, 0 }, /* 230 */ + {0, 0, 0, 0, 0 }, /* 231 */ + {0, 0, 0, 0, 0 }, /* 232 */ + {0, 0, 0, 0, 0 }, /* 233 */ + {0, 0, 0, 0, 0 }, /* 234 */ + {0, 0, 0, 0, 0 }, /* 235 */ + {0, 0, 0, 0, 0 }, /* 236 */ + {0, 0, 0, 0, 0 }, /* 237 */ + {0, 0, 0, 0, 0 }, /* 238 */ + {0, 0, 0, 0, 0 }, /* 239 */ + {0, 0, 0, 0, 0 }, /* 240 */ + {0, 0, 0, 0, 0 }, /* 241 */ + {0, 0, 0, 0, 0 }, /* 242 */ + {0, 0, 0, 0, 0 }, /* 243 */ + {0, 0, 0, 0, 0 }, /* 244 */ + {0, 0, 0, 0, 0 }, /* 245 */ + {0, 0, 0, 0, 0 }, /* 246 */ + {0, 0, 0, 0, 0 }, /* 247 */ + {0, 0, 0, 0, 0 }, /* 248 */ + {0, 0, 0, 0, 0 }, /* 249 */ + {0, 0, 0, 0, 0 }, /* 250 */ + {0, 0, 0, 0, 0 }, /* 251 */ + {0, 0, 0, 0, 0 }, /* 252 */ + {0, 0, 0, 0, 0 }, /* 253 */ + {0, 0, 0, 0, 0 }, /* 254 */ + {0, 0, 0, 0, 0 } /* 255 */ +}; + +static KPTAB ext_kptab[] = +{ + {0, 0, 0, 0, }, /* MUST BE EMPTY */ + {PADENTER, SHF_PADENTER, CTL_PADENTER, ALT_PADENTER}, /* 13 */ + {PADSLASH, SHF_PADSLASH, CTL_PADSLASH, ALT_PADSLASH}, /* 111 */ + {KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP }, /* 33 */ + {KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN }, /* 34 */ + {KEY_END, KEY_SEND, CTL_END, ALT_END }, /* 35 */ + {KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME }, /* 36 */ + {KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT }, /* 37 */ + {KEY_UP, KEY_SUP, CTL_UP, ALT_UP }, /* 38 */ + {KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT }, /* 39 */ + {KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN }, /* 40 */ + {KEY_IC, KEY_SIC, CTL_INS, ALT_INS }, /* 45 */ + {KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL }, /* 46 */ + {PADSLASH, SHF_PADSLASH, CTL_PADSLASH, ALT_PADSLASH}, /* 191 */ +}; + +/* End of kptab[] */ + +void PDC_set_keyboard_binary(bool on) +{ + DWORD mode; + + PDC_LOG(("PDC_set_keyboard_binary() - called\n")); + + GetConsoleMode(pdc_con_in, &mode); + SetConsoleMode(pdc_con_in, !on ? (mode | ENABLE_PROCESSED_INPUT) : + (mode & ~ENABLE_PROCESSED_INPUT)); +} + +/* check if a key or mouse event is waiting */ + +bool PDC_check_key(void) +{ + if (key_count > 0) + return TRUE; + + GetNumberOfConsoleInputEvents(pdc_con_in, &event_count); + + return (event_count != 0); +} + +/* _get_key_count returns 0 if save_ip doesn't contain an event which + should be passed back to the user. This function filters "useless" + events. + + The function returns the number of keys waiting. This may be > 1 + if the repetition of real keys pressed so far are > 1. + + Returns 0 on NUMLOCK, CAPSLOCK, SCROLLLOCK. + + Returns 1 for SHIFT, ALT, CTRL only if no other key has been pressed + in between, and SP->return_key_modifiers is set; these are returned + on keyup. + + Normal keys are returned on keydown only. The number of repetitions + are returned. Dead keys (diacritics) are omitted. See below for a + description. +*/ + +static int _get_key_count(void) +{ + int num_keys = 0, vk; + + PDC_LOG(("_get_key_count() - called\n")); + + vk = KEV.wVirtualKeyCode; + + if (KEV.bKeyDown) + { + /* key down */ + + save_press = 0; + + if (vk == VK_CAPITAL || vk == VK_NUMLOCK || vk == VK_SCROLL) + { + /* throw away these modifiers */ + } + else if (vk == VK_SHIFT || vk == VK_CONTROL || vk == VK_MENU) + { + /* These keys are returned on keyup only. */ + + save_press = vk; + switch (vk) + { + case VK_SHIFT: + left_key = GetKeyState(VK_LSHIFT); + break; + case VK_CONTROL: + left_key = GetKeyState(VK_LCONTROL); + break; + case VK_MENU: + left_key = GetKeyState(VK_LMENU); + } + } + else + { + /* Check for diacritics. These are dead keys. Some locales + have modified characters like umlaut-a, which is an "a" + with two dots on it. In some locales you have to press a + special key (the dead key) immediately followed by the + "a" to get a composed umlaut-a. The special key may have + a normal meaning with different modifiers. */ + + if (KEV.uChar.UnicodeChar || !(MapVirtualKey(vk, 2) & 0x80000000)) + num_keys = KEV.wRepeatCount; + } + } + else + { + /* key up */ + + /* Only modifier keys or the results of ALT-numpad entry are + returned on keyup */ + + if ((vk == VK_MENU && KEV.uChar.UnicodeChar) || + ((vk == VK_SHIFT || vk == VK_CONTROL || vk == VK_MENU) && + vk == save_press)) + { + save_press = 0; + num_keys = 1; + } + } + + PDC_LOG(("_get_key_count() - returning: num_keys %d\n", num_keys)); + + return num_keys; +} + +/* _process_key_event returns -1 if the key in save_ip should be + ignored. Otherwise it returns the keycode which should be returned + by PDC_get_key(). save_ip must be a key event. + + CTRL-ALT support has been disabled, when is it emitted plainly? */ + +static int _process_key_event(void) +{ + int key = +#ifdef PDC_WIDE + KEV.uChar.UnicodeChar; +#else + KEV.uChar.AsciiChar; +#endif + WORD vk = KEV.wVirtualKeyCode; + DWORD state = KEV.dwControlKeyState; + + int idx; + BOOL enhanced; + + SP->key_code = TRUE; + + /* Save the key modifiers. Do this first to allow to detect e.g. a + pressed CTRL key after a hit of NUMLOCK. */ + + if (state & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) + SP->key_modifiers |= PDC_KEY_MODIFIER_ALT; + + if (state & SHIFT_PRESSED) + SP->key_modifiers |= PDC_KEY_MODIFIER_SHIFT; + + if (state & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) + SP->key_modifiers |= PDC_KEY_MODIFIER_CONTROL; + + if (state & NUMLOCK_ON) + SP->key_modifiers |= PDC_KEY_MODIFIER_NUMLOCK; + + /* Handle modifier keys hit by themselves */ + + switch (vk) + { + case VK_SHIFT: /* shift */ + if (!SP->return_key_modifiers) + return -1; + + return (left_key & 0x8000) ? KEY_SHIFT_L : KEY_SHIFT_R; + + case VK_CONTROL: /* control */ + if (!SP->return_key_modifiers) + return -1; + + return (left_key & 0x8000) ? KEY_CONTROL_L : KEY_CONTROL_R; + + case VK_MENU: /* alt */ + if (!key) + { + if (!SP->return_key_modifiers) + return -1; + + return (left_key & 0x8000) ? KEY_ALT_L : KEY_ALT_R; + } + } + + /* The system may emit Ascii or Unicode characters depending on + whether ReadConsoleInputA or ReadConsoleInputW is used. + + Normally, if key != 0 then the system did the translation + successfully. But this is not true for LEFT_ALT (different to + RIGHT_ALT). In case of LEFT_ALT we can get key != 0. So + check for this first. */ + + if (key && ( !(state & LEFT_ALT_PRESSED) || + (state & RIGHT_ALT_PRESSED) )) + { + /* This code should catch all keys returning a printable + character. Characters above 0x7F should be returned as + positive codes. */ + + if (kptab[vk].extended == 0) + { + SP->key_code = FALSE; + return key; + } + } + + /* This case happens if a functional key has been entered. */ + + if ((state & ENHANCED_KEY) && (kptab[vk].extended != 999)) + { + enhanced = TRUE; + idx = kptab[vk].extended; + } + else + { + enhanced = FALSE; + idx = vk; + } + + if (state & SHIFT_PRESSED) + key = enhanced ? ext_kptab[idx].shift : kptab[idx].shift; + + else if (state & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) + key = enhanced ? ext_kptab[idx].control : kptab[idx].control; + + else if (state & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) + key = enhanced ? ext_kptab[idx].alt : kptab[idx].alt; + + else + key = enhanced ? ext_kptab[idx].normal : kptab[idx].normal; + + if (key < KEY_CODE_YES) + SP->key_code = FALSE; + + return key; +} + +static int _process_mouse_event(void) +{ + static const DWORD button_mask[] = {1, 4, 2}; + short action, shift_flags = 0; + int i; + + save_press = 0; + SP->key_code = TRUE; + + memset(&SP->mouse_status, 0, sizeof(MOUSE_STATUS)); + + /* Handle scroll wheel */ + + if (MEV.dwEventFlags == 4) + { + SP->mouse_status.changes = (MEV.dwButtonState & 0xFF000000) ? + PDC_MOUSE_WHEEL_DOWN : PDC_MOUSE_WHEEL_UP; + + SP->mouse_status.x = -1; + SP->mouse_status.y = -1; + + memset(&old_mouse_status, 0, sizeof(old_mouse_status)); + + return KEY_MOUSE; + } + + if (MEV.dwEventFlags == 8) + { + SP->mouse_status.changes = (MEV.dwButtonState & 0xFF000000) ? + PDC_MOUSE_WHEEL_RIGHT : PDC_MOUSE_WHEEL_LEFT; + + SP->mouse_status.x = -1; + SP->mouse_status.y = -1; + + memset(&old_mouse_status, 0, sizeof(old_mouse_status)); + + return KEY_MOUSE; + } + + action = (MEV.dwEventFlags == 2) ? BUTTON_DOUBLE_CLICKED : + ((MEV.dwEventFlags == 1) ? BUTTON_MOVED : BUTTON_PRESSED); + + for (i = 0; i < 3; i++) + SP->mouse_status.button[i] = + (MEV.dwButtonState & button_mask[i]) ? action : 0; + + if (action == BUTTON_PRESSED && MEV.dwButtonState & 7 && SP->mouse_wait) + { + /* Check for a click -- a PRESS followed immediately by a release */ + + if (!event_count) + { + napms(SP->mouse_wait); + + GetNumberOfConsoleInputEvents(pdc_con_in, &event_count); + } + + if (event_count) + { + INPUT_RECORD ip; + DWORD count; + bool have_click = FALSE; + + PeekConsoleInput(pdc_con_in, &ip, 1, &count); + + for (i = 0; i < 3; i++) + { + if (SP->mouse_status.button[i] == BUTTON_PRESSED && + !(ip.Event.MouseEvent.dwButtonState & button_mask[i])) + { + SP->mouse_status.button[i] = BUTTON_CLICKED; + have_click = TRUE; + } + } + + /* If a click was found, throw out the event */ + + if (have_click) + ReadConsoleInput(pdc_con_in, &ip, 1, &count); + } + } + + SP->mouse_status.x = MEV.dwMousePosition.X; + SP->mouse_status.y = MEV.dwMousePosition.Y; + + SP->mouse_status.changes = 0; + + for (i = 0; i < 3; i++) + { + if (old_mouse_status.button[i] != SP->mouse_status.button[i]) + SP->mouse_status.changes |= (1 << i); + + if (SP->mouse_status.button[i] == BUTTON_MOVED) + { + /* Discard non-moved "moves" */ + + if (SP->mouse_status.x == old_mouse_status.x && + SP->mouse_status.y == old_mouse_status.y) + return -1; + + /* Motion events always flag the button as changed */ + + SP->mouse_status.changes |= (1 << i); + SP->mouse_status.changes |= PDC_MOUSE_MOVED; + break; + } + } + + old_mouse_status = SP->mouse_status; + + /* Treat click events as release events for comparison purposes */ + + for (i = 0; i < 3; i++) + { + if (old_mouse_status.button[i] == BUTTON_CLICKED || + old_mouse_status.button[i] == BUTTON_DOUBLE_CLICKED) + old_mouse_status.button[i] = BUTTON_RELEASED; + } + + /* Check for SHIFT/CONTROL/ALT */ + + if (MEV.dwControlKeyState & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) + shift_flags |= BUTTON_ALT; + + if (MEV.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) + shift_flags |= BUTTON_CONTROL; + + if (MEV.dwControlKeyState & SHIFT_PRESSED) + shift_flags |= BUTTON_SHIFT; + + if (shift_flags) + { + for (i = 0; i < 3; i++) + { + if (SP->mouse_status.changes & (1 << i)) + SP->mouse_status.button[i] |= shift_flags; + } + } + + return KEY_MOUSE; +} + +/* return the next available key or mouse event */ + +int PDC_get_key(void) +{ + SP->key_modifiers = 0L; + + if (!key_count) + { + DWORD count; + + ReadConsoleInput(pdc_con_in, &save_ip, 1, &count); + event_count--; + + if (save_ip.EventType == MOUSE_EVENT || + save_ip.EventType == WINDOW_BUFFER_SIZE_EVENT) + key_count = 1; + else if (save_ip.EventType == KEY_EVENT) + key_count = _get_key_count(); + } + + if (key_count) + { + key_count--; + + switch (save_ip.EventType) + { + case KEY_EVENT: + return _process_key_event(); + + case MOUSE_EVENT: + return _process_mouse_event(); + + case WINDOW_BUFFER_SIZE_EVENT: + if (REV.dwSize.Y != LINES || REV.dwSize.X != COLS) + { + if (!SP->resized) + { + SP->resized = TRUE; + SP->key_code = TRUE; + return KEY_RESIZE; + } + } + } + } + + return -1; +} + +/* discard any pending keyboard or mouse input -- this is the core + routine for flushinp() */ + +void PDC_flushinp(void) +{ + PDC_LOG(("PDC_flushinp() - called\n")); + + FlushConsoleInputBuffer(pdc_con_in); +} + +bool PDC_has_mouse(void) +{ + return TRUE; +} + +int PDC_mouse_set(void) +{ + DWORD mode; + + /* If turning on mouse input: Set ENABLE_MOUSE_INPUT, and clear + all other flags, except processed input mode; + If turning off the mouse: Set QuickEdit Mode to the status it + had on startup, and clear all other flags, except etc. */ + + GetConsoleMode(pdc_con_in, &mode); + mode = (mode & 1) | 0x0088; + SetConsoleMode(pdc_con_in, mode | (SP->_trap_mbe ? + ENABLE_MOUSE_INPUT : pdc_quick_edit)); + + memset(&old_mouse_status, 0, sizeof(old_mouse_status)); + + return OK; +} + +int PDC_modifiers_set(void) +{ + return OK; +} diff --git a/Utilities/cmpdcurses/wincon/pdcscrn.c b/Utilities/cmpdcurses/wincon/pdcscrn.c new file mode 100644 index 0000000..e2f4ddd --- /dev/null +++ b/Utilities/cmpdcurses/wincon/pdcscrn.c @@ -0,0 +1,686 @@ +/* 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; +} diff --git a/Utilities/cmpdcurses/wincon/pdcsetsc.c b/Utilities/cmpdcurses/wincon/pdcsetsc.c new file mode 100644 index 0000000..a2d1b6d --- /dev/null +++ b/Utilities/cmpdcurses/wincon/pdcsetsc.c @@ -0,0 +1,130 @@ +/* PDCurses */ + +#include "pdcwin.h" + +/*man-start************************************************************** + +pdcsetsc +-------- + +### Synopsis + + int PDC_set_blink(bool blinkon); + int PDC_set_bold(bool boldon); + void PDC_set_title(const char *title); + +### Description + + PDC_set_blink() toggles whether the A_BLINK attribute sets an actual + blink mode (TRUE), or sets the background color to high intensity + (FALSE). The default is platform-dependent (FALSE in most cases). It + returns OK if it could set the state to match the given parameter, + ERR otherwise. + + PDC_set_bold() toggles whether the A_BOLD attribute selects an actual + bold font (TRUE), or sets the foreground color to high intensity + (FALSE). It returns OK if it could set the state to match the given + parameter, ERR otherwise. + + PDC_set_title() sets the title of the window in which the curses + program is running. This function may not do anything on some + platforms. + +### Portability + X/Open ncurses NetBSD + PDC_set_blink - - - + PDC_set_title - - - + +**man-end****************************************************************/ + +int PDC_curs_set(int visibility) +{ + CONSOLE_CURSOR_INFO cci; + int ret_vis; + + PDC_LOG(("PDC_curs_set() - called: visibility=%d\n", visibility)); + + ret_vis = SP->visibility; + + if (GetConsoleCursorInfo(pdc_con_out, &cci) == FALSE) + return ERR; + + switch(visibility) + { + case 0: /* invisible */ + cci.bVisible = FALSE; + break; + case 2: /* highly visible */ + cci.bVisible = TRUE; + cci.dwSize = 95; + break; + default: /* normal visibility */ + cci.bVisible = TRUE; + cci.dwSize = SP->orig_cursor; + break; + } + + if (SetConsoleCursorInfo(pdc_con_out, &cci) == FALSE) + return ERR; + + SP->visibility = visibility; + return ret_vis; +} + +void PDC_set_title(const char *title) +{ +#ifdef PDC_WIDE + wchar_t wtitle[512]; +#endif + PDC_LOG(("PDC_set_title() - called:<%s>\n", title)); + +#ifdef PDC_WIDE + PDC_mbstowcs(wtitle, title, 511); + SetConsoleTitleW(wtitle); +#else + SetConsoleTitleA(title); +#endif +} + +int PDC_set_blink(bool blinkon) +{ + if (!SP) + return ERR; + + if (SP->color_started) + { + COLORS = 16; + if (PDC_can_change_color()) /* is_nt */ + { + if (pdc_conemu || SetConsoleMode(pdc_con_out, 0x0004)) /* VT */ + COLORS = PDC_MAXCOL; + + if (!pdc_conemu) + SetConsoleMode(pdc_con_out, 0x0010); /* LVB */ + } + } + + if (blinkon) + { + if (!(SP->termattrs & A_BLINK)) + { + SP->termattrs |= A_BLINK; + pdc_last_blink = GetTickCount(); + } + } + else + { + if (SP->termattrs & A_BLINK) + { + SP->termattrs &= ~A_BLINK; + PDC_blink_text(); + } + } + + return OK; +} + +int PDC_set_bold(bool boldon) +{ + return boldon ? ERR : OK; +} diff --git a/Utilities/cmpdcurses/wincon/pdcutil.c b/Utilities/cmpdcurses/wincon/pdcutil.c new file mode 100644 index 0000000..a40cf45 --- /dev/null +++ b/Utilities/cmpdcurses/wincon/pdcutil.c @@ -0,0 +1,26 @@ +/* PDCurses */ + +#include "pdcwin.h" + +void PDC_beep(void) +{ + PDC_LOG(("PDC_beep() - called\n")); + +/* MessageBeep(MB_OK); */ + MessageBeep(0XFFFFFFFF); +} + +void PDC_napms(int ms) +{ + PDC_LOG(("PDC_napms() - called: ms=%d\n", ms)); + + if ((SP->termattrs & A_BLINK) && (GetTickCount() >= pdc_last_blink + 500)) + PDC_blink_text(); + + Sleep(ms); +} + +const char *PDC_sysname(void) +{ + return "Windows"; +} diff --git a/Utilities/cmpdcurses/wincon/pdcwin.h b/Utilities/cmpdcurses/wincon/pdcwin.h new file mode 100644 index 0000000..08d3579 --- /dev/null +++ b/Utilities/cmpdcurses/wincon/pdcwin.h @@ -0,0 +1,27 @@ +/* PDCurses */ + +#if defined(PDC_WIDE) && !defined(UNICODE) +# define UNICODE +#endif + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#undef MOUSE_MOVED +#include <curspriv.h> + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE 1 /* kill nonsense warnings */ +#endif + +typedef struct {short r, g, b; bool mapped;} PDCCOLOR; + +extern PDCCOLOR pdc_color[PDC_MAXCOL]; + +extern HANDLE pdc_con_out, pdc_con_in; +extern DWORD pdc_quick_edit; +extern DWORD pdc_last_blink; +extern short pdc_curstoreal[16], pdc_curstoansi[16]; +extern short pdc_oldf, pdc_oldb, pdc_oldu; +extern bool pdc_conemu, pdc_wt, pdc_ansi; + +extern void PDC_blink_text(void); |