Merge upstream PDCurses changes.

This commit is contained in:
casey langen 2022-12-23 14:58:59 -08:00
parent 9f489c1811
commit 41717e4401
26 changed files with 1003 additions and 399 deletions

View File

@ -39,10 +39,10 @@ Defined by this header:
/* the 'endwin_*' #defines below should be updated. */
#define PDC_VER_MAJOR 4
#define PDC_VER_MINOR 3
#define PDC_VER_CHANGE 4
#define PDC_VER_CHANGE 5
#define PDC_VER_YEAR 2022
#define PDC_VER_MONTH 07
#define PDC_VER_DAY 29
#define PDC_VER_MONTH 12
#define PDC_VER_DAY 15
#define PDC_STRINGIZE( x) #x
#define PDC_stringize( x) PDC_STRINGIZE( x)
@ -97,6 +97,9 @@ extern "C"
#define int16_t short
#else
#include <stdint.h>
#ifdef __DMC__
#define uint64_t unsigned long long
#endif
#endif
/*----------------------------------------------------------------------
@ -349,6 +352,11 @@ typedef struct
*
*/
/* Avoid using the WINDOW or SCREEN structs directly -- doing so
makes your code PDCurses*-only and may result in future binary
incompatibility; use the corresponding functions if possible.
These structs may eventually be made private. */
typedef struct _win /* definition of a window */
{
int _cury; /* current pseudo-cursor */
@ -380,8 +388,7 @@ typedef struct _win /* definition of a window */
int _smincol, _smaxcol; /* saved position used only for pads */
} WINDOW;
/* Avoid using the SCREEN struct directly -- use the corresponding
functions if possible. This struct may eventually be made private. */
/* See above warning against directly accessing SCREEN elements. */
typedef struct
{
@ -439,7 +446,7 @@ typedef struct
int *c_ungch; /* array of ungotten chars */
int c_ungind; /* ungetch() push index */
int c_ungmax; /* allocated size of ungetch() buffer */
void *atrtab; /* table of color pairs */
struct _opaque_screen_t *opaque; /* internal library variables */
} SCREEN;
/*----------------------------------------------------------------------
@ -1701,12 +1708,25 @@ 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_cleared(const WINDOW *);
PDCEX bool is_idcok(const WINDOW *);
PDCEX bool is_idlok(const WINDOW *);
PDCEX bool is_immedok(const WINDOW *);
PDCEX bool is_keypad(const WINDOW *);
PDCEX bool is_leaveok(const WINDOW *);
PDCEX bool is_leaveok(const WINDOW *);
PDCEX bool is_nodelay(const WINDOW *);
PDCEX bool is_notimeout(const WINDOW *);
PDCEX bool is_pad(const WINDOW *);
PDCEX void reset_color_pairs( void);
PDCEX bool is_scrollok(const WINDOW *);
PDCEX bool is_subwin(const WINDOW *);
PDCEX bool is_syncok(const WINDOW *);
PDCEX int set_tabsize(int);
PDCEX int use_default_colors(void);
PDCEX int wgetdelay(const WINDOW *);
PDCEX WINDOW *wgetparent(const WINDOW *);
PDCEX int wgetscrreg(const WINDOW *, int *, int *);
PDCEX int wresize(WINDOW *, int, int);
PDCEX bool has_mouse(void);
@ -1765,7 +1785,6 @@ 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
@ -1780,7 +1799,7 @@ 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 void PDC_set_window_resized_callback(void (*callback)(void));
PDCEX int PDC_set_preferred_fontface( const wchar_t* fontface);
PDCEX void PDC_set_color_intensify_enabled( bool enabled);

View File

@ -84,12 +84,12 @@ 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 */
int PDC_init_atrtab(void);
void PDC_free_atrtab(void);
WINDOW *PDC_makelines(WINDOW *);
WINDOW *PDC_makenew(int, int, int, int);
int PDC_mouse_in_slk(int, int);
@ -137,5 +137,24 @@ PDCEX int PDC_wcwidth( const int32_t ucs);
#define _is_altcharset( ch) (((ch) & (A_ALTCHARSET | (A_CHARTEXT ^ 0x7f))) == A_ALTCHARSET)
#if PDC_COLOR_BITS < 15
typedef int16_t hash_idx_t;
#else
typedef int32_t hash_idx_t;
#endif
struct _opaque_screen_t
{
struct _pdc_pair *pairs;
int pairs_allocated;
int first_col;
bool default_colors;
hash_idx_t *pair_hash_tbl;
int pair_hash_tbl_size, pair_hash_tbl_used;
int n_windows;
WINDOW **window_list;
unsigned trace_flags;
bool want_trace_fflush;
};
#endif /* __CURSES_INTERNALS__ */

View File

@ -14,24 +14,7 @@ extern "C"
{
#endif
typedef struct panelobs
{
struct panelobs *above;
struct panel *pan;
} PANELOBS;
typedef struct panel
{
WINDOW *win;
int wstarty;
int wendy;
int wstartx;
int wendx;
struct panel *below;
struct panel *above;
const void *user;
struct panelobs *obscure;
} PANEL;
typedef struct panel PANEL;
PDCEX int bottom_panel(PANEL *pan);
PDCEX int del_panel(PANEL *pan);

View File

@ -27,7 +27,6 @@ color
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);
@ -100,11 +99,7 @@ color
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.
foreground is white.
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
@ -145,7 +140,7 @@ color
/* Color pair structure */
typedef struct
typedef struct _pdc_pair
{
int f; /* foreground color */
int b; /* background color */
@ -154,12 +149,6 @@ typedef struct
int COLORS = 0;
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);
@ -167,7 +156,7 @@ static void _init_pair_core(int pair, int fg, int bg);
static void _unlink_color_pair( const int pair_no)
{
PDC_PAIR *p = (PDC_PAIR *)SP->atrtab;
PDC_PAIR *p = SP->opaque->pairs;
PDC_PAIR *curr = p + pair_no;
p[curr->next].prev = curr->prev;
@ -176,7 +165,7 @@ static void _unlink_color_pair( const int pair_no)
static void _link_color_pair( const int pair_no, const int head)
{
PDC_PAIR *p = (PDC_PAIR *)SP->atrtab;
PDC_PAIR *p = SP->opaque->pairs;
PDC_PAIR *curr = p + pair_no;
curr->next = p[head].next;
@ -184,23 +173,14 @@ static void _link_color_pair( const int pair_no, const int 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);
assert( SP->opaque->pair_hash_tbl_size);
rval ^= rval >> 11;
rval ^= rval << 7;
rval &= (_pair_hash_tbl_size - 1);
rval &= (SP->opaque->pair_hash_tbl_size - 1);
return( rval);
}
@ -211,39 +191,41 @@ https://www.projectpluto.com/hashing.htm for details. */
#define ADVANCE_HASH_PROBE( idx, iter) \
{ idx++; \
if( iter % GROUP_SIZE == 0) idx += iter - GROUP_SIZE; \
idx &= (_pair_hash_tbl_size - 1); }
idx &= (SP->opaque->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)
assert( SP->opaque && SP->opaque->pairs);
if( SP->opaque->pair_hash_tbl_used * 5 / 4 >= SP->opaque->pair_hash_tbl_size)
{
int i, n_pairs;
PDC_PAIR *p = (PDC_PAIR *)SP->atrtab;
PDC_PAIR *p = SP->opaque->pairs;
for( i = 1, n_pairs = 0; i < atrtab_size_alloced; i++)
for( i = 1, n_pairs = 0; i < SP->opaque->pairs_allocated; 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++)
SP->opaque->pair_hash_tbl_used = n_pairs;
SP->opaque->pair_hash_tbl_size = 8; /* minimum table size */
while( n_pairs >= SP->opaque->pair_hash_tbl_size * 3 / 4)
SP->opaque->pair_hash_tbl_size <<= 1; /* more than 75% of table is full */
if( SP->opaque->pair_hash_tbl)
free( SP->opaque->pair_hash_tbl);
SP->opaque->pair_hash_tbl = (hash_idx_t *)calloc(
SP->opaque->pair_hash_tbl_size, sizeof( hash_idx_t));
for( i = 1; i < SP->opaque->pairs_allocated; 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++)
for( iter = 0; SP->opaque->pair_hash_tbl[idx]; iter++)
ADVANCE_HASH_PROBE( idx, iter);
_pair_hash_tbl[idx] = (hash_idx_t)i;
SP->opaque->pair_hash_tbl[idx] = (hash_idx_t)i;
}
}
}
static int _default_foreground_idx = COLOR_WHITE, _default_background_idx = COLOR_BLACK;
int start_color(void)
{
PDC_LOG(("start_color() - called\n"));
@ -256,10 +238,11 @@ int start_color(void)
PDC_set_blink(FALSE); /* Also sets COLORS */
if (!default_colors && SP->orig_attr && getenv("PDC_ORIGINAL_COLORS"))
default_colors = TRUE;
if (!SP->opaque->default_colors && SP->orig_attr && getenv("PDC_ORIGINAL_COLORS"))
SP->opaque->default_colors = TRUE;
_init_pair_core( 0, _default_foreground_idx, _default_background_idx);
_init_pair_core( 0, _default_foreground_idx,
_default_background_idx);
if( !SP->_preserve)
curscr->_clear = TRUE;
#if !defined( CHTYPE_32) && !defined(OS2) && !defined(DOS)
@ -286,7 +269,7 @@ void PDC_set_default_colors( const int fg_idx, const int bg_idx)
static void _normalize(int *fg, int *bg)
{
const bool using_defaults = (SP->orig_attr && (default_colors || !SP->color_started));
const bool using_defaults = (SP->orig_attr && (SP->opaque->default_colors || !SP->color_started));
if (*fg == -1 || *fg == UNSET_COLOR_PAIR)
*fg = using_defaults ? SP->orig_fore : _default_foreground_idx;
@ -362,29 +345,30 @@ 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( SP->opaque);
assert( SP->opaque->pairs_allocated);
assert( pair < COLOR_PAIRS);
if( pair >= atrtab_size_alloced)
if( pair >= SP->opaque->pairs_allocated)
{
int i, new_size = atrtab_size_alloced * 2;
int i, new_size = SP->opaque->pairs_allocated * 2;
while( pair >= new_size)
new_size += new_size;
SP->atrtab = (void *)realloc( SP->atrtab, (new_size + 1) * sizeof( PDC_PAIR));
assert( SP->atrtab);
for( i = atrtab_size_alloced + 1; i <= new_size; i++)
SP->opaque->pairs = (PDC_PAIR *)realloc( SP->opaque->pairs,
(new_size + 1) * sizeof( PDC_PAIR));
assert( SP->opaque);
for( i = SP->opaque->pairs_allocated + 1; i <= new_size; i++)
{
p = (PDC_PAIR *)SP->atrtab + i;
p = SP->opaque->pairs + i;
p->f = UNSET_COLOR_PAIR;
_link_color_pair( i, atrtab_size_alloced);
_link_color_pair( i, SP->opaque->pairs_allocated);
}
atrtab_size_alloced = new_size;
SP->opaque->pairs_allocated = new_size;
}
assert( pair >= 0);
assert( pair < atrtab_size_alloced);
p = (PDC_PAIR *)SP->atrtab + pair;
assert( pair < SP->opaque->pairs_allocated);
p = SP->opaque->pairs + 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
@ -398,12 +382,12 @@ static void _init_pair_core(int pair, int fg, int bg)
{
int idx = _hash_color_pair( p->f, p->b), iter;
for( iter = 0; _pair_hash_tbl[idx] != pair; iter++)
for( iter = 0; SP->opaque->pair_hash_tbl[idx] != pair; iter++)
{
assert( _pair_hash_tbl[idx]);
assert( SP->opaque->pair_hash_tbl[idx]);
ADVANCE_HASH_PROBE( idx, iter);
}
_pair_hash_tbl[idx] = -1; /* mark as freed */
SP->opaque->pair_hash_tbl[idx] = -1; /* mark as freed */
}
if( pair)
_unlink_color_pair( pair);
@ -413,14 +397,14 @@ static void _init_pair_core(int pair, int fg, int bg)
{
int idx = _hash_color_pair( fg, bg), iter;
for( iter = 0; _pair_hash_tbl[idx] > 0; iter++)
for( iter = 0; SP->opaque->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( !SP->opaque->pair_hash_tbl[idx]) /* using a new pair */
SP->opaque->pair_hash_tbl_used++;
SP->opaque->pair_hash_tbl[idx] = (hash_idx_t)pair;
}
if( pair)
_link_color_pair( pair, (p->f == UNSET_COLOR_PAIR ? atrtab_size_alloced : 0));
_link_color_pair( pair, (p->f == UNSET_COLOR_PAIR ? SP->opaque->pairs_allocated : 0));
if( refresh_pair)
_set_cells_to_refresh_for_pair_change( pair);
}
@ -430,8 +414,9 @@ int init_extended_pair(int pair, int fg, int bg)
PDC_LOG(("init_pair() - called: pair %d fg %d bg %d\n", pair, fg, bg));
assert( SP);
if (!SP || !SP->color_started || pair < 1 || pair >= COLOR_PAIRS ||
fg < first_col || fg >= COLORS || bg < first_col || bg >= COLORS)
if (!SP || !SP->color_started || pair < 1 || pair >= COLOR_PAIRS
|| fg < SP->opaque->first_col || fg >= COLORS
|| bg < SP->opaque->first_col || bg >= COLORS)
return ERR;
_init_pair_core(pair, fg, bg);
@ -494,14 +479,14 @@ bool can_change_color(void)
int extended_pair_content(int pair, int *fg, int *bg)
{
PDC_PAIR *p = (PDC_PAIR *)SP->atrtab + pair;
PDC_PAIR *p = SP->opaque->pairs + pair;
PDC_LOG(("pair_content() - called\n"));
if (pair < 0 || pair >= COLOR_PAIRS || !fg || !bg)
return ERR;
if( pair >= atrtab_size_alloced || (pair && p->f == UNSET_COLOR_PAIR))
if( pair >= SP->opaque->pairs_allocated || (pair && p->f == UNSET_COLOR_PAIR))
{
*fg = COLOR_RED; /* signal use of uninitialized pair */
*bg = COLOR_BLUE; /* with visible, but odd, colors */
@ -534,8 +519,8 @@ int use_default_colors(void)
{
PDC_LOG(("use_default_colors() - called\n"));
default_colors = TRUE;
first_col = -1;
SP->opaque->default_colors = TRUE;
SP->opaque->first_col = -1;
return assume_default_colors(-1, -1);
}
@ -558,19 +543,25 @@ int PDC_set_line_color(short color)
int PDC_init_atrtab(void)
{
assert( SP);
if( !SP->atrtab)
if( !SP->opaque)
{
PDC_PAIR *p;
atrtab_size_alloced = 1;
SP->atrtab = calloc( 2, sizeof(PDC_PAIR));
assert( SP->atrtab);
if( !SP->atrtab)
SP->opaque = (struct _opaque_screen_t *)calloc( 1, sizeof( struct _opaque_screen_t));
assert( SP->opaque);
if( !SP->opaque)
return -1;
p = (PDC_PAIR *)SP->atrtab;
SP->opaque->pairs_allocated = 1;
SP->opaque->pairs = (PDC_PAIR *)calloc( 2, sizeof(PDC_PAIR));
assert( SP->opaque->pairs);
if( !SP->opaque->pairs)
return -1;
p = (PDC_PAIR *)SP->opaque->pairs;
p[0].f = p[1].f = UNSET_COLOR_PAIR;
p[0].prev = p[0].next = 0;
p[1].prev = p[1].next = 1;
SP->opaque->default_colors = FALSE;
PDC_set_default_colors( _default_foreground_idx, _default_background_idx);
}
_init_pair_core( 0,
(SP->orig_attr ? SP->orig_fore : _default_foreground_idx),
@ -578,6 +569,21 @@ int PDC_init_atrtab(void)
return( 0);
}
void PDC_free_atrtab(void)
{
assert( SP);
assert( SP->opaque);
assert( SP->opaque->pairs);
if( SP->opaque->pair_hash_tbl)
free( SP->opaque->pair_hash_tbl);
SP->opaque->pair_hash_tbl = NULL;
SP->opaque->pair_hash_tbl_size = SP->opaque->pair_hash_tbl_used = 0;
if( SP->opaque->pairs)
free( SP->opaque->pairs);
free( SP->opaque);
SP->opaque = NULL;
}
int init_pair( short pair, short fg, short bg)
{
return( init_extended_pair( (int)pair, (int)fg, (int)bg));
@ -620,15 +626,15 @@ 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++)
assert( SP->opaque);
assert( SP->opaque->pairs_allocated);
for( iter = 0; SP->opaque->pair_hash_tbl[idx]; iter++)
{
int i;
if( (i = _pair_hash_tbl[idx]) > 0)
if( (i = SP->opaque->pair_hash_tbl[idx]) > 0)
{
PDC_PAIR *p = (PDC_PAIR *)SP->atrtab;
PDC_PAIR *p = SP->opaque->pairs;
if( p[i].f == fg && p[i].b == bg)
{
@ -657,9 +663,9 @@ int alloc_pair( int fg, int bg)
if( -1 == rval) /* pair isn't already allocated. First, look */
{ /* for an unset color pair. */
PDC_PAIR *p = (PDC_PAIR *)SP->atrtab;
PDC_PAIR *p = SP->opaque->pairs;
rval = p[atrtab_size_alloced].prev;
rval = p[SP->opaque->pairs_allocated].prev;
assert( rval);
if( COLOR_PAIRS == rval) /* all color pairs are in use; */
rval = p[0].prev; /* 'repurpose' the oldest pair */
@ -674,11 +680,11 @@ 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( SP && SP->opaque && SP->opaque->pairs);
assert( pair >= 1 && pair < SP->opaque->pairs_allocated);
p = SP->opaque->pairs + pair;
assert( p->f != UNSET_COLOR_PAIR);
if (!SP || !SP->color_started || pair < 1 || pair >= atrtab_size_alloced
if (!SP || !SP->color_started || pair < 1 || pair >= SP->opaque->pairs_allocated
|| p->f == UNSET_COLOR_PAIR)
return ERR;
@ -686,20 +692,10 @@ int free_pair( int pair)
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( );
assert( SP && SP->opaque && SP->opaque->pairs);
PDC_free_atrtab( );
PDC_init_atrtab( );
curscr->_clear = TRUE;
}
@ -723,27 +719,27 @@ 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;
assert( SP && SP->opaque && SP->opaque->pairs);
p = (PDC_PAIR *)SP->opaque->pairs;
idx = 0;
while( n_used < atrtab_size_alloced + 10 && p[idx].next)
while( n_used < SP->opaque->pairs_allocated + 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( next >= 0 && next < SP->opaque->pairs_allocated);
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)
idx = SP->opaque->pairs_allocated;
while( n_free < SP->opaque->pairs_allocated + 10 && p[idx].next != SP->opaque->pairs_allocated)
{ /* 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( next > 0 && next <= SP->opaque->pairs_allocated);
assert( p[next].prev == idx);
idx = p[idx].next;
n_free++;
@ -753,10 +749,10 @@ int PDC_check_color_pair_table( int *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;
results[2] = SP->opaque->pairs_allocated + 1; /* include the 'dummy' pair */
results[3] = SP->opaque->pair_hash_tbl_size;
results[4] = SP->opaque->pair_hash_tbl_used;
}
return( (n_used + n_free == atrtab_size_alloced + 1) ? 0 : -1);
return( (n_used + n_free == SP->opaque->pairs_allocated + 1) ? 0 : -1);
}
#endif /* #ifdef PDC_COLOR_PAIR_DEBUGGING_FUNCTIONS */

View File

@ -0,0 +1,134 @@
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#if defined( _WIN32) || defined( __WATCOMC__)
#include <direct.h>
#else
#include <unistd.h>
#endif
/* Code to 'configure' curses.h. Run as, e.g.,
./config_curses -DPDC_WIDE -DXCURSES
it will check to see if the existing curses.h has those options set
(and not the others, such as CHTYPE_32). Essentially, it just checks
to see if the existing configuration matches the one described on the
command line.
If it matches, we exit without doing anything. No file is updated.
If the configurations differ, a new 'curses0.h' is created that
has the options given on the command line. This is done by reading in
the existing 'curses.h', snipping out the lines with config data,
and inserting new ones. When we're done, we remove 'curses.h' and
move our new 'curses0.h' into its place. This will force a full
recompile on the next build, which is what we want anyway if
the configuration has changed. */
int main( const int argc, const char **argv)
{
FILE *ifile, *ofile;
int options_found = 0, i, j, options_desired = 0;
int verbose = 0;
const char *option_text[] = {
"XCURSES", "PDC_RGB", "PDC_WIDE",
"PDC_FORCE_UTF8", "PDC_DLL_BUILD", "PDC_NCMOUSE",
"CHTYPE_32" };
const int n_options = (int)( sizeof( option_text) / sizeof( option_text[0]));
char buff[300];
const char *curses_h_filename = "curses.h";
const char *curses0_h_filename = "curses0.h";
for( i = 1; i < argc; i++)
if( argv[i][0] == '-')
switch( argv[i][1])
{
case 'd':
{
int err_code;
const char *arg = (!argv[i][2] && i < argc - 1 ?
argv[i + 1] : argv[i] + 2);
#ifdef _WIN32
err_code = _chdir( arg);
#else
err_code = chdir( arg);
#endif
if( err_code)
{
fprintf( stderr, "Couldn't change dir to '%s'\n", arg);
perror( NULL);
return( -1);
}
}
break;
case 'v':
verbose = 1;
break;
case 'D':
for( j = 0; j < n_options; j++)
if( !strcmp( argv[i] + 2, option_text[j]))
options_desired |= (1 << j);
break;
default:
printf( "Option '%s' not recognized\n", argv[i]);
}
ifile = fopen( curses_h_filename, "rb");
assert( ifile);
while( fgets( buff, sizeof( buff), ifile))
if( !memcmp( buff, " #define ", 11))
for( j = 0; j < n_options; j++)
if( !memcmp( buff + 11, option_text[j], strlen( option_text[j]))
&& buff[11 + strlen( option_text[j])] <= ' ')
options_found |= (1 << j);
if( verbose)
printf( "options_found = 0x%x options_desired = 0x%x\n",
options_found, options_desired);
if( options_found == options_desired)
{
fclose( ifile); /* nothing to do */
return( 0);
}
fseek( ifile, 0L, SEEK_SET);
ofile = fopen( curses0_h_filename, "wb");
assert( ofile);
while( fgets( buff, sizeof( buff), ifile))
{
fputs( buff, ofile);
if( !memcmp( buff, "**man-end*******", 16))
{
fputs( "\n", ofile);
for( i = 0; i < n_options; i++)
if( options_desired & (1 << i))
{
if( !strcmp( option_text[i], "PDC_DLL_BUILD"))
fprintf( ofile, "#if defined( __WIN32) && !defined( PDC_DLL_BUILD)\n");
else
fprintf( ofile, "#ifndef %s\n", option_text[i]);
fprintf( ofile, " #define %s\n", option_text[i]);
fprintf( ofile, "#endif\n");
}
fputs( "\n", ofile);
while( fgets( buff, sizeof( buff), ifile)
&& memcmp( buff, "#define PDCURSES", 16))
;
fputs( buff, ofile); /* dump rest of file unaltered*/
while( fgets( buff, sizeof( buff), ifile))
fputs( buff, ofile);
}
}
fclose( ofile);
fclose( ifile);
#ifdef _WIN32
_unlink( curses_h_filename);
#else
unlink( curses_h_filename);
#endif
rename( curses0_h_filename, curses_h_filename);
if( verbose)
printf( "curses.h updated\n");
return( 0);
}

View File

@ -58,12 +58,6 @@ debug
#include <sys/types.h>
#include <time.h>
/* 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, ...)
{
va_list args;
@ -86,7 +80,7 @@ void PDC_debug(const char *fmt, ...)
by setting the environment variable PDC_TRACE_FLUSH. This may
impact performance. */
if (want_fflush)
if (SP->opaque->want_trace_fflush)
fflush(SP->dbfp);
/* If with PDC_TRACE_FLUSH enabled you are still losing logging in
@ -121,9 +115,9 @@ void traceon(void)
return;
}
PDC_trace_flags = TRACE_MAXIMUM;
SP->opaque->trace_flags = TRACE_MAXIMUM;
if (getenv("PDC_TRACE_FLUSH"))
want_fflush = TRUE;
SP->opaque->want_trace_fflush = TRUE;
PDC_LOG(("traceon() - called\n"));
}
@ -138,19 +132,19 @@ void traceoff(void)
fclose(SP->dbfp);
SP->dbfp = NULL;
PDC_trace_flags = TRACE_DISABLE;
want_fflush = FALSE;
SP->opaque->trace_flags = TRACE_DISABLE;
SP->opaque->want_trace_fflush = FALSE;
}
unsigned curses_trace( const unsigned param)
{
const unsigned rval = PDC_trace_flags;
const unsigned rval = SP->opaque->trace_flags;
assert( SP);
if( SP)
{
param ? traceon( ) : traceoff( );
PDC_trace_flags = param;
SP->opaque->trace_flags = param;
}
PDC_LOG(("curses_trace() - called\n"));
return( rval);

View File

@ -0,0 +1,129 @@
/* PDCurses */
/* Common pieces between DOS and DOSVGA 'pdcutil' functions */
void PDC_beep(void)
{
PDCREGS regs;
PDC_LOG(("PDC_beep() - called\n"));
regs.W.ax = 0x0e07; /* Write ^G in TTY fashion */
regs.W.bx = 0;
PDCINT(0x10, regs);
}
#define MAX_TICK 0x1800b0L
/* no. of IRQ 0 clock ticks per day; BIOS counter (0:0x46c) will go
to MAX_TICK - 1 before wrapping to 0 at midnight */
#define MS_PER_DAY 86400000L
/* 1080 seconds = 18 minutes = 1/80 day is exactly 19663 ticks.
If asked to nap for longer than 1080000 milliseconds, we take
one or more 18-minute naps. This avoids wraparound issues and
the integer overflows that would result for ms > MAX_LONG / 859
(about 42 minutes). */
#define MAX_NAP_SPAN (MS_PER_DAY / 80ul)
void PDC_napmsl( long ms)
{
long tick0, ticks_to_wait;
PDC_LOG(("PDC_napms() - called: ms=%d\n", ms));
while( ms > MAX_NAP_SPAN)
{
PDC_napmsl( MAX_NAP_SPAN);
ms -= MAX_NAP_SPAN;
}
/* We should convert from milliseconds to BIOS ticks by
multiplying by MAX_TICK and dividing by MS_PER_DAY. But
that would overflow, and we'd need floating point math.
The following is good to four parts per billion and
doesn't overflow (because 0 <= ms <= MAX_NAP_SPAN). */
ticks_to_wait = (ms * 859L) / 47181L + 1L;
tick0 = getdosmemdword(0x46c);
for( ;;)
{
long ticks_elapsed = getdosmemdword(0x46c) - tick0;
PDCREGS regs;
if( ticks_elapsed < 0L) /* midnight rollover */
ticks_elapsed += MAX_TICK;
if (ticks_elapsed > ticks_to_wait)
return;
regs.W.ax = 0x1680;
PDCINT(0x2f, regs);
PDCINT(0x28, regs);
}
}
void PDC_napms( int ms)
{
PDC_napmsl( (long)ms);
}
#ifdef __DJGPP__
unsigned char getdosmembyte(int offset)
{
unsigned char b;
dosmemget(offset, sizeof(unsigned char), &b);
return b;
}
unsigned short getdosmemword(int offset)
{
unsigned short w;
dosmemget(offset, sizeof(unsigned short), &w);
return w;
}
unsigned long getdosmemdword(int offset)
{
unsigned long dw;
dosmemget(offset, sizeof(unsigned long), &dw);
return dw;
}
void setdosmembyte(int offset, unsigned char b)
{
dosmemput(&b, sizeof(unsigned char), offset);
}
void setdosmemword(int offset, unsigned short w)
{
dosmemput(&w, sizeof(unsigned short), offset);
}
void setdosmemdword(int offset, unsigned long d)
{
dosmemput(&d, sizeof(unsigned long), offset);
}
#endif
#if defined(__WATCOMC__) && defined(__386__)
void PDC_dpmi_int(int vector, pdc_dpmi_regs *rmregs)
{
union REGPACK regs = {0};
rmregs->w.ss = 0;
rmregs->w.sp = 0;
rmregs->w.flags = 0;
regs.w.ax = 0x300;
regs.h.bl = vector;
regs.x.edi = FP_OFF(rmregs);
regs.x.es = FP_SEG(rmregs);
intr(0x31, &regs);
}
#endif

View File

@ -227,10 +227,10 @@ static void _copy(void)
return;
#ifdef PDC_WIDE
wtmp = malloc((len + 1) * sizeof(wchar_t));
wtmp = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
len *= 3;
#endif
tmp = malloc(len + 1);
tmp = (char *)malloc(len + 1);
for (j = y_start, pos = 0; j <= y_end; j++)
{
@ -278,13 +278,13 @@ static int _paste(void)
return -1;
#ifdef PDC_WIDE
wpaste = malloc(len * sizeof(wchar_t));
wpaste = (wchar_t *)malloc(len * sizeof(wchar_t));
len = (long)PDC_mbstowcs(wpaste, paste, len);
#endif
newmax = len + SP->c_ungind;
if (newmax > SP->c_ungmax)
{
SP->c_ungch = realloc(SP->c_ungch, newmax * sizeof(int));
SP->c_ungch = (int *)realloc(SP->c_ungch, newmax * sizeof(int));
if (!SP->c_ungch)
return -1;
SP->c_ungmax = newmax;
@ -406,6 +406,60 @@ static int _mouse_key(void)
return key;
}
/* ftime() is consided obsolete. But it's all we have for
millisecond precision on older compilers/systems. We'll
use gettimeofday() when available. */
#if defined(__TURBOC__) || defined(__EMX__) || defined(__DJGPP__) || \
defined( __DMC__) || defined(__WATCOMC__) || defined(_MSC_VER)
#include <sys/timeb.h>
long PDC_millisecs( void)
{
struct timeb t;
ftime( &t);
return( (long)t.time * 1000L + (long)t.millitm);
}
#else
#include <sys/time.h>
long PDC_millisecs( void)
{
struct timeval t;
gettimeofday( &t, NULL);
return( t.tv_sec * 1000 + t.tv_usec / 1000);
}
#endif
/* On many systems, checking for a key hit is quite slow. If
PDC_check_key( ) returns FALSE, we can safely stop checking for
a key hit for a millisecond. This ensures we won't call it more
than 1000 times per second.
On DOS, it appears that checking the time is so slow that we're
better off (by a small margin) not using this scheme. */
static bool _fast_check_key( void)
{
#if defined( __DMC__) && !defined( _WIN32)
return( PDC_check_key( ));
#else
static long prev_millisecond;
const long curr_ms = PDC_millisecs( );
bool rval;
if( prev_millisecond == curr_ms)
return( FALSE);
rval = PDC_check_key( );
if( !rval)
prev_millisecond = curr_ms;
return( rval);
#endif
}
bool PDC_is_function_key( const int key)
{
return( key >= KEY_MIN && key < KEY_MAX);
@ -466,7 +520,7 @@ int wgetch(WINDOW *win)
{
/* is there a keystroke ready? */
while( !PDC_check_key())
while( !_fast_check_key())
{
/* if not, handle timeout() and halfdelay() */
int nap_time = 50;
@ -486,26 +540,36 @@ int wgetch(WINDOW *win)
key = PDC_get_key();
/* copy or paste? */
/* loop back if we did not get a key yet */
#ifndef _WIN32
if (SP->key_modifiers & PDC_KEY_MODIFIER_SHIFT)
#endif
{
if (PDC_function_key[FUNCTION_KEY_COPY] == key)
{
_copy();
continue;
}
else if (PDC_function_key[FUNCTION_KEY_PASTE] == key)
key = _paste();
}
if (key == -1)
continue;
/* filter mouse events; translate mouse clicks in the slk
area to function keys */
area to function keys (especially copy + pase) */
if( key == KEY_MOUSE)
{
key = _mouse_key();
}
else
{
/* copy or paste? */
#ifndef _WIN32
if (SP->key_modifiers & PDC_KEY_MODIFIER_SHIFT)
#endif
{
if (PDC_function_key[FUNCTION_KEY_COPY] == key)
{
_copy();
continue;
}
else if (PDC_function_key[FUNCTION_KEY_PASTE] == key)
key = _paste();
}
}
/* filter special keys if not in keypad mode */

View File

@ -74,12 +74,17 @@ int wgetnstr(WINDOW *win, char *str, int n)
{
#ifdef PDC_WIDE
wchar_t wstr[MAXLINE + 1];
wint_t wintstr[MAXLINE + 1];
int i;
if (n < 0 || n > MAXLINE)
n = MAXLINE;
if (wgetn_wstr(win, (wint_t *)wstr, n) == ERR)
if (wgetn_wstr(win, wintstr, n) == ERR)
return ERR;
for (i = 0; i < n; ++i) {
wstr[i] = (wchar_t)wintstr[i];
}
return (int)PDC_wcstombs(str, wstr, n);
#else

View File

@ -18,7 +18,6 @@ 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);
@ -52,15 +51,6 @@ 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.
@ -203,6 +193,9 @@ WINDOW *initscr(void)
LINES = SP->lines = PDC_get_rows();
COLS = SP->cols = PDC_get_columns();
if( PDC_init_atrtab()) /* set up default colors */
return NULL;
if (LINES < 2 || COLS < 2)
{
fprintf(stderr, "initscr(): LINES=%d COLS=%d: too small.\n",
@ -268,8 +261,6 @@ WINDOW *initscr(void)
else
curscr->_clear = TRUE;
if( PDC_init_atrtab()) /* set up default colors */
return NULL;
MOUSE_X_POS = MOUSE_Y_POS = -1;
BUTTON_STATUS(1) = BUTTON_RELEASED;
@ -333,14 +324,6 @@ bool isendwin(void)
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"));
@ -360,26 +343,32 @@ SCREEN *set_term(SCREEN *new)
return (new == SP) ? SP : NULL;
}
void PDC_free_pair_hash_table( void); /* color.c */
void delscreen(SCREEN *sp)
{
int i = 0;
struct _opaque_screen_t *optr;
PDC_LOG(("delscreen() - called\n"));
assert( SP);
if (!SP || sp != SP)
return;
traceoff( );
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 */
delwin(stdscr);
delwin(curscr);
delwin(SP->lastscr);
/* Mark all windows as 'parentless'. That way, we can */
/* delete all windows associated with SP. */
optr = SP->opaque;
for( i = 0; i < optr->n_windows; i++)
optr->window_list[i]->_parent = NULL;
while( optr->n_windows)
delwin( optr->window_list[0]);
PDC_free_atrtab( );
stdscr = (WINDOW *)NULL;
curscr = (WINDOW *)NULL;
SP->lastscr = (WINDOW *)NULL;

View File

@ -1,4 +1,4 @@
/* PDCurses */
/* PDCursesMod */
#include <curspriv.h>
#include <assert.h>
@ -28,6 +28,7 @@ inopts
void qiflush(void);
void timeout(int delay);
void wtimeout(WINDOW *win, int delay);
int wgetdelay(const WINDOW *win);
int typeahead(int fildes);
bool PDC_getcbreak(void);
bool PDC_getecho(void);
@ -36,6 +37,8 @@ inopts
int nocrmode(void);
bool is_keypad(const WINDOW *win);
bool is_nodelay(const WINDOW *win);
bool is_notimeout(const WINDOW *win);
### Description
@ -89,6 +92,8 @@ inopts
delay is given; i.e., 1-99 will wait 50ms, 100-149 will wait 100ms,
etc.
wgetdelay() returns the delay timeout as set in wtimeout().
intrflush(), notimeout(), noqiflush(), qiflush() and typeahead() do
nothing in PDCurses, but are included for compatibility with other
curses implementations.
@ -98,10 +103,16 @@ inopts
is_keypad() reports whether the specified window is in keypad mode.
is_nodelay() reports whether the specified window is in nodelay mode.
### Return Value
All functions except is_keypad() and the void functions return OK on
success and ERR on error.
All functions that return integers return OK on success and ERR on
error. is_keypad() and is_nodelay() return TRUE or FALSE.
is_notimeout() is provided for compatibility with other curses
implementations. It has no real meaning in PDCursesMod and will
always return FALSE.
### Portability
X/Open ncurses NetBSD
@ -125,10 +136,13 @@ inopts
qiflush Y Y Y
timeout Y Y Y
wtimeout Y Y Y
wgetdelay - Y -
typeahead Y Y Y
crmode Y Y Y
nocrmode Y Y Y
is_keypad - Y Y
is_nodelay - Y -
is_notimeout - Y -
**man-end****************************************************************/
@ -298,6 +312,17 @@ int notimeout(WINDOW *win, bool flag)
return OK;
}
int wgetdelay(const WINDOW *win)
{
PDC_LOG(("wgetdelay() - called\n"));
assert( win);
if (!win)
return 0;
return win->_delayms;
}
int raw(void)
{
PDC_LOG(("raw() - called\n"));
@ -410,3 +435,24 @@ bool is_keypad(const WINDOW *win)
return win->_use_keypad;
}
bool is_nodelay(const WINDOW *win)
{
PDC_LOG(("is_nodelay() - called\n"));
assert( win);
if (!win)
return FALSE;
return win->_nodelay;
}
bool is_notimeout(const WINDOW *win)
{
PDC_LOG(("is_notimeout() - called - returning FALSE...\n"));
assert( win);
INTENTIONALLY_UNUSED_PARAMETER( win);
return FALSE;
}

View File

@ -115,10 +115,10 @@ static int _restore_mode(int i)
{
if (ctty[i].been_set == TRUE)
{
void *atrtab = SP->atrtab;
void *opaque = SP->opaque;
memcpy(SP, &(ctty[i].saved), sizeof(SCREEN));
SP->atrtab = atrtab;
SP->opaque = opaque;
if (ctty[i].saved.raw_out)
raw();

View File

@ -42,7 +42,7 @@ char *keyname(int key)
/* Key names must be in exactly the same order as in curses.h */
static char *key_names[] =
static const char *key_names[] =
{
"KEY_BREAK", "KEY_DOWN", "KEY_UP", "KEY_LEFT", "KEY_RIGHT",
"KEY_HOME", "KEY_BACKSPACE", "KEY_F0", "KEY_F(1)", "KEY_F(2)",

View File

@ -1,4 +1,4 @@
/* PDCurses */
/* PDCursesMod */
#include <curspriv.h>
#include <assert.h>
@ -17,11 +17,17 @@ outopts
int leaveok(WINDOW *win, bool bf);
int setscrreg(int top, int bot);
int wsetscrreg(WINDOW *win, int top, int bot);
int wgetscrreg(const WINDOW *win, int *top, int *bot);
int scrollok(WINDOW *win, bool bf);
int raw_output(bool bf);
bool is_cleared(const WINDOW *win);
bool is_idlok(const WINDOW *win);
bool is_idcok(const WINDOW *win);
bool is_immedok(const WINDOW *win);
bool is_leaveok(const WINDOW *win);
bool is_scrollok(const WINDOW *win);
### Description
@ -43,20 +49,36 @@ outopts
will cause all lines in the scrolling region to scroll up one line.
setscrreg() is the stdscr version.
idlok() and idcok() do nothing in PDCurses, but are provided for
compatibility with other curses implementations.
wgetscrreg() gets the top and bottom margins as set in wsetscrreg().
idlok(), idcok(), is_idlok() and is_idcok() do nothing in PDCursesMod,
but are provided for compatibility with other curses implementations.
raw_output() enables the output of raw characters using the standard
*add* and *ins* curses functions (that is, it disables translation of
control characters).
is_cleared() reports whether the specified window causes clear at next
refresh.
is_immedok() reports whether the specified window is in immedok mode.
is_leaveok() reports whether the specified window is in leaveok mode.
is_scrollok() reports whether the specified window allows scrolling.
### Return Value
All functions except is_leaveok() return OK on success and ERR on
All functions returning integers return OK on success and ERR on
error.
is_cleared(), is_immedok(), is_leaveok() and is_scrollok() are
booleans and return TRUE or FALSE.
is_idlok() and is_idcok() are provided for compatibility with other
curses implementations. They have no real meaning in PDCursesMod and
will always return FALSE.
### Portability
X/Open ncurses NetBSD
clearok Y Y Y
@ -66,8 +88,14 @@ outopts
leaveok Y Y Y
setscrreg Y Y Y
wsetscrreg Y Y Y
wgetscrreg - Y -
scrollok Y Y Y
is_cleared - Y -
is_idlok - Y -
is_idcok - Y -
is_immedok - Y -
is_leaveok - Y Y
is_scrollok - Y -
raw_output - - -
**man-end****************************************************************/
@ -148,6 +176,22 @@ int wsetscrreg(WINDOW *win, int top, int bottom)
return ERR;
}
int wgetscrreg(const WINDOW *win, int *top, int *bot)
{
PDC_LOG(("wgetscrreg() - called\n"));
assert( win);
assert( top);
assert( bot);
if (!win || !top || !bot)
return ERR;
*top = win->_tmarg;
*bot = win->_bmarg;
return OK;
}
int scrollok(WINDOW *win, bool bf)
{
PDC_LOG(("scrollok() - called\n"));
@ -161,6 +205,70 @@ int scrollok(WINDOW *win, bool bf)
return OK;
}
bool is_cleared(const WINDOW *win)
{
PDC_LOG(("is_cleared() - called\n"));
assert( win);
if (!win)
return FALSE;
return win->_clear;
}
bool is_idlok(const WINDOW *win)
{
PDC_LOG(("is_idlok() - called\n"));
INTENTIONALLY_UNUSED_PARAMETER( win);
assert( win);
return FALSE;
}
bool is_idcok(const WINDOW *win)
{
PDC_LOG(("is_idcok() - called\n"));
INTENTIONALLY_UNUSED_PARAMETER( win);
assert( win);
return FALSE;
}
bool is_immedok(const WINDOW *win)
{
PDC_LOG(("is_immedok() - called\n"));
assert( win);
if (!win)
return FALSE;
return win->_immed;
}
bool is_leaveok(const WINDOW *win)
{
PDC_LOG(("is_leaveok() - called\n"));
assert( win);
if (!win)
return FALSE;
return win->_leaveit;
}
bool is_scrollok(const WINDOW *win)
{
PDC_LOG(("is_scrollok() - called\n"));
assert( win);
if (!win)
return FALSE;
return win->_scroll;
}
int raw_output(bool bf)
{
PDC_LOG(("raw_output() - called\n"));
@ -173,14 +281,3 @@ int raw_output(bool bf)
return OK;
}
bool is_leaveok(const WINDOW *win)
{
PDC_LOG(("is_leaveok() - called\n"));
assert( win);
if (!win)
return FALSE;
return win->_leaveit;
}

View File

@ -74,6 +74,8 @@ pad
**man-end****************************************************************/
void PDC_add_window_to_list( WINDOW *win);
#include <string.h>
/* save values for pechochar() */
@ -104,6 +106,7 @@ WINDOW *newpad(int nlines, int ncols)
win->_smincol = 0;
win->_smaxrow = min(LINES, nlines) - 1;
win->_smaxcol = min(COLS, ncols) - 1;
PDC_add_window_to_list( win);
return win;
}
@ -160,6 +163,7 @@ WINDOW *subpad(WINDOW *orig, int nlines, int ncols, int begy, int begx)
win->_smincol = 0;
win->_smaxrow = min(LINES, nlines) - 1;
win->_smaxcol = min(COLS, ncols) - 1;
PDC_add_window_to_list( win);
return win;
}

View File

@ -130,9 +130,30 @@ panel
#include <panel.h>
#include <stdlib.h>
PANEL *_bottom_panel = (PANEL *)0;
PANEL *_top_panel = (PANEL *)0;
PANEL _stdscr_pseudo_panel;
typedef struct panelobs PANELOBS;
struct panelobs
{
struct panelobs *above;
struct panel *pan;
};
struct panel
{
WINDOW *win;
int wstarty;
int wendy;
int wstartx;
int wendx;
struct panel *below;
struct panel *above;
const void *user;
struct panelobs *obscure;
};
static PANEL *_bottom_panel = (PANEL *)0;
static PANEL *_top_panel = (PANEL *)0;
static PANEL _stdscr_pseudo_panel;
#ifdef PANEL_DEBUG

View File

@ -6,13 +6,6 @@ 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
#define uint32_t unsigned long
#define uint16_t unsigned short
#else
#include <stdint.h>
#endif
#include <stdlib.h>
#include <assert.h>

View File

@ -66,25 +66,28 @@ scr_dump
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);
const uint32_t x = (uint32_t)text | ((uint32_t)attribs << 21);
const uint32_t y = ((uint32_t)attribs >> 11) | ((uint32_t)color_pair << 1);
x = (uint64_t)text | ((uint64_t)attribs << 21) | ((uint64_t)color_pair << 33);
memcpy( buff, &x, 8);
memcpy( buff, &x, 4);
memcpy( buff + 4, &y, 4);
/* 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;
uint32_t x, y;
chtype c, 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;
memcpy( &x, buff, 4);
memcpy( &y, buff + 4, 4);
text = (chtype)x & A_CHARTEXT;
attribs = (chtype)( ((x >> 21) & 0xfff) | ((y & 1) << 11));
color_pair = (chtype)(y >> 1) & 0xfffff;
c = text | (attribs << PDC_CHARTEXT_BITS) | COLOR_PAIR( color_pair);
return( (chtype)c);
}
@ -153,6 +156,12 @@ int putwin(WINDOW *win, FILE *filep)
return OK;
}
void PDC_add_window_to_list( WINDOW *win);
#ifdef _MSC_VER
#pragma warning( disable: 4701) /* suppress spurious warnings */
#endif /* about 'uninitialised' variables */
WINDOW *getwin(FILE *filep)
{
WINDOW *win, temp_win;
@ -246,10 +255,15 @@ WINDOW *getwin(FILE *filep)
}
touchwin(win);
PDC_add_window_to_list( win);
return win;
}
#ifdef _MSC_VER
#pragma warning( default: 4701)
#endif
int scr_dump(const char *filename)
{
FILE *filep;

View File

@ -1,4 +1,4 @@
/* PDCurses */
/* PDCursesMod */
#include <curspriv.h>
#include <assert.h>
@ -28,11 +28,8 @@ slk
int slk_wset(int labnum, const wchar_t *label, int justify);
int PDC_mouse_in_slk(int y, int x);
void PDC_slk_free(void);
void PDC_slk_initialize(void);
wchar_t *slk_wlabel(int labnum)
wchar_t *slk_wlabel(int labnum);
attr_t slk_attr( void); (ncurses extension)
### Description
@ -54,12 +51,12 @@ slk
2 lines used
55 5-5 format (pdcurses format)
In PDCurses, one can alternatively set fmt as a series of hex
In PDCursesMod, one can alternatively set fmt as a series of hex
digits specifying the format. For example, 0x414 would result
in 4-1-4 format; 0x21b3 would result in 2-1-11-3 format; and
so on. Also, negating fmt results in the index line being added.
Also, in PDCurses, one can call slk_init() at any time
Also, in PDCursesMod, one can call slk_init() at any time
_after_ initscr(), to reset the label format. If you do this,
you'll need to reset the label text and call slk_refresh(). However,
you can't toggle the index line or turn SLK on or off after initscr()
@ -89,10 +86,8 @@ slk
slk_attr_on Y Y Y
slk_attr_set Y Y Y
slk_attr_off Y Y Y
slk_attr - Y -
slk_wset Y Y Y
PDC_mouse_in_slk - - -
PDC_slk_free - - -
PDC_slk_initialize - - -
slk_wlabel - - -
**man-end****************************************************************/
@ -157,7 +152,7 @@ int slk_init(int fmt)
fmt, labels, slk));
if( slk)
free( slk);
slk = calloc(labels, sizeof(struct SLK));
slk = (struct SLK *)calloc(labels, sizeof(struct SLK));
PDC_LOG(( "New slk: %p; SP = %p\n", slk, SP));
if (!slk)
@ -437,6 +432,18 @@ int slk_attrset(const chtype attrs)
return rc;
}
attr_t slk_attr( void)
{
PDC_LOG(("slk_attrset() - called\n"));
assert( SP);
if (!SP)
return ERR;
assert( SP->slk_winptr);
return( SP->slk_winptr->_attrs & (A_ATTRIBUTES & ~A_COLOR));
}
int extended_slk_color( int pair)
{
int rc;

View File

@ -470,7 +470,7 @@ static int _process_key_event(void)
#ifdef PDC_WIDE
KEV.uChar.UnicodeChar;
#else
KEV.uChar.AsciiChar;
(unsigned char)KEV.uChar.AsciiChar;
#endif
WORD vk = KEV.wVirtualKeyCode;
DWORD state = KEV.dwControlKeyState;

View File

@ -718,7 +718,3 @@ void PDC_set_resize_limits( const int new_min_lines, const int new_max_lines,
INTENTIONALLY_UNUSED_PARAMETER( new_min_cols);
INTENTIONALLY_UNUSED_PARAMETER( new_max_cols);
}
void PDC_free_platform_dependent_memory( void)
{
}

View File

@ -1,8 +1,5 @@
/* PDCurses */
#ifndef __PDC_WIN_H__
#define __PDC_WIN_H__
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
# define _CRT_SECURE_NO_DEPRECATE 1 /* kill nonsense warnings */
#endif
@ -11,6 +8,10 @@
# define _CRT_SECURE_NO_DEPRECATE 1 /* kill nonsense warnings */
#endif
#if defined( PDC_FORCE_UTF8)
#define PDC_WIDE
#endif
#if defined(PDC_WIDE) && !defined(UNICODE)
# define UNICODE
#endif
@ -32,5 +33,3 @@ extern short pdc_oldf, pdc_oldb, pdc_oldu;
extern bool pdc_conemu, pdc_wt, pdc_ansi;
extern void PDC_blink_text(void);
#endif

View File

@ -1,5 +1,6 @@
/* PDCurses */
#include <stdlib.h>
#include <curspriv.h>
#include <assert.h>
@ -16,19 +17,19 @@ window
WINDOW *subwin(WINDOW* orig, int nlines, int ncols,
int begy, int begx);
WINDOW *dupwin(WINDOW *win);
WINDOW *wgetparent(const WINDOW *win);
int delwin(WINDOW *win);
int mvwin(WINDOW *win, int y, int x);
int mvderwin(WINDOW *win, int pary, int parx);
int syncok(WINDOW *win, bool bf);
bool is_subwin(const WINDOW *win);
bool is_syncok(const WINDOW *win);
void wsyncup(WINDOW *win);
void wcursyncup(WINDOW *win);
void wsyncdown(WINDOW *win);
WINDOW *resize_window(WINDOW *win, int nlines, int ncols);
int wresize(WINDOW *win, int nlines, int ncols);
WINDOW *PDC_makelines(WINDOW *win);
WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx);
void PDC_sync(WINDOW *win);
### Description
@ -38,9 +39,8 @@ window
ncols to COLS - begx. Create a new full-screen window by calling
newwin(0, 0, 0, 0).
delwin() deletes the named window, freeing all associated memory. In
the case of overlapping windows, subwindows should be deleted before
the main window.
delwin() deletes the named window, freeing all associated memory.
Subwindows must be deleted before the main window can be deleted.
mvwin() moves the window so that the upper left-hand corner is at
position (y,x). If the move would cause the window to be off the
@ -65,11 +65,19 @@ window
dupwin() creates an exact duplicate of the window win.
wgetparent() returns the parent WINDOW pointer for subwindows, or NULL
for windows having no parent.
wsyncup() causes a touchwin() of all of the window's parents.
If wsyncok() is called with a second argument of TRUE, this causes a
If syncok() is called with a second argument of TRUE, this causes a
wsyncup() to be called every time the window is changed.
is_subwin() reports whether the specified window is a subwindow,
created by subwin() or derwin().
is_syncok() reports whether the specified window is in syncok mode.
wcursyncup() causes the current cursor position of all of a window's
ancestors to reflect the current cursor position of the current
window.
@ -85,16 +93,6 @@ window
window. (However, you still can call it _on_ subwindows.) It returns
OK or ERR.
PDC_makenew() allocates all data for a new WINDOW * except the actual
lines themselves. If it's unable to allocate memory for the window
structure, it will free all allocated memory and return a NULL
pointer.
PDC_makelines() allocates the memory for the lines.
PDC_sync() handles wrefresh() and wsyncup() calls when a window is
changed.
### Return Value
newwin(), subwin(), derwin() and dupwin() return a pointer to the new
@ -120,19 +118,31 @@ window
derwin Y Y Y
mvderwin Y Y Y
dupwin Y Y Y
wgetparent - Y -
wsyncup Y Y Y
syncok Y Y Y
is_subwin - Y -
is_syncok - Y -
wcursyncup Y Y Y
wsyncdown Y Y Y
wresize - Y Y
resize_window - - -
PDC_makelines - - -
PDC_makenew - - -
PDC_sync - - -
**man-end****************************************************************/
#include <stdlib.h>
/*library-internals-begin************************************************
PDC_makenew() allocates all data for a new WINDOW * except the actual
lines themselves. If it's unable to allocate memory for the window
structure, it will free all allocated memory and return a NULL
pointer.
PDC_makelines() allocates the memory for the lines.
PDC_sync() handles wrefresh() and wsyncup() calls when a window is
changed.
**library-internals-end**************************************************/
WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx)
{
@ -143,17 +153,17 @@ WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx)
/* allocate the window structure itself */
win = calloc(1, sizeof(WINDOW));
win = (WINDOW *)calloc(1, sizeof(WINDOW));
if (!win)
return win;
/* allocate the line pointer array */
win->_y = malloc(nlines * sizeof(chtype *));
win->_y = (chtype **)malloc(nlines * sizeof(chtype *));
/* allocate the minchng and maxchng arrays */
win->_firstch = malloc(nlines * sizeof(int) * 2);
win->_firstch = (int *)malloc(nlines * sizeof(int) * 2);
if (!win->_firstch || !win->_y)
{
delwin( win);
@ -193,7 +203,7 @@ WINDOW *PDC_makelines(WINDOW *win)
nlines = win->_maxy;
ncols = win->_maxx;
win->_y[0] = malloc(ncols * nlines * sizeof(chtype));
win->_y[0] = (chtype *)malloc(ncols * nlines * sizeof(chtype));
if (!win->_y[0])
{
/* if error, free all the data */
@ -217,6 +227,24 @@ void PDC_sync(WINDOW *win)
wsyncup(win);
}
#define is_power_of_two( X) (!((X) & ((X) - 1)))
static void _resize_window_list( SCREEN *scr_ptr)
{
if( is_power_of_two( scr_ptr->opaque->n_windows))
scr_ptr->opaque->window_list =
(WINDOW **)realloc( scr_ptr->opaque->window_list,
scr_ptr->opaque->n_windows * 2 * sizeof( WINDOW *));
}
void PDC_add_window_to_list( WINDOW *win)
{
SP->opaque->n_windows++;
_resize_window_list( SP);
assert( SP->opaque->window_list);
SP->opaque->window_list[SP->opaque->n_windows - 1] = win;
}
WINDOW *newwin(int nlines, int ncols, int begy, int begx)
{
WINDOW *win;
@ -238,19 +266,44 @@ WINDOW *newwin(int nlines, int ncols, int begy, int begx)
win = PDC_makelines(win);
if (win)
{
werase(win);
PDC_add_window_to_list( win);
}
return win;
}
int delwin(WINDOW *win)
{
PDC_LOG(("delwin() - called\n"));
int i;
PDC_LOG(("delwin() - called\n"));
assert( win);
if (!win)
return ERR;
/* make sure win has no subwindows */
for( i = 0; i < SP->opaque->n_windows; i++)
{
assert( SP->opaque->window_list[i]->_parent != win);
if( SP->opaque->window_list[i]->_parent == win)
return( ERR);
}
if( win->_firstch && win->_y && win->_y[0])
{
i = 0; /* make sure win is in the window list */
while( i < SP->opaque->n_windows && SP->opaque->window_list[i] != win)
i++;
assert( i < SP->opaque->n_windows);
if( i == SP->opaque->n_windows)
return( ERR);
SP->opaque->n_windows--; /* remove win from window list */
SP->opaque->window_list[i] = SP->opaque->window_list[SP->opaque->n_windows];
_resize_window_list( SP);
}
/* subwindows use parents' lines */
if (!(win->_flags & (_SUBWIN|_SUBPAD)))
@ -262,7 +315,6 @@ int delwin(WINDOW *win)
if( win->_y)
free(win->_y);
free(win);
return OK;
}
@ -329,6 +381,7 @@ WINDOW *subwin(WINDOW *orig, int nlines, int ncols, int begy, int begx)
win->_y[i] = orig->_y[j] + k;
win->_flags |= _SUBWIN;
PDC_add_window_to_list( win);
return win;
}
@ -366,7 +419,7 @@ int mvderwin(WINDOW *win, int pary, int parx)
WINDOW *dupwin(WINDOW *win)
{
WINDOW *new;
WINDOW *new_win;
chtype *ptr, *ptr1;
int nlines, ncols, begy, begx, i;
@ -379,52 +432,64 @@ WINDOW *dupwin(WINDOW *win)
begy = win->_begy;
begx = win->_begx;
new = PDC_makenew(nlines, ncols, begy, begx);
if (new)
new = PDC_makelines(new);
new_win = PDC_makenew(nlines, ncols, begy, begx);
if (new_win)
new_win = PDC_makelines(new_win);
if (!new)
if (!new_win)
return (WINDOW *)NULL;
/* copy the contents of win into new */
/* copy the contents of win into new_win */
for (i = 0; i < nlines; i++)
{
for (ptr = new->_y[i], ptr1 = win->_y[i];
ptr < new->_y[i] + ncols; ptr++, ptr1++)
for (ptr = new_win->_y[i], ptr1 = win->_y[i];
ptr < new_win->_y[i] + ncols; ptr++, ptr1++)
*ptr = *ptr1;
PDC_mark_line_as_changed( new, i);
PDC_mark_line_as_changed( new_win, i);
}
new->_curx = win->_curx;
new->_cury = win->_cury;
new->_maxy = win->_maxy;
new->_maxx = win->_maxx;
new->_begy = win->_begy;
new->_begx = win->_begx;
new->_flags = win->_flags;
new->_attrs = win->_attrs;
new->_clear = win->_clear;
new->_leaveit = win->_leaveit;
new->_scroll = win->_scroll;
new->_nodelay = win->_nodelay;
new->_delayms = win->_delayms;
new->_use_keypad = win->_use_keypad;
new->_tmarg = win->_tmarg;
new->_bmarg = win->_bmarg;
new->_parx = win->_parx;
new->_pary = win->_pary;
new->_parent = win->_parent;
new->_bkgd = win->_bkgd;
new->_flags = win->_flags;
new_win->_curx = win->_curx;
new_win->_cury = win->_cury;
new_win->_maxy = win->_maxy;
new_win->_maxx = win->_maxx;
new_win->_begy = win->_begy;
new_win->_begx = win->_begx;
new_win->_flags = win->_flags;
new_win->_attrs = win->_attrs;
new_win->_clear = win->_clear;
new_win->_leaveit = win->_leaveit;
new_win->_scroll = win->_scroll;
new_win->_nodelay = win->_nodelay;
new_win->_delayms = win->_delayms;
new_win->_use_keypad = win->_use_keypad;
new_win->_tmarg = win->_tmarg;
new_win->_bmarg = win->_bmarg;
new_win->_parx = win->_parx;
new_win->_pary = win->_pary;
new_win->_parent = win->_parent;
new_win->_bkgd = win->_bkgd;
new_win->_flags = win->_flags;
PDC_add_window_to_list( new_win);
return new;
return new_win;
}
WINDOW *wgetparent(const WINDOW *win)
{
PDC_LOG(("wgetparent() - called\n"));
assert( win);
if (!win)
return NULL;
return win->_parent;
}
WINDOW *resize_window(WINDOW *win, int nlines, int ncols)
{
WINDOW *new;
WINDOW *new_win;
int save_cury, save_curx, new_begy, new_begx;
PDC_LOG(("resize_window() - called: nlines %d ncols %d\n",
@ -437,14 +502,14 @@ WINDOW *resize_window(WINDOW *win, int nlines, int ncols)
if (win->_flags & _SUBPAD)
{
new = subpad(win->_parent, nlines, ncols, win->_begy, win->_begx);
if (!new)
new_win = subpad(win->_parent, nlines, ncols, win->_begy, win->_begx);
if (!new_win)
return (WINDOW *)NULL;
}
else if (win->_flags & _SUBWIN)
{
new = subwin(win->_parent, nlines, ncols, win->_begy, win->_begx);
if (!new)
new_win = subwin(win->_parent, nlines, ncols, win->_begy, win->_begx);
if (!new_win)
return (WINDOW *)NULL;
}
else
@ -460,53 +525,52 @@ WINDOW *resize_window(WINDOW *win, int nlines, int ncols)
new_begx = win->_begx;
}
new = PDC_makenew(nlines, ncols, new_begy, new_begx);
if (!new)
new_win = PDC_makenew(nlines, ncols, new_begy, new_begx);
if (!new_win)
return (WINDOW *)NULL;
}
save_curx = min(win->_curx, (new->_maxx - 1));
save_cury = min(win->_cury, (new->_maxy - 1));
save_curx = min(win->_curx, (new_win->_maxx - 1));
save_cury = min(win->_cury, (new_win->_maxy - 1));
if (!(win->_flags & (_SUBPAD|_SUBWIN)))
{
new = PDC_makelines(new);
if (!new)
new_win = PDC_makelines(new_win);
if (!new_win)
return (WINDOW *)NULL;
new->_bkgd = win->_bkgd;
werase(new);
new_win->_bkgd = win->_bkgd;
werase(new_win);
copywin(win, new, 0, 0, 0, 0, min(win->_maxy, new->_maxy) - 1,
min(win->_maxx, new->_maxx) - 1, FALSE);
copywin(win, new_win, 0, 0, 0, 0, min(win->_maxy, new_win->_maxy) - 1,
min(win->_maxx, new_win->_maxx) - 1, FALSE);
if (win->_y[0])
free(win->_y[0]);
}
new->_flags = win->_flags;
new->_attrs = win->_attrs;
new->_clear = win->_clear;
new->_leaveit = win->_leaveit;
new->_scroll = win->_scroll;
new->_nodelay = win->_nodelay;
new->_delayms = win->_delayms;
new->_use_keypad = win->_use_keypad;
new->_tmarg = (win->_tmarg > new->_maxy - 1) ? 0 : win->_tmarg;
new->_bmarg = (win->_bmarg == win->_maxy - 1) ?
new->_maxy - 1 : min(win->_bmarg, (new->_maxy - 1));
new->_parent = win->_parent;
new->_immed = win->_immed;
new->_sync = win->_sync;
new->_bkgd = win->_bkgd;
new_win->_flags = win->_flags;
new_win->_attrs = win->_attrs;
new_win->_clear = win->_clear;
new_win->_leaveit = win->_leaveit;
new_win->_scroll = win->_scroll;
new_win->_nodelay = win->_nodelay;
new_win->_delayms = win->_delayms;
new_win->_use_keypad = win->_use_keypad;
new_win->_tmarg = (win->_tmarg > new_win->_maxy - 1) ? 0 : win->_tmarg;
new_win->_bmarg = (win->_bmarg == win->_maxy - 1) ?
new_win->_maxy - 1 : min(win->_bmarg, (new_win->_maxy - 1));
new_win->_parent = win->_parent;
new_win->_immed = win->_immed;
new_win->_sync = win->_sync;
new_win->_bkgd = win->_bkgd;
new->_curx = save_curx;
new->_cury = save_cury;
new_win->_curx = save_curx;
new_win->_cury = save_cury;
free(win->_firstch);
free(win->_y);
*win = *new;
free(new);
*win = *new_win;
free(new_win);
return win;
}
@ -539,6 +603,28 @@ int syncok(WINDOW *win, bool bf)
return OK;
}
bool is_subwin(const WINDOW *win)
{
PDC_LOG(("is_subwin() - called\n"));
assert( win);
if (!win)
return FALSE;
return ((win->_flags & _SUBWIN) ? TRUE : FALSE);
}
bool is_syncok(const WINDOW *win)
{
PDC_LOG(("is_syncok() - called\n"));
assert( win);
if (!win)
return FALSE;
return win->_sync;
}
void wcursyncup(WINDOW *win)
{
WINDOW *tmp;

View File

@ -226,8 +226,8 @@ static LONG scale_font_for_current_dpi( LONG size)
}
int PDC_font_size = -1;
TCHAR PDC_font_name[256] = _T("\0");
TCHAR PDC_preferred_fontface[256] = _T("\0"); /* can be set by application */
TCHAR PDC_font_name[128];
TCHAR PDC_preferred_fontface[128]; /* can be set by application */
static TCHAR* PDC_default_font_name = _T("Courier New");
/* The calling application can override the default fontface with
@ -534,7 +534,6 @@ void PDC_transform_line_given_hdc( const HDC hdc, const int lineno,
mbtowc( &z, &c, 1);
ch = (chtype)z;
}
assert( "We should never get here");
#endif
buff[olen] = (wchar_t)ch;
lpDx[olen] = PDC_cxChar;

View File

@ -17,14 +17,17 @@ 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);
MSG msg;
extern HWND PDC_hWnd;
while( PeekMessage(&msg, PDC_hWnd, 0, 0, PM_REMOVE) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if( PDC_key_queue_low != PDC_key_queue_high)
return TRUE;
return FALSE;

View File

@ -2,7 +2,6 @@
#include "pdcwin.h"
#include <tchar.h>
#include <stdint.h>
#include <assert.h>
#include "pdccolor.h"
#ifdef WIN32_LEAN_AND_MEAN
@ -28,7 +27,7 @@ inlined functions. Until we puzzle out which ones do and which
don't, we'll just leave "inlined" functions as plain old static
functions. */
#ifdef _MSC_VER
#if defined( _MSC_VER) || defined( __BORLANDC__)
#define INLINE static
#else
#define INLINE static inline
@ -150,6 +149,8 @@ void PDC_scr_close(void)
void PDC_scr_free(void)
{
PDC_free_palette( );
DestroyWindow( PDC_hWnd);
ttytype[1] = 0;
}
int PDC_choose_a_new_font( void); /* pdcdisp.c */
@ -985,7 +986,6 @@ INLINE int set_default_sizes_from_registry( const int n_cols, const int n_rows,
static void adjust_font_size( const int font_size_change)
{
extern int PDC_font_size;
RECT client_rect;
PDC_font_size += font_size_change;
if( PDC_font_size < 2)
@ -1002,6 +1002,8 @@ static void adjust_font_size( const int font_size_change)
/* you disagree, I have others. */
if( IsZoomed( PDC_hWnd))
{
RECT client_rect;
GetClientRect(PDC_hWnd, &client_rect);
PDC_n_rows = client_rect.bottom / PDC_cyChar;
PDC_n_cols = client_rect.right / PDC_cxChar;
@ -1071,8 +1073,9 @@ 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, DWORD window_style,
DWORD window_ex_style)
static void adjust_window_size( int *xpixels, int *ypixels,
const DWORD window_style,
const DWORD window_ex_style)
{
RECT rect;
@ -1195,7 +1198,7 @@ INLINE void HandleSizing( WPARAM wParam, LPARAM lParam )
rect->left = rect->right - rounded_width;
}
typedef void(*resize_callback_fnptr)();
typedef void(*resize_callback_fnptr)(void);
static resize_callback_fnptr resize_callback = NULL;
void PDC_set_window_resized_callback(resize_callback_fnptr callback) {
resize_callback = callback;
@ -1216,6 +1219,11 @@ static void HandleSize( const WPARAM wParam, const LPARAM lParam)
prev_wParam = SIZE_MINIMIZED;
return;
}
if( wParam == (WPARAM)-99)
{
prev_wParam = (WPARAM)-99;
return;
}
new_n_rows = n_ypixels / PDC_cyChar;
new_n_cols = n_xpixels / PDC_cxChar;
@ -1282,8 +1290,9 @@ struct BACK_BUFFER {
static void PrepareBackBuffer(HDC hdc, RECT rect)
{
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
const int width = rect.right - rect.left;
const int height = rect.bottom - rect.top;
memset(&back_buffer, 0, sizeof(back_buffer));
back_buffer.rect = rect;
back_buffer.window_dc = hdc;
@ -1294,17 +1303,15 @@ static void PrepareBackBuffer(HDC hdc, RECT rect)
back_buffer.is_rect_valid = width > 0 && height > 0;
}
static void BlitBackBuffer()
static void BlitBackBuffer( void)
{
const RECT* r = NULL;
int width = 0;
int height = 0;
if (back_buffer.is_rect_valid)
{
r = &back_buffer.rect;
width = r->right - r->left;
height = r->bottom - r->top;
const RECT* r = &back_buffer.rect;
const int width = r->right - r->left;
const int height = r->bottom - r->top;
BitBlt(
back_buffer.window_dc,
r->left, r->top,
@ -1325,7 +1332,6 @@ static void HandlePaint( HWND hwnd )
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); */
@ -1335,21 +1341,22 @@ static void HandlePaint( HWND hwnd )
PrepareBackBuffer(window_dc, client_rect);
memory_dc = back_buffer.memory_dc;
{
/* paint the background black. */
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 && PDC_n_cols > 0 && PDC_n_rows > 0)
{
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]);
}
/* paint the background black. */
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 && PDC_n_cols > 0 && PDC_n_rows > 0)
{
int i;
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);
@ -1739,7 +1746,7 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd,
static int xbutton_pressed = 0;
static int modified_key_to_return = 0;
static bool ignore_resize = FALSE;
int button = -1, action = -1;
int button, action;
PDC_hWnd = hwnd;
if( !hwnd)
@ -1808,6 +1815,7 @@ static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd,
{
const int mouse_x = LOWORD( lParam) / PDC_cxChar;
const int mouse_y = HIWORD( lParam) / PDC_cyChar;
if( add_mouse( 0, BUTTON_MOVED, mouse_x, mouse_y))
modified_key_to_return = 0;
}
@ -2062,7 +2070,6 @@ it's inlined. */
INLINE int set_up_window( void)
{
/* create the dialog window */
WNDCLASS wndclass ;
HMENU hMenu;
HANDLE hInstance = GetModuleHandle( NULL);
int n_default_columns = 80;
@ -2087,6 +2094,7 @@ INLINE int set_up_window( void)
if( !wndclass_has_been_registered)
{
ATOM rval;
WNDCLASS wndclass ;
wndclass.style = CS_VREDRAW | CS_HREDRAW;
wndclass.lpfnWndProc = WndProc ;
@ -2148,9 +2156,11 @@ INLINE int set_up_window( void)
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);
adjust_window_size( &xsize, &ysize, window_style, window_ex_style);
}
HandleSize( (WPARAM)-99, 0);
PDC_hWnd = CreateWindowEx( window_ex_style,
AppName, WindowTitle,
window_style,
@ -2210,6 +2220,7 @@ int PDC_scr_open(void)
return ERR;
debug_printf( "colors alloc\n");
PDC_bDone = FALSE;
SP->mouse_wait = PDC_CLICK_PERIOD;
SP->visibility = 0; /* no cursor, by default */
SP->curscol = SP->cursrow = 0;
@ -2353,7 +2364,3 @@ int PDC_init_color( int color, int red, int green, int blue)
PDC_set_palette_entry( color, new_rgb);
return OK;
}
void PDC_free_platform_dependent_memory( void)
{
}