From 1b0f75048707ff8b91abcd37da5bba3f4f29ab5f Mon Sep 17 00:00:00 2001 From: casey langen Date: Sun, 24 Jul 2022 12:15:16 -0700 Subject: [PATCH 1/6] Bill Gray (who works on PDCursesMod) believes the deadlock to be fixed, so let's give the latest upstream code another try! --- src/3rdparty/win32_include/curses.h | 574 ++++---- src/3rdparty/win32_include/curspriv.h | 25 +- src/3rdparty/win32_include/panel.h | 2 + src/3rdparty/win32_include/term.h | 48 + src/3rdparty/win32_src/pdcurses/acs_defs.h | 33 +- src/3rdparty/win32_src/pdcurses/addch.c | 379 ++++-- src/3rdparty/win32_src/pdcurses/addchstr.c | 23 +- src/3rdparty/win32_src/pdcurses/addstr.c | 8 +- src/3rdparty/win32_src/pdcurses/attr.c | 53 +- src/3rdparty/win32_src/pdcurses/beep.c | 1 + src/3rdparty/win32_src/pdcurses/bkgd.c | 6 + src/3rdparty/win32_src/pdcurses/border.c | 71 +- src/3rdparty/win32_src/pdcurses/clear.c | 9 +- src/3rdparty/win32_src/pdcurses/color.c | 437 +++++- src/3rdparty/win32_src/pdcurses/debug.c | 56 +- src/3rdparty/win32_src/pdcurses/delch.c | 7 +- src/3rdparty/win32_src/pdcurses/deleteln.c | 16 +- src/3rdparty/win32_src/pdcurses/getch.c | 142 +- src/3rdparty/win32_src/pdcurses/getstr.c | 53 +- src/3rdparty/win32_src/pdcurses/getyx.c | 9 + src/3rdparty/win32_src/pdcurses/inch.c | 6 + src/3rdparty/win32_src/pdcurses/inchstr.c | 3 + src/3rdparty/win32_src/pdcurses/initscr.c | 83 +- src/3rdparty/win32_src/pdcurses/inopts.c | 33 + src/3rdparty/win32_src/pdcurses/insch.c | 9 +- src/3rdparty/win32_src/pdcurses/insstr.c | 7 +- src/3rdparty/win32_src/pdcurses/instr.c | 7 + src/3rdparty/win32_src/pdcurses/kernel.c | 8 +- src/3rdparty/win32_src/pdcurses/keyname.c | 38 +- src/3rdparty/win32_src/pdcurses/mouse.c | 19 +- src/3rdparty/win32_src/pdcurses/move.c | 2 + src/3rdparty/win32_src/pdcurses/outopts.c | 8 + src/3rdparty/win32_src/pdcurses/overlay.c | 40 +- src/3rdparty/win32_src/pdcurses/pad.c | 84 +- src/3rdparty/win32_src/pdcurses/panel.c | 57 +- src/3rdparty/win32_src/pdcurses/pdcclip.c | 135 ++ src/3rdparty/win32_src/pdcurses/pdccolor.c | 92 +- src/3rdparty/win32_src/pdcurses/pdccolor.h | 4 + src/3rdparty/win32_src/pdcurses/refresh.c | 45 +- src/3rdparty/win32_src/pdcurses/scr_dump.c | 207 ++- src/3rdparty/win32_src/pdcurses/scroll.c | 2 + src/3rdparty/win32_src/pdcurses/slk.c | 30 +- src/3rdparty/win32_src/pdcurses/termattr.c | 5 +- src/3rdparty/win32_src/pdcurses/terminfo.c | 242 ++++ src/3rdparty/win32_src/pdcurses/touch.c | 78 +- src/3rdparty/win32_src/pdcurses/util.c | 235 +++- src/3rdparty/win32_src/pdcurses/winclip.c | 146 ++ .../win32_src/pdcurses/wincon/pdcclip.c | 145 +- .../win32_src/pdcurses/wincon/pdcdisp.c | 212 +-- .../win32_src/pdcurses/wincon/pdckbd.c | 314 +++-- .../win32_src/pdcurses/wincon/pdcscrn.c | 69 +- .../win32_src/pdcurses/wincon/pdcutil.c | 25 +- .../win32_src/pdcurses/wincon/pdcwin.h | 17 +- src/3rdparty/win32_src/pdcurses/window.c | 79 +- .../win32_src/pdcurses/wingui/pdcclip.c | 174 +-- .../win32_src/pdcurses/wingui/pdcdisp.c | 18 +- .../win32_src/pdcurses/wingui/pdckbd.c | 20 +- .../win32_src/pdcurses/wingui/pdcscrn.c | 1178 ++++++++--------- .../win32_src/pdcurses/wingui/pdcsetsc.c | 15 + .../win32_src/pdcurses/wingui/pdcutil.c | 49 +- .../win32_src/pdcurses/wingui/pdcwin.h | 60 +- src/musikcube/cursespp/App.cpp | 3 +- src/musikcube/musikcube.vcxproj | 24 +- 63 files changed, 3831 insertions(+), 2148 deletions(-) create mode 100644 src/3rdparty/win32_include/term.h create mode 100644 src/3rdparty/win32_src/pdcurses/pdcclip.c create mode 100644 src/3rdparty/win32_src/pdcurses/terminfo.c create mode 100644 src/3rdparty/win32_src/pdcurses/winclip.c diff --git a/src/3rdparty/win32_include/curses.h b/src/3rdparty/win32_include/curses.h index 12881347b..532c3edfb 100755 --- a/src/3rdparty/win32_include/curses.h +++ b/src/3rdparty/win32_include/curses.h @@ -1,9 +1,10 @@ /*----------------------------------------------------------------------* - * PDCurses * + * PDCursesMod * *----------------------------------------------------------------------*/ #ifndef __PDCURSES__ #define __PDCURSES__ 1 +#define __PDCURSESMOD__ 1 /*man-start************************************************************** @@ -13,6 +14,7 @@ Define before inclusion (only those needed): PDC_RGB if you want to use RGB color definitions (Red = 1, Green = 2, Blue = 4) instead of BGR PDC_WIDE if building / built with wide-character support + PDC_FORCE_UTF8 if forcing use of UTF8 (implies PDC_WIDE) PDC_DLL_BUILD if building / built as a Windows DLL PDC_NCMOUSE to use the ncurses mouse API instead of PDCurses' traditional mouse API @@ -23,18 +25,24 @@ Defined by this header: PDC_BUILD API build version PDC_VER_MAJOR major version number PDC_VER_MINOR minor version number + PDC_VER_CHANGE version change number + PDC_VER_YEAR year of version + PDC_VER_MONTH month of version + PDC_VER_DAY day of month of version PDC_VERDOT version string **man-end****************************************************************/ #define PDCURSES 1 #define PDC_BUILD (PDC_VER_MAJOR*1000 + PDC_VER_MINOR *100 + PDC_VER_CHANGE) + /* NOTE : For version changes that are not backward compatible, */ + /* the 'endwin_*' #defines below should be updated. */ #define PDC_VER_MAJOR 4 -#define PDC_VER_MINOR 1 -#define PDC_VER_CHANGE 99 -#define PDC_VER_YEAR 2020 -#define PDC_VER_MONTH 05 -#define PDC_VER_DAY 20 +#define PDC_VER_MINOR 3 +#define PDC_VER_CHANGE 3 +#define PDC_VER_YEAR 2022 +#define PDC_VER_MONTH 07 +#define PDC_VER_DAY 24 #define PDC_STRINGIZE( x) #x #define PDC_stringize( x) PDC_STRINGIZE( x) @@ -43,7 +51,9 @@ Defined by this header: PDC_stringize( PDC_VER_MINOR) "." \ PDC_stringize( PDC_VER_CHANGE) -#define CHTYPE_LONG 1 /* chtype >= 32 bits */ +#define PDC_VER_YMD PDC_stringize( PDC_VER_YEAR) "-" \ + PDC_stringize( PDC_VER_MONTH) "-" \ + PDC_stringize( PDC_VER_DAY) #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L # define PDC_99 1 @@ -59,6 +69,10 @@ Defined by this header: #include #include +#if defined( PDC_FORCE_UTF8) && !defined( PDC_WIDE) + #define PDC_WIDE +#endif + #ifdef PDC_WIDE # include #endif @@ -79,6 +93,8 @@ extern "C" #define uint64_t unsigned __int64 #define uint32_t unsigned long #define uint16_t unsigned short + #define int32_t long + #define int16_t short #else #include #endif @@ -104,15 +120,14 @@ extern "C" #if !defined(PDC_PP98) && !defined(__bool_true_false_are_defined) typedef unsigned char bool; #endif - + #if defined( CHTYPE_32) - #if defined( CHTYPE_64) - #error CHTYPE cannot be both CHTYPE_32 and CHTYPE_64 - #endif typedef uint32_t chtype; /* chtypes will be 32 bits */ + typedef uint32_t mmask_t; #else - #define CHTYPE_64 typedef uint64_t chtype; /* chtypes will be 64 bits */ + typedef uint64_t mmask_t; + #define PDC_LONG_MMASK #ifdef PDC_WIDE #define USING_COMBINING_CHARACTER_SCHEME #endif @@ -140,7 +155,9 @@ enum PDC_port PDC_PORT_SDL1 = 5, PDC_PORT_SDL2 = 6, PDC_PORT_VT = 7, - PDC_PORT_DOSVGA = 8 + PDC_PORT_DOSVGA = 8, + PDC_PORT_PLAN9 = 9, + PDC_PORT_LINUX_FB = 10 }; /* Use this structure with PDC_get_version() for run-time info about the @@ -175,12 +192,6 @@ enum #define PDC_MAX_MOUSE_BUTTONS 9 -#if _LP64 -typedef unsigned int mmask_t; -#else -typedef unsigned long mmask_t; -#endif - typedef struct { int x; /* absolute column, 0 based, measured in characters */ @@ -214,21 +225,21 @@ typedef struct * 10 <- button 2 has changed 1 * 100 <- button 3 has changed 2 * 1000 <- mouse has moved 3 - * 10000 <- mouse position report 4 + * (Not actually used!) 10000 <- mouse position report 4 * 100000 <- mouse wheel up 5 * 1000000 <- mouse wheel down 6 * 10000000 <- mouse wheel left 7 * 100000000 <- mouse wheel right 8 - * 1000000000 <- button 4 has changed 9 - * (NOTE: buttons 6 to 10000000000 <- button 5 has changed 10 - * 9 aren't implemented 100000000000 <- button 6 has changed 11 - * in any flavor of 1000000000000 <- button 7 has changed 12 - * PDCurses yet!) 10000000000000 <- button 8 has changed 13 + * (Buttons 4 and up are 1000000000 <- button 4 has changed 9 + * PDCursesMod-only, 10000000000 <- button 5 has changed 10 + * and only 4 & 5 are 100000000000 <- button 6 has changed 11 + * currently used) 1000000000000 <- button 7 has changed 12 + * 10000000000000 <- button 8 has changed 13 * 100000000000000 <- button 9 has changed 14 */ #define PDC_MOUSE_MOVED 0x0008 -#define PDC_MOUSE_POSITION 0x0010 +#define PDC_MOUSE_UNUSED_BIT 0x0010 #define PDC_MOUSE_WHEEL_UP 0x0020 #define PDC_MOUSE_WHEEL_DOWN 0x0040 #define PDC_MOUSE_WHEEL_LEFT 0x0080 @@ -236,7 +247,6 @@ typedef struct #define A_BUTTON_CHANGED (Mouse_status.changes & 7) #define MOUSE_MOVED (Mouse_status.changes & PDC_MOUSE_MOVED) -#define MOUSE_POS_REPORT (Mouse_status.changes & PDC_MOUSE_POSITION) #define BUTTON_CHANGED(x) (Mouse_status.changes & (1 << ((x) - ((x)<4 ? 1 : -5)))) #define BUTTON_STATUS(x) (Mouse_status.button[(x) - 1]) #define MOUSE_WHEEL_UP (Mouse_status.changes & PDC_MOUSE_WHEEL_UP) @@ -246,26 +256,39 @@ typedef struct /* mouse bit-masks */ -#define BUTTON1_RELEASED 0x00000001L -#define BUTTON1_PRESSED 0x00000002L -#define BUTTON1_CLICKED 0x00000004L -#define BUTTON1_DOUBLE_CLICKED 0x00000008L -#define BUTTON1_TRIPLE_CLICKED 0x00000010L -#define BUTTON1_MOVED 0x00000010L /* PDCurses */ +#define BUTTON1_RELEASED (mmask_t)0x01 +#define BUTTON1_PRESSED (mmask_t)0x02 +#define BUTTON1_CLICKED (mmask_t)0x04 +#define BUTTON1_DOUBLE_CLICKED (mmask_t)0x08 +#define BUTTON1_TRIPLE_CLICKED (mmask_t)0x10 -#define BUTTON2_RELEASED 0x00000020L -#define BUTTON2_PRESSED 0x00000040L -#define BUTTON2_CLICKED 0x00000080L -#define BUTTON2_DOUBLE_CLICKED 0x00000100L -#define BUTTON2_TRIPLE_CLICKED 0x00000200L -#define BUTTON2_MOVED 0x00000200L /* PDCurses */ +/* With the "traditional" 32-bit mmask_t, mouse move and triple-clicks +share the same bit and can't be distinguished. 64-bit mmask_ts allow us +to make the distinction, and will allow other events to be added later. */ -#define BUTTON3_RELEASED 0x00000400L -#define BUTTON3_PRESSED 0x00000800L -#define BUTTON3_CLICKED 0x00001000L -#define BUTTON3_DOUBLE_CLICKED 0x00002000L -#define BUTTON3_TRIPLE_CLICKED 0x00004000L -#define BUTTON3_MOVED 0x00004000L /* PDCurses */ +#ifdef PDC_LONG_MMASK + #define BUTTON1_MOVED (mmask_t)0x20 /* PDCurses */ + #define PDC_BITS_PER_BUTTON 6 +#else + #define BUTTON1_MOVED (mmask_t)0x10 /* PDCurses */ + #define PDC_BITS_PER_BUTTON 5 +#endif + +#define PDC_SHIFTED_BUTTON( button, n) ((mmask_t)(button) << (((n) - 1) * PDC_BITS_PER_BUTTON)) + +#define BUTTON2_RELEASED PDC_SHIFTED_BUTTON( BUTTON1_RELEASED, 2) +#define BUTTON2_PRESSED PDC_SHIFTED_BUTTON( BUTTON1_PRESSED, 2) +#define BUTTON2_CLICKED PDC_SHIFTED_BUTTON( BUTTON1_CLICKED, 2) +#define BUTTON2_DOUBLE_CLICKED PDC_SHIFTED_BUTTON( BUTTON1_DOUBLE_CLICKED, 2) +#define BUTTON2_TRIPLE_CLICKED PDC_SHIFTED_BUTTON( BUTTON1_TRIPLE_CLICKED, 2) +#define BUTTON2_MOVED PDC_SHIFTED_BUTTON( BUTTON1_MOVED, 2) + +#define BUTTON3_RELEASED PDC_SHIFTED_BUTTON( BUTTON1_RELEASED, 3) +#define BUTTON3_PRESSED PDC_SHIFTED_BUTTON( BUTTON1_PRESSED, 3) +#define BUTTON3_CLICKED PDC_SHIFTED_BUTTON( BUTTON1_CLICKED, 3) +#define BUTTON3_DOUBLE_CLICKED PDC_SHIFTED_BUTTON( BUTTON1_DOUBLE_CLICKED, 3) +#define BUTTON3_TRIPLE_CLICKED PDC_SHIFTED_BUTTON( BUTTON1_TRIPLE_CLICKED, 3) +#define BUTTON3_MOVED PDC_SHIFTED_BUTTON( BUTTON1_MOVED, 3) /* For the ncurses-compatible functions only, BUTTON4_PRESSED and BUTTON5_PRESSED are returned for mouse scroll wheel up and down; @@ -273,25 +296,27 @@ typedef struct as described above for WinGUI, and perhaps to be extended to other PDCurses flavors */ -#define BUTTON4_RELEASED 0x00008000L -#define BUTTON4_PRESSED 0x00010000L -#define BUTTON4_CLICKED 0x00020000L -#define BUTTON4_DOUBLE_CLICKED 0x00040000L -#define BUTTON4_TRIPLE_CLICKED 0x00080000L +#define BUTTON4_RELEASED PDC_SHIFTED_BUTTON( BUTTON1_RELEASED, 4) +#define BUTTON4_PRESSED PDC_SHIFTED_BUTTON( BUTTON1_PRESSED, 4) +#define BUTTON4_CLICKED PDC_SHIFTED_BUTTON( BUTTON1_CLICKED, 4) +#define BUTTON4_DOUBLE_CLICKED PDC_SHIFTED_BUTTON( BUTTON1_DOUBLE_CLICKED, 4) +#define BUTTON4_TRIPLE_CLICKED PDC_SHIFTED_BUTTON( BUTTON1_TRIPLE_CLICKED, 4) +#define BUTTON4_MOVED PDC_SHIFTED_BUTTON( BUTTON1_MOVED, 4) -#define BUTTON5_RELEASED 0x00100000L -#define BUTTON5_PRESSED 0x00200000L -#define BUTTON5_CLICKED 0x00400000L -#define BUTTON5_DOUBLE_CLICKED 0x00800000L -#define BUTTON5_TRIPLE_CLICKED 0x01000000L +#define BUTTON5_RELEASED PDC_SHIFTED_BUTTON( BUTTON1_RELEASED, 5) +#define BUTTON5_PRESSED PDC_SHIFTED_BUTTON( BUTTON1_PRESSED, 5) +#define BUTTON5_CLICKED PDC_SHIFTED_BUTTON( BUTTON1_CLICKED, 5) +#define BUTTON5_DOUBLE_CLICKED PDC_SHIFTED_BUTTON( BUTTON1_DOUBLE_CLICKED, 5) +#define BUTTON5_TRIPLE_CLICKED PDC_SHIFTED_BUTTON( BUTTON1_TRIPLE_CLICKED, 5) +#define BUTTON5_MOVED PDC_SHIFTED_BUTTON( BUTTON1_MOVED, 5) -#define MOUSE_WHEEL_SCROLL 0x02000000L /* PDCurses */ -#define BUTTON_MODIFIER_SHIFT 0x04000000L /* PDCurses */ -#define BUTTON_MODIFIER_CONTROL 0x08000000L /* PDCurses */ -#define BUTTON_MODIFIER_ALT 0x10000000L /* PDCurses */ +#define MOUSE_WHEEL_SCROLL PDC_SHIFTED_BUTTON( BUTTON1_RELEASED, 6) +#define BUTTON_MODIFIER_SHIFT (MOUSE_WHEEL_SCROLL << 1) +#define BUTTON_MODIFIER_CONTROL (MOUSE_WHEEL_SCROLL << 2) +#define BUTTON_MODIFIER_ALT (MOUSE_WHEEL_SCROLL << 3) +#define REPORT_MOUSE_POSITION (MOUSE_WHEEL_SCROLL << 4) -#define ALL_MOUSE_EVENTS 0x1fffffffL -#define REPORT_MOUSE_POSITION 0x20000000L +#define ALL_MOUSE_EVENTS (REPORT_MOUSE_POSITION - 1) /* ncurses mouse interface */ @@ -350,16 +375,11 @@ typedef struct _win /* definition of a window */ int _delayms; /* milliseconds of delay for getch() */ int _parx, _pary; /* coords relative to parent (0,0) */ struct _win *_parent; /* subwin's pointer to parent win */ + int _pminrow, _pmincol; /* saved position used only for pads */ + int _sminrow, _smaxrow; /* saved position used only for pads */ + int _smincol, _smaxcol; /* saved position used only for pads */ } WINDOW; -/* Color pair structure */ - -typedef struct -{ - int f; /* foreground color */ - int b; /* background color */ -} PDC_PAIR; - /* Avoid using the SCREEN struct directly -- use the corresponding functions if possible. This struct may eventually be made private. */ @@ -402,8 +422,8 @@ typedef struct on last key press */ bool return_key_modifiers; /* TRUE if modifier keys are returned as "real" keys */ - bool key_code; /* TRUE if last key is a special key; - used internally by get_wch() */ + bool in_endwin; /* if we're in endwin(), we should use + only signal-safe code */ MOUSE_STATUS mouse_status; /* last returned mouse status */ short line_color; /* color of line attributes - default -1 */ attr_t termattrs; /* attribute capabilities */ @@ -419,7 +439,7 @@ typedef struct int *c_ungch; /* array of ungotten chars */ int c_ungind; /* ungetch() push index */ int c_ungmax; /* allocated size of ungetch() buffer */ - PDC_PAIR *atrtab; /* table of color pairs */ + void *atrtab; /* table of color pairs */ } SCREEN; /*---------------------------------------------------------------------- @@ -455,34 +475,51 @@ PDCEX char ttytype[]; /* terminal name/description */ Text Attributes =============== -If CHTYPE_32 is #defined, PDCurses uses a 32-bit integer for its chtype: +By default, PDCurses uses 64-bit integers for its chtype. All chtypes +have bits devoted to character data, attribute data, and color pair data. +There are three configurations supported : +Default, 64-bit chtype, both wide- and 8-bit character builds: +------------------------------------------------------------------------------- +|63|62|..|53|52|..|34|33|32|31|30|29|28|..|22|21|20|19|18|17|16|..| 3| 2| 1| 0| +------------------------------------------------------------------------------- + unused |color pair | modifiers | character eg 'a' + + 21 character bits (0-20), enough for full Unicode coverage + 12 attribute bits (21-32) + 20 color pair bits (33-52), enough for 1048576 color pairs + 11 currently unused bits (53-63) + +32-bit chtypes with wide characters (CHTYPE_32 and PDC_WIDE are #defined): +--------------------------------------------------------------------+ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|..| 2| 1| 0| +--------------------------------------------------------------------+ color pair | modifiers | character eg 'a' + 16 character bits (0-16), enough for BMP (Unicode below 64K) + 8 attribute bits (16-23) + 8 color pair bits (24-31), for 256 color pairs -There are 256 color pairs (8 bits), 8 bits for modifiers, and 16 bits -for character data. The modifiers are bold, underline, right-line, -left-line, italic, reverse and blink, plus the alternate character set -indicator. +32-bit chtypes with narrow characters (CHTYPE_32 #defined, PDC_WIDE is not): + +--------------------------------------------------------------------+ + |31|30|29|28|..|22|21|20|19|18|17|16|..|12|11|10| 9| 8| 7| 6|..| 1| 0| + +--------------------------------------------------------------------+ + color pair | modifiers |character + 8 character bits (0-7); only 8-bit charsets will work + 12 attribute bits (8-19) + 12 color pair bits (20-31), for 4096 pairs - By default, a 64-bit chtype is used : +All attribute modifier schemes include eight "basic" bits: bold, underline, +right-line, left-line, italic, reverse and blink attributes, plus the +alternate character set indicator. For default and 32-bit narrow builds, +three more bits are used for overlined, dimmed, and strikeout attributes; +a fourth bit is reserved. -------------------------------------------------------------------------------- -|63|62|61|60|59|..|34|33|32|31|30|29|28|..|22|21|20|19|18|17|16|..| 3| 2| 1| 0| -------------------------------------------------------------------------------- - color number | modifiers | character eg 'a' - - We take five more bits for the character (thus allowing Unicode values -past 64K; the full range of Unicode goes up to 0x10ffff, requiring 21 bits -total), and four more bits for attributes. Three are currently used as -A_OVERLINE, A_DIM, and A_STRIKEOUT; one more is reserved for future use. -On some platforms, bits 33-40 are used to select a color pair (can run from -0 to 255). Bits 41 and 42 have been added to this to get 1024 color pairs. -On some platforms (as of 2020 May 17, WinGUI and VT), bits 33-52 are used, -allowing 2^20 = 1048576 color pairs. That should be enough for anybody, and -leaves twelve bits for other uses. +Default chtypes have enough character bits to support the full range of +Unicode, all attributes, and 2^20 = 1048576 color pairs. Note, though, +that as of 2022 Jun 17, only WinGUI, VT, X11, Linux framebuffer, and +SDLn have COLOR_PAIRS = 1048576. Other platforms (DOSVGA, Plan9, WinCon) +may join them. Some (DOS, OS/2) simply do not have full-color +capability. **man-end****************************************************************/ @@ -490,59 +527,59 @@ leaves twelve bits for other uses. #define A_NORMAL (chtype)0 -#ifdef CHTYPE_64 +#ifndef CHTYPE_32 + /* 64-bit chtypes, both wide- and narrow */ # define PDC_CHARTEXT_BITS 21 - # define A_CHARTEXT (chtype)( ((chtype)0x1 << PDC_CHARTEXT_BITS) - 1) - # define A_ALTCHARSET ((chtype)0x001 << PDC_CHARTEXT_BITS) - # define A_RIGHT ((chtype)0x002 << PDC_CHARTEXT_BITS) - # define A_LEFT ((chtype)0x004 << PDC_CHARTEXT_BITS) - # define A_INVIS ((chtype)0x008 << PDC_CHARTEXT_BITS) - # define A_UNDERLINE ((chtype)0x010 << PDC_CHARTEXT_BITS) - # define A_REVERSE ((chtype)0x020 << PDC_CHARTEXT_BITS) - # define A_BLINK ((chtype)0x040 << PDC_CHARTEXT_BITS) - # define A_BOLD ((chtype)0x080 << PDC_CHARTEXT_BITS) - # define A_OVERLINE ((chtype)0x100 << PDC_CHARTEXT_BITS) - # define A_STRIKEOUT ((chtype)0x200 << PDC_CHARTEXT_BITS) - # define A_DIM ((chtype)0x400 << PDC_CHARTEXT_BITS) -#if 0 - /* May come up with a use for this bit */ - /* someday; reserved for the future: */ - # define A_FUTURE_2 ((chtype)0x800 << PDC_CHARTEXT_BITS) -#endif - # define PDC_COLOR_SHIFT (PDC_CHARTEXT_BITS + 12) - # define A_COLOR ((chtype)0x7fffffff << PDC_COLOR_SHIFT) - # define A_ATTRIBUTES (((chtype)0xfff << PDC_CHARTEXT_BITS) | A_COLOR) -# else /* plain ol' 32-bit chtypes */ - # define PDC_CHARTEXT_BITS 16 - # define A_ALTCHARSET (chtype)0x00010000 - # define A_RIGHT (chtype)0x00020000 - # define A_LEFT (chtype)0x00040000 - # define A_INVIS (chtype)0x00080000 - # define A_UNDERLINE (chtype)0x00100000 - # define A_REVERSE (chtype)0x00200000 - # define A_BLINK (chtype)0x00400000 - # define A_BOLD (chtype)0x00800000 - # define A_COLOR (chtype)0xff000000 - # define PDC_COLOR_SHIFT 24 + # define PDC_ATTRIBUTE_BITS 12 + # define PDC_COLOR_BITS 20 +# else #ifdef PDC_WIDE - # define A_CHARTEXT (chtype)0x0000ffff - # define A_ATTRIBUTES (chtype)0xffff0000 - # define A_DIM A_NORMAL - # define A_OVERLINE A_NORMAL - # define A_STRIKEOUT A_NORMAL -#else /* with 8-bit chars, we have bits for these attribs : */ - # define A_CHARTEXT (chtype)0x000000ff - # define A_ATTRIBUTES (chtype)0xffffe000 - # define A_DIM (chtype)0x00008000 - # define A_OVERLINE (chtype)0x00004000 - # define A_STRIKEOUT (chtype)0x00002000 + /* 32-bit chtypes, wide character */ + # define PDC_CHARTEXT_BITS 16 + # define PDC_ATTRIBUTE_BITS 8 + # define PDC_COLOR_BITS 8 +#else + /* 32-bit chtypes, narrow (8-bit) characters */ + # define PDC_CHARTEXT_BITS 8 + # define PDC_ATTRIBUTE_BITS 12 + # define PDC_COLOR_BITS 12 #endif #endif +# define PDC_COLOR_SHIFT (PDC_CHARTEXT_BITS + PDC_ATTRIBUTE_BITS) +# define A_COLOR ((((chtype)1 << PDC_COLOR_BITS) - 1) << PDC_COLOR_SHIFT) +# define A_ATTRIBUTES (((((chtype)1 << PDC_ATTRIBUTE_BITS) - 1) << PDC_CHARTEXT_BITS) | A_COLOR) +# define A_CHARTEXT (((chtype)1 << PDC_CHARTEXT_BITS) - 1) + +#define PDC_ATTRIBUTE_BIT( N) ((chtype)1 << (N)) +# define A_ALTCHARSET PDC_ATTRIBUTE_BIT( PDC_CHARTEXT_BITS) +# define A_RIGHT PDC_ATTRIBUTE_BIT( PDC_CHARTEXT_BITS + 1) +# define A_LEFT PDC_ATTRIBUTE_BIT( PDC_CHARTEXT_BITS + 2) +# define A_INVIS PDC_ATTRIBUTE_BIT( PDC_CHARTEXT_BITS + 3) +# define A_UNDERLINE PDC_ATTRIBUTE_BIT( PDC_CHARTEXT_BITS + 4) +# define A_REVERSE PDC_ATTRIBUTE_BIT( PDC_CHARTEXT_BITS + 5) +# define A_BLINK PDC_ATTRIBUTE_BIT( PDC_CHARTEXT_BITS + 6) +# define A_BOLD PDC_ATTRIBUTE_BIT( PDC_CHARTEXT_BITS + 7) +#if PDC_COLOR_BITS >= 11 + # define A_OVERLINE PDC_ATTRIBUTE_BIT( PDC_CHARTEXT_BITS + 8) + # define A_STRIKEOUT PDC_ATTRIBUTE_BIT( PDC_CHARTEXT_BITS + 9) + # define A_DIM PDC_ATTRIBUTE_BIT( PDC_CHARTEXT_BITS + 10) +/* Reserved bit : PDC_ATTRIBUTE_BIT( PDC_CHARTEXT_BITS + 11) */ +#else + # define A_DIM A_NORMAL + # define A_OVERLINE A_NORMAL + # define A_STRIKEOUT A_NORMAL +#endif + #define A_ITALIC A_INVIS -#define A_PROTECT (A_UNDERLINE | A_LEFT | A_RIGHT) +#define A_PROTECT (A_UNDERLINE | A_LEFT | A_RIGHT | A_OVERLINE) #define A_STANDOUT (A_REVERSE | A_BOLD) /* X/Open */ +#define A_HORIZONTAL A_NORMAL +#define A_LOW A_NORMAL +#define A_TOP A_NORMAL +#define A_VERTICAL A_NORMAL + #define CHR_MSK A_CHARTEXT /* Obsolete */ #define ATR_MSK A_ATTRIBUTES /* Obsolete */ #define ATR_NRM A_NORMAL /* Obsolete */ @@ -717,7 +754,11 @@ Some won't work in non-wide X11 builds (see 'acs_defs.h' for details). */ #define ACS_NEQUAL PDC_ACS('%') #define ACS_STERLING PDC_ACS('~') -/* Box char aliases */ +/* Box char aliases. The four characters tell you if a Single +line points up, right, down, and/or left from the center; +or if it's Blank; or if it's Thick or Double. The Thick +ones are an ncurses extension; the Double and Single/Double +ones are a PDCursesMod extension. */ #define ACS_BSSB ACS_ULCORNER #define ACS_SSBB ACS_LLCORNER @@ -823,6 +864,18 @@ Some won't work in non-wide X11 builds (see 'acs_defs.h' for details). */ # define WACS_D_BTEE (&(acs_map['K'])) # define WACS_D_TTEE (&(acs_map['L'])) +# define WACS_T_LRCORNER (&(acs_map[0])) +# define WACS_T_URCORNER (&(acs_map[1])) +# define WACS_T_ULCORNER (&(acs_map[2])) +# define WACS_T_LLCORNER (&(acs_map[3])) +# define WACS_T_PLUS (&(acs_map[4])) +# define WACS_T_LTEE (&(acs_map[5])) +# define WACS_T_RTEE (&(acs_map[6])) +# define WACS_T_BTEE (&(acs_map[7])) +# define WACS_T_TTEE (&(acs_map[8])) +# define WACS_T_HLINE (&(acs_map[9])) +# define WACS_T_VLINE (&(acs_map[10])) + # define WACS_DS_LRCORNER (&(acs_map['M'])) # define WACS_DS_URCORNER (&(acs_map['N'])) # define WACS_DS_ULCORNER (&(acs_map['O'])) @@ -870,6 +923,18 @@ Some won't work in non-wide X11 builds (see 'acs_defs.h' for details). */ # define WACS_BSBS WACS_HLINE # define WACS_SBSB WACS_VLINE # define WACS_SSSS WACS_PLUS + +# define WACS_BTTB WACS_T_ULCORNER +# define WACS_TTBB WACS_T_LLCORNER +# define WACS_BBTT WACS_T_URCORNER +# define WACS_TBBT WACS_T_LRCORNER +# define WACS_TBTT WACS_T_RTEE +# define WACS_TTTB WACS_T_LTEE +# define WACS_TTBT WACS_T_BTEE +# define WACS_BTTS WACS_T_TTEE +# define WACS_BTBT WACS_T_HLINE +# define WACS_TBTB WACS_T_VLINE +# define WACS_TTTT WACS_T_PLUS #endif /*** Color macros ***/ @@ -1075,7 +1140,8 @@ Some won't work in non-wide X11 builds (see 'acs_defs.h' for details). */ #define ALT_DEL (KEY_OFFSET + 0xde) /* alt-delete */ #define ALT_INS (KEY_OFFSET + 0xdf) /* alt-insert */ #define CTL_UP (KEY_OFFSET + 0xe0) /* ctl-up arrow */ -#define CTL_DOWN (KEY_OFFSET + 0xe1) /* ctl-down arrow */ +#define CTL_DOWN (KEY_OFFSET + 0xe1) /* ctl-down arrow: orig PDCurses def */ +#define CTL_DN (KEY_OFFSET + 0xe1) /* ctl-down arrow: ncurses def */ #define CTL_TAB (KEY_OFFSET + 0xe2) /* ctl-tab */ #define ALT_TAB (KEY_OFFSET + 0xe3) #define ALT_MINUS (KEY_OFFSET + 0xe4) @@ -1149,117 +1215,45 @@ Some won't work in non-wide X11 builds (see 'acs_defs.h' for details). */ #define KEY_SUP (KEY_OFFSET + 0x123) /* Shifted up arrow */ #define KEY_SDOWN (KEY_OFFSET + 0x124) /* Shifted down arrow */ - /* The following were added 2011 Sep 14, and are */ - /* not returned by most flavors of PDCurses: */ + /* The following are PDCursesMod extensions. Even there, not all + platforms support them. */ -#define CTL_SEMICOLON (KEY_OFFSET + 0x125) -#define CTL_EQUAL (KEY_OFFSET + 0x126) -#define CTL_COMMA (KEY_OFFSET + 0x127) -#define CTL_MINUS (KEY_OFFSET + 0x128) -#define CTL_STOP (KEY_OFFSET + 0x129) -#define CTL_FSLASH (KEY_OFFSET + 0x12a) -#define CTL_BQUOTE (KEY_OFFSET + 0x12b) +#define KEY_APPS (KEY_OFFSET + 0x125) -#define KEY_APPS (KEY_OFFSET + 0x12c) -#define KEY_SAPPS (KEY_OFFSET + 0x12d) -#define CTL_APPS (KEY_OFFSET + 0x12e) -#define ALT_APPS (KEY_OFFSET + 0x12f) +#define KEY_PAUSE (KEY_OFFSET + 0x126) -#define KEY_PAUSE (KEY_OFFSET + 0x130) -#define KEY_SPAUSE (KEY_OFFSET + 0x131) -#define CTL_PAUSE (KEY_OFFSET + 0x132) +#define KEY_PRINTSCREEN (KEY_OFFSET + 0x127) +#define KEY_SCROLLLOCK (KEY_OFFSET + 0x128) -#define KEY_PRINTSCREEN (KEY_OFFSET + 0x133) -#define ALT_PRINTSCREEN (KEY_OFFSET + 0x134) -#define KEY_SCROLLLOCK (KEY_OFFSET + 0x135) -#define ALT_SCROLLLOCK (KEY_OFFSET + 0x136) - -#define CTL_0 (KEY_OFFSET + 0x137) -#define CTL_1 (KEY_OFFSET + 0x138) -#define CTL_2 (KEY_OFFSET + 0x139) -#define CTL_3 (KEY_OFFSET + 0x13a) -#define CTL_4 (KEY_OFFSET + 0x13b) -#define CTL_5 (KEY_OFFSET + 0x13c) -#define CTL_6 (KEY_OFFSET + 0x13d) -#define CTL_7 (KEY_OFFSET + 0x13e) -#define CTL_8 (KEY_OFFSET + 0x13f) -#define CTL_9 (KEY_OFFSET + 0x140) - -#define KEY_BROWSER_BACK (KEY_OFFSET + 0x141) -#define KEY_SBROWSER_BACK (KEY_OFFSET + 0x142) -#define KEY_CBROWSER_BACK (KEY_OFFSET + 0x143) -#define KEY_ABROWSER_BACK (KEY_OFFSET + 0x144) -#define KEY_BROWSER_FWD (KEY_OFFSET + 0x145) -#define KEY_SBROWSER_FWD (KEY_OFFSET + 0x146) -#define KEY_CBROWSER_FWD (KEY_OFFSET + 0x147) -#define KEY_ABROWSER_FWD (KEY_OFFSET + 0x148) -#define KEY_BROWSER_REF (KEY_OFFSET + 0x149) -#define KEY_SBROWSER_REF (KEY_OFFSET + 0x14A) -#define KEY_CBROWSER_REF (KEY_OFFSET + 0x14B) -#define KEY_ABROWSER_REF (KEY_OFFSET + 0x14C) -#define KEY_BROWSER_STOP (KEY_OFFSET + 0x14D) -#define KEY_SBROWSER_STOP (KEY_OFFSET + 0x14E) -#define KEY_CBROWSER_STOP (KEY_OFFSET + 0x14F) -#define KEY_ABROWSER_STOP (KEY_OFFSET + 0x150) -#define KEY_SEARCH (KEY_OFFSET + 0x151) -#define KEY_SSEARCH (KEY_OFFSET + 0x152) -#define KEY_CSEARCH (KEY_OFFSET + 0x153) -#define KEY_ASEARCH (KEY_OFFSET + 0x154) -#define KEY_FAVORITES (KEY_OFFSET + 0x155) -#define KEY_SFAVORITES (KEY_OFFSET + 0x156) -#define KEY_CFAVORITES (KEY_OFFSET + 0x157) -#define KEY_AFAVORITES (KEY_OFFSET + 0x158) -#define KEY_BROWSER_HOME (KEY_OFFSET + 0x159) -#define KEY_SBROWSER_HOME (KEY_OFFSET + 0x15A) -#define KEY_CBROWSER_HOME (KEY_OFFSET + 0x15B) -#define KEY_ABROWSER_HOME (KEY_OFFSET + 0x15C) -#define KEY_VOLUME_MUTE (KEY_OFFSET + 0x15D) -#define KEY_SVOLUME_MUTE (KEY_OFFSET + 0x15E) -#define KEY_CVOLUME_MUTE (KEY_OFFSET + 0x15F) -#define KEY_AVOLUME_MUTE (KEY_OFFSET + 0x160) -#define KEY_VOLUME_DOWN (KEY_OFFSET + 0x161) -#define KEY_SVOLUME_DOWN (KEY_OFFSET + 0x162) -#define KEY_CVOLUME_DOWN (KEY_OFFSET + 0x163) -#define KEY_AVOLUME_DOWN (KEY_OFFSET + 0x164) -#define KEY_VOLUME_UP (KEY_OFFSET + 0x165) -#define KEY_SVOLUME_UP (KEY_OFFSET + 0x166) -#define KEY_CVOLUME_UP (KEY_OFFSET + 0x167) -#define KEY_AVOLUME_UP (KEY_OFFSET + 0x168) -#define KEY_NEXT_TRACK (KEY_OFFSET + 0x169) -#define KEY_SNEXT_TRACK (KEY_OFFSET + 0x16A) -#define KEY_CNEXT_TRACK (KEY_OFFSET + 0x16B) -#define KEY_ANEXT_TRACK (KEY_OFFSET + 0x16C) -#define KEY_PREV_TRACK (KEY_OFFSET + 0x16D) -#define KEY_SPREV_TRACK (KEY_OFFSET + 0x16E) -#define KEY_CPREV_TRACK (KEY_OFFSET + 0x16F) -#define KEY_APREV_TRACK (KEY_OFFSET + 0x170) -#define KEY_MEDIA_STOP (KEY_OFFSET + 0x171) -#define KEY_SMEDIA_STOP (KEY_OFFSET + 0x172) -#define KEY_CMEDIA_STOP (KEY_OFFSET + 0x173) -#define KEY_AMEDIA_STOP (KEY_OFFSET + 0x174) -#define KEY_PLAY_PAUSE (KEY_OFFSET + 0x175) -#define KEY_SPLAY_PAUSE (KEY_OFFSET + 0x176) -#define KEY_CPLAY_PAUSE (KEY_OFFSET + 0x177) -#define KEY_APLAY_PAUSE (KEY_OFFSET + 0x178) -#define KEY_LAUNCH_MAIL (KEY_OFFSET + 0x179) -#define KEY_SLAUNCH_MAIL (KEY_OFFSET + 0x17A) -#define KEY_CLAUNCH_MAIL (KEY_OFFSET + 0x17B) -#define KEY_ALAUNCH_MAIL (KEY_OFFSET + 0x17C) -#define KEY_MEDIA_SELECT (KEY_OFFSET + 0x17D) -#define KEY_SMEDIA_SELECT (KEY_OFFSET + 0x17E) -#define KEY_CMEDIA_SELECT (KEY_OFFSET + 0x17F) -#define KEY_AMEDIA_SELECT (KEY_OFFSET + 0x180) -#define KEY_LAUNCH_APP1 (KEY_OFFSET + 0x181) -#define KEY_SLAUNCH_APP1 (KEY_OFFSET + 0x182) -#define KEY_CLAUNCH_APP1 (KEY_OFFSET + 0x183) -#define KEY_ALAUNCH_APP1 (KEY_OFFSET + 0x184) -#define KEY_LAUNCH_APP2 (KEY_OFFSET + 0x185) -#define KEY_SLAUNCH_APP2 (KEY_OFFSET + 0x186) -#define KEY_CLAUNCH_APP2 (KEY_OFFSET + 0x187) -#define KEY_ALAUNCH_APP2 (KEY_OFFSET + 0x188) +#define KEY_BROWSER_BACK (KEY_OFFSET + 0x129) +#define KEY_BROWSER_FWD (KEY_OFFSET + 0x12a) +#define KEY_BROWSER_REF (KEY_OFFSET + 0x12b) +#define KEY_BROWSER_STOP (KEY_OFFSET + 0x12c) +#define KEY_SEARCH (KEY_OFFSET + 0x12d) +#define KEY_FAVORITES (KEY_OFFSET + 0x12e) +#define KEY_BROWSER_HOME (KEY_OFFSET + 0x12f) +#define KEY_VOLUME_MUTE (KEY_OFFSET + 0x130) +#define KEY_VOLUME_DOWN (KEY_OFFSET + 0x131) +#define KEY_VOLUME_UP (KEY_OFFSET + 0x132) +#define KEY_NEXT_TRACK (KEY_OFFSET + 0x133) +#define KEY_PREV_TRACK (KEY_OFFSET + 0x134) +#define KEY_MEDIA_STOP (KEY_OFFSET + 0x135) +#define KEY_PLAY_PAUSE (KEY_OFFSET + 0x136) +#define KEY_LAUNCH_MAIL (KEY_OFFSET + 0x137) +#define KEY_MEDIA_SELECT (KEY_OFFSET + 0x138) +#define KEY_LAUNCH_APP1 (KEY_OFFSET + 0x139) +#define KEY_LAUNCH_APP2 (KEY_OFFSET + 0x13a) +#define KEY_LAUNCH_APP3 (KEY_OFFSET + 0x13b) +#define KEY_LAUNCH_APP4 (KEY_OFFSET + 0x13c) +#define KEY_LAUNCH_APP5 (KEY_OFFSET + 0x13d) +#define KEY_LAUNCH_APP6 (KEY_OFFSET + 0x13e) +#define KEY_LAUNCH_APP7 (KEY_OFFSET + 0x13f) +#define KEY_LAUNCH_APP8 (KEY_OFFSET + 0x140) +#define KEY_LAUNCH_APP9 (KEY_OFFSET + 0x141) +#define KEY_LAUNCH_APP10 (KEY_OFFSET + 0x142) #define KEY_MIN KEY_BREAK /* Minimum curses key value */ -#define KEY_MAX KEY_ALAUNCH_APP2 /* Maximum curses key */ +#define KEY_MAX KEY_LAUNCH_APP10 /* Maximum curses key */ #define KEY_F(n) (KEY_F0 + (n)) @@ -1314,6 +1308,29 @@ PDCEX int doupdate(void); PDCEX WINDOW *dupwin(WINDOW *); PDCEX int echochar(const chtype); PDCEX int echo(void); + +#ifdef PDC_WIDE + #ifdef PDC_FORCE_UTF8 + #ifdef CHTYPE_32 + #define endwin endwin_u32_4302 + #else + #define endwin endwin_u64_4302 + #endif + #else + #ifdef CHTYPE_32 + #define endwin endwin_w32_4302 + #else + #define endwin endwin_w64_4302 + #endif + #endif +#else /* 8-bit chtypes */ + #ifdef CHTYPE_32 + #define endwin endwin_x32_4302 + #else + #define endwin endwin_x64_4302 + #endif +#endif + PDCEX int endwin(void); PDCEX char erasechar(void); PDCEX int erase(void); @@ -1341,29 +1358,6 @@ PDCEX int init_color(short, short, short, short); PDCEX int init_extended_color(int, int, int, int); PDCEX int init_extended_pair(int, int, int); PDCEX int init_pair(short, short, short); - -#ifdef PDC_WIDE - #ifdef PDC_FORCE_UTF8 - #ifdef CHTYPE_32 - #define initscr initscr_u32 - #else - #define initscr initscr_u64 - #endif - #else - #ifdef CHTYPE_32 - #define initscr initscr_w32 - #else - #define initscr initscr_w64 - #endif - #endif -#else /* 8-bit chtypes */ - #ifdef CHTYPE_32 - #define initscr initscr_x32 - #else - #define initscr initscr_x64 - #endif -#endif - PDCEX WINDOW *initscr(void); PDCEX int innstr(char *, int); PDCEX int insch(chtype); @@ -1476,6 +1470,7 @@ PDCEX int slk_attr_on(const attr_t, void *); PDCEX int slk_attrset(const chtype); PDCEX int slk_attr_set(const attr_t, short, void *); PDCEX int slk_clear(void); +PDCEX int extended_slk_color(int); PDCEX int slk_color(short); PDCEX int slk_init(int); PDCEX char *slk_label(int); @@ -1679,6 +1674,8 @@ PDCEX int getcurx(WINDOW *); PDCEX int getcury(WINDOW *); PDCEX void traceoff(void); PDCEX void traceon(void); +PDCEX void trace( const unsigned); +PDCEX unsigned curses_trace( const unsigned); PDCEX char *unctrl(chtype); PDCEX int crmode(void); @@ -1698,12 +1695,16 @@ PDCEX mmask_t getmouse(void); /* ncurses */ +PDCEX int alloc_pair(int, int); PDCEX int assume_default_colors(int, int); PDCEX const char *curses_version(void); +PDCEX int find_pair(int, int); +PDCEX int free_pair( int); PDCEX bool has_key(int); PDCEX bool is_keypad(const WINDOW *); PDCEX bool is_leaveok(const WINDOW *); PDCEX bool is_pad(const WINDOW *); +PDCEX void reset_color_pairs( void); PDCEX int set_tabsize(int); PDCEX int use_default_colors(void); PDCEX int wresize(WINDOW *, int, int); @@ -1741,13 +1742,17 @@ PDCEX char wordchar(void); PDCEX wchar_t *slk_wlabel(int); #endif +PDCEX bool PDC_getcbreak(void); +PDCEX bool PDC_getecho(void); PDCEX void PDC_debug(const char *, ...); +PDCEX void _tracef(const char *, ...); PDCEX void PDC_get_version(PDC_VERSION *); PDCEX int PDC_ungetch(int); PDCEX int PDC_set_blink(bool); PDCEX int PDC_set_bold(bool); PDCEX int PDC_set_line_color(short); PDCEX void PDC_set_title(const char *); +PDCEX int PDC_set_box_type( const int box_type); PDCEX int PDC_clearclipboard(void); PDCEX int PDC_freeclipboard(char *); @@ -1760,6 +1765,7 @@ PDCEX void PDC_set_resize_limits( const int new_min_lines, const int new_max_lines, const int new_min_cols, const int new_max_cols); +PDCEX void PDC_free_memory_allocations( void); #define FUNCTION_KEY_SHUT_DOWN 0 #define FUNCTION_KEY_PASTE 1 @@ -1767,13 +1773,14 @@ PDCEX void PDC_set_resize_limits( const int new_min_lines, #define FUNCTION_KEY_SHRINK_FONT 3 #define FUNCTION_KEY_CHOOSE_FONT 4 #define FUNCTION_KEY_ABORT 5 -#define PDC_MAX_FUNCTION_KEYS 6 +#define FUNCTION_KEY_COPY 6 +#define PDC_MAX_FUNCTION_KEYS 7 PDCEX int PDC_set_function_key( const unsigned function, const int new_key); +PDCEX int PDC_get_function_key( const unsigned function); PDCEX int PDC_set_preferred_fontface( const wchar_t* fontface); -PDCEX void PDC_set_color_intensify_enabled( bool enabled); PDCEX void PDC_set_default_menu_visibility(int visible); PDCEX WINDOW *Xinitscr(int, char **); @@ -1824,6 +1831,11 @@ PDCEX int wunderscore(WINDOW *); #define PDC_save_key_modifiers(x) (OK) #define PDC_get_input_fd() 0 +/* masks for PDC_set_box_type() */ + +#define PDC_BOX_DOUBLED_V 1 +#define PDC_BOX_DOUBLED_H 2 + /* return codes from PDC_getclipboard() and PDC_setclipboard() calls */ #define PDC_CLIP_SUCCESS 0 @@ -1839,6 +1851,30 @@ PDCEX int wunderscore(WINDOW *); #define PDC_KEY_MODIFIER_NUMLOCK 8 #define PDC_KEY_MODIFIER_REPEAT 16 +/* Bitflags for trace(), curses_trace(), for ncurses compatibility. +Values were copied from ncurses. Note that those involving terminfo, +termcap, and TTY control bits are meaningless in PDCurses and will be +ignored. */ + +#define TRACE_DISABLE 0x0000 /* turn off tracing */ +#define TRACE_TIMES 0x0001 /* trace user and system times of updates */ +#define TRACE_TPUTS 0x0002 /* trace tputs calls */ +#define TRACE_UPDATE 0x0004 /* trace update actions, old & new screens */ +#define TRACE_MOVE 0x0008 /* trace cursor moves and scrolls */ +#define TRACE_CHARPUT 0x0010 /* trace all character outputs */ +#define TRACE_ORDINARY 0x001F /* trace all update actions */ +#define TRACE_CALLS 0x0020 /* trace all curses calls */ +#define TRACE_VIRTPUT 0x0040 /* trace virtual character puts */ +#define TRACE_IEVENT 0x0080 /* trace low-level input processing */ +#define TRACE_BITS 0x0100 /* trace state of TTY control bits */ +#define TRACE_ICALLS 0x0200 /* trace internal/nested calls */ +#define TRACE_CCALLS 0x0400 /* trace per-character calls */ +#define TRACE_DATABASE 0x0800 /* trace read/write of terminfo/termcap data */ +#define TRACE_ATTRS 0x1000 /* trace attribute updates */ + +#define TRACE_SHIFT 13 /* number of bits in the trace masks */ +#define TRACE_MAXIMUM ((1u << TRACE_SHIFT) - 1u) /* max tracing */ + #ifdef __cplusplus # ifndef PDC_PP98 # undef bool diff --git a/src/3rdparty/win32_include/curspriv.h b/src/3rdparty/win32_include/curspriv.h index 746239e8c..c4ba2f851 100644 --- a/src/3rdparty/win32_include/curspriv.h +++ b/src/3rdparty/win32_include/curspriv.h @@ -4,22 +4,30 @@ #ifndef __CURSES_INTERNALS__ #define __CURSES_INTERNALS__ 1 +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE 1 /* kill nonsense warnings */ +#endif + #define CURSES_LIBRARY #include #if defined(__TURBOC__) || defined(__EMX__) || defined(__DJGPP__) || \ defined(PDC_99) || defined(__WATCOMC__) -# ifndef HAVE_VSSCANF +# if !defined( HAVE_VSSCANF) && !defined( __DMC__) # define HAVE_VSSCANF /* have vsscanf() */ # endif #endif #if defined(PDC_99) || defined(__WATCOMC__) -# ifndef HAVE_VSNPRINTF +# if !defined( HAVE_VSNPRINTF) && !defined( __DMC__) # define HAVE_VSNPRINTF /* have vsnprintf() */ # endif #endif +#if defined( PDC_FORCE_UTF8) && !defined( PDC_WIDE) + #define PDC_WIDE +#endif + /*----------------------------------------------------------------------*/ typedef struct /* structure for ripped off lines */ @@ -76,6 +84,7 @@ void PDC_scr_free(void); int PDC_scr_open(void); void PDC_set_keyboard_binary(bool); void PDC_transform_line(int, int, int, const chtype *); +void PDC_free_platform_dependent_memory( void); const char *PDC_sysname(void); /* Internal cross-module functions */ @@ -87,11 +96,17 @@ int PDC_mouse_in_slk(int, int); void PDC_slk_free(void); void PDC_slk_initialize(void); void PDC_sync(WINDOW *); +PDCEX void PDC_set_default_colors( const int, const int); +void PDC_set_changed_cells_range( WINDOW *, const int y, const int start, const int end); +void PDC_mark_line_as_changed( WINDOW *win, const int y); +void PDC_mark_cells_as_changed( WINDOW *, const int y, const int start, const int end); +void PDC_mark_cell_as_changed( WINDOW *, const int y, const int x); #ifdef PDC_WIDE int PDC_mbtowc(wchar_t *, const char *, size_t); size_t PDC_mbstowcs(wchar_t *, const char *, size_t); size_t PDC_wcstombs(char *, const wchar_t *, size_t); +PDCEX int PDC_wcwidth( const int32_t ucs); #endif #ifdef PDCDEBUG @@ -113,10 +128,14 @@ size_t PDC_wcstombs(char *, const wchar_t *, size_t); #define PDC_CLICK_PERIOD 150 /* time to wait for a click, if not set by mouseinterval() */ -#define PDC_COLOR_PAIRS 256 #define PDC_MAXCOL 768 /* maximum possible COLORS; may be less */ #define _INBUFSIZ 512 /* size of terminal input buffer */ #define NUNGETCH 256 /* max # chars to ungetch() */ +#define INTENTIONALLY_UNUSED_PARAMETER( param) (void)(param) + +#define _is_altcharset( ch) (((ch) & (A_ALTCHARSET | (A_CHARTEXT ^ 0x7f))) == A_ALTCHARSET) + + #endif /* __CURSES_INTERNALS__ */ diff --git a/src/3rdparty/win32_include/panel.h b/src/3rdparty/win32_include/panel.h index 7f1fb1f17..57ff06d41 100755 --- a/src/3rdparty/win32_include/panel.h +++ b/src/3rdparty/win32_include/panel.h @@ -40,6 +40,8 @@ PDCEX int move_panel(PANEL *pan, int starty, int startx); PDCEX PANEL *new_panel(WINDOW *win); PDCEX PANEL *panel_above(const PANEL *pan); PDCEX PANEL *panel_below(const PANEL *pan); +PDCEX PANEL *ground_panel(SCREEN *sp); +PDCEX PANEL *ceiling_panel(SCREEN *sp); PDCEX int panel_hidden(const PANEL *pan); PDCEX const void *panel_userptr(const PANEL *pan); PDCEX WINDOW *panel_window(const PANEL *pan); diff --git a/src/3rdparty/win32_include/term.h b/src/3rdparty/win32_include/term.h new file mode 100644 index 000000000..323244fea --- /dev/null +++ b/src/3rdparty/win32_include/term.h @@ -0,0 +1,48 @@ +/* Public Domain Curses */ + +/* PDCurses doesn't operate with terminfo, but we need these functions for + compatibility, to allow some things (notably, interface libraries for + other languages) to be compiled. Anyone who tries to actually _use_ + them will be disappointed, since they only return ERR. */ + +#ifndef __PDCURSES_TERM_H__ +#define __PDCURSES_TERM_H__ 1 + +#include + +#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS) +extern "C" +{ +#endif + +typedef struct +{ + const char *_termname; +} TERMINAL; + +/* PDCEX is defined in curses.h */ +PDCEX TERMINAL *cur_term; + +PDCEX int del_curterm(TERMINAL *); +PDCEX int putp(const char *); +PDCEX int restartterm(const char *, int, int *); +PDCEX TERMINAL *set_curterm(TERMINAL *); +PDCEX int setterm(const char *); +PDCEX int setupterm(const char *, int, int *); +PDCEX int tgetent(char *, const char *); +PDCEX int tgetflag(const char *); +PDCEX int tgetnum(const char *); +PDCEX char *tgetstr(const char *, char **); +PDCEX char *tgoto(const char *, int, int); +PDCEX int tigetflag(const char *); +PDCEX int tigetnum(const char *); +PDCEX char *tigetstr(const char *); +PDCEX char *tparm(const char *, long, long, long, long, long, + long, long, long, long); +PDCEX int tputs(const char *, int, int (*)(int)); + +#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS) +} +#endif + +#endif /* __PDCURSES_TERM_H__ */ diff --git a/src/3rdparty/win32_src/pdcurses/acs_defs.h b/src/3rdparty/win32_src/pdcurses/acs_defs.h index 58be15186..d24364406 100644 --- a/src/3rdparty/win32_src/pdcurses/acs_defs.h +++ b/src/3rdparty/win32_src/pdcurses/acs_defs.h @@ -186,7 +186,28 @@ Only 32 are used in ncurses. So caution is advised. */ #define CENTERED_SQUARE CHOOSE( 0xfe, 0x25a0, TBD) #define NON_BREAKING_SPACE CHOOSE( 0xff, 0x00a0, 0xa0) +#ifdef NOT_CURRENTLY_IMPLEMENTED +/* The following four characters are not currently implemented. However, +they would enable rounded box corners when Unicode is available. +(Otherwise, the 'traditional' unrounded corner character is used.) */ +#define BOX_URROUNDED CHOOSE( 0xbf, 0x256e, 12) +#define BOX_LLROUNDED CHOOSE( 0xc0, 0x2570, 14) +#define BOX_LRROUNDED CHOOSE( 0xd9, 0x256f, 11) +#define BOX_ULROUNDED CHOOSE( 0xda, 0x256d, 13) +#endif /* #ifdef NOT_CURRENTLY_IMPLEMENTED */ + +#define BOX_T_URCORNER CHOOSE( 0xbf, 0x2513, 12) +#define BOX_T_LRCORNER CHOOSE( 0xd9, 0x251b, 11) +#define BOX_T_ULCORNER CHOOSE( 0xda, 0x250f, 13) +#define BOX_T_LLCORNER CHOOSE( 0xc0, 0x2517, 14) +#define BOX_T_BTEE CHOOSE( 0xc1, 0x253b, 23) +#define BOX_T_TTEE CHOOSE( 0xc2, 0x252f, 24) +#define BOX_T_LTEE CHOOSE( 0xc3, 0x2523, 21) +#define BOX_T_RTEE CHOOSE( 0xb4, 0x252b, 22) +#define BOX_T_HLINE CHOOSE( 0xc4, 0x2501, 18) +#define BOX_T_VLINE CHOOSE( 0xb3, 0x2503, 25) +#define BOX_T_PLUS CHOOSE( 0xc5, 0x254b, 15) /* It says at http://unicode.org/charts/PDF/U2300.pdf */ /* that '...the scan line numbers here refer to old, */ @@ -194,9 +215,9 @@ Only 32 are used in ncurses. So caution is advised. */ /* nine scan lines per fixed-size character glyph. */ /* Even-numbered scan lines are unified with box */ /* drawing graphics." */ - /* The utility of these is questionable; they'd */ - /* work Just Fine in wingdi (_if_ the appropriate */ - /* glyphs are available), but not elsewhere. */ + /* The utility of these is questionable; they */ + /* work Just Fine in wide-character builds if the */ + /* glyphs are available, but not elsewhere. */ #define HORIZ_SCAN_LINE_1 CHOOSE( 0x2d, 0x23ba, 16) #define HORIZ_SCAN_LINE_3 CHOOSE( 0x2d, 0x23bb, 17) #define HORIZ_SCAN_LINE_7 CHOOSE( 0x2d, 0x23bc, 19) @@ -210,8 +231,10 @@ Only 32 are used in ncurses. So caution is advised. */ chtype acs_map[128] = { - A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7), A(8), - A(9), A(10), + BOX_T_LRCORNER, BOX_T_URCORNER, BOX_T_ULCORNER, /* 0 1 2 */ + BOX_T_LLCORNER, BOX_T_PLUS, /* 3 4 */ + BOX_T_LTEE, BOX_T_RTEE, BOX_T_BTEE, BOX_T_TTEE, /* 5 6 7 8 */ + BOX_T_HLINE, BOX_T_VLINE, /* 9 10 */ CLUB, HEART, SPADE, SMILE, REV_SMILE, /* 11 12 13 14 15 */ MEDIUM_BULLET, WHITE_BULLET, PILCROW, SECTION_SIGN, /* 16 17 18 19 */ A_ORDINAL, O_ORDINAL, LOWERCASE_PHI, /* 20 21 22 */ diff --git a/src/3rdparty/win32_src/pdcurses/addch.c b/src/3rdparty/win32_src/pdcurses/addch.c index 120a51e39..f9447c8dd 100644 --- a/src/3rdparty/win32_src/pdcurses/addch.c +++ b/src/3rdparty/win32_src/pdcurses/addch.c @@ -1,5 +1,13 @@ /* PDCurses */ +/* On Linux, and probably some other platforms, we can just +use the built-in wcwidth() function. */ +#ifdef __linux + #define HAVE_WCWIDTH + #define _XOPEN_SOURCE + #include +#endif + #include #include @@ -118,45 +126,49 @@ addch So if PDC_WIDE is defined _and_ we're using 64-bit chtypes, we're using the combining character scheme. See curses.h. */ -#ifdef USING_COMBINING_CHARACTER_SCHEME +#ifdef PDC_WIDE #include -/* - * A greatly stripped-down version of Markus Kuhn's excellent - * wcwidth implementation. For his latest version and many - * comments, see http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c - * For PDCurses, only mk_wcwidth is used, modified to take an - * int argument instead of wchar_t, because in MS-land, wchar_t - * is 16 bits; getting the full Unicode range requires 21 bits. - * Also modified format/indenting to conform to PDCurses norms. - * NOTE that this version is current only to Unicode 5.0! Some - * updates are almost certainly needed... - */ -struct interval +#ifdef HAVE_WCWIDTH + +PDCEX int PDC_wcwidth( const int32_t ucs) { - int32_t first, last; -}; + return( wcwidth( (wchar_t)ucs)); +} -/* auxiliary function for binary search in interval table */ +#else +/* A greatly modified version of Markus Kuhn's excellent +wcwidth implementation. For his latest version and many +comments, see http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c +For PDCurses, only PDC_wcwidth is used, modified to take an +int argument instead of wchar_t, because in MS-land, wchar_t +is 16 bits; getting the full Unicode range requires 21 bits. +Also modified format/indenting to conform to PDCurses norms, +and (June 2022) updated from Unicode 5.0 to 14.0.0. See +uni_tbl.c in the Bill-Gray/junk repository. -static int bisearch( const int32_t ucs, const struct interval *table, int max) +Following function modified from one in the README.md at +https://github.com/depp/uniset */ + +static bool _uniset_test( uint16_t const set[][2], uint32_t c) { - int min = 0; - int mid; + const unsigned int p = c >> 16; + unsigned int l = set[p][0] + 17, r = set[p][1] + 17; - if (ucs < table[0].first || ucs > table[max].last) - return 0; - while (max >= min) + assert( p <= 16); /* i.e., 0 <= c <= 0x10ffff => c is in Unicode's range */ + c &= 0xffff; + while (l < r) { - mid = (min + max) / 2; - if (ucs > table[mid].last) - min = mid + 1; - else if (ucs < table[mid].first) - max = mid - 1; + const unsigned int m = (l + r) / 2; + + if( c < set[m][0]) + r = m; + else if( c > set[m][1]) + l = m + 1; else - return 1; + return TRUE; } - return 0; + return( FALSE); } /* The following two functions define the column width of an ISO 10646 @@ -191,61 +203,179 @@ static int bisearch( const int32_t ucs, const struct interval *table, int max) * in ISO 10646. */ -static int mk_wcwidth( const int32_t ucs) +PDCEX int PDC_wcwidth( const int32_t ucs) { - /* sorted list of non-overlapping intervals of non-spacing characters */ - /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ - static const struct interval combining[] = - { - { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 }, - { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, - { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 }, - { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 }, - { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, - { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, - { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 }, - { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, - { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, - { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, - { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, - { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, - { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, - { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, - { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, - { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D }, - { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, - { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, - { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC }, - { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, - { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, - { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, - { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, - { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, - { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, - { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, - { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, - { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, - { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, - { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F }, - { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 }, - { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, - { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, - { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, - { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, - { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, - { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, - { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF }, - { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 }, - { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F }, - { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, - { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, - { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, - { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, - { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 }, - { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, - { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, - { 0xE0100, 0xE01EF } - }; + /* see 'uni_tbl.c' in the Bill-Gray/junk repo */ +const uint16_t tbl_for_zero_width_chars[][2] = { + { /* plane 0 */ 0, 202 }, + { /* plane 1 */ 202, 312 }, + { /* plane 2 */ 0, 0 }, + { /* plane 3 */ 0, 0 }, + { /* plane 4 */ 0, 0 }, + { /* plane 5 */ 0, 0 }, + { /* plane 6 */ 0, 0 }, + { /* plane 7 */ 0, 0 }, + { /* plane 8 */ 0, 0 }, + { /* plane 9 */ 0, 0 }, + { /* plane 10 */ 0, 0 }, + { /* plane 11 */ 0, 0 }, + { /* plane 12 */ 0, 0 }, + { /* plane 13 */ 0, 0 }, + { /* plane 14 */ 312, 313 }, + { /* plane 15 */ 0, 0 }, + { /* plane 16 */ 0, 0 }, + { 0x00AD, 0x036F }, { 0x0483, 0x0489 }, { 0x0591, 0x05BD }, + { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, { 0x05C4, 0x05C5 }, + { 0x05C7, 0x05C7 }, { 0x0600, 0x0605 }, { 0x0610, 0x061A }, + { 0x061C, 0x061C }, { 0x064B, 0x065F }, { 0x0670, 0x0670 }, + { 0x06D6, 0x06DD }, { 0x06DF, 0x06E4 }, { 0x06E7, 0x06E8 }, + { 0x06EA, 0x06ED }, { 0x070F, 0x070F }, { 0x0711, 0x0711 }, + { 0x0730, 0x074A }, { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, + { 0x07FD, 0x07FD }, { 0x0816, 0x0819 }, { 0x081B, 0x0823 }, + { 0x0825, 0x0827 }, { 0x0829, 0x082D }, { 0x0859, 0x085B }, + { 0x0890, 0x089F }, { 0x08CA, 0x0902 }, { 0x093A, 0x093A }, + { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, + { 0x0951, 0x0957 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, + { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, + { 0x09E2, 0x09E3 }, { 0x09FE, 0x0A02 }, { 0x0A3C, 0x0A3C }, + { 0x0A41, 0x0A51 }, { 0x0A70, 0x0A71 }, { 0x0A75, 0x0A75 }, + { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC8 }, + { 0x0ACD, 0x0ACD }, { 0x0AE2, 0x0AE3 }, { 0x0AFA, 0x0B01 }, + { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B44 }, + { 0x0B4D, 0x0B56 }, { 0x0B62, 0x0B63 }, { 0x0B82, 0x0B82 }, + { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C00, 0x0C00 }, + { 0x0C04, 0x0C04 }, { 0x0C3C, 0x0C3C }, { 0x0C3E, 0x0C40 }, + { 0x0C46, 0x0C56 }, { 0x0C62, 0x0C63 }, { 0x0C81, 0x0C81 }, + { 0x0CBC, 0x0CBC }, { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, + { 0x0CCC, 0x0CCD }, { 0x0CE2, 0x0CE3 }, { 0x0D00, 0x0D01 }, + { 0x0D3B, 0x0D3C }, { 0x0D41, 0x0D44 }, { 0x0D4D, 0x0D4D }, + { 0x0D62, 0x0D63 }, { 0x0D81, 0x0D81 }, { 0x0DCA, 0x0DCA }, + { 0x0DD2, 0x0DD6 }, { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, + { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EBC }, + { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, + { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, + { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F8D, 0x0FBC }, + { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1037 }, + { 0x1039, 0x103A }, { 0x103D, 0x103E }, { 0x1058, 0x1059 }, + { 0x105E, 0x1060 }, { 0x1071, 0x1074 }, { 0x1082, 0x1082 }, + { 0x1085, 0x1086 }, { 0x108D, 0x108D }, { 0x109D, 0x109D }, + { 0x1160, 0x11FF }, { 0x135D, 0x135F }, { 0x1712, 0x1714 }, + { 0x1732, 0x1733 }, { 0x1752, 0x1753 }, { 0x1772, 0x1773 }, + { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 }, + { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, { 0x180B, 0x180F }, + { 0x1885, 0x1886 }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, + { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, + { 0x1A17, 0x1A18 }, { 0x1A1B, 0x1A1B }, { 0x1A56, 0x1A56 }, + { 0x1A58, 0x1A60 }, { 0x1A62, 0x1A62 }, { 0x1A65, 0x1A6C }, + { 0x1A73, 0x1A7F }, { 0x1AB0, 0x1B03 }, { 0x1B34, 0x1B34 }, + { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, + { 0x1B6B, 0x1B73 }, { 0x1B80, 0x1B81 }, { 0x1BA2, 0x1BA5 }, + { 0x1BA8, 0x1BA9 }, { 0x1BAB, 0x1BAD }, { 0x1BE6, 0x1BE6 }, + { 0x1BE8, 0x1BE9 }, { 0x1BED, 0x1BED }, { 0x1BEF, 0x1BF1 }, + { 0x1C2C, 0x1C33 }, { 0x1C36, 0x1C37 }, { 0x1CD0, 0x1CD2 }, + { 0x1CD4, 0x1CE0 }, { 0x1CE2, 0x1CE8 }, { 0x1CED, 0x1CED }, + { 0x1CF4, 0x1CF4 }, { 0x1CF8, 0x1CF9 }, { 0x1DC0, 0x1DFF }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x206F }, + { 0x20D0, 0x20F0 }, { 0x2CEF, 0x2CF1 }, { 0x2D7F, 0x2D7F }, + { 0x2DE0, 0x2DFF }, { 0x302A, 0x302D }, { 0x3099, 0x309A }, + { 0xA66F, 0xA672 }, { 0xA674, 0xA67D }, { 0xA69E, 0xA69F }, + { 0xA6F0, 0xA6F1 }, { 0xA802, 0xA802 }, { 0xA806, 0xA806 }, + { 0xA80B, 0xA80B }, { 0xA825, 0xA826 }, { 0xA82C, 0xA82C }, + { 0xA8C4, 0xA8C5 }, { 0xA8E0, 0xA8F1 }, { 0xA8FF, 0xA8FF }, + { 0xA926, 0xA92D }, { 0xA947, 0xA951 }, { 0xA980, 0xA982 }, + { 0xA9B3, 0xA9B3 }, { 0xA9B6, 0xA9B9 }, { 0xA9BC, 0xA9BD }, + { 0xA9E5, 0xA9E5 }, { 0xAA29, 0xAA2E }, { 0xAA31, 0xAA32 }, + { 0xAA35, 0xAA36 }, { 0xAA43, 0xAA43 }, { 0xAA4C, 0xAA4C }, + { 0xAA7C, 0xAA7C }, { 0xAAB0, 0xAAB0 }, { 0xAAB2, 0xAAB4 }, + { 0xAAB7, 0xAAB8 }, { 0xAABE, 0xAABF }, { 0xAAC1, 0xAAC1 }, + { 0xAAEC, 0xAAED }, { 0xAAF6, 0xAAF6 }, { 0xABE5, 0xABE5 }, + { 0xABE8, 0xABE8 }, { 0xABED, 0xABED }, { 0xFB1E, 0xFB1E }, + { 0xFE00, 0xFE0F }, { 0xFE20, 0xFE2F }, { 0xFEFF, 0xFEFF }, + { 0xFFF9, 0xFFFB }, { 0x01FD, 0x01FD }, { 0x02E0, 0x02E0 }, + { 0x0376, 0x037A }, { 0x0A01, 0x0A0F }, { 0x0A38, 0x0A3F }, + { 0x0AE5, 0x0AE6 }, { 0x0D24, 0x0D27 }, { 0x0EAB, 0x0EAC }, + { 0x0F46, 0x0F50 }, { 0x0F82, 0x0F85 }, { 0x1001, 0x1001 }, + { 0x1038, 0x1046 }, { 0x1070, 0x1070 }, { 0x1073, 0x1074 }, + { 0x107F, 0x1081 }, { 0x10B3, 0x10B6 }, { 0x10B9, 0x10BA }, + { 0x10BD, 0x10BD }, { 0x10C2, 0x10CD }, { 0x1100, 0x1102 }, + { 0x1127, 0x112B }, { 0x112D, 0x1134 }, { 0x1173, 0x1173 }, + { 0x1180, 0x1181 }, { 0x11B6, 0x11BE }, { 0x11C9, 0x11CC }, + { 0x11CF, 0x11CF }, { 0x122F, 0x1231 }, { 0x1234, 0x1234 }, + { 0x1236, 0x1237 }, { 0x123E, 0x123E }, { 0x12DF, 0x12DF }, + { 0x12E3, 0x12EA }, { 0x1300, 0x1301 }, { 0x133B, 0x133C }, + { 0x1340, 0x1340 }, { 0x1366, 0x1374 }, { 0x1438, 0x143F }, + { 0x1442, 0x1444 }, { 0x1446, 0x1446 }, { 0x145E, 0x145E }, + { 0x14B3, 0x14B8 }, { 0x14BA, 0x14BA }, { 0x14BF, 0x14C0 }, + { 0x14C2, 0x14C3 }, { 0x15B2, 0x15B5 }, { 0x15BC, 0x15BD }, + { 0x15BF, 0x15C0 }, { 0x15DC, 0x162F }, { 0x1633, 0x163A }, + { 0x163D, 0x163D }, { 0x163F, 0x1640 }, { 0x16AB, 0x16AB }, + { 0x16AD, 0x16AD }, { 0x16B0, 0x16B5 }, { 0x16B7, 0x16B7 }, + { 0x171D, 0x171F }, { 0x1722, 0x1725 }, { 0x1727, 0x172B }, + { 0x182F, 0x1837 }, { 0x1839, 0x183A }, { 0x193B, 0x193C }, + { 0x193E, 0x193E }, { 0x1943, 0x1943 }, { 0x19D4, 0x19DB }, + { 0x19E0, 0x19E0 }, { 0x1A01, 0x1A0A }, { 0x1A33, 0x1A38 }, + { 0x1A3B, 0x1A3E }, { 0x1A47, 0x1A47 }, { 0x1A51, 0x1A56 }, + { 0x1A59, 0x1A5B }, { 0x1A8A, 0x1A96 }, { 0x1A98, 0x1A99 }, + { 0x1C30, 0x1C3D }, { 0x1C3F, 0x1C3F }, { 0x1C92, 0x1CA7 }, + { 0x1CAA, 0x1CB0 }, { 0x1CB2, 0x1CB3 }, { 0x1CB5, 0x1CB6 }, + { 0x1D31, 0x1D45 }, { 0x1D47, 0x1D47 }, { 0x1D90, 0x1D91 }, + { 0x1D95, 0x1D95 }, { 0x1D97, 0x1D97 }, { 0x1EF3, 0x1EF4 }, + { 0x3430, 0x3438 }, { 0x6AF0, 0x6AF4 }, { 0x6B30, 0x6B36 }, + { 0x6F4F, 0x6F4F }, { 0x6F8F, 0x6F92 }, { 0x6FE4, 0x6FE4 }, + { 0xBC9D, 0xBC9E }, { 0xBCA0, 0xCF46 }, { 0xD167, 0xD169 }, + { 0xD173, 0xD182 }, { 0xD185, 0xD18B }, { 0xD1AA, 0xD1AD }, + { 0xD242, 0xD244 }, { 0xDA00, 0xDA36 }, { 0xDA3B, 0xDA6C }, + { 0xDA75, 0xDA75 }, { 0xDA84, 0xDA84 }, { 0xDA9B, 0xDAAF }, + { 0xE000, 0xE02A }, { 0xE130, 0xE136 }, { 0xE2AE, 0xE2AE }, + { 0xE2EC, 0xE2EF }, { 0xE8D0, 0xE8D6 }, { 0xE944, 0xE94A }, + { 0x0001, 0x01EF } }; + +const uint16_t tbl_for_fullwidth_chars[][2] = { + { /* plane 0 */ 0, 46 }, + { /* plane 1 */ 46, 80 }, + { /* plane 2 */ 80, 81 }, + { /* plane 3 */ 81, 82 }, + { /* plane 4 */ 0, 0 }, + { /* plane 5 */ 0, 0 }, + { /* plane 6 */ 0, 0 }, + { /* plane 7 */ 0, 0 }, + { /* plane 8 */ 0, 0 }, + { /* plane 9 */ 0, 0 }, + { /* plane 10 */ 0, 0 }, + { /* plane 11 */ 0, 0 }, + { /* plane 12 */ 0, 0 }, + { /* plane 13 */ 0, 0 }, + { /* plane 14 */ 0, 0 }, + { /* plane 15 */ 0, 0 }, + { /* plane 16 */ 0, 0 }, + { 0x1100, 0x115F }, { 0x231A, 0x231B }, { 0x2329, 0x232A }, + { 0x23E9, 0x23EC }, { 0x23F0, 0x23F0 }, { 0x23F3, 0x23F3 }, + { 0x25FD, 0x25FE }, { 0x2614, 0x2615 }, { 0x2648, 0x2653 }, + { 0x267F, 0x267F }, { 0x2693, 0x2693 }, { 0x26A1, 0x26A1 }, + { 0x26AA, 0x26AB }, { 0x26BD, 0x26BE }, { 0x26C4, 0x26C5 }, + { 0x26CE, 0x26CE }, { 0x26D4, 0x26D4 }, { 0x26EA, 0x26EA }, + { 0x26F2, 0x26F3 }, { 0x26F5, 0x26F5 }, { 0x26FA, 0x26FA }, + { 0x26FD, 0x26FD }, { 0x2705, 0x2705 }, { 0x270A, 0x270B }, + { 0x2728, 0x2728 }, { 0x274C, 0x274C }, { 0x274E, 0x274E }, + { 0x2753, 0x2755 }, { 0x2757, 0x2757 }, { 0x2795, 0x2797 }, + { 0x27B0, 0x27B0 }, { 0x27BF, 0x27BF }, { 0x2B1B, 0x2B1C }, + { 0x2B50, 0x2B50 }, { 0x2B55, 0x2B55 }, { 0x2E80, 0x303E }, + { 0x3041, 0x3247 }, { 0x3250, 0x4DBF }, { 0x4E00, 0xA4C6 }, + { 0xA960, 0xA97C }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF }, + { 0xFE10, 0xFE19 }, { 0xFE30, 0xFE6B }, { 0xFF01, 0xFF60 }, + { 0xFFE0, 0xFFE6 }, { 0x6FE0, 0xB2FB }, { 0xF004, 0xF004 }, + { 0xF0CF, 0xF0CF }, { 0xF18E, 0xF18E }, { 0xF191, 0xF19A }, + { 0xF200, 0xF320 }, { 0xF32D, 0xF335 }, { 0xF337, 0xF37C }, + { 0xF37E, 0xF393 }, { 0xF3A0, 0xF3CA }, { 0xF3CF, 0xF3D3 }, + { 0xF3E0, 0xF3F0 }, { 0xF3F4, 0xF3F4 }, { 0xF3F8, 0xF43E }, + { 0xF440, 0xF440 }, { 0xF442, 0xF4FC }, { 0xF4FF, 0xF53D }, + { 0xF54B, 0xF54E }, { 0xF550, 0xF567 }, { 0xF57A, 0xF57A }, + { 0xF595, 0xF596 }, { 0xF5A4, 0xF5A4 }, { 0xF5FB, 0xF64F }, + { 0xF680, 0xF6C5 }, { 0xF6CC, 0xF6CC }, { 0xF6D0, 0xF6D2 }, + { 0xF6D5, 0xF6DF }, { 0xF6EB, 0xF6EC }, { 0xF6F4, 0xF6FC }, + { 0xF7E0, 0xF7F0 }, { 0xF90C, 0xF93A }, { 0xF93C, 0xF945 }, + { 0xF947, 0xF9FF }, { 0xFA70, 0xFAF6 }, { 0x0000, 0xFFFF }, + { 0x0000, 0xFFFD } }; /* test for 8-bit control characters */ if (ucs == 0) @@ -253,30 +383,23 @@ static int mk_wcwidth( const int32_t ucs) if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) return -1; - if( ucs < combining[0].first) /* everything else up to 0x300 is a */ + if( ucs < 0x300) /* everything else up to 0x300 is a */ return( 1); /* plain old single-width character */ + if( ucs >= 0x110000) + return( 1); /* binary search in table of non-spacing characters */ - if (bisearch(ucs, combining, - sizeof(combining) / sizeof(struct interval) - 1)) + if( _uniset_test( tbl_for_zero_width_chars, ucs)) return 0; /* if we arrive here, ucs is not a combining or C0/C1 control character */ - - return 1 + - (ucs >= 0x1100 && - (ucs <= 0x115f || /* Hangul Jamo init. consonants */ - ucs == 0x2329 || ucs == 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && - ucs != 0x303f) || /* CJK ... Yi */ - (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ - (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ - (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ - (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ - (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ - (ucs >= 0xffe0 && ucs <= 0xffe6) || - (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd))); + if( _uniset_test( tbl_for_fullwidth_chars, ucs)) + return 2; + else + return 1; } +#endif + +#ifdef USING_COMBINING_CHARACTER_SCHEME /* The handling of "fullwidth" characters (those consuming two "normal" columns) and combining characters (characters that can add accents to a @@ -330,7 +453,7 @@ static struct combined_char int32_t root, added; } *combos = NULL; -static int find_combined_char_idx( const cchar_t root, const cchar_t added) +int PDC_find_combined_char_idx( const cchar_t root, const cchar_t added) { int i; @@ -350,6 +473,9 @@ static int find_combined_char_idx( const cchar_t root, const cchar_t added) return( i); } +#define IS_LOW_SURROGATE( c) ((c) >= 0xdc00 && (c) < 0xe000) +#define IS_HIGH_SURROGATE( c) ((c) >= 0xd800 && (c) < 0xdc00) + int PDC_expand_combined_characters( const cchar_t c, cchar_t *added) { if( !c) /* flag to free up memory */ @@ -366,6 +492,7 @@ int PDC_expand_combined_characters( const cchar_t c, cchar_t *added) } #endif /* #ifdef USING_COMBINING_CHARACTER_SCHEME */ +#endif /* #ifdef PDC_WIDE */ int waddch( WINDOW *win, const chtype ch) { @@ -394,19 +521,33 @@ int waddch( WINDOW *win, const chtype ch) text = ch & A_CHARTEXT; attr = ch & A_ATTRIBUTES; #ifdef USING_COMBINING_CHARACTER_SCHEME - text_width = mk_wcwidth( (int)text); + text_width = PDC_wcwidth( (int)text); - if( !text_width && text && (x || y)) - { /* it's a combining char; combine w/prev char */ - if( x) - x--; - else + if( x || y) + { + const bool is_combining = (text && !text_width); + const bool is_low_surrogate = IS_LOW_SURROGATE( text); + + if( is_combining || is_low_surrogate) { - y--; - x = win->_maxx - 1; + chtype prev_char; + + if( x) + x--; + else + { + y--; + x = win->_maxx - 1; + } + prev_char = win->_y[y][x] & A_CHARTEXT; + if( is_combining) + text = COMBINED_CHAR_START + + PDC_find_combined_char_idx( prev_char, text); + else if( IS_HIGH_SURROGATE( prev_char)) + text = 0x10000 + ((prev_char - 0xd800) << 10) + (text - 0xdc00); + else /* low surrogate after a non-high surrogate; not */ + text = prev_char; /* supposed to happen */ } - text = COMBINED_CHAR_START - + find_combined_char_idx( win->_y[y][x], text); } #endif @@ -502,21 +643,13 @@ int waddch( WINDOW *win, const chtype ch) text |= attr; - /* Only change _firstch/_lastch if the character to be added is + /* Only change 'dirty' cells if the character to be added is different from the character/attribute that is already in that position in the window. */ if (win->_y[y][x] != text) { - if (win->_firstch[y] == _NO_CHANGE) - win->_firstch[y] = win->_lastch[y] = x; - else - if (x < win->_firstch[y]) - win->_firstch[y] = x; - else - if (x > win->_lastch[y]) - win->_lastch[y] = x; - + PDC_mark_cell_as_changed( win, y, x); win->_y[y][x] = text; } @@ -645,6 +778,7 @@ int wadd_wch(WINDOW *win, const cchar_t *wch) { PDC_LOG(("wadd_wch() - called: win=%p wch=%x\n", win, *wch)); + assert( wch); return wch ? waddch(win, *wch) : ERR; } @@ -687,6 +821,7 @@ int wecho_wchar(WINDOW *win, const cchar_t *wch) { PDC_LOG(("wecho_wchar() - called: win=%p wch=%x\n", win, *wch)); + assert( wch); if (!wch || (wadd_wch(win, wch) == ERR)) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/addchstr.c b/src/3rdparty/win32_src/pdcurses/addchstr.c index 10fc27941..b95c82662 100644 --- a/src/3rdparty/win32_src/pdcurses/addchstr.c +++ b/src/3rdparty/win32_src/pdcurses/addchstr.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -69,11 +70,13 @@ addchstr int waddchnstr(WINDOW *win, const chtype *ch, int n) { - int y, x, maxx, minx; + int y, x; chtype *ptr; PDC_LOG(("waddchnstr() - called: win=%p n=%d\n", win, n)); + assert( win); + assert( ch); if (!win || !ch || !n || n < -1) return ERR; @@ -84,31 +87,15 @@ int waddchnstr(WINDOW *win, const chtype *ch, int n) if (n == -1 || n > win->_maxx - x) n = win->_maxx - x; - minx = win->_firstch[y]; - maxx = win->_lastch[y]; - for (; n && *ch; n--, x++, ptr++, ch++) { if (*ptr != *ch) { - if (x < minx || minx == _NO_CHANGE) - minx = x; - - if (x > maxx) - maxx = x; - - PDC_LOG(("y %d x %d minx %d maxx %d *ptr %x *ch" - " %x firstch: %d lastch: %d\n", - y, x, minx, maxx, *ptr, *ch, - win->_firstch[y], win->_lastch[y])); - + PDC_mark_cell_as_changed( win, y, x); *ptr = *ch; } } - win->_firstch[y] = minx; - win->_lastch[y] = maxx; - return OK; } diff --git a/src/3rdparty/win32_src/pdcurses/addstr.c b/src/3rdparty/win32_src/pdcurses/addstr.c index a7d853965..86151c705 100644 --- a/src/3rdparty/win32_src/pdcurses/addstr.c +++ b/src/3rdparty/win32_src/pdcurses/addstr.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -69,10 +70,12 @@ int waddnstr(WINDOW *win, const char *str, int n) PDC_LOG(("waddnstr() - called: string=\"%s\" n %d \n", str, n)); + assert( win); + assert( str); if (!win || !str) return ERR; - while (str[i] && (i < n || n < 0)) + while( (i < n || n < 0) && str[i]) { #ifdef PDC_WIDE wchar_t wch; @@ -162,10 +165,13 @@ int waddnwstr(WINDOW *win, const wchar_t *wstr, int n) PDC_LOG(("waddnwstr() - called\n")); + assert( win); + assert( wstr); if (!win || !wstr) return ERR; while (wstr[i] && (i < n || n < 0)) + while( (i < n || n < 0) && wstr[i]) { chtype wch = wstr[i++]; diff --git a/src/3rdparty/win32_src/pdcurses/attr.c b/src/3rdparty/win32_src/pdcurses/attr.c index 020f1482f..0d55ed8c6 100644 --- a/src/3rdparty/win32_src/pdcurses/attr.c +++ b/src/3rdparty/win32_src/pdcurses/attr.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -68,16 +69,19 @@ attr wattroff() turns off the named attributes without affecting any other attributes; wattron() turns them on. - wcolor_set() sets the window color to the value of color_pair. opts - is unused. + wcolor_set() sets the window color to the value of color_pair. If + opts is non-NULL, it is treated as a pointer to an integer containing + the desired color pair, and color_pair is ignored (this is an ncurses + extension). standout() is the same as attron(A_STANDOUT). standend() is the same as attrset(A_NORMAL); that is, it turns off all attributes. The attr_* and wattr_* functions are intended for use with the WA_* attributes. In PDCurses, these are the same as A_*, and there is no - difference in bevahior from the chtype-based functions. In all cases, - opts is unused. + difference in behavior from the chtype-based functions. If opts is + non-NULL, it is used as a pointer to an integer and the color pair + is stored in it (this is an ncurses extension). wattr_get() retrieves the attributes and color pair for the specified window. @@ -86,7 +90,9 @@ attr the current line of a given window, without changing the existing text, or alterting the window's attributes. An n of -1 extends the change to the edge of the window. The changes take effect - immediately. opts is unused. + immediately. If opts is non-NULL, it is treated as a pointer to + an integer containing the desired color pair, and color_pair is + ignored (this is an ncurses extension). wunderscore() turns on the A_UNDERLINE attribute; wunderend() turns it off. underscore() and underend() are the stdscr versions. @@ -133,6 +139,7 @@ int wattroff(WINDOW *win, chtype attrs) { PDC_LOG(("wattroff() - called\n")); + assert( win); if (!win) return ERR; @@ -154,6 +161,7 @@ int wattron(WINDOW *win, chtype attrs) PDC_LOG(("wattron() - called\n")); + assert( win); if (!win) return ERR; @@ -183,6 +191,7 @@ int wattrset(WINDOW *win, chtype attrs) { PDC_LOG(("wattrset() - called\n")); + assert( win); if (!win) return ERR; @@ -228,17 +237,21 @@ int wstandout(WINDOW *win) chtype getattrs(WINDOW *win) { + assert( win); return win ? win->_attrs : 0; } int wcolor_set(WINDOW *win, short color_pair, void *opts) { + const int integer_color_pair = (opts ? *(int *)opts : (int)color_pair); + PDC_LOG(("wcolor_set() - called\n")); + assert( win); if (!win) return ERR; - win->_attrs = (win->_attrs & ~A_COLOR) | COLOR_PAIR(color_pair); + win->_attrs = (win->_attrs & ~A_COLOR) | COLOR_PAIR(integer_color_pair); return OK; } @@ -254,6 +267,7 @@ int wattr_get(WINDOW *win, attr_t *attrs, short *color_pair, void *opts) { PDC_LOG(("wattr_get() - called\n")); + assert( win); if (!win) return ERR; @@ -262,6 +276,8 @@ int wattr_get(WINDOW *win, attr_t *attrs, short *color_pair, void *opts) if (color_pair) *color_pair = (short)PAIR_NUMBER(win->_attrs); + if( opts) + *(int *)opts = (int)PAIR_NUMBER( win->_attrs); return OK; } @@ -277,6 +293,8 @@ int wattr_off(WINDOW *win, attr_t attrs, void *opts) { PDC_LOG(("wattr_off() - called\n")); + INTENTIONALLY_UNUSED_PARAMETER( opts); + assert( !opts); return wattroff(win, attrs); } @@ -284,6 +302,8 @@ int attr_off(attr_t attrs, void *opts) { PDC_LOG(("attr_off() - called\n")); + INTENTIONALLY_UNUSED_PARAMETER( opts); + assert( !opts); return wattroff(stdscr, attrs); } @@ -291,6 +311,8 @@ int wattr_on(WINDOW *win, attr_t attrs, void *opts) { PDC_LOG(("wattr_off() - called\n")); + if( opts) + attrs = (attrs & ~A_COLOR) | COLOR_PAIR( *(int *)opts); return wattron(win, attrs); } @@ -298,17 +320,20 @@ int attr_on(attr_t attrs, void *opts) { PDC_LOG(("attr_on() - called\n")); - return wattron(stdscr, attrs); + return wattr_on(stdscr, attrs, opts); } int wattr_set(WINDOW *win, attr_t attrs, short color_pair, void *opts) { + const int integer_color_pair = (opts ? *(int *)opts : (int)color_pair); + PDC_LOG(("wattr_set() - called\n")); + assert( win); if (!win) return ERR; - win->_attrs = (attrs & (A_ATTRIBUTES & ~A_COLOR)) | COLOR_PAIR(color_pair); + win->_attrs = (attrs & (A_ATTRIBUTES & ~A_COLOR)) | COLOR_PAIR(integer_color_pair); return OK; } @@ -324,13 +349,15 @@ int wchgat(WINDOW *win, int n, attr_t attr, short color, const void *opts) { chtype *dest, newattr; int startpos, endpos; + const int integer_color_pair = (opts ? *(int *)opts : (int)color); PDC_LOG(("wchgat() - called\n")); + assert( win); if (!win) return ERR; - newattr = (attr & A_ATTRIBUTES) | COLOR_PAIR(color); + newattr = (attr & A_ATTRIBUTES) | COLOR_PAIR(integer_color_pair); startpos = win->_curx; endpos = ((n < 0) ? win->_maxx : min(startpos + n, win->_maxx)) - 1; @@ -339,13 +366,7 @@ int wchgat(WINDOW *win, int n, attr_t attr, short color, const void *opts) for (n = startpos; n <= endpos; n++) dest[n] = (dest[n] & A_CHARTEXT) | newattr; - n = win->_cury; - - if (startpos < win->_firstch[n] || win->_firstch[n] == _NO_CHANGE) - win->_firstch[n] = startpos; - - if (endpos > win->_lastch[n]) - win->_lastch[n] = endpos; + PDC_mark_cells_as_changed( win, win->_cury, startpos, endpos); PDC_sync(win); diff --git a/src/3rdparty/win32_src/pdcurses/beep.c b/src/3rdparty/win32_src/pdcurses/beep.c index 85845dec3..21b138adc 100644 --- a/src/3rdparty/win32_src/pdcurses/beep.c +++ b/src/3rdparty/win32_src/pdcurses/beep.c @@ -55,6 +55,7 @@ int flash(void) PDC_LOG(("flash() - called\n")); + assert( curscr); if (!curscr) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/bkgd.c b/src/3rdparty/win32_src/pdcurses/bkgd.c index f57643731..0806dce68 100644 --- a/src/3rdparty/win32_src/pdcurses/bkgd.c +++ b/src/3rdparty/win32_src/pdcurses/bkgd.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -72,6 +73,7 @@ int wbkgd(WINDOW *win, chtype ch) PDC_LOG(("wbkgd() - called\n")); + assert( win); if (!win) return ERR; @@ -172,6 +174,7 @@ chtype getbkgd(WINDOW *win) { PDC_LOG(("getbkgd() - called\n")); + assert( win); return win ? win->_bkgd : (chtype)ERR; } @@ -180,6 +183,7 @@ int wbkgrnd(WINDOW *win, const cchar_t *wch) { PDC_LOG(("wbkgrnd() - called\n")); + assert( wch); return wch ? wbkgd(win, *wch) : ERR; } @@ -209,6 +213,8 @@ int wgetbkgrnd(WINDOW *win, cchar_t *wch) { PDC_LOG(("wgetbkgrnd() - called\n")); + assert( win); + assert( wch); if (!win || !wch) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/border.c b/src/3rdparty/win32_src/pdcurses/border.c index 62458b683..43d924a26 100644 --- a/src/3rdparty/win32_src/pdcurses/border.c +++ b/src/3rdparty/win32_src/pdcurses/border.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -40,6 +41,7 @@ border int mvvline_set(int y, int x, const cchar_t *wch, int n); int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n); int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n); + int PDC_set_box_type( const int box_type); ### Description @@ -55,6 +57,11 @@ border bl bottom left corner of border ACS_LLCORNER br bottom right corner of border ACS_LRCORNER + PDC_set_box_type() can reset these defaults to use the double-line + characters. 'box_type' can include the bitflag constants. + PDC_BOX_DOUBLED_V and/or PDC_BOX_DOUBLED_H. The previously set + default box type is returned. + hline() and whline() draw a horizontal line, using ch, starting from the current cursor position. The cursor position does not change. The line is at most n characters long, or as many as will fit in the @@ -134,27 +141,50 @@ static chtype _attr_passthru(WINDOW *win, chtype ch) return ch; } +static int _box_type = 0; + + +int PDC_set_box_type( const int box_type) +{ + const int rval = _box_type; + + _box_type = box_type; + return( rval); +} + int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, chtype bl, chtype br) { int i, ymax, xmax; + chtype def_val; + const int doubled_v = (_box_type & PDC_BOX_DOUBLED_V); + const int doubled_h = (_box_type & PDC_BOX_DOUBLED_H); PDC_LOG(("wborder() - called\n")); + assert( win); if (!win) return ERR; ymax = win->_maxy - 1; xmax = win->_maxx - 1; - ls = _attr_passthru(win, ls ? ls : ACS_VLINE); - rs = _attr_passthru(win, rs ? rs : ACS_VLINE); - ts = _attr_passthru(win, ts ? ts : ACS_HLINE); - bs = _attr_passthru(win, bs ? bs : ACS_HLINE); - tl = _attr_passthru(win, tl ? tl : ACS_ULCORNER); - tr = _attr_passthru(win, tr ? tr : ACS_URCORNER); - bl = _attr_passthru(win, bl ? bl : ACS_LLCORNER); - br = _attr_passthru(win, br ? br : ACS_LRCORNER); + def_val = (doubled_v ? ACS_D_VLINE : ACS_VLINE); + ls = _attr_passthru(win, ls ? ls : def_val); + rs = _attr_passthru(win, rs ? rs : def_val); + def_val = (doubled_h ? ACS_D_HLINE : ACS_HLINE); + ts = _attr_passthru(win, ts ? ts : def_val); + bs = _attr_passthru(win, bs ? bs : def_val); + + if( doubled_v) + def_val = doubled_h ? ACS_D_LRCORNER : ACS_DS_LRCORNER; + else + def_val = doubled_h ? ACS_SD_LRCORNER : ACS_LRCORNER; + + tl = _attr_passthru(win, tl ? tl : def_val + 2); + tr = _attr_passthru(win, tr ? tr : def_val + 1); + bl = _attr_passthru(win, bl ? bl : def_val + 3); + br = _attr_passthru(win, br ? br : def_val); for (i = 1; i < xmax; i++) { @@ -173,11 +203,13 @@ int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs, win->_y[ymax][0] = bl; win->_y[ymax][xmax] = br; - for (i = 0; i <= ymax; i++) + for (i = 1; i < ymax; i++) { - win->_firstch[i] = 0; - win->_lastch[i] = xmax; + PDC_mark_cell_as_changed( win, i, 0); + PDC_mark_cell_as_changed( win, i, xmax); } + PDC_set_changed_cells_range( win, 0, 0, xmax); + PDC_set_changed_cells_range( win, ymax, 0, xmax); PDC_sync(win); @@ -206,6 +238,7 @@ int whline(WINDOW *win, chtype ch, int n) PDC_LOG(("whline() - called\n")); + assert( win); if (!win || n < 1) return ERR; @@ -219,11 +252,7 @@ int whline(WINDOW *win, chtype ch, int n) n = win->_cury; - if (startpos < win->_firstch[n] || win->_firstch[n] == _NO_CHANGE) - win->_firstch[n] = startpos; - - if (endpos > win->_lastch[n]) - win->_lastch[n] = endpos; + PDC_mark_cells_as_changed( win, n, startpos, endpos); PDC_sync(win); @@ -263,6 +292,7 @@ int wvline(WINDOW *win, chtype ch, int n) PDC_LOG(("wvline() - called\n")); + assert( win); if (!win || n < 1) return ERR; @@ -274,12 +304,7 @@ int wvline(WINDOW *win, chtype ch, int n) for (n = win->_cury; n < endpos; n++) { win->_y[n][x] = ch; - - if (x < win->_firstch[n] || win->_firstch[n] == _NO_CHANGE) - win->_firstch[n] = x; - - if (x > win->_lastch[n]) - win->_lastch[n] = x; + PDC_mark_cell_as_changed( win, n, x); } PDC_sync(win); @@ -348,6 +373,7 @@ int whline_set(WINDOW *win, const cchar_t *wch, int n) { PDC_LOG(("whline_set() - called\n")); + assert( wch); return wch ? whline(win, *wch, n) : ERR; } @@ -382,6 +408,7 @@ int wvline_set(WINDOW *win, const cchar_t *wch, int n) { PDC_LOG(("wvline_set() - called\n")); + assert( wch); return wch ? wvline(win, *wch, n) : ERR; } diff --git a/src/3rdparty/win32_src/pdcurses/clear.c b/src/3rdparty/win32_src/pdcurses/clear.c index 50ff7ad3f..80938dd4e 100644 --- a/src/3rdparty/win32_src/pdcurses/clear.c +++ b/src/3rdparty/win32_src/pdcurses/clear.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -58,6 +59,7 @@ int wclrtoeol(WINDOW *win) PDC_LOG(("wclrtoeol() - called: Row: %d Col: %d\n", win->_cury, win->_curx)); + assert( win); if (!win) return ERR; @@ -71,10 +73,7 @@ int wclrtoeol(WINDOW *win) for (minx = x, ptr = &win->_y[y][x]; minx < win->_maxx; minx++, ptr++) *ptr = blank; - if (x < win->_firstch[y] || win->_firstch[y] == _NO_CHANGE) - win->_firstch[y] = x; - - win->_lastch[y] = win->_maxx - 1; + PDC_mark_cells_as_changed( win, y, x, win->_maxx - 1); PDC_sync(win); return OK; @@ -93,6 +92,7 @@ int wclrtobot(WINDOW *win) PDC_LOG(("wclrtobot() - called\n")); + assert( win); if (!win) return ERR; @@ -144,6 +144,7 @@ int wclear(WINDOW *win) { PDC_LOG(("wclear() - called\n")); + assert( win); if (!win) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/color.c b/src/3rdparty/win32_src/pdcurses/color.c index 85707e451..032d6bc30 100644 --- a/src/3rdparty/win32_src/pdcurses/color.c +++ b/src/3rdparty/win32_src/pdcurses/color.c @@ -21,8 +21,13 @@ color int init_extended_color(int color, int red, int green, int blue); int extended_color_content(int color, int *red, int *green, int *blue); + int alloc_pair( int fg, int bg); int assume_default_colors(int f, int b); + int find_pair( int fg, int bg); + int free_pair( int pair); int use_default_colors(void); + void reset_color_pairs(void); + void PDC_set_default_colors( const int fg_idx, const int bg_idx); int PDC_set_line_color(short color); @@ -80,6 +85,27 @@ color variable PDC_ORIGINAL_COLORS is set at the time start_color() is called, that's equivalent to calling use_default_colors(). + alloc_pair(), find_pair() and free_pair() are also from ncurses. + free_pair() marks a pair as unused; find_pair() returns an existing + pair with the specified foreground and background colors, if one + exists. And alloc_pair() returns such a pair whether or not it was + previously set, overwriting the oldest initialized pair if there are + no free pairs. + + reset_color_pairs(), also from ncurses, discards all color pair + information that was set with init_pair(). In practice, this means + all color pairs except pair 0 become undefined. + + VT and WinCon define 'default' colors to be those inherited from + the terminal; SDLn defines them to be the colors of the background + image, if any. On all other platforms, and on SDLn if there's no + background images, the default background is black; the default + foreground is white. PDC_set_default_colors(), a PDCursesMod- + specific function, allows you to override this and define default + colors before calling initscr(). This was added for the Plan9 + platform, where the desired default is black text on a white + background, but it can be used with any platform. + PDC_set_line_color() is used to set the color, globally, for the color of the lines drawn for the attributes: A_UNDERLINE, A_LEFT and A_RIGHT. A value of -1 (the default) indicates that the current @@ -89,8 +115,10 @@ color ### Return Value - All functions return OK on success and ERR on error, except for - has_colors() and can_change_colors(), which return TRUE or FALSE. + Most functions return OK on success and ERR on error. has_colors() + and can_change_colors() return TRUE or FALSE. alloc_pair() and + find_pair() return a pair number, or -1 on error. + ### Portability X/Open ncurses NetBSD @@ -101,7 +129,10 @@ color can_change_color Y Y Y init_color Y Y Y color_content Y Y Y + alloc_pair - Y - assume_default_colors - Y Y + find_pair - Y - + free_pair - Y - use_default_colors - Y Y PDC_set_line_color - - - @@ -112,15 +143,107 @@ color #include #include +/* Color pair structure */ + +typedef struct +{ + int f; /* foreground color */ + int b; /* background color */ + int prev, next; /* doubly-linked list indices */ +} PDC_PAIR; + int COLORS = 0; -int COLOR_PAIRS = PDC_COLOR_PAIRS; +int COLOR_PAIRS = 1; /* until start_color() is called */ static int atrtab_size_alloced; static bool default_colors = FALSE; static int first_col = 0; +static int _default_foreground_idx = COLOR_WHITE; +static int _default_background_idx = COLOR_BLACK; + +static void _init_pair_core(int pair, int fg, int bg); #define UNSET_COLOR_PAIR -2 +static void _unlink_color_pair( const int pair_no) +{ + PDC_PAIR *p = (PDC_PAIR *)SP->atrtab; + PDC_PAIR *curr = p + pair_no; + + p[curr->next].prev = curr->prev; + p[curr->prev].next = curr->next; +} + +static void _link_color_pair( const int pair_no, const int head) +{ + PDC_PAIR *p = (PDC_PAIR *)SP->atrtab; + PDC_PAIR *curr = p + pair_no; + + curr->next = p[head].next; + curr->prev = head; + p[head].next = p[curr->next].prev = pair_no; +} + +#if PDC_COLOR_BITS < 15 + typedef int16_t hash_idx_t; +#else + typedef int32_t hash_idx_t; +#endif + +static hash_idx_t *_pair_hash_tbl = NULL; +static int _pair_hash_tbl_size = 0, _pair_hash_tbl_used = 0; + +static int _hash_color_pair( const int fg, const int bg) +{ + int rval = (fg * 31469 + bg * 19583); + + assert( _pair_hash_tbl_size); + rval ^= rval >> 11; + rval ^= rval << 7; + rval &= (_pair_hash_tbl_size - 1); + return( rval); +} + +/* Linear/triangular-number hybrid hash table probing sequence. See +https://www.projectpluto.com/hashing.htm for details. */ + +#define GROUP_SIZE 4 +#define ADVANCE_HASH_PROBE( idx, iter) \ + { idx++; \ + if( iter % GROUP_SIZE == 0) idx += iter - GROUP_SIZE; \ + idx &= (_pair_hash_tbl_size - 1); } + +static void _check_hash_tbl( void) +{ + assert( SP->atrtab); + if( _pair_hash_tbl_used * 5 / 4 >= _pair_hash_tbl_size) + { + int i, n_pairs; + PDC_PAIR *p = (PDC_PAIR *)SP->atrtab; + + for( i = 1, n_pairs = 0; i < atrtab_size_alloced; i++) + if( p[i].f != UNSET_COLOR_PAIR) + n_pairs++; + _pair_hash_tbl_used = n_pairs; + _pair_hash_tbl_size = 8; /* minimum table size */ + while( n_pairs >= _pair_hash_tbl_size * 3 / 4) + _pair_hash_tbl_size <<= 1; /* more than 75% of table is full */ + if( _pair_hash_tbl) + free( _pair_hash_tbl); + _pair_hash_tbl = (hash_idx_t *)calloc( + _pair_hash_tbl_size, sizeof( hash_idx_t)); + for( i = 1; i < atrtab_size_alloced; i++) + if( p[i].f != UNSET_COLOR_PAIR) + { + int idx = _hash_color_pair( p[i].f, p[i].b), iter; + + for( iter = 0; _pair_hash_tbl[idx]; iter++) + ADVANCE_HASH_PROBE( idx, iter); + _pair_hash_tbl[idx] = (hash_idx_t)i; + } + } +} + int start_color(void) { PDC_LOG(("start_color() - called\n")); @@ -136,8 +259,10 @@ int start_color(void) if (!default_colors && SP->orig_attr && getenv("PDC_ORIGINAL_COLORS")) default_colors = TRUE; - PDC_init_atrtab(); -#if defined( CHTYPE_64) && !defined(OS2) && !defined(DOS) + _init_pair_core( 0, _default_foreground_idx, _default_background_idx); + if( !SP->_preserve) + curscr->_clear = TRUE; +#if !defined( CHTYPE_32) && !defined(OS2) && !defined(DOS) if( COLORS >= 1024 && (long)INT_MAX > 1024L * 1024L) COLOR_PAIRS = 1024 * 1024; else if( COLORS >= 16) @@ -147,47 +272,119 @@ int start_color(void) else COLOR_PAIRS = INT_MAX; } -#endif +#else + COLOR_PAIRS = (1 << PDC_COLOR_BITS); +#endif /* will be 256 (wide-char builds) or 4096 (8-bit chars) */ return OK; } +void PDC_set_default_colors( const int fg_idx, const int bg_idx) +{ + _default_foreground_idx = fg_idx; + _default_background_idx = bg_idx; +} + static void _normalize(int *fg, int *bg) { const bool using_defaults = (SP->orig_attr && (default_colors || !SP->color_started)); if (*fg == -1 || *fg == UNSET_COLOR_PAIR) - *fg = using_defaults ? SP->orig_fore : COLOR_WHITE; + *fg = using_defaults ? SP->orig_fore : _default_foreground_idx; - if (*bg == -1 || *bg == UNSET_COLOR_PAIR) - *bg = using_defaults ? SP->orig_back : COLOR_BLACK; + if (*bg == -1 || *fg == UNSET_COLOR_PAIR) + *bg = using_defaults ? SP->orig_back : _default_background_idx; +} + +/* When a color pair is reset, all cells of that color should be +redrawn. refresh() and doupdate() don't redraw for color pair changes, +so we have to redraw that text specifically. The following test is +equivalent to 'if( pair == (int)PAIR_NUMBER( *line))', but saves a +few cycles by not shifting. */ + +#define USES_TARGET_PAIR( ch) (!(((ch) ^ mask) & A_COLOR)) + +static void _set_cells_to_refresh_for_pair_change( const int pair) +{ + int x, y; + const chtype mask = ((chtype)pair << PDC_COLOR_SHIFT); + + assert( SP->lines); + assert( curscr && curscr->_y); + if( !curscr->_clear) + for( y = 0; y < SP->lines; y++) + { + chtype *line = curscr->_y[y]; + + assert( line); + for( x = 0; x < SP->cols; x++) + if( USES_TARGET_PAIR( line[x])) + { + const int start_x = x++; + + while( x < SP->cols && USES_TARGET_PAIR( line[x])) + x++; + PDC_transform_line( y, start_x, x - start_x, line + start_x); + } + } +} + +/* Similarly, if PDC_set_bold(), PDC_set_blink(), or +PDC_set_line_color() is called (and changes the way in which text +with those attributes is drawn), the corresponding text should be +redrawn. */ + +void PDC_set_cells_to_refresh_for_attr_change( const chtype attr) +{ + int x, y; + + assert( SP->lines); + assert( curscr && curscr->_y); + if( !curscr->_clear) + for( y = 0; y < SP->lines; y++) + { + chtype *line = curscr->_y[y]; + + assert( line); + for( x = 0; x < SP->cols; x++) + if( !(*line & attr)) + { + const int start_x = x++; + + while( x < SP->cols && !(*line & attr)) + x++; + PDC_transform_line( y, start_x, x - start_x, line + start_x); + } + } } static void _init_pair_core(int pair, int fg, int bg) { PDC_PAIR *p; + bool refresh_pair; assert( SP->atrtab); assert( atrtab_size_alloced); + assert( pair < COLOR_PAIRS); if( pair >= atrtab_size_alloced) { int i, new_size = atrtab_size_alloced * 2; while( pair >= new_size) new_size += new_size; - SP->atrtab = (PDC_PAIR *)realloc( SP->atrtab, new_size * sizeof( PDC_PAIR)); + SP->atrtab = (void *)realloc( SP->atrtab, (new_size + 1) * sizeof( PDC_PAIR)); assert( SP->atrtab); - p = SP->atrtab + atrtab_size_alloced; - for( i = new_size - atrtab_size_alloced; i; i--, p++) + for( i = atrtab_size_alloced + 1; i <= new_size; i++) { - p->f = COLOR_GREEN; /* signal uninitialized pairs by */ - p->b = COLOR_YELLOW; /* using unusual colors */ + p = (PDC_PAIR *)SP->atrtab + i; + p->f = UNSET_COLOR_PAIR; + _link_color_pair( i, atrtab_size_alloced); } atrtab_size_alloced = new_size; } assert( pair >= 0); assert( pair < atrtab_size_alloced); - p = SP->atrtab + pair; + p = (PDC_PAIR *)SP->atrtab + pair; /* To allow the PDC_PRESERVE_SCREEN option to work, we only reset curscr if this call to init_pair() alters a color pair created by @@ -195,13 +392,37 @@ static void _init_pair_core(int pair, int fg, int bg) _normalize(&fg, &bg); - if (p->f != UNSET_COLOR_PAIR) + refresh_pair = (p->f != UNSET_COLOR_PAIR && (p->f != fg || p->b != bg)); + _check_hash_tbl( ); + if( pair && p->f != UNSET_COLOR_PAIR) { - if (p->f != fg || p->b != bg) - curscr->_clear = TRUE; + int idx = _hash_color_pair( p->f, p->b), iter; + + for( iter = 0; _pair_hash_tbl[idx] != pair; iter++) + { + assert( _pair_hash_tbl[idx]); + ADVANCE_HASH_PROBE( idx, iter); + } + _pair_hash_tbl[idx] = -1; /* mark as freed */ } + if( pair) + _unlink_color_pair( pair); p->f = fg; p->b = bg; + if( pair && fg != UNSET_COLOR_PAIR) + { + int idx = _hash_color_pair( fg, bg), iter; + + for( iter = 0; _pair_hash_tbl[idx] > 0; iter++) + ADVANCE_HASH_PROBE( idx, iter); + if( !_pair_hash_tbl[idx]) /* using a new pair */ + _pair_hash_tbl_used++; + _pair_hash_tbl[idx] = (hash_idx_t)pair; + } + if( pair) + _link_color_pair( pair, (p->f == UNSET_COLOR_PAIR ? atrtab_size_alloced : 0)); + if( refresh_pair) + _set_cells_to_refresh_for_pair_change( pair); } int init_extended_pair(int pair, int fg, int bg) @@ -214,7 +435,6 @@ int init_extended_pair(int pair, int fg, int bg) return ERR; _init_pair_core(pair, fg, bg); - return OK; } @@ -222,6 +442,7 @@ bool has_colors(void) { PDC_LOG(("has_colors() - called\n")); + assert( SP); return SP ? !(SP->mono) : FALSE; } @@ -236,7 +457,7 @@ int init_extended_color(int color, int red, int green, int blue) return ERR; SP->dirty = TRUE; - + curscr->_clear = TRUE; return PDC_init_color(color, red, green, blue); } @@ -273,20 +494,22 @@ bool can_change_color(void) int extended_pair_content(int pair, int *fg, int *bg) { + PDC_PAIR *p = (PDC_PAIR *)SP->atrtab + pair; + PDC_LOG(("pair_content() - called\n")); if (pair < 0 || pair >= COLOR_PAIRS || !fg || !bg) return ERR; - if( pair >= atrtab_size_alloced) + if( pair >= atrtab_size_alloced || (pair && p->f == UNSET_COLOR_PAIR)) { *fg = COLOR_RED; /* signal use of uninitialized pair */ *bg = COLOR_BLUE; /* with visible, but odd, colors */ } else { - *fg = SP->atrtab[pair].f; - *bg = SP->atrtab[pair].b; + *fg = p->f; + *bg = p->b; } return OK; } @@ -325,25 +548,33 @@ int PDC_set_line_color(short color) if (!SP || color < -1 || color >= COLORS) return ERR; + if( SP->line_color != color) + PDC_set_cells_to_refresh_for_attr_change( + A_OVERLINE | A_UNDERLINE | A_LEFTLINE | A_RIGHTLINE | A_STRIKEOUT); SP->line_color = color; - return OK; } int PDC_init_atrtab(void) { - int i; - assert( SP); if( !SP->atrtab) { - atrtab_size_alloced = PDC_COLOR_PAIRS; - SP->atrtab = calloc( atrtab_size_alloced, sizeof(PDC_PAIR)); + PDC_PAIR *p; + + atrtab_size_alloced = 1; + SP->atrtab = calloc( 2, sizeof(PDC_PAIR)); + assert( SP->atrtab); if( !SP->atrtab) return -1; + p = (PDC_PAIR *)SP->atrtab; + p[0].f = p[1].f = UNSET_COLOR_PAIR; + p[0].prev = p[0].next = 0; + p[1].prev = p[1].next = 1; } - for (i = 0; i < atrtab_size_alloced; i++) - _init_pair_core( i, UNSET_COLOR_PAIR, UNSET_COLOR_PAIR); + _init_pair_core( 0, + (SP->orig_attr ? SP->orig_fore : _default_foreground_idx), + (SP->orig_attr ? SP->orig_back : _default_background_idx)); return( 0); } @@ -383,3 +614,149 @@ int color_content( short color, short *red, short *green, short *blue) } return( rval); } + +int find_pair( int fg, int bg) +{ + int idx = _hash_color_pair( fg, bg), iter; + + assert( SP); + assert( SP->atrtab); + assert( atrtab_size_alloced); + for( iter = 0; _pair_hash_tbl[idx]; iter++) + { + int i; + + if( (i = _pair_hash_tbl[idx]) > 0) + { + PDC_PAIR *p = (PDC_PAIR *)SP->atrtab; + + if( p[i].f == fg && p[i].b == bg) + { + _unlink_color_pair( i); /* unlink it and relink it */ + _link_color_pair( i, 0); /* to make it the 'head' node */ + return( i); /* we found the color */ + } + } + ADVANCE_HASH_PROBE( idx, iter); + } + return( -1); +} + +/* alloc_pair() first simply looks to see if the desired pair is +already allocated. If it has been, we're done. + + If it hasn't been, the doubly-linked list of free color +pairs (see 'pairs.txt') will indicate an available node. If +we've actually run out of free color pairs, the doubly-linked +list of used color pairs will link to the oldest inserted node. +*/ + +int alloc_pair( int fg, int bg) +{ + int rval = find_pair( fg, bg); + + if( -1 == rval) /* pair isn't already allocated. First, look */ + { /* for an unset color pair. */ + PDC_PAIR *p = (PDC_PAIR *)SP->atrtab; + + rval = p[atrtab_size_alloced].prev; + assert( rval); + if( COLOR_PAIRS == rval) /* all color pairs are in use; */ + rval = p[0].prev; /* 'repurpose' the oldest pair */ + if( ERR == init_extended_pair( rval, fg, bg)) + rval = -1; + assert( rval != -1); + } + return( rval); +} + +int free_pair( int pair) +{ + PDC_PAIR *p; + + assert( SP && SP->atrtab); + assert( pair >= 1 && pair < atrtab_size_alloced); + p = (PDC_PAIR *)SP->atrtab + pair; + assert( p->f != UNSET_COLOR_PAIR); + if (!SP || !SP->color_started || pair < 1 || pair >= atrtab_size_alloced + || p->f == UNSET_COLOR_PAIR) + return ERR; + + _init_pair_core(pair, UNSET_COLOR_PAIR, 0); + return OK; +} + +void PDC_free_pair_hash_table( void) +{ + if( _pair_hash_tbl) + free( _pair_hash_tbl); + _pair_hash_tbl = NULL; + _pair_hash_tbl_size = _pair_hash_tbl_used = 0; +} + +void reset_color_pairs( void) +{ + assert( SP && SP->atrtab); + free( SP->atrtab); + SP->atrtab = NULL; + PDC_free_pair_hash_table( ); + PDC_init_atrtab( ); + curscr->_clear = TRUE; +} + +#ifdef PDC_COLOR_PAIR_DEBUGGING_FUNCTIONS + +/* The following is solely for testing the color pair table, and +specifically its two doubly-linked lists (one of 'used' pairs, one of +'free' pairs). The elements in both lists are counted. The total should +equal the number of allocated pairs. All pairs in the first linked list +are checked to make sure they're really used; all in the second to make +sure they're really free. We also check that the links are consistent. +The return value is 0 if the table checks out, -1 if it does not. +'results' contains the number of used pairs, the number of free pairs, +and the number of allocated pairs (which should be the sum of the first +two numbers.) It also returns some data on the hash table size and +usage. See 'pairs.txt' for more details. */ + +int PDC_check_color_pair_table( int *results) +{ + int idx, n_used = 1, n_free = 1; + PDC_PAIR *p; + + assert( SP && SP->atrtab); + p = (PDC_PAIR *)SP->atrtab; + idx = 0; + while( n_used < atrtab_size_alloced + 10 && p[idx].next) + { /* loop through all _used_ color pairs */ + const int next = p[idx].next; + + assert( p[idx].f != UNSET_COLOR_PAIR); + assert( next >= 0 && next < atrtab_size_alloced); + assert( p[next].prev == idx); + idx = p[idx].next; + n_used++; + } + + idx = atrtab_size_alloced; + while( n_free < atrtab_size_alloced + 10 && p[idx].next != atrtab_size_alloced) + { /* loop through all _free_ color pairs */ + const int next = p[idx].next; + + assert( p[idx].f == UNSET_COLOR_PAIR); + assert( next > 0 && next <= atrtab_size_alloced); + assert( p[next].prev == idx); + idx = p[idx].next; + n_free++; + } + + if( results) + { + results[0] = n_used; + results[1] = n_free; + results[2] = atrtab_size_alloced + 1; /* include the 'dummy' pair */ + results[3] = _pair_hash_tbl_size; + results[4] = _pair_hash_tbl_used; + } + return( (n_used + n_free == atrtab_size_alloced + 1) ? 0 : -1); +} +#endif /* #ifdef PDC_COLOR_PAIR_DEBUGGING_FUNCTIONS */ diff --git a/src/3rdparty/win32_src/pdcurses/debug.c b/src/3rdparty/win32_src/pdcurses/debug.c index 2aaff6c72..ffec691a5 100644 --- a/src/3rdparty/win32_src/pdcurses/debug.c +++ b/src/3rdparty/win32_src/pdcurses/debug.c @@ -12,17 +12,32 @@ debug void traceon(void); void traceoff(void); + unsigned curses_trace( const unsigned); + void trace( const unsigned); void PDC_debug(const char *, ...); + void _tracef(const char *, ...); ### Description traceon() and traceoff() toggle the recording of debugging information to the file "trace". Although not standard, similar - functions are in some other curses implementations. + functions are in some other curses implementations (e.g., SVr4). + + curses_trace() turns tracing on if called with a non-zero value and + off if called with zero. At some point, the input value will be + used to set flags for more nuanced trace output, a la ncurses; but + at present, debugging is simply on or off. The previous tracing + flags are returned. + + trace() is a duplicate of curses_trace(), but returns nothing. It + is deprecated because it often conflicts with application names. PDC_debug() is the function that writes to the file, based on whether traceon() has been called. It's used from the PDC_LOG() macro. + _tracef() is an ncurses alias for PDC_debug, and is added solely + for compatibility. + The environment variable PDC_TRACE_FLUSH controls whether the trace file contents are fflushed after each write. The default is not. Set it to enable this (may affect performance). @@ -31,7 +46,10 @@ debug X/Open ncurses NetBSD traceon - - - traceoff - - - + trace - Y - + curses_trace - Y - PDC_debug - - - + _tracef - Y - **man-end****************************************************************/ @@ -40,6 +58,10 @@ debug #include #include +/* PDC_trace_flags will eventually be global or part of the SCREEN struct. */ + +static unsigned PDC_trace_flags = 0; + static bool want_fflush = FALSE; void PDC_debug(const char *fmt, ...) @@ -49,7 +71,7 @@ void PDC_debug(const char *fmt, ...) time_t now; assert( SP); - if (!SP || !SP->dbfp) + if (!SP || !SP->dbfp || SP->in_endwin) return; time(&now); @@ -73,6 +95,15 @@ void PDC_debug(const char *fmt, ...) expect terrible performance. */ } +void _tracef(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + PDC_debug( fmt, args); + va_end(args); +} + void traceon(void) { assert( SP); @@ -90,6 +121,7 @@ void traceon(void) return; } + PDC_trace_flags = TRACE_MAXIMUM; if (getenv("PDC_TRACE_FLUSH")) want_fflush = TRUE; @@ -106,5 +138,25 @@ void traceoff(void) fclose(SP->dbfp); SP->dbfp = NULL; + PDC_trace_flags = TRACE_DISABLE; want_fflush = FALSE; } + +unsigned curses_trace( const unsigned param) +{ + const unsigned rval = PDC_trace_flags; + + assert( SP); + if( SP) + { + param ? traceon( ) : traceoff( ); + PDC_trace_flags = param; + } + PDC_LOG(("curses_trace() - called\n")); + return( rval); +} + +void trace( const unsigned param) +{ + curses_trace( param); +} diff --git a/src/3rdparty/win32_src/pdcurses/delch.c b/src/3rdparty/win32_src/pdcurses/delch.c index 970a5a81c..2a7a26fc5 100644 --- a/src/3rdparty/win32_src/pdcurses/delch.c +++ b/src/3rdparty/win32_src/pdcurses/delch.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -44,6 +45,7 @@ int wdelch(WINDOW *win) PDC_LOG(("wdelch() - called\n")); + assert( win); if (!win) return ERR; @@ -58,10 +60,7 @@ int wdelch(WINDOW *win) win->_y[y][maxx] = win->_bkgd; - win->_lastch[y] = maxx; - - if ((win->_firstch[y] == _NO_CHANGE) || (win->_firstch[y] > x)) - win->_firstch[y] = x; + PDC_mark_cells_as_changed( win, y, x, maxx); PDC_sync(win); diff --git a/src/3rdparty/win32_src/pdcurses/deleteln.c b/src/3rdparty/win32_src/pdcurses/deleteln.c index 8e7563f38..7d0b5a3b1 100644 --- a/src/3rdparty/win32_src/pdcurses/deleteln.c +++ b/src/3rdparty/win32_src/pdcurses/deleteln.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -60,6 +61,7 @@ int wdeleteln(WINDOW *win) PDC_LOG(("wdeleteln() - called\n")); + assert( win); if (!win) return ERR; @@ -72,8 +74,7 @@ int wdeleteln(WINDOW *win) for (y = win->_cury; y < win->_bmarg; y++) { win->_y[y] = win->_y[y + 1]; - win->_firstch[y] = 0; - win->_lastch[y] = win->_maxx - 1; + PDC_mark_line_as_changed( win, y); } for (ptr = temp; (ptr - temp < win->_maxx); ptr++) @@ -81,8 +82,7 @@ int wdeleteln(WINDOW *win) if (win->_cury <= win->_bmarg) { - win->_firstch[win->_bmarg] = 0; - win->_lastch[win->_bmarg] = win->_maxx - 1; + PDC_mark_line_as_changed( win, win->_bmarg); win->_y[win->_bmarg] = temp; } @@ -122,6 +122,7 @@ int winsdelln(WINDOW *win, int n) PDC_LOG(("winsdelln() - called\n")); + assert( win); if (!win) return ERR; @@ -156,6 +157,7 @@ int winsertln(WINDOW *win) PDC_LOG(("winsertln() - called\n")); + assert( win); if (!win) return ERR; @@ -168,8 +170,7 @@ int winsertln(WINDOW *win) for (y = win->_maxy - 1; y > win->_cury; y--) { win->_y[y] = win->_y[y - 1]; - win->_firstch[y] = 0; - win->_lastch[y] = win->_maxx - 1; + PDC_mark_line_as_changed( win, y); } win->_y[win->_cury] = temp; @@ -177,8 +178,7 @@ int winsertln(WINDOW *win) for (end = &temp[win->_maxx - 1]; temp <= end; temp++) *temp = blank; - win->_firstch[win->_cury] = 0; - win->_lastch[win->_cury] = win->_maxx - 1; + PDC_mark_line_as_changed( win, win->_cury); return OK; } diff --git a/src/3rdparty/win32_src/pdcurses/getch.c b/src/3rdparty/win32_src/pdcurses/getch.c index 19b3f4873..553118373 100644 --- a/src/3rdparty/win32_src/pdcurses/getch.c +++ b/src/3rdparty/win32_src/pdcurses/getch.c @@ -40,7 +40,7 @@ getch If keypad() is TRUE, and a function key is pressed, the token for that function key will be returned instead of the raw characters. Possible function keys are defined in with integers - beginning with 0401, whose names begin with KEY_. + starting at KEY_OFFSET, whose names begin with KEY_. If nodelay(win, TRUE) has been called on the window and no input is waiting, the value ERR is returned. @@ -55,8 +55,9 @@ getch PDCurses is built with the PDC_WIDE option. It takes a pointer to a wint_t rather than returning the key as an int, and instead returns KEY_CODE_YES if the key is a function key. Otherwise, it returns OK - or ERR. It's important to check for KEY_CODE_YES, since regular wide - characters can have the same values as function key codes. + or ERR. It's important to check for KEY_CODE_YES; on most Curses + implementations (not PDCursesMod), regular wide characters can have + the same values as function key codes. unget_wch() puts a wide character on the input queue. @@ -94,6 +95,75 @@ getch #include + /* By default, the PDC_function_key[] array contains 0 */ + /* (i.e., there's no key that's supposed to be returned for */ + /* exit handling), and 22 = Ctrl-V (i.e., hit Ctrl-V to */ + /* paste text from the clipboard into the key queue); then */ + /* no key by default to enlarge/decrease font size or to */ + /* select a font from the font dialog; then Ctrl-C for copy. */ + +static int PDC_function_key[PDC_MAX_FUNCTION_KEYS] = { 0, 22, 0, 0, 0, 0, 3 }; + +/*man-start************************************************************** + +Function keys +------------- + +### Synopsis + + int PDC_set_function_key( const unsigned function, const int new_key); + int PDC_get_function_key( const unsigned function); + +### Description + + Allows one to set a 'shut down' key, and reassign hotkeys used for + copying to/pasting from the clipboard and enlarging and decreasing the + font size, and for using the font selection dialog (on platforms where + these things are possible and implemented). For example, calling + + PDC_set_function_key( FUNCTION_KEY_SHUT_DOWN, ALT_Q); + + would reset PDCursesMod such that, if the user clicks on the 'close' + box, Alt-Q would be added to the key queue. This would give the app the + opportunity to shut things down gracefully, perhaps asking "are you + sure", and/or "save changes or discard or cancel", rather than just + having the window close (the default behavior). + + Similarly, one can set FUNCTION_KEY_ABORT to a key which, when pressed, + will cause the program to abort gracelessly (no key returned to the + application). One would normally use this to enable/disable Ctrl-C or + Ctrl-Break, or to set a different 'abort' key so that Ctrl-C can be + used for copying. + +### Return Value + + Returns key code previously set for that function, or -1 if the + function does not actually exist. + +### Portability + + PDCursesMod-only function. + +**man-end****************************************************************/ +int PDC_set_function_key( const unsigned function, const int new_key) +{ + int old_key = -1; + + assert( function < PDC_MAX_FUNCTION_KEYS); + if( function < PDC_MAX_FUNCTION_KEYS) + { + old_key = PDC_function_key[function]; + PDC_function_key[function] = new_key; + } + return( old_key); +} + +int PDC_get_function_key( const unsigned function) +{ + assert( function < PDC_MAX_FUNCTION_KEYS); + return( PDC_function_key[function]); +} + static int _get_box(int *y_start, int *y_end, int *x_start, int *x_end) { int start, end; @@ -231,10 +301,13 @@ static int _paste(void) return key; } +#define WHEEL_EVENTS (PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN|PDC_MOUSE_WHEEL_RIGHT | PDC_MOUSE_WHEEL_LEFT) + static int _mouse_key(void) { - int i, key = KEY_MOUSE, changes = SP->mouse_status.changes; - const unsigned long mbe = SP->_trap_mbe; + int i, key = KEY_MOUSE; + const int changes = SP->mouse_status.changes; + const mmask_t mbe = SP->_trap_mbe; bool can_select = !(mbe & (BUTTON1_MOVED | BUTTON1_PRESSED | BUTTON1_RELEASED)); bool can_paste = !(mbe & BUTTON2_CLICKED); /* really means 'can do these things without shift' */ @@ -269,7 +342,6 @@ static int _mouse_key(void) changes & 2 && (SP->mouse_status.button[1] & BUTTON_ACTION_MASK) == BUTTON_CLICKED) { - SP->key_code = FALSE; return _paste(); } @@ -279,7 +351,7 @@ static int _mouse_key(void) { if (changes & (1 << i)) { - int shf = i * 5; + int shf = i * PDC_BITS_PER_BUTTON; short button = SP->mouse_status.button[i] & BUTTON_ACTION_MASK; if ( (!(mbe & (BUTTON1_PRESSED << shf)) && @@ -310,14 +382,13 @@ static int _mouse_key(void) SP->mouse_status.changes ^= PDC_MOUSE_MOVED; } - if (changes & (PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN)) + if (changes & WHEEL_EVENTS) { if (!(mbe & MOUSE_WHEEL_SCROLL)) - SP->mouse_status.changes &= - ~(PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN); + SP->mouse_status.changes &= ~WHEEL_EVENTS; } - if (!changes) + if (!SP->mouse_status.changes) return -1; /* Check for click in slk area */ @@ -335,11 +406,16 @@ static int _mouse_key(void) return key; } +bool PDC_is_function_key( const int key) +{ + return( key >= KEY_MIN && key < KEY_MAX); +} + #define WAIT_FOREVER -1 int wgetch(WINDOW *win) { - int key, remaining_millisecs; + int key = ERR, remaining_millisecs; PDC_LOG(("wgetch() - called\n")); @@ -366,13 +442,19 @@ int wgetch(WINDOW *win) /* if ungotten char exists, remove and return it */ if (SP->c_ungind) - return SP->c_ungch[--(SP->c_ungind)]; + key = SP->c_ungch[--(SP->c_ungind)]; /* if normal and data in buffer */ - if ((!SP->raw_inp && !SP->cbreak) && (SP->c_gindex < SP->c_pindex)) - return SP->c_buffer[SP->c_gindex++]; + else if ((!SP->raw_inp && !SP->cbreak) && (SP->c_gindex < SP->c_pindex)) + key = SP->c_buffer[SP->c_gindex++]; + if( key != ERR) + { + if( key == KEY_RESIZE) + resize_term( 0, 0); + return( key); + } /* prepare to buffer data */ SP->c_pindex = 0; @@ -384,7 +466,7 @@ int wgetch(WINDOW *win) { /* is there a keystroke ready? */ - if (!PDC_check_key()) + while( !PDC_check_key()) { /* if not, handle timeout() and halfdelay() */ int nap_time = 50; @@ -398,7 +480,6 @@ int wgetch(WINDOW *win) remaining_millisecs -= nap_time; } napms( nap_time); - continue; /* then check again */ } /* if there is, fetch it */ @@ -407,26 +488,28 @@ int wgetch(WINDOW *win) /* copy or paste? */ +#ifndef _WIN32 if (SP->key_modifiers & PDC_KEY_MODIFIER_SHIFT) +#endif { - if (0x03 == key) + if (PDC_function_key[FUNCTION_KEY_COPY] == key) { _copy(); continue; } - else if (0x16 == key) + else if (PDC_function_key[FUNCTION_KEY_PASTE] == key) key = _paste(); } /* filter mouse events; translate mouse clicks in the slk area to function keys */ - if (SP->key_code && key == KEY_MOUSE) + if( key == KEY_MOUSE) key = _mouse_key(); /* filter special keys if not in keypad mode */ - if (SP->key_code && !win->_use_keypad) + if( key != KEY_RESIZE && PDC_is_function_key( key) && !win->_use_keypad) key = -1; /* unwanted key? loop back */ @@ -445,7 +528,7 @@ int wgetch(WINDOW *win) /* if echo is enabled */ - if (SP->echo && !SP->key_code) + if (SP->echo && !PDC_is_function_key( key)) { waddch(win, key); wrefresh(win); @@ -454,7 +537,11 @@ int wgetch(WINDOW *win) /* if no buffering */ if (SP->raw_inp || SP->cbreak) + { + if( key == KEY_RESIZE) + resize_term( 0, 0); return key; + } /* if no overflow, put data in buffer */ @@ -470,7 +557,11 @@ int wgetch(WINDOW *win) /* if we got a line */ if (key == '\n' || key == '\r') + { + if( SP->c_buffer[SP->c_gindex] == KEY_RESIZE) + resize_term( 0, 0); return SP->c_buffer[SP->c_gindex++]; + } } } @@ -529,7 +620,7 @@ unsigned long PDC_get_key_modifiers(void) assert( SP); if (!SP) - return ERR; + return (unsigned long)ERR; return SP->key_modifiers; } @@ -553,6 +644,7 @@ int wget_wch(WINDOW *win, wint_t *wch) PDC_LOG(("wget_wch() - called\n")); + assert( wch); if (!wch) return ERR; @@ -561,9 +653,9 @@ int wget_wch(WINDOW *win, wint_t *wch) if (key == ERR) return ERR; - *wch = key; + *wch = (wint_t)key; - return SP->key_code ? KEY_CODE_YES : OK; + return PDC_is_function_key( key) ? KEY_CODE_YES : OK; } int get_wch(wint_t *wch) diff --git a/src/3rdparty/win32_src/pdcurses/getstr.c b/src/3rdparty/win32_src/pdcurses/getstr.c index a021a9c11..768d731aa 100644 --- a/src/3rdparty/win32_src/pdcurses/getstr.c +++ b/src/3rdparty/win32_src/pdcurses/getstr.c @@ -37,7 +37,8 @@ getstr wgetch()'d values into a multibyte string in the current locale before returning it. The resulting string is placed in the area pointed to by *str. The routines with n as the last argument read at - most n characters. + most n characters. Note that this does not include the terminating + '\0' character; be sure your buffer has room for that. Note that there's no way to know how long the buffer passed to wgetstr() is, so use wgetnstr() to avoid buffer overflows. @@ -188,15 +189,12 @@ int wgetnstr(WINDOW *win, char *str, int n) break; default: - if (chars < n) + if (chars < n && ch < 0x100) { - if (!SP->key_code && ch < 0x100) - { - *p++ = (char)ch; - if (oldecho) - waddch(win, ch); - chars++; - } + *p++ = (char)ch; + if (oldecho) + waddch(win, ch); + chars++; } else beep(); @@ -280,6 +278,13 @@ int mvwgetnstr(WINDOW *win, int y, int x, char *str, int n) } #ifdef PDC_WIDE +static void _clear_preceding_char( WINDOW *win, const int ch) +{ + waddstr(win, "\b \b"); + if( PDC_wcwidth( (int32_t)ch) == 2 || ch < ' ') + waddstr(win, "\b \b"); /* fullwidth & ctrl chars take two columns */ +} + int wgetn_wstr(WINDOW *win, wint_t *wstr, int n) { int ch, i, num, x, chars; @@ -326,7 +331,7 @@ int wgetn_wstr(WINDOW *win, wint_t *wstr, int n) { if (oldecho) waddch(win, ch); - *p++ = ch; + *p++ = (wint_t)ch; ++chars; } else @@ -337,11 +342,9 @@ int wgetn_wstr(WINDOW *win, wint_t *wstr, int n) case _ECHAR: /* CTRL-H -- Delete character */ if (p > wstr) { - if (oldecho) - waddstr(win, "\b \b"); ch = *--p; - if ((ch < ' ') && (oldecho)) - waddstr(win, "\b \b"); + if (oldecho) + _clear_preceding_char( win, ch); chars--; } break; @@ -349,11 +352,9 @@ int wgetn_wstr(WINDOW *win, wint_t *wstr, int n) case _DLCHAR: /* CTRL-U -- Delete line */ while (p > wstr) { - if (oldecho) - waddstr(win, "\b \b"); ch = *--p; - if ((ch < ' ') && (oldecho)) - waddstr(win, "\b \b"); + if (oldecho) + _clear_preceding_char( win, ch); } chars = 0; break; @@ -362,20 +363,16 @@ int wgetn_wstr(WINDOW *win, wint_t *wstr, int n) while ((p > wstr) && (*(p - 1) == ' ')) { - if (oldecho) - waddstr(win, "\b \b"); - --p; /* remove space */ + if (oldecho) + _clear_preceding_char( win, *p); chars--; } while ((p > wstr) && (*(p - 1) != ' ')) { - if (oldecho) - waddstr(win, "\b \b"); - ch = *--p; - if ((ch < ' ') && (oldecho)) - waddstr(win, "\b \b"); + if (oldecho) + _clear_preceding_char( win, ch); chars--; } break; @@ -390,9 +387,9 @@ int wgetn_wstr(WINDOW *win, wint_t *wstr, int n) default: if (chars < n) { - if (!SP->key_code) + if( ch < KEY_MIN || ch >= KEY_MAX) { - *p++ = ch; + *p++ = (wint_t)ch; if (oldecho) waddch(win, ch); chars++; diff --git a/src/3rdparty/win32_src/pdcurses/getyx.c b/src/3rdparty/win32_src/pdcurses/getyx.c index 9400076e0..0f9b7c8cd 100644 --- a/src/3rdparty/win32_src/pdcurses/getyx.c +++ b/src/3rdparty/win32_src/pdcurses/getyx.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -76,6 +77,7 @@ int getbegy(WINDOW *win) { PDC_LOG(("getbegy() - called\n")); + assert( win); return win ? win->_begy : ERR; } @@ -83,6 +85,7 @@ int getbegx(WINDOW *win) { PDC_LOG(("getbegx() - called\n")); + assert( win); return win ? win->_begx : ERR; } @@ -90,6 +93,7 @@ int getcury(WINDOW *win) { PDC_LOG(("getcury() - called\n")); + assert( win); return win ? win->_cury : ERR; } @@ -97,6 +101,7 @@ int getcurx(WINDOW *win) { PDC_LOG(("getcurx() - called\n")); + assert( win); return win ? win->_curx : ERR; } @@ -104,6 +109,7 @@ int getpary(WINDOW *win) { PDC_LOG(("getpary() - called\n")); + assert( win); return win ? win->_pary : ERR; } @@ -111,6 +117,7 @@ int getparx(WINDOW *win) { PDC_LOG(("getparx() - called\n")); + assert( win); return win ? win->_parx : ERR; } @@ -118,6 +125,7 @@ int getmaxy(WINDOW *win) { PDC_LOG(("getmaxy() - called\n")); + assert( win); return win ? win->_maxy : ERR; } @@ -125,6 +133,7 @@ int getmaxx(WINDOW *win) { PDC_LOG(("getmaxx() - called\n")); + assert( win); return win ? win->_maxx : ERR; } diff --git a/src/3rdparty/win32_src/pdcurses/inch.c b/src/3rdparty/win32_src/pdcurses/inch.c index e3275a8c9..c5293bcd6 100644 --- a/src/3rdparty/win32_src/pdcurses/inch.c +++ b/src/3rdparty/win32_src/pdcurses/inch.c @@ -1,5 +1,6 @@ /* PDCurses */ +#include #include /*man-start************************************************************** @@ -47,6 +48,7 @@ chtype winch(WINDOW *win) { PDC_LOG(("winch() - called\n")); + assert( win); if (!win) return (chtype)ERR; @@ -85,6 +87,8 @@ int win_wch(WINDOW *win, cchar_t *wcval) { PDC_LOG(("win_wch() - called\n")); + assert( win); + assert( wcval); if (!win || !wcval) return ERR; @@ -104,6 +108,7 @@ int mvin_wch(int y, int x, cchar_t *wcval) { PDC_LOG(("mvin_wch() - called\n")); + assert( wcval); if (!wcval || (move(y, x) == ERR)) return ERR; @@ -116,6 +121,7 @@ int mvwin_wch(WINDOW *win, int y, int x, cchar_t *wcval) { PDC_LOG(("mvwin_wch() - called\n")); + assert( wcval); if (!wcval || (wmove(win, y, x) == ERR)) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/inchstr.c b/src/3rdparty/win32_src/pdcurses/inchstr.c index 97a00831e..671853950 100644 --- a/src/3rdparty/win32_src/pdcurses/inchstr.c +++ b/src/3rdparty/win32_src/pdcurses/inchstr.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -65,6 +66,8 @@ int winchnstr(WINDOW *win, chtype *ch, int n) PDC_LOG(("winchnstr() - called\n")); + assert( win); + assert( ch); if (!win || !ch || n < 0) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/initscr.c b/src/3rdparty/win32_src/pdcurses/initscr.c index fd71238f4..611665d48 100644 --- a/src/3rdparty/win32_src/pdcurses/initscr.c +++ b/src/3rdparty/win32_src/pdcurses/initscr.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include #include /*man-start************************************************************** @@ -17,6 +18,7 @@ initscr SCREEN *newterm(const char *type, FILE *outfd, FILE *infd); SCREEN *set_term(SCREEN *new); void delscreen(SCREEN *sp); + void PDC_free_memory_allocations( void); int resize_term(int nlines, int ncols); bool is_termresized(void); @@ -50,6 +52,15 @@ initscr needed. In PDCurses, the parameter must be the value of SP, and delscreen() sets SP to NULL. + PDC_free_memory_allocations() frees all memory allocated by PDCurses, + including SP and any platform-dependent memory. It should be called + after endwin(), not instead of it. It need not be called, because + remaining memory will be freed at exit; but it can help in diagnosing + memory leak issues by ruling out any from PDCurses. + + Note that SDLn and X11 have known memory leaks within their libraries, + which appear to be effectively unfixable. + set_term() does nothing meaningful in PDCurses, but is included for compatibility with other curses implementations. @@ -61,10 +72,9 @@ initscr and X11 allow user resizing, while DOS, OS/2, SDL and Windows console allow programmatic resizing. If you want to support user resizing, you should check for getch() returning KEY_RESIZE, and/or call - is_termresized() at appropriate times; if either condition occurs, - call resize_term(0, 0). Then, with either user or programmatic - resizing, you'll have to resize any windows you've created, as - appropriate; resize_term() only handles stdscr and curscr. + is_termresized() at appropriate times. Then, with either user or + programmatic resizing, you'll have to resize any windows you've + created, as appropriate; resize_term() only handles stdscr and curscr. is_termresized() returns TRUE if the curses screen has been resized by the user, and a call to resize_term() is needed. Checking for @@ -102,7 +112,38 @@ initscr char ttytype[128]; -const char *_curses_notice = "PDCurses " PDC_VERDOT " - " __DATE__; +#if PDC_VER_MONTH == 1 + #define PDC_VER_MONTH_STR "Jan" +#elif PDC_VER_MONTH == 2 + #define PDC_VER_MONTH_STR "Feb" +#elif PDC_VER_MONTH == 3 + #define PDC_VER_MONTH_STR "Mar" +#elif PDC_VER_MONTH == 4 + #define PDC_VER_MONTH_STR "Apr" +#elif PDC_VER_MONTH == 5 + #define PDC_VER_MONTH_STR "May" +#elif PDC_VER_MONTH == 6 + #define PDC_VER_MONTH_STR "Jun" +#elif PDC_VER_MONTH == 7 + #define PDC_VER_MONTH_STR "Jul" +#elif PDC_VER_MONTH == 8 + #define PDC_VER_MONTH_STR "Aug" +#elif PDC_VER_MONTH == 9 + #define PDC_VER_MONTH_STR "Sep" +#elif PDC_VER_MONTH == 10 + #define PDC_VER_MONTH_STR "Oct" +#elif PDC_VER_MONTH == 11 + #define PDC_VER_MONTH_STR "Nov" +#elif PDC_VER_MONTH == 12 + #define PDC_VER_MONTH_STR "Dec" +#else + #define PDC_VER_MONTH_STR "!!!" +#endif + +const char *_curses_notice = "PDCursesMod " PDC_VERDOT " - "\ + PDC_stringize( PDC_VER_YEAR) "-" \ + PDC_VER_MONTH_STR "-" \ + PDC_stringize( PDC_VER_DAY); SCREEN *SP = (SCREEN*)NULL; /* curses variables */ WINDOW *curscr = (WINDOW *)NULL; /* the current screen image */ @@ -240,7 +281,7 @@ WINDOW *initscr(void) def_shell_mode(); - sprintf(ttytype, "pdcurses|PDCurses for %s", PDC_sysname()); + longname( ); SP->c_buffer = malloc(_INBUFSIZ * sizeof(int)); if (!SP->c_buffer) @@ -269,6 +310,7 @@ WINDOW *Xinitscr(int argc, char **argv) int endwin(void) { + SP->in_endwin = TRUE; PDC_LOG(("endwin() - called\n")); /* Allow temporary exit from curses using endwin() */ @@ -279,6 +321,7 @@ int endwin(void) assert( SP); SP->alive = FALSE; + SP->in_endwin = FALSE; return OK; } @@ -286,13 +329,25 @@ bool isendwin(void) { PDC_LOG(("isendwin() - called\n")); + assert( SP); return SP ? !(SP->alive) : FALSE; } +void PDC_free_memory_allocations( void) +{ + PDC_free_platform_dependent_memory( ); + PDC_clearclipboard( ); + traceoff( ); + delscreen( SP); +} + SCREEN *newterm(const char *type, FILE *outfd, FILE *infd) { PDC_LOG(("newterm() - called\n")); + INTENTIONALLY_UNUSED_PARAMETER( type); + INTENTIONALLY_UNUSED_PARAMETER( outfd); + INTENTIONALLY_UNUSED_PARAMETER( infd); return initscr() ? SP : NULL; } @@ -305,6 +360,8 @@ SCREEN *set_term(SCREEN *new) return (new == SP) ? SP : NULL; } +void PDC_free_pair_hash_table( void); /* color.c */ + void delscreen(SCREEN *sp) { PDC_LOG(("delscreen() - called\n")); @@ -316,6 +373,7 @@ void delscreen(SCREEN *sp) free(SP->c_ungch); free(SP->c_buffer); free(SP->atrtab); + PDC_free_pair_hash_table(); PDC_slk_free(); /* free the soft label keys, if needed */ @@ -336,11 +394,16 @@ void delscreen(SCREEN *sp) int resize_term(int nlines, int ncols) { + PANEL *panel_ptr = NULL; + PDC_LOG(("resize_term() - called: nlines %d\n", nlines)); - if (!stdscr || PDC_resize_screen(nlines, ncols) == ERR) + if( PDC_resize_screen(nlines, ncols) == ERR) return ERR; + if( !stdscr) + return OK; + SP->resized = FALSE; SP->lines = PDC_get_rows(); @@ -374,6 +437,11 @@ int resize_term(int nlines, int ncols) touchwin(stdscr); wnoutrefresh(stdscr); + while( (panel_ptr = panel_above( panel_ptr)) != NULL) + { + touchwin(panel_window(panel_ptr)); + wnoutrefresh(panel_window(panel_ptr)); + } return OK; } @@ -393,6 +461,7 @@ void PDC_get_version(PDC_VERSION *ver) { extern enum PDC_port PDC_port_val; + assert( ver); if (!ver) return; diff --git a/src/3rdparty/win32_src/pdcurses/inopts.c b/src/3rdparty/win32_src/pdcurses/inopts.c index bba9c197a..5e924af47 100644 --- a/src/3rdparty/win32_src/pdcurses/inopts.c +++ b/src/3rdparty/win32_src/pdcurses/inopts.c @@ -29,6 +29,8 @@ inopts void timeout(int delay); void wtimeout(WINDOW *win, int delay); int typeahead(int fildes); + bool PDC_getcbreak(void); + bool PDC_getecho(void); int crmode(void); int nocrmode(void); @@ -48,6 +50,9 @@ inopts the input routine. Initially, input characters are echoed. Subsequent calls to echo() and noecho() do not flush type-ahead. + PDC_getcbreak() and PDC_getecho() return the current cbreak and echo + states. + halfdelay() is similar to cbreak(), but allows for a time limit to be specified, in tenths of a second. This causes getch() to block for that period before returning ERR if no key has been received. tenths @@ -104,6 +109,8 @@ inopts nocbreak Y Y Y echo Y Y Y noecho Y Y Y + PDC_getcbreak - - - + PDC_getecho - - - halfdelay Y Y Y intrflush Y Y Y keypad Y Y Y @@ -152,6 +159,14 @@ int nocbreak(void) return OK; } +bool PDC_getcbreak(void) +{ + PDC_LOG(("PDC_getcbreak() - called\n")); + + assert( SP); + return( SP->cbreak); +} + int echo(void) { PDC_LOG(("echo() - called\n")); @@ -178,6 +193,14 @@ int noecho(void) return OK; } +bool PDC_getecho(void) +{ + PDC_LOG(("PDC_getecho() - called\n")); + + assert( SP); + return( SP->echo); +} + int halfdelay(int tenths) { PDC_LOG(("halfdelay() - called\n")); @@ -195,6 +218,8 @@ int intrflush(WINDOW *win, bool bf) { PDC_LOG(("intrflush() - called\n")); + INTENTIONALLY_UNUSED_PARAMETER( win); + INTENTIONALLY_UNUSED_PARAMETER( bf); return OK; } @@ -202,6 +227,7 @@ int keypad(WINDOW *win, bool bf) { PDC_LOG(("keypad() - called\n")); + assert( win); if (!win) return ERR; @@ -214,6 +240,7 @@ int meta(WINDOW *win, bool bf) { PDC_LOG(("meta() - called\n")); + INTENTIONALLY_UNUSED_PARAMETER( win); assert( SP); if (!SP) return ERR; @@ -253,6 +280,7 @@ int nodelay(WINDOW *win, bool flag) { PDC_LOG(("nodelay() - called\n")); + assert( win); if (!win) return ERR; @@ -265,6 +293,8 @@ int notimeout(WINDOW *win, bool flag) { PDC_LOG(("notimeout() - called\n")); + INTENTIONALLY_UNUSED_PARAMETER( win); + INTENTIONALLY_UNUSED_PARAMETER( flag); return OK; } @@ -308,6 +338,7 @@ void qiflush(void) int typeahead(int fildes) { + INTENTIONALLY_UNUSED_PARAMETER( fildes); PDC_LOG(("typeahead() - called\n")); return OK; @@ -317,6 +348,7 @@ void wtimeout(WINDOW *win, int delay) { PDC_LOG(("wtimeout() - called\n")); + assert( win); if (!win) return; @@ -372,6 +404,7 @@ bool is_keypad(const WINDOW *win) { PDC_LOG(("is_keypad() - called\n")); + assert( win); if (!win) return FALSE; diff --git a/src/3rdparty/win32_src/pdcurses/insch.c b/src/3rdparty/win32_src/pdcurses/insch.c index 201506e8c..e3cf51ac6 100644 --- a/src/3rdparty/win32_src/pdcurses/insch.c +++ b/src/3rdparty/win32_src/pdcurses/insch.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -71,6 +72,7 @@ int winsch(WINDOW *win, chtype ch) PDC_LOG(("winsch() - called: win=%p ch=%x (text=%c attr=0x%x)\n", win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES)); + assert( win); if (!win) return ERR; @@ -154,10 +156,7 @@ int winsch(WINDOW *win, chtype ch) memmove(temp + 1, temp, (maxx - x - 1) * sizeof(chtype)); - win->_lastch[y] = maxx - 1; - - if ((win->_firstch[y] == _NO_CHANGE) || (win->_firstch[y] > x)) - win->_firstch[y] = x; + PDC_mark_cells_as_changed( win, y, x, maxx - 1); *temp = ch; } @@ -238,6 +237,8 @@ int wins_wch(WINDOW *win, const cchar_t *wch) { PDC_LOG(("wins_wch() - called\n")); + assert( win); + assert( wch); return wch ? winsch(win, *wch) : ERR; } diff --git a/src/3rdparty/win32_src/pdcurses/insstr.c b/src/3rdparty/win32_src/pdcurses/insstr.c index cd536bdbe..e35d850b5 100644 --- a/src/3rdparty/win32_src/pdcurses/insstr.c +++ b/src/3rdparty/win32_src/pdcurses/insstr.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -77,6 +78,8 @@ int winsnstr(WINDOW *win, const char *str, int n) PDC_LOG(("winsnstr() - called: string=\"%s\" n %d \n", str, n)); + assert( win); + assert( str); if (!win || !str) return ERR; @@ -92,7 +95,7 @@ int winsnstr(WINDOW *win, const char *str, int n) p = wstr; i = 0; - while (str[i] && i < n) + while( i < n && str[i]) { int retval = PDC_mbtowc(p, str + i, n - i); @@ -184,6 +187,8 @@ int wins_nwstr(WINDOW *win, const wchar_t *wstr, int n) PDC_LOG(("wins_nwstr() - called\n")); + assert( win); + assert( wstr); if (!win || !wstr) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/instr.c b/src/3rdparty/win32_src/pdcurses/instr.c index 718d2ae39..42194a9ac 100644 --- a/src/3rdparty/win32_src/pdcurses/instr.c +++ b/src/3rdparty/win32_src/pdcurses/instr.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -67,6 +68,8 @@ int winnstr(WINDOW *win, char *str, int n) #ifdef PDC_WIDE wchar_t wstr[513]; + assert( win); + assert( str); if (n < 0 || n > 512) n = 512; @@ -78,6 +81,8 @@ int winnstr(WINDOW *win, char *str, int n) chtype *src; int i; + assert( win); + assert( str); PDC_LOG(("winnstr() - called: n %d \n", n)); if (!win || !str) @@ -166,6 +171,8 @@ int winnwstr(WINDOW *win, wchar_t *wstr, int n) PDC_LOG(("winnstr() - called: n %d \n", n)); + assert( win); + assert( wstr); if (!win || !wstr) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/kernel.c b/src/3rdparty/win32_src/pdcurses/kernel.c index bb1d0bd43..5a2af19e3 100644 --- a/src/3rdparty/win32_src/pdcurses/kernel.c +++ b/src/3rdparty/win32_src/pdcurses/kernel.c @@ -115,7 +115,10 @@ static int _restore_mode(int i) { if (ctty[i].been_set == TRUE) { + void *atrtab = SP->atrtab; + memcpy(SP, &(ctty[i].saved), sizeof(SCREEN)); + SP->atrtab = atrtab; if (ctty[i].saved.raw_out) raw(); @@ -218,7 +221,9 @@ int curs_set(int visibility) PDC_LOG(("curs_set() - called: visibility=%d\n", visibility)); - if ((visibility < 0) || (visibility > 0x10000)) + assert( visibility >= 0); + assert( !(visibility & ~0xf0f)); + if ((visibility < 0) || (visibility & ~0xf0f)) return ERR; ret_vis = PDC_curs_set(visibility); @@ -268,6 +273,7 @@ int ripoffline(int line, int (*init)(WINDOW *, int)) { PDC_LOG(("ripoffline() - called: line=%d\n", line)); + assert( init); if (linesrippedoff < 5 && line && init) { linesripped[(int)linesrippedoff].line = line; diff --git a/src/3rdparty/win32_src/pdcurses/keyname.c b/src/3rdparty/win32_src/pdcurses/keyname.c index 3ba9d68f8..f81c83384 100644 --- a/src/3rdparty/win32_src/pdcurses/keyname.c +++ b/src/3rdparty/win32_src/pdcurses/keyname.c @@ -102,33 +102,17 @@ char *keyname(int key) "SHF_IC", "SHF_DC", "KEY_MOUSE", "KEY_SHIFT_L", "KEY_SHIFT_R", "KEY_CONTROL_L", "KEY_CONTROL_R", "KEY_ALT_L", "KEY_ALT_R", "KEY_RESIZE", "KEY_SUP", "KEY_SDOWN", - /* Win32a extras: */ - "CTL_SEMICOLON", "CTL_EQUAL", "CTL_COMMA", - "CTL_MINUS", "CTL_STOP", "CTL_FSLASH", - "CTL_BQUOTE", "KEY_APPS", "KEY_SAPPS", "CTL_APPS", - "ALT_APPS", "KEY_PAUSE", "KEY_SPAUSE", - "CTL_PAUSE", "KEY_PRINTSCREEN", "ALT_PRINTSCREEN", - "KEY_SCROLLLOCK", "ALT_SCROLLLOCK", - "CTL_0", "CTL_1", "CTL_2", "CTL_3", "CTL_4", - "CTL_5", "CTL_6", "CTL_7", "CTL_8", "CTL_9", - "BROWSER_BACK", "SBROWSER_BACK", "CBROWSER_BACK", "ABROWSER_BACK", - "BROWSER_FWD", "SBROWSER_FWD", "CBROWSER_FWD", "ABROWSER_FWD", - "BROWSER_REF", "SBROWSER_REF", "CBROWSER_REF", "ABROWSER_REF", - "BROWSER_STOP", "SBROWSER_STOP", "CBROWSER_STOP", "ABROWSER_STOP", - "SEARCH", "SSEARCH", "CSEARCH", "ASEARCH", - "FAVORITES", "SFAVORITES", "CFAVORITES", "AFAVORITES", - "BROWSER_HOME", "SBROWSER_HOME", "CBROWSER_HOME", "ABROWSER_HOME", - "VOLUME_MUTE", "SVOLUME_MUTE", "CVOLUME_MUTE", "AVOLUME_MUTE", - "VOLUME_DOWN", "SVOLUME_DOWN", "CVOLUME_DOWN", "AVOLUME_DOWN", - "VOLUME_UP", "SVOLUME_UP", "CVOLUME_UP", "AVOLUME_UP", - "NEXT_TRACK", "SNEXT_TRACK", "CNEXT_TRACK", "ANEXT_TRACK", - "PREV_TRACK", "SPREV_TRACK", "CPREV_TRACK", "APREV_TRACK", - "MEDIA_STOP", "SMEDIA_STOP", "CMEDIA_STOP", "AMEDIA_STOP", - "PLAY_PAUSE", "SPLAY_PAUSE", "CPLAY_PAUSE", "APLAY_PAUSE", - "LAUNCH_MAIL", "SLAUNCH_MAIL", "CLAUNCH_MAIL", "ALAUNCH_MAIL", - "MEDIA_SELECT", "SMEDIA_SELECT", "CMEDIA_SELECT", "AMEDIA_SELECT", - "LAUNCH_APP1", "SLAUNCH_APP1", "CLAUNCH_APP1", "ALAUNCH_APP1", - "LAUNCH_APP2", "SLAUNCH_APP2", "CLAUNCH_APP2", "ALAUNCH_APP2" }; + /* PDCursesMod additions: */ + "KEY_APPS", "KEY_PAUSE", + "KEY_PRINTSCREEN", "KEY_SCROLLLOCK", + "BROWSER_BACK", "BROWSER_FWD", "BROWSER_REF", "BROWSER_STOP", + "SEARCH", "FAVORITES", "BROWSER_HOME", + "VOLUME_MUTE", "VOLUME_DOWN", "VOLUME_UP", + "NEXT_TRACK", "PREV_TRACK", "MEDIA_STOP", "PLAY_PAUSE", + "LAUNCH_MAIL", "MEDIA_SELECT", + "LAUNCH_APP1", "LAUNCH_APP2", "LAUNCH_APP3", "LAUNCH_APP4", + "LAUNCH_APP5", "LAUNCH_APP6", "LAUNCH_APP7", "LAUNCH_APP8", + "LAUNCH_APP9", "LAUNCH_APP10" }; PDC_LOG(("keyname() - called: key %d\n", key)); diff --git a/src/3rdparty/win32_src/pdcurses/mouse.c b/src/3rdparty/win32_src/pdcurses/mouse.c index f14feff7e..ddc42d74b 100644 --- a/src/3rdparty/win32_src/pdcurses/mouse.c +++ b/src/3rdparty/win32_src/pdcurses/mouse.c @@ -241,6 +241,7 @@ bool wenclose(const WINDOW *win, int y, int x) { PDC_LOG(("wenclose() - called: %p %d %d\n", win, y, x)); + assert( win); return (win && y >= win->_begy && y < win->_begy + win->_maxy && x >= win->_begx && x < win->_begx + win->_maxx); } @@ -251,6 +252,9 @@ bool wmouse_trafo(const WINDOW *win, int *y, int *x, bool to_screen) PDC_LOG(("wmouse_trafo() - called\n")); + assert( win); + assert( x); + assert( y); if (!win || !y || !x) return FALSE; @@ -300,18 +304,18 @@ mmask_t mousemask(mmask_t mask, mmask_t *oldmask) if (oldmask) *oldmask = SP->_trap_mbe; - /* The ncurses interface doesn't work with our move events, so - filter them here */ + /* The ncurses interface doesn't work with our move events + when using 32-bit mmask_ts, so filter them here */ +#if !defined( PDC_LONG_MMASK) mask &= ~(BUTTON1_MOVED | BUTTON2_MOVED | BUTTON3_MOVED); +#endif mouse_set(mask); return SP->_trap_mbe; } -#define BITS_PER_BUTTON 5 - int nc_getmouse(MEVENT *event) { int i; @@ -338,7 +342,7 @@ int nc_getmouse(MEVENT *event) { if (Mouse_status.changes & (1 << i)) { - const int shf = i * BITS_PER_BUTTON; + const int shf = i * PDC_BITS_PER_BUTTON; const short button = Mouse_status.button[i] & BUTTON_ACTION_MASK; if (button == BUTTON_RELEASED) @@ -361,7 +365,7 @@ int nc_getmouse(MEVENT *event) /* 'Moves' (i.e., button is pressed) and 'position reports' */ /* (mouse moved with no button down) are all reported as */ /* 'position reports' in NCurses, which lacks 'move' events. */ - if( (MOUSE_MOVED || MOUSE_POS_REPORT) && (SP->_trap_mbe & REPORT_MOUSE_POSITION)) + if( MOUSE_MOVED && (SP->_trap_mbe & REPORT_MOUSE_POSITION)) bstate |= REPORT_MOUSE_POSITION; for( i = 0; i < 3; i++) @@ -388,6 +392,7 @@ int ungetmouse(MEVENT *event) PDC_LOG(("ungetmouse() - called\n")); + assert( event); if (!event || ungot) return ERR; @@ -401,7 +406,7 @@ int ungetmouse(MEVENT *event) for (i = 0; i < 3; i++) { - int shf = i * 5; + int shf = i * PDC_BITS_PER_BUTTON; short button = 0; if (bstate & ((BUTTON1_RELEASED | BUTTON1_PRESSED | diff --git a/src/3rdparty/win32_src/pdcurses/move.c b/src/3rdparty/win32_src/pdcurses/move.c index ed2cd743e..db2bc9512 100644 --- a/src/3rdparty/win32_src/pdcurses/move.c +++ b/src/3rdparty/win32_src/pdcurses/move.c @@ -56,6 +56,8 @@ int mvcur(int oldrow, int oldcol, int newrow, int newcol) oldrow, oldcol, newrow, newcol)); assert( SP); + INTENTIONALLY_UNUSED_PARAMETER( oldrow); + INTENTIONALLY_UNUSED_PARAMETER( oldcol); if (!SP || newrow < 0 || newrow >= LINES || newcol < 0 || newcol >= COLS) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/outopts.c b/src/3rdparty/win32_src/pdcurses/outopts.c index 37d3de978..5e4110f42 100644 --- a/src/3rdparty/win32_src/pdcurses/outopts.c +++ b/src/3rdparty/win32_src/pdcurses/outopts.c @@ -76,6 +76,7 @@ int clearok(WINDOW *win, bool bf) { PDC_LOG(("clearok() - called\n")); + assert( win); if (!win) return ERR; @@ -86,6 +87,8 @@ int clearok(WINDOW *win, bool bf) int idlok(WINDOW *win, bool bf) { + INTENTIONALLY_UNUSED_PARAMETER( win); + INTENTIONALLY_UNUSED_PARAMETER( bf); PDC_LOG(("idlok() - called\n")); return OK; @@ -93,6 +96,8 @@ int idlok(WINDOW *win, bool bf) void idcok(WINDOW *win, bool bf) { + INTENTIONALLY_UNUSED_PARAMETER( win); + INTENTIONALLY_UNUSED_PARAMETER( bf); PDC_LOG(("idcok() - called\n")); } @@ -108,6 +113,7 @@ int leaveok(WINDOW *win, bool bf) { PDC_LOG(("leaveok() - called\n")); + assert( win); if (!win) return ERR; @@ -129,6 +135,7 @@ int wsetscrreg(WINDOW *win, int top, int bottom) { PDC_LOG(("wsetscrreg() - called: top %d bottom %d\n", top, bottom)); + assert( win); if (win && 0 <= top && top <= win->_cury && win->_cury <= bottom && bottom < win->_maxy) { @@ -145,6 +152,7 @@ int scrollok(WINDOW *win, bool bf) { PDC_LOG(("scrollok() - called\n")); + assert( win); if (!win) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/overlay.c b/src/3rdparty/win32_src/pdcurses/overlay.c index 5bcc62745..92561386f 100644 --- a/src/3rdparty/win32_src/pdcurses/overlay.c +++ b/src/3rdparty/win32_src/pdcurses/overlay.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -53,24 +54,23 @@ static int _copy_win(const WINDOW *src_w, WINDOW *dst_w, int src_tr, int src_tc, int src_br, int src_bc, int dst_tr, int dst_tc, bool _overlay) { - int col, line, y1, fc, *minchng, *maxchng; + int col, line, y1, fc; chtype *w1ptr, *w2ptr; int lc = 0; int xdiff = src_bc - src_tc; int ydiff = src_br - src_tr; + assert( src_w); + assert( dst_w); + assert( dst_tr >= 0); if (!src_w || !dst_w) return ERR; - minchng = dst_w->_firstch; - maxchng = dst_w->_lastch; - - for (y1 = 0; y1 < dst_tr; y1++) - { - minchng++; - maxchng++; - } + if( dst_tr < 0) + y1 = 0; + else + y1 = dst_tr; for (line = 0; line < ydiff; line++) { @@ -96,21 +96,7 @@ static int _copy_win(const WINDOW *src_w, WINDOW *dst_w, int src_tr, w2ptr++; } - if (*minchng == _NO_CHANGE) - { - *minchng = fc; - *maxchng = lc; - } - else if (fc != _NO_CHANGE) - { - if (fc < *minchng) - *minchng = fc; - if (lc > *maxchng) - *maxchng = lc; - } - - minchng++; - maxchng++; + PDC_mark_cells_as_changed( dst_w, y1 + line, fc, lc); } return OK; @@ -122,6 +108,8 @@ int _copy_overlap(const WINDOW *src_w, WINDOW *dst_w, bool overlay) int src_start_x, src_start_y, dst_start_x, dst_start_y; int xdiff, ydiff; + assert( src_w); + assert( dst_w); if (!src_w || !dst_w) return ERR; @@ -194,6 +182,8 @@ int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr, int src_tc, PDC_LOG(("copywin() - called\n")); + assert( src_w); + assert( dst_w); if (!src_w || !dst_w || dst_w == curscr || dst_br >= dst_w->_maxy || dst_bc >= dst_w->_maxx || dst_tr < 0 || dst_tc < 0) return ERR; @@ -210,5 +200,5 @@ int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr, int src_tc, src_end_x = src_tc + min_cols; return _copy_win(src_w, dst_w, src_tr, src_tc, src_end_y, src_end_x, - dst_tr, dst_tc, _overlay); + dst_tr, dst_tc, (bool)_overlay); } diff --git a/src/3rdparty/win32_src/pdcurses/pad.c b/src/3rdparty/win32_src/pdcurses/pad.c index 0b1d6147c..c1c04e6c9 100644 --- a/src/3rdparty/win32_src/pdcurses/pad.c +++ b/src/3rdparty/win32_src/pdcurses/pad.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -77,9 +78,6 @@ pad /* save values for pechochar() */ -static int save_pminrow, save_pmincol; -static int save_sminrow, save_smincol, save_smaxrow, save_smaxcol; - WINDOW *newpad(int nlines, int ncols) { WINDOW *win; @@ -100,12 +98,12 @@ WINDOW *newpad(int nlines, int ncols) /* save default values in case pechochar() is the first call to prefresh(). */ - save_pminrow = 0; - save_pmincol = 0; - save_sminrow = 0; - save_smincol = 0; - save_smaxrow = min(LINES, nlines) - 1; - save_smaxcol = min(COLS, ncols) - 1; + win->_pminrow = 0; + win->_pmincol = 0; + win->_sminrow = 0; + win->_smincol = 0; + win->_smaxrow = min(LINES, nlines) - 1; + win->_smaxcol = min(COLS, ncols) - 1; return win; } @@ -118,6 +116,7 @@ WINDOW *subpad(WINDOW *orig, int nlines, int ncols, int begy, int begx) PDC_LOG(("subpad() - called: lines=%d cols=%d begy=%d begx=%d\n", nlines, ncols, begy, begx)); + assert( orig); if (!orig || !(orig->_flags & _PAD)) return (WINDOW *)NULL; @@ -155,12 +154,12 @@ WINDOW *subpad(WINDOW *orig, int nlines, int ncols, int begy, int begx) /* save default values in case pechochar() is the first call to prefresh(). */ - save_pminrow = 0; - save_pmincol = 0; - save_sminrow = 0; - save_smincol = 0; - save_smaxrow = min(LINES, nlines) - 1; - save_smaxcol = min(COLS, ncols) - 1; + win->_pminrow = 0; + win->_pmincol = 0; + win->_sminrow = 0; + win->_smincol = 0; + win->_smaxrow = min(LINES, nlines) - 1; + win->_smaxcol = min(COLS, ncols) - 1; return win; } @@ -179,13 +178,12 @@ int prefresh(WINDOW *win, int py, int px, int sy1, int sx1, int sy2, int sx2) int pnoutrefresh(WINDOW *w, int py, int px, int sy1, int sx1, int sy2, int sx2) { int num_cols; - int sline = sy1; - int pline = py; + int sline; + int pline; PDC_LOG(("pnoutrefresh() - called\n")); - if (!w || !(w->_flags & (_PAD|_SUBPAD)) || (sy2 >= LINES) || (sx2 >= COLS)) - return ERR; + assert( w); if (py < 0) py = 0; @@ -196,9 +194,14 @@ int pnoutrefresh(WINDOW *w, int py, int px, int sy1, int sx1, int sy2, int sx2) if (sx1 < 0) sx1 = 0; - if (sy2 < sy1 || sx2 < sx1) + if ((!w || !(w->_flags & (_PAD|_SUBPAD)) || + (sy2 >= LINES) || (sx2 >= COLS)) || + (sy2 < sy1) || (sx2 < sx1)) return ERR; + sline = sy1; + pline = py; + num_cols = min((sx2 - sx1 + 1), (w->_maxx - px)); while (sline <= sy2) @@ -208,15 +211,8 @@ int pnoutrefresh(WINDOW *w, int py, int px, int sy1, int sx1, int sy2, int sx2) memcpy(curscr->_y[sline] + sx1, w->_y[pline] + px, num_cols * sizeof(chtype)); - if ((curscr->_firstch[sline] == _NO_CHANGE) - || (curscr->_firstch[sline] > sx1)) - curscr->_firstch[sline] = sx1; - - if (sx2 > curscr->_lastch[sline]) - curscr->_lastch[sline] = sx2; - - w->_firstch[pline] = _NO_CHANGE; /* updated now */ - w->_lastch[pline] = _NO_CHANGE; /* updated now */ + PDC_mark_cells_as_changed( curscr, sline, sx1, sx2); + PDC_set_changed_cells_range( w, pline, _NO_CHANGE, _NO_CHANGE); } sline++; @@ -240,30 +236,51 @@ int pnoutrefresh(WINDOW *w, int py, int px, int sy1, int sx1, int sy2, int sx2) curscr->_curx = (w->_curx - px) + sx1; } + w->_pminrow = py; + w->_pmincol = px; + w->_sminrow = sy1; + w->_smincol = sx1; + w->_smaxrow = sy2; + w->_smaxcol = sx2; return OK; } +int PDC_pnoutrefresh_with_stored_params( WINDOW *pad) +{ + return prefresh(pad, pad->_pminrow, pad->_pmincol, pad->_sminrow, + pad->_smincol, pad->_smaxrow, pad->_smaxcol); +} + int pechochar(WINDOW *pad, chtype ch) { + int rval; + PDC_LOG(("pechochar() - called\n")); if (waddch(pad, ch) == ERR) return ERR; - return prefresh(pad, save_pminrow, save_pmincol, save_sminrow, - save_smincol, save_smaxrow, save_smaxcol); + rval = PDC_pnoutrefresh_with_stored_params( pad); + if( rval == OK) + doupdate( ); + return( rval); } #ifdef PDC_WIDE int pecho_wchar(WINDOW *pad, const cchar_t *wch) { + int rval; + PDC_LOG(("pecho_wchar() - called\n")); + assert( wch); if (!wch || (waddch(pad, *wch) == ERR)) return ERR; - return prefresh(pad, save_pminrow, save_pmincol, save_sminrow, - save_smincol, save_smaxrow, save_smaxcol); + rval = PDC_pnoutrefresh_with_stored_params( pad); + if( rval == OK) + doupdate( ); + return( rval); } #endif @@ -271,6 +288,7 @@ bool is_pad(const WINDOW *pad) { PDC_LOG(("is_pad() - called\n")); + assert( pad); if (!pad) return FALSE; diff --git a/src/3rdparty/win32_src/pdcurses/panel.c b/src/3rdparty/win32_src/pdcurses/panel.c index b3c48fcc1..15ddba5c3 100644 --- a/src/3rdparty/win32_src/pdcurses/panel.c +++ b/src/3rdparty/win32_src/pdcurses/panel.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -16,6 +17,8 @@ panel PANEL *new_panel(WINDOW *win); PANEL *panel_above(const PANEL *pan); PANEL *panel_below(const PANEL *pan); + PANEL *ground_panel(SCREEN *sp); + PANEL *ceiling_panel(SCREEN *sp); int panel_hidden(const PANEL *pan); const void *panel_userptr(const PANEL *pan); WINDOW *panel_window(const PANEL *pan); @@ -64,6 +67,10 @@ panel or NULL if pan is the bottom panel. If the value of pan passed is NULL, this function returns a pointer to the top panel in the deck. + ground_panel() returns a pointer to the bottom panel in the deck. + + ceiling_panel() returns a pointer to the top panel in the deck. + panel_hidden() returns OK if pan is hidden and ERR if it is not. panel_userptr() - Each panel has a user pointer available for @@ -104,6 +111,8 @@ panel new_panel - Y Y panel_above - Y Y panel_below - Y Y + ground_panel - Y N + ceiling_panel - Y N panel_hidden - Y Y panel_userptr - Y Y panel_window - Y Y @@ -123,7 +132,7 @@ panel PANEL *_bottom_panel = (PANEL *)0; PANEL *_top_panel = (PANEL *)0; -PANEL _stdscr_pseudo_panel = { (WINDOW *)0 }; +PANEL _stdscr_pseudo_panel; #ifdef PANEL_DEBUG @@ -190,6 +199,8 @@ static void Touchline(PANEL *pan, int start, int count) static bool _panels_overlapped(PANEL *pan1, PANEL *pan2) { + assert( pan1); + assert( pan2); if (!pan1 || !pan2) return FALSE; @@ -404,6 +415,7 @@ static void _panel_unlink(PANEL *pan) int bottom_panel(PANEL *pan) { + assert( pan); if (!pan) return ERR; @@ -420,6 +432,7 @@ int bottom_panel(PANEL *pan) int del_panel(PANEL *pan) { + assert( pan); if (pan) { if (_panel_is_linked(pan)) @@ -434,6 +447,7 @@ int del_panel(PANEL *pan) int hide_panel(PANEL *pan) { + assert( pan); if (!pan) return ERR; @@ -452,8 +466,9 @@ int hide_panel(PANEL *pan) int move_panel(PANEL *pan, int starty, int startx) { WINDOW *win; - int maxy, maxx; + int maxy, maxx, rval; + assert( pan); if (!pan) return ERR; @@ -462,24 +477,26 @@ int move_panel(PANEL *pan, int starty, int startx) win = pan->win; - if (mvwin(win, starty, startx) == ERR) - return ERR; - - getbegyx(win, pan->wstarty, pan->wstartx); - getmaxyx(win, maxy, maxx); - pan->wendy = pan->wstarty + maxy; - pan->wendx = pan->wstartx + maxx; + rval = mvwin(win, starty, startx); + if( rval != ERR) + { + getbegyx(win, pan->wstarty, pan->wstartx); + getmaxyx(win, maxy, maxx); + pan->wendy = pan->wstarty + maxy; + pan->wendx = pan->wstartx + maxx; + } if (_panel_is_linked(pan)) _calculate_obscure(); - return OK; + return rval; } PANEL *new_panel(WINDOW *win) { PANEL *pan; + assert( win); if (!win) return (PANEL *)NULL; @@ -529,8 +546,21 @@ PANEL *panel_below(const PANEL *pan) return pan ? pan->below : _top_panel; } +PANEL *ceiling_panel( SCREEN *sp) +{ + INTENTIONALLY_UNUSED_PARAMETER( sp); + return( panel_below( NULL)); +} + +PANEL *ground_panel( SCREEN *sp) +{ + INTENTIONALLY_UNUSED_PARAMETER( sp); + return( panel_above( NULL)); +} + int panel_hidden(const PANEL *pan) { + assert( pan); if (!pan) return ERR; @@ -539,6 +569,7 @@ int panel_hidden(const PANEL *pan) const void *panel_userptr(const PANEL *pan) { + assert( pan); return pan ? pan->user : NULL; } @@ -546,6 +577,7 @@ WINDOW *panel_window(const PANEL *pan) { PDC_LOG(("panel_window() - called\n")); + assert( pan); if (!pan) return (WINDOW *)NULL; @@ -556,6 +588,8 @@ int replace_panel(PANEL *pan, WINDOW *win) { int maxy, maxx; + assert( pan); + assert( win); if (!pan) return ERR; @@ -576,6 +610,7 @@ int replace_panel(PANEL *pan, WINDOW *win) int set_panel_userptr(PANEL *pan, const void *uptr) { + assert( pan); if (!pan) return ERR; @@ -585,6 +620,7 @@ int set_panel_userptr(PANEL *pan, const void *uptr) int show_panel(PANEL *pan) { + assert( pan); if (!pan) return ERR; @@ -601,6 +637,7 @@ int show_panel(PANEL *pan) int top_panel(PANEL *pan) { + assert( pan); return show_panel(pan); } diff --git a/src/3rdparty/win32_src/pdcurses/pdcclip.c b/src/3rdparty/win32_src/pdcurses/pdcclip.c new file mode 100644 index 000000000..dff4d56dc --- /dev/null +++ b/src/3rdparty/win32_src/pdcurses/pdcclip.c @@ -0,0 +1,135 @@ +/* PDCurses */ + +#include +#include + +#include + +/*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****************************************************************/ + +/* This version is used (at present) in the VT, framebuffer, DOS, +and DOSVGA ports, and could be used for the Plan9 one as well. These +platforms lack system clipboards, so we just store the clipboard text +in a malloced buffer. */ + +/* global clipboard contents, should be NULL if none set */ + +static char *pdc_clipboard = NULL; + +int PDC_getclipboard(char **contents, long *length) +{ + int len; + + PDC_LOG(("PDC_getclipboard() - called\n")); + + if (!pdc_clipboard) + return PDC_CLIP_EMPTY; + + len = (int)strlen(pdc_clipboard); + *contents = malloc(len + 1); + if (!*contents) + return PDC_CLIP_MEMORY_ERROR; + + strcpy(*contents, pdc_clipboard); + *length = len; + + return PDC_CLIP_SUCCESS; +} + +int PDC_setclipboard(const char *contents, long length) +{ + PDC_LOG(("PDC_setclipboard() - called\n")); + + PDC_clearclipboard( ); + + if (contents) + { + pdc_clipboard = malloc(length + 1); + if (!pdc_clipboard) + return PDC_CLIP_MEMORY_ERROR; + + strcpy(pdc_clipboard, contents); + } + + return PDC_CLIP_SUCCESS; +} + +int PDC_freeclipboard(char *contents) +{ + PDC_LOG(("PDC_freeclipboard() - called\n")); + + /* should we also free empty the system clipboard? probably not */ + + if (contents) + { + /* NOTE: We free the memory, but we can not set caller's pointer + to NULL, so if caller calls again then will try to access + free'd memory. We 1st overwrite memory with a string so if + caller tries to use free memory they won't get what they + expect & hopefully notice. */ + const char *refreed = "!Freed buffer PDC clipboard!"; + const char *tptr = refreed; + char *tptr2 = contents; + + while( *tptr2 && *tptr) + *tptr2++ = *tptr++; + + free(contents); + } + + return PDC_CLIP_SUCCESS; +} + +int PDC_clearclipboard(void) +{ + PDC_LOG(("PDC_clearclipboard() - called\n")); + + if (pdc_clipboard) + { + free(pdc_clipboard); + pdc_clipboard = NULL; + } + + return PDC_CLIP_SUCCESS; +} diff --git a/src/3rdparty/win32_src/pdcurses/pdccolor.c b/src/3rdparty/win32_src/pdcurses/pdccolor.c index 81feda332..60fa49659 100644 --- a/src/3rdparty/win32_src/pdcurses/pdccolor.c +++ b/src/3rdparty/win32_src/pdcurses/pdccolor.c @@ -1,9 +1,10 @@ /* PDCurses */ -/* Palette management code used by VT and WinGUI for 'full color' -(24-bit). It will be used eventually by X11, SDL1/2, and DOSVGA, -all of which are full-color capable. See 'pdccolor.txt' for a -rationale of how this works. */ +/* Palette management code used by VT, WinGUI, SDL1/2, and X11 for +'full color' (24-bit). It may eventually be used by DOSVGA, WinCon, +and/or the Plan9 platform, all of which have full color capability. +It will presumably never be useful for the DOS or OS/2 platforms. +See 'pdccolor.txt' for a rationale of how this works. */ #ifdef NO_STDINT_H #define uint64_t unsigned long long @@ -18,7 +19,7 @@ rationale of how this works. */ #define PACKED_RGB uint32_t #ifndef PACK_RGB - #define PACK_RGB( red, green, blue) ((red) | ((green)<<8) | ((blue) << 16)) + #define PACK_RGB( red, green, blue) ((red) | ((green)<<8) | ((PACKED_RGB)(blue) << 16)) #endif #include @@ -36,11 +37,16 @@ PACKED_RGB PDC_default_color( int idx) assert( idx >= 0); if( idx < 16) { - const int intensity = ((idx & 8) ? 0xff : 0xc0); + if( idx == 8) + rval = PACK_RGB( 0x80, 0x80, 0x80); + else + { + const int intensity = ((idx & 8) ? 0xff : 0xc0); - rval = PACK_RGB( ((idx & COLOR_RED) ? intensity : 0), - ((idx & COLOR_GREEN) ? intensity : 0), - ((idx & COLOR_BLUE) ? intensity : 0)); + rval = PACK_RGB( ((idx & COLOR_RED) ? intensity : 0), + ((idx & COLOR_GREEN) ? intensity : 0), + ((idx & COLOR_BLUE) ? intensity : 0)); + } } else if( idx < 216 + 16) { /* colors 16-231 are a 6x6x6 color cube */ @@ -82,7 +88,10 @@ PACKED_RGB PDC_get_palette_entry( const int idx) PACKED_RGB rval; if( idx < palette_size) + { + assert( idx >= 0); rval = rgbs[idx]; + } else rval = PDC_default_color( idx); return( rval); @@ -117,13 +126,6 @@ int PDC_set_palette_entry( const int idx, const PACKED_RGB rgb) return( rval); } -static bool intensify_enabled = TRUE; - -PDCEX void PDC_set_color_intensify_enabled( bool enabled) -{ - intensify_enabled = enabled; -} - /* This function 'intensifies' a color by shifting it toward white. */ /* It used to average the input color with white. Then it did a */ /* weighted average: 2/3 of the input color, 1/3 white, for a */ @@ -138,11 +140,6 @@ PDCEX void PDC_set_color_intensify_enabled( bool enabled) static PACKED_RGB intensified_color( PACKED_RGB ival) { - if ( !intensify_enabled) - { - return ival; - } - int rgb, i; PACKED_RGB oval = 0; @@ -184,20 +181,17 @@ void PDC_get_rgb_values( const chtype srcp, bool reverse_colors = ((srcp & A_REVERSE) ? TRUE : FALSE); bool intensify_backgnd = FALSE; bool default_foreground = FALSE, default_background = FALSE; + int foreground_index, background_index; - { - int foreground_index, background_index; - - extended_pair_content( color, &foreground_index, &background_index); - if( foreground_index < 0 && SP->orig_attr) - default_foreground = TRUE; - else - *foreground_rgb = PDC_get_palette_entry( foreground_index); - if( background_index < 0 && SP->orig_attr) - default_background = TRUE; - else - *background_rgb = PDC_get_palette_entry( background_index); - } + extended_pair_content( color, &foreground_index, &background_index); + if( foreground_index < 0 && SP->orig_attr) + default_foreground = TRUE; + else + *foreground_rgb = PDC_get_palette_entry( foreground_index); + if( background_index < 0 && SP->orig_attr) + default_background = TRUE; + else + *background_rgb = PDC_get_palette_entry( background_index); if( srcp & A_BLINK) { @@ -206,6 +200,22 @@ void PDC_get_rgb_values( const chtype srcp, else if( PDC_blink_state) reverse_colors ^= 1; } + if( default_foreground) + *foreground_rgb = (PACKED_RGB)-1; + else if( srcp & A_BOLD & ~SP->termattrs) + *foreground_rgb = intensified_color( *foreground_rgb); + + if( default_background) + *background_rgb = (PACKED_RGB)-1; + else if( intensify_backgnd) + *background_rgb = intensified_color( *background_rgb); + if( srcp & A_DIM) + { + if( !default_foreground) + *foreground_rgb = dimmed_color( *foreground_rgb); + if( !default_background) + *background_rgb = dimmed_color( *background_rgb); + } if( reverse_colors) { const PACKED_RGB temp = *foreground_rgb; @@ -213,18 +223,4 @@ void PDC_get_rgb_values( const chtype srcp, *foreground_rgb = *background_rgb; *background_rgb = temp; } - - if( srcp & A_BOLD & ~SP->termattrs) - *foreground_rgb = intensified_color( *foreground_rgb); - if( intensify_backgnd) - *background_rgb = intensified_color( *background_rgb); - if( srcp & A_DIM) - { - *foreground_rgb = dimmed_color( *foreground_rgb); - *background_rgb = dimmed_color( *background_rgb); - } - if( default_foreground) - *foreground_rgb = (PACKED_RGB)-1; - if( default_background) - *background_rgb = (PACKED_RGB)-1; } diff --git a/src/3rdparty/win32_src/pdcurses/pdccolor.h b/src/3rdparty/win32_src/pdcurses/pdccolor.h index b4cd7d32e..97212805c 100644 --- a/src/3rdparty/win32_src/pdcurses/pdccolor.h +++ b/src/3rdparty/win32_src/pdcurses/pdccolor.h @@ -5,6 +5,10 @@ extern int PDC_blink_state; typedef uint32_t PACKED_RGB; +#define Get_BValue( rgb) ((int)( (rgb) >> 16)) +#define Get_GValue( rgb) ((int)( (rgb) >> 8) & 0xff) +#define Get_RValue( rgb) ((int)((rgb) & 0xff)) + int PDC_init_palette( void); void PDC_get_rgb_values( const chtype srcp, PACKED_RGB *foreground_rgb, PACKED_RGB *background_rgb); diff --git a/src/3rdparty/win32_src/pdcurses/refresh.c b/src/3rdparty/win32_src/pdcurses/refresh.c index d00d1851d..07640e687 100644 --- a/src/3rdparty/win32_src/pdcurses/refresh.c +++ b/src/3rdparty/win32_src/pdcurses/refresh.c @@ -58,6 +58,20 @@ refresh #include +static void _normalize_cursor( WINDOW *win) +{ + if( win->_cury < 0) + win->_cury = 0; + if( win->_cury >= win->_maxy) + win->_cury = win->_maxy - 1; + if( win->_curx < 0) + win->_curx = 0; + if( win->_curx >= win->_maxx) + win->_curx = win->_maxx - 1; +} + +int PDC_pnoutrefresh_with_stored_params( WINDOW *pad); /* pad.c */ + int wnoutrefresh(WINDOW *win) { int begy, begx; /* window's place on screen */ @@ -65,15 +79,18 @@ int wnoutrefresh(WINDOW *win) PDC_LOG(("wnoutrefresh() - called: win=%p\n", win)); - if ( !win || (win->_flags & (_PAD|_SUBPAD)) ) + assert( win); + if ( !win) return ERR; + if( is_pad( win)) + return PDC_pnoutrefresh_with_stored_params( win); begy = win->_begy; begx = win->_begx; - for (i = 0, j = begy; i < win->_maxy; i++, j++) + for (i = 0, j = begy; i < win->_maxy && j < curscr->_maxy; i++, j++) { - if (win->_firstch[i] != _NO_CHANGE) + if (win->_firstch[i] != _NO_CHANGE && j >= 0) { chtype *src = win->_y[i]; chtype *dest = curscr->_y[j] + begx; @@ -81,6 +98,11 @@ int wnoutrefresh(WINDOW *win) int first = win->_firstch[i]; /* first changed */ int last = win->_lastch[i]; /* last changed */ + if( last > curscr->_maxx - begx - 1) /* don't run off right-hand */ + last = curscr->_maxx - begx - 1; /* edge of screen */ + if( first < -begx) /* ...nor the left edge */ + first = -begx; + /* ignore areas on the outside that are marked as changed, but really aren't */ @@ -107,11 +129,8 @@ int wnoutrefresh(WINDOW *win) if (last > curscr->_lastch[j]) curscr->_lastch[j] = last; } - - win->_firstch[i] = _NO_CHANGE; /* updated now */ } - - win->_lastch[i] = _NO_CHANGE; /* updated now */ + PDC_set_changed_cells_range( win, i, _NO_CHANGE, _NO_CHANGE); } if (win->_clear) @@ -121,6 +140,7 @@ int wnoutrefresh(WINDOW *win) { curscr->_cury = win->_cury + begy; curscr->_curx = win->_curx + begx; + _normalize_cursor( curscr); } return OK; @@ -205,8 +225,7 @@ int doupdate(void) first++; } - curscr->_firstch[y] = _NO_CHANGE; - curscr->_lastch[y] = _NO_CHANGE; + PDC_set_changed_cells_range( curscr, y, _NO_CHANGE, _NO_CHANGE); } } @@ -229,6 +248,7 @@ int wrefresh(WINDOW *win) PDC_LOG(("wrefresh() - called\n")); + assert( win); if ( !win || (win->_flags & (_PAD|_SUBPAD)) ) return ERR; @@ -259,14 +279,12 @@ int wredrawln(WINDOW *win, int start, int num) PDC_LOG(("wredrawln() - called: win=%p start=%d num=%d\n", win, start, num)); + assert( win); if (!win || start > win->_maxy || start + num > win->_maxy) return ERR; for (i = start; i < start + num; i++) - { - win->_firstch[i] = 0; - win->_lastch[i] = win->_maxx - 1; - } + PDC_mark_line_as_changed( win, i); return OK; } @@ -275,6 +293,7 @@ int redrawwin(WINDOW *win) { PDC_LOG(("redrawwin() - called: win=%p\n", win)); + assert( win); if (!win) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/scr_dump.c b/src/3rdparty/win32_src/pdcurses/scr_dump.c index d9105bda9..d7fac2c2c 100644 --- a/src/3rdparty/win32_src/pdcurses/scr_dump.c +++ b/src/3rdparty/win32_src/pdcurses/scr_dump.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -60,87 +61,161 @@ scr_dump #include #include -#define DUMPVER 1 /* Should be updated whenever the WINDOW struct is +#define DUMPVER 2 /* Should be updated whenever the WINDOW struct is changed */ +static void _stuff_chtype_into_eight_bytes( char *buff, const chtype c) +{ + uint64_t x; + const chtype text = c & A_CHARTEXT; + const chtype color_pair = PAIR_NUMBER( c); + const chtype attribs = (c >> PDC_CHARTEXT_BITS) & (((chtype)1 << PDC_ATTRIBUTE_BITS) - 1); + + x = (uint64_t)text | ((uint64_t)attribs << 21) | ((uint64_t)color_pair << 33); + memcpy( buff, &x, 8); + /* Should reverse these eight bytes on big-Endian machines */ +} + +static chtype _get_chtype_from_eight_bytes( const char *buff) +{ + uint64_t c, x, text, color_pair, attribs; + + /* Should reverse these eight bytes on big-Endian machines */ + memcpy( &x, buff, 8); + text = x & 0x1ffff; + attribs = (x >> 21) & 0xfff; + color_pair = (x >> 33) & 0xfffff; + c = text | (attribs << PDC_CHARTEXT_BITS) | COLOR_PAIR( color_pair); + return( (chtype)c); +} + +/* In PDCursesMod 4.3.3 and earlier, the on-disk representation of a +window was entirely binary. A WINDOW struct was written out, and the +window's chtype data was written out. Portability of these files was +nearly zero. Alignment and structure packing differences, differences +in the sizes of ints, bools, and pointers, 32-bit vs. 64-bit +chtypes and endianness would usually ensure that a file written by one +program couldn't be read by another. + +Adding grief to this is the fact that the window structure changed in +4.3.1. Files written with 4.3.0 and earlier could not be read in +4.3.1 and later. + +The window structure is now written out in ASCII, which should help +with cross-compiler and cross-OS compatibility. chtypes are expanded +to the 64-bit form on writing and compacted back upon reading. You +will get scrambled colors and/or attributes if you make a file with +one program that uses attributes or color pairs beyond the reach of +the program reading the file. Error checks for this may be added. */ + +static const char *_format_nine_ints = "%d %d %d %d %d %d %d %d %d\n"; +static const char *_format_three_ints = "%d %d %d\n"; + int putwin(WINDOW *win, FILE *filep) { - static const char *marker = "PDC"; - static const unsigned char version = DUMPVER; + char buff[16]; + int y, x; PDC_LOG(("putwin() - called\n")); + assert( filep); /* write the marker and the WINDOW struct */ - if (filep && fwrite(marker, strlen(marker), 1, filep) - && fwrite(&version, 1, 1, filep) - && fwrite(win, sizeof(WINDOW), 1, filep)) - { - int i; + if( !filep || !fprintf( filep, "%s\n", curses_version( ))) + return( ERR); - /* write each line */ + if( !fprintf( filep, _format_nine_ints, + DUMPVER, (int)sizeof( WINDOW), win->_cury, win->_curx, + win->_maxy, win->_maxx, win->_begy, win->_begx, win->_flags)) + return( ERR); - for (i = 0; i < win->_maxy && win->_y[i]; i++) - if (!fwrite(win->_y[i], win->_maxx * sizeof(chtype), 1, filep)) + if( !fprintf( filep, _format_nine_ints, + win->_clear, win->_leaveit, win->_scroll, win->_nodelay, + win->_immed, win->_sync, win->_use_keypad, win->_tmarg, win->_bmarg)) + return( ERR); + + if( !fprintf( filep, _format_three_ints, + win->_delayms, win->_parx, win->_pary)) + return( ERR); + + _stuff_chtype_into_eight_bytes( buff, win->_attrs); + _stuff_chtype_into_eight_bytes( buff + 8, win->_bkgd); + if( !fwrite(buff, 16, 1, filep)) + return ERR; + + for( y = 0; y < win->_maxy && win->_y[y]; y++) + for( x = 0; x < win->_maxx; x++) + { + _stuff_chtype_into_eight_bytes( buff, win->_y[y][x]); + if( !fwrite(buff, 8, 1, filep)) return ERR; - - return OK; - } - - return ERR; + } + return OK; } WINDOW *getwin(FILE *filep) { - WINDOW *win; - char marker[4]; - int i, nlines, ncols; + WINDOW *win, temp_win; + char buff[80]; + int nlines, y; + int _clear, _leaveit, _scroll, _nodelay, _immed, _sync, _use_keypad; + int version, window_size; + bool failure = FALSE; PDC_LOG(("getwin() - called\n")); - win = malloc(sizeof(WINDOW)); + assert( filep); + memset( &temp_win, 0, sizeof( WINDOW)); + + if (!filep || !fgets( buff, sizeof( buff), filep) + || strncmp( buff, curses_version( ), 14)) + failure = TRUE; + else if( !fgets( buff, sizeof( buff), filep) + || 9 != sscanf( buff, _format_nine_ints, &version, &window_size, + &temp_win._cury, &temp_win._curx, &temp_win._maxy, &temp_win._maxx, + &temp_win._begy, &temp_win._begx, &temp_win._flags) + || version != DUMPVER) + failure = TRUE; + else if( !fgets( buff, sizeof( buff), filep) + || 9 != sscanf( buff, _format_nine_ints, &_clear, &_leaveit, + &_scroll, &_nodelay, &_immed, &_sync, &_use_keypad, + &temp_win._tmarg, &temp_win._bmarg)) + failure = TRUE; + else if( !fgets( buff, sizeof( buff), filep) + || 3 != sscanf( buff, _format_three_ints, &temp_win._delayms, + &temp_win._parx, &temp_win._pary)) + failure = TRUE; + else if( !fread( buff, 16, 1, filep)) + failure = TRUE; + + if( failure) + return (WINDOW *)NULL; + + win = PDC_makenew( temp_win._maxy, temp_win._maxx, temp_win._begy, temp_win._begx); if (!win) return (WINDOW *)NULL; - - /* check for the marker, and load the WINDOW struct */ - - if (!filep || !fread(marker, 4, 1, filep) || strncmp(marker, "PDC", 3) - || marker[3] != DUMPVER || !fread(win, sizeof(WINDOW), 1, filep)) + else { - free(win); - return (WINDOW *)NULL; + chtype **saved_y = win->_y; + int *saved_firstch = win->_firstch; + int *saved_lastch = win->_lastch; + + memcpy( win, &temp_win, sizeof( WINDOW)); + win->_y = saved_y; + win->_firstch = saved_firstch; + win->_lastch = saved_lastch; } + win->_attrs = _get_chtype_from_eight_bytes( buff); + win->_bkgd = _get_chtype_from_eight_bytes( buff + 8); + win->_clear = _clear; + win->_leaveit = _leaveit; + win->_scroll = _scroll; + win->_nodelay = _nodelay; + win->_immed = _immed; + win->_sync = _sync; + win->_use_keypad = _use_keypad; nlines = win->_maxy; - ncols = win->_maxx; - - /* allocate the line pointer array */ - - win->_y = malloc(nlines * sizeof(chtype *)); - if (!win->_y) - { - free(win); - return (WINDOW *)NULL; - } - - /* allocate the minchng and maxchng arrays */ - - win->_firstch = malloc(nlines * sizeof(int)); - if (!win->_firstch) - { - free(win->_y); - free(win); - return (WINDOW *)NULL; - } - - win->_lastch = malloc(nlines * sizeof(int)); - if (!win->_lastch) - { - free(win->_firstch); - free(win->_y); - free(win); - return (WINDOW *)NULL; - } /* allocate the lines */ @@ -150,15 +225,26 @@ WINDOW *getwin(FILE *filep) /* read them */ - for (i = 0; i < nlines; i++) + for( y = 0; y < nlines && !failure; y++) { - if (!fread(win->_y[i], ncols * sizeof(chtype), 1, filep)) + const int ncols = win->_maxx; + int x; + + for( x = 0; x < ncols && !failure; x++) { - delwin(win); - return (WINDOW *)NULL; + if (!fread( buff, 8, 1, filep)) + failure = TRUE; + else + win->_y[y][x] = _get_chtype_from_eight_bytes( buff); } } + if( failure) + { + delwin(win); + return (WINDOW *)NULL; + } + touchwin(win); return win; @@ -184,6 +270,7 @@ int scr_init(const char *filename) { PDC_LOG(("scr_init() - called: filename %s\n", filename)); + INTENTIONALLY_UNUSED_PARAMETER( filename); return OK; } diff --git a/src/3rdparty/win32_src/pdcurses/scroll.c b/src/3rdparty/win32_src/pdcurses/scroll.c index ffe8d0d94..87b07dcd0 100644 --- a/src/3rdparty/win32_src/pdcurses/scroll.c +++ b/src/3rdparty/win32_src/pdcurses/scroll.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -45,6 +46,7 @@ int wscrl(WINDOW *win, int n) /* Check if window scrolls. Valid for window AND pad */ + assert( win); if (!win || !win->_scroll || !n) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/slk.c b/src/3rdparty/win32_src/pdcurses/slk.c index 5a02803ad..4bf511e0c 100644 --- a/src/3rdparty/win32_src/pdcurses/slk.c +++ b/src/3rdparty/win32_src/pdcurses/slk.c @@ -393,6 +393,7 @@ int slk_attr_on(const attr_t attrs, void *opts) { PDC_LOG(("slk_attr_on() - called\n")); + INTENTIONALLY_UNUSED_PARAMETER( opts); return slk_attron(attrs); } @@ -416,6 +417,7 @@ int slk_attr_off(const attr_t attrs, void *opts) { PDC_LOG(("slk_attr_off() - called\n")); + INTENTIONALLY_UNUSED_PARAMETER( opts); return slk_attroff(attrs); } @@ -435,27 +437,41 @@ int slk_attrset(const chtype attrs) return rc; } -int slk_color(short color_pair) +int extended_slk_color( int pair) { int rc; + PDC_LOG(("extended_slk_color() - called\n")); + + assert( SP); + if (!SP) + return ERR; + + rc = wcolor_set(SP->slk_winptr, 0, (void *)&pair); + _redraw(); + + return rc; +} + +int slk_color(short color_pair) +{ + int integer_color_pair = (int)color_pair; + PDC_LOG(("slk_color() - called\n")); assert( SP); if (!SP) return ERR; - - rc = wcolor_set(SP->slk_winptr, color_pair, NULL); - _redraw(); - - return rc; + return( extended_slk_color( integer_color_pair)); } int slk_attr_set(const attr_t attrs, short color_pair, void *opts) { + const int integer_color_pair = (opts ? *(int *)opts : (int)color_pair); + PDC_LOG(("slk_attr_set() - called\n")); - return slk_attrset(attrs | COLOR_PAIR(color_pair)); + return slk_attrset(attrs | COLOR_PAIR(integer_color_pair)); } static void _slk_calc(void) diff --git a/src/3rdparty/win32_src/pdcurses/termattr.c b/src/3rdparty/win32_src/pdcurses/termattr.c index 37c84a435..fd3ec6514 100644 --- a/src/3rdparty/win32_src/pdcurses/termattr.c +++ b/src/3rdparty/win32_src/pdcurses/termattr.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -112,7 +113,7 @@ char *longname(void) { PDC_LOG(("longname() - called\n")); - sprintf(ttytype, "pdcurses|PDCurses for %s", PDC_sysname()); + sprintf(ttytype, "pdcurses|PDCursesMod for %s", PDC_sysname()); return ttytype + 9; /* skip "pdcurses|" */ } @@ -151,6 +152,7 @@ int erasewchar(wchar_t *ch) { PDC_LOG(("erasewchar() - called\n")); + assert( ch); if (!ch) return ERR; @@ -163,6 +165,7 @@ int killwchar(wchar_t *ch) { PDC_LOG(("killwchar() - called\n")); + assert( ch); if (!ch) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/terminfo.c b/src/3rdparty/win32_src/pdcurses/terminfo.c new file mode 100644 index 000000000..7dc36e5d6 --- /dev/null +++ b/src/3rdparty/win32_src/pdcurses/terminfo.c @@ -0,0 +1,242 @@ +/* PDCurses */ + +#include + +/*man-start************************************************************** + +terminfo +-------- + +### Synopsis + + int vidattr(chtype attr); + int vid_attr(attr_t attr, short color_pair, void *opt); + int vidputs(chtype attr, int (*putfunc)(int)); + int vid_puts(attr_t attr, short color_pair, void *opt, + int (*putfunc)(int)); + + int del_curterm(TERMINAL *); + int putp(const char *); + int restartterm(const char *, int, int *); + TERMINAL *set_curterm(TERMINAL *); + int setterm(const char *term); + int setupterm(const char *, int, int *); + int tgetent(char *, const char *); + int tgetflag(const char *); + int tgetnum(const char *); + char *tgetstr(const char *, char **); + char *tgoto(const char *, int, int); + int tigetflag(const char *); + int tigetnum(const char *); + char *tigetstr(const char *); + char *tparm(const char *,long, long, long, long, long, long, + long, long, long); + int tputs(const char *, int, int (*)(int)); + +### Description + + These functions are currently implemented as stubs, + returning the appropriate errors and doing nothing else. + They are only compiled and used for certain ncurses tests. + +### Portability + X/Open BSD SYS V + mvcur Y Y Y + +**man-end****************************************************************/ + +#include + +TERMINAL *cur_term = NULL; + +int vidattr(chtype attr) +{ + PDC_LOG(("vidattr() - called: attr %d\n", attr)); + + INTENTIONALLY_UNUSED_PARAMETER( attr); + return ERR; +} + +int vid_attr(attr_t attr, short color_pair, void *opt) +{ + PDC_LOG(("vid_attr() - called\n")); + + INTENTIONALLY_UNUSED_PARAMETER( attr); + INTENTIONALLY_UNUSED_PARAMETER( color_pair); + INTENTIONALLY_UNUSED_PARAMETER( opt); + return ERR; +} + +int vidputs(chtype attr, int (*putfunc)(int)) +{ + PDC_LOG(("vidputs() - called: attr %d\n", attr)); + + INTENTIONALLY_UNUSED_PARAMETER( attr); + INTENTIONALLY_UNUSED_PARAMETER( putfunc); + return ERR; +} + +int vid_puts(attr_t attr, short color_pair, void *opt, int (*putfunc)(int)) +{ + PDC_LOG(("vid_puts() - called\n")); + + INTENTIONALLY_UNUSED_PARAMETER( attr); + INTENTIONALLY_UNUSED_PARAMETER( color_pair); + INTENTIONALLY_UNUSED_PARAMETER( opt); + INTENTIONALLY_UNUSED_PARAMETER( putfunc); + return ERR; +} + +int del_curterm(TERMINAL *oterm) +{ + PDC_LOG(("del_curterm() - called\n")); + + INTENTIONALLY_UNUSED_PARAMETER( oterm); + return ERR; +} + +int putp(const char *str) +{ + PDC_LOG(("putp() - called: str %s\n", str)); + + INTENTIONALLY_UNUSED_PARAMETER( str); + return ERR; +} + +int restartterm(const char *term, int filedes, int *errret) +{ + PDC_LOG(("restartterm() - called\n")); + + if (errret) + *errret = -1; + + INTENTIONALLY_UNUSED_PARAMETER( term); + INTENTIONALLY_UNUSED_PARAMETER( filedes); + return ERR; +} + +TERMINAL *set_curterm(TERMINAL *nterm) +{ + PDC_LOG(("set_curterm() - called\n")); + + INTENTIONALLY_UNUSED_PARAMETER( nterm); + return (TERMINAL *)NULL; +} + +int setterm(const char *term) +{ + PDC_LOG(("setterm() - called\n")); + + INTENTIONALLY_UNUSED_PARAMETER( term); + return ERR; +} + +int setupterm(const char *term, int filedes, int *errret) +{ + PDC_LOG(("setupterm() - called\n")); + + if (errret) + *errret = -1; + else + fprintf(stderr, "There is no terminfo database\n"); + + INTENTIONALLY_UNUSED_PARAMETER( term); + INTENTIONALLY_UNUSED_PARAMETER( filedes); + return ERR; +} + +int tgetent(char *bp, const char *name) +{ + PDC_LOG(("tgetent() - called: name %s\n", name)); + + INTENTIONALLY_UNUSED_PARAMETER( bp); + INTENTIONALLY_UNUSED_PARAMETER( name); + return ERR; +} + +int tgetflag(const char *id) +{ + PDC_LOG(("tgetflag() - called: id %s\n", id)); + + INTENTIONALLY_UNUSED_PARAMETER( id); + return ERR; +} + +int tgetnum(const char *id) +{ + PDC_LOG(("tgetnum() - called: id %s\n", id)); + + INTENTIONALLY_UNUSED_PARAMETER( id); + return ERR; +} + +char *tgetstr(const char *id, char **area) +{ + PDC_LOG(("tgetstr() - called: id %s\n", id)); + + INTENTIONALLY_UNUSED_PARAMETER( id); + INTENTIONALLY_UNUSED_PARAMETER( area); + return (char *)NULL; +} + +char *tgoto(const char *cap, int col, int row) +{ + PDC_LOG(("tgoto() - called\n")); + + INTENTIONALLY_UNUSED_PARAMETER( cap); + INTENTIONALLY_UNUSED_PARAMETER( col); + INTENTIONALLY_UNUSED_PARAMETER( row); + return (char *)NULL; +} + +int tigetflag(const char *capname) +{ + PDC_LOG(("tigetflag() - called: capname %s\n", capname)); + + INTENTIONALLY_UNUSED_PARAMETER( capname); + return -1; +} + +int tigetnum(const char *capname) +{ + PDC_LOG(("tigetnum() - called: capname %s\n", capname)); + + INTENTIONALLY_UNUSED_PARAMETER( capname); + return -2; +} + +char *tigetstr(const char *capname) +{ + PDC_LOG(("tigetstr() - called: capname %s\n", capname)); + + INTENTIONALLY_UNUSED_PARAMETER( capname); + return (char *)(-1); +} + +char *tparm(const char *cap, long p1, long p2, long p3, long p4, + long p5, long p6, long p7, long p8, long p9) +{ + PDC_LOG(("tparm() - called: cap %s\n", cap)); + INTENTIONALLY_UNUSED_PARAMETER( cap); + INTENTIONALLY_UNUSED_PARAMETER( p1); + INTENTIONALLY_UNUSED_PARAMETER( p2); + INTENTIONALLY_UNUSED_PARAMETER( p3); + INTENTIONALLY_UNUSED_PARAMETER( p4); + INTENTIONALLY_UNUSED_PARAMETER( p5); + INTENTIONALLY_UNUSED_PARAMETER( p6); + INTENTIONALLY_UNUSED_PARAMETER( p7); + INTENTIONALLY_UNUSED_PARAMETER( p8); + INTENTIONALLY_UNUSED_PARAMETER( p9); + + return (char *)NULL; +} + +int tputs(const char *str, int affcnt, int (*putfunc)(int)) +{ + PDC_LOG(("tputs() - called\n")); + + INTENTIONALLY_UNUSED_PARAMETER( str); + INTENTIONALLY_UNUSED_PARAMETER( affcnt); + INTENTIONALLY_UNUSED_PARAMETER( putfunc); + return ERR; +} diff --git a/src/3rdparty/win32_src/pdcurses/touch.c b/src/3rdparty/win32_src/pdcurses/touch.c index e1b7c60ef..24c5f8f59 100644 --- a/src/3rdparty/win32_src/pdcurses/touch.c +++ b/src/3rdparty/win32_src/pdcurses/touch.c @@ -1,6 +1,7 @@ /* PDCurses */ #include +#include /*man-start************************************************************** @@ -60,20 +61,57 @@ touch **man-end****************************************************************/ +void PDC_set_changed_cells_range( WINDOW *win, const int y, const int start, const int end) +{ + assert( win); + assert( y >= 0 && y < win->_maxy); + win->_firstch[y] = start; + win->_lastch[y] = end; +} + +void PDC_mark_line_as_changed( WINDOW *win, const int y) +{ + assert( win); + assert( y >= 0 && y < win->_maxy); + win->_firstch[y] = 0; + win->_lastch[y] = win->_maxx - 1; +} + +void PDC_mark_cells_as_changed( WINDOW *win, const int y, const int start, const int end) +{ + assert( win); + assert( y >= 0 && y < win->_maxy); + if( win->_firstch[y] == _NO_CHANGE) + { + win->_firstch[y] = start; + win->_lastch[y] = end; + } + else + { + if( win->_firstch[y] > start) + win->_firstch[y] = start; + if( win->_lastch[y] < end) + win->_lastch[y] = end; + } +} + +void PDC_mark_cell_as_changed( WINDOW *win, const int y, const int x) +{ + PDC_mark_cells_as_changed( win, y, x, x); +} + int touchwin(WINDOW *win) { int i; PDC_LOG(("touchwin() - called: Win=%x\n", win)); + assert( win); if (!win) return ERR; for (i = 0; i < win->_maxy; i++) - { - win->_firstch[i] = 0; - win->_lastch[i] = win->_maxx - 1; - } + PDC_mark_line_as_changed( win, i); return OK; } @@ -85,14 +123,12 @@ int touchline(WINDOW *win, int start, int count) PDC_LOG(("touchline() - called: win=%p start %d count %d\n", win, start, count)); + assert( win); if (!win || start > win->_maxy || start + count > win->_maxy) return ERR; for (i = start; i < start + count; i++) - { - win->_firstch[i] = 0; - win->_lastch[i] = win->_maxx - 1; - } + PDC_mark_line_as_changed( win, i); return OK; } @@ -103,14 +139,12 @@ int untouchwin(WINDOW *win) PDC_LOG(("untouchwin() - called: win=%p", win)); + assert( win); if (!win) return ERR; for (i = 0; i < win->_maxy; i++) - { - win->_firstch[i] = _NO_CHANGE; - win->_lastch[i] = _NO_CHANGE; - } + PDC_set_changed_cells_range( win, i, _NO_CHANGE, _NO_CHANGE); return OK; } @@ -122,21 +156,16 @@ int wtouchln(WINDOW *win, int y, int n, int changed) PDC_LOG(("wtouchln() - called: win=%p y=%d n=%d changed=%d\n", win, y, n, changed)); + assert( win); if (!win || y > win->_maxy || y + n > win->_maxy) return ERR; for (i = y; i < y + n; i++) { if (changed) - { - win->_firstch[i] = 0; - win->_lastch[i] = win->_maxx - 1; - } + PDC_mark_line_as_changed( win, i); else - { - win->_firstch[i] = _NO_CHANGE; - win->_lastch[i] = _NO_CHANGE; - } + PDC_set_changed_cells_range( win, i, _NO_CHANGE, _NO_CHANGE); } return OK; @@ -146,6 +175,7 @@ bool is_linetouched(WINDOW *win, int line) { PDC_LOG(("is_linetouched() - called: win=%p line=%d\n", win, line)); + assert( win); if (!win || line > win->_maxy || line < 0) return FALSE; @@ -158,6 +188,7 @@ bool is_wintouched(WINDOW *win) PDC_LOG(("is_wintouched() - called: win=%p\n", win)); + assert( win); if (win) for (i = 0; i < win->_maxy; i++) if (win->_firstch[i] != _NO_CHANGE) @@ -172,6 +203,8 @@ int touchoverlap(const WINDOW *win1, WINDOW *win2) PDC_LOG(("touchoverlap() - called: win1=%p win2=%p\n", win1, win2)); + assert( win1); + assert( win2); if (!win1 || !win2) return ERR; @@ -190,10 +223,7 @@ int touchoverlap(const WINDOW *win1, WINDOW *win2) endx -= 1; for (y = starty; y < endy; y++) - { - win2->_firstch[y] = startx; - win2->_lastch[y] = endx; - } + PDC_set_changed_cells_range( win2, y, startx, endx); return OK; } diff --git a/src/3rdparty/win32_src/pdcurses/util.c b/src/3rdparty/win32_src/pdcurses/util.c index f5b8f887d..cf89eedf3 100644 --- a/src/3rdparty/win32_src/pdcurses/util.c +++ b/src/3rdparty/win32_src/pdcurses/util.c @@ -39,18 +39,15 @@ util getcchar() works in two modes: When wch is not NULL, it reads the cchar_t pointed to by wcval and stores the attributes in attrs, the color pair in color_pair, and the text in the wide-character string - wch. When wch is NULL, getcchar() merely returns the number of wide - characters in wcval. In either mode, the opts argument is unused. + wch. If opts is non-NULL, it is treated as a pointer to an integer + and the color pair is stored in it (this is an ncurses extension). + When wch is NULL, getcchar() merely returns the number of wide + characters in wcval. setcchar constructs a cchar_t at wcval from the wide-character text - at wch, the attributes in attr and the color pair in color_pair. The - opts argument is unused. - - Currently, the length returned by getcchar() is always 1 or 0. - Similarly, setcchar() will only take the first wide character from - wch, and ignore any others that it "should" take (i.e., combining - characters). Nor will it correctly handle any character outside the - basic multilingual plane (UCS-2). + at wch, the attributes in attr and the color pair in color_pair. If + the opts argument is non-NULL, it is treated as a pointer to an + integer containing the desired color pair and color_pair is ignored. ### Return Value @@ -118,6 +115,7 @@ void filter(void) void use_env(bool x) { + INTENTIONALLY_UNUSED_PARAMETER( x); PDC_LOG(("use_env() - called: x %d\n", x)); } @@ -132,69 +130,216 @@ int PDC_wc_to_utf8( char *dest, const int32_t code) { int n_bytes_out; - if (code < 0x80) + if( code < 0) + n_bytes_out = 0; + else if (code < 0x80) { - dest[0] = (char)code; + if( dest) + dest[0] = (char)code; n_bytes_out = 1; } else if (code < 0x800) { - dest[0] = (char) (((code >> 6) & 0x1f) | 0xc0); - dest[1] = (char) ((code & 0x3f) | 0x80); + if( dest) + { + dest[0] = (char) (((code >> 6) & 0x1f) | 0xc0); + dest[1] = (char) ((code & 0x3f) | 0x80); + } n_bytes_out = 2; } else if( code < 0x10000) { - dest[0] = (char) (((code >> 12) & 0x0f) | 0xe0); - dest[1] = (char) (((code >> 6) & 0x3f) | 0x80); - dest[2] = (char) ((code & 0x3f) | 0x80); + if( dest) + { + dest[0] = (char) (((code >> 12) & 0x0f) | 0xe0); + dest[1] = (char) (((code >> 6) & 0x3f) | 0x80); + dest[2] = (char) ((code & 0x3f) | 0x80); + } n_bytes_out = 3; } - else /* Unicode past 64K, i.e., SMP */ + else if( code < 0x110000) /* Unicode past 64K, i.e., SMP */ { - dest[0] = (char) (((code >> 18) & 0x0f) | 0xf0); - dest[1] = (char) (((code >> 12) & 0x3f) | 0x80); - dest[2] = (char) (((code >> 6) & 0x3f) | 0x80); - dest[3] = (char) ((code & 0x3f) | 0x80); + if( dest) + { + dest[0] = (char) (((code >> 18) & 0x0f) | 0xf0); + dest[1] = (char) (((code >> 12) & 0x3f) | 0x80); + dest[2] = (char) (((code >> 6) & 0x3f) | 0x80); + dest[3] = (char) ((code & 0x3f) | 0x80); + } n_bytes_out = 4; } + else /* not valid Unicode */ + n_bytes_out = 0; return( n_bytes_out); } #ifdef PDC_WIDE + + /* I think that only under Windows is wchar_t 16 bits. */ +#ifdef _WIN32 + #define WCHAR_T_IS_16_BITS +#endif + + /* This expands a string of wchar_t values, possibly including surrogate + pairs, into an array of int32_t Unicode points. The output array will + contain exactly as many values as the input array, _unless_ the input + has Unicode surrogate pairs in it. In that case, each input pair will + result in only one output value. */ + +#define IS_HIGH_SURROGATE( x) ((x) >= 0xd800 && (x) < 0xdc00) +#define IS_LOW_SURROGATE( x) ((x) >= 0xdc00 && (x) < 0xe000) +#define IS_SURROGATE( x) ((x) >= 0xd800 && (x) < 0xe000) + +static int _wchar_to_int32_array( int32_t *obuff, const int obuffsize, const wchar_t *wch) +{ + int i; + + for( i = 0; i < obuffsize && *wch; i++) + { + if( IS_SURROGATE( wch[0])) + { + if( IS_LOW_SURROGATE( wch[1]) && IS_HIGH_SURROGATE( wch[0])) + obuff[i] = (((int32_t)wch[0] - 0xd800) << 10) + 0x10000 + + (int32_t)wch[1] - 0xdc00; + else /* malformed surrogate pair */ + return( -1); + wch++; + wch++; + } + else + obuff[i] = *wch++; + } + if( i < obuffsize) + obuff[i] = (int32_t)0; + else /* no room for null terminator */ + i = -1; + return( i); +} + +/* Inverse of the above function : given a null-terminated array of Unicode +points, encode them as a null-terminated array of wchar_t values. On +strange systems where wchar_t does not handle all of Unicode (is 16 bits), +such as Microsoft Windows, input values in the SMP will be converted to +a surrogate pair of wchar_t values. On more modern systems, the output +will essentially equal the input. */ + +static int _int32_to_wchar_array( wchar_t *obuff, const int obuffsize, const int32_t *wint) +{ + int i = 0; + + if( !obuff) /* just getting the size of the output array */ + { +#ifdef WCHAR_T_IS_16_BITS + while( *wint) + i += 1 + (*wint++ >= 0x10000 ? 1 : 0); +#else + while( *wint++) + i++; +#endif + return( i + 1); /* include the '\0' terminator */ + } + while( i < obuffsize && *wint) + { +#ifdef WCHAR_T_IS_16_BITS + if( *wint >= 0x10000) /* make surrogate pair */ + { + obuff[i++] = (wchar_t)( 0xd800 + (*wint >> 10)); + if( i < obuffsize) + obuff[i++] = (wchar_t)( 0xdc00 + (*wint & 0x3ff)); + wint++; + } + else +#endif + obuff[i++] = (wchar_t)*wint++; + } + if( i < obuffsize) + obuff[i++] = '\0'; + else /* didn't fit in the buffer */ + i = -1; + return( i); +} + +#ifdef USING_COMBINING_CHARACTER_SCHEME + int PDC_expand_combined_characters( const cchar_t c, cchar_t *added); + int PDC_find_combined_char_idx( const cchar_t root, const cchar_t added); + + #define COMBINED_CHAR_START 0x110001 +#endif + int getcchar(const cchar_t *wcval, wchar_t *wch, attr_t *attrs, short *color_pair, void *opts) { + int32_t c[20]; + int n = 0; + + assert( wcval); if (!wcval) return ERR; - - if (wch) + c[0] = (int32_t)( *wcval & A_CHARTEXT); + /* TODO: if c[0] == 0x110000, it's a placeholder with a + fullwidth character to its left. If c[0] > 0x110001, it's + a marker for a combining character string. */ +#ifdef USING_COMBINING_CHARACTER_SCHEME + while( n < 10 && c[n] >= COMBINED_CHAR_START) { + cchar_t added; + + c[n + 1] = PDC_expand_combined_characters( c[n], &added); + c[n] = (int32_t)added; + n++; + } +#endif + c[++n] = 0; + if( !wch) + return( c[0] ? _int32_to_wchar_array( NULL, 0, c) : -1); + else + { + int i, j; + int32_t swap_val; + + for( i = 0, j = n - 1; i < j; i++, j--) + { + swap_val = c[i]; + c[i] = c[j]; + c[j] = swap_val; + } + _int32_to_wchar_array( wch, 20, c); + assert( attrs); + assert( color_pair); if (!attrs || !color_pair) return ERR; - *wch = (wchar_t)(*wcval & A_CHARTEXT); *attrs = (*wcval & (A_ATTRIBUTES & ~A_COLOR)); *color_pair = (short)( PAIR_NUMBER(*wcval & A_COLOR)); - - if (*wch) - *++wch = L'\0'; - + if( opts) + *(int *)opts = (int)( PAIR_NUMBER(*wcval & A_COLOR)); return OK; } - else - return ((*wcval & A_CHARTEXT) != L'\0'); } int setcchar(cchar_t *wcval, const wchar_t *wch, const attr_t attrs, short color_pair, const void *opts) { + int32_t ochar[20], rval; +#ifdef USING_COMBINING_CHARACTER_SCHEME + int i; +#endif + + const int integer_color_pair = (opts ? *(int *)opts : (int)color_pair); + assert( wcval); + assert( wch); if (!wcval || !wch) return ERR; - - *wcval = *wch | attrs | COLOR_PAIR(color_pair); - + _wchar_to_int32_array( ochar, 20, wch); + rval = ochar[0]; + /* If len_out > 1, we have combining characters. See */ + /* 'addch.c' for a discussion of how we handle those. */ +#ifdef USING_COMBINING_CHARACTER_SCHEME + for( i = 1; ochar[i]; i++) + rval = COMBINED_CHAR_START + PDC_find_combined_char_idx( rval, ochar[i]); +#endif + *wcval = rval | attrs | COLOR_PAIR(integer_color_pair); return OK; } @@ -206,6 +351,7 @@ wchar_t *wunctrl(cchar_t *wc) PDC_LOG(("wunctrl() - called\n")); + assert( wc); if (!wc) return NULL; @@ -233,10 +379,12 @@ wchar_t *wunctrl(cchar_t *wc) int PDC_mbtowc(wchar_t *pwc, const char *s, size_t n) { # ifdef PDC_FORCE_UTF8 - wchar_t key; + uint32_t key; int i = -1; const unsigned char *string; + assert( s); + assert( pwc); if (!s || (n < 1)) return -1; @@ -249,7 +397,9 @@ int PDC_mbtowc(wchar_t *pwc, const char *s, size_t n) /* Simplistic UTF-8 decoder -- a little validation */ - if ((key & 0xc0) == 0xc0 && IS_CONTINUATION_BYTE( string[1])) + if( !(key & 0x80)) /* 'ordinary' 7-bit ASCII */ + i = 1; + else if ((key & 0xc0) == 0xc0 && IS_CONTINUATION_BYTE( string[1])) { if ((key & 0xe0) == 0xc0 && 1 < n) { @@ -273,13 +423,14 @@ int PDC_mbtowc(wchar_t *pwc, const char *s, size_t n) i = 4; /* four-byte sequence : U+10000 to U+10FFFF */ } } - else /* 'ordinary' 7-bit ASCII */ - i = 1; - *pwc = key; + if( i > 0) + *pwc = (wchar_t)key; return i; # else + assert( s); + assert( pwc); return mbtowc(pwc, s, n); # endif } @@ -289,6 +440,8 @@ size_t PDC_mbstowcs(wchar_t *dest, const char *src, size_t n) # ifdef PDC_FORCE_UTF8 size_t i = 0, len; + assert( src); + assert( dest); if (!src || !dest) return 0; @@ -299,7 +452,7 @@ size_t PDC_mbstowcs(wchar_t *dest, const char *src, size_t n) int retval = PDC_mbtowc(dest + i, src, len); if (retval < 1) - return -1; + return (size_t)-1; src += retval; len -= retval; @@ -317,6 +470,8 @@ size_t PDC_wcstombs(char *dest, const wchar_t *src, size_t n) # ifdef PDC_FORCE_UTF8 size_t i = 0; + assert( src); + assert( dest); if (!src || !dest) return 0; diff --git a/src/3rdparty/win32_src/pdcurses/winclip.c b/src/3rdparty/win32_src/pdcurses/winclip.c new file mode 100644 index 000000000..b055a6761 --- /dev/null +++ b/src/3rdparty/win32_src/pdcurses/winclip.c @@ -0,0 +1,146 @@ +/* Windows clipboard code shared by WinCon, WinGUI, Windows +builds for VT and (at some point) SDL1. */ + +/*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 = (long)wcslen((wchar_t *)handle) * 3; +#else + len = (long)strlen((char *)handle); +#endif + *contents = (char *)GlobalAlloc(GMEM_FIXED, len + 1); + + if (!*contents) + { + CloseClipboard(); + return PDC_CLIP_MEMORY_ERROR; + } + +#ifdef PDC_WIDE + len = (long)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/src/3rdparty/win32_src/pdcurses/wincon/pdcclip.c b/src/3rdparty/win32_src/pdcurses/wincon/pdcclip.c index 5a204ec76..de4ddd24b 100644 --- a/src/3rdparty/win32_src/pdcurses/wincon/pdcclip.c +++ b/src/3rdparty/win32_src/pdcurses/wincon/pdcclip.c @@ -1,149 +1,6 @@ /* PDCurses */ #include "pdcwin.h" - #include -/*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 = (long)wcslen((wchar_t *)handle) * 3; -#else - len = (long)strlen((char *)handle); -#endif - *contents = (char *)GlobalAlloc(GMEM_FIXED, len + 1); - - if (!*contents) - { - CloseClipboard(); - return PDC_CLIP_MEMORY_ERROR; - } - -#ifdef PDC_WIDE - len = (long)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; -} +#include "winclip.c" diff --git a/src/3rdparty/win32_src/pdcurses/wincon/pdcdisp.c b/src/3rdparty/win32_src/pdcurses/wincon/pdcdisp.c index fa1f3a78e..6d4269003 100644 --- a/src/3rdparty/win32_src/pdcurses/wincon/pdcdisp.c +++ b/src/3rdparty/win32_src/pdcurses/wincon/pdcdisp.c @@ -4,6 +4,7 @@ #include #include +#include #ifdef PDC_WIDE #define USE_UNICODE_ACS_CHARS 1 @@ -26,13 +27,13 @@ void PDC_gotoyx(int row, int col) 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; + coord.X = (SHORT)col; + coord.Y = (SHORT)row; SetConsoleCursorPosition(pdc_con_out, coord); } -void _set_ansi_color(short f, short b, attr_t attr) +static void _set_ansi_color(short f, short b, attr_t attr) { char esc[64], *p; short tmp, underline; @@ -138,12 +139,119 @@ void _set_ansi_color(short f, short b, attr_t attr) } } -void _new_packet(attr_t attr, int lineno, int x, int len, const chtype *srcp) +#define MAX_PACKET_SIZE 128 + +#ifdef PDC_WIDE +const chtype MAX_UNICODE = 0x10ffff; +const chtype DUMMY_CHAR_NEXT_TO_FULLWIDTH = 0x110000; + +#endif + +static void _show_run_of_ansi_characters( const attr_t attr, + const int fore, const int back, const bool blink, + const int lineno, const int x, const chtype *srcp, const int len) { - int j; - short fore, back; +#ifdef PDC_WIDE + WCHAR buffer[MAX_PACKET_SIZE]; +#else + char buffer[MAX_PACKET_SIZE]; +#endif + int j, n_out; + + for (j = n_out = 0; j < len; j++) + { + chtype ch = srcp[j]; + + if( _is_altcharset( ch)) + ch = acs_map[ch & 0x7f]; + + if (blink && blinked_off) + ch = ' '; + +#ifdef PDC_WIDE + if( (ch & A_CHARTEXT) != DUMMY_CHAR_NEXT_TO_FULLWIDTH) + buffer[n_out++] = (WCHAR)( ch & A_CHARTEXT); +#else + buffer[n_out++] = (char)( ch & A_CHARTEXT); +#endif + } + + PDC_gotoyx(lineno, x); + _set_ansi_color( (short)fore, (short)back, attr); +#ifdef PDC_WIDE + WriteConsoleW(pdc_con_out, buffer, n_out, NULL, NULL); +#else + WriteConsoleA(pdc_con_out, buffer, n_out, NULL, NULL); +#endif +} + +static void _show_run_of_nonansi_characters( const attr_t attr, + int fore, int back, const bool blink, + const int lineno, const int x, const chtype *srcp, const int len) +{ + CHAR_INFO buffer[MAX_PACKET_SIZE]; + COORD bufSize, bufPos; + SMALL_RECT sr; + WORD mapped_attr; + int j, n_out;; + + fore = pdc_curstoreal[fore]; + back = pdc_curstoreal[back]; + + if (attr & A_REVERSE) + mapped_attr = (WORD)( back | (fore << 4)); + else + mapped_attr = (WORD)( 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 = n_out = 0; j < len; j++) + { + chtype ch = srcp[j]; + + if( _is_altcharset( ch)) + ch = acs_map[ch & 0x7f]; + + if (blink && blinked_off) + ch = ' '; + + buffer[n_out].Attributes = mapped_attr; +#ifdef PDC_WIDE + if( (ch & A_CHARTEXT) != DUMMY_CHAR_NEXT_TO_FULLWIDTH) +#endif + buffer[n_out++].Char.UnicodeChar = (WCHAR)( ch & A_CHARTEXT); + } + + bufPos.X = bufPos.Y = 0; + bufSize.X = (SHORT)n_out; + bufSize.Y = 1; + + sr.Top = sr.Bottom = (SHORT)lineno; + sr.Left = (SHORT)x; + sr.Right = (SHORT)( x + len - 1); + + WriteConsoleOutput(pdc_con_out, buffer, bufSize, bufPos, &sr); +} + +static void _new_packet(attr_t attr, int lineno, int x, int len, const chtype *srcp) +{ + int fore, back; bool blink, ansi; + assert( len >= 0); + while( len > MAX_PACKET_SIZE) + { + _new_packet( attr, lineno, x, MAX_PACKET_SIZE, srcp); + srcp += MAX_PACKET_SIZE; + x += MAX_PACKET_SIZE; + len -= MAX_PACKET_SIZE; + } + if (pdc_ansi && (lineno == (SP->lines - 1)) && ((x + len) == SP->cols)) { len--; @@ -155,7 +263,7 @@ void _new_packet(attr_t attr, int lineno, int x, int len, const chtype *srcp) return; } - pair_content(PAIR_NUMBER(attr), &fore, &back); + extended_pair_content(PAIR_NUMBER(attr), &fore, &back); ansi = pdc_ansi || (fore >= 16 || back >= 16); blink = (SP->termattrs & A_BLINK) && (attr & A_BLINK); @@ -172,79 +280,9 @@ void _new_packet(attr_t attr, int lineno, int x, int len, const chtype *srcp) 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 (blink && blinked_off) - ch = ' '; - - buffer[j] = (WCHAR)( 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 - } + _show_run_of_ansi_characters( attr, fore, back, blink, lineno, x, srcp, len); else - { - 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 = (WCHAR)( 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); - } + _show_run_of_nonansi_characters( attr, fore, back, blink, lineno, x, srcp, len); } /* update the given physical line to look like the corresponding line in @@ -278,7 +316,17 @@ void PDC_transform_line(int lineno, int x, int len, const chtype *srcp) void PDC_blink_text(void) { + CONSOLE_CURSOR_INFO cci; int i, j, k; + bool oldvis; + + GetConsoleCursorInfo(pdc_con_out, &cci); + oldvis = (bool)cci.bVisible; + if (oldvis) + { + cci.bVisible = FALSE; + SetConsoleCursorInfo(pdc_con_out, &cci); + } if (!(SP->termattrs & A_BLINK)) blinked_off = FALSE; @@ -301,6 +349,12 @@ void PDC_blink_text(void) } PDC_gotoyx(SP->cursrow, SP->curscol); + if (oldvis) + { + cci.bVisible = TRUE; + SetConsoleCursorInfo(pdc_con_out, &cci); + } + pdc_last_blink = GetTickCount(); } diff --git a/src/3rdparty/win32_src/pdcurses/wincon/pdckbd.c b/src/3rdparty/win32_src/pdcurses/wincon/pdckbd.c index bf2464f07..2dc314fce 100644 --- a/src/3rdparty/win32_src/pdcurses/wincon/pdckbd.c +++ b/src/3rdparty/win32_src/pdcurses/wincon/pdckbd.c @@ -80,16 +80,16 @@ static KPTAB kptab[] = {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 */ + {0x30, 0x29, '0', ALT_0, 0 }, /* 48 */ + {0x31, 0x21, '1', ALT_1, 0 }, /* 49 */ + {0x32, 0x40, '2', ALT_2, 0 }, /* 50 */ + {0x33, 0x23, '3', ALT_3, 0 }, /* 51 */ + {0x34, 0x24, '4', ALT_4, 0 }, /* 52 */ + {0x35, 0x25, '5', ALT_5, 0 }, /* 53 */ + {0x36, 0x5E, '6', ALT_6, 0 }, /* 54 */ + {0x37, 0x26, '7', ALT_7, 0 }, /* 55 */ + {0x38, 0x2A, '8', ALT_8, 0 }, /* 56 */ + {0x39, 0x28, '9', ALT_9, 0 }, /* 57 */ {0, 0, 0, 0, 0 }, /* 58 */ {0, 0, 0, 0, 0 }, /* 59 */ {0, 0, 0, 0, 0 }, /* 60 */ @@ -125,7 +125,7 @@ static KPTAB kptab[] = {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, 13 }, /* 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 */ @@ -159,63 +159,186 @@ static KPTAB kptab[] = /* 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 }, /* 7c 124 VK_F13 */ + {0, 0, 0, 0, 0 }, /* 7d 125 VK_F14 */ + {0, 0, 0, 0, 0 }, /* 7e 126 VK_F15 */ + {0, 0, 0, 0, 0 }, /* 7f 127 VK_F16 */ + {0, 0, 0, 0, 0 }, /* 80 128 VK_F17 */ + {0, 0, 0, 0, 0 }, /* 81 129 VK_F18 */ + {0, 0, 0, 0, 0 }, /* 82 130 VK_F19 */ + {0, 0, 0, 0, 0 }, /* 83 131 VK_F20 */ + {0, 0, 0, 0, 0 }, /* 84 132 VK_F21 */ + {0, 0, 0, 0, 0 }, /* 85 133 VK_F22 */ + {0, 0, 0, 0, 0 }, /* 86 134 VK_F23 */ + {0, 0, 0, 0, 0 }, /* 87 135 VK_F24 */ + {0, 0, 0, 0, 0}, /* 136 unassigned */ + {0, 0, 0, 0, 0}, /* 137 unassigned */ + {0, 0, 0, 0, 0}, /* 138 unassigned */ + {0, 0, 0, 0, 0}, /* 139 unassigned */ + {0, 0, 0, 0, 0}, /* 140 unassigned */ + {0, 0, 0, 0, 0}, /* 141 unassigned */ + {0, 0, 0, 0, 0}, /* 142 unassigned */ + {0, 0, 0, 0, 0}, /* 143 unassigned */ + {0, 0, 0, 0, 0}, /* 144 VK_NUMLOCK */ + {KEY_SCROLLLOCK, 0, 0, KEY_SCROLLLOCK, 0}, /* 145 VKSCROLL */ + {0, 0, 0, 0, 0}, /* 146 OEM specific */ + {0, 0, 0, 0, 0}, /* 147 OEM specific */ + {0, 0, 0, 0, 0}, /* 148 OEM specific */ + {0, 0, 0, 0, 0}, /* 149 OEM specific */ + {0, 0, 0, 0, 0}, /* 150 OEM specific */ + {0, 0, 0, 0, 0}, /* 151 Unassigned */ + {0, 0, 0, 0, 0}, /* 152 Unassigned */ + {0, 0, 0, 0, 0}, /* 153 Unassigned */ + {0, 0, 0, 0, 0}, /* 154 Unassigned */ + {0, 0, 0, 0, 0}, /* 155 Unassigned */ + {0, 0, 0, 0, 0}, /* 156 Unassigned */ + {0, 0, 0, 0, 0}, /* 157 Unassigned */ + {0, 0, 0, 0, 0}, /* 158 Unassigned */ + {0, 0, 0, 0, 0}, /* 159 Unassigned */ + {0, 0, 0, 0, 0}, /* 160 VK_LSHIFT */ + {0, 0, 0, 0, 0}, /* 161 VK_RSHIFT */ + {0, 0, 0, 0, 0}, /* 162 VK_LCONTROL */ + {0, 0, 0, 0, 0}, /* 163 VK_RCONTROL */ + {0, 0, 0, 0, 0}, /* 164 VK_LMENU */ + {0, 0, 0, 0, 0}, /* 165 VK_RMENU */ + {0, 0, 0, 0, 14}, /* 166 VK_BROWSER_BACK */ + {0, 0, 0, 0, 15}, /* 167 VK_BROWSER_FORWARD */ + {0, 0, 0, 0, 16}, /* 168 VK_BROWSER_REFRESH */ + {0, 0, 0, 0, 17}, /* 169 VK_BROWSER_STOP */ + {0, 0, 0, 0, 18}, /* 170 VK_BROWSER_SEARCH */ + {0, 0, 0, 0, 19}, /* 171 VK_BROWSER_FAVORITES */ + {0, 0, 0, 0, 20}, /* 172 VK_BROWSER_HOME */ + {0, 0, 0, 0, 21}, /* 173 VK_VOLUME_MUTE */ + {0, 0, 0, 0, 22}, /* 174 VK_VOLUME_DOWN */ + {0, 0, 0, 0, 23}, /* 175 VK_VOLUME_UP */ + {0, 0, 0, 0, 24}, /* 176 VK_MEDIA_NEXT_TRACK */ + {0, 0, 0, 0, 25}, /* 177 VK_MEDIA_PREV_TRACK */ + {0, 0, 0, 0, 26}, /* 178 VK_MEDIA_STOP */ + {0, 0, 0, 0, 27}, /* 179 VK_MEDIA_PLAY_PAUSE */ + {0, 0, 0, 0, 28}, /* 180 VK_LAUNCH_MAIL */ + {0, 0, 0, 0, 29}, /* 181 VK_LAUNCH_MEDIA_SELECT */ + {0, 0, 0, 0, 30}, /* 182 VK_LAUNCH_APP1 */ + {0, 0, 0, 0, 31}, /* 183 VK_LAUNCH_APP2 */ + {0, 0, 0, 0, 0}, /* 184 Reserved */ + {0, 0, 0, 0, 0}, /* 185 Reserved */ + {';', ':', ';', ALT_SEMICOLON, 0}, /* 186 VK_OEM_1 */ + {'=', '+', '=', ALT_EQUAL, 0}, /* 187 VK_OEM_PLUS */ + {',', '<', ',', ALT_COMMA, 0}, /* 188 VK_OEM_COMMA */ + {'-', '_', '-', ALT_MINUS, 0}, /* 189 VK_OEM_MINUS */ + {'.', '>', '.', ALT_STOP, 0}, /* 190 VK_OEM_PERIOD */ + {'/', '?', '/', ALT_FSLASH, 0}, /* 191 VK_OEM_2 */ + {'`', '~', '`', ALT_BQUOTE, 0}, /* 192 VK_OEM_3 */ + {0, 0, 0, 0, 0}, /* 193 */ + {0, 0, 0, 0, 0}, /* 194 */ + {0, 0, 0, 0, 0}, /* 195 */ + {0, 0, 0, 0, 0}, /* 196 */ + {0, 0, 0, 0, 0}, /* 197 */ + {0, 0, 0, 0, 0}, /* 198 */ + {0, 0, 0, 0, 0}, /* 199 */ + {0, 0, 0, 0, 0}, /* 200 */ + {0, 0, 0, 0, 0}, /* 201 */ + {0, 0, 0, 0, 0}, /* 202 */ + {0, 0, 0, 0, 0}, /* 203 */ + {0, 0, 0, 0, 0}, /* 204 */ + {0, 0, 0, 0, 0}, /* 205 */ + {0, 0, 0, 0, 0}, /* 206 */ + {0, 0, 0, 0, 0}, /* 207 */ + {0, 0, 0, 0, 0}, /* 208 */ + {0, 0, 0, 0, 0}, /* 209 */ + {0, 0, 0, 0, 0}, /* 210 */ + {0, 0, 0, 0, 0}, /* 211 */ + {0, 0, 0, 0, 0}, /* 212 */ + {0, 0, 0, 0, 0}, /* 213 */ + {0, 0, 0, 0, 0}, /* 214 */ + {0, 0, 0, 0, 0}, /* 215 */ + {0, 0, 0, 0, 0}, /* 216 */ + {0, 0, 0, 0, 0}, /* 217 */ + {0, 0, 0, 0, 0}, /* 218 */ + {0x5B, 0x7B, 0x1B, ALT_LBRACKET,0 }, /* 219 DB */ + {0x5C, 0x7C, 0x1C, ALT_BSLASH, 0 }, /* 220 DC */ + {0x5D, 0x7D, 0x1D, ALT_RBRACKET,0 }, /* 221 DD */ + {0, 0, 0x27, ALT_FQUOTE, 0 }, /* 222 DE */ + {0, 0, 0, 0, 0 }, /* 223 DF VK_OEM_8 */ + {0, 0, 0, 0, 0 }, /* 224 E0 Reserved */ + {0, 0, 0, 0, 0 }, /* 225 E1 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 226 E2 VK_OEM_102 */ + {0, 0, 0, 0, 0 }, /* 227 E3 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 228 E4 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 229 E5 VK_PROCESSKEY */ + {0, 0, 0, 0, 0 }, /* 230 E6 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 231 E7 VK_PACKET */ + {0, 0, 0, 0, 0 }, /* 232 E8 Unassigned */ + {0, 0, 0, 0, 0 }, /* 233 E9 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 234 EA OEM-specific */ + {0, 0, 0, 0, 0 }, /* 235 EB OEM-specific */ + {0, 0, 0, 0, 0 }, /* 236 EC OEM-specific */ + {0, 0, 0, 0, 0 }, /* 237 ED OEM-specific */ + {0, 0, 0, 0, 0 }, /* 238 EE OEM-specific */ + {0, 0, 0, 0, 0 }, /* 239 EF OEM-specific */ + {0, 0, 0, 0, 0 }, /* 240 F0 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 241 F1 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 242 F2 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 243 F3 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 244 F4 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 245 F5 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 246 F6 VK_ATTN */ + {0, 0, 0, 0, 0 }, /* 247 F7 VK_CRSEL */ + {0, 0, 0, 0, 0 }, /* 248 F8 VK_EXSEL */ + {0, 0, 0, 0, 0 }, /* 249 F9 VK_EREOF */ + {0, 0, 0, 0, 0 }, /* 250 FA VK_PLAY */ + {0, 0, 0, 0, 0 }, /* 251 FB VK_ZOOM */ + {0, 0, 0, 0, 0 }, /* 252 FC VK_NONAME */ + {0, 0, 0, 0, 0 }, /* 253 FD VK_PA1 */ + {0, 0, 0, 0, 0 } /* 254 FE VK_OEM_CLEAR */ }; -static KPTAB ext_kptab[] = +static const 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 */ + {0, 0, 0, 0, 0}, /* 0 MUST BE EMPTY */ + {PADENTER, SHF_PADENTER, CTL_PADENTER, ALT_PADENTER, 0}, /* 1 13 */ + {PADSLASH, SHF_PADSLASH, CTL_PADSLASH, ALT_PADSLASH, 0}, /* 2 111 */ + {KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP, 0}, /* 3 33 */ + {KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN, 0}, /* 4 34 */ + {KEY_END, KEY_SEND, CTL_END, ALT_END, 0}, /* 5 35 */ + {KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME, 0}, /* 6 36 */ + {KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT, 0}, /* 7 37 */ + {KEY_UP, KEY_SUP, CTL_UP, ALT_UP, 0}, /* 8 38 */ + {KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT, 0}, /* 9 39 */ + {KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN, 0}, /* 10 40 */ + {KEY_IC, KEY_SIC, CTL_INS, ALT_INS, 0}, /* 11 45 */ + {KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL, 0}, /* 12 46 */ + {KEY_APPS, KEY_APPS, KEY_APPS, KEY_APPS, 0}, /* 13 93 VK_APPS */ + {KEY_BROWSER_BACK, KEY_BROWSER_BACK, KEY_BROWSER_BACK, KEY_BROWSER_BACK, 0}, /* 14 166 VK_BROWSER_BACK */ + {KEY_BROWSER_FWD, KEY_BROWSER_FWD, KEY_BROWSER_FWD, KEY_BROWSER_FWD, 0}, /* 15 167 VK_BROWSER_FORWARD */ + {KEY_BROWSER_REF, KEY_BROWSER_REF, KEY_BROWSER_REF, KEY_BROWSER_REF, 0}, /* 16 168 VK_BROWSER_REFRESH */ + {KEY_BROWSER_STOP, KEY_BROWSER_STOP, KEY_BROWSER_STOP, KEY_BROWSER_STOP, 0}, /* 17 169 VK_BROWSER_STOP */ + {KEY_SEARCH, KEY_SEARCH, KEY_SEARCH, KEY_SEARCH, 0}, /* 18 170 VK_BROWSER_SEARCH */ + {KEY_FAVORITES, KEY_FAVORITES, KEY_FAVORITES, KEY_FAVORITES, 0}, /* 19 171 VK_BROWSER_FAVORITES */ + {KEY_BROWSER_HOME, KEY_BROWSER_HOME, KEY_BROWSER_HOME, KEY_BROWSER_HOME, 0}, /* 20 172 VK_BROWSER_HOME */ + {KEY_VOLUME_MUTE, KEY_VOLUME_MUTE, KEY_VOLUME_MUTE, KEY_VOLUME_MUTE, 0}, /* 21 173 VK_VOLUME_MUTE */ + {KEY_VOLUME_DOWN, KEY_VOLUME_DOWN, KEY_VOLUME_DOWN, KEY_VOLUME_DOWN, 0}, /* 22 174 VK_VOLUME_DOWN */ + {KEY_VOLUME_UP, KEY_VOLUME_UP, KEY_VOLUME_UP, KEY_VOLUME_UP, 0}, /* 23 175 VK_VOLUME_UP */ + {KEY_NEXT_TRACK, KEY_NEXT_TRACK, KEY_NEXT_TRACK, KEY_NEXT_TRACK, 0}, /* 24 176 VK_MEDIA_NEXT_TRACK */ + {KEY_PREV_TRACK, KEY_PREV_TRACK, KEY_PREV_TRACK, KEY_PREV_TRACK, 0}, /* 25 177 VK_MEDIA_PREV_TRACK */ + {KEY_MEDIA_STOP, KEY_MEDIA_STOP, KEY_MEDIA_STOP, KEY_MEDIA_STOP, 0}, /* 26 178 VK_MEDIA_STOP */ + {KEY_PLAY_PAUSE, KEY_PLAY_PAUSE, KEY_PLAY_PAUSE, KEY_PLAY_PAUSE, 0}, /* 27 179 VK_MEDIA_PLAY_PAUSE */ + {KEY_LAUNCH_MAIL, KEY_LAUNCH_MAIL, KEY_LAUNCH_MAIL, KEY_LAUNCH_MAIL, 0}, /* 28 180 VK_LAUNCH_MAIL */ + {KEY_MEDIA_SELECT, KEY_MEDIA_SELECT, KEY_MEDIA_SELECT, KEY_MEDIA_SELECT, 0}, /* 29 181 VK_LAUNCH_MEDIA_SELECT */ + {KEY_LAUNCH_APP1, KEY_LAUNCH_APP1, KEY_LAUNCH_APP1, KEY_LAUNCH_APP1, 0}, /* 30 182 VK_LAUNCH_APP1 */ + {KEY_LAUNCH_APP2, KEY_LAUNCH_APP2, KEY_LAUNCH_APP2, KEY_LAUNCH_APP2, 0}, /* 31 183 VK_LAUNCH_APP2 */ }; /* 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 */ @@ -317,6 +440,24 @@ static int _get_key_count(void) return num_keys; } +typedef const char *(CDECL *wine_version_func)(void); + +static bool running_under_wine( void) +{ + static int rval = -1; + + if( -1 == rval) + { + HMODULE hntdll = GetModuleHandleA( "ntdll.dll"); + + if( GetProcAddress(hntdll, "wine_get_version") != (FARPROC)NULL) + rval = 1; + else + rval = 0; + } + return( (bool)rval); +} + /* _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. @@ -325,15 +466,18 @@ static int _get_key_count(void) static int _process_key_event(void) { - int key = (unsigned short)KEV.uChar.UnicodeChar; + 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. */ @@ -391,10 +535,7 @@ static int _process_key_event(void) positive codes. */ if (kptab[vk].extended == 0) - { - SP->key_code = FALSE; return key; - } } /* This case happens if a functional key has been entered. */ @@ -410,7 +551,16 @@ static int _process_key_event(void) idx = vk; } - if (state & SHIFT_PRESSED) + if( idx < 0) + key = -1; + + else if( enhanced && (size_t)idx >= sizeof( ext_kptab) / sizeof( ext_kptab[0])) + key = -1; /* unhandled key outside table */ + + else if( !enhanced && (size_t)idx >= sizeof( kptab) / sizeof( kptab[0])) + key = -1; /* unhandled key outside table */ + + else if (state & SHIFT_PRESSED) key = enhanced ? ext_kptab[idx].shift : kptab[idx].shift; else if (state & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) @@ -420,10 +570,22 @@ static int _process_key_event(void) key = enhanced ? ext_kptab[idx].alt : kptab[idx].alt; else + { key = enhanced ? ext_kptab[idx].normal : kptab[idx].normal; + if( running_under_wine( )) + { + size_t i; /* Wine mangles some keys. */ + static const int wine_remaps[] = { + KEY_A1, KEY_HOME, KEY_A3, KEY_PPAGE, + KEY_C1, KEY_END, KEY_C3, KEY_NPAGE, + KEY_A2, KEY_UP, KEY_C2, KEY_DOWN, + KEY_B3, KEY_RIGHT, KEY_B1, KEY_LEFT }; - if (key < KEY_CODE_YES) - SP->key_code = FALSE; + for( i = 0; i < sizeof( wine_remaps) / sizeof( wine_remaps[0]); i += 2) + if( key == wine_remaps[i]) + key = wine_remaps[i + 1]; + } + } return key; } @@ -435,7 +597,6 @@ static int _process_mouse_event(void) int i; save_press = 0; - SP->key_code = TRUE; memset(&SP->mouse_status, 0, sizeof(MOUSE_STATUS)); @@ -602,7 +763,6 @@ int PDC_get_key(void) if (!SP->resized) { SP->resized = TRUE; - SP->key_code = TRUE; return KEY_RESIZE; } } @@ -629,13 +789,17 @@ bool PDC_has_mouse(void) int PDC_mouse_set(void) { - /* If turning on mouse input: Set ENABLE_MOUSE_INPUT, and clear - all other flags, including the extended flags; - If turning off the mouse: Set QuickEdit Mode to the status it - had on startup, and clear all other flags */ + DWORD mode; - SetConsoleMode(pdc_con_in, SP->_trap_mbe ? - (ENABLE_MOUSE_INPUT|0x0088) : (pdc_quick_edit|0x0088)); + /* 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)); diff --git a/src/3rdparty/win32_src/pdcurses/wincon/pdcscrn.c b/src/3rdparty/win32_src/pdcurses/wincon/pdcscrn.c index 7ce575854..597141059 100644 --- a/src/3rdparty/win32_src/pdcurses/wincon/pdcscrn.c +++ b/src/3rdparty/win32_src/pdcurses/wincon/pdcscrn.c @@ -14,9 +14,6 @@ HANDLE pdc_con_in = INVALID_HANDLE_VALUE; DWORD pdc_quick_edit; -/* special purpose function keys */ -static int PDC_shutdown_key[PDC_MAX_FUNCTION_KEYS] = { 0, 0, 0, 0, 0 }; - static short realtocurs[16] = { COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_RED, @@ -35,7 +32,7 @@ static short ansitocurs[16] = short pdc_curstoreal[16], pdc_curstoansi[16]; short pdc_oldf, pdc_oldb, pdc_oldu; -bool pdc_conemu, pdc_ansi; +bool pdc_conemu, pdc_wt, pdc_ansi; enum { PDC_RESTORE_NONE, PDC_RESTORE_BUFFER }; @@ -107,7 +104,15 @@ static LPTOP_LEVEL_EXCEPTION_FILTER xcpt_filter; static DWORD old_console_mode = 0; -static bool is_nt; +/* MSVC++ 7.1 was the last version to support Win95/98/ME. If we're +on any MSVC after that (_MSC_VER > 1310), is_nt is going to be true +no matter what. */ + +#if defined(_MSC_VER) && _MSC_VER > 1310 + const bool is_nt = TRUE; +#else + static bool is_nt; +#endif static void _reset_old_colors(void) { @@ -319,6 +324,7 @@ static LONG WINAPI _restore_console(LPEXCEPTION_POINTERS ep) { PDC_scr_close(); + INTENTIONALLY_UNUSED_PARAMETER( ep); return EXCEPTION_CONTINUE_SEARCH; } @@ -387,8 +393,8 @@ int PDC_scr_open(void) for (i = 0; i < 16; i++) { - pdc_curstoreal[realtocurs[i]] = i; - pdc_curstoansi[ansitocurs[i]] = i; + pdc_curstoreal[realtocurs[i]] = (short)i; + pdc_curstoansi[ansitocurs[i]] = (short)i; } _reset_old_colors(); @@ -402,11 +408,18 @@ int PDC_scr_open(void) exit(1); } +#if !defined(_MSC_VER) || _MSC_VER <= 1310 is_nt = !(GetVersion() & 0x80000000); +#endif - str = getenv("ConEmuANSI"); + pdc_wt = !!getenv("WT_SESSION"); + str = pdc_wt ? NULL : getenv("ConEmuANSI"); pdc_conemu = !!str; - pdc_ansi = pdc_conemu ? !strcmp(str, "ON") : FALSE; + pdc_ansi = +#ifdef PDC_WIDE + pdc_wt ? TRUE : +#endif + pdc_conemu ? !strcmp(str, "ON") : FALSE; GetConsoleScreenBufferInfo(pdc_con_out, &csbi); GetConsoleScreenBufferInfo(pdc_con_out, &orig_scr); @@ -462,6 +475,7 @@ int PDC_scr_open(void) SP->termattrs |= A_UNDERLINE | A_LEFT | A_RIGHT; PDC_reset_prog_mode(); + PDC_set_function_key( FUNCTION_KEY_COPY, 0); SP->mono = FALSE; @@ -518,8 +532,12 @@ int PDC_resize_screen(int nlines, int ncols) { SMALL_RECT rect; COORD size, max; + const bool prog_resize = nlines || ncols; - bool prog_resize = nlines || ncols; + if( !stdscr) /* We're trying to specify an initial screen size */ + { /* before calling initscr(). This works on some */ + return OK; /* some platforms, but not on this one (yet). */ + } if (!prog_resize) { @@ -533,12 +551,12 @@ int PDC_resize_screen(int nlines, int ncols) max = GetLargestConsoleWindowSize(pdc_con_out); rect.Left = rect.Top = 0; - rect.Right = ncols - 1; + rect.Right = (SHORT)ncols - 1; if (rect.Right > max.X) rect.Right = max.X; - rect.Bottom = nlines - 1; + rect.Bottom = (SHORT)nlines - 1; if (rect.Bottom > max.Y) rect.Bottom = max.Y; @@ -608,10 +626,12 @@ void PDC_reset_shell_mode(void) void PDC_restore_screen_mode(int i) { + INTENTIONALLY_UNUSED_PARAMETER( i); } void PDC_save_screen_mode(int i) { + INTENTIONALLY_UNUSED_PARAMETER( i); } bool PDC_can_change_color(void) @@ -621,7 +641,7 @@ bool PDC_can_change_color(void) int PDC_color_content(int color, int *red, int *green, int *blue) { - if (color < 16 && !pdc_conemu) + if (color < 16 && !(pdc_conemu || pdc_wt)) { COLORREF *color_table = _get_colors(); @@ -660,7 +680,7 @@ int PDC_init_color(int color, int red, int green, int blue) return OK; } - if (color < 16 && !pdc_conemu) + if (color < 16 && !(pdc_conemu || pdc_wt)) { COLORREF *color_table = _get_colors(); @@ -678,9 +698,9 @@ int PDC_init_color(int color, int red, int green, int blue) } else { - pdc_color[color].r = red; - pdc_color[color].g = green; - pdc_color[color].b = blue; + pdc_color[color].r = (short)red; + pdc_color[color].g = (short)green; + pdc_color[color].b = (short)blue; pdc_color[color].mapped = TRUE; } @@ -693,17 +713,12 @@ without this, we get an unresolved external... */ void PDC_set_resize_limits( const int new_min_lines, const int new_max_lines, const int new_min_cols, const int new_max_cols) { + INTENTIONALLY_UNUSED_PARAMETER( new_min_lines); + INTENTIONALLY_UNUSED_PARAMETER( new_max_lines); + INTENTIONALLY_UNUSED_PARAMETER( new_min_cols); + INTENTIONALLY_UNUSED_PARAMETER( new_max_cols); } -/* PDC_set_function_key() does nothing on this platform */ -int PDC_set_function_key( const unsigned function, const int new_key) +void PDC_free_platform_dependent_memory( void) { - int old_key = -1; - - if( function < PDC_MAX_FUNCTION_KEYS) - { - old_key = PDC_shutdown_key[function]; - PDC_shutdown_key[function] = new_key; - } - return( old_key); } diff --git a/src/3rdparty/win32_src/pdcurses/wincon/pdcutil.c b/src/3rdparty/win32_src/pdcurses/wincon/pdcutil.c index 291e88980..499afa148 100644 --- a/src/3rdparty/win32_src/pdcurses/wincon/pdcutil.c +++ b/src/3rdparty/win32_src/pdcurses/wincon/pdcutil.c @@ -1,13 +1,31 @@ /* PDCurses */ #include "pdcwin.h" +#ifdef WIN32_LEAN_AND_MEAN +#include +#include +#endif + +static volatile int _beep_count = 0; + +static void beep_thread(LPVOID lpParameter) +{ + INTENTIONALLY_UNUSED_PARAMETER( lpParameter); + while( _beep_count) + { + if (!PlaySound((LPCTSTR) SND_ALIAS_SYSTEMDEFAULT, NULL, SND_ALIAS_ID)) + Beep(800, 200); + _beep_count--; + } +} void PDC_beep(void) { PDC_LOG(("PDC_beep() - called\n")); -/* MessageBeep(MB_OK); */ - MessageBeep(0XFFFFFFFF); + _beep_count++; + if( _beep_count == 1) + _beginthread( beep_thread, 0, NULL); } void PDC_napms(int ms) @@ -17,7 +35,8 @@ void PDC_napms(int ms) if ((SP->termattrs & A_BLINK) && (GetTickCount() >= pdc_last_blink + 500)) PDC_blink_text(); - Sleep(ms); + if( ms) + Sleep(ms); } const char *PDC_sysname(void) diff --git a/src/3rdparty/win32_src/pdcurses/wincon/pdcwin.h b/src/3rdparty/win32_src/pdcurses/wincon/pdcwin.h index 5b99af458..d19a79c77 100644 --- a/src/3rdparty/win32_src/pdcurses/wincon/pdcwin.h +++ b/src/3rdparty/win32_src/pdcurses/wincon/pdcwin.h @@ -1,7 +1,12 @@ /* PDCurses */ -#ifndef __PDC_WINCON_WIN_H__ -#define __PDC_WINCON_WIN_H__ +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE 1 /* kill nonsense warnings */ +#endif + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE 1 /* kill nonsense warnings */ +#endif #if defined(PDC_WIDE) && !defined(UNICODE) # define UNICODE @@ -12,10 +17,6 @@ #undef MOUSE_MOVED #include -#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]; @@ -25,8 +26,6 @@ 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_ansi; +extern bool pdc_conemu, pdc_wt, pdc_ansi; extern void PDC_blink_text(void); - -#endif diff --git a/src/3rdparty/win32_src/pdcurses/window.c b/src/3rdparty/win32_src/pdcurses/window.c index 487cf3e5c..f1b948133 100644 --- a/src/3rdparty/win32_src/pdcurses/window.c +++ b/src/3rdparty/win32_src/pdcurses/window.c @@ -150,30 +150,17 @@ WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx) /* allocate the line pointer array */ win->_y = malloc(nlines * sizeof(chtype *)); - if (!win->_y) - { - free(win); - return (WINDOW *)NULL; - } /* allocate the minchng and maxchng arrays */ - win->_firstch = malloc(nlines * sizeof(int)); - if (!win->_firstch) + win->_firstch = malloc(nlines * sizeof(int) * 2); + if (!win->_firstch || !win->_y) { - free(win->_y); - free(win); + delwin( win); return (WINDOW *)NULL; } - win->_lastch = malloc(nlines * sizeof(int)); - if (!win->_lastch) - { - free(win->_firstch); - free(win->_y); - free(win); - return (WINDOW *)NULL; - } + win->_lastch = win->_firstch + nlines; /* initialize window variables */ @@ -195,34 +182,27 @@ WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx) WINDOW *PDC_makelines(WINDOW *win) { - int i, j, nlines, ncols; + int i, nlines, ncols; PDC_LOG(("PDC_makelines() - called\n")); + assert( win); if (!win) return (WINDOW *)NULL; nlines = win->_maxy; ncols = win->_maxx; - for (i = 0; i < nlines; i++) + win->_y[0] = malloc(ncols * nlines * sizeof(chtype)); + if (!win->_y[0]) { - win->_y[i] = malloc(ncols * sizeof(chtype)); - if (!win->_y[i]) - { - /* if error, free all the data */ + /* if error, free all the data */ - for (j = 0; j < i; j++) - free(win->_y[j]); - - free(win->_firstch); - free(win->_lastch); - free(win->_y); - free(win); - - return (WINDOW *)NULL; - } + delwin( win); + return (WINDOW *)NULL; } + for (i = 1; i < nlines; i++) + win->_y[i] = win->_y[i - 1] + ncols; return win; } @@ -265,23 +245,22 @@ WINDOW *newwin(int nlines, int ncols, int begy, int begx) int delwin(WINDOW *win) { - int i; - PDC_LOG(("delwin() - called\n")); + assert( win); if (!win) return ERR; /* subwindows use parents' lines */ if (!(win->_flags & (_SUBWIN|_SUBPAD))) - for (i = 0; i < win->_maxy && win->_y[i]; i++) - if (win->_y[i]) - free(win->_y[i]); + if (win->_y[0]) + free(win->_y[0]); - free(win->_firstch); - free(win->_lastch); - free(win->_y); + if( win->_firstch) + free(win->_firstch); + if( win->_y) + free(win->_y); free(win); return OK; @@ -291,6 +270,7 @@ int mvwin(WINDOW *win, int y, int x) { PDC_LOG(("mvwin() - called\n")); + assert( win); if (!win || (y + win->_maxy > LINES || y < 0) || (x + win->_maxx > COLS || x < 0)) return ERR; @@ -312,6 +292,7 @@ WINDOW *subwin(WINDOW *orig, int nlines, int ncols, int begy, int begx) /* make sure window fits inside the original one */ + assert( orig); if (!orig || (begy < orig->_begy) || (begx < orig->_begx) || (begy + nlines) > (orig->_begy + orig->_maxy) || (begx + ncols) > (orig->_begx + orig->_maxx)) @@ -362,6 +343,7 @@ int mvderwin(WINDOW *win, int pary, int parx) int i, j; WINDOW *mypar; + assert( win); if (!win || !(win->_parent)) return ERR; @@ -388,6 +370,7 @@ WINDOW *dupwin(WINDOW *win) chtype *ptr, *ptr1; int nlines, ncols, begy, begx, i; + assert( win); if (!win) return (WINDOW *)NULL; @@ -411,8 +394,7 @@ WINDOW *dupwin(WINDOW *win) ptr < new->_y[i] + ncols; ptr++, ptr1++) *ptr = *ptr1; - new->_firstch[i] = 0; - new->_lastch[i] = ncols - 1; + PDC_mark_line_as_changed( new, i); } new->_curx = win->_curx; @@ -443,7 +425,7 @@ WINDOW *dupwin(WINDOW *win) WINDOW *resize_window(WINDOW *win, int nlines, int ncols) { WINDOW *new; - int i, save_cury, save_curx, new_begy, new_begx; + int save_cury, save_curx, new_begy, new_begx; PDC_LOG(("resize_window() - called: nlines %d ncols %d\n", nlines, ncols)); @@ -492,14 +474,14 @@ WINDOW *resize_window(WINDOW *win, int nlines, int ncols) if (!new) return (WINDOW *)NULL; + new->_bkgd = win->_bkgd; werase(new); copywin(win, new, 0, 0, 0, 0, min(win->_maxy, new->_maxy) - 1, min(win->_maxx, new->_maxx) - 1, FALSE); - for (i = 0; i < win->_maxy && win->_y[i]; i++) - if (win->_y[i]) - free(win->_y[i]); + if (win->_y[0]) + free(win->_y[0]); } new->_flags = win->_flags; @@ -520,9 +502,7 @@ WINDOW *resize_window(WINDOW *win, int nlines, int ncols) new->_curx = save_curx; new->_cury = save_cury; - free(win->_firstch); - free(win->_lastch); free(win->_y); *win = *new; @@ -550,6 +530,7 @@ int syncok(WINDOW *win, bool bf) { PDC_LOG(("syncok() - called\n")); + assert( win); if (!win) return ERR; diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdcclip.c b/src/3rdparty/win32_src/pdcurses/wingui/pdcclip.c index 0b86951ae..de4ddd24b 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdcclip.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdcclip.c @@ -1,174 +1,6 @@ -/* Public Domain Curses */ +/* PDCurses */ #include "pdcwin.h" +#include -/*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 BSD SYS V - 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_handle( HANDLE *handle) -{ - 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; - } - - return PDC_CLIP_SUCCESS; -} - -int PDC_getclipboard(char **contents, long *length) -{ - HANDLE handle; - int rval = PDC_getclipboard_handle( &handle); - - if( rval == PDC_CLIP_SUCCESS) - { - void *tptr = GlobalLock( handle); - - if( tptr) - { -#ifdef PDC_WIDE - size_t len = wcslen((wchar_t *)tptr) * 3; -#else - size_t len = strlen( tptr); -#endif - - *contents = (char *)GlobalAlloc( GMEM_FIXED, len + 1); - - if( !*contents) - rval = PDC_CLIP_MEMORY_ERROR; - else - { -#ifdef PDC_WIDE - len = PDC_wcstombs( (char *)*contents, tptr, len); -#else - strcpy((char *)*contents, tptr); -#endif - } - *length = (long)len; - GlobalUnlock( handle); - } - else - rval = PDC_CLIP_MEMORY_ERROR; - CloseClipboard(); - } - return rval; -} - -int PDC_setclipboard_raw( const char *contents, long length, - const bool translate_multibyte_to_wide_char) -{ - HGLOBAL handle; - LPTSTR buff; - - PDC_LOG(("PDC_setclipboard() - called\n")); - - if (!OpenClipboard(NULL)) - return PDC_CLIP_ACCESS_ERROR; - - handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, - (length + 1) * sizeof(TCHAR)); - - if (!handle) - return PDC_CLIP_MEMORY_ERROR; - - buff = GlobalLock(handle); - -#ifdef PDC_WIDE - if( translate_multibyte_to_wide_char) - PDC_mbstowcs((wchar_t *)buff, contents, length); - else - memcpy((char *)buff, contents, (length + 1) * sizeof( wchar_t)); -#else - memcpy((char *)buff, contents, length); - buff[length] = 0; /* ensure null termination */ -#endif - GlobalUnlock(handle); - EmptyClipboard(); - - if( !SetClipboardData(PDC_TEXT, handle)) - { - GlobalFree(handle); - return PDC_CLIP_ACCESS_ERROR; - } - - CloseClipboard(); - - return PDC_CLIP_SUCCESS; -} - -int PDC_setclipboard(const char *contents, long length) -{ - return( PDC_setclipboard_raw( contents, length, TRUE)); -} - -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; -} +#include "winclip.c" diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdcdisp.c b/src/3rdparty/win32_src/pdcurses/wingui/pdcdisp.c index 18d724b68..474ff25d1 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdcdisp.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdcdisp.c @@ -326,6 +326,7 @@ int PDC_choose_a_new_font( void) CHOOSEFONT cf; int rval; extern HWND PDC_hWnd; + extern CRITICAL_SECTION PDC_cs; lf.lfHeight = -PDC_font_size; debug_printf( "In PDC_choose_a_new_font: %d\n", lf.lfHeight); @@ -334,16 +335,19 @@ int PDC_choose_a_new_font( void) cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_SELECTSCRIPT; cf.hwndOwner = PDC_hWnd; cf.lpLogFont = &lf; + LeaveCriticalSection(&PDC_cs); rval = ChooseFont( &cf); - if( rval) + EnterCriticalSection(&PDC_cs); + if( rval) { #ifdef PDC_WIDE wcscpy( PDC_font_name, lf.lfFaceName); #else strcpy( PDC_font_name, lf.lfFaceName); #endif + PDC_font_size = -lf.lfHeight; + debug_printf( "output size: %d\n", lf.lfHeight); + } debug_printf( "rval %d; %ld\n", rval, CommDlgExtendedError( )); - debug_printf( "output size: %d\n", lf.lfHeight); - PDC_font_size = -lf.lfHeight; return( rval); } @@ -371,7 +375,7 @@ static bool character_is_in_font( chtype ichar) int i; WCRANGE *wptr = PDC_unicode_range_data->ranges; - if( (ichar & A_ALTCHARSET) && (ichar & A_CHARTEXT) < 0x80) + if( _is_altcharset( ichar)) ichar = acs_map[ichar & 0x7f]; ichar &= A_CHARTEXT; if( ichar > MAX_UNICODE) /* assume combining chars won't be */ @@ -468,7 +472,7 @@ void PDC_transform_line_given_hdc( const HDC hdc, const int lineno, while( len) { - const attr_t attrib = (attr_t)( *srcp >> PDC_REAL_ATTR_SHIFT); + const attr_t attrib = (attr_t)( *srcp & ~A_CHARTEXT); const int color = (int)(( *srcp & A_COLOR) >> PDC_COLOR_SHIFT); attr_t new_font_attrib = (*srcp & (A_BOLD | A_ITALIC)); RECT clip_rect; @@ -484,7 +488,7 @@ void PDC_transform_line_given_hdc( const HDC hdc, const int lineno, && (in_font == character_is_in_font( srcp[i]) || (srcp[i] & A_CHARTEXT) == MAX_UNICODE) #endif - && attrib == (attr_t)( srcp[i] >> PDC_REAL_ATTR_SHIFT); i++) + && attrib == (attr_t)( srcp[i] & ~A_CHARTEXT); i++) { chtype ch = srcp[i] & A_CHARTEXT; @@ -520,7 +524,7 @@ void PDC_transform_line_given_hdc( const HDC hdc, const int lineno, } } #endif - if( (srcp[i] & A_ALTCHARSET) && ch < 0x80) + if( _is_altcharset( srcp[i])) ch = acs_map[ch & 0x7f]; else if( ch < 32) ch = starting_ascii_to_unicode[ch]; diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdckbd.c b/src/3rdparty/win32_src/pdcurses/wingui/pdckbd.c index db43b5808..7cd9e2f96 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdckbd.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdckbd.c @@ -6,6 +6,8 @@ void PDC_set_keyboard_binary(bool on) { PDC_LOG(("PDC_set_keyboard_binary() - called\n")); + + INTENTIONALLY_UNUSED_PARAMETER( on); } /* check if a key or mouse event is waiting */ @@ -15,19 +17,20 @@ void PDC_set_keyboard_binary(bool on) extern int PDC_key_queue_low, PDC_key_queue_high; extern int PDC_key_queue[KEY_QUEUE_SIZE]; -/* PDCurses message/event callback */ -/* Calling PDC_napms for one millisecond ensures that the message loop */ -/* is called and messages in general, and keyboard events in particular, */ -/* get processed. */ - bool PDC_check_key(void) { - PDC_napms( 1); + extern CRITICAL_SECTION PDC_cs; + + LeaveCriticalSection(&PDC_cs); + SwitchToThread( ); + EnterCriticalSection(&PDC_cs); if( PDC_key_queue_low != PDC_key_queue_high) return TRUE; return FALSE; } +int PDC_get_mouse_event_from_queue( void); /* pdcscrn.c */ + /* return the next available key or mouse event */ int PDC_get_key(void) @@ -47,8 +50,9 @@ int PDC_get_key(void) if( PDC_key_queue_low == KEY_QUEUE_SIZE) PDC_key_queue_low = 0; } + if( rval == KEY_MOUSE) + PDC_get_mouse_event_from_queue( ); } - SP->key_code = (rval >= KEY_MIN && rval <= KEY_MAX); return rval; } @@ -59,6 +63,8 @@ void PDC_flushinp(void) { PDC_LOG(("PDC_flushinp() - called\n")); PDC_key_queue_low = PDC_key_queue_high = 0; + while( !PDC_get_mouse_event_from_queue( )) + ; } bool PDC_has_mouse( void) diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c b/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c index 707180521..2119e93aa 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "pdccolor.h" #ifdef WIN32_LEAN_AND_MEAN #ifdef PDC_WIDE @@ -18,7 +19,7 @@ static int menu_shown = 1; static int min_lines = 25, max_lines = 25; static int min_cols = 80, max_cols = 80; -#if defined( CHTYPE_64) && defined( PDC_WIDE) +#if !defined( CHTYPE_32) && defined( PDC_WIDE) #define USING_COMBINING_CHARACTER_SCHEME int PDC_expand_combined_characters( const cchar_t c, cchar_t *added); /* addch.c */ #endif @@ -37,9 +38,10 @@ functions. */ static int add_mouse( int button, const int action, const int x, const int y); static int keep_size_within_bounds( int *lines, int *cols); INLINE int set_default_sizes_from_registry( const int n_cols, const int n_rows, - const int xloc, const int yloc, const int menu_shown); + const int xloc, const int yloc); void PDC_transform_line_given_hdc( const HDC hdc, const int lineno, int x, int len, const chtype *srcp); +int PDC_get_mouse_event_from_queue( void); /* pdcscrn.c */ /* We have a 'base' standard palette of 256 colors, plus a true-color cube of 16 million colors. */ @@ -60,13 +62,12 @@ cube of 16 million colors. */ #define PDC_MAX_MOUSE_BUTTONS 3 #endif -#define VERTICAL_WHEEL_EVENT PDC_MAX_MOUSE_BUTTONS -#define HORIZONTAL_WHEEL_EVENT (PDC_MAX_MOUSE_BUTTONS + 1) +#define WHEEL_EVENT PDC_MAX_MOUSE_BUTTONS int PDC_show_ctrl_alts = 0; /* RR: Removed statis on next line */ -bool PDC_bDone = FALSE; +/*bool PDC_bDone = FALSE;*/ static HWND originally_focussed_window; int debug_printf( const char *format, ...) @@ -95,7 +96,6 @@ int debug_printf( const char *format, ...) { printf( "Opening '%s' failed\n", output_filename); exit( 0); - debugging = FALSE; /* don't bother trying again */ } } } @@ -105,6 +105,8 @@ int debug_printf( const char *format, ...) HWND PDC_hWnd; static int PDC_argc = 0; static char **PDC_argv = NULL; +uint32_t winthr_id = 0; +CRITICAL_SECTION PDC_cs; static void final_cleanup( void) { @@ -115,7 +117,7 @@ static void final_cleanup( void) GetWindowRect( PDC_hWnd, &rect); set_default_sizes_from_registry( SP->cols, SP->lines, - rect.left, rect.top, menu_shown); + rect.left, rect.top); } PDC_LOG(( "final_cleanup: freeing fonts\n")); PDC_transform_line( 0, 0, 0, NULL); /* free any fonts */ @@ -141,7 +143,7 @@ void PDC_scr_close(void) { PDC_LOG(("PDC_scr_close() - called\n")); final_cleanup( ); - PDC_bDone = TRUE; + /*PDC_bDone = TRUE;*/ } /* NOTE that PDC_scr_free( ) is called only from delscreen( ), */ @@ -157,15 +159,6 @@ int PDC_choose_a_new_font( void); /* pdcdisp.c */ #define KEY_QUEUE_SIZE 30 - /* By default, the PDC_shutdown_key[] array contains 0 */ - /* (i.e., there's no key that's supposed to be returned for */ - /* exit handling), and 22 = Ctrl-V (i.e., hit Ctrl-V to */ - /* paste text from the clipboard into the key queue); then */ - /* Ctl-= (enlarge font) and Ctl-Minus (decrease font); then */ - /* Ctl-, (select font from dialog). */ - -static int PDC_shutdown_key[PDC_MAX_FUNCTION_KEYS] = { 0, 22, CTL_EQUAL, CTL_MINUS, - CTL_COMMA }; int PDC_n_rows, PDC_n_cols; int PDC_cxChar, PDC_cyChar, PDC_key_queue_low = 0, PDC_key_queue_high = 0; int PDC_key_queue[KEY_QUEUE_SIZE]; @@ -213,13 +206,13 @@ static void add_key_to_queue( const int new_key) } } unicode_radix = 10; - if( new_key && new_key == PDC_shutdown_key[FUNCTION_KEY_ABORT]) + if( new_key && new_key == PDC_get_function_key( FUNCTION_KEY_ABORT)) exit( -1); - else if( new_key && new_key == PDC_shutdown_key[FUNCTION_KEY_ENLARGE_FONT]) + else if( new_key && new_key == PDC_get_function_key( FUNCTION_KEY_ENLARGE_FONT)) adjust_font_size( 1); - else if( new_key && new_key == PDC_shutdown_key[FUNCTION_KEY_SHRINK_FONT]) + else if( new_key && new_key == PDC_get_function_key( FUNCTION_KEY_SHRINK_FONT)) adjust_font_size( -1); - else if( new_key && new_key == PDC_shutdown_key[FUNCTION_KEY_CHOOSE_FONT]) + else if( new_key && new_key == PDC_get_function_key( FUNCTION_KEY_CHOOSE_FONT)) { if( PDC_choose_a_new_font( )) adjust_font_size( 0); @@ -251,7 +244,7 @@ static const KPTAB kptab[] = {0, 0, 0, 0, 0 }, /* 0 */ {0, 0, 0, 0, 0 }, /* 1 VK_LBUTTON */ {0, 0, 0, 0, 0 }, /* 2 VK_RBUTTON */ - {CTL_PAUSE, 'a', 'b', 'c', 0 }, /* 3 VK_CANCEL */ + {KEY_PAUSE, 'a', 'b', 'c', 0 }, /* 3 VK_CANCEL */ {0, 0, 0, 0, 0 }, /* 4 VK_MBUTTON */ {0, 0, 0, 0, 0 }, /* 5 */ {0, 0, 0, 0, 0 }, /* 6 */ @@ -267,7 +260,7 @@ static const KPTAB kptab[] = {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 */ - {KEY_PAUSE, KEY_SPAUSE,CTL_PAUSE, 0, 0 }, /* 19 VK_PAUSE */ + {KEY_PAUSE, KEY_PAUSE, KEY_PAUSE, 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 */ @@ -292,20 +285,20 @@ static const KPTAB kptab[] = {0, 0, 0, 0, 0 }, /* 41 VK_SELECT */ {0, 0, 0, 0, 0 }, /* 42 VK_PRINT */ {0, 0, 0, 0, 0 }, /* 43 VK_EXECUTE */ - {KEY_PRINTSCREEN, 0, 0, ALT_PRINTSCREEN, 0 }, /* 44 VK_SNAPSHOT*/ + {KEY_PRINTSCREEN, 0, 0, KEY_PRINTSCREEN, 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, CTL_0, ALT_0, 0 }, /* 48 */ - {0x31, 0x21, CTL_1, ALT_1, 0 }, /* 49 */ - {0x32, 0x40, CTL_2, ALT_2, 0 }, /* 50 */ - {0x33, 0x23, CTL_3, ALT_3, 0 }, /* 51 */ - {0x34, 0x24, CTL_4, ALT_4, 0 }, /* 52 */ - {0x35, 0x25, CTL_5, ALT_5, 0 }, /* 53 */ - {0x36, 0x5E, CTL_6, ALT_6, 0 }, /* 54 */ - {0x37, 0x26, CTL_7, ALT_7, 0 }, /* 55 */ - {0x38, 0x2A, CTL_8, ALT_8, 0 }, /* 56 */ - {0x39, 0x28, CTL_9, ALT_9, 0 }, /* 57 */ + {0x30, 0x29, '0', ALT_0, 0 }, /* 48 */ + {0x31, 0x21, '1', ALT_1, 0 }, /* 49 */ + {0x32, 0x40, '2', ALT_2, 0 }, /* 50 */ + {0x33, 0x23, '3', ALT_3, 0 }, /* 51 */ + {0x34, 0x24, '4', ALT_4, 0 }, /* 52 */ + {0x35, 0x25, '5', ALT_5, 0 }, /* 53 */ + {0x36, 0x5E, '6', ALT_6, 0 }, /* 54 */ + {0x37, 0x26, '7', ALT_7, 0 }, /* 55 */ + {0x38, 0x2A, '8', ALT_8, 0 }, /* 56 */ + {0x39, 0x28, '9', ALT_9, 0 }, /* 57 */ {0, 0, 0, 0, 0 }, /* 58 */ {0, 0, 0, 0, 0 }, /* 59 */ {0, 0, 0, 0, 0 }, /* 60 */ @@ -341,7 +334,7 @@ static const KPTAB kptab[] = {0x7A, 0x5A, 0x1A, ALT_Z, 0 }, /* 90 */ {0, 0, 0, 0, 0 }, /* 91 VK_LWIN */ {0, 0, 0, 0, 0 }, /* 92 VK_RWIN */ - {KEY_APPS, KEY_SAPPS, CTL_APPS, ALT_APPS, 13 }, /* 93 VK_APPS */ + {KEY_APPS, KEY_APPS, KEY_APPS, KEY_APPS, 13 }, /* 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 */ @@ -375,18 +368,18 @@ static const KPTAB kptab[] = /* 124 through 218 */ - {0, 0, 0, 0, 0}, /* 124 VK_F13 */ - {0, 0, 0, 0, 0}, /* 125 VK_F14 */ - {0, 0, 0, 0, 0}, /* 126 VK_F15 */ - {0, 0, 0, 0, 0}, /* 127 VK_F16 */ - {0, 0, 0, 0, 0}, /* 128 VK_F17 */ - {0, 0, 0, 0, 0}, /* 129 VK_F18 */ - {0, 0, 0, 0, 0}, /* 130 VK_F19 */ - {0, 0, 0, 0, 0}, /* 131 VK_F20 */ - {0, 0, 0, 0, 0}, /* 132 VK_F21 */ - {0, 0, 0, 0, 0}, /* 133 VK_F22 */ - {0, 0, 0, 0, 0}, /* 134 VK_F23 */ - {0, 0, 0, 0, 0}, /* 135 VK_F24 */ + {0, 0, 0, 0, 0 }, /* 7c 124 VK_F13 */ + {0, 0, 0, 0, 0 }, /* 7d 125 VK_F14 */ + {0, 0, 0, 0, 0 }, /* 7e 126 VK_F15 */ + {0, 0, 0, 0, 0 }, /* 7f 127 VK_F16 */ + {0, 0, 0, 0, 0 }, /* 80 128 VK_F17 */ + {0, 0, 0, 0, 0 }, /* 81 129 VK_F18 */ + {0, 0, 0, 0, 0 }, /* 82 130 VK_F19 */ + {0, 0, 0, 0, 0 }, /* 83 131 VK_F20 */ + {0, 0, 0, 0, 0 }, /* 84 132 VK_F21 */ + {0, 0, 0, 0, 0 }, /* 85 133 VK_F22 */ + {0, 0, 0, 0, 0 }, /* 86 134 VK_F23 */ + {0, 0, 0, 0, 0 }, /* 87 135 VK_F24 */ {0, 0, 0, 0, 0}, /* 136 unassigned */ {0, 0, 0, 0, 0}, /* 137 unassigned */ {0, 0, 0, 0, 0}, /* 138 unassigned */ @@ -396,7 +389,7 @@ static const KPTAB kptab[] = {0, 0, 0, 0, 0}, /* 142 unassigned */ {0, 0, 0, 0, 0}, /* 143 unassigned */ {0, 0, 0, 0, 0}, /* 144 VK_NUMLOCK */ - {KEY_SCROLLLOCK, 0, 0, ALT_SCROLLLOCK, 0}, /* 145 VKSCROLL */ + {KEY_SCROLLLOCK, 0, 0, KEY_SCROLLLOCK, 0}, /* 145 VKSCROLL */ {0, 0, 0, 0, 0}, /* 146 OEM specific */ {0, 0, 0, 0, 0}, /* 147 OEM specific */ {0, 0, 0, 0, 0}, /* 148 OEM specific */ @@ -437,13 +430,13 @@ static const KPTAB kptab[] = {0, 0, 0, 0, 31}, /* 183 VK_LAUNCH_APP2 */ {0, 0, 0, 0, 0}, /* 184 Reserved */ {0, 0, 0, 0, 0}, /* 185 Reserved */ - {';', ':', CTL_SEMICOLON, ALT_SEMICOLON, 0}, /* 186 VK_OEM_1 */ - {'=', '+', CTL_EQUAL, ALT_EQUAL, 0}, /* 187 VK_OEM_PLUS */ - {',', '<', CTL_COMMA, ALT_COMMA, 0}, /* 188 VK_OEM_COMMA */ - {'-', '_', CTL_MINUS, ALT_MINUS, 0}, /* 189 VK_OEM_MINUS */ - {'.', '>', CTL_STOP, ALT_STOP, 0}, /* 190 VK_OEM_PERIOD */ - {'/', '?', CTL_FSLASH, ALT_FSLASH, 0}, /* 191 VK_OEM_2 */ - {'`', '~', CTL_BQUOTE, ALT_BQUOTE, 0}, /* 192 VK_OEM_3 */ + {';', ':', ';', ALT_SEMICOLON, 0}, /* 186 VK_OEM_1 */ + {'=', '+', '=', ALT_EQUAL, 0}, /* 187 VK_OEM_PLUS */ + {',', '<', ',', ALT_COMMA, 0}, /* 188 VK_OEM_COMMA */ + {'-', '_', '-', ALT_MINUS, 0}, /* 189 VK_OEM_MINUS */ + {'.', '>', '.', ALT_STOP, 0}, /* 190 VK_OEM_PERIOD */ + {'/', '?', '/', ALT_FSLASH, 0}, /* 191 VK_OEM_2 */ + {'`', '~', '`', ALT_BQUOTE, 0}, /* 192 VK_OEM_3 */ {0, 0, 0, 0, 0}, /* 193 */ {0, 0, 0, 0, 0}, /* 194 */ {0, 0, 0, 0, 0}, /* 195 */ @@ -476,83 +469,104 @@ static const KPTAB kptab[] = {'\'', '"', 0x27, ALT_FQUOTE, 0 }, /* 222 VK_OEM_7 */ {0, 0, 0, 0, 0 }, /* 223 VK_OEM_8 */ {0, 0, 0, 0, 0 }, /* 224 */ - {0, 0, 0, 0, 0 } /* 225 */ + {0, 0, 0, 0, 0 }, /* 225 */ + {0, 0, 0, 0, 0 }, /* 226 E2 VK_OEM_102 */ + {0, 0, 0, 0, 0 }, /* 227 E3 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 228 E4 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 229 E5 VK_PROCESSKEY */ + {0, 0, 0, 0, 0 }, /* 230 E6 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 231 E7 VK_PACKET */ + {0, 0, 0, 0, 0 }, /* 232 E8 Unassigned */ + {0, 0, 0, 0, 0 }, /* 233 E9 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 234 EA OEM-specific */ + {0, 0, 0, 0, 0 }, /* 235 EB OEM-specific */ + {0, 0, 0, 0, 0 }, /* 236 EC OEM-specific */ + {0, 0, 0, 0, 0 }, /* 237 ED OEM-specific */ + {0, 0, 0, 0, 0 }, /* 238 EE OEM-specific */ + {0, 0, 0, 0, 0 }, /* 239 EF OEM-specific */ + {0, 0, 0, 0, 0 }, /* 240 F0 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 241 F1 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 242 F2 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 243 F3 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 244 F4 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 245 F5 OEM-specific */ + {0, 0, 0, 0, 0 }, /* 246 F6 VK_ATTN */ + {0, 0, 0, 0, 0 }, /* 247 F7 VK_CRSEL */ + {0, 0, 0, 0, 0 }, /* 248 F8 VK_EXSEL */ + {0, 0, 0, 0, 0 }, /* 249 F9 VK_EREOF */ + {0, 0, 0, 0, 0 }, /* 250 FA VK_PLAY */ + {0, 0, 0, 0, 0 }, /* 251 FB VK_ZOOM */ + {0, 0, 0, 0, 0 }, /* 252 FC VK_NONAME */ + {0, 0, 0, 0, 0 }, /* 253 FD VK_PA1 */ + {0, 0, 0, 0, 0 } /* 254 FE VK_OEM_CLEAR */ }; /* End of kptab[] */ static const KPTAB ext_kptab[] = { - {0, 0, 0, 0, }, /* 0 MUST BE EMPTY */ - {PADENTER, SHF_PADENTER, CTL_PADENTER, ALT_PADENTER}, /* 1 13 */ - {PADSLASH, SHF_PADSLASH, CTL_PADSLASH, ALT_PADSLASH}, /* 2 111 */ - {KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP }, /* 3 33 */ - {KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN }, /* 4 34 */ - {KEY_END, KEY_SEND, CTL_END, ALT_END }, /* 5 35 */ - {KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME }, /* 6 36 */ - {KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT }, /* 7 37 */ - {KEY_UP, KEY_SUP, CTL_UP, ALT_UP }, /* 8 38 */ - {KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT }, /* 9 39 */ - {KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN }, /* 10 40 */ - {KEY_IC, KEY_SIC, CTL_INS, ALT_INS }, /* 11 45 */ - {KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL }, /* 12 46 */ - {KEY_APPS, KEY_SAPPS , CTL_APPS, ALT_APPS }, /* 13 93 VK_APPS */ - {KEY_BROWSER_BACK, KEY_SBROWSER_BACK, KEY_CBROWSER_BACK, KEY_ABROWSER_BACK, }, /* 14 166 VK_BROWSER_BACK */ - {KEY_BROWSER_FWD, KEY_SBROWSER_FWD, KEY_CBROWSER_FWD, KEY_ABROWSER_FWD, }, /* 15 167 VK_BROWSER_FORWARD */ - {KEY_BROWSER_REF, KEY_SBROWSER_REF, KEY_CBROWSER_REF, KEY_ABROWSER_REF, }, /* 16 168 VK_BROWSER_REFRESH */ - {KEY_BROWSER_STOP, KEY_SBROWSER_STOP, KEY_CBROWSER_STOP, KEY_ABROWSER_STOP, }, /* 17 169 VK_BROWSER_STOP */ - {KEY_SEARCH, KEY_SSEARCH, KEY_CSEARCH, KEY_ASEARCH, }, /* 18 170 VK_BROWSER_SEARCH */ - {KEY_FAVORITES, KEY_SFAVORITES, KEY_CFAVORITES, KEY_AFAVORITES, }, /* 19 171 VK_BROWSER_FAVORITES */ - {KEY_BROWSER_HOME, KEY_SBROWSER_HOME, KEY_CBROWSER_HOME, KEY_ABROWSER_HOME, }, /* 20 172 VK_BROWSER_HOME */ - {KEY_VOLUME_MUTE, KEY_SVOLUME_MUTE, KEY_CVOLUME_MUTE, KEY_AVOLUME_MUTE, }, /* 21 173 VK_VOLUME_MUTE */ - {KEY_VOLUME_DOWN, KEY_SVOLUME_DOWN, KEY_CVOLUME_DOWN, KEY_AVOLUME_DOWN, }, /* 22 174 VK_VOLUME_DOWN */ - {KEY_VOLUME_UP, KEY_SVOLUME_UP, KEY_CVOLUME_UP, KEY_AVOLUME_UP, }, /* 23 175 VK_VOLUME_UP */ - {KEY_NEXT_TRACK, KEY_SNEXT_TRACK, KEY_CNEXT_TRACK, KEY_ANEXT_TRACK, }, /* 24 176 VK_MEDIA_NEXT_TRACK */ - {KEY_PREV_TRACK, KEY_SPREV_TRACK, KEY_CPREV_TRACK, KEY_APREV_TRACK, }, /* 25 177 VK_MEDIA_PREV_TRACK */ - {KEY_MEDIA_STOP, KEY_SMEDIA_STOP, KEY_CMEDIA_STOP, KEY_AMEDIA_STOP, }, /* 26 178 VK_MEDIA_STOP */ - {KEY_PLAY_PAUSE, KEY_SPLAY_PAUSE, KEY_CPLAY_PAUSE, KEY_APLAY_PAUSE, }, /* 27 179 VK_MEDIA_PLAY_PAUSE */ - {KEY_LAUNCH_MAIL, KEY_SLAUNCH_MAIL, KEY_CLAUNCH_MAIL, KEY_ALAUNCH_MAIL, }, /* 28 180 VK_LAUNCH_MAIL */ - {KEY_MEDIA_SELECT, KEY_SMEDIA_SELECT, KEY_CMEDIA_SELECT, KEY_AMEDIA_SELECT, }, /* 29 181 VK_LAUNCH_MEDIA_SELECT */ - {KEY_LAUNCH_APP1, KEY_SLAUNCH_APP1, KEY_CLAUNCH_APP1, KEY_ALAUNCH_APP1, }, /* 30 182 VK_LAUNCH_APP1 */ - {KEY_LAUNCH_APP2, KEY_SLAUNCH_APP2, KEY_CLAUNCH_APP2, KEY_ALAUNCH_APP2, }, /* 31 183 VK_LAUNCH_APP2 */ + {0, 0, 0, 0, 0}, /* 0 MUST BE EMPTY */ + {PADENTER, SHF_PADENTER, CTL_PADENTER, ALT_PADENTER, 0}, /* 1 13 */ + {PADSLASH, SHF_PADSLASH, CTL_PADSLASH, ALT_PADSLASH, 0}, /* 2 111 */ + {KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP, 0}, /* 3 33 */ + {KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN, 0}, /* 4 34 */ + {KEY_END, KEY_SEND, CTL_END, ALT_END, 0}, /* 5 35 */ + {KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME, 0}, /* 6 36 */ + {KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT, 0}, /* 7 37 */ + {KEY_UP, KEY_SUP, CTL_UP, ALT_UP, 0}, /* 8 38 */ + {KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT, 0}, /* 9 39 */ + {KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN, 0}, /* 10 40 */ + {KEY_IC, KEY_SIC, CTL_INS, ALT_INS, 0}, /* 11 45 */ + {KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL, 0}, /* 12 46 */ + {KEY_APPS, KEY_APPS, KEY_APPS, KEY_APPS, 0}, /* 13 93 VK_APPS */ + {KEY_BROWSER_BACK, KEY_BROWSER_BACK, KEY_BROWSER_BACK, KEY_BROWSER_BACK, 0}, /* 14 166 VK_BROWSER_BACK */ + {KEY_BROWSER_FWD, KEY_BROWSER_FWD, KEY_BROWSER_FWD, KEY_BROWSER_FWD, 0}, /* 15 167 VK_BROWSER_FORWARD */ + {KEY_BROWSER_REF, KEY_BROWSER_REF, KEY_BROWSER_REF, KEY_BROWSER_REF, 0}, /* 16 168 VK_BROWSER_REFRESH */ + {KEY_BROWSER_STOP, KEY_BROWSER_STOP, KEY_BROWSER_STOP, KEY_BROWSER_STOP, 0}, /* 17 169 VK_BROWSER_STOP */ + {KEY_SEARCH, KEY_SEARCH, KEY_SEARCH, KEY_SEARCH, 0}, /* 18 170 VK_BROWSER_SEARCH */ + {KEY_FAVORITES, KEY_FAVORITES, KEY_FAVORITES, KEY_FAVORITES, 0}, /* 19 171 VK_BROWSER_FAVORITES */ + {KEY_BROWSER_HOME, KEY_BROWSER_HOME, KEY_BROWSER_HOME, KEY_BROWSER_HOME, 0}, /* 20 172 VK_BROWSER_HOME */ + {KEY_VOLUME_MUTE, KEY_VOLUME_MUTE, KEY_VOLUME_MUTE, KEY_VOLUME_MUTE, 0}, /* 21 173 VK_VOLUME_MUTE */ + {KEY_VOLUME_DOWN, KEY_VOLUME_DOWN, KEY_VOLUME_DOWN, KEY_VOLUME_DOWN, 0}, /* 22 174 VK_VOLUME_DOWN */ + {KEY_VOLUME_UP, KEY_VOLUME_UP, KEY_VOLUME_UP, KEY_VOLUME_UP, 0}, /* 23 175 VK_VOLUME_UP */ + {KEY_NEXT_TRACK, KEY_NEXT_TRACK, KEY_NEXT_TRACK, KEY_NEXT_TRACK, 0}, /* 24 176 VK_MEDIA_NEXT_TRACK */ + {KEY_PREV_TRACK, KEY_PREV_TRACK, KEY_PREV_TRACK, KEY_PREV_TRACK, 0}, /* 25 177 VK_MEDIA_PREV_TRACK */ + {KEY_MEDIA_STOP, KEY_MEDIA_STOP, KEY_MEDIA_STOP, KEY_MEDIA_STOP, 0}, /* 26 178 VK_MEDIA_STOP */ + {KEY_PLAY_PAUSE, KEY_PLAY_PAUSE, KEY_PLAY_PAUSE, KEY_PLAY_PAUSE, 0}, /* 27 179 VK_MEDIA_PLAY_PAUSE */ + {KEY_LAUNCH_MAIL, KEY_LAUNCH_MAIL, KEY_LAUNCH_MAIL, KEY_LAUNCH_MAIL, 0}, /* 28 180 VK_LAUNCH_MAIL */ + {KEY_MEDIA_SELECT, KEY_MEDIA_SELECT, KEY_MEDIA_SELECT, KEY_MEDIA_SELECT, 0}, /* 29 181 VK_LAUNCH_MEDIA_SELECT */ + {KEY_LAUNCH_APP1, KEY_LAUNCH_APP1, KEY_LAUNCH_APP1, KEY_LAUNCH_APP1, 0}, /* 30 182 VK_LAUNCH_APP1 */ + {KEY_LAUNCH_APP2, KEY_LAUNCH_APP2, KEY_LAUNCH_APP2, KEY_LAUNCH_APP2, 0}, /* 31 183 VK_LAUNCH_APP2 */ }; HFONT PDC_get_font_handle( const int is_bold); /* pdcdisp.c */ -/* Mouse handling is done as follows: +/* Mouse handling is done as follows. Windows (*) gives us a +sequence of "raw" mouse events, which are : - What we want is a setup wherein, if the user presses and releases a -mouse button within SP->mouse_wait milliseconds, there will be a -KEY_MOUSE issued through getch( ) and the "button state" for that button -will be set to BUTTON_CLICKED. + button pressed + button released + wheel up/down/left/right + mouse moved - If the user presses and releases the button, and it takes _longer_ -than SP->mouse_wait milliseconds, then there should be a KEY_MOUSE -issued with the "button state" set to BUTTON_PRESSED. Then, later, -another KEY_MOUSE with a BUTTON_RELEASED. + We need to provide a sequence of "combined" mouse events, +in which presses and releases get combined into clicks, +double-clicks, and triple-clicks if the "raw" events are within +SP->mouse_wait milliseconds of each other and the mouse doesn't +move in between. add_mouse( ) takes the "raw" events and figures +out what "combined" events should be emitted. - To accomplish this: when a message such as WM_LBUTTONDOWN, -WM_RBUTTONDOWN, or WM_MBUTTONDOWN is issued (and more recently WM_XBUTTONDOWN -for five-button mice), we set up a timer with a period of SP->mouse_wait -milliseconds. There are then two possibilities. The user will release the -button quickly (so it's a "click") or they won't (and it's a "press/release"). + If the raw event is a press or release, we also set a timer to +trigger in SP->mouse_wait milliseconds. When that timer event is +triggered, it calls add_mouse( -1, -1, -1, -1), meaning "synthesize +all events and pass them to add_mouse_event_to_queue( )". Basically, if +we hit the timeout _or_ the mouse is moved, we can send combined events +to add_mouse_event_to_queue( ). A corresponding KEY_MOUSE event will +be added to the key queue. - In the first case, we'll get the WM_xBUTTONUP message before the -WM_TIMER one. We'll kill the timer and set up the BUTTON_CLICKED state. (*) - - In the second case, we'll get the WM_TIMER message first, so we'll -set the BUTTON_PRESSED state and kill the timer. Eventually, the user -will get around to letting go of the mouse button, and we'll get that -WM_xBUTTONUP message. At that time, we'll set the BUTTON_RELEASED state -and add the second KEY_MOUSE to the key queue. - - Also, note that if there is already a KEY_MOUSE to the queue, there's -no point in adding another one. At least at present, the actual mouse -events aren't queued anyway. So if there was, say, a click and then a -release without getch( ) being called in between, you'd then have two -KEY_MOUSEs on the queue, but would have lost all information about what -the first one actually was. Hence the code near the end of this function -to ensure there isn't already a KEY_MOUSE in the queue. + A mouse move is simply ignored if it's within the current +character cell. (Note that ncurses does provide 'mouse move' events +even if the mouse has only moved within the character cell.) Also, a note about wheel handling. Pre-Vista, you could just say "the wheel went up" or "the wheel went down". Vista introduced the possibility @@ -563,132 +577,12 @@ is that whereas before, each movement would be 120 units (the default), you might now get a series of 40-unit moves and should emit a wheel up/down event on every third move. - (*) Things are actually slightly more complicated than this. In general, -it'll just be a plain old BUTTON_CLICKED state. But if there was another -BUTTON_CLICKED within the last 2 * SP->mouse_wait milliseconds, then this -must be a _double_ click, so we set the BUTTON_DOUBLE_CLICKED state. And -if, within that time frame, there was a double or triple click, then we -set the BUTTON_TRIPLE_CLICKED state. There isn't a "quad" or higher state, -so if you quadruple-click the mouse, with each click separated by less -than 2 * SP->mouse_wait milliseconds, then the messages sent will be -BUTTON_CLICKED, BUTTON_DOUBLE_CLICKED, BUTTON_TRIPLE_CLICKED, and -then another BUTTON_TRIPLE_CLICKED. */ - -static bool mouse_key_already_in_queue( void) -{ - int i = PDC_key_queue_low; - - while( i != PDC_key_queue_high) - { - if( PDC_key_queue[i] == KEY_MOUSE) - { - debug_printf( "Mouse key already in queue\n"); - return( TRUE); - } - i = (i + 1) % KEY_QUEUE_SIZE; - } - return( FALSE); -} - -static int set_mouse( const int button_index, const int button_state, - const int x, const int y) -{ - int n_key_mouse_to_add = 1; - POINT pt; - - /* If there is already a KEY_MOUSE in the queue, we */ - /* don't really want to add another one. See above. */ - if( mouse_key_already_in_queue( )) - return( -1); - pt.x = x; - pt.y = y; - memset(&SP->mouse_status, 0, sizeof(MOUSE_STATUS)); - if( button_state == BUTTON_MOVED) - { - if( button_index < 0) - SP->mouse_status.changes = PDC_MOUSE_POSITION; - else - SP->mouse_status.changes = PDC_MOUSE_MOVED | (1 << button_index); - } - else - { - if( button_index < PDC_MAX_MOUSE_BUTTONS) - { - SP->mouse_status.button[button_index] = (short)button_state; - if( button_index < 3) - SP->mouse_status.changes = (1 << button_index); - else - SP->mouse_status.changes = (0x40 << button_index); - } - else /* actually a wheel mouse movement */ - { /* button_state = number of units moved */ - static int mouse_wheel_vertical_loc = 0; - static int mouse_wheel_horizontal_loc = 0; - const int mouse_wheel_sensitivity = 120; - - n_key_mouse_to_add = 0; - if( button_index == VERTICAL_WHEEL_EVENT) - { - mouse_wheel_vertical_loc += button_state; - while( mouse_wheel_vertical_loc > mouse_wheel_sensitivity / 2) - { - n_key_mouse_to_add++; - mouse_wheel_vertical_loc -= mouse_wheel_sensitivity; - SP->mouse_status.changes |= PDC_MOUSE_WHEEL_UP; - } - while( mouse_wheel_vertical_loc < -mouse_wheel_sensitivity / 2) - { - n_key_mouse_to_add++; - mouse_wheel_vertical_loc += mouse_wheel_sensitivity; - SP->mouse_status.changes |= PDC_MOUSE_WHEEL_DOWN; - } - } - else /* must be a horizontal event: */ - { - mouse_wheel_horizontal_loc += button_state; - while( mouse_wheel_horizontal_loc > mouse_wheel_sensitivity / 2) - { - n_key_mouse_to_add++; - mouse_wheel_horizontal_loc -= mouse_wheel_sensitivity; - SP->mouse_status.changes |= PDC_MOUSE_WHEEL_RIGHT; - } - while( mouse_wheel_horizontal_loc < -mouse_wheel_sensitivity / 2) - { - n_key_mouse_to_add++; - mouse_wheel_horizontal_loc += mouse_wheel_sensitivity; - SP->mouse_status.changes |= PDC_MOUSE_WHEEL_LEFT; - } - } - } - } - SP->mouse_status.x = pt.x; - SP->mouse_status.y = pt.y; - { - int i, button_flags = 0; - - if( GetKeyState( VK_MENU) & 0x8000) - button_flags |= PDC_BUTTON_ALT; - - if( GetKeyState( VK_SHIFT) & 0x8000) - button_flags |= PDC_BUTTON_SHIFT; - - if( GetKeyState( VK_CONTROL) & 0x8000) - button_flags |= PDC_BUTTON_CONTROL; - - for (i = 0; i < PDC_MAX_MOUSE_BUTTONS; i++) - SP->mouse_status.button[i] |= button_flags; - } - /* If the window is maximized, the click may occur just */ - /* outside the "real" screen area. If so, we again */ - /* don't want to add a key to the queue: */ - if( SP->mouse_status.x >= PDC_n_cols || SP->mouse_status.y >= PDC_n_rows) - n_key_mouse_to_add = 0; - /* OK, there isn't a KEY_MOUSE already in the queue. */ - /* So we'll add one (or zero or more, for wheel mice): */ - while( n_key_mouse_to_add--) - add_key_to_queue( KEY_MOUSE); - return( 0); -} + (*) This is not necessarily Windows-specific. The same logic should +apply in any system where a timer can be set. Or a "timer" could be +synthesized by storing the time of the last mouse event, comparing +it to the current time, and saying that if SP->mouse_wait milliseconds +have elapsed, it's time to call add_mouse( -1, -1, -1, -1) to force +all mouse events to be output. */ /* The following should be #defined in 'winuser.h', but such is */ /* not always the case. The following fixes the exceptions: */ @@ -1029,6 +923,7 @@ static void get_app_name( TCHAR *buff, const size_t buff_size, const bool includ static BOOL CALLBACK get_app_icon_callback(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG_PTR lParam) { + INTENTIONALLY_UNUSED_PARAMETER( lpszType); *((HICON *) lParam) = LoadIcon(hModule, lpszName); return FALSE; /* stop enumeration after first icon */ } @@ -1054,7 +949,7 @@ for, say, Testcurs, while having different settings for, say, Firework or Rain or one's own programs. */ INLINE int set_default_sizes_from_registry( const int n_cols, const int n_rows, - const int xloc, const int yloc, const int menu_shown) + const int xloc, const int yloc) { DWORD is_new_key; HKEY hNewKey; @@ -1212,8 +1107,8 @@ void PDC_set_resize_limits( const int new_min_lines, const int new_max_lines, /* one on each side. Vertically, we need two frame heights, plus room */ /* for the application title and the menu. */ -static void adjust_window_size( int *xpixels, int *ypixels, int window_style, - const int menu_shown) +static void adjust_window_size( int *xpixels, int *ypixels, DWORD window_style, + DWORD window_ex_style) { RECT rect; @@ -1221,7 +1116,7 @@ static void adjust_window_size( int *xpixels, int *ypixels, int window_style, rect.right = *xpixels; rect.bottom = *ypixels; /* printf( "Adjusting to %d, %d\n", *xpixels, *ypixels); */ - AdjustWindowRect( &rect, window_style, menu_shown); + AdjustWindowRectEx( &rect, window_style, menu_shown, window_ex_style); *xpixels = rect.right - rect.left; *ypixels = rect.bottom - rect.top; } @@ -1254,7 +1149,7 @@ static int keep_size_within_bounds( int *lines, int *cols) } INLINE int get_default_sizes_from_registry( int *n_cols, int *n_rows, - int *xloc, int *yloc, int *menu_shown) + int *xloc, int *yloc) { TCHAR data[100]; DWORD size_out = sizeof( data); @@ -1279,7 +1174,7 @@ INLINE int get_default_sizes_from_registry( int *n_cols, int *n_rows, my_stscanf( data, _T( "%dx%d,%d,%d,%d,%d;%d,%d,%d,%d:%n"), &x, &y, &PDC_font_size, - xloc, yloc, menu_shown, + xloc, yloc, &menu_shown, &minl, &maxl, &minc, &maxc, &bytes_read); @@ -1339,22 +1234,6 @@ INLINE void HandleSizing( WPARAM wParam, LPARAM lParam ) rect->left = rect->right - rounded_width; } -/* Under Wine, it appears that the code to force the window size to be -an integral number of columns and rows doesn't work. This is because -WM_SIZING messages aren't sent (this is apparently fixed as of Wine 1.7.18, -though I've not tried it yet; I'm still on Wine 1.6, the stable branch.) -You can therefore end up in a loop where the code keeps trying to resize a -window that isn't actually resizing. So, _when running in Wine only_, -we want that code not to be executed... which means having to figure out: -are we running under Wine? Which means that when PDCurses/WinGUI is -initialized, we set the following 'wine_version' pointer. One could -actually call wine_version(), if not NULL, to get the current Wine -version. */ - -typedef const char *(CDECL *wine_version_func)(void); - -static wine_version_func wine_version; - static void HandleSize( const WPARAM wParam, const LPARAM lParam) { static WPARAM prev_wParam = (WPARAM)-99; @@ -1364,9 +1243,6 @@ static void HandleSize( const WPARAM wParam, const LPARAM lParam) debug_printf( "WM_SIZE: wParam %x %d %d %d\n", (unsigned)wParam, n_xpixels, n_ypixels, SP->resized); -/* if( wine_version) - printf( "Wine version: %s\n", wine_version( )); */ - if( wParam == SIZE_MINIMIZED ) { @@ -1399,8 +1275,6 @@ static void HandleSize( const WPARAM wParam, const LPARAM lParam) SP->resized = TRUE; } } - else if( wine_version) - return; add_resize_key = 1; if( wParam == SIZE_RESTORED && @@ -1410,7 +1284,8 @@ static void HandleSize( const WPARAM wParam, const LPARAM lParam) int new_ypixels = PDC_cyChar * PDC_n_rows; adjust_window_size( &new_xpixels, &new_ypixels, - GetWindowLong( PDC_hWnd, GWL_STYLE), menu_shown); + GetWindowLong( PDC_hWnd, GWL_STYLE), + GetWindowLong( PDC_hWnd, GWL_EXSTYLE)); debug_printf( "Irregular size\n"); SetWindowPos( PDC_hWnd, 0, 0, 0, new_xpixels, new_ypixels, @@ -1423,13 +1298,6 @@ static void HandleSize( const WPARAM wParam, const LPARAM lParam) prev_wParam = wParam; } -static int HandleMouseMove( WPARAM wParam, LPARAM lParam) -{ - const int mouse_x = LOWORD( lParam) / PDC_cxChar; - const int mouse_y = HIWORD( lParam) / PDC_cyChar; - - return( add_mouse( 0, BUTTON_MOVED, mouse_x, mouse_y) != -1); -} static void HandlePaint( HWND hwnd ) { @@ -1473,7 +1341,6 @@ static void HandleSyskeyDown( const WPARAM wParam, const LPARAM lParam, const int alt_pressed = (GetKeyState( VK_MENU) & 0x8000); const int extended = ((lParam & 0x01000000) != 0); const int repeated = (int)( lParam >> 30) & 1; - const KPTAB *kptr = kptab + wParam; int key = 0; static int repeat_count; @@ -1507,8 +1374,14 @@ static void HandleSyskeyDown( const WPARAM wParam, const LPARAM lParam, if( !key) /* it's not a shift, ctl, alt handled above */ { + const KPTAB *kptr = kptab + wParam; + + assert( wParam < sizeof( kptab) / sizeof( kptab[0])); if( extended && kptr->extended != 999) + { + assert( kptr->extended < sizeof( ext_kptab) / sizeof( ext_kptab[0])); kptr = ext_kptab + kptr->extended; + } if( alt_pressed) key = kptr->alt; @@ -1539,6 +1412,14 @@ static void HandleSyskeyDown( const WPARAM wParam, const LPARAM lParam, key_already_handled = TRUE; } } + + if( key > ' ' && key < KEY_MIN && ctrl_pressed && !alt_pressed) + add_key_to_queue( key); + else if( shift_pressed) + { + if( (key >= '0' && key <= '9') || key == '.') + add_key_to_queue( key); /* Shift-numpad cases */ + } SP->key_modifiers = 0; /* Save the key modifiers if required. Do this first to allow to detect e.g. a pressed CTRL key after a hit of NUMLOCK. */ @@ -1559,74 +1440,34 @@ static void HandleSyskeyDown( const WPARAM wParam, const LPARAM lParam, SP->key_modifiers |= PDC_KEY_MODIFIER_REPEAT; } -/* Blinking text is supposed to blink twice a second. Therefore, -HandleTimer( ) is called every .5 seconds. - - In truth, it's not so much 'blinking' as 'changing certain types of -text' that happens. If text is really blinking (i.e., PDC_set_blink(TRUE) -has been called), we need to flip that text. Or if text _was_ blinking -and we've just called PDC_set_blink(FALSE), all that text has to be -redrawn in 'standout' mode. Also, if PDC_set_line_color() has been -called, all text with left/right/under/over/strikeout lines needs to -be redrawn. - - Also, if we've switched from rendering bold text using a bold -font to showing it in intensified color, or vice versa, then all -bold text needs to be redrawn. - - So. After determining which attributes require redrawing (if any), -we run through all of 'curscr' and look for text with those attributes -set. If we find such text, we run it through PDC_transform_line. -(To speed matters up slightly, we skip over text at the start and end -of each line that lacks the desired attributes. We could conceivably -get more clever; as it stands, if the very first and very last -characters are blinking, we redraw the entire line, even though -everything in between may not require it. But it would probably be a -lot of code for little benefit.) - - Note that by default, we'll usually find that the line color hasn't -changed and the 'blink mode' is still FALSE. In that case, attr_to_seek -will be zero and the only thing we'll do here is to blink the cursor. */ - static void HandleTimer( const WPARAM wParam ) { int i; /* see WndProc() notes */ - static attr_t prev_termattrs; - static int prev_line_color = -1; - chtype attr_to_seek = 0; - if( prev_line_color != SP->line_color) - attr_to_seek = A_ALL_LINES; - if( (SP->termattrs | prev_termattrs) & A_BLINK) - attr_to_seek |= A_BLINK; - if( (SP->termattrs ^ prev_termattrs) & A_BOLD) - attr_to_seek |= A_BOLD; - prev_line_color = SP->line_color; - prev_termattrs = SP->termattrs; + INTENTIONALLY_UNUSED_PARAMETER( wParam); PDC_blink_state ^= 1; - if( attr_to_seek) + if( SP->termattrs & A_BLINK) { for( i = 0; i < SP->lines; i++) { if( curscr->_y[i]) { - int j = 0, n_chars; + int j = 0; chtype *line = curscr->_y[i]; /* skip over starting text that isn't blinking: */ - while( j < SP->cols && !(*line & attr_to_seek)) + while( j < SP->cols) { - j++; - line++; + int k; + + while( j < SP->cols && !(line[j] & A_BLINK)) + j++; + k = j; + while( j < SP->cols && (line[j] & A_BLINK)) + j++; + if( k != j) + PDC_transform_line( i, k, j - k, line + k); } - n_chars = SP->cols - j; - /* then skip over text at the end that's not blinking: */ - while( n_chars && !(line[n_chars - 1] & attr_to_seek)) - { - n_chars--; - } - if( n_chars) - PDC_transform_line( i, j, n_chars, line); } /* else MessageBox( 0, "NULL _y[] found\n", "PDCurses", MB_OK); */ @@ -1657,7 +1498,7 @@ static HMENU set_menu( void) INLINE void HandleMenuToggle( bool *ptr_ignore_resize) { - const bool is_zoomed = IsZoomed( PDC_hWnd); + const BOOL is_zoomed = IsZoomed( PDC_hWnd); HMENU hMenu; menu_shown ^= 1; @@ -1670,9 +1511,8 @@ INLINE void HandleMenuToggle( bool *ptr_ignore_resize) if( !menu_shown) { hMenu = GetMenu( PDC_hWnd); /* destroy existing menu */ + SetMenu( PDC_hWnd, NULL); DestroyMenu( hMenu); - hMenu = CreateMenu( ); /* then set an empty menu */ - SetMenu( PDC_hWnd, hMenu); } else { @@ -1688,45 +1528,124 @@ INLINE void HandleMenuToggle( bool *ptr_ignore_resize) InvalidateRect( PDC_hWnd, NULL, FALSE); } -INLINE uint64_t milliseconds_since_1970( void) -{ - FILETIME ft; - const uint64_t jd_1601 = 2305813; /* actually 2305813.5 */ - const uint64_t jd_1970 = 2440587; /* actually 2440587.5 */ - const uint64_t ten_million = 10000000; - const uint64_t diff = (jd_1970 - jd_1601) * ten_million * 86400; - uint64_t decimicroseconds_since_1970; /* i.e., time in units of 1e-7 seconds */ - - GetSystemTimeAsFileTime( &ft); - decimicroseconds_since_1970 = ((uint64_t)ft.dwLowDateTime | - ((uint64_t)ft.dwHighDateTime << 32)) - diff; - return( decimicroseconds_since_1970 / 10000); -} - typedef struct { int x, y; int button, action; + int button_flags; /* Alt, shift, ctrl */ } PDC_mouse_event; +/* As "combined" mouse events (i.e., clicks and double- and triple-clicks +along with the usual mouse moves, button presses and releases, and wheel +movements) occur, we add them to a queue. They are removed for each +KEY_MOUSE event from getch( ), and SP->mouse_status is set to reflect +what the mouse was doing at that event. + +Seven queued mouse events is possibly overkill. */ + +#define MAX_MOUSE_QUEUE 7 + +static PDC_mouse_event mouse_queue[MAX_MOUSE_QUEUE]; +static int n_mouse_queue = 0; + +int PDC_get_mouse_event_from_queue( void) +{ + size_t i; + + if( !n_mouse_queue) + return( -1); + EnterCriticalSection(&PDC_cs); + memset(&SP->mouse_status, 0, sizeof(MOUSE_STATUS)); + if( mouse_queue->action == BUTTON_MOVED) + { + if( mouse_queue->button < 0) + SP->mouse_status.changes = PDC_MOUSE_MOVED; + else + { + SP->mouse_status.changes = PDC_MOUSE_MOVED | (1 << mouse_queue->button); + SP->mouse_status.button[mouse_queue->button] = BUTTON_MOVED; + } + } + else + { + if( mouse_queue->button < PDC_MAX_MOUSE_BUTTONS) + { + SP->mouse_status.button[mouse_queue->button] = (short)mouse_queue->action; + if( mouse_queue->button < 3) + SP->mouse_status.changes = (1 << mouse_queue->button); + else + SP->mouse_status.changes = (0x40 << mouse_queue->button); + } + else if( mouse_queue->button == WHEEL_EVENT) + SP->mouse_status.changes |= mouse_queue->action; + } + SP->mouse_status.x = mouse_queue->x; + SP->mouse_status.y = mouse_queue->y; + for (i = 0; i < PDC_MAX_MOUSE_BUTTONS; i++) + SP->mouse_status.button[i] |= mouse_queue->button_flags; + n_mouse_queue--; + memmove( mouse_queue, mouse_queue + 1, n_mouse_queue * sizeof( PDC_mouse_event)); + LeaveCriticalSection(&PDC_cs); + return( 0); +} + +static void add_mouse_event_to_queue( const int button, const int action, + const int x, const int y) +{ + if( x < PDC_n_cols && y < PDC_n_rows && n_mouse_queue < MAX_MOUSE_QUEUE) + { + int button_flags = 0; + + mouse_queue[n_mouse_queue].button = button; + mouse_queue[n_mouse_queue].action = action; + mouse_queue[n_mouse_queue].x = x; + mouse_queue[n_mouse_queue].y = y; + if( GetKeyState( VK_MENU) & 0x8000) + button_flags |= PDC_BUTTON_ALT; + + if( GetKeyState( VK_SHIFT) & 0x8000) + button_flags |= PDC_BUTTON_SHIFT; + + if( GetKeyState( VK_CONTROL) & 0x8000) + button_flags |= PDC_BUTTON_CONTROL; + mouse_queue[n_mouse_queue].button_flags = button_flags; + n_mouse_queue++; + add_key_to_queue( KEY_MOUSE); + } +} + +/* 'button_count' is zero if a button hasn't been pressed; one if it +has been; two if pressed/released (clicked); three if clicked and +pressed again... all the way up to six if it's been triple-clicked. */ + static int add_mouse( int button, const int action, const int x, const int y) { - static int n = 0; - static PDC_mouse_event e[10]; - static uint64_t prev_t = 0; - const uint64_t curr_t = milliseconds_since_1970( ); - const int timing_slop = 20; - bool within_timeout = (curr_t < prev_t + SP->mouse_wait + timing_slop); - static int mouse_state = 0; + bool flush_events_to_queue = (button == -1 || action == BUTTON_MOVED); + static int mouse_state = 0, button_count[PDC_MAX_MOUSE_BUTTONS]; static int prev_x, prev_y = -1; const bool actually_moved = (x != prev_x || y != prev_y); + size_t i; - if( action == BUTTON_MOVED && mouse_key_already_in_queue( )) - return( 0); - if( action == BUTTON_PRESSED) - mouse_state |= (1 << button); - else if( action == BUTTON_RELEASED) + if( action == BUTTON_RELEASED) + { mouse_state &= ~(1 << button); + if( !button_count[button - 1]) /* a release with no matching press */ + { + add_mouse_event_to_queue( button - 1, BUTTON_RELEASED, x, y); + return( 0); + } + else if( button_count[button - 1] & 1) + { + button_count[button - 1]++; + if( button_count[button - 1] == 6) /* triple-click completed */ + flush_events_to_queue = TRUE; + } + } + else if( action == BUTTON_PRESSED && !(button_count[button - 1] & 1)) + { + mouse_state |= (1 << button); + button_count[button - 1]++; + } if( button >= 0) { prev_x = x; @@ -1734,73 +1653,34 @@ static int add_mouse( int button, const int action, const int x, const int y) } if( action == BUTTON_MOVED) { - int i; - bool report_this_move = FALSE; - if( !actually_moved) /* have to move to a new character cell, */ return( -1); /* not just a new pixel */ button = -1; /* assume no buttons down */ - for( i = 0; i < 9; i++) + for( i = 0; i < PDC_MAX_MOUSE_BUTTONS; i++) if( (mouse_state >> i) & 1) - button = i; + button = (int)i; if( button == -1 && !(SP->_trap_mbe & REPORT_MOUSE_POSITION)) return( -1); - if( (button == 1 && (SP->_trap_mbe & BUTTON1_MOVED)) - || (button == 2 && (SP->_trap_mbe & BUTTON2_MOVED)) - || (button == 3 && (SP->_trap_mbe & BUTTON3_MOVED))) - report_this_move = TRUE; - else if( SP->_trap_mbe & REPORT_MOUSE_POSITION) - { - report_this_move = TRUE; - button = 0; - } - debug_printf( "Move button %d, (%d %d) : %d\n", button, x, y, report_this_move); - if( !report_this_move) - return( -1); } - if( !within_timeout || action == BUTTON_MOVED) - while( n && !set_mouse( e->button - 1, e->action, e->x, e->y)) - { - n--; - memmove( e, e + 1, n * sizeof( PDC_mouse_event)); - } + if( flush_events_to_queue) + for( i = 0; i < PDC_MAX_MOUSE_BUTTONS; i++) + if( button_count[i]) + { + const int events[4] = { 0, BUTTON_CLICKED, + BUTTON_DOUBLE_CLICKED, BUTTON_TRIPLE_CLICKED }; + + assert( button_count[i] > 0 && button_count[i] < 7); + if( button_count[i] >= 2) + add_mouse_event_to_queue( (int)i, events[button_count[i] / 2], prev_x, prev_y); + if( button_count[i] & 1) + add_mouse_event_to_queue( (int)i, BUTTON_PRESSED, prev_x, prev_y); + button_count[i] = 0; + } if( action == BUTTON_MOVED) - if( !set_mouse( button - 1, action, x, y)) - return( n); - if( button < 0 && action != BUTTON_MOVED) - return( n); /* we're just checking for timed-out events */ - debug_printf( "Button %d, act %d, dt %ld : n %d\n", button, action, - (long)( curr_t - prev_t), n); - e[n].button = button; - e[n].action = action; - e[n].x = x; - e[n].y = y; - if( n) - { - int merged_act = 0; - - do - { - if( e[n - 1].button == e[n].button) - { - if( e[n - 1].action == BUTTON_PRESSED && e[n].action == BUTTON_RELEASED) - merged_act = BUTTON_CLICKED; - else if( e[n - 1].action == BUTTON_CLICKED && e[n].action == BUTTON_CLICKED) - merged_act = BUTTON_DOUBLE_CLICKED; - else if( e[n - 1].action == BUTTON_DOUBLE_CLICKED && e[n].action == BUTTON_CLICKED) - merged_act = BUTTON_TRIPLE_CLICKED; - if( merged_act) - { - n--; - e[n].action = merged_act; - } - } - } while( n && merged_act); - } - prev_t = curr_t; - n++; - return( n); + add_mouse_event_to_queue( button - 1, action, x, y); + debug_printf( "Button %d, act %d\n", button, action); + return( 0); } /* Note that there are two types of WM_TIMER timer messages. One type @@ -1838,11 +1718,6 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, static bool ignore_resize = FALSE; int button = -1, action = -1; - PDC_hWnd = hwnd; - if( !hwnd) - debug_printf( "Null hWnd: msg %u, wParam %x, lParam %lx\n", - message, wParam, lParam); - switch (message) { case WM_SIZING: @@ -1852,30 +1727,71 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, case WM_SIZE: /* If ignore_resize = 1, don't bother resizing; */ /* the final window size has yet to be set */ - if( ignore_resize == FALSE) - HandleSize( wParam, lParam); + if( ignore_resize == FALSE) { + EnterCriticalSection(&PDC_cs); + HandleSize( wParam, lParam); + LeaveCriticalSection(&PDC_cs); + } return 0 ; case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: + EnterCriticalSection(&PDC_cs); { + static int mouse_wheel_vertical_loc = 0; + static int mouse_wheel_horizontal_loc = 0; + const int mouse_wheel_sensitivity = 120; POINT pt; pt.x = LOWORD( lParam); pt.y = HIWORD( lParam); ScreenToClient( hwnd, &pt); - debug_printf( "Mouse wheel: %u %x %lx\n", message, wParam, lParam); + pt.x /= PDC_cxChar; + pt.y /= PDC_cyChar; modified_key_to_return = 0; - set_mouse( (message == WM_MOUSEWHEEL) - ? VERTICAL_WHEEL_EVENT : HORIZONTAL_WHEEL_EVENT, - (short)( HIWORD(wParam)), pt.x / PDC_cxChar, pt.y / PDC_cyChar); + if( message == WM_MOUSEWHEEL) /* i.e., vertical */ + { + mouse_wheel_vertical_loc += (short)HIWORD( wParam); + while( mouse_wheel_vertical_loc > mouse_wheel_sensitivity / 2) + { + mouse_wheel_vertical_loc -= mouse_wheel_sensitivity; + add_mouse_event_to_queue( WHEEL_EVENT, PDC_MOUSE_WHEEL_UP, pt.x, pt.y); + } + while( mouse_wheel_vertical_loc < -mouse_wheel_sensitivity / 2) + { + mouse_wheel_vertical_loc += mouse_wheel_sensitivity; + add_mouse_event_to_queue( WHEEL_EVENT, PDC_MOUSE_WHEEL_DOWN, pt.x, pt.y); + } + } + else /* must be a horizontal event: */ + { + mouse_wheel_horizontal_loc += (short)HIWORD( wParam); + while( mouse_wheel_horizontal_loc > mouse_wheel_sensitivity / 2) + { + mouse_wheel_horizontal_loc -= mouse_wheel_sensitivity; + add_mouse_event_to_queue( WHEEL_EVENT, PDC_MOUSE_WHEEL_RIGHT, pt.x, pt.y); + } + while( mouse_wheel_horizontal_loc < -mouse_wheel_sensitivity / 2) + { + mouse_wheel_horizontal_loc += mouse_wheel_sensitivity; + add_mouse_event_to_queue( WHEEL_EVENT, PDC_MOUSE_WHEEL_LEFT, pt.x, pt.y); + } + } } - break; + LeaveCriticalSection(&PDC_cs); + return 0; case WM_MOUSEMOVE: - if( HandleMouseMove( wParam, lParam)) + { + const int mouse_x = LOWORD( lParam) / PDC_cxChar; + const int mouse_y = HIWORD( lParam) / PDC_cyChar; + + EnterCriticalSection(&PDC_cs); + if( add_mouse( 0, BUTTON_MOVED, mouse_x, mouse_y)) modified_key_to_return = 0; - break; + LeaveCriticalSection(&PDC_cs); + } + return 0; case WM_LBUTTONDOWN: button = 1; @@ -1936,11 +1852,14 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, /* refresh.c. I'm not entirely sure that this is what ought to be */ /* done, though it does appear to work correctly. */ case WM_PAINT: + EnterCriticalSection(&PDC_cs); HandlePaint( hwnd ); - break; + LeaveCriticalSection(&PDC_cs); + return 0; case WM_KEYUP: case WM_SYSKEYUP: + EnterCriticalSection(&PDC_cs); if( wParam == VK_MENU && numpad_unicode_value) { modified_key_to_return = numpad_unicode_value; @@ -1951,10 +1870,14 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, { add_key_to_queue( modified_key_to_return ); modified_key_to_return = 0; + LeaveCriticalSection(&PDC_cs); + return 0; } - break; + LeaveCriticalSection(&PDC_cs); + return DefWindowProc(hwnd, message, wParam, lParam); case WM_CHAR: /* _Don't_ add Shift-Tab; it's handled elsewhere */ + EnterCriticalSection(&PDC_cs); if( wParam == 3 && !SP->raw_inp) /* Ctrl-C hit */ exit( 0); if( wParam != 9 || !(GetKeyState( VK_SHIFT) & 0x8000)) @@ -1962,128 +1885,110 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, add_key_to_queue( (int)wParam ); key_already_handled = FALSE; last_key_handled = 0; - break; + LeaveCriticalSection(&PDC_cs); + return 0; case WM_KEYDOWN: case WM_SYSKEYDOWN: if( wParam < 225 && wParam > 0 ) { + EnterCriticalSection(&PDC_cs); HandleSyskeyDown( wParam, lParam, &modified_key_to_return ); + LeaveCriticalSection(&PDC_cs); + return 0; } - return 0 ; + return DefWindowProc(hwnd, message, wParam, lParam); case WM_SYSCHAR: return 0 ; case WM_TIMER: + EnterCriticalSection(&PDC_cs); if( wParam != TIMER_ID_FOR_BLINKING) { KillTimer( PDC_hWnd, (int)wParam); -#if 0 /* checkme */ - within_timeout = FALSE; -#endif + add_mouse( -1, -1, -1, -1); } else if( SP && curscr && curscr->_y) { /* blink the blinking text */ HandleTimer( wParam ); } - break; + LeaveCriticalSection(&PDC_cs); + return 0; case WM_CLOSE: + EnterCriticalSection(&PDC_cs); + if( !PDC_get_function_key( FUNCTION_KEY_SHUT_DOWN)) { - if( !PDC_shutdown_key[FUNCTION_KEY_SHUT_DOWN]) - { - final_cleanup( ); - PDC_bDone = TRUE; - exit( 0); - } - else - add_key_to_queue( PDC_shutdown_key[FUNCTION_KEY_SHUT_DOWN]); + final_cleanup( ); + /*PDC_bDone = TRUE;*/ + exit( 0); } + else + add_key_to_queue( PDC_get_function_key( FUNCTION_KEY_SHUT_DOWN)); + + LeaveCriticalSection(&PDC_cs); return( 0); case WM_COMMAND: case WM_SYSCOMMAND: if( wParam == WM_EXIT_GRACELESSLY) { + EnterCriticalSection(&PDC_cs); final_cleanup( ); - PDC_bDone = TRUE; + /*PDC_bDone = TRUE;*/ exit( 0); } else if( wParam == WM_ENLARGE_FONT || wParam == WM_SHRINK_FONT) { + EnterCriticalSection(&PDC_cs); adjust_font_size( (wParam == WM_ENLARGE_FONT) ? 1 : -1); + LeaveCriticalSection(&PDC_cs); return( 0); } else if( wParam == WM_CHOOSE_FONT) { + EnterCriticalSection(&PDC_cs); if( PDC_choose_a_new_font( )) adjust_font_size( 0); + LeaveCriticalSection(&PDC_cs); return( 0); } else if( wParam == WM_TOGGLE_MENU) { + EnterCriticalSection(&PDC_cs); HandleMenuToggle( &ignore_resize); + LeaveCriticalSection(&PDC_cs); + return 0; } - break; + return DefWindowProc(hwnd, message, wParam, lParam); case WM_DESTROY: + EnterCriticalSection(&PDC_cs); PDC_LOG(("WM_DESTROY\n")); PostQuitMessage (0) ; - PDC_bDone = TRUE; + /*PDC_bDone = TRUE;*/ + LeaveCriticalSection(&PDC_cs); return 0 ; + + default: + return DefWindowProc( hwnd, message, wParam, lParam) ; } - if( button != -1) - { - add_mouse( button, action, LOWORD( lParam) / PDC_cxChar, HIWORD( lParam) / PDC_cyChar); - if( action == BUTTON_PRESSED) - SetCapture( hwnd); - else - ReleaseCapture( ); -#if 0 /* checkme */ - SetTimer( hwnd, 0, SP->mouse_wait, NULL); -#endif - } + + /* mouse button handling code */ + assert( button != -1); + EnterCriticalSection(&PDC_cs); + + add_mouse( button, action, LOWORD( lParam) / PDC_cxChar, HIWORD( lParam) / PDC_cyChar); + if( action == BUTTON_PRESSED) + SetCapture( hwnd); else - add_mouse( -1, -1, -1, -1); - return DefWindowProc( hwnd, message, wParam, lParam) ; -} + ReleaseCapture( ); + SetTimer( hwnd, 0, SP->mouse_wait, NULL); - /* Default behaviour is that, when one clicks on the 'close' button, */ - /* exit( 0) is called, just as in the SDL and X11 versions. But if */ - /* one wishes, one can call PDC_set_shutdown_key to cause those */ - /* buttons to put a specified character into the input queue. It's */ - /* then the application's problem to exit gracefully, perhaps with */ - /* messages such as 'are you sure' and so forth. */ - /* If you've set a shutdown key, there's always a risk that the */ - /* program will get stuck in a loop and never process said key. So */ - /* when the key is set, a 'Kill' item is appended to the system menu */ - /* so that the user still has some way to terminate the app, albeit */ - /* with extreme prejudice (i.e., click on 'Kill' and exit is called */ - /* and the app exits gracelessly.) */ - -int PDC_set_function_key( const unsigned function, const int new_key) -{ - int old_key = -1; - - if( function < PDC_MAX_FUNCTION_KEYS) - { - old_key = PDC_shutdown_key[function]; - PDC_shutdown_key[function] = new_key; - } - - if( function == FUNCTION_KEY_SHUT_DOWN) - if( (new_key && !old_key) || (old_key && !new_key)) - { - HMENU hMenu = GetSystemMenu( PDC_hWnd, FALSE); - - if( new_key) - AppendMenu( hMenu, MF_STRING, WM_EXIT_GRACELESSLY, _T( "Kill")); - else - RemoveMenu( hMenu, WM_EXIT_GRACELESSLY, MF_BYCOMMAND); - } - return( old_key); + LeaveCriticalSection(&PDC_cs); + return 0; } /* Used to define whether or not the Font/Paste menu is visible by default. @@ -2141,6 +2046,79 @@ static void clip_or_center_window_to_monitor( HWND hwnd) } #endif +struct PDC_WININFO { + HANDLE hInstance; + int xsize; + int ysize; + DWORD window_style; + DWORD window_ex_style; + int xloc; + int yloc; + TCHAR WindowTitle[MAX_PATH]; +}; + +static const TCHAR *AppName = _T( "Curses_App"); +static HANDLE winthr_ready; + +/* Thread that creates and manages the WinGUI window. + The return type (and declared type of winthr_id) is uint32_t instead of + DWORD to avoid compiler warnings. */ + +static uint32_t WINAPI window_thread(LPVOID lpParameter) +{ + MSG msg; + HMENU hMenu; + struct PDC_WININFO *winfo = (struct PDC_WININFO *) lpParameter; + BOOL rval; + + PDC_hWnd = CreateWindowEx(winfo->window_ex_style, AppName, + winfo->WindowTitle, winfo->window_style, + winfo->xloc, winfo->yloc, + winfo->xsize, winfo->ysize, + NULL, (menu_shown ? set_menu( ) : NULL), + winfo->hInstance, NULL) ; + + if( !PDC_hWnd) + { + const DWORD last_error = GetLastError( ); + + debug_printf( "CreateWindow failed; GetLastError = %ld", last_error); + return( 2); + } + + hMenu = GetSystemMenu( PDC_hWnd, FALSE); + AppendMenu( hMenu, MF_STRING | (menu_shown ? MF_CHECKED : MF_UNCHECKED), WM_TOGGLE_MENU, _T( "Menu")); + AppendMenu( hMenu, MF_STRING, WM_CHOOSE_FONT, _T( "Choose Font")); + + debug_printf( "menu set\n"); + + ShowWindow (PDC_hWnd, + (winfo->window_style & WS_MAXIMIZE) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL); + debug_printf( "window shown\n"); + UpdateWindow (PDC_hWnd) ; + debug_printf( "window updated\n"); + SetTimer( PDC_hWnd, TIMER_ID_FOR_BLINKING, 500, NULL); + debug_printf( "timer set\n"); + +#if defined( MONITOR_DEFAULTTONEAREST) && WINVER >= 0x0410 + /* if the window is off-screen, move it on screen. */ + clip_or_center_window_to_monitor( PDC_hWnd); +#endif + + SetEvent(winthr_ready); + + while ((rval = GetMessage(&msg, NULL, 0, 0)) == TRUE) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + if (rval == -1) { + debug_printf("GetMessage() error: GetLastError = %lu\n", GetLastError()); + return 1; + } + return 0; +} + /* By default, the user cannot resize the window. This is because many apps don't handle KEY_RESIZE, and one can get odd behavior in such cases. There are two ways around this. If you call @@ -2165,30 +2143,34 @@ INLINE int set_up_window( void) { /* create the dialog window */ WNDCLASS wndclass ; - HMENU hMenu; HANDLE hInstance = GetModuleHandle( NULL); int n_default_columns = 80; int n_default_rows = 25; - int xsize, ysize, window_style; - int xloc = CW_USEDEFAULT; - int yloc = CW_USEDEFAULT; - TCHAR WindowTitle[MAX_PATH]; - const TCHAR *AppName = _T( "Curses_App"); + struct PDC_WININFO winfo; HICON icon; - static bool wndclass_has_been_registered = FALSE; + /*static bool wndclass_has_been_registered = FALSE;*/ + HANDLE winthr_h; + HANDLE hWait[2]; + DWORD winthr_status; if( !hInstance) debug_printf( "No instance: %d\n", GetLastError( )); + + winfo.hInstance = hInstance; + winfo.xloc = CW_USEDEFAULT; + winfo.yloc = CW_USEDEFAULT; + originally_focussed_window = GetForegroundWindow( ); debug_printf( "hInstance %x\nOriginal window %x\n", hInstance, originally_focussed_window); - /* set the window icon from the icon in the process */ - icon = get_app_icon(hInstance); - if( !icon ) - icon = LoadIcon( NULL, IDI_APPLICATION); - if( !wndclass_has_been_registered) + /*if( !wndclass_has_been_registered)*/ { ATOM rval; + /* set the window icon from the icon in the process */ + icon = get_app_icon(hInstance); + if( !icon ) + icon = LoadIcon( NULL, IDI_APPLICATION); + wndclass.style = CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; @@ -2208,12 +2190,12 @@ INLINE int set_up_window( void) debug_printf( "RegisterClass failed: GetLastError = %lx\n", last_error); return( -1); } - wndclass_has_been_registered = TRUE; + /*wndclass_has_been_registered = TRUE;*/ } - get_app_name( WindowTitle, MAX_PATH, TRUE); + get_app_name( winfo.WindowTitle, MAX_PATH, TRUE); #ifdef PDC_WIDE - debug_printf( "WindowTitle = '%ls'\n", WindowTitle); + debug_printf( "WindowTitle = '%ls'\n", winfo.WindowTitle); #endif if( PDC_n_rows > 2 && PDC_n_cols > 2) @@ -2222,8 +2204,8 @@ INLINE int set_up_window( void) n_default_rows = PDC_n_rows; } - get_default_sizes_from_registry( &n_default_columns, &n_default_rows, &xloc, &yloc, - &menu_shown); + get_default_sizes_from_registry( &n_default_columns, &n_default_rows, + &winfo.xloc, &winfo.yloc, &menu_shown); if( ttytype[1]) PDC_set_resize_limits( (unsigned char)ttytype[0], @@ -2231,57 +2213,55 @@ INLINE int set_up_window( void) (unsigned char)ttytype[2], (unsigned char)ttytype[3]); debug_printf( "Size %d x %d, loc %d x %d; menu %d\n", - n_default_columns, n_default_rows, xloc, yloc, menu_shown); + n_default_columns, n_default_rows, winfo.xloc, winfo.yloc, menu_shown); get_character_sizes( NULL, &PDC_cxChar, &PDC_cyChar); if( min_lines != max_lines || min_cols != max_cols) - window_style = ((n_default_columns == -1) ? + winfo.window_style = ((n_default_columns == -1) ? WS_MAXIMIZE | WS_OVERLAPPEDWINDOW : WS_OVERLAPPEDWINDOW); else /* fixed-size window: looks "normal", but w/o a maximize box */ - window_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + winfo.window_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + + winfo.window_ex_style = WS_EX_CLIENTEDGE; if( n_default_columns == -1) - xsize = ysize = CW_USEDEFAULT; + winfo.xsize = winfo.ysize = CW_USEDEFAULT; else { keep_size_within_bounds( &n_default_rows, &n_default_columns); - xsize = PDC_cxChar * n_default_columns; - ysize = PDC_cyChar * n_default_rows; - adjust_window_size( &xsize, &ysize, window_style, menu_shown); + winfo.xsize = PDC_cxChar * n_default_columns; + winfo.ysize = PDC_cyChar * n_default_rows; + adjust_window_size( &winfo.xsize, &winfo.ysize, winfo.window_style, + winfo.window_ex_style); } - PDC_hWnd = CreateWindow( AppName, WindowTitle, window_style, - xloc, yloc, - xsize, ysize, - NULL, (menu_shown ? set_menu( ) : NULL), - hInstance, NULL) ; - - if( !PDC_hWnd) - { - const DWORD last_error = GetLastError( ); - - debug_printf( "CreateWindow failed; GetLastError = %ld", last_error); - return( -2); + InitializeCriticalSection(&PDC_cs); + winthr_ready = CreateEvent(NULL, FALSE, FALSE, NULL); + winthr_h = (HANDLE) _beginthreadex(NULL, 0, window_thread, &winfo, 0, &winthr_id); + if (winthr_h == (HANDLE) 0) { + debug_printf("_beginthreadex() failed: %s\n", strerror(errno)); + DeleteCriticalSection(&PDC_cs); + CloseHandle(winthr_ready); + CloseHandle(winthr_h); + return -1; } - hMenu = GetSystemMenu( PDC_hWnd, FALSE); - AppendMenu( hMenu, MF_STRING | (menu_shown ? MF_CHECKED : MF_UNCHECKED), WM_TOGGLE_MENU, _T( "Menu")); - AppendMenu( hMenu, MF_STRING, WM_CHOOSE_FONT, _T( "Choose Font")); - - debug_printf( "menu set\n"); - - ShowWindow (PDC_hWnd, - (n_default_columns == -1) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL); - debug_printf( "window shown\n"); - UpdateWindow (PDC_hWnd) ; - debug_printf( "window updated\n"); - SetTimer( PDC_hWnd, TIMER_ID_FOR_BLINKING, 500, NULL); - debug_printf( "timer set\n"); - -#if defined( MONITOR_DEFAULTTONEAREST) && WINVER >= 0x0410 - /* if the window is off-screen, move it on screen. */ - clip_or_center_window_to_monitor( PDC_hWnd); -#endif + hWait[0] = winthr_ready; + hWait[1] = winthr_h; + WaitForMultipleObjects(2, hWait, FALSE, INFINITE); + CloseHandle(winthr_ready); + if (!GetExitCodeThread(winthr_h, &winthr_status)) { + debug_printf("GetExitCodeThread() failed: GetLastError = %lu\n", GetLastError()); + DeleteCriticalSection(&PDC_cs); + CloseHandle(winthr_h); + return -1; + } + CloseHandle(winthr_h); + if (winthr_status != STILL_ACTIVE) { + debug_printf("Premature window_thread termination: exit code = %lu\n", winthr_status); + DeleteCriticalSection(&PDC_cs); + return winthr_status; + } return( 0); } @@ -2301,11 +2281,6 @@ INLINE int set_up_window( void) int PDC_scr_open(void) { - HMODULE hntdll = GetModuleHandle( _T("ntdll.dll")); - - if( hntdll) - wine_version = (wine_version_func)GetProcAddress(hntdll, "wine_get_version"); - PDC_LOG(("PDC_scr_open() - called\n")); COLORS = N_COLORS; /* should give this a try and see if it works! */ if (!SP || PDC_init_palette( )) @@ -2346,6 +2321,8 @@ int PDC_scr_open(void) while( !PDC_get_rows( )) /* wait for screen to be drawn and */ ; /* actual size to be determined */ + EnterCriticalSection(&PDC_cs); + debug_printf( "Back from PDC_get_rows\n"); SP->lines = PDC_get_rows(); SP->cols = PDC_get_columns(); @@ -2362,6 +2339,7 @@ int PDC_scr_open(void) } /* PDC_reset_prog_mode(); doesn't do anything anyway */ + PDC_set_function_key( FUNCTION_KEY_COPY, 0); debug_printf( "...we're done\n"); return OK; } @@ -2393,11 +2371,19 @@ int PDC_resize_screen( int nlines, int ncols) if( new_width != client_rect.right || new_height != client_rect.bottom) { /* check to make sure size actually changed */ + DWORD thr_id = GetCurrentThreadId(); add_resize_key = 0; + + if (thr_id != winthr_id) + LeaveCriticalSection(&PDC_cs); + SetWindowPos( PDC_hWnd, 0, 0, 0, new_width + (rect.right - rect.left) - client_rect.right, new_height + (rect.bottom - rect.top) - client_rect.bottom, SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW); + + if (thr_id != winthr_id) + EnterCriticalSection(&PDC_cs); } } return OK; @@ -2421,21 +2407,12 @@ void PDC_reset_shell_mode(void) void PDC_restore_screen_mode(int i) { + INTENTIONALLY_UNUSED_PARAMETER( i); } void PDC_save_screen_mode(int i) { -} - -/* NOTE: as with PDC_init_color() (see below), this function has to -redraw all text with color attribute 'pair' to match the newly-set -foreground and background colors. The loops to go through every character -in curscr, looking for those that need to be redrawn and ignoring -those at the front and start of each line, are very similar. */ - -static int get_pair( const chtype ch) -{ - return( (int)( (ch & A_COLOR) >> PDC_COLOR_SHIFT)); + INTENTIONALLY_UNUSED_PARAMETER( i); } bool PDC_can_change_color(void) @@ -2454,63 +2431,16 @@ int PDC_color_content( int color, int *red, int *green, int *blue) return OK; } -/* We have an odd problem when changing colors with PDC_init_color(). On -palette-based systems, you just change the palette and the hardware takes -care of the rest. Here, though, we actually need to redraw any text that's -drawn in the specified color. So we gotta look at each character and see if -either the foreground or background matches the index that we're changing. -Then, that text gets redrawn. For speed/simplicity, the code looks for the -first and last character in each line that would be affected, then draws those -in between (frequently, this will be zero characters, i.e., no text on that -particular line happens to use the color index in question.) See similar code -above for PDC_init_pair(), to handle basically the same problem. */ - -static int color_used_for_this_char( const chtype c, const int idx) -{ - const int color = get_pair( c); - int fg, bg; - int rval; - - extended_pair_content( color, &fg, &bg); - rval = (fg == idx || bg == idx); - return( rval); -} - int PDC_init_color( int color, int red, int green, int blue) { const COLORREF new_rgb = RGB(DIVROUND(red * 255, 1000), DIVROUND(green * 255, 1000), DIVROUND(blue * 255, 1000)); - if( !PDC_set_palette_entry( color, new_rgb)) - { - /* Possibly go through curscr and redraw everything with that color! */ - if( curscr && curscr->_y) - { - int i; - - for( i = 0; i < SP->lines; i++) - if( curscr->_y[i]) - { - int j = 0, n_chars; - chtype *line = curscr->_y[i]; - - /* skip over starting text that isn't of the desired color: */ - while( j < SP->cols - && !color_used_for_this_char( *line, color)) - { - j++; - line++; - } - n_chars = SP->cols - j; - /* then skip over text at the end that's not the right color: */ - while( n_chars && - !color_used_for_this_char( line[n_chars - 1], color)) - n_chars--; - if( n_chars) - PDC_transform_line( i, j, n_chars, line); - } - } - } + PDC_set_palette_entry( color, new_rgb); return OK; } + +void PDC_free_platform_dependent_memory( void) +{ +} diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdcsetsc.c b/src/3rdparty/win32_src/pdcurses/wingui/pdcsetsc.c index 7d8d240c3..3b2f1cab5 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdcsetsc.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdcsetsc.c @@ -1,5 +1,6 @@ /* Public Domain Curses */ +#include #include "pdcwin.h" #include "pdccolor.h" @@ -59,17 +60,20 @@ int PDC_curs_set(int visibility) void PDC_set_title(const char *title) { extern HWND PDC_hWnd; + extern CRITICAL_SECTION PDC_cs; #ifdef PDC_WIDE wchar_t wtitle[512]; #endif PDC_LOG(("PDC_set_title() - called:<%s>\n", title)); + LeaveCriticalSection(&PDC_cs); #ifdef PDC_WIDE PDC_mbstowcs(wtitle, title, 511); SetWindowTextW( PDC_hWnd, wtitle); #else SetWindowTextA( PDC_hWnd, title); #endif + EnterCriticalSection(&PDC_cs); } /* If SP->termattrs & A_BLINK is on, then text with the A_BLINK */ @@ -89,15 +93,26 @@ void PDC_set_title(const char *title) /* the user _must_ pay attention; say, "the nuclear reactor */ /* is about to melt down". Otherwise, the bolder, brighter */ /* text should be attention-getting enough. */ + /* Note also that when turning 'blink' On, we don't have to */ + /* mark curscr as needing to be cleared. Blinking will begin */ + /* within half a second anyway. (This is an exception to the */ + /* general rule that changes only take place after refresh().) */ static int reset_attr( const attr_t attr, const bool attron) { + attr_t prev_termattrs; + + assert( SP); if (!SP) return ERR; + prev_termattrs = SP->termattrs; if( attron) SP->termattrs |= attr; else SP->termattrs &= ~attr; + if( prev_termattrs != SP->termattrs) + if( !attron || attr == A_BOLD) + curscr->_clear = TRUE; return OK; } diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdcutil.c b/src/3rdparty/win32_src/pdcurses/wingui/pdcutil.c index 8e0a23344..59959e0e6 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdcutil.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdcutil.c @@ -1,42 +1,45 @@ /* Public Domain Curses */ #include "pdcwin.h" +#ifdef WIN32_LEAN_AND_MEAN +#include +#include +#endif + +extern CRITICAL_SECTION PDC_cs; + +static volatile int _beep_count = 0; + +static void beep_thread(LPVOID lpParameter) +{ + INTENTIONALLY_UNUSED_PARAMETER( lpParameter); + while( _beep_count) + { + if (!PlaySound((LPCTSTR) SND_ALIAS_SYSTEMDEFAULT, NULL, SND_ALIAS_ID)) + Beep(800, 200); + _beep_count--; + } +} void PDC_beep(void) { PDC_LOG(("PDC_beep() - called\n")); - -/* MessageBeep(MB_OK); */ - MessageBeep(0XFFFFFFFF); + _beep_count++; + if( _beep_count == 1) + _beginthread( beep_thread, 0, NULL); } void PDC_napms(int ms) /* 'ms' = milli, _not_ microseconds! */ { /* RR: keep GUI window responsive while PDCurses sleeps */ - MSG msg; - DWORD curr_ms = GetTickCount( ); - const DWORD milliseconds_sleep_limit = ms + curr_ms; - extern bool PDC_bDone; PDC_LOG(("PDC_napms() - called: ms=%d\n", ms)); - /* Pump all pending messages from WIN32 to the window handler */ - while( !PDC_bDone && curr_ms < milliseconds_sleep_limit ) + if( ms) { - const DWORD max_sleep_ms = 50; /* check msgs 20 times/second */ - DWORD sleep_millisecs; - - while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - curr_ms = GetTickCount( ); - sleep_millisecs = milliseconds_sleep_limit - curr_ms; - if( sleep_millisecs > max_sleep_ms) - sleep_millisecs = max_sleep_ms; - Sleep( sleep_millisecs); - curr_ms += sleep_millisecs; + LeaveCriticalSection(&PDC_cs); + Sleep(ms); + EnterCriticalSection(&PDC_cs); } } diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdcwin.h b/src/3rdparty/win32_src/pdcurses/wingui/pdcwin.h index ccba0f17a..094e36a09 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdcwin.h +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdcwin.h @@ -2,6 +2,14 @@ /* $Id: pdcwin.h,v 1.6 2008/07/13 06:36:32 wmcbrine Exp $ */ +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE 1 /* kill nonsense warnings */ +#endif + +#if defined( PDC_FORCE_UTF8) && !defined( PDC_WIDE) + #define PDC_WIDE +#endif + #ifdef PDC_WIDE #if !defined( UNICODE) # define UNICODE @@ -11,10 +19,6 @@ #endif #endif -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE 1 /* kill nonsense warnings */ -#endif - #define WIN32_LEAN_AND_MEAN #include @@ -78,50 +82,4 @@ the PDC_CURSOR macro for this, as in... #define PDC_CURSOR( A, B) ((A)<<8 | (B)) #define PDC_CURSOR_IS_BLINKING \ - ((SP->visibility >> 8) != (SP->visibility & 0xff)) - -/* With 64-bit chtypes, we're allowing 20 bits for the character -(thus Unicode values up to 0xffffff) plus one bit to indicate the -alternate character set. With 32-bit chtypes, we don't have so -many bits to play with and limit ourselves to 16-bit characters -(i.e., Unicode past 0xffff can't be shown), plus that one bit -for alternate chars. With 16-bit chtypes, there are only eight -bits available to the character. PDC_REAL_ATTR_SHIFT gives the -number of low bits devoted to storing characters. */ - -# ifdef CHTYPE_32 - # define PDC_REAL_ATTR_SHIFT 17 -#else /* 64-bit chtypes */ - # define PDC_REAL_ATTR_SHIFT 21 -#endif - - /* The PDC_set_function_key() function allows one to set a 'shut down' -key, and reassign hotkeys used for pasting from the clipboard and -enlarging and decreasing the font size, and for using the font selection -dialog. For example, calling - -PDC_set_function_key( FUNCTION_KEY_SHUT_DOWN, ALT_Q); - -would reset the library so that, if the user clicks on the 'close' box, -Alt-Q would be added to the key queue. This would give the app the -opportunity to shut things down (and perhaps ask "are you sure", and/or -"save changes or discard or cancel"), rather than just having the -window close (the default behavior). - - Also, by default, Ctrl-V "pastes" the clipboard into the key queue, -and Ctrl-Equals brings up the font selection dialog. But one could -call, for example, - -PDC_set_function_key( FUNCTION_KEY_PASTE, CTL_Z); - - to reset the "paste" key to be Ctrl-Z. Or one could call - -PDC_set_function_key( FUNCTION_KEY_PASTE, 0); - - to shut off that function. (It would still be accessible from the menu.) - - Thus far, this is a WinGUI-flavor specific function. But it could, and -in my opinion should, be made available in the SDL and XCurses flavors too. - - The return value is the key previously used for that function. -*/ + ((SP->visibility >> 8) != (SP->visibility & 0xff)) \ No newline at end of file diff --git a/src/musikcube/cursespp/App.cpp b/src/musikcube/cursespp/App.cpp index d53554842..ca6445bcc 100755 --- a/src/musikcube/cursespp/App.cpp +++ b/src/musikcube/cursespp/App.cpp @@ -120,7 +120,7 @@ generate button click events for Window instances to handle. beware: kludge and hacks below... */ struct MouseButtonState { bool Update(const MEVENT& rawEvent) { - const int state = rawEvent.bstate; + const mmask_t state = rawEvent.bstate; const int x = rawEvent.x; const int y = rawEvent.y; bool result = false; @@ -300,7 +300,6 @@ void App::InitCurses() { /* needs to happen after initscr() */ PDC_set_default_menu_visibility(0); PDC_set_title(this->appTitle.c_str()); - PDC_set_color_intensify_enabled(false); win32::InterceptWndProc(); win32::SetAppTitle(this->appTitle); if (this->iconId) { diff --git a/src/musikcube/musikcube.vcxproj b/src/musikcube/musikcube.vcxproj index e7abcbb63..3fc2083be 100755 --- a/src/musikcube/musikcube.vcxproj +++ b/src/musikcube/musikcube.vcxproj @@ -303,7 +303,7 @@ MachineX86 - pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;libcurl.lib;libssl-1_1.lib;libcrypto-1_1.lib;%(AdditionalDependencies) + pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;Winmm.lib;libcurl.lib;libssl-1_1.lib;libcrypto-1_1.lib;%(AdditionalDependencies) false @@ -349,7 +349,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win\font\*.ttf" "$(TargetDir)fonts\" /Y /e MachineX86 - pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;libcurl.lib;libssl-1_1.lib;libcrypto-1_1.lib;%(AdditionalDependencies) + pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;Winmm.lib;libcurl.lib;libssl-1_1.lib;libcrypto-1_1.lib;%(AdditionalDependencies) false @@ -395,7 +395,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win\font\*.ttf" "$(TargetDir)fonts\" /Y /e MachineX86 - pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;libcurl.lib;libssl-1_1.lib;libcrypto-1_1.lib;%(AdditionalDependencies) + pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;Winmm.lib;libcurl.lib;libssl-1_1.lib;libcrypto-1_1.lib;%(AdditionalDependencies) false @@ -439,7 +439,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win\font\*.ttf" "$(TargetDir)fonts\" /Y /e Windows - pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;libcurl.lib;libssl-1_1-x64.lib;libcrypto-1_1-x64.lib;%(AdditionalDependencies) + pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;Winmm.lib;libcurl.lib;libssl-1_1-x64.lib;libcrypto-1_1-x64.lib;%(AdditionalDependencies) false @@ -483,7 +483,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win\font\*.ttf" "$(TargetDir)fonts\" /Y /e Windows - pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;libcurl.lib;libssl-1_1-x64.lib;libcrypto-1_1-x64.lib;%(AdditionalDependencies) + pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;Winmm.lib;libcurl.lib;libssl-1_1-x64.lib;libcrypto-1_1-x64.lib;%(AdditionalDependencies) false @@ -527,7 +527,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win\font\*.ttf" "$(TargetDir)fonts\" /Y /e Console - pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;libcurl.lib;libssl-1_1-x64.lib;libcrypto-1_1-x64.lib;%(AdditionalDependencies) + pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;Winmm.lib;libcurl.lib;libssl-1_1-x64.lib;libcrypto-1_1-x64.lib;%(AdditionalDependencies) false @@ -579,7 +579,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win\font\*.ttf" "$(TargetDir)fonts\" /Y /e MachineX86 - pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;libcurl.lib;libssl-1_1.lib;libcrypto-1_1.lib;%(AdditionalDependencies) + pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;Winmm.lib;libcurl.lib;libssl-1_1.lib;libcrypto-1_1.lib;%(AdditionalDependencies) true @@ -631,7 +631,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win\font\*.ttf" "$(TargetDir)fonts\" /Y /e MachineX86 - pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;libcurl.lib;libssl-1_1.lib;libcrypto-1_1.lib;%(AdditionalDependencies) + pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;Winmm.lib;libcurl.lib;libssl-1_1.lib;libcrypto-1_1.lib;%(AdditionalDependencies) true @@ -683,7 +683,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win\font\*.ttf" "$(TargetDir)fonts\" /Y /e MachineX86 - pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;libcurl.lib;libssl-1_1.lib;libcrypto-1_1.lib;%(AdditionalDependencies) + pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;Winmm.lib;libcurl.lib;libssl-1_1.lib;libcrypto-1_1.lib;%(AdditionalDependencies) true @@ -734,7 +734,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win\font\*.ttf" "$(TargetDir)fonts\" /Y /e - pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;libcurl.lib;libssl-1_1-x64.lib;libcrypto-1_1-x64.lib;%(AdditionalDependencies) + pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;Winmm.lib;libcurl.lib;libssl-1_1-x64.lib;libcrypto-1_1-x64.lib;%(AdditionalDependencies) false @@ -785,7 +785,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win\font\*.ttf" "$(TargetDir)fonts\" /Y /e - pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;libcurl.lib;libssl-1_1-x64.lib;libcrypto-1_1-x64.lib;%(AdditionalDependencies) + pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;Winmm.lib;libcurl.lib;libssl-1_1-x64.lib;libcrypto-1_1-x64.lib;%(AdditionalDependencies) false @@ -836,7 +836,7 @@ xcopy "$(SolutionDir)src\3rdparty\bin\win\font\*.ttf" "$(TargetDir)fonts\" /Y /e - pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;libcurl.lib;libssl-1_1-x64.lib;libcrypto-1_1-x64.lib;%(AdditionalDependencies) + pdh.lib;psapi.lib;Ws2_32.lib;wldap32.lib;Comctl32.lib;Winmm.lib;libcurl.lib;libssl-1_1-x64.lib;libcrypto-1_1-x64.lib;%(AdditionalDependencies) false From f8a7e43a7517b3570498ebe55175786196945c36 Mon Sep 17 00:00:00 2001 From: casey langen Date: Sun, 24 Jul 2022 15:06:55 -0700 Subject: [PATCH 2/6] Reverted multi-threaded PDCurses changes, added a couple tweaks to make resizing work better. --- src/3rdparty/win32_include/curses.h | 3 + .../win32_src/pdcurses/wingui/pdcdisp.c | 5 +- .../win32_src/pdcurses/wingui/pdckbd.c | 11 +- .../win32_src/pdcurses/wingui/pdcscrn.c | 328 +++++------------- .../win32_src/pdcurses/wingui/pdcsetsc.c | 3 - .../win32_src/pdcurses/wingui/pdcutil.c | 26 +- src/musikcube/cursespp/App.cpp | 34 +- src/musikcube/cursespp/cursespp/App.h | 1 + 8 files changed, 148 insertions(+), 263 deletions(-) diff --git a/src/3rdparty/win32_include/curses.h b/src/3rdparty/win32_include/curses.h index 532c3edfb..aba348c98 100755 --- a/src/3rdparty/win32_include/curses.h +++ b/src/3rdparty/win32_include/curses.h @@ -1780,7 +1780,10 @@ PDCEX int PDC_set_function_key( const unsigned function, const int new_key); PDCEX int PDC_get_function_key( const unsigned function); +PDCEX void PDC_set_window_resized_callback(void (*callback)()); + PDCEX int PDC_set_preferred_fontface( const wchar_t* fontface); +PDCEX void PDC_set_color_intensify_enabled( bool enabled); PDCEX void PDC_set_default_menu_visibility(int visible); PDCEX WINDOW *Xinitscr(int, char **); diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdcdisp.c b/src/3rdparty/win32_src/pdcurses/wingui/pdcdisp.c index 474ff25d1..ad818cfff 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdcdisp.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdcdisp.c @@ -235,7 +235,7 @@ their preferred one. If that font fails to load, we will fallback to the global default (currently "Courier New") */ int PDC_set_preferred_fontface( const TCHAR* fontface) { - int len = fontface == 0 ? 0 : wcslen( fontface); + int len = fontface == 0 ? 0 : (int) wcslen( fontface); if ( len < sizeof( PDC_preferred_fontface)) { wcsncpy( PDC_preferred_fontface, fontface, len); @@ -326,7 +326,6 @@ int PDC_choose_a_new_font( void) CHOOSEFONT cf; int rval; extern HWND PDC_hWnd; - extern CRITICAL_SECTION PDC_cs; lf.lfHeight = -PDC_font_size; debug_printf( "In PDC_choose_a_new_font: %d\n", lf.lfHeight); @@ -335,9 +334,7 @@ int PDC_choose_a_new_font( void) cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_SELECTSCRIPT; cf.hwndOwner = PDC_hWnd; cf.lpLogFont = &lf; - LeaveCriticalSection(&PDC_cs); rval = ChooseFont( &cf); - EnterCriticalSection(&PDC_cs); if( rval) { #ifdef PDC_WIDE wcscpy( PDC_font_name, lf.lfFaceName); diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdckbd.c b/src/3rdparty/win32_src/pdcurses/wingui/pdckbd.c index 7cd9e2f96..72a96a425 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdckbd.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdckbd.c @@ -17,13 +17,14 @@ void PDC_set_keyboard_binary(bool on) extern int PDC_key_queue_low, PDC_key_queue_high; extern int PDC_key_queue[KEY_QUEUE_SIZE]; +/* PDCurses message/event callback */ +/* Calling PDC_napms for one millisecond ensures that the message loop */ +/* is called and messages in general, and keyboard events in particular, */ +/* get processed. */ + bool PDC_check_key(void) { - extern CRITICAL_SECTION PDC_cs; - - LeaveCriticalSection(&PDC_cs); - SwitchToThread( ); - EnterCriticalSection(&PDC_cs); + PDC_napms( 1); if( PDC_key_queue_low != PDC_key_queue_high) return TRUE; return FALSE; diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c b/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c index 2119e93aa..bf078cc73 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "pdccolor.h" #ifdef WIN32_LEAN_AND_MEAN #ifdef PDC_WIDE @@ -67,7 +66,7 @@ cube of 16 million colors. */ int PDC_show_ctrl_alts = 0; /* RR: Removed statis on next line */ -/*bool PDC_bDone = FALSE;*/ +bool PDC_bDone = FALSE; static HWND originally_focussed_window; int debug_printf( const char *format, ...) @@ -105,8 +104,6 @@ int debug_printf( const char *format, ...) HWND PDC_hWnd; static int PDC_argc = 0; static char **PDC_argv = NULL; -uint32_t winthr_id = 0; -CRITICAL_SECTION PDC_cs; static void final_cleanup( void) { @@ -143,7 +140,7 @@ void PDC_scr_close(void) { PDC_LOG(("PDC_scr_close() - called\n")); final_cleanup( ); - /*PDC_bDone = TRUE;*/ + PDC_bDone = TRUE; } /* NOTE that PDC_scr_free( ) is called only from delscreen( ), */ @@ -985,35 +982,6 @@ INLINE int set_default_sizes_from_registry( const int n_cols, const int n_rows, return( rval != ERROR_SUCCESS); } -/* If the window is maximized, there will usually be a fractional -character width at the right and bottom edges. The following code fills -that in with a black brush. It takes the "paint rectangle", the area -passed with a WM_PAINT message that specifies what chunk of the client -area needs to be redrawn. - - If the window is _not_ maximized, this shouldn't happen; the window -width/height should always be an integral multiple of the character -width/height, with no slivers at the right and bottom edges. */ - -static void fix_up_edges( const HDC hdc, const RECT *rect) -{ - const int x = PDC_n_cols * PDC_cxChar; - const int y = PDC_n_rows * PDC_cyChar; - - if( rect->right >= x || rect->bottom >= y) - { - const HBRUSH hOldBrush = - SelectObject( hdc, GetStockObject( BLACK_BRUSH)); - - SelectObject( hdc, GetStockObject( NULL_PEN)); - if( rect->right >= x) - Rectangle( hdc, x, rect->top, rect->right + 1, rect->bottom + 1); - if( rect->bottom >= y) - Rectangle( hdc, rect->left, y, rect->right + 1, rect->bottom + 1); - SelectObject( hdc, hOldBrush); - } -} - static void adjust_font_size( const int font_size_change) { extern int PDC_font_size; @@ -1045,7 +1013,7 @@ static void adjust_font_size( const int font_size_change) SP->resized = TRUE; hdc = GetDC (PDC_hWnd) ; GetClientRect( PDC_hWnd, &client_rect); - fix_up_edges( hdc, &client_rect); + InvalidateRect(PDC_hWnd, &client_rect, TRUE); ReleaseDC( PDC_hWnd, hdc) ; } else @@ -1149,7 +1117,7 @@ static int keep_size_within_bounds( int *lines, int *cols) } INLINE int get_default_sizes_from_registry( int *n_cols, int *n_rows, - int *xloc, int *yloc) + int *xloc, int *yloc, int *menu_shown) { TCHAR data[100]; DWORD size_out = sizeof( data); @@ -1170,18 +1138,15 @@ INLINE int get_default_sizes_from_registry( int *n_cols, int *n_rows, { extern int PDC_font_size; int x = -1, y = -1, bytes_read = 0; - int minl = 0, maxl = 0, minc = 0, maxc = 0; my_stscanf( data, _T( "%dx%d,%d,%d,%d,%d;%d,%d,%d,%d:%n"), &x, &y, &PDC_font_size, - xloc, yloc, &menu_shown, - &minl, &maxl, - &minc, &maxc, + xloc, yloc, menu_shown, + &min_lines, &max_lines, + &min_cols, &max_cols, &bytes_read); if( bytes_read > 0 && data[bytes_read - 1] == ':') my_tcscpy( PDC_font_name, data + bytes_read); - if ( !resize_limits_set) - PDC_set_resize_limits(minl, maxl, minc, maxc); if( n_cols) *n_cols = x; if( n_rows) @@ -1234,6 +1199,12 @@ INLINE void HandleSizing( WPARAM wParam, LPARAM lParam ) rect->left = rect->right - rounded_width; } +typedef void(*resize_callback_fnptr)(); +static resize_callback_fnptr resize_callback = NULL; +void PDC_set_window_resized_callback(resize_callback_fnptr callback) { + resize_callback = callback; +} + static void HandleSize( const WPARAM wParam, const LPARAM lParam) { static WPARAM prev_wParam = (WPARAM)-99; @@ -1244,11 +1215,12 @@ static void HandleSize( const WPARAM wParam, const LPARAM lParam) debug_printf( "WM_SIZE: wParam %x %d %d %d\n", (unsigned)wParam, n_xpixels, n_ypixels, SP->resized); - if( wParam == SIZE_MINIMIZED ) + if ( wParam == SIZE_MINIMIZED ) { prev_wParam = SIZE_MINIMIZED; return; } + new_n_rows = n_ypixels / PDC_cyChar; new_n_cols = n_xpixels / PDC_cxChar; debug_printf( "Size was %d x %d; will be %d x %d\n", @@ -1273,6 +1245,9 @@ static void HandleSize( const WPARAM wParam, const LPARAM lParam) /* don't add a key when the window is initialized */ add_key_to_queue( KEY_RESIZE); SP->resized = TRUE; + if (resize_callback) { + resize_callback(); + } } } @@ -1298,20 +1273,22 @@ static void HandleSize( const WPARAM wParam, const LPARAM lParam) prev_wParam = wParam; } - static void HandlePaint( HWND hwnd ) { PAINTSTRUCT ps; HDC hdc; - RECT rect; - GetUpdateRect( hwnd, &rect, FALSE); /* printf( "In HandlePaint: %ld %ld, %ld %ld\n", rect.left, rect.top, rect.right, rect.bottom); */ hdc = BeginPaint( hwnd, &ps); + RECT rect = ps.rcPaint; - fix_up_edges( hdc, &rect); + /* paint the background black. */ + const HBRUSH hOldBrush = + SelectObject(hdc, GetStockObject(BLACK_BRUSH)); + Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom); + SelectObject(hdc, hOldBrush); if( curscr && curscr->_y) { @@ -1554,7 +1531,6 @@ int PDC_get_mouse_event_from_queue( void) if( !n_mouse_queue) return( -1); - EnterCriticalSection(&PDC_cs); memset(&SP->mouse_status, 0, sizeof(MOUSE_STATUS)); if( mouse_queue->action == BUTTON_MOVED) { @@ -1585,7 +1561,6 @@ int PDC_get_mouse_event_from_queue( void) SP->mouse_status.button[i] |= mouse_queue->button_flags; n_mouse_queue--; memmove( mouse_queue, mouse_queue + 1, n_mouse_queue * sizeof( PDC_mouse_event)); - LeaveCriticalSection(&PDC_cs); return( 0); } @@ -1718,6 +1693,11 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, static bool ignore_resize = FALSE; int button = -1, action = -1; + PDC_hWnd = hwnd; + if( !hwnd) + debug_printf( "Null hWnd: msg %u, wParam %x, lParam %lx\n", + message, wParam, lParam); + switch (message) { case WM_SIZING: @@ -1727,16 +1707,12 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, case WM_SIZE: /* If ignore_resize = 1, don't bother resizing; */ /* the final window size has yet to be set */ - if( ignore_resize == FALSE) { - EnterCriticalSection(&PDC_cs); - HandleSize( wParam, lParam); - LeaveCriticalSection(&PDC_cs); - } + if( ignore_resize == FALSE) + HandleSize( wParam, lParam); return 0 ; case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: - EnterCriticalSection(&PDC_cs); { static int mouse_wheel_vertical_loc = 0; static int mouse_wheel_horizontal_loc = 0; @@ -1778,18 +1754,14 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, } } } - LeaveCriticalSection(&PDC_cs); return 0; case WM_MOUSEMOVE: { const int mouse_x = LOWORD( lParam) / PDC_cxChar; const int mouse_y = HIWORD( lParam) / PDC_cyChar; - - EnterCriticalSection(&PDC_cs); if( add_mouse( 0, BUTTON_MOVED, mouse_x, mouse_y)) modified_key_to_return = 0; - LeaveCriticalSection(&PDC_cs); } return 0; @@ -1852,14 +1824,11 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, /* refresh.c. I'm not entirely sure that this is what ought to be */ /* done, though it does appear to work correctly. */ case WM_PAINT: - EnterCriticalSection(&PDC_cs); HandlePaint( hwnd ); - LeaveCriticalSection(&PDC_cs); return 0; case WM_KEYUP: case WM_SYSKEYUP: - EnterCriticalSection(&PDC_cs); if( wParam == VK_MENU && numpad_unicode_value) { modified_key_to_return = numpad_unicode_value; @@ -1870,14 +1839,11 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, { add_key_to_queue( modified_key_to_return ); modified_key_to_return = 0; - LeaveCriticalSection(&PDC_cs); return 0; } - LeaveCriticalSection(&PDC_cs); return DefWindowProc(hwnd, message, wParam, lParam); case WM_CHAR: /* _Don't_ add Shift-Tab; it's handled elsewhere */ - EnterCriticalSection(&PDC_cs); if( wParam == 3 && !SP->raw_inp) /* Ctrl-C hit */ exit( 0); if( wParam != 9 || !(GetKeyState( VK_SHIFT) & 0x8000)) @@ -1885,16 +1851,13 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, add_key_to_queue( (int)wParam ); key_already_handled = FALSE; last_key_handled = 0; - LeaveCriticalSection(&PDC_cs); return 0; case WM_KEYDOWN: case WM_SYSKEYDOWN: if( wParam < 225 && wParam > 0 ) { - EnterCriticalSection(&PDC_cs); HandleSyskeyDown( wParam, lParam, &modified_key_to_return ); - LeaveCriticalSection(&PDC_cs); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); @@ -1903,7 +1866,6 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, return 0 ; case WM_TIMER: - EnterCriticalSection(&PDC_cs); if( wParam != TIMER_ID_FOR_BLINKING) { KillTimer( PDC_hWnd, (int)wParam); @@ -1914,11 +1876,9 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, /* blink the blinking text */ HandleTimer( wParam ); } - LeaveCriticalSection(&PDC_cs); return 0; case WM_CLOSE: - EnterCriticalSection(&PDC_cs); if( !PDC_get_function_key( FUNCTION_KEY_SHUT_DOWN)) { final_cleanup( ); @@ -1927,49 +1887,38 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, } else add_key_to_queue( PDC_get_function_key( FUNCTION_KEY_SHUT_DOWN)); - - LeaveCriticalSection(&PDC_cs); - return( 0); + return 0; case WM_COMMAND: case WM_SYSCOMMAND: if( wParam == WM_EXIT_GRACELESSLY) { - EnterCriticalSection(&PDC_cs); final_cleanup( ); - /*PDC_bDone = TRUE;*/ + PDC_bDone = TRUE; exit( 0); } else if( wParam == WM_ENLARGE_FONT || wParam == WM_SHRINK_FONT) { - EnterCriticalSection(&PDC_cs); adjust_font_size( (wParam == WM_ENLARGE_FONT) ? 1 : -1); - LeaveCriticalSection(&PDC_cs); return( 0); } else if( wParam == WM_CHOOSE_FONT) { - EnterCriticalSection(&PDC_cs); if( PDC_choose_a_new_font( )) adjust_font_size( 0); - LeaveCriticalSection(&PDC_cs); return( 0); } else if( wParam == WM_TOGGLE_MENU) { - EnterCriticalSection(&PDC_cs); HandleMenuToggle( &ignore_resize); - LeaveCriticalSection(&PDC_cs); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); case WM_DESTROY: - EnterCriticalSection(&PDC_cs); PDC_LOG(("WM_DESTROY\n")); PostQuitMessage (0) ; - /*PDC_bDone = TRUE;*/ - LeaveCriticalSection(&PDC_cs); + PDC_bDone = TRUE; return 0 ; default: @@ -1977,17 +1926,13 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, } /* mouse button handling code */ - assert( button != -1); - EnterCriticalSection(&PDC_cs); - - add_mouse( button, action, LOWORD( lParam) / PDC_cxChar, HIWORD( lParam) / PDC_cyChar); - if( action == BUTTON_PRESSED) - SetCapture( hwnd); + assert(button != -1); + add_mouse(button, action, LOWORD(lParam) / PDC_cxChar, HIWORD(lParam) / PDC_cyChar); + if (action == BUTTON_PRESSED) + SetCapture(hwnd); else - ReleaseCapture( ); - SetTimer( hwnd, 0, SP->mouse_wait, NULL); - - LeaveCriticalSection(&PDC_cs); + ReleaseCapture(); + SetTimer(hwnd, 0, SP->mouse_wait, NULL); return 0; } @@ -2046,79 +1991,6 @@ static void clip_or_center_window_to_monitor( HWND hwnd) } #endif -struct PDC_WININFO { - HANDLE hInstance; - int xsize; - int ysize; - DWORD window_style; - DWORD window_ex_style; - int xloc; - int yloc; - TCHAR WindowTitle[MAX_PATH]; -}; - -static const TCHAR *AppName = _T( "Curses_App"); -static HANDLE winthr_ready; - -/* Thread that creates and manages the WinGUI window. - The return type (and declared type of winthr_id) is uint32_t instead of - DWORD to avoid compiler warnings. */ - -static uint32_t WINAPI window_thread(LPVOID lpParameter) -{ - MSG msg; - HMENU hMenu; - struct PDC_WININFO *winfo = (struct PDC_WININFO *) lpParameter; - BOOL rval; - - PDC_hWnd = CreateWindowEx(winfo->window_ex_style, AppName, - winfo->WindowTitle, winfo->window_style, - winfo->xloc, winfo->yloc, - winfo->xsize, winfo->ysize, - NULL, (menu_shown ? set_menu( ) : NULL), - winfo->hInstance, NULL) ; - - if( !PDC_hWnd) - { - const DWORD last_error = GetLastError( ); - - debug_printf( "CreateWindow failed; GetLastError = %ld", last_error); - return( 2); - } - - hMenu = GetSystemMenu( PDC_hWnd, FALSE); - AppendMenu( hMenu, MF_STRING | (menu_shown ? MF_CHECKED : MF_UNCHECKED), WM_TOGGLE_MENU, _T( "Menu")); - AppendMenu( hMenu, MF_STRING, WM_CHOOSE_FONT, _T( "Choose Font")); - - debug_printf( "menu set\n"); - - ShowWindow (PDC_hWnd, - (winfo->window_style & WS_MAXIMIZE) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL); - debug_printf( "window shown\n"); - UpdateWindow (PDC_hWnd) ; - debug_printf( "window updated\n"); - SetTimer( PDC_hWnd, TIMER_ID_FOR_BLINKING, 500, NULL); - debug_printf( "timer set\n"); - -#if defined( MONITOR_DEFAULTTONEAREST) && WINVER >= 0x0410 - /* if the window is off-screen, move it on screen. */ - clip_or_center_window_to_monitor( PDC_hWnd); -#endif - - SetEvent(winthr_ready); - - while ((rval = GetMessage(&msg, NULL, 0, 0)) == TRUE) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - if (rval == -1) { - debug_printf("GetMessage() error: GetLastError = %lu\n", GetLastError()); - return 1; - } - return 0; -} - /* By default, the user cannot resize the window. This is because many apps don't handle KEY_RESIZE, and one can get odd behavior in such cases. There are two ways around this. If you call @@ -2143,34 +2015,30 @@ INLINE int set_up_window( void) { /* create the dialog window */ WNDCLASS wndclass ; + HMENU hMenu; HANDLE hInstance = GetModuleHandle( NULL); int n_default_columns = 80; int n_default_rows = 25; - struct PDC_WININFO winfo; + int xsize, ysize, window_style; + int xloc = CW_USEDEFAULT; + int yloc = CW_USEDEFAULT; + TCHAR WindowTitle[MAX_PATH]; + const TCHAR *AppName = _T( "Curses_App"); HICON icon; - /*static bool wndclass_has_been_registered = FALSE;*/ - HANDLE winthr_h; - HANDLE hWait[2]; - DWORD winthr_status; + static bool wndclass_has_been_registered = FALSE; if( !hInstance) debug_printf( "No instance: %d\n", GetLastError( )); - - winfo.hInstance = hInstance; - winfo.xloc = CW_USEDEFAULT; - winfo.yloc = CW_USEDEFAULT; - originally_focussed_window = GetForegroundWindow( ); debug_printf( "hInstance %x\nOriginal window %x\n", hInstance, originally_focussed_window); - /*if( !wndclass_has_been_registered)*/ + /* set the window icon from the icon in the process */ + icon = get_app_icon(hInstance); + if( !icon ) + icon = LoadIcon( NULL, IDI_APPLICATION); + if( !wndclass_has_been_registered) { ATOM rval; - /* set the window icon from the icon in the process */ - icon = get_app_icon(hInstance); - if( !icon ) - icon = LoadIcon( NULL, IDI_APPLICATION); - wndclass.style = CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; @@ -2190,12 +2058,12 @@ INLINE int set_up_window( void) debug_printf( "RegisterClass failed: GetLastError = %lx\n", last_error); return( -1); } - /*wndclass_has_been_registered = TRUE;*/ + wndclass_has_been_registered = TRUE; } - get_app_name( winfo.WindowTitle, MAX_PATH, TRUE); + get_app_name( WindowTitle, MAX_PATH, TRUE); #ifdef PDC_WIDE - debug_printf( "WindowTitle = '%ls'\n", winfo.WindowTitle); + debug_printf( "WindowTitle = '%ls'\n", WindowTitle); #endif if( PDC_n_rows > 2 && PDC_n_cols > 2) @@ -2205,7 +2073,7 @@ INLINE int set_up_window( void) } get_default_sizes_from_registry( &n_default_columns, &n_default_rows, - &winfo.xloc, &winfo.yloc, &menu_shown); + &xloc, &yloc, &menu_shown); if( ttytype[1]) PDC_set_resize_limits( (unsigned char)ttytype[0], @@ -2213,55 +2081,61 @@ INLINE int set_up_window( void) (unsigned char)ttytype[2], (unsigned char)ttytype[3]); debug_printf( "Size %d x %d, loc %d x %d; menu %d\n", - n_default_columns, n_default_rows, winfo.xloc, winfo.yloc, menu_shown); + n_default_columns, n_default_rows, xloc, yloc, menu_shown); get_character_sizes( NULL, &PDC_cxChar, &PDC_cyChar); if( min_lines != max_lines || min_cols != max_cols) - winfo.window_style = ((n_default_columns == -1) ? + window_style = ((n_default_columns == -1) ? WS_MAXIMIZE | WS_OVERLAPPEDWINDOW : WS_OVERLAPPEDWINDOW); else /* fixed-size window: looks "normal", but w/o a maximize box */ - winfo.window_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + window_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; - winfo.window_ex_style = WS_EX_CLIENTEDGE; + DWORD window_ex_style = WS_EX_CLIENTEDGE; if( n_default_columns == -1) - winfo.xsize = winfo.ysize = CW_USEDEFAULT; + xsize = ysize = CW_USEDEFAULT; else { keep_size_within_bounds( &n_default_rows, &n_default_columns); - winfo.xsize = PDC_cxChar * n_default_columns; - winfo.ysize = PDC_cyChar * n_default_rows; - adjust_window_size( &winfo.xsize, &winfo.ysize, winfo.window_style, - winfo.window_ex_style); + xsize = PDC_cxChar * n_default_columns; + ysize = PDC_cyChar * n_default_rows; + adjust_window_size( &xsize, &ysize, window_style, menu_shown); } - InitializeCriticalSection(&PDC_cs); - winthr_ready = CreateEvent(NULL, FALSE, FALSE, NULL); - winthr_h = (HANDLE) _beginthreadex(NULL, 0, window_thread, &winfo, 0, &winthr_id); - if (winthr_h == (HANDLE) 0) { - debug_printf("_beginthreadex() failed: %s\n", strerror(errno)); - DeleteCriticalSection(&PDC_cs); - CloseHandle(winthr_ready); - CloseHandle(winthr_h); - return -1; + PDC_hWnd = CreateWindowEx( window_ex_style, + AppName, WindowTitle, + window_style, + xloc, yloc, + xsize, ysize, + NULL, (menu_shown ? set_menu( ) : NULL), + hInstance, NULL) ; + + if( !PDC_hWnd) + { + const DWORD last_error = GetLastError( ); + + debug_printf( "CreateWindow failed; GetLastError = %ld", last_error); + return( -2); } - hWait[0] = winthr_ready; - hWait[1] = winthr_h; - WaitForMultipleObjects(2, hWait, FALSE, INFINITE); - CloseHandle(winthr_ready); - if (!GetExitCodeThread(winthr_h, &winthr_status)) { - debug_printf("GetExitCodeThread() failed: GetLastError = %lu\n", GetLastError()); - DeleteCriticalSection(&PDC_cs); - CloseHandle(winthr_h); - return -1; - } - CloseHandle(winthr_h); - if (winthr_status != STILL_ACTIVE) { - debug_printf("Premature window_thread termination: exit code = %lu\n", winthr_status); - DeleteCriticalSection(&PDC_cs); - return winthr_status; - } + hMenu = GetSystemMenu( PDC_hWnd, FALSE); + AppendMenu( hMenu, MF_STRING | (menu_shown ? MF_CHECKED : MF_UNCHECKED), WM_TOGGLE_MENU, _T( "Menu")); + AppendMenu( hMenu, MF_STRING, WM_CHOOSE_FONT, _T( "Choose Font")); + + debug_printf( "menu set\n"); + + ShowWindow (PDC_hWnd, + (n_default_columns == -1) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL); + debug_printf( "window shown\n"); + UpdateWindow (PDC_hWnd) ; + debug_printf( "window updated\n"); + SetTimer( PDC_hWnd, TIMER_ID_FOR_BLINKING, 500, NULL); + debug_printf( "timer set\n"); + +#if defined( MONITOR_DEFAULTTONEAREST) && WINVER >= 0x0410 + /* if the window is off-screen, move it on screen. */ + clip_or_center_window_to_monitor( PDC_hWnd); +#endif return( 0); } @@ -2321,8 +2195,6 @@ int PDC_scr_open(void) while( !PDC_get_rows( )) /* wait for screen to be drawn and */ ; /* actual size to be determined */ - EnterCriticalSection(&PDC_cs); - debug_printf( "Back from PDC_get_rows\n"); SP->lines = PDC_get_rows(); SP->cols = PDC_get_columns(); @@ -2371,19 +2243,11 @@ int PDC_resize_screen( int nlines, int ncols) if( new_width != client_rect.right || new_height != client_rect.bottom) { /* check to make sure size actually changed */ - DWORD thr_id = GetCurrentThreadId(); add_resize_key = 0; - - if (thr_id != winthr_id) - LeaveCriticalSection(&PDC_cs); - SetWindowPos( PDC_hWnd, 0, 0, 0, new_width + (rect.right - rect.left) - client_rect.right, new_height + (rect.bottom - rect.top) - client_rect.bottom, SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW); - - if (thr_id != winthr_id) - EnterCriticalSection(&PDC_cs); } } return OK; diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdcsetsc.c b/src/3rdparty/win32_src/pdcurses/wingui/pdcsetsc.c index 3b2f1cab5..16abd6fc5 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdcsetsc.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdcsetsc.c @@ -60,20 +60,17 @@ int PDC_curs_set(int visibility) void PDC_set_title(const char *title) { extern HWND PDC_hWnd; - extern CRITICAL_SECTION PDC_cs; #ifdef PDC_WIDE wchar_t wtitle[512]; #endif PDC_LOG(("PDC_set_title() - called:<%s>\n", title)); - LeaveCriticalSection(&PDC_cs); #ifdef PDC_WIDE PDC_mbstowcs(wtitle, title, 511); SetWindowTextW( PDC_hWnd, wtitle); #else SetWindowTextA( PDC_hWnd, title); #endif - EnterCriticalSection(&PDC_cs); } /* If SP->termattrs & A_BLINK is on, then text with the A_BLINK */ diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdcutil.c b/src/3rdparty/win32_src/pdcurses/wingui/pdcutil.c index 59959e0e6..04fe80cae 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdcutil.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdcutil.c @@ -6,8 +6,6 @@ #include #endif -extern CRITICAL_SECTION PDC_cs; - static volatile int _beep_count = 0; static void beep_thread(LPVOID lpParameter) @@ -32,14 +30,30 @@ void PDC_beep(void) void PDC_napms(int ms) /* 'ms' = milli, _not_ microseconds! */ { /* RR: keep GUI window responsive while PDCurses sleeps */ + MSG msg; + DWORD curr_ms = GetTickCount( ); + const DWORD milliseconds_sleep_limit = ms + curr_ms; + extern bool PDC_bDone; PDC_LOG(("PDC_napms() - called: ms=%d\n", ms)); - if( ms) + /* Pump all pending messages from WIN32 to the window handler */ + while( !PDC_bDone && curr_ms < milliseconds_sleep_limit ) { - LeaveCriticalSection(&PDC_cs); - Sleep(ms); - EnterCriticalSection(&PDC_cs); + const DWORD max_sleep_ms = 50; /* check msgs 20 times/second */ + DWORD sleep_millisecs; + + while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + curr_ms = GetTickCount( ); + sleep_millisecs = milliseconds_sleep_limit - curr_ms; + if( sleep_millisecs > max_sleep_ms) + sleep_millisecs = max_sleep_ms; + Sleep( sleep_millisecs); + curr_ms += sleep_millisecs; } } diff --git a/src/musikcube/cursespp/App.cpp b/src/musikcube/cursespp/App.cpp index ca6445bcc..43601aecf 100755 --- a/src/musikcube/cursespp/App.cpp +++ b/src/musikcube/cursespp/App.cpp @@ -112,6 +112,12 @@ static bool isLangUtf8() { } #endif +#ifdef WIN32 +static void pdcWinguiResizeCallback() { + App::Instance().NotifyResized(); +} +#endif + /* the way curses represents mouse button state is really gross, and makes it annoying to process click events with low latency while also supporting double clicks and multiple buttons. this structure is used to maintain and manipulate @@ -299,6 +305,7 @@ void App::InitCurses() { #ifdef PDCURSES_WINGUI /* needs to happen after initscr() */ PDC_set_default_menu_visibility(0); + PDC_set_window_resized_callback(&pdcWinguiResizeCallback); PDC_set_title(this->appTitle.c_str()); win32::InterceptWndProc(); win32::SetAppTitle(this->appTitle); @@ -596,22 +603,13 @@ process: } } - resized |= lastWidth != Screen::GetWidth() || lastHeight != Screen::GetHeight(); - + resized |= + lastWidth != Screen::GetWidth() || + lastHeight != Screen::GetHeight(); if (resized) { - resized = false; lastWidth = Screen::GetWidth(); lastHeight = Screen::GetHeight(); - - resize_term(0, 0); - - Window::InvalidateScreen(); - - if (this->resizeHandler) { - this->resizeHandler(); - } - - this->OnResized(); + this->NotifyResized(); } this->CheckShowOverlay(); @@ -635,6 +633,16 @@ process: overlays.Clear(); } +void App::NotifyResized() { + resized = false; + resize_term(0, 0); + Window::InvalidateScreen(); + if (this->resizeHandler) { + this->resizeHandler(); + } + this->OnResized(); +} + void App::UpdateFocusedWindow(IWindowPtr window) { if (this->state.focused != window) { this->state.focused = window; diff --git a/src/musikcube/cursespp/cursespp/App.h b/src/musikcube/cursespp/cursespp/App.h index 610cb8412..84c6bfe9d 100644 --- a/src/musikcube/cursespp/cursespp/App.h +++ b/src/musikcube/cursespp/cursespp/App.h @@ -69,6 +69,7 @@ namespace cursespp { void SetQuitKey(const std::string& kn); void Minimize(); void Restore(); + void NotifyResized(); #ifdef WIN32 static bool Running(const std::string& uniqueId, const std::string& title); From 57688429cda8d8fed8d7ccf1c5008f0fecb47576 Mon Sep 17 00:00:00 2001 From: casey langen Date: Sun, 24 Jul 2022 16:14:07 -0700 Subject: [PATCH 3/6] More PDCurses redraw fixes. --- .../win32_src/pdcurses/wingui/pdcscrn.c | 107 +++++++++++++----- 1 file changed, 79 insertions(+), 28 deletions(-) diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c b/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c index bf078cc73..2d9b259c5 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c @@ -1002,8 +1002,6 @@ static void adjust_font_size( const int font_size_change) if( IsZoomed( PDC_hWnd)) { RECT client_rect; - HDC hdc; - GetClientRect( PDC_hWnd, &client_rect); PDC_n_rows = client_rect.bottom / PDC_cyChar; PDC_n_cols = client_rect.right / PDC_cxChar; @@ -1011,10 +1009,8 @@ static void adjust_font_size( const int font_size_change) PDC_resize_screen( PDC_n_rows, PDC_n_cols); add_key_to_queue( KEY_RESIZE); SP->resized = TRUE; - hdc = GetDC (PDC_hWnd) ; GetClientRect( PDC_hWnd, &client_rect); - InvalidateRect(PDC_hWnd, &client_rect, TRUE); - ReleaseDC( PDC_hWnd, hdc) ; + InvalidateRect(PDC_hWnd, &client_rect, FALSE); } else { @@ -1273,37 +1269,92 @@ static void HandleSize( const WPARAM wParam, const LPARAM lParam) prev_wParam = wParam; } +/* to prevent flicker during repaint, we'll draw everything to a +dynamically allocated backing buffer, then blit it back to the +window's device context in one go. */ +struct BACK_BUFFER { + HBITMAP memory_bitmap; + HDC memory_dc, window_dc; + HANDLE original_object; + RECT rect; + bool is_rect_valid; +} backBuffer; + +static void PrepareBackBuffer(HDC hdc, RECT rect) +{ + memset(&backBuffer, 0, sizeof(backBuffer)); + int width = rect.right - rect.left; + int height = rect.bottom - rect.top; + backBuffer.rect = rect; + backBuffer.window_dc = hdc; + backBuffer.memory_dc = CreateCompatibleDC(hdc); + backBuffer.memory_bitmap = CreateCompatibleBitmap(hdc, width, height); + backBuffer.original_object = + SelectObject(backBuffer.memory_dc, backBuffer.memory_bitmap); + backBuffer.is_rect_valid = width > 0 && height > 0; +} + +static void BlitBackBuffer() +{ + if (backBuffer.is_rect_valid) + { + const RECT* r = &backBuffer.rect; + int width = r->right - r->left; + int height = r->bottom - r->top; + BitBlt( + backBuffer.window_dc, + r->left, r->top, + width, height, + backBuffer.memory_dc, + 0, 0, + SRCCOPY); + } + SelectObject(backBuffer.memory_dc, backBuffer.original_object); + DeleteObject(backBuffer.memory_bitmap); + DeleteObject(backBuffer.memory_dc); + memset(&backBuffer, 0, sizeof(backBuffer)); +} + static void HandlePaint( HWND hwnd ) { PAINTSTRUCT ps; - HDC hdc; + HDC windowDC, memoryDC; + RECT clientRect; /* printf( "In HandlePaint: %ld %ld, %ld %ld\n", rect.left, rect.top, rect.right, rect.bottom); */ - hdc = BeginPaint( hwnd, &ps); - RECT rect = ps.rcPaint; + windowDC = BeginPaint( hwnd, &ps); + GetClientRect(hwnd, &clientRect); - /* paint the background black. */ - const HBRUSH hOldBrush = - SelectObject(hdc, GetStockObject(BLACK_BRUSH)); - Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom); - SelectObject(hdc, hOldBrush); - - if( curscr && curscr->_y) + PrepareBackBuffer(windowDC, clientRect); + memoryDC = backBuffer.memory_dc; { - int i, x1, n_chars; + /* paint the background black. */ + const HBRUSH hOldBrush = + SelectObject(memoryDC, GetStockObject(BLACK_BRUSH)); + Rectangle(memoryDC, + clientRect.left, clientRect.top, + clientRect.right, clientRect.bottom); + SelectObject(memoryDC, hOldBrush); - x1 = rect.left / PDC_cxChar; - n_chars = rect.right / PDC_cxChar - x1 + 1; - if( n_chars > SP->cols - x1) - n_chars = SP->cols - x1; - if( n_chars > 0) - for( i = rect.top / PDC_cyChar; i <= rect.bottom / PDC_cyChar; i++) - if( i < SP->lines && curscr->_y[i]) - PDC_transform_line_given_hdc( hdc, i, x1, - n_chars, curscr->_y[i] + x1); + /* paint all the rows */ + if (curscr && curscr->_y) + { + int i, x1, n_chars; + + x1 = clientRect.left / PDC_cxChar; + n_chars = clientRect.right / PDC_cxChar - x1 + 1; + if (n_chars > SP->cols - x1) + n_chars = SP->cols - x1; + if (n_chars > 0) + for (i = clientRect.top / PDC_cyChar; i <= clientRect.bottom / PDC_cyChar; i++) + if (i < SP->lines && curscr->_y[i]) + PDC_transform_line_given_hdc(memoryDC, i, x1, + n_chars, curscr->_y[i] + x1); + } } + BlitBackBuffer(); EndPaint( hwnd, &ps ); } @@ -1818,7 +1869,7 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, return 0 ; case WM_ERASEBKGND: /* no need to erase background; it'll */ - return( 0); /* all get painted over anyway */ + return 1; /* all get painted over anyway */ /* The WM_PAINT routine is sort of "borrowed" from doupdate( ) from */ /* refresh.c. I'm not entirely sure that this is what ought to be */ @@ -2039,14 +2090,14 @@ INLINE int set_up_window( void) { ATOM rval; - wndclass.style = CS_VREDRAW ; + wndclass.style = CS_VREDRAW | CS_HREDRAW; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = icon; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; - wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; + wndclass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = AppName ; From f3dbca0ad76cbfeb7aeed0c3ee208094e82cedae Mon Sep 17 00:00:00 2001 From: casey langen Date: Mon, 25 Jul 2022 19:09:24 -0700 Subject: [PATCH 4/6] More PDCurses changes. --- src/3rdparty/win32_include/acs_defs.h | 265 ++++++++++++++++++ src/3rdparty/win32_src/pdcurses/deprec.c | 27 ++ .../win32_src/pdcurses/wingui/pdcscrn.c | 94 +++---- 3 files changed, 338 insertions(+), 48 deletions(-) create mode 100644 src/3rdparty/win32_include/acs_defs.h create mode 100644 src/3rdparty/win32_src/pdcurses/deprec.c diff --git a/src/3rdparty/win32_include/acs_defs.h b/src/3rdparty/win32_include/acs_defs.h new file mode 100644 index 000000000..c8c02a737 --- /dev/null +++ b/src/3rdparty/win32_include/acs_defs.h @@ -0,0 +1,265 @@ +/* Many of the following #defines are completely unused for the +nonce. For each character, its code point in code page 437, +Unicode, and page 8859-1 are given. The first is used for +non-wide builds in Win32 console, DOS, SDL, and OS/2. +Unicode is used for all wide builds, and for the non-wide +build of WinGUI. Code page 8859-1 is used for non-wide X11. + + All of these characters exist in CP437 and Unicode. Some +don't exist in 8859-1, in which case the last column is 'TBD'. +Only 32 are used in ncurses. So caution is advised. */ + +#ifdef USE_ISO8859_CHARSET + #define CHOOSE( A, B, C) (C) + #define TBD '!' +#else + #define CHOOSE( A, B, C) (USE_UNICODE_ACS_CHARS ? B : A) +#endif + +/* Codes found from https://en.wikipedia.org/wiki/Code_page_437 */ + +#define SMILE CHOOSE( 0x01, 0x263a, 'O') +#define REV_SMILE CHOOSE( 0x02, 0x263b, 'O') +#define HEART CHOOSE( 0x03, 0x2665, 'H') +#define DIAMOND CHOOSE( 0x04, 0x2666, 0x01) +#define CLUB CHOOSE( 0x05, 0x2663, 'C') +#define SPADE CHOOSE( 0x06, 0x2660, 'S') +#define MEDIUM_BULLET CHOOSE( 0x07, 0x2022, 0xb7) +#define REV_BULLET CHOOSE( 0x08, 0x2508, 0xb7) +#define WHITE_BULLET CHOOSE( 0x09, 0x25cb, 7) +#define REV_WHITE_BULLET CHOOSE( 0x0a, 0x25D9, 7) +#define MALE_SYM CHOOSE( 0x0b, 0x2642, 'm') +#define FEMALE_SYM CHOOSE( 0x0c, 0x2640, 'f') +#define QTR_NOTE CHOOSE( 0x0d, 0x266a, 0xbc) +#define EIGHTH_NOTE CHOOSE( 0x0e, 0x266b, 0xbd) +#define SPLAT CHOOSE( 0x0f, 0xa4 , 0xa4) +#define RIGHT_TRIANGLE CHOOSE( 0x10, 0x25b6, '>') +#define LEFT_TRIANGLE CHOOSE( 0x11, 0x25c0, '<') +#define UP_DOWN_ARROW CHOOSE( 0x12, 0x2195, 0x19) +#define DBL_BANG CHOOSE( 0x13, 0x203c, '!') +#define PILCROW CHOOSE( 0x14, 0xb6 , 0xb6) +#define SECTION_SIGN CHOOSE( 0x15, 0xa7 , 0xa7) +#define LOW_QTR_BLOCK CHOOSE( 0x16, 0x25b2, '_') +#define UP_DOWN_ARROW_UNDERSCORED CHOOSE( 0x17, 0x21ab, 0x19) +#define UP_ARROW CHOOSE( 0x18, 0x2191, '^') +#define DOWN_ARROW CHOOSE( 0x19, 0x2193, 'v') +#define RIGHT_ARROW CHOOSE( 0x1a, 0x2192, '>') +#define LEFT_ARROW CHOOSE( 0x1b, 0x2190, '<') +#define RIGHT_ANGLE CHOOSE( 0x1c, 0x221f, 0xe) +#define LEFT_RIGHT_ARROW CHOOSE( 0x1d, 0x2194, '-') +#define UP_TRIANGLE CHOOSE( 0x1e, 0x25b2, '^') +#define DOWN_TRIANGLE CHOOSE( 0x1f, 0x25bc, 'v') + +#define UPPERCASE_C_CEDILLA CHOOSE( 0x80, 0xc7 , 0xc7) +#define LOWERCASE_U_UMLAUT CHOOSE( 0x81, 0xfc , 0xfc) +#define LOWERCASE_E_ACUTE CHOOSE( 0x82, 0xe9 , 0xe9) +#define LOWERCASE_A_CIRCUMFLEX CHOOSE( 0x83, 0xe2 , 0xe2) +#define LOWERCASE_A_UMLAUT CHOOSE( 0x84, 0xe4 , 0xe4) +#define LOWERCASE_A_GRAVE CHOOSE( 0x85, 0xe0 , 0xea) +#define LOWERCASE_A_RING CHOOSE( 0x86, 0xe5 , 0xe5) +#define LOWERCASE_C_CEDILLA CHOOSE( 0x87, 0xe7 , 0xe7) +#define LOWERCASE_E_CIRCUMFLEX CHOOSE( 0x88, 0xea , 0xea) +#define LOWERCASE_E_UMLAUT CHOOSE( 0x89, 0xeb , 0xeb) +#define LOWERCASE_E_GRAVE CHOOSE( 0x8a, 0xe8 , 0xe8) +#define LOWERCASE_I_UMLAUT CHOOSE( 0x8b, 0xef , 0xef) +#define LOWERCASE_I_CIRCUMFLEX CHOOSE( 0x8c, 0xee , 0xee) +#define LOWERCASE_I_GRAVE CHOOSE( 0x8d, 0xec , 0xce) +#define UPPERCASE_A_UMLAUT CHOOSE( 0x8e, 0xc4 , 0xc4) +#define UPPERCASE_A_RING CHOOSE( 0x8f, 0xc5 , 0xc5) + +#define UPPERCASE_E_ACUTE CHOOSE( 0x90, 0xc9 , 0xc9) +#define LOWERCASE_AE_LIGATURE CHOOSE( 0x91, 0xe6 , 0xe6) +#define UPPERCASE_AE_LIGATURE CHOOSE( 0x92, 0xc6 , 0xc6) +#define LOWERCASE_O_CIRCUMFLEX CHOOSE( 0x93, 0xf4 , 0xf4) +#define LOWERCASE_O_UMLAUT CHOOSE( 0x94, 0xf6 , 0xf6) +#define LOWERCASE_O_GRAVE CHOOSE( 0x95, 0xf2 , 0xf2) +#define LOWERCASE_U_CIRCUMFLEX CHOOSE( 0x96, 0xfb , 0xfb) +#define LOWERCASE_U_GRAVE CHOOSE( 0x97, 0xf9 , 0xf9) +#define LOWERCASE_Y_UMLAUT CHOOSE( 0x98, 0xff , 0xff) +#define UPPERCASE_O_UMLAUT CHOOSE( 0x99, 0xd6 , 0xd6) +#define UPPERCASE_U_UMLAUT CHOOSE( 0x9a, 0xdc , 0xdc) +#define CENT_SIGN CHOOSE( 0x9b, 0xa2 , 0xa2) +#define STERLING_SIGN CHOOSE( 0x9c, 0xa3 , 30) +#define YEN_SIGN CHOOSE( 0x9d, 0xa5 , 0xa5) +#define PESETA_SIGN CHOOSE( 0x9e, 0x20a7, TBD) +#define F_WITH_HOOK CHOOSE( 0x9f, 0x0192, TBD) + +#define LOWERCASE_A_ACUTE CHOOSE( 0xa0, 0xe1 , 0xe1) +#define LOWERCASE_I_ACUTE CHOOSE( 0xa1, 0xed , 0xed) +#define LOWERCASE_O_ACUTE CHOOSE( 0xa2, 0xf3 , 0xf3) +#define LOWERCASE_U_ACUTE CHOOSE( 0xa3, 0xfa , 0xfa) +#define LOWERCASE_N_TILDE CHOOSE( 0xa4, 0xf1 , 0xf1) +#define UPPERCASE_N_TILDE CHOOSE( 0xa5, 0xd1 , 0xd1) +#define A_ORDINAL CHOOSE( 0xa6, 0xaa , 0xaa) +#define O_ORDINAL CHOOSE( 0xa7, 0xba , 0xba) +#define INVERTED_QUESTION_MARK CHOOSE( 0xa8, 0xbf , 0xbf) +#define REVERSED_NOT_SIGN CHOOSE( 0xa9, 0x2310, TBD) +#define NOT_SIGN CHOOSE( 0xaa, 0xac , 0xac) +#define VULGAR_HALF CHOOSE( 0xab, 0xbd , 0xbd) +#define VULGAR_QUARTER CHOOSE( 0xac, 0xbc , 0xbc) +#define INVERTED_EXCLAMATION_MARK CHOOSE( 0xad, 0xa1 , 0xa1) +#define LEFT_ANGLE_QUOTE_MARK CHOOSE( 0xae, 0xab , 0xab) +#define RIGHT_ANGLE_QUOTE_MARK CHOOSE( 0xaf, 0xbb , 0xbb) + +#define LIGHT_SHADE CHOOSE( 0xb0, 0x2591, '#' ) +#define MEDIUM_SHADE CHOOSE( 0xb1, 0x2592, 2) +#define DARK_SHADE CHOOSE( 0xb2, 0x2593, TBD) +#define BOX_VLINE CHOOSE( 0xb3, 0x2502, 25) +#define BOX_RTEE CHOOSE( 0xb4, 0x2524, 22) +#define BOX_SD_RTEE CHOOSE( 0xb5, 0x2561, 22) +#define BOX_DS_RTEE CHOOSE( 0xb6, 0x2562, 22) +#define BOX_DS_URCORNER CHOOSE( 0xb7, 0x2556, 12) +#define BOX_SD_URCORNER CHOOSE( 0xb8, 0x2555, 12) +#define BOX_D_RTEE CHOOSE( 0xb9, 0x2563, 22) +#define BOX_D_VLINE CHOOSE( 0xba, 0x2551, 25) +#define BOX_D_URCORNER CHOOSE( 0xbb, 0x2557, 12) +#define BOX_D_LRCORNER CHOOSE( 0xbc, 0x255D, 11) +#define BOX_DS_LRCORNER CHOOSE( 0xbd, 0x255c, 11) +#define BOX_SD_LRCORNER CHOOSE( 0xbe, 0x255b, 11) +#define BOX_URCORNER CHOOSE( 0xbf, 0x2510, 12) + +#define BOX_LLCORNER CHOOSE( 0xc0, 0x2514, 14) +#define BOX_BTEE CHOOSE( 0xc1, 0x2534, 23) +#define BOX_TTEE CHOOSE( 0xc2, 0x252c, 24) +#define BOX_LTEE CHOOSE( 0xc3, 0x251c, 21) +#define BOX_HLINE CHOOSE( 0xc4, 0x2500, 18) +#define BOX_PLUS CHOOSE( 0xc5, 0x253c, 15) +#define BOX_SD_LTEE CHOOSE( 0xc6, 0x255e, 21) +#define BOX_DS_LTEE CHOOSE( 0xc7, 0x255f, 21) +#define BOX_D_LLCORNER CHOOSE( 0xc8, 0x255A, 14) +#define BOX_D_ULCORNER CHOOSE( 0xc9, 0x2554, 13) +#define BOX_D_BTEE CHOOSE( 0xca, 0x2569, 23) +#define BOX_D_TTEE CHOOSE( 0xcb, 0x2566, 24) +#define BOX_D_LTEE CHOOSE( 0xcc, 0x2560, 21) +#define BOX_D_HLINE CHOOSE( 0xcd, 0x2550, 18) +#define BOX_D_PLUS CHOOSE( 0xce, 0x256C, 15) +#define BOX_SD_BTEE CHOOSE( 0xcf, 0x2567, 23) + +#define BOX_DS_BTEE CHOOSE( 0xd0, 0x2568, 23) +#define BOX_SD_TTEE CHOOSE( 0xd1, 0x2564, 24) +#define BOX_DS_TTEE CHOOSE( 0xd2, 0x2565, 24) +#define BOX_DS_LLCORNER CHOOSE( 0xd3, 0x2559, 14) +#define BOX_SD_LLCORNER CHOOSE( 0xd4, 0x2558, 14) +#define BOX_SD_ULCORNER CHOOSE( 0xd5, 0x2552, 13) +#define BOX_DS_ULCORNER CHOOSE( 0xd6, 0x2553, 13) +#define BOX_DS_PLUS CHOOSE( 0xd7, 0x256b, 15) +#define BOX_SD_PLUS CHOOSE( 0xd8, 0x256a, 15) +#define BOX_LRCORNER CHOOSE( 0xd9, 0x2518, 11) +#define BOX_ULCORNER CHOOSE( 0xda, 0x250c, 13) +#define FULL_BLOCK CHOOSE( 0xdb, 0x2588, 0) +#define LOWER_HALF_BLOCK CHOOSE( 0xdc, 0x2584, TBD) +#define LEFT_HALF_BLOCK CHOOSE( 0xdd, 0x258c, TBD) +#define RIGHT_HALF_BLOCK CHOOSE( 0xde, 0x2590, TBD) +#define UPPER_HALF_BLOCK CHOOSE( 0xdf, 0x2580, TBD) + +#define ALPHA CHOOSE( 0xe0, 0x03b1, TBD) +#define BETA CHOOSE( 0xe1, 0x00df, TBD) +#define GAMMA CHOOSE( 0xe2, 0x0393, TBD) +#define PI CHOOSE( 0xe3, 0x03c0, 28) +#define UPPERCASE_SIGMA CHOOSE( 0xe4, 0x03a3, TBD) +#define LOWERCASE_SIGMA CHOOSE( 0xe5, 0x03c3, TBD) +#define MU CHOOSE( 0xe6, 0x00b5, 0xb5) +#define TAU CHOOSE( 0xe7, 0x03c4, TBD) +#define UPPERCASE_PHI CHOOSE( 0xe8, 0x03a6, TBD) +#define THETA CHOOSE( 0xe9, 0x0398, TBD) +#define OMEGA CHOOSE( 0xea, 0x03a9, TBD) +#define DELTA CHOOSE( 0xeb, 0x03b4, TBD) +#define INFINITY_SIGN CHOOSE( 0xec, 0x221e, TBD) +#define LOWERCASE_PHI CHOOSE( 0xed, 0x03c6, TBD) +#define EPSILON CHOOSE( 0xee, 0x03b5, TBD) +#define INTERSECTION CHOOSE( 0xef, 0x2229, TBD) + +#define TRIPLE_BAR CHOOSE( 0xf0, 0x2261, TBD) +#define PLUS_OR_MINUS CHOOSE( 0xf1, 0x00b1, 8) +#define GREATER_THAN_OR_EQUAL_TO CHOOSE( 0xf2, 0x2265, 27) +#define LESSER_THAN_OR_EQUAL_TO CHOOSE( 0xf3, 0x2264, 26) +#define UPPER_HALF_INTEGRAL_SIGN CHOOSE( 0xf4, 0x2320, TBD) +#define LOWER_HALF_INTEGRAL_SIGN CHOOSE( 0xf5, 0x2321, TBD) +#define DIVISION_SIGN CHOOSE( 0xf6, 0x00f7, 0xf7) +#define APPROXIMATELY_EQUALS_SIGN CHOOSE( 0xf7, 0x2248, TBD) +#define DEGREE_SIGN CHOOSE( 0xf8, 0x00b0, 0xb0) +#define LARGE_BULLET CHOOSE( 0xf9, 0x2219, 7) +#define SMALL_BULLET CHOOSE( 0xfa, 0x00b7, 0xb7) +#define SQUARE_ROOT CHOOSE( 0xfb, 0x221a, TBD) +#define SUPERSCRIPT_N CHOOSE( 0xfc, 0x207f, TBD) +#define SUPERSCRIPT_2 CHOOSE( 0xfd, 0x00b2, 0xb2) +#define CENTERED_SQUARE CHOOSE( 0xfe, 0x25a0, TBD) +#define NON_BREAKING_SPACE CHOOSE( 0xff, 0x00a0, TBD) + + + + /* It says at http://unicode.org/charts/PDF/U2300.pdf */ + /* that '...the scan line numbers here refer to old, */ + /* low-resolution technology for terminals, with only */ + /* nine scan lines per fixed-size character glyph. */ + /* Even-numbered scan lines are unified with box */ + /* drawing graphics." */ + /* The utility of these is questionable; they'd */ + /* work Just Fine in wingdi (_if_ the appropriate */ + /* glyphs are available), but not elsewhere. */ +#define HORIZ_SCAN_LINE_1 CHOOSE( 0x2d, 0x23ba, 16) +#define HORIZ_SCAN_LINE_3 CHOOSE( 0x2d, 0x23bb, 17) +#define HORIZ_SCAN_LINE_7 CHOOSE( 0x2d, 0x23bc, 19) +#define HORIZ_SCAN_LINE_9 CHOOSE( '_', 0x23bd, 20) + + /* Code page 437 lacks a 'for real' not-equals, so for that, */ + /* we use the double-horizontal single-vertical box drawing : */ +#define NOT_EQUALS_SIGN CHOOSE( 0xd8, 0x2260, 29) + +# define A(x) ((chtype)x | A_ALTCHARSET) + +chtype acs_map[128] = +{ + A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7), A(8), + A(9), A(10), + CLUB, HEART, SPADE, SMILE, REV_SMILE, /* 11 12 13 14 15 */ + MEDIUM_BULLET, WHITE_BULLET, PILCROW, SECTION_SIGN, /* 16 17 18 19 */ + A_ORDINAL, O_ORDINAL, LOWERCASE_PHI, /* 20 21 22 */ + INVERTED_EXCLAMATION_MARK, INVERTED_QUESTION_MARK, /* 23 24 */ + REVERSED_NOT_SIGN, NOT_SIGN, /* 25 26 */ + UPPER_HALF_INTEGRAL_SIGN, LOWER_HALF_INTEGRAL_SIGN, /* 27 28 */ + SUPERSCRIPT_N, CENTERED_SQUARE, F_WITH_HOOK, /* 29 30 31 */ + + RIGHT_ARROW, LEFT_ARROW, UP_ARROW, DOWN_ARROW, /* 32 !"# */ + + PI, NOT_EQUALS_SIGN, VULGAR_HALF, VULGAR_QUARTER, /* $%&' */ + '(', + LEFT_ANGLE_QUOTE_MARK, RIGHT_ANGLE_QUOTE_MARK, /* )* */ + DARK_SHADE, SUPERSCRIPT_2, INFINITY_SIGN, /* +,- */ + ALPHA, BETA, GAMMA, UPPERCASE_SIGMA, LOWERCASE_SIGMA, /* ./012 */ + '3', + MU, TAU, UPPERCASE_PHI, THETA, OMEGA, DELTA, EPSILON, /* 456789: */ + + BOX_SD_LRCORNER, BOX_SD_URCORNER, BOX_SD_ULCORNER, /* ;<= */ + BOX_SD_LLCORNER, BOX_SD_PLUS, /* >? */ + BOX_SD_LTEE, BOX_SD_RTEE, BOX_SD_BTEE, BOX_SD_TTEE, /* @ABC */ + + BOX_D_LRCORNER, BOX_D_URCORNER, BOX_D_ULCORNER, /* DEF */ + BOX_D_LLCORNER, BOX_D_PLUS, /* GH */ + BOX_D_LTEE, BOX_D_RTEE, BOX_D_BTEE, BOX_D_TTEE, /* IJKL */ + + BOX_DS_LRCORNER, BOX_DS_URCORNER, BOX_DS_ULCORNER, /* MNO */ + BOX_DS_LLCORNER, BOX_DS_PLUS, /* PQ */ + BOX_DS_LTEE, BOX_DS_RTEE, BOX_DS_BTEE, BOX_DS_TTEE, /* RSTU */ + + BOX_LRCORNER, BOX_URCORNER, BOX_ULCORNER, /* VWX */ + BOX_LLCORNER, BOX_PLUS, /* YZ */ + BOX_LTEE, BOX_RTEE, BOX_BTEE, BOX_TTEE, /* [\]^ */ + + BOX_HLINE, BOX_VLINE, BOX_D_HLINE, BOX_D_VLINE, /* _`ab */ + + DIVISION_SIGN, APPROXIMATELY_EQUALS_SIGN, /* cd */ + INTERSECTION, TRIPLE_BAR, /* ef */ + SMALL_BULLET, LARGE_BULLET, SQUARE_ROOT, /* ghi */ + DIAMOND, MEDIUM_SHADE, /* jk */ + HORIZ_SCAN_LINE_1, HORIZ_SCAN_LINE_3, /* lm */ + HORIZ_SCAN_LINE_7, HORIZ_SCAN_LINE_9, /* no */ + UPPER_HALF_BLOCK, LOWER_HALF_BLOCK, /* pq */ + LEFT_HALF_BLOCK, RIGHT_HALF_BLOCK, FULL_BLOCK, /* rst */ + LESSER_THAN_OR_EQUAL_TO, GREATER_THAN_OR_EQUAL_TO, /* uv */ + DEGREE_SIGN, PLUS_OR_MINUS, LIGHT_SHADE, SPLAT, /* wxyz */ + CENT_SIGN, YEN_SIGN, PESETA_SIGN, STERLING_SIGN, /* {|}~ */ + A(127) +}; + +# undef A diff --git a/src/3rdparty/win32_src/pdcurses/deprec.c b/src/3rdparty/win32_src/pdcurses/deprec.c new file mode 100644 index 000000000..a7c9a82bc --- /dev/null +++ b/src/3rdparty/win32_src/pdcurses/deprec.c @@ -0,0 +1,27 @@ +/* PDCurses */ + +#include + +/* Deprecated functions. These should not be used, and will eventually + be removed. They're here solely for the benefit of applications that + linked to them in older versions of PDCurses. */ + +bool PDC_check_bios_key(void) +{ + return PDC_check_key(); +} + +int PDC_get_bios_key(void) +{ + return PDC_get_key(); +} + +bool PDC_get_ctrl_break(void) +{ + return !SP->raw_inp; +} + +int PDC_set_ctrl_break(bool setting) +{ + return setting ? noraw() : raw(); +} diff --git a/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c b/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c index 2d9b259c5..0cc746583 100644 --- a/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c +++ b/src/3rdparty/win32_src/pdcurses/wingui/pdcscrn.c @@ -1278,84 +1278,81 @@ struct BACK_BUFFER { HANDLE original_object; RECT rect; bool is_rect_valid; -} backBuffer; +} back_buffer; static void PrepareBackBuffer(HDC hdc, RECT rect) { - memset(&backBuffer, 0, sizeof(backBuffer)); int width = rect.right - rect.left; int height = rect.bottom - rect.top; - backBuffer.rect = rect; - backBuffer.window_dc = hdc; - backBuffer.memory_dc = CreateCompatibleDC(hdc); - backBuffer.memory_bitmap = CreateCompatibleBitmap(hdc, width, height); - backBuffer.original_object = - SelectObject(backBuffer.memory_dc, backBuffer.memory_bitmap); - backBuffer.is_rect_valid = width > 0 && height > 0; + memset(&back_buffer, 0, sizeof(back_buffer)); + back_buffer.rect = rect; + back_buffer.window_dc = hdc; + back_buffer.memory_dc = CreateCompatibleDC(hdc); + back_buffer.memory_bitmap = CreateCompatibleBitmap(hdc, width, height); + back_buffer.original_object = + SelectObject(back_buffer.memory_dc, back_buffer.memory_bitmap); + back_buffer.is_rect_valid = width > 0 && height > 0; } static void BlitBackBuffer() { - if (backBuffer.is_rect_valid) + const RECT* r = NULL; + int width = 0; + int height = 0; + + if (back_buffer.is_rect_valid) { - const RECT* r = &backBuffer.rect; - int width = r->right - r->left; - int height = r->bottom - r->top; + r = &back_buffer.rect; + width = r->right - r->left; + height = r->bottom - r->top; BitBlt( - backBuffer.window_dc, + back_buffer.window_dc, r->left, r->top, width, height, - backBuffer.memory_dc, + back_buffer.memory_dc, 0, 0, SRCCOPY); } - SelectObject(backBuffer.memory_dc, backBuffer.original_object); - DeleteObject(backBuffer.memory_bitmap); - DeleteObject(backBuffer.memory_dc); - memset(&backBuffer, 0, sizeof(backBuffer)); + SelectObject(back_buffer.memory_dc, back_buffer.original_object); + DeleteObject(back_buffer.memory_bitmap); + DeleteObject(back_buffer.memory_dc); + memset(&back_buffer, 0, sizeof(back_buffer)); } static void HandlePaint( HWND hwnd ) { PAINTSTRUCT ps; - HDC windowDC, memoryDC; - RECT clientRect; + HDC window_dc, memory_dc; + RECT client_rect; + HBRUSH old_brush; + int i; /* printf( "In HandlePaint: %ld %ld, %ld %ld\n", rect.left, rect.top, rect.right, rect.bottom); */ - windowDC = BeginPaint( hwnd, &ps); - GetClientRect(hwnd, &clientRect); + window_dc = BeginPaint( hwnd, &ps); + GetClientRect(hwnd, &client_rect); - PrepareBackBuffer(windowDC, clientRect); - memoryDC = backBuffer.memory_dc; + PrepareBackBuffer(window_dc, client_rect); + memory_dc = back_buffer.memory_dc; { /* paint the background black. */ - const HBRUSH hOldBrush = - SelectObject(memoryDC, GetStockObject(BLACK_BRUSH)); - Rectangle(memoryDC, - clientRect.left, clientRect.top, - clientRect.right, clientRect.bottom); - SelectObject(memoryDC, hOldBrush); + old_brush = SelectObject(memory_dc, GetStockObject(BLACK_BRUSH)); + Rectangle(memory_dc, + client_rect.left, client_rect.top, + client_rect.right, client_rect.bottom); + SelectObject(memory_dc, old_brush); /* paint all the rows */ - if (curscr && curscr->_y) + if (curscr && curscr->_y && PDC_n_cols > 0 && PDC_n_rows > 0) { - int i, x1, n_chars; - - x1 = clientRect.left / PDC_cxChar; - n_chars = clientRect.right / PDC_cxChar - x1 + 1; - if (n_chars > SP->cols - x1) - n_chars = SP->cols - x1; - if (n_chars > 0) - for (i = clientRect.top / PDC_cyChar; i <= clientRect.bottom / PDC_cyChar; i++) - if (i < SP->lines && curscr->_y[i]) - PDC_transform_line_given_hdc(memoryDC, i, x1, - n_chars, curscr->_y[i] + x1); + for (i = 0; i < PDC_n_rows; i++) + if (i < SP->lines && curscr->_y[i]) + PDC_transform_line_given_hdc(memory_dc, i, 0, PDC_n_cols, curscr->_y[i]); } } BlitBackBuffer(); - EndPaint( hwnd, &ps ); + EndPaint(hwnd, &ps); } static bool key_already_handled = FALSE; @@ -1753,14 +1750,14 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd, { case WM_SIZING: HandleSizing( wParam, lParam ); - return( TRUE ); + return 1; case WM_SIZE: /* If ignore_resize = 1, don't bother resizing; */ /* the final window size has yet to be set */ if( ignore_resize == FALSE) HandleSize( wParam, lParam); - return 0 ; + return 0; case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: @@ -2070,7 +2067,8 @@ INLINE int set_up_window( void) HANDLE hInstance = GetModuleHandle( NULL); int n_default_columns = 80; int n_default_rows = 25; - int xsize, ysize, window_style; + int xsize, ysize; + DWORD window_style, window_ex_style; int xloc = CW_USEDEFAULT; int yloc = CW_USEDEFAULT; TCHAR WindowTitle[MAX_PATH]; @@ -2141,7 +2139,7 @@ INLINE int set_up_window( void) else /* fixed-size window: looks "normal", but w/o a maximize box */ window_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; - DWORD window_ex_style = WS_EX_CLIENTEDGE; + window_ex_style = WS_EX_CLIENTEDGE; if( n_default_columns == -1) xsize = ysize = CW_USEDEFAULT; From 64b77d5f7d269278ace0a98cf64e8a9401f9a9b6 Mon Sep 17 00:00:00 2001 From: casey langen Date: Mon, 25 Jul 2022 19:12:17 -0700 Subject: [PATCH 5/6] App-level changes to support correct redrawing while resizing on Windows. --- src/musikcube/cursespp/App.cpp | 37 +++++++++++++++------------ src/musikcube/cursespp/Window.cpp | 3 ++- src/musikcube/cursespp/cursespp/App.h | 1 + 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/musikcube/cursespp/App.cpp b/src/musikcube/cursespp/App.cpp index 43601aecf..f83b22177 100755 --- a/src/musikcube/cursespp/App.cpp +++ b/src/musikcube/cursespp/App.cpp @@ -115,6 +115,7 @@ static bool isLangUtf8() { #ifdef WIN32 static void pdcWinguiResizeCallback() { App::Instance().NotifyResized(); + App::Instance().Layout(); } #endif @@ -612,22 +613,7 @@ process: this->NotifyResized(); } - this->CheckShowOverlay(); - this->EnsureFocusIsValid(); - - /* we want to dispatch messages here, before we call WriteToScreen(), - because dispatched messages may trigger UI updates, including layouts, - which may lead panels to get destroyed and recreated, which can - cause the screen to redraw outside of do_update() calls. so we dispatch - messages, ensure our overlay is on top, then do a redraw. */ - Window::MessageQueue().Dispatch(); - - if (this->state.overlayWindow) { - this->state.overlay->BringToTop(); /* active overlay is always on top... */ - } - - /* always last to avoid flicker. see above. */ - Window::WriteToScreen(this->state.input); + this->Layout(); } overlays.Clear(); @@ -643,6 +629,25 @@ void App::NotifyResized() { this->OnResized(); } +void App::Layout() { + this->CheckShowOverlay(); + this->EnsureFocusIsValid(); + + /* we want to dispatch messages here, before we call WriteToScreen(), + because dispatched messages may trigger UI updates, including layouts, + which may lead panels to get destroyed and recreated, which can + cause the screen to redraw outside of do_update() calls. so we dispatch + messages, ensure our overlay is on top, then do a redraw. */ + Window::MessageQueue().Dispatch(); + + if (this->state.overlayWindow) { + this->state.overlay->BringToTop(); /* active overlay is always on top... */ + } + + /* always last to avoid flicker. see above. */ + Window::WriteToScreen(this->state.input); +} + void App::UpdateFocusedWindow(IWindowPtr window) { if (this->state.focused != window) { this->state.focused = window; diff --git a/src/musikcube/cursespp/Window.cpp b/src/musikcube/cursespp/Window.cpp index 4f9158ef8..269ec73a4 100755 --- a/src/musikcube/cursespp/Window.cpp +++ b/src/musikcube/cursespp/Window.cpp @@ -105,6 +105,7 @@ static inline void DrawCursor(IInput* input) { const int targetY = 0; const int targetX = (int) input->Position(); wmove(content, targetY, targetX); + wnoutrefresh(content); } return; } @@ -131,8 +132,8 @@ bool Window::WriteToScreen(IInput* input) { if (drawPending && !freeze) { drawPending = false; update_panels(); - doupdate(); DrawCursor(input); + doupdate(); return true; } else if (freeze) { diff --git a/src/musikcube/cursespp/cursespp/App.h b/src/musikcube/cursespp/cursespp/App.h index 84c6bfe9d..d6ac5bb32 100644 --- a/src/musikcube/cursespp/cursespp/App.h +++ b/src/musikcube/cursespp/cursespp/App.h @@ -70,6 +70,7 @@ namespace cursespp { void Minimize(); void Restore(); void NotifyResized(); + void Layout(); #ifdef WIN32 static bool Running(const std::string& uniqueId, const std::string& title); From 7d932c921a50ff59937d6897465827ecbee357b0 Mon Sep 17 00:00:00 2001 From: casey langen Date: Tue, 26 Jul 2022 19:09:14 -0700 Subject: [PATCH 6/6] Update CHANGELOG --- CHANGELOG.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 99893079c..74b0bf950 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,6 +4,7 @@ * fixed PulseAudio compile issue. * fixed `musikdroid` app notification on Android 13 devices. * updated `musikdroid` dependencies and tooling, fixed a few warnings. +* merged latest upstream `PDCurses` code for Windows builds. --------------------------------------------------------------------------------