mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-31 10:50:16 -06:00
PDCurses 2021-12-08 (f1cd4f45)
Code extracted from:
https://github.com/wmcbrine/PDCurses.git
at commit f1cd4f4569451a5028ddf3d3c202f0ad6b1ae446 (f1cd4f4569451a5028ddf3d3c202f0ad6b1ae446).
This commit is contained in:
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* -whitespace
|
||||
65
README.md
Normal file
65
README.md
Normal file
@@ -0,0 +1,65 @@
|
||||
Welcome to PDCurses!
|
||||
====================
|
||||
|
||||
PDCurses is an implementation of X/Open curses for multiple platforms.
|
||||
The latest version can be found at:
|
||||
|
||||
https://pdcurses.org/
|
||||
|
||||
For changes, see the [History] file. The main documentation is now in
|
||||
the [docs] directory.
|
||||
|
||||
|
||||
Legal Stuff
|
||||
-----------
|
||||
|
||||
The core package is in the public domain, but small portions of PDCurses
|
||||
are subject to copyright under various licenses. Each directory
|
||||
contains a README.md file, with a section titled "Distribution Status"
|
||||
which describes the status of the files in that directory.
|
||||
|
||||
If you use PDCurses in an application, an acknowledgement would be
|
||||
appreciated, but is not mandatory. If you make corrections or
|
||||
enhancements to PDCurses, please forward them to the current maintainer
|
||||
for the benefit of other users.
|
||||
|
||||
This software is provided AS IS with NO WARRANTY whatsoever.
|
||||
|
||||
|
||||
Ports
|
||||
-----
|
||||
|
||||
PDCurses has been ported to DOS, OS/2, Windows, X11 and SDL. A directory
|
||||
containing the port-specific source files exists for each of these
|
||||
platforms.
|
||||
|
||||
Build instructions are in the README.md file for each platform:
|
||||
|
||||
- [DOS]
|
||||
- [OS/2]
|
||||
- [SDL 1.x]
|
||||
- [SDL 2.x]
|
||||
- [Windows]
|
||||
- [X11]
|
||||
|
||||
|
||||
Distribution Status
|
||||
-------------------
|
||||
|
||||
All files in this directory (not including subdirectories) are released
|
||||
to the public domain.
|
||||
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
William McBrine <wmcbrine@gmail.com>
|
||||
|
||||
[History]: docs/HISTORY.md
|
||||
[docs]: docs/README.md
|
||||
[DOS]: dos/README.md
|
||||
[OS/2]: os2/README.md
|
||||
[SDL 1.x]: sdl1/README.md
|
||||
[SDL 2.x]: sdl2/README.md
|
||||
[Windows]: wincon/README.md
|
||||
[X11]: x11/README.md
|
||||
35
common/acs437.h
Normal file
35
common/acs437.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* ACS definitions originally by jshumate@wrdis01.robins.af.mil -- these
|
||||
match code page 437 and compatible pages (CP850, CP852, etc.) */
|
||||
|
||||
chtype acs_map[128] =
|
||||
{
|
||||
PDC_ACS(0), PDC_ACS(1), PDC_ACS(2), PDC_ACS(3), PDC_ACS(4),
|
||||
PDC_ACS(5), PDC_ACS(6), PDC_ACS(7), PDC_ACS(8), PDC_ACS(9),
|
||||
PDC_ACS(10), PDC_ACS(11), PDC_ACS(12), PDC_ACS(13), PDC_ACS(14),
|
||||
PDC_ACS(15), PDC_ACS(16), PDC_ACS(17), PDC_ACS(18), PDC_ACS(19),
|
||||
PDC_ACS(20), PDC_ACS(21), PDC_ACS(22), PDC_ACS(23), PDC_ACS(24),
|
||||
PDC_ACS(25), PDC_ACS(26), PDC_ACS(27), PDC_ACS(28), PDC_ACS(29),
|
||||
PDC_ACS(30), PDC_ACS(31), ' ', '!', '"', '#', '$', '%', '&', '\'',
|
||||
'(', ')', '*',
|
||||
|
||||
PDC_ACS(0x1a), PDC_ACS(0x1b), PDC_ACS(0x18), PDC_ACS(0x19),
|
||||
|
||||
'/',
|
||||
|
||||
0xdb,
|
||||
|
||||
'1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=',
|
||||
'>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||||
|
||||
PDC_ACS(0x04), 0xb1,
|
||||
|
||||
'b', 'c', 'd', 'e',
|
||||
|
||||
0xf8, 0xf1, 0xb0, PDC_ACS(0x0f), 0xd9, 0xbf, 0xda, 0xc0, 0xc5, 0x2d,
|
||||
0x2d, 0xc4, 0x2d, 0x5f, 0xc3, 0xb4, 0xc1, 0xc2, 0xb3, 0xf3, 0xf2,
|
||||
0xe3, 0xd8, 0x9c, 0xf9,
|
||||
|
||||
PDC_ACS(127)
|
||||
};
|
||||
35
common/acsuni.h
Normal file
35
common/acsuni.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* ACS Unicode mapping */
|
||||
|
||||
chtype acs_map[128] =
|
||||
{
|
||||
PDC_ACS(0), PDC_ACS(1), PDC_ACS(2), PDC_ACS(3), PDC_ACS(4),
|
||||
PDC_ACS(5), PDC_ACS(6), PDC_ACS(7), PDC_ACS(8), PDC_ACS(9),
|
||||
PDC_ACS(10), PDC_ACS(11), PDC_ACS(12), PDC_ACS(13), PDC_ACS(14),
|
||||
PDC_ACS(15), PDC_ACS(16), PDC_ACS(17), PDC_ACS(18), PDC_ACS(19),
|
||||
PDC_ACS(20), PDC_ACS(21), PDC_ACS(22), PDC_ACS(23), PDC_ACS(24),
|
||||
PDC_ACS(25), PDC_ACS(26), PDC_ACS(27), PDC_ACS(28), PDC_ACS(29),
|
||||
PDC_ACS(30), PDC_ACS(31), ' ', '!', '"', '#', '$', '%', '&', '\'',
|
||||
'(', ')', '*',
|
||||
|
||||
0x2192, 0x2190, 0x2191, 0x2193,
|
||||
|
||||
'/',
|
||||
|
||||
0x2588,
|
||||
|
||||
'1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=',
|
||||
'>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||||
|
||||
0x2666, 0x2592,
|
||||
|
||||
'b', 'c', 'd', 'e',
|
||||
|
||||
0x00b0, 0x00b1, 0x2591, 0x00a4, 0x2518, 0x2510, 0x250c, 0x2514,
|
||||
0x253c, 0x23ba, 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524,
|
||||
0x2534, 0x252c, 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3,
|
||||
0x00b7,
|
||||
|
||||
PDC_ACS(127)
|
||||
};
|
||||
122
curspriv.h
Normal file
122
curspriv.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/* Private definitions and declarations for use within PDCurses.
|
||||
These should generally not be referenced by applications. */
|
||||
|
||||
#ifndef __CURSES_INTERNALS__
|
||||
#define __CURSES_INTERNALS__ 1
|
||||
|
||||
#define CURSES_LIBRARY
|
||||
#include <curses.h>
|
||||
|
||||
#if defined(__TURBOC__) || defined(__EMX__) || defined(__DJGPP__) || \
|
||||
defined(PDC_99) || defined(__WATCOMC__)
|
||||
# ifndef HAVE_VSSCANF
|
||||
# define HAVE_VSSCANF /* have vsscanf() */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(PDC_99) || defined(__WATCOMC__)
|
||||
# ifndef HAVE_VSNPRINTF
|
||||
# define HAVE_VSNPRINTF /* have vsnprintf() */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
typedef struct /* structure for ripped off lines */
|
||||
{
|
||||
int line;
|
||||
int (*init)(WINDOW *, int);
|
||||
} RIPPEDOFFLINE;
|
||||
|
||||
/* Window properties */
|
||||
|
||||
#define _SUBWIN 0x01 /* window is a subwindow */
|
||||
#define _PAD 0x10 /* X/Open Pad. */
|
||||
#define _SUBPAD 0x20 /* X/Open subpad. */
|
||||
|
||||
/* Miscellaneous */
|
||||
|
||||
#define _NO_CHANGE -1 /* flags line edge unchanged */
|
||||
|
||||
#define _ECHAR 0x08 /* Erase char (^H) */
|
||||
#define _DWCHAR 0x17 /* Delete Word char (^W) */
|
||||
#define _DLCHAR 0x15 /* Delete Line char (^U) */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* Platform implementation functions */
|
||||
|
||||
void PDC_beep(void);
|
||||
bool PDC_can_change_color(void);
|
||||
int PDC_color_content(short, short *, short *, short *);
|
||||
bool PDC_check_key(void);
|
||||
int PDC_curs_set(int);
|
||||
void PDC_doupdate(void);
|
||||
void PDC_flushinp(void);
|
||||
int PDC_get_columns(void);
|
||||
int PDC_get_cursor_mode(void);
|
||||
int PDC_get_key(void);
|
||||
int PDC_get_rows(void);
|
||||
void PDC_gotoyx(int, int);
|
||||
bool PDC_has_mouse(void);
|
||||
int PDC_init_color(short, short, short, short);
|
||||
int PDC_modifiers_set(void);
|
||||
int PDC_mouse_set(void);
|
||||
void PDC_napms(int);
|
||||
void PDC_reset_prog_mode(void);
|
||||
void PDC_reset_shell_mode(void);
|
||||
int PDC_resize_screen(int, int);
|
||||
void PDC_restore_screen_mode(int);
|
||||
void PDC_save_screen_mode(int);
|
||||
#ifdef XCURSES
|
||||
void PDC_set_args(int, char **);
|
||||
#endif
|
||||
void PDC_scr_close(void);
|
||||
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 *);
|
||||
const char *PDC_sysname(void);
|
||||
|
||||
/* Internal cross-module functions */
|
||||
|
||||
void PDC_init_atrtab(void);
|
||||
WINDOW *PDC_makelines(WINDOW *);
|
||||
WINDOW *PDC_makenew(int, int, int, int);
|
||||
int PDC_mouse_in_slk(int, int);
|
||||
void PDC_slk_free(void);
|
||||
void PDC_slk_initialize(void);
|
||||
void PDC_sync(WINDOW *);
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
#ifdef PDCDEBUG
|
||||
# define PDC_LOG(x) if (SP && SP->dbfp) PDC_debug x
|
||||
#else
|
||||
# define PDC_LOG(x)
|
||||
#endif
|
||||
|
||||
/* Internal macros for attributes */
|
||||
|
||||
#ifndef max
|
||||
# define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef min
|
||||
# define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define DIVROUND(num, divisor) ((num) + ((divisor) >> 1)) / (divisor)
|
||||
|
||||
#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() */
|
||||
|
||||
#endif /* __CURSES_INTERNALS__ */
|
||||
54
panel.h
Normal file
54
panel.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*----------------------------------------------------------------------*
|
||||
* Panels for PDCurses *
|
||||
*----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __PDCURSES_PANEL_H__
|
||||
#define __PDCURSES_PANEL_H__ 1
|
||||
|
||||
#include <curses.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
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;
|
||||
|
||||
PDCEX int bottom_panel(PANEL *pan);
|
||||
PDCEX int del_panel(PANEL *pan);
|
||||
PDCEX int hide_panel(PANEL *pan);
|
||||
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 int panel_hidden(const PANEL *pan);
|
||||
PDCEX const void *panel_userptr(const PANEL *pan);
|
||||
PDCEX WINDOW *panel_window(const PANEL *pan);
|
||||
PDCEX int replace_panel(PANEL *pan, WINDOW *win);
|
||||
PDCEX int set_panel_userptr(PANEL *pan, const void *uptr);
|
||||
PDCEX int show_panel(PANEL *pan);
|
||||
PDCEX int top_panel(PANEL *pan);
|
||||
PDCEX void update_panels(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PDCURSES_PANEL_H__ */
|
||||
25
pdcurses/README.md
Normal file
25
pdcurses/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
PDCurses Portable Core
|
||||
======================
|
||||
|
||||
This directory contains core PDCurses source code files common to all
|
||||
platforms.
|
||||
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
These modules are built by the platform-specific makefiles, in the
|
||||
platform directories.
|
||||
|
||||
|
||||
Distribution Status
|
||||
-------------------
|
||||
|
||||
The files in this directory are released to the public domain.
|
||||
|
||||
|
||||
Acknowledgements
|
||||
----------------
|
||||
|
||||
The panel library was originally provided by
|
||||
Warren Tucker <wht@n4hgf.mt-park.ga.us>
|
||||
408
pdcurses/addch.c
Normal file
408
pdcurses/addch.c
Normal file
@@ -0,0 +1,408 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
addch
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int addch(const chtype ch);
|
||||
int waddch(WINDOW *win, const chtype ch);
|
||||
int mvaddch(int y, int x, const chtype ch);
|
||||
int mvwaddch(WINDOW *win, int y, int x, const chtype ch);
|
||||
int echochar(const chtype ch);
|
||||
int wechochar(WINDOW *win, const chtype ch);
|
||||
|
||||
int addrawch(chtype ch);
|
||||
int waddrawch(WINDOW *win, chtype ch);
|
||||
int mvaddrawch(int y, int x, chtype ch);
|
||||
int mvwaddrawch(WINDOW *win, int y, int x, chtype ch);
|
||||
|
||||
int add_wch(const cchar_t *wch);
|
||||
int wadd_wch(WINDOW *win, const cchar_t *wch);
|
||||
int mvadd_wch(int y, int x, const cchar_t *wch);
|
||||
int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch);
|
||||
int echo_wchar(const cchar_t *wch);
|
||||
int wecho_wchar(WINDOW *win, const cchar_t *wch);
|
||||
|
||||
### Description
|
||||
|
||||
addch() adds the chtype ch to the default window (stdscr) at the
|
||||
current cursor position, and advances the cursor. Note that chtypes
|
||||
can convey both text (a single character) and attributes, including a
|
||||
color pair. add_wch() is the wide-character version of this function,
|
||||
taking a pointer to a cchar_t instead of a chtype.
|
||||
|
||||
waddch() is like addch(), but also lets you specify the window. (This
|
||||
is in fact the core output routine.) wadd_wch() is the wide version.
|
||||
|
||||
mvaddch() moves the cursor to the specified (y, x) position, and adds
|
||||
ch to stdscr. mvadd_wch() is the wide version.
|
||||
|
||||
mvwaddch() moves the cursor to the specified position and adds ch to
|
||||
the specified window. mvwadd_wch() is the wide version.
|
||||
|
||||
echochar() adds ch to stdscr at the current cursor position and calls
|
||||
refresh(). echo_wchar() is the wide version.
|
||||
|
||||
wechochar() adds ch to the specified window and calls wrefresh().
|
||||
wecho_wchar() is the wide version.
|
||||
|
||||
addrawch(), waddrawch(), mvaddrawch() and mvwaddrawch() are PDCurses-
|
||||
specific wrappers for addch() etc. that disable the translation of
|
||||
control characters.
|
||||
|
||||
The following applies to all these functions:
|
||||
|
||||
If the cursor moves on to the right margin, an automatic newline is
|
||||
performed. If scrollok is enabled, and a character is added to the
|
||||
bottom right corner of the window, the scrolling region will be
|
||||
scrolled up one line. If scrolling is not allowed, ERR will be
|
||||
returned.
|
||||
|
||||
If ch is a tab, newline, or backspace, the cursor will be moved
|
||||
appropriately within the window. If ch is a newline, the clrtoeol
|
||||
routine is called before the cursor is moved to the beginning of the
|
||||
next line. If newline mapping is off, the cursor will be moved to
|
||||
the next line, but the x coordinate will be unchanged. If ch is a
|
||||
tab the cursor is moved to the next tab position within the window.
|
||||
If ch is another control character, it will be drawn in the ^X
|
||||
notation. Calling the inch() routine after adding a control
|
||||
character returns the representation of the control character, not
|
||||
the control character.
|
||||
|
||||
Video attributes can be combined with a character by ORing them into
|
||||
the parameter. Text, including attributes, can be copied from one
|
||||
place to another by using inch() and addch().
|
||||
|
||||
Note that in PDCurses, for now, a cchar_t and a chtype are the same.
|
||||
The text field is 16 bits wide, and is treated as Unicode (UCS-2)
|
||||
when PDCurses is built with wide-character support (define PDC_WIDE).
|
||||
So, in functions that take a chtype, like addch(), both the wide and
|
||||
narrow versions will handle Unicode. But for portability, you should
|
||||
use the wide functions.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
addch Y Y Y
|
||||
waddch Y Y Y
|
||||
mvaddch Y Y Y
|
||||
mvwaddch Y Y Y
|
||||
echochar Y Y Y
|
||||
wechochar Y Y Y
|
||||
add_wch Y Y Y
|
||||
wadd_wch Y Y Y
|
||||
mvadd_wch Y Y Y
|
||||
mvwadd_wch Y Y Y
|
||||
echo_wchar Y Y Y
|
||||
wecho_wchar Y Y Y
|
||||
addrawch - - -
|
||||
waddrawch - - -
|
||||
mvaddrawch - - -
|
||||
mvwaddrawch - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int waddch(WINDOW *win, const chtype ch)
|
||||
{
|
||||
int x, y;
|
||||
chtype text, attr;
|
||||
bool xlat;
|
||||
|
||||
PDC_LOG(("waddch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
|
||||
win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));
|
||||
|
||||
if (!win || !SP)
|
||||
return ERR;
|
||||
|
||||
x = win->_curx;
|
||||
y = win->_cury;
|
||||
|
||||
if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0)
|
||||
return ERR;
|
||||
|
||||
xlat = !SP->raw_out && !(ch & A_ALTCHARSET);
|
||||
text = ch & A_CHARTEXT;
|
||||
attr = ch & A_ATTRIBUTES;
|
||||
|
||||
if (xlat && (text < ' ' || text == 0x7f))
|
||||
{
|
||||
int x2;
|
||||
|
||||
switch (text)
|
||||
{
|
||||
case '\t':
|
||||
for (x2 = ((x / TABSIZE) + 1) * TABSIZE; x < x2; x++)
|
||||
{
|
||||
if (waddch(win, attr | ' ') == ERR)
|
||||
return ERR;
|
||||
|
||||
/* if tab to next line, exit the loop */
|
||||
|
||||
if (!win->_curx)
|
||||
break;
|
||||
}
|
||||
return OK;
|
||||
|
||||
case '\n':
|
||||
/* if lf -> crlf */
|
||||
|
||||
if (!SP->raw_out)
|
||||
x = 0;
|
||||
|
||||
wclrtoeol(win);
|
||||
|
||||
if (++y > win->_bmarg)
|
||||
{
|
||||
y--;
|
||||
|
||||
if (wscrl(win, 1) == ERR)
|
||||
return ERR;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
/* don't back over left margin */
|
||||
|
||||
if (--x < 0)
|
||||
case '\r':
|
||||
x = 0;
|
||||
|
||||
break;
|
||||
|
||||
case 0x7f:
|
||||
if (waddch(win, attr | '^') == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddch(win, attr | '?');
|
||||
|
||||
default:
|
||||
/* handle control chars */
|
||||
|
||||
if (waddch(win, attr | '^') == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddch(win, ch + '@');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the incoming character doesn't have its own attribute,
|
||||
then use the current attributes for the window. If it has
|
||||
attributes but not a color component, OR the attributes to
|
||||
the current attributes for the window. If it has a color
|
||||
component, use the attributes solely from the incoming
|
||||
character. */
|
||||
|
||||
if (!(attr & A_COLOR))
|
||||
attr |= win->_attrs;
|
||||
|
||||
/* wrs (4/10/93): Apply the same sort of logic for the window
|
||||
background, in that it only takes precedence if other color
|
||||
attributes are not there and that the background character
|
||||
will only print if the printing character is blank. */
|
||||
|
||||
if (!(attr & A_COLOR))
|
||||
attr |= win->_bkgd & A_ATTRIBUTES;
|
||||
else
|
||||
attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR);
|
||||
|
||||
if (text == ' ')
|
||||
text = win->_bkgd & A_CHARTEXT;
|
||||
|
||||
/* Add the attribute back into the character. */
|
||||
|
||||
text |= attr;
|
||||
|
||||
/* Only change _firstch/_lastch 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;
|
||||
|
||||
win->_y[y][x] = text;
|
||||
}
|
||||
|
||||
if (++x >= win->_maxx)
|
||||
{
|
||||
/* wrap around test */
|
||||
|
||||
x = 0;
|
||||
|
||||
if (++y > win->_bmarg)
|
||||
{
|
||||
y--;
|
||||
|
||||
if (wscrl(win, 1) == ERR)
|
||||
{
|
||||
PDC_sync(win);
|
||||
return ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
win->_curx = x;
|
||||
win->_cury = y;
|
||||
|
||||
if (win->_immed)
|
||||
wrefresh(win);
|
||||
if (win->_sync)
|
||||
wsyncup(win);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int addch(const chtype ch)
|
||||
{
|
||||
PDC_LOG(("addch() - called: ch=%x\n", ch));
|
||||
|
||||
return waddch(stdscr, ch);
|
||||
}
|
||||
|
||||
int mvaddch(int y, int x, const chtype ch)
|
||||
{
|
||||
PDC_LOG(("mvaddch() - called: y=%d x=%d ch=%x\n", y, x, ch));
|
||||
|
||||
if (move(y,x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddch(stdscr, ch);
|
||||
}
|
||||
|
||||
int mvwaddch(WINDOW *win, int y, int x, const chtype ch)
|
||||
{
|
||||
PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d ch=%d\n", win, y, x, ch));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddch(win, ch);
|
||||
}
|
||||
|
||||
int echochar(const chtype ch)
|
||||
{
|
||||
PDC_LOG(("echochar() - called: ch=%x\n", ch));
|
||||
|
||||
return wechochar(stdscr, ch);
|
||||
}
|
||||
|
||||
int wechochar(WINDOW *win, const chtype ch)
|
||||
{
|
||||
PDC_LOG(("wechochar() - called: win=%p ch=%x\n", win, ch));
|
||||
|
||||
if (waddch(win, ch) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wrefresh(win);
|
||||
}
|
||||
|
||||
int waddrawch(WINDOW *win, chtype ch)
|
||||
{
|
||||
PDC_LOG(("waddrawch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
|
||||
win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));
|
||||
|
||||
if ((ch & A_CHARTEXT) < ' ' || (ch & A_CHARTEXT) == 0x7f)
|
||||
ch |= A_ALTCHARSET;
|
||||
|
||||
return waddch(win, ch);
|
||||
}
|
||||
|
||||
int addrawch(chtype ch)
|
||||
{
|
||||
PDC_LOG(("addrawch() - called: ch=%x\n", ch));
|
||||
|
||||
return waddrawch(stdscr, ch);
|
||||
}
|
||||
|
||||
int mvaddrawch(int y, int x, chtype ch)
|
||||
{
|
||||
PDC_LOG(("mvaddrawch() - called: y=%d x=%d ch=%d\n", y, x, ch));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddrawch(stdscr, ch);
|
||||
}
|
||||
|
||||
int mvwaddrawch(WINDOW *win, int y, int x, chtype ch)
|
||||
{
|
||||
PDC_LOG(("mvwaddrawch() - called: win=%p y=%d x=%d ch=%d\n",
|
||||
win, y, x, ch));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddrawch(win, ch);
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int wadd_wch(WINDOW *win, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("wadd_wch() - called: win=%p wch=%x\n", win, *wch));
|
||||
|
||||
return wch ? waddch(win, *wch) : ERR;
|
||||
}
|
||||
|
||||
int add_wch(const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("add_wch() - called: wch=%x\n", *wch));
|
||||
|
||||
return wadd_wch(stdscr, wch);
|
||||
}
|
||||
|
||||
int mvadd_wch(int y, int x, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("mvaddch() - called: y=%d x=%d wch=%x\n", y, x, *wch));
|
||||
|
||||
if (move(y,x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wadd_wch(stdscr, wch);
|
||||
}
|
||||
|
||||
int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d wch=%d\n",
|
||||
win, y, x, *wch));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wadd_wch(win, wch);
|
||||
}
|
||||
|
||||
int echo_wchar(const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("echo_wchar() - called: wch=%x\n", *wch));
|
||||
|
||||
return wecho_wchar(stdscr, wch);
|
||||
}
|
||||
|
||||
int wecho_wchar(WINDOW *win, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("wecho_wchar() - called: win=%p wch=%x\n", win, *wch));
|
||||
|
||||
if (!wch || (wadd_wch(win, wch) == ERR))
|
||||
return ERR;
|
||||
|
||||
return wrefresh(win);
|
||||
}
|
||||
#endif
|
||||
244
pdcurses/addchstr.c
Normal file
244
pdcurses/addchstr.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
addchstr
|
||||
--------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int addchstr(const chtype *ch);
|
||||
int addchnstr(const chtype *ch, int n);
|
||||
int waddchstr(WINDOW *win, const chtype *ch);
|
||||
int waddchnstr(WINDOW *win, const chtype *ch, int n);
|
||||
int mvaddchstr(int y, int x, const chtype *ch);
|
||||
int mvaddchnstr(int y, int x, const chtype *ch, int n);
|
||||
int mvwaddchstr(WINDOW *, int y, int x, const chtype *ch);
|
||||
int mvwaddchnstr(WINDOW *, int y, int x, const chtype *ch, int n);
|
||||
|
||||
int add_wchstr(const cchar_t *wch);
|
||||
int add_wchnstr(const cchar_t *wch, int n);
|
||||
int wadd_wchstr(WINDOW *win, const cchar_t *wch);
|
||||
int wadd_wchnstr(WINDOW *win, const cchar_t *wch, int n);
|
||||
int mvadd_wchstr(int y, int x, const cchar_t *wch);
|
||||
int mvadd_wchnstr(int y, int x, const cchar_t *wch, int n);
|
||||
int mvwadd_wchstr(WINDOW *win, int y, int x, const cchar_t *wch);
|
||||
int mvwadd_wchnstr(WINDOW *win, int y, int x, const cchar_t *wch,
|
||||
int n);
|
||||
|
||||
### Description
|
||||
|
||||
These routines write a chtype or cchar_t string directly into the
|
||||
window structure, starting at the current or specified position. The
|
||||
four routines with n as the last argument copy at most n elements,
|
||||
but no more than will fit on the line. If n == -1 then the whole
|
||||
string is copied, up to the maximum number that will fit on the line.
|
||||
|
||||
The cursor position is not advanced. These routines do not check for
|
||||
newline or other special characters, nor does any line wrapping
|
||||
occur.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK or ERR.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
addchstr Y Y Y
|
||||
waddchstr Y Y Y
|
||||
mvaddchstr Y Y Y
|
||||
mvwaddchstr Y Y Y
|
||||
addchnstr Y Y Y
|
||||
waddchnstr Y Y Y
|
||||
mvaddchnstr Y Y Y
|
||||
mvwaddchnstr Y Y Y
|
||||
add_wchstr Y Y Y
|
||||
wadd_wchstr Y Y Y
|
||||
mvadd_wchstr Y Y Y
|
||||
mvwadd_wchstr Y Y Y
|
||||
add_wchnstr Y Y Y
|
||||
wadd_wchnstr Y Y Y
|
||||
mvadd_wchnstr Y Y Y
|
||||
mvwadd_wchnstr Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int waddchnstr(WINDOW *win, const chtype *ch, int n)
|
||||
{
|
||||
int y, x, maxx, minx;
|
||||
chtype *ptr;
|
||||
|
||||
PDC_LOG(("waddchnstr() - called: win=%p n=%d\n", win, n));
|
||||
|
||||
if (!win || !ch || !n || n < -1)
|
||||
return ERR;
|
||||
|
||||
x = win->_curx;
|
||||
y = win->_cury;
|
||||
ptr = &(win->_y[y][x]);
|
||||
|
||||
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]));
|
||||
|
||||
*ptr = *ch;
|
||||
}
|
||||
}
|
||||
|
||||
win->_firstch[y] = minx;
|
||||
win->_lastch[y] = maxx;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int addchstr(const chtype *ch)
|
||||
{
|
||||
PDC_LOG(("addchstr() - called\n"));
|
||||
|
||||
return waddchnstr(stdscr, ch, -1);
|
||||
}
|
||||
|
||||
int addchnstr(const chtype *ch, int n)
|
||||
{
|
||||
PDC_LOG(("addchnstr() - called\n"));
|
||||
|
||||
return waddchnstr(stdscr, ch, n);
|
||||
}
|
||||
|
||||
int waddchstr(WINDOW *win, const chtype *ch)
|
||||
{
|
||||
PDC_LOG(("waddchstr() - called: win=%p\n", win));
|
||||
|
||||
return waddchnstr(win, ch, -1);
|
||||
}
|
||||
|
||||
int mvaddchstr(int y, int x, const chtype *ch)
|
||||
{
|
||||
PDC_LOG(("mvaddchstr() - called: y %d x %d\n", y, x));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddchnstr(stdscr, ch, -1);
|
||||
}
|
||||
|
||||
int mvaddchnstr(int y, int x, const chtype *ch, int n)
|
||||
{
|
||||
PDC_LOG(("mvaddchnstr() - called: y %d x %d n %d\n", y, x, n));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddchnstr(stdscr, ch, n);
|
||||
}
|
||||
|
||||
int mvwaddchstr(WINDOW *win, int y, int x, const chtype *ch)
|
||||
{
|
||||
PDC_LOG(("mvwaddchstr() - called:\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddchnstr(win, ch, -1);
|
||||
}
|
||||
|
||||
int mvwaddchnstr(WINDOW *win, int y, int x, const chtype *ch, int n)
|
||||
{
|
||||
PDC_LOG(("mvwaddchnstr() - called: y %d x %d n %d \n", y, x, n));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddchnstr(win, ch, n);
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int wadd_wchnstr(WINDOW *win, const cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("wadd_wchnstr() - called: win=%p n=%d\n", win, n));
|
||||
|
||||
return waddchnstr(win, wch, n);
|
||||
}
|
||||
|
||||
int add_wchstr(const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("add_wchstr() - called\n"));
|
||||
|
||||
return wadd_wchnstr(stdscr, wch, -1);
|
||||
}
|
||||
|
||||
int add_wchnstr(const cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("add_wchnstr() - called\n"));
|
||||
|
||||
return wadd_wchnstr(stdscr, wch, n);
|
||||
}
|
||||
|
||||
int wadd_wchstr(WINDOW *win, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("wadd_wchstr() - called: win=%p\n", win));
|
||||
|
||||
return wadd_wchnstr(win, wch, -1);
|
||||
}
|
||||
|
||||
int mvadd_wchstr(int y, int x, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("mvadd_wchstr() - called: y %d x %d\n", y, x));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wadd_wchnstr(stdscr, wch, -1);
|
||||
}
|
||||
|
||||
int mvadd_wchnstr(int y, int x, const cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("mvadd_wchnstr() - called: y %d x %d n %d\n", y, x, n));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wadd_wchnstr(stdscr, wch, n);
|
||||
}
|
||||
|
||||
int mvwadd_wchstr(WINDOW *win, int y, int x, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("mvwadd_wchstr() - called:\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wadd_wchnstr(win, wch, -1);
|
||||
}
|
||||
|
||||
int mvwadd_wchnstr(WINDOW *win, int y, int x, const cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("mvwadd_wchnstr() - called: y %d x %d n %d \n", y, x, n));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wadd_wchnstr(win, wch, n);
|
||||
}
|
||||
#endif
|
||||
239
pdcurses/addstr.c
Normal file
239
pdcurses/addstr.c
Normal file
@@ -0,0 +1,239 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
addstr
|
||||
------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int addstr(const char *str);
|
||||
int addnstr(const char *str, int n);
|
||||
int waddstr(WINDOW *win, const char *str);
|
||||
int waddnstr(WINDOW *win, const char *str, int n);
|
||||
int mvaddstr(int y, int x, const char *str);
|
||||
int mvaddnstr(int y, int x, const char *str, int n);
|
||||
int mvwaddstr(WINDOW *win, int y, int x, const char *str);
|
||||
int mvwaddnstr(WINDOW *win, int y, int x, const char *str, int n);
|
||||
|
||||
int addwstr(const wchar_t *wstr);
|
||||
int addnwstr(const wchar_t *wstr, int n);
|
||||
int waddwstr(WINDOW *win, const wchar_t *wstr);
|
||||
int waddnwstr(WINDOW *win, const wchar_t *wstr, int n);
|
||||
int mvaddwstr(int y, int x, const wchar_t *wstr);
|
||||
int mvaddnwstr(int y, int x, const wchar_t *wstr, int n);
|
||||
int mvwaddwstr(WINDOW *win, int y, int x, const wchar_t *wstr);
|
||||
int mvwaddnwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n);
|
||||
|
||||
### Description
|
||||
|
||||
These routines write all the characters of the null-terminated string
|
||||
str or wide-character string wstr to the given window. The
|
||||
functionality is similar to calling waddch() once for each character
|
||||
in the string; except that, when PDCurses is built with wide-
|
||||
character support enabled, the narrow-character functions treat the
|
||||
string as a multibyte string in the current locale, and convert it.
|
||||
The routines with n as the last argument write at most n characters;
|
||||
if n is negative, then the entire string will be added.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK or ERR.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
addstr Y Y Y
|
||||
waddstr Y Y Y
|
||||
mvaddstr Y Y Y
|
||||
mvwaddstr Y Y Y
|
||||
addnstr Y Y Y
|
||||
waddnstr Y Y Y
|
||||
mvaddnstr Y Y Y
|
||||
mvwaddnstr Y Y Y
|
||||
addwstr Y Y Y
|
||||
waddwstr Y Y Y
|
||||
mvaddwstr Y Y Y
|
||||
mvwaddwstr Y Y Y
|
||||
addnwstr Y Y Y
|
||||
waddnwstr Y Y Y
|
||||
mvaddnwstr Y Y Y
|
||||
mvwaddnwstr Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int waddnstr(WINDOW *win, const char *str, int n)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
PDC_LOG(("waddnstr() - called: string=\"%s\" n %d \n", str, n));
|
||||
|
||||
if (!win || !str)
|
||||
return ERR;
|
||||
|
||||
while (str[i] && (i < n || n < 0))
|
||||
{
|
||||
#ifdef PDC_WIDE
|
||||
wchar_t wch;
|
||||
int retval = PDC_mbtowc(&wch, str + i, n >= 0 ? n - i : 6);
|
||||
|
||||
if (retval <= 0)
|
||||
return OK;
|
||||
|
||||
i += retval;
|
||||
#else
|
||||
chtype wch = (unsigned char)(str[i++]);
|
||||
#endif
|
||||
if (waddch(win, wch) == ERR)
|
||||
return ERR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int addstr(const char *str)
|
||||
{
|
||||
PDC_LOG(("addstr() - called: string=\"%s\"\n", str));
|
||||
|
||||
return waddnstr(stdscr, str, -1);
|
||||
}
|
||||
|
||||
int addnstr(const char *str, int n)
|
||||
{
|
||||
PDC_LOG(("addnstr() - called: string=\"%s\" n %d \n", str, n));
|
||||
|
||||
return waddnstr(stdscr, str, n);
|
||||
}
|
||||
|
||||
int waddstr(WINDOW *win, const char *str)
|
||||
{
|
||||
PDC_LOG(("waddstr() - called: string=\"%s\"\n", str));
|
||||
|
||||
return waddnstr(win, str, -1);
|
||||
}
|
||||
|
||||
int mvaddstr(int y, int x, const char *str)
|
||||
{
|
||||
PDC_LOG(("mvaddstr() - called: y %d x %d string=\"%s\"\n", y, x, str));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddnstr(stdscr, str, -1);
|
||||
}
|
||||
|
||||
int mvaddnstr(int y, int x, const char *str, int n)
|
||||
{
|
||||
PDC_LOG(("mvaddnstr() - called: y %d x %d string=\"%s\" n %d \n",
|
||||
y, x, str, n));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddnstr(stdscr, str, n);
|
||||
}
|
||||
|
||||
int mvwaddstr(WINDOW *win, int y, int x, const char *str)
|
||||
{
|
||||
PDC_LOG(("mvwaddstr() - called: string=\"%s\"\n", str));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddnstr(win, str, -1);
|
||||
}
|
||||
|
||||
int mvwaddnstr(WINDOW *win, int y, int x, const char *str, int n)
|
||||
{
|
||||
PDC_LOG(("mvwaddnstr() - called: y %d x %d string=\"%s\" n %d \n",
|
||||
y, x, str, n));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddnstr(win, str, n);
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int waddnwstr(WINDOW *win, const wchar_t *wstr, int n)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
PDC_LOG(("waddnwstr() - called\n"));
|
||||
|
||||
if (!win || !wstr)
|
||||
return ERR;
|
||||
|
||||
while (wstr[i] && (i < n || n < 0))
|
||||
{
|
||||
chtype wch = wstr[i++];
|
||||
|
||||
if (waddch(win, wch) == ERR)
|
||||
return ERR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int addwstr(const wchar_t *wstr)
|
||||
{
|
||||
PDC_LOG(("addwstr() - called\n"));
|
||||
|
||||
return waddnwstr(stdscr, wstr, -1);
|
||||
}
|
||||
|
||||
int addnwstr(const wchar_t *wstr, int n)
|
||||
{
|
||||
PDC_LOG(("addnwstr() - called\n"));
|
||||
|
||||
return waddnwstr(stdscr, wstr, n);
|
||||
}
|
||||
|
||||
int waddwstr(WINDOW *win, const wchar_t *wstr)
|
||||
{
|
||||
PDC_LOG(("waddwstr() - called\n"));
|
||||
|
||||
return waddnwstr(win, wstr, -1);
|
||||
}
|
||||
|
||||
int mvaddwstr(int y, int x, const wchar_t *wstr)
|
||||
{
|
||||
PDC_LOG(("mvaddstr() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddnwstr(stdscr, wstr, -1);
|
||||
}
|
||||
|
||||
int mvaddnwstr(int y, int x, const wchar_t *wstr, int n)
|
||||
{
|
||||
PDC_LOG(("mvaddnstr() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddnwstr(stdscr, wstr, n);
|
||||
}
|
||||
|
||||
int mvwaddwstr(WINDOW *win, int y, int x, const wchar_t *wstr)
|
||||
{
|
||||
PDC_LOG(("mvwaddstr() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddnwstr(win, wstr, -1);
|
||||
}
|
||||
|
||||
int mvwaddnwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n)
|
||||
{
|
||||
PDC_LOG(("mvwaddnstr() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return waddnwstr(win, wstr, n);
|
||||
}
|
||||
#endif
|
||||
409
pdcurses/attr.c
Normal file
409
pdcurses/attr.c
Normal file
@@ -0,0 +1,409 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
attr
|
||||
----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int attroff(chtype attrs);
|
||||
int wattroff(WINDOW *win, chtype attrs);
|
||||
int attron(chtype attrs);
|
||||
int wattron(WINDOW *win, chtype attrs);
|
||||
int attrset(chtype attrs);
|
||||
int wattrset(WINDOW *win, chtype attrs);
|
||||
int standend(void);
|
||||
int wstandend(WINDOW *win);
|
||||
int standout(void);
|
||||
int wstandout(WINDOW *win);
|
||||
|
||||
int color_set(short color_pair, void *opts);
|
||||
int wcolor_set(WINDOW *win, short color_pair, void *opts);
|
||||
|
||||
int attr_get(attr_t *attrs, short *color_pair, void *opts);
|
||||
int attr_off(attr_t attrs, void *opts);
|
||||
int attr_on(attr_t attrs, void *opts);
|
||||
int attr_set(attr_t attrs, short color_pair, void *opts);
|
||||
int wattr_get(WINDOW *win, attr_t *attrs, short *color_pair,
|
||||
void *opts);
|
||||
int wattr_off(WINDOW *win, attr_t attrs, void *opts);
|
||||
int wattr_on(WINDOW *win, attr_t attrs, void *opts);
|
||||
int wattr_set(WINDOW *win, attr_t attrs, short color_pair,
|
||||
void *opts);
|
||||
|
||||
int chgat(int n, attr_t attr, short color, const void *opts);
|
||||
int mvchgat(int y, int x, int n, attr_t attr, short color,
|
||||
const void *opts);
|
||||
int mvwchgat(WINDOW *win, int y, int x, int n, attr_t attr,
|
||||
short color, const void *opts);
|
||||
int wchgat(WINDOW *win, int n, attr_t attr, short color,
|
||||
const void *opts);
|
||||
|
||||
chtype getattrs(WINDOW *win);
|
||||
|
||||
int underend(void);
|
||||
int wunderend(WINDOW *win);
|
||||
int underscore(void);
|
||||
int wunderscore(WINDOW *win);
|
||||
|
||||
### Description
|
||||
|
||||
These functions manipulate the current attributes and/or colors of
|
||||
the named window. These attributes can be any combination of
|
||||
A_STANDOUT, A_REVERSE, A_BOLD, A_DIM, A_BLINK, A_UNDERLINE. These
|
||||
constants are defined in <curses.h> and can be combined with the
|
||||
bitwise-OR operator (|).
|
||||
|
||||
The current attributes of a window are applied to all chtypes that
|
||||
are written into the window with waddch(). Attributes are a property
|
||||
of the chtype, and move with the character through any scrolling or
|
||||
insert/delete operations.
|
||||
|
||||
wattrset() sets the current attributes of the given window to attrs.
|
||||
attrset() is the stdscr version.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
wattr_get() retrieves the attributes and color pair for the specified
|
||||
window.
|
||||
|
||||
wchgat() sets the color pair and attributes for the next n cells on
|
||||
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.
|
||||
|
||||
wunderscore() turns on the A_UNDERLINE attribute; wunderend() turns
|
||||
it off. underscore() and underend() are the stdscr versions.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
attroff Y Y Y
|
||||
wattroff Y Y Y
|
||||
attron Y Y Y
|
||||
wattron Y Y Y
|
||||
attrset Y Y Y
|
||||
wattrset Y Y Y
|
||||
standend Y Y Y
|
||||
wstandend Y Y Y
|
||||
standout Y Y Y
|
||||
wstandout Y Y Y
|
||||
color_set Y Y Y
|
||||
wcolor_set Y Y Y
|
||||
attr_get Y Y Y
|
||||
wattr_get Y Y Y
|
||||
attr_on Y Y Y
|
||||
wattr_on Y Y Y
|
||||
attr_off Y Y Y
|
||||
wattr_off Y Y Y
|
||||
attr_set Y Y Y
|
||||
wattr_set Y Y Y
|
||||
chgat Y Y Y
|
||||
wchgat Y Y Y
|
||||
mvchgat Y Y Y
|
||||
mvwchgat Y Y Y
|
||||
getattrs - Y Y
|
||||
underend - - Y
|
||||
wunderend - - Y
|
||||
underscore - - Y
|
||||
wunderscore - - Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int wattroff(WINDOW *win, chtype attrs)
|
||||
{
|
||||
PDC_LOG(("wattroff() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
win->_attrs &= (~attrs & A_ATTRIBUTES);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int attroff(chtype attrs)
|
||||
{
|
||||
PDC_LOG(("attroff() - called\n"));
|
||||
|
||||
return wattroff(stdscr, attrs);
|
||||
}
|
||||
|
||||
int wattron(WINDOW *win, chtype attrs)
|
||||
{
|
||||
chtype newcolr, oldcolr, newattr, oldattr;
|
||||
|
||||
PDC_LOG(("wattron() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
if ((win->_attrs & A_COLOR) && (attrs & A_COLOR))
|
||||
{
|
||||
oldcolr = win->_attrs & A_COLOR;
|
||||
oldattr = win->_attrs ^ oldcolr;
|
||||
newcolr = attrs & A_COLOR;
|
||||
newattr = (attrs & A_ATTRIBUTES) ^ newcolr;
|
||||
newattr |= oldattr;
|
||||
win->_attrs = newattr | newcolr;
|
||||
}
|
||||
else
|
||||
win->_attrs |= (attrs & A_ATTRIBUTES);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int attron(chtype attrs)
|
||||
{
|
||||
PDC_LOG(("attron() - called\n"));
|
||||
|
||||
return wattron(stdscr, attrs);
|
||||
}
|
||||
|
||||
int wattrset(WINDOW *win, chtype attrs)
|
||||
{
|
||||
PDC_LOG(("wattrset() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
win->_attrs = attrs & A_ATTRIBUTES;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int attrset(chtype attrs)
|
||||
{
|
||||
PDC_LOG(("attrset() - called\n"));
|
||||
|
||||
return wattrset(stdscr, attrs);
|
||||
}
|
||||
|
||||
int standend(void)
|
||||
{
|
||||
PDC_LOG(("standend() - called\n"));
|
||||
|
||||
return wattrset(stdscr, A_NORMAL);
|
||||
}
|
||||
|
||||
int standout(void)
|
||||
{
|
||||
PDC_LOG(("standout() - called\n"));
|
||||
|
||||
return wattrset(stdscr, A_STANDOUT);
|
||||
}
|
||||
|
||||
int wstandend(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("wstandend() - called\n"));
|
||||
|
||||
return wattrset(win, A_NORMAL);
|
||||
}
|
||||
|
||||
int wstandout(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("wstandout() - called\n"));
|
||||
|
||||
return wattrset(win, A_STANDOUT);
|
||||
}
|
||||
|
||||
chtype getattrs(WINDOW *win)
|
||||
{
|
||||
return win ? win->_attrs : 0;
|
||||
}
|
||||
|
||||
int wcolor_set(WINDOW *win, short color_pair, void *opts)
|
||||
{
|
||||
PDC_LOG(("wcolor_set() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
win->_attrs = (win->_attrs & ~A_COLOR) | COLOR_PAIR(color_pair);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int color_set(short color_pair, void *opts)
|
||||
{
|
||||
PDC_LOG(("color_set() - called\n"));
|
||||
|
||||
return wcolor_set(stdscr, color_pair, opts);
|
||||
}
|
||||
|
||||
int wattr_get(WINDOW *win, attr_t *attrs, short *color_pair, void *opts)
|
||||
{
|
||||
PDC_LOG(("wattr_get() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
if (attrs)
|
||||
*attrs = win->_attrs & (A_ATTRIBUTES & ~A_COLOR);
|
||||
|
||||
if (color_pair)
|
||||
*color_pair = PAIR_NUMBER(win->_attrs);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int attr_get(attr_t *attrs, short *color_pair, void *opts)
|
||||
{
|
||||
PDC_LOG(("attr_get() - called\n"));
|
||||
|
||||
return wattr_get(stdscr, attrs, color_pair, opts);
|
||||
}
|
||||
|
||||
int wattr_off(WINDOW *win, attr_t attrs, void *opts)
|
||||
{
|
||||
PDC_LOG(("wattr_off() - called\n"));
|
||||
|
||||
return wattroff(win, attrs);
|
||||
}
|
||||
|
||||
int attr_off(attr_t attrs, void *opts)
|
||||
{
|
||||
PDC_LOG(("attr_off() - called\n"));
|
||||
|
||||
return wattroff(stdscr, attrs);
|
||||
}
|
||||
|
||||
int wattr_on(WINDOW *win, attr_t attrs, void *opts)
|
||||
{
|
||||
PDC_LOG(("wattr_off() - called\n"));
|
||||
|
||||
return wattron(win, attrs);
|
||||
}
|
||||
|
||||
int attr_on(attr_t attrs, void *opts)
|
||||
{
|
||||
PDC_LOG(("attr_on() - called\n"));
|
||||
|
||||
return wattron(stdscr, attrs);
|
||||
}
|
||||
|
||||
int wattr_set(WINDOW *win, attr_t attrs, short color_pair, void *opts)
|
||||
{
|
||||
PDC_LOG(("wattr_set() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
win->_attrs = (attrs & (A_ATTRIBUTES & ~A_COLOR)) | COLOR_PAIR(color_pair);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int attr_set(attr_t attrs, short color_pair, void *opts)
|
||||
{
|
||||
PDC_LOG(("attr_get() - called\n"));
|
||||
|
||||
return wattr_set(stdscr, attrs, color_pair, opts);
|
||||
}
|
||||
|
||||
int wchgat(WINDOW *win, int n, attr_t attr, short color, const void *opts)
|
||||
{
|
||||
chtype *dest, newattr;
|
||||
int startpos, endpos;
|
||||
|
||||
PDC_LOG(("wchgat() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
newattr = (attr & A_ATTRIBUTES) | COLOR_PAIR(color);
|
||||
|
||||
startpos = win->_curx;
|
||||
endpos = ((n < 0) ? win->_maxx : min(startpos + n, win->_maxx)) - 1;
|
||||
dest = win->_y[win->_cury];
|
||||
|
||||
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_sync(win);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int chgat(int n, attr_t attr, short color, const void *opts)
|
||||
{
|
||||
PDC_LOG(("chgat() - called\n"));
|
||||
|
||||
return wchgat(stdscr, n, attr, color, opts);
|
||||
}
|
||||
|
||||
int mvchgat(int y, int x, int n, attr_t attr, short color, const void *opts)
|
||||
{
|
||||
PDC_LOG(("mvchgat() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wchgat(stdscr, n, attr, color, opts);
|
||||
}
|
||||
|
||||
int mvwchgat(WINDOW *win, int y, int x, int n, attr_t attr, short color,
|
||||
const void *opts)
|
||||
{
|
||||
PDC_LOG(("mvwchgat() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wchgat(win, n, attr, color, opts);
|
||||
}
|
||||
|
||||
int underend(void)
|
||||
{
|
||||
PDC_LOG(("underend() - called\n"));
|
||||
|
||||
return wattroff(stdscr, A_UNDERLINE);
|
||||
}
|
||||
|
||||
int wunderend(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("wunderend() - called\n"));
|
||||
|
||||
return wattroff(win, A_UNDERLINE);
|
||||
}
|
||||
|
||||
int underscore(void)
|
||||
{
|
||||
PDC_LOG(("underscore() - called\n"));
|
||||
|
||||
return wattron(stdscr, A_UNDERLINE);
|
||||
}
|
||||
|
||||
int wunderscore(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("wunderscore() - called\n"));
|
||||
|
||||
return wattron(win, A_UNDERLINE);
|
||||
}
|
||||
74
pdcurses/beep.c
Normal file
74
pdcurses/beep.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
beep
|
||||
----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int beep(void);
|
||||
int flash(void);
|
||||
|
||||
### Description
|
||||
|
||||
beep() sounds the audible bell on the terminal, if possible; if not,
|
||||
it calls flash().
|
||||
|
||||
flash() "flashes" the screen, by inverting the foreground and
|
||||
background of every cell, pausing, and then restoring the original
|
||||
attributes.
|
||||
|
||||
### Return Value
|
||||
|
||||
These functions return ERR if called before initscr(), otherwise OK.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
beep Y Y Y
|
||||
flash Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int beep(void)
|
||||
{
|
||||
PDC_LOG(("beep() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
if (SP->audible)
|
||||
PDC_beep();
|
||||
else
|
||||
flash();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int flash(void)
|
||||
{
|
||||
int z, y, x;
|
||||
|
||||
PDC_LOG(("flash() - called\n"));
|
||||
|
||||
if (!curscr)
|
||||
return ERR;
|
||||
|
||||
/* Reverse each cell; wait; restore the screen */
|
||||
|
||||
for (z = 0; z < 2; z++)
|
||||
{
|
||||
for (y = 0; y < LINES; y++)
|
||||
for (x = 0; x < COLS; x++)
|
||||
curscr->_y[y][x] ^= A_REVERSE;
|
||||
|
||||
wrefresh(curscr);
|
||||
|
||||
if (!z)
|
||||
napms(50);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
226
pdcurses/bkgd.c
Normal file
226
pdcurses/bkgd.c
Normal file
@@ -0,0 +1,226 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
bkgd
|
||||
----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int bkgd(chtype ch);
|
||||
void bkgdset(chtype ch);
|
||||
chtype getbkgd(WINDOW *win);
|
||||
int wbkgd(WINDOW *win, chtype ch);
|
||||
void wbkgdset(WINDOW *win, chtype ch);
|
||||
|
||||
int bkgrnd(const cchar_t *wch);
|
||||
void bkgrndset(const cchar_t *wch);
|
||||
int getbkgrnd(cchar_t *wch);
|
||||
int wbkgrnd(WINDOW *win, const cchar_t *wch);
|
||||
void wbkgrndset(WINDOW *win, const cchar_t *wch);
|
||||
int wgetbkgrnd(WINDOW *win, cchar_t *wch);
|
||||
|
||||
### Description
|
||||
|
||||
bkgdset() and wbkgdset() manipulate the background of a window. The
|
||||
background is a chtype consisting of any combination of attributes
|
||||
and a character; it is combined with each chtype added or inserted to
|
||||
the window by waddch() or winsch(). Only the attribute part is used
|
||||
to set the background of non-blank characters, while both character
|
||||
and attributes are used for blank positions.
|
||||
|
||||
bkgd() and wbkgd() not only change the background, but apply it
|
||||
immediately to every cell in the window.
|
||||
|
||||
wbkgrnd(), wbkgrndset() and wgetbkgrnd() are the "wide-character"
|
||||
versions of these functions, taking a pointer to a cchar_t instead of
|
||||
a chtype. However, in PDCurses, cchar_t and chtype are the same.
|
||||
|
||||
The attributes that are defined with the attrset()/attron() set of
|
||||
functions take precedence over the background attributes if there is
|
||||
a conflict (e.g., different color pairs).
|
||||
|
||||
### Return Value
|
||||
|
||||
bkgd() and wbkgd() return OK, unless the window is NULL, in which
|
||||
case they return ERR.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
bkgd Y Y Y
|
||||
bkgdset Y Y Y
|
||||
getbkgd Y Y Y
|
||||
wbkgd Y Y Y
|
||||
wbkgdset Y Y Y
|
||||
bkgrnd Y Y Y
|
||||
bkgrndset Y Y Y
|
||||
getbkgrnd Y Y Y
|
||||
wbkgrnd Y Y Y
|
||||
wbkgrndset Y Y Y
|
||||
wgetbkgrnd Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int wbkgd(WINDOW *win, chtype ch)
|
||||
{
|
||||
int x, y;
|
||||
chtype oldcolr, oldch, newcolr, newch, colr, attr;
|
||||
chtype oldattr = 0, newattr = 0;
|
||||
chtype *winptr;
|
||||
|
||||
PDC_LOG(("wbkgd() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
if (win->_bkgd == ch)
|
||||
return OK;
|
||||
|
||||
oldcolr = win->_bkgd & A_COLOR;
|
||||
if (oldcolr)
|
||||
oldattr = (win->_bkgd & A_ATTRIBUTES) ^ oldcolr;
|
||||
|
||||
oldch = win->_bkgd & A_CHARTEXT;
|
||||
|
||||
wbkgdset(win, ch);
|
||||
|
||||
newcolr = win->_bkgd & A_COLOR;
|
||||
if (newcolr)
|
||||
newattr = (win->_bkgd & A_ATTRIBUTES) ^ newcolr;
|
||||
|
||||
newch = win->_bkgd & A_CHARTEXT;
|
||||
|
||||
/* what follows is what seems to occur in the System V
|
||||
implementation of this routine */
|
||||
|
||||
for (y = 0; y < win->_maxy; y++)
|
||||
{
|
||||
for (x = 0; x < win->_maxx; x++)
|
||||
{
|
||||
winptr = win->_y[y] + x;
|
||||
|
||||
ch = *winptr;
|
||||
|
||||
/* determine the colors and attributes of the character read
|
||||
from the window */
|
||||
|
||||
colr = ch & A_COLOR;
|
||||
attr = ch & (A_ATTRIBUTES ^ A_COLOR);
|
||||
|
||||
/* if the color is the same as the old background color,
|
||||
then make it the new background color, otherwise leave it */
|
||||
|
||||
if (colr == oldcolr)
|
||||
colr = newcolr;
|
||||
|
||||
/* remove any attributes (non color) from the character that
|
||||
were part of the old background, then combine the
|
||||
remaining ones with the new background */
|
||||
|
||||
attr ^= oldattr;
|
||||
attr |= newattr;
|
||||
|
||||
/* change character if it is there because it was the old
|
||||
background character */
|
||||
|
||||
ch &= A_CHARTEXT;
|
||||
if (ch == oldch)
|
||||
ch = newch;
|
||||
|
||||
ch |= (attr | colr);
|
||||
|
||||
*winptr = ch;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
touchwin(win);
|
||||
PDC_sync(win);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int bkgd(chtype ch)
|
||||
{
|
||||
PDC_LOG(("bkgd() - called\n"));
|
||||
|
||||
return wbkgd(stdscr, ch);
|
||||
}
|
||||
|
||||
void wbkgdset(WINDOW *win, chtype ch)
|
||||
{
|
||||
PDC_LOG(("wbkgdset() - called\n"));
|
||||
|
||||
if (win)
|
||||
{
|
||||
if (!(ch & A_CHARTEXT))
|
||||
ch |= ' ';
|
||||
|
||||
win->_bkgd = ch;
|
||||
}
|
||||
}
|
||||
|
||||
void bkgdset(chtype ch)
|
||||
{
|
||||
PDC_LOG(("bkgdset() - called\n"));
|
||||
|
||||
wbkgdset(stdscr, ch);
|
||||
}
|
||||
|
||||
chtype getbkgd(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("getbkgd() - called\n"));
|
||||
|
||||
return win ? win->_bkgd : (chtype)ERR;
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int wbkgrnd(WINDOW *win, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("wbkgrnd() - called\n"));
|
||||
|
||||
return wch ? wbkgd(win, *wch) : ERR;
|
||||
}
|
||||
|
||||
int bkgrnd(const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("bkgrnd() - called\n"));
|
||||
|
||||
return wbkgrnd(stdscr, wch);
|
||||
}
|
||||
|
||||
void wbkgrndset(WINDOW *win, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("wbkgdset() - called\n"));
|
||||
|
||||
if (wch)
|
||||
wbkgdset(win, *wch);
|
||||
}
|
||||
|
||||
void bkgrndset(const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("bkgrndset() - called\n"));
|
||||
|
||||
wbkgrndset(stdscr, wch);
|
||||
}
|
||||
|
||||
int wgetbkgrnd(WINDOW *win, cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("wgetbkgrnd() - called\n"));
|
||||
|
||||
if (!win || !wch)
|
||||
return ERR;
|
||||
|
||||
*wch = win->_bkgd;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getbkgrnd(cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("getbkgrnd() - called\n"));
|
||||
|
||||
return wgetbkgrnd(stdscr, wch);
|
||||
}
|
||||
#endif
|
||||
414
pdcurses/border.c
Normal file
414
pdcurses/border.c
Normal file
@@ -0,0 +1,414 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
border
|
||||
------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl,
|
||||
chtype tr, chtype bl, chtype br);
|
||||
int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts,
|
||||
chtype bs, chtype tl, chtype tr, chtype bl, chtype br);
|
||||
int box(WINDOW *win, chtype verch, chtype horch);
|
||||
int hline(chtype ch, int n);
|
||||
int vline(chtype ch, int n);
|
||||
int whline(WINDOW *win, chtype ch, int n);
|
||||
int wvline(WINDOW *win, chtype ch, int n);
|
||||
int mvhline(int y, int x, chtype ch, int n);
|
||||
int mvvline(int y, int x, chtype ch, int n);
|
||||
int mvwhline(WINDOW *win, int y, int x, chtype ch, int n);
|
||||
int mvwvline(WINDOW *win, int y, int x, chtype ch, int n);
|
||||
|
||||
int border_set(const cchar_t *ls, const cchar_t *rs,
|
||||
const cchar_t *ts, const cchar_t *bs,
|
||||
const cchar_t *tl, const cchar_t *tr,
|
||||
const cchar_t *bl, const cchar_t *br);
|
||||
int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs,
|
||||
const cchar_t *ts, const cchar_t *bs,
|
||||
const cchar_t *tl, const cchar_t *tr,
|
||||
const cchar_t *bl, const cchar_t *br);
|
||||
int box_set(WINDOW *win, const cchar_t *verch, const cchar_t *horch);
|
||||
int hline_set(const cchar_t *wch, int n);
|
||||
int vline_set(const cchar_t *wch, int n);
|
||||
int whline_set(WINDOW *win, const cchar_t *wch, int n);
|
||||
int wvline_set(WINDOW *win, const cchar_t *wch, int n);
|
||||
int mvhline_set(int y, int x, const cchar_t *wch, int n);
|
||||
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);
|
||||
|
||||
### Description
|
||||
|
||||
border(), wborder(), and box() draw a border around the edge of the
|
||||
window. If any argument is zero, an appropriate default is used:
|
||||
|
||||
ls left side of border ACS_VLINE
|
||||
rs right side of border ACS_VLINE
|
||||
ts top side of border ACS_HLINE
|
||||
bs bottom side of border ACS_HLINE
|
||||
tl top left corner of border ACS_ULCORNER
|
||||
tr top right corner of border ACS_URCORNER
|
||||
bl bottom left corner of border ACS_LLCORNER
|
||||
br bottom right corner of border ACS_LRCORNER
|
||||
|
||||
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
|
||||
window.
|
||||
|
||||
vline() and wvline() draw a vertical 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
|
||||
window.
|
||||
|
||||
The *_set functions are the "wide-character" versions, taking
|
||||
pointers to cchar_t instead of chtype. Note that in PDCurses, chtype
|
||||
and cchar_t are the same.
|
||||
|
||||
### Return Value
|
||||
|
||||
These functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
border Y Y Y
|
||||
wborder Y Y Y
|
||||
box Y Y Y
|
||||
hline Y Y Y
|
||||
vline Y Y Y
|
||||
whline Y Y Y
|
||||
wvline Y Y Y
|
||||
mvhline Y Y Y
|
||||
mvvline Y Y Y
|
||||
mvwhline Y Y Y
|
||||
mvwvline Y Y Y
|
||||
border_set Y Y Y
|
||||
wborder_set Y Y Y
|
||||
box_set Y Y Y
|
||||
hline_set Y Y Y
|
||||
vline_set Y Y Y
|
||||
whline_set Y Y Y
|
||||
wvline_set Y Y Y
|
||||
mvhline_set Y Y Y
|
||||
mvvline_set Y Y Y
|
||||
mvwhline_set Y Y Y
|
||||
mvwvline_set Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
/* _attr_passthru() -- Takes a single chtype 'ch' and checks if the
|
||||
current attribute of window 'win', as set by wattrset(), and/or the
|
||||
current background of win, as set by wbkgd(), should by combined with
|
||||
it. Attributes set explicitly in ch take precedence. */
|
||||
|
||||
static chtype _attr_passthru(WINDOW *win, chtype ch)
|
||||
{
|
||||
chtype attr;
|
||||
|
||||
/* If the incoming character doesn't have its own attribute, then
|
||||
use the current attributes for the window. If the incoming
|
||||
character has attributes, but not a color component, OR the
|
||||
attributes to the current attributes for the window. If the
|
||||
incoming character has a color component, use only the attributes
|
||||
from the incoming character. */
|
||||
|
||||
attr = ch & A_ATTRIBUTES;
|
||||
if (!(attr & A_COLOR))
|
||||
attr |= win->_attrs;
|
||||
|
||||
/* wrs (4/10/93) -- Apply the same sort of logic for the window
|
||||
background, in that it only takes precedence if other color
|
||||
attributes are not there. */
|
||||
|
||||
if (!(attr & A_COLOR))
|
||||
attr |= win->_bkgd & A_ATTRIBUTES;
|
||||
else
|
||||
attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR);
|
||||
|
||||
ch = (ch & A_CHARTEXT) | attr;
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs,
|
||||
chtype tl, chtype tr, chtype bl, chtype br)
|
||||
{
|
||||
int i, ymax, xmax;
|
||||
|
||||
PDC_LOG(("wborder() - called\n"));
|
||||
|
||||
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);
|
||||
|
||||
for (i = 1; i < xmax; i++)
|
||||
{
|
||||
win->_y[0][i] = ts;
|
||||
win->_y[ymax][i] = bs;
|
||||
}
|
||||
|
||||
for (i = 1; i < ymax; i++)
|
||||
{
|
||||
win->_y[i][0] = ls;
|
||||
win->_y[i][xmax] = rs;
|
||||
}
|
||||
|
||||
win->_y[0][0] = tl;
|
||||
win->_y[0][xmax] = tr;
|
||||
win->_y[ymax][0] = bl;
|
||||
win->_y[ymax][xmax] = br;
|
||||
|
||||
for (i = 0; i <= ymax; i++)
|
||||
{
|
||||
win->_firstch[i] = 0;
|
||||
win->_lastch[i] = xmax;
|
||||
}
|
||||
|
||||
PDC_sync(win);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl,
|
||||
chtype tr, chtype bl, chtype br)
|
||||
{
|
||||
PDC_LOG(("border() - called\n"));
|
||||
|
||||
return wborder(stdscr, ls, rs, ts, bs, tl, tr, bl, br);
|
||||
}
|
||||
|
||||
int box(WINDOW *win, chtype verch, chtype horch)
|
||||
{
|
||||
PDC_LOG(("box() - called\n"));
|
||||
|
||||
return wborder(win, verch, verch, horch, horch, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
int whline(WINDOW *win, chtype ch, int n)
|
||||
{
|
||||
chtype *dest;
|
||||
int startpos, endpos;
|
||||
|
||||
PDC_LOG(("whline() - called\n"));
|
||||
|
||||
if (!win || n < 1)
|
||||
return ERR;
|
||||
|
||||
startpos = win->_curx;
|
||||
endpos = min(startpos + n, win->_maxx) - 1;
|
||||
dest = win->_y[win->_cury];
|
||||
ch = _attr_passthru(win, ch ? ch : ACS_HLINE);
|
||||
|
||||
for (n = startpos; n <= endpos; n++)
|
||||
dest[n] = ch;
|
||||
|
||||
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_sync(win);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int hline(chtype ch, int n)
|
||||
{
|
||||
PDC_LOG(("hline() - called\n"));
|
||||
|
||||
return whline(stdscr, ch, n);
|
||||
}
|
||||
|
||||
int mvhline(int y, int x, chtype ch, int n)
|
||||
{
|
||||
PDC_LOG(("mvhline() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return whline(stdscr, ch, n);
|
||||
}
|
||||
|
||||
int mvwhline(WINDOW *win, int y, int x, chtype ch, int n)
|
||||
{
|
||||
PDC_LOG(("mvwhline() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return whline(win, ch, n);
|
||||
}
|
||||
|
||||
int wvline(WINDOW *win, chtype ch, int n)
|
||||
{
|
||||
int endpos, x;
|
||||
|
||||
PDC_LOG(("wvline() - called\n"));
|
||||
|
||||
if (!win || n < 1)
|
||||
return ERR;
|
||||
|
||||
endpos = min(win->_cury + n, win->_maxy);
|
||||
x = win->_curx;
|
||||
|
||||
ch = _attr_passthru(win, ch ? ch : ACS_VLINE);
|
||||
|
||||
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_sync(win);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int vline(chtype ch, int n)
|
||||
{
|
||||
PDC_LOG(("vline() - called\n"));
|
||||
|
||||
return wvline(stdscr, ch, n);
|
||||
}
|
||||
|
||||
int mvvline(int y, int x, chtype ch, int n)
|
||||
{
|
||||
PDC_LOG(("mvvline() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wvline(stdscr, ch, n);
|
||||
}
|
||||
|
||||
int mvwvline(WINDOW *win, int y, int x, chtype ch, int n)
|
||||
{
|
||||
PDC_LOG(("mvwvline() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wvline(win, ch, n);
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs,
|
||||
const cchar_t *ts, const cchar_t *bs, const cchar_t *tl,
|
||||
const cchar_t *tr, const cchar_t *bl, const cchar_t *br)
|
||||
{
|
||||
PDC_LOG(("wborder_set() - called\n"));
|
||||
|
||||
return wborder(win, ls ? *ls : 0, rs ? *rs : 0, ts ? *ts : 0,
|
||||
bs ? *bs : 0, tl ? *tl : 0, tr ? *tr : 0,
|
||||
bl ? *bl : 0, br ? *br : 0);
|
||||
}
|
||||
|
||||
int border_set(const cchar_t *ls, const cchar_t *rs, const cchar_t *ts,
|
||||
const cchar_t *bs, const cchar_t *tl, const cchar_t *tr,
|
||||
const cchar_t *bl, const cchar_t *br)
|
||||
{
|
||||
PDC_LOG(("border_set() - called\n"));
|
||||
|
||||
return wborder_set(stdscr, ls, rs, ts, bs, tl, tr, bl, br);
|
||||
}
|
||||
|
||||
int box_set(WINDOW *win, const cchar_t *verch, const cchar_t *horch)
|
||||
{
|
||||
PDC_LOG(("box_set() - called\n"));
|
||||
|
||||
return wborder_set(win, verch, verch, horch, horch,
|
||||
(const cchar_t *)NULL, (const cchar_t *)NULL,
|
||||
(const cchar_t *)NULL, (const cchar_t *)NULL);
|
||||
}
|
||||
|
||||
int whline_set(WINDOW *win, const cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("whline_set() - called\n"));
|
||||
|
||||
return wch ? whline(win, *wch, n) : ERR;
|
||||
}
|
||||
|
||||
int hline_set(const cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("hline_set() - called\n"));
|
||||
|
||||
return whline_set(stdscr, wch, n);
|
||||
}
|
||||
|
||||
int mvhline_set(int y, int x, const cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("mvhline_set() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return whline_set(stdscr, wch, n);
|
||||
}
|
||||
|
||||
int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("mvwhline_set() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return whline_set(win, wch, n);
|
||||
}
|
||||
|
||||
int wvline_set(WINDOW *win, const cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("wvline_set() - called\n"));
|
||||
|
||||
return wch ? wvline(win, *wch, n) : ERR;
|
||||
}
|
||||
|
||||
int vline_set(const cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("vline_set() - called\n"));
|
||||
|
||||
return wvline_set(stdscr, wch, n);
|
||||
}
|
||||
|
||||
int mvvline_set(int y, int x, const cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("mvvline_set() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wvline_set(stdscr, wch, n);
|
||||
}
|
||||
|
||||
int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("mvwvline_set() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wvline_set(win, wch, n);
|
||||
}
|
||||
#endif
|
||||
159
pdcurses/clear.c
Normal file
159
pdcurses/clear.c
Normal file
@@ -0,0 +1,159 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
clear
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int clear(void);
|
||||
int wclear(WINDOW *win);
|
||||
int erase(void);
|
||||
int werase(WINDOW *win);
|
||||
int clrtobot(void);
|
||||
int wclrtobot(WINDOW *win);
|
||||
int clrtoeol(void);
|
||||
int wclrtoeol(WINDOW *win);
|
||||
|
||||
### Description
|
||||
|
||||
erase() and werase() copy blanks (i.e. the background chtype) to
|
||||
every cell of the window.
|
||||
|
||||
clear() and wclear() are similar to erase() and werase(), but they
|
||||
also call clearok() to ensure that the the window is cleared on the
|
||||
next wrefresh().
|
||||
|
||||
clrtobot() and wclrtobot() clear the window from the current cursor
|
||||
position to the end of the window.
|
||||
|
||||
clrtoeol() and wclrtoeol() clear the window from the current cursor
|
||||
position to the end of the current line.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
clear Y Y Y
|
||||
wclear Y Y Y
|
||||
erase Y Y Y
|
||||
werase Y Y Y
|
||||
clrtobot Y Y Y
|
||||
wclrtobot Y Y Y
|
||||
clrtoeol Y Y Y
|
||||
wclrtoeol Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int wclrtoeol(WINDOW *win)
|
||||
{
|
||||
int x, y, minx;
|
||||
chtype blank, *ptr;
|
||||
|
||||
PDC_LOG(("wclrtoeol() - called: Row: %d Col: %d\n",
|
||||
win->_cury, win->_curx));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
y = win->_cury;
|
||||
x = win->_curx;
|
||||
|
||||
/* wrs (4/10/93) account for window background */
|
||||
|
||||
blank = win->_bkgd;
|
||||
|
||||
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_sync(win);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int clrtoeol(void)
|
||||
{
|
||||
PDC_LOG(("clrtoeol() - called\n"));
|
||||
|
||||
return wclrtoeol(stdscr);
|
||||
}
|
||||
|
||||
int wclrtobot(WINDOW *win)
|
||||
{
|
||||
int savey, savex;
|
||||
|
||||
PDC_LOG(("wclrtobot() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
savey = win->_cury;
|
||||
savex = win->_curx;
|
||||
|
||||
/* should this involve scrolling region somehow ? */
|
||||
|
||||
if (win->_cury + 1 < win->_maxy)
|
||||
{
|
||||
win->_curx = 0;
|
||||
win->_cury++;
|
||||
for (; win->_maxy > win->_cury; win->_cury++)
|
||||
wclrtoeol(win);
|
||||
win->_cury = savey;
|
||||
win->_curx = savex;
|
||||
}
|
||||
wclrtoeol(win);
|
||||
|
||||
PDC_sync(win);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int clrtobot(void)
|
||||
{
|
||||
PDC_LOG(("clrtobot() - called\n"));
|
||||
|
||||
return wclrtobot(stdscr);
|
||||
}
|
||||
|
||||
int werase(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("werase() - called\n"));
|
||||
|
||||
if (wmove(win, 0, 0) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wclrtobot(win);
|
||||
}
|
||||
|
||||
int erase(void)
|
||||
{
|
||||
PDC_LOG(("erase() - called\n"));
|
||||
|
||||
return werase(stdscr);
|
||||
}
|
||||
|
||||
int wclear(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("wclear() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
win->_clear = TRUE;
|
||||
return werase(win);
|
||||
}
|
||||
|
||||
int clear(void)
|
||||
{
|
||||
PDC_LOG(("clear() - called\n"));
|
||||
|
||||
return wclear(stdscr);
|
||||
}
|
||||
362
pdcurses/color.c
Normal file
362
pdcurses/color.c
Normal file
@@ -0,0 +1,362 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
color
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
bool has_colors(void);
|
||||
int start_color(void);
|
||||
int init_pair(short pair, short fg, short bg);
|
||||
int pair_content(short pair, short *fg, short *bg);
|
||||
bool can_change_color(void);
|
||||
int init_color(short color, short red, short green, short blue);
|
||||
int color_content(short color, short *red, short *green, short *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);
|
||||
|
||||
int PDC_set_line_color(short color);
|
||||
|
||||
### Description
|
||||
|
||||
To use these routines, first, call start_color(). Colors are always
|
||||
used in pairs, referred to as color-pairs. A color-pair is created by
|
||||
init_pair(), and consists of a foreground color and a background
|
||||
color. After initialization, COLOR_PAIR(n) can be used like any other
|
||||
video attribute.
|
||||
|
||||
has_colors() reports whether the terminal supports color.
|
||||
|
||||
start_color() initializes eight basic colors (black, red, green,
|
||||
yellow, blue, magenta, cyan, and white), and two global variables:
|
||||
COLORS and COLOR_PAIRS (respectively defining the maximum number of
|
||||
colors and color-pairs the terminal is capable of displaying).
|
||||
|
||||
init_pair() changes the definition of a color-pair. It takes three
|
||||
arguments: the number of the color-pair to be redefined, and the new
|
||||
values of the foreground and background colors. The pair number must
|
||||
be between 0 and COLOR_PAIRS - 1, inclusive. The foreground and
|
||||
background must be between 0 and COLORS - 1, inclusive. If the color
|
||||
pair was previously initialized, the screen is refreshed, and all
|
||||
occurrences of that color-pair are changed to the new definition.
|
||||
|
||||
pair_content() is used to determine what the colors of a given color-
|
||||
pair consist of.
|
||||
|
||||
can_change_color() indicates if the terminal has the capability to
|
||||
change the definition of its colors.
|
||||
|
||||
init_color() is used to redefine a color, if possible. Each of the
|
||||
components -- red, green, and blue -- is specified in a range from 0
|
||||
to 1000, inclusive.
|
||||
|
||||
color_content() reports the current definition of a color in the same
|
||||
format as used by init_color().
|
||||
|
||||
assume_default_colors() and use_default_colors() emulate the ncurses
|
||||
extensions of the same names. assume_default_colors(f, b) is
|
||||
essentially the same as init_pair(0, f, b) (which isn't allowed); it
|
||||
redefines the default colors. use_default_colors() allows the use of
|
||||
-1 as a foreground or background color with init_pair(), and calls
|
||||
assume_default_colors(-1, -1); -1 represents the foreground or
|
||||
background color that the terminal had at startup. If the environment
|
||||
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.
|
||||
|
||||
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
|
||||
foreground color should be used.
|
||||
|
||||
NOTE: COLOR_PAIR() and PAIR_NUMBER() are implemented as macros.
|
||||
|
||||
### Return Value
|
||||
|
||||
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
|
||||
has_colors Y Y Y
|
||||
start_color Y Y Y
|
||||
init_pair Y Y Y
|
||||
pair_content Y Y Y
|
||||
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 - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int COLORS = 0;
|
||||
int COLOR_PAIRS = PDC_COLOR_PAIRS;
|
||||
|
||||
static bool default_colors = FALSE;
|
||||
static short first_col = 0;
|
||||
static int allocnum = 0;
|
||||
|
||||
int start_color(void)
|
||||
{
|
||||
PDC_LOG(("start_color() - called\n"));
|
||||
|
||||
if (!SP || SP->mono)
|
||||
return ERR;
|
||||
|
||||
SP->color_started = TRUE;
|
||||
|
||||
PDC_set_blink(FALSE); /* Also sets COLORS */
|
||||
|
||||
if (!default_colors && SP->orig_attr && getenv("PDC_ORIGINAL_COLORS"))
|
||||
default_colors = TRUE;
|
||||
|
||||
PDC_init_atrtab();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void _normalize(short *fg, short *bg)
|
||||
{
|
||||
if (*fg == -1)
|
||||
*fg = SP->orig_attr ? SP->orig_fore : COLOR_WHITE;
|
||||
|
||||
if (*bg == -1)
|
||||
*bg = SP->orig_attr ? SP->orig_back : COLOR_BLACK;
|
||||
}
|
||||
|
||||
static void _init_pair_core(short pair, short fg, short bg)
|
||||
{
|
||||
PDC_PAIR *p = SP->atrtab + pair;
|
||||
|
||||
_normalize(&fg, &bg);
|
||||
|
||||
/* 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
|
||||
the user. */
|
||||
|
||||
if (p->set)
|
||||
{
|
||||
if (p->f != fg || p->b != bg)
|
||||
curscr->_clear = TRUE;
|
||||
}
|
||||
|
||||
p->f = fg;
|
||||
p->b = bg;
|
||||
p->count = allocnum++;
|
||||
p->set = TRUE;
|
||||
}
|
||||
|
||||
int init_pair(short pair, short fg, short bg)
|
||||
{
|
||||
PDC_LOG(("init_pair() - called: pair %d fg %d bg %d\n", pair, fg, bg));
|
||||
|
||||
if (!SP || !SP->color_started || pair < 1 || pair >= COLOR_PAIRS ||
|
||||
fg < first_col || fg >= COLORS || bg < first_col || bg >= COLORS)
|
||||
return ERR;
|
||||
|
||||
_init_pair_core(pair, fg, bg);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
bool has_colors(void)
|
||||
{
|
||||
PDC_LOG(("has_colors() - called\n"));
|
||||
|
||||
return SP ? !(SP->mono) : FALSE;
|
||||
}
|
||||
|
||||
int init_color(short color, short red, short green, short blue)
|
||||
{
|
||||
PDC_LOG(("init_color() - called\n"));
|
||||
|
||||
if (!SP || color < 0 || color >= COLORS || !PDC_can_change_color() ||
|
||||
red < -1 || red > 1000 || green < -1 || green > 1000 ||
|
||||
blue < -1 || blue > 1000)
|
||||
return ERR;
|
||||
|
||||
SP->dirty = TRUE;
|
||||
|
||||
return PDC_init_color(color, red, green, blue);
|
||||
}
|
||||
|
||||
int color_content(short color, short *red, short *green, short *blue)
|
||||
{
|
||||
PDC_LOG(("color_content() - called\n"));
|
||||
|
||||
if (color < 0 || color >= COLORS || !red || !green || !blue)
|
||||
return ERR;
|
||||
|
||||
if (PDC_can_change_color())
|
||||
return PDC_color_content(color, red, green, blue);
|
||||
else
|
||||
{
|
||||
/* Simulated values for platforms that don't support palette
|
||||
changing */
|
||||
|
||||
short maxval = (color & 8) ? 1000 : 680;
|
||||
|
||||
*red = (color & COLOR_RED) ? maxval : 0;
|
||||
*green = (color & COLOR_GREEN) ? maxval : 0;
|
||||
*blue = (color & COLOR_BLUE) ? maxval : 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
bool can_change_color(void)
|
||||
{
|
||||
PDC_LOG(("can_change_color() - called\n"));
|
||||
|
||||
return PDC_can_change_color();
|
||||
}
|
||||
|
||||
int pair_content(short pair, short *fg, short *bg)
|
||||
{
|
||||
PDC_LOG(("pair_content() - called\n"));
|
||||
|
||||
if (pair < 0 || pair >= COLOR_PAIRS || !fg || !bg)
|
||||
return ERR;
|
||||
|
||||
*fg = SP->atrtab[pair].f;
|
||||
*bg = SP->atrtab[pair].b;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int assume_default_colors(int f, int b)
|
||||
{
|
||||
PDC_LOG(("assume_default_colors() - called: f %d b %d\n", f, b));
|
||||
|
||||
if (f < -1 || f >= COLORS || b < -1 || b >= COLORS)
|
||||
return ERR;
|
||||
|
||||
if (SP->color_started)
|
||||
_init_pair_core(0, f, b);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int use_default_colors(void)
|
||||
{
|
||||
PDC_LOG(("use_default_colors() - called\n"));
|
||||
|
||||
default_colors = TRUE;
|
||||
first_col = -1;
|
||||
|
||||
return assume_default_colors(-1, -1);
|
||||
}
|
||||
|
||||
int PDC_set_line_color(short color)
|
||||
{
|
||||
PDC_LOG(("PDC_set_line_color() - called: %d\n", color));
|
||||
|
||||
if (!SP || color < -1 || color >= COLORS)
|
||||
return ERR;
|
||||
|
||||
SP->line_color = color;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void PDC_init_atrtab(void)
|
||||
{
|
||||
PDC_PAIR *p = SP->atrtab;
|
||||
short i, fg, bg;
|
||||
|
||||
if (SP->color_started && !default_colors)
|
||||
{
|
||||
fg = COLOR_WHITE;
|
||||
bg = COLOR_BLACK;
|
||||
}
|
||||
else
|
||||
fg = bg = -1;
|
||||
|
||||
_normalize(&fg, &bg);
|
||||
|
||||
for (i = 0; i < PDC_COLOR_PAIRS; i++)
|
||||
{
|
||||
p[i].f = fg;
|
||||
p[i].b = bg;
|
||||
p[i].set = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int free_pair(int pair)
|
||||
{
|
||||
if (pair < 1 || pair >= PDC_COLOR_PAIRS || !(SP->atrtab[pair].set))
|
||||
return ERR;
|
||||
|
||||
SP->atrtab[pair].set = FALSE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int find_pair(int fg, int bg)
|
||||
{
|
||||
int i;
|
||||
PDC_PAIR *p = SP->atrtab;
|
||||
|
||||
for (i = 0; i < PDC_COLOR_PAIRS; i++)
|
||||
if (p[i].set && p[i].f == fg && p[i].b == bg)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _find_oldest()
|
||||
{
|
||||
int i, lowind = 0, lowval = 0;
|
||||
PDC_PAIR *p = SP->atrtab;
|
||||
|
||||
for (i = 1; i < PDC_COLOR_PAIRS; i++)
|
||||
{
|
||||
if (!p[i].set)
|
||||
return i;
|
||||
|
||||
if (!lowval || (p[i].count < lowval))
|
||||
{
|
||||
lowind = i;
|
||||
lowval = p[i].count;
|
||||
}
|
||||
}
|
||||
|
||||
return lowind;
|
||||
}
|
||||
|
||||
int alloc_pair(int fg, int bg)
|
||||
{
|
||||
int i = find_pair(fg, bg);
|
||||
|
||||
if (-1 == i)
|
||||
{
|
||||
i = _find_oldest();
|
||||
|
||||
if (ERR == init_pair(i, fg, bg))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
106
pdcurses/debug.c
Normal file
106
pdcurses/debug.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
debug
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
void traceon(void);
|
||||
void traceoff(void);
|
||||
void PDC_debug(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.
|
||||
|
||||
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.
|
||||
|
||||
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).
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
traceon - - -
|
||||
traceoff - - -
|
||||
PDC_debug - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
static bool want_fflush = FALSE;
|
||||
|
||||
void PDC_debug(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char hms[9];
|
||||
time_t now;
|
||||
|
||||
if (!SP || !SP->dbfp)
|
||||
return;
|
||||
|
||||
time(&now);
|
||||
strftime(hms, 9, "%H:%M:%S", localtime(&now));
|
||||
fprintf(SP->dbfp, "At: %8.8ld - %s ", (long) clock(), hms);
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(SP->dbfp, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
/* If you are crashing and losing debugging information, enable this
|
||||
by setting the environment variable PDC_TRACE_FLUSH. This may
|
||||
impact performance. */
|
||||
|
||||
if (want_fflush)
|
||||
fflush(SP->dbfp);
|
||||
|
||||
/* If with PDC_TRACE_FLUSH enabled you are still losing logging in
|
||||
crashes, you may need to add a platform-dependent mechanism to
|
||||
flush the OS buffers as well (such as fsync() on POSIX) -- but
|
||||
expect terrible performance. */
|
||||
}
|
||||
|
||||
void traceon(void)
|
||||
{
|
||||
if (!SP)
|
||||
return;
|
||||
|
||||
if (SP->dbfp)
|
||||
fclose(SP->dbfp);
|
||||
|
||||
/* open debug log file append */
|
||||
SP->dbfp = fopen("trace", "a");
|
||||
if (!SP->dbfp)
|
||||
{
|
||||
fprintf(stderr, "PDC_debug(): Unable to open debug log file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (getenv("PDC_TRACE_FLUSH"))
|
||||
want_fflush = TRUE;
|
||||
|
||||
PDC_LOG(("traceon() - called\n"));
|
||||
}
|
||||
|
||||
void traceoff(void)
|
||||
{
|
||||
if (!SP || !SP->dbfp)
|
||||
return;
|
||||
|
||||
PDC_LOG(("traceoff() - called\n"));
|
||||
|
||||
fclose(SP->dbfp);
|
||||
SP->dbfp = NULL;
|
||||
want_fflush = FALSE;
|
||||
}
|
||||
96
pdcurses/delch.c
Normal file
96
pdcurses/delch.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
delch
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int delch(void);
|
||||
int wdelch(WINDOW *win);
|
||||
int mvdelch(int y, int x);
|
||||
int mvwdelch(WINDOW *win, int y, int x);
|
||||
|
||||
### Description
|
||||
|
||||
The character under the cursor in the window is deleted. All
|
||||
characters to the right on the same line are moved to the left one
|
||||
position and the last character on the line is filled with a blank.
|
||||
The cursor position does not change (after moving to y, x if
|
||||
coordinates are specified).
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
delch Y Y Y
|
||||
wdelch Y Y Y
|
||||
mvdelch Y Y Y
|
||||
mvwdelch Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int wdelch(WINDOW *win)
|
||||
{
|
||||
int y, x, maxx;
|
||||
chtype *temp1;
|
||||
|
||||
PDC_LOG(("wdelch() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
y = win->_cury;
|
||||
x = win->_curx;
|
||||
maxx = win->_maxx - 1;
|
||||
temp1 = &win->_y[y][x];
|
||||
|
||||
memmove(temp1, temp1 + 1, (maxx - x) * sizeof(chtype));
|
||||
|
||||
/* wrs (4/10/93) account for window background */
|
||||
|
||||
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_sync(win);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int delch(void)
|
||||
{
|
||||
PDC_LOG(("delch() - called\n"));
|
||||
|
||||
return wdelch(stdscr);
|
||||
}
|
||||
|
||||
int mvdelch(int y, int x)
|
||||
{
|
||||
PDC_LOG(("mvdelch() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wdelch(stdscr);
|
||||
}
|
||||
|
||||
int mvwdelch(WINDOW *win, int y, int x)
|
||||
{
|
||||
PDC_LOG(("mvwdelch() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wdelch(win);
|
||||
}
|
||||
211
pdcurses/deleteln.c
Normal file
211
pdcurses/deleteln.c
Normal file
@@ -0,0 +1,211 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
deleteln
|
||||
--------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int deleteln(void);
|
||||
int wdeleteln(WINDOW *win);
|
||||
int insdelln(int n);
|
||||
int winsdelln(WINDOW *win, int n);
|
||||
int insertln(void);
|
||||
int winsertln(WINDOW *win);
|
||||
|
||||
int mvdeleteln(int y, int x);
|
||||
int mvwdeleteln(WINDOW *win, int y, int x);
|
||||
int mvinsertln(int y, int x);
|
||||
int mvwinsertln(WINDOW *win, int y, int x);
|
||||
|
||||
### Description
|
||||
|
||||
With the deleteln() and wdeleteln() functions, the line under the
|
||||
cursor in the window is deleted. All lines below the current line are
|
||||
moved up one line. The bottom line of the window is cleared. The
|
||||
cursor position does not change.
|
||||
|
||||
With the insertln() and winsertn() functions, a blank line is
|
||||
inserted above the current line and the bottom line is lost.
|
||||
|
||||
mvdeleteln(), mvwdeleteln(), mvinsertln() and mvwinsertln() allow
|
||||
moving the cursor and inserting/deleting in one call.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
deleteln Y Y Y
|
||||
wdeleteln Y Y Y
|
||||
mvdeleteln - - -
|
||||
mvwdeleteln - - -
|
||||
insdelln Y Y Y
|
||||
winsdelln Y Y Y
|
||||
insertln Y Y Y
|
||||
winsertln Y Y Y
|
||||
mvinsertln - - -
|
||||
mvwinsertln - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int wdeleteln(WINDOW *win)
|
||||
{
|
||||
chtype blank, *temp, *ptr;
|
||||
int y;
|
||||
|
||||
PDC_LOG(("wdeleteln() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
/* wrs (4/10/93) account for window background */
|
||||
|
||||
blank = win->_bkgd;
|
||||
|
||||
temp = win->_y[win->_cury];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
for (ptr = temp; (ptr - temp < win->_maxx); ptr++)
|
||||
*ptr = blank; /* make a blank line */
|
||||
|
||||
if (win->_cury <= win->_bmarg)
|
||||
{
|
||||
win->_firstch[win->_bmarg] = 0;
|
||||
win->_lastch[win->_bmarg] = win->_maxx - 1;
|
||||
win->_y[win->_bmarg] = temp;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int deleteln(void)
|
||||
{
|
||||
PDC_LOG(("deleteln() - called\n"));
|
||||
|
||||
return wdeleteln(stdscr);
|
||||
}
|
||||
|
||||
int mvdeleteln(int y, int x)
|
||||
{
|
||||
PDC_LOG(("mvdeleteln() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wdeleteln(stdscr);
|
||||
}
|
||||
|
||||
int mvwdeleteln(WINDOW *win, int y, int x)
|
||||
{
|
||||
PDC_LOG(("mvwdeleteln() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wdeleteln(win);
|
||||
}
|
||||
|
||||
int winsdelln(WINDOW *win, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
PDC_LOG(("winsdelln() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
for (i = 0; i < n; i++)
|
||||
if (winsertln(win) == ERR)
|
||||
return ERR;
|
||||
}
|
||||
else if (n < 0)
|
||||
{
|
||||
n = -n;
|
||||
for (i = 0; i < n; i++)
|
||||
if (wdeleteln(win) == ERR)
|
||||
return ERR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int insdelln(int n)
|
||||
{
|
||||
PDC_LOG(("insdelln() - called\n"));
|
||||
|
||||
return winsdelln(stdscr, n);
|
||||
}
|
||||
|
||||
int winsertln(WINDOW *win)
|
||||
{
|
||||
chtype blank, *temp, *end;
|
||||
int y;
|
||||
|
||||
PDC_LOG(("winsertln() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
/* wrs (4/10/93) account for window background */
|
||||
|
||||
blank = win->_bkgd;
|
||||
|
||||
temp = win->_y[win->_maxy - 1];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
win->_y[win->_cury] = temp;
|
||||
|
||||
for (end = &temp[win->_maxx - 1]; temp <= end; temp++)
|
||||
*temp = blank;
|
||||
|
||||
win->_firstch[win->_cury] = 0;
|
||||
win->_lastch[win->_cury] = win->_maxx - 1;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int insertln(void)
|
||||
{
|
||||
PDC_LOG(("insertln() - called\n"));
|
||||
|
||||
return winsertln(stdscr);
|
||||
}
|
||||
|
||||
int mvinsertln(int y, int x)
|
||||
{
|
||||
PDC_LOG(("mvinsertln() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winsertln(stdscr);
|
||||
}
|
||||
|
||||
int mvwinsertln(WINDOW *win, int y, int x)
|
||||
{
|
||||
PDC_LOG(("mvwinsertln() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winsertln(win);
|
||||
}
|
||||
589
pdcurses/getch.c
Normal file
589
pdcurses/getch.c
Normal file
@@ -0,0 +1,589 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
getch
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int getch(void);
|
||||
int wgetch(WINDOW *win);
|
||||
int mvgetch(int y, int x);
|
||||
int mvwgetch(WINDOW *win, int y, int x);
|
||||
int ungetch(int ch);
|
||||
int flushinp(void);
|
||||
|
||||
int get_wch(wint_t *wch);
|
||||
int wget_wch(WINDOW *win, wint_t *wch);
|
||||
int mvget_wch(int y, int x, wint_t *wch);
|
||||
int mvwget_wch(WINDOW *win, int y, int x, wint_t *wch);
|
||||
int unget_wch(const wchar_t wch);
|
||||
|
||||
unsigned long PDC_get_key_modifiers(void);
|
||||
int PDC_return_key_modifiers(bool flag);
|
||||
|
||||
### Description
|
||||
|
||||
With the getch(), wgetch(), mvgetch(), and mvwgetch() functions, a
|
||||
character is read from the terminal associated with the window. In
|
||||
nodelay mode, if there is no input waiting, the value ERR is
|
||||
returned. In delay mode, the program will hang until the system
|
||||
passes text through to the program. Depending on the setting of
|
||||
cbreak(), this will be after one character or after the first
|
||||
newline. Unless noecho() has been set, the character will also be
|
||||
echoed into the designated window.
|
||||
|
||||
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 <curses.h> with integers
|
||||
beginning with 0401, 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.
|
||||
|
||||
ungetch() places ch back onto the input queue to be returned by the
|
||||
next call to wgetch().
|
||||
|
||||
flushinp() throws away any type-ahead that has been typed by the user
|
||||
and has not yet been read by the program.
|
||||
|
||||
wget_wch() is the wide-character version of wgetch(), available when
|
||||
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.
|
||||
|
||||
unget_wch() puts a wide character on the input queue.
|
||||
|
||||
PDC_get_key_modifiers() returns the keyboard modifiers (shift,
|
||||
control, alt, numlock) effective at the time of the last getch()
|
||||
call. Use the macros PDC_KEY_MODIFIER_* to determine which
|
||||
modifier(s) were set. PDC_return_key_modifiers() tells getch() to
|
||||
return modifier keys pressed alone as keystrokes (KEY_ALT_L, etc.).
|
||||
These may not work on all platforms.
|
||||
|
||||
NOTE: getch() and ungetch() are implemented as macros, to avoid
|
||||
conflict with many DOS compiler's runtime libraries.
|
||||
|
||||
### Return Value
|
||||
|
||||
These functions return ERR or the value of the character, meta
|
||||
character or function key token.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
getch Y Y Y
|
||||
wgetch Y Y Y
|
||||
mvgetch Y Y Y
|
||||
mvwgetch Y Y Y
|
||||
ungetch Y Y Y
|
||||
flushinp Y Y Y
|
||||
get_wch Y Y Y
|
||||
wget_wch Y Y Y
|
||||
mvget_wch Y Y Y
|
||||
mvwget_wch Y Y Y
|
||||
unget_wch Y Y Y
|
||||
PDC_get_key_modifiers - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static int _get_box(int *y_start, int *y_end, int *x_start, int *x_end)
|
||||
{
|
||||
int start, end;
|
||||
|
||||
if (SP->sel_start < SP->sel_end)
|
||||
{
|
||||
start = SP->sel_start;
|
||||
end = SP->sel_end;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = SP->sel_end;
|
||||
end = SP->sel_start;
|
||||
}
|
||||
|
||||
*y_start = start / COLS;
|
||||
*x_start = start % COLS;
|
||||
|
||||
*y_end = end / COLS;
|
||||
*x_end = end % COLS;
|
||||
|
||||
return (end - start) + (*y_end - *y_start);
|
||||
}
|
||||
|
||||
static void _highlight(void)
|
||||
{
|
||||
int i, j, y_start, y_end, x_start, x_end;
|
||||
|
||||
if (-1 == SP->sel_start)
|
||||
return;
|
||||
|
||||
_get_box(&y_start, &y_end, &x_start, &x_end);
|
||||
|
||||
for (j = y_start; j <= y_end; j++)
|
||||
for (i = (j == y_start ? x_start : 0);
|
||||
i < (j == y_end ? x_end : COLS); i++)
|
||||
curscr->_y[j][i] ^= A_REVERSE;
|
||||
|
||||
wrefresh(curscr);
|
||||
}
|
||||
|
||||
static void _copy(void)
|
||||
{
|
||||
#ifdef PDC_WIDE
|
||||
wchar_t *wtmp;
|
||||
# define TMP wtmp
|
||||
# define MASK A_CHARTEXT
|
||||
#else
|
||||
# define TMP tmp
|
||||
# define MASK 0xff
|
||||
#endif
|
||||
char *tmp;
|
||||
long pos;
|
||||
int i, j, y_start, y_end, x_start, x_end, len;
|
||||
|
||||
if (-1 == SP->sel_start)
|
||||
return;
|
||||
|
||||
len = _get_box(&y_start, &y_end, &x_start, &x_end);
|
||||
|
||||
if (!len)
|
||||
return;
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
wtmp = malloc((len + 1) * sizeof(wchar_t));
|
||||
len *= 3;
|
||||
#endif
|
||||
tmp = malloc(len + 1);
|
||||
|
||||
for (j = y_start, pos = 0; j <= y_end; j++)
|
||||
{
|
||||
for (i = (j == y_start ? x_start : 0);
|
||||
i < (j == y_end ? x_end : COLS); i++)
|
||||
TMP[pos++] = curscr->_y[j][i] & MASK;
|
||||
|
||||
while (y_start != y_end && pos > 0 && TMP[pos - 1] == 32)
|
||||
pos--;
|
||||
|
||||
if (j < y_end)
|
||||
TMP[pos++] = 10;
|
||||
}
|
||||
TMP[pos] = 0;
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
pos = PDC_wcstombs(tmp, wtmp, len);
|
||||
#endif
|
||||
|
||||
PDC_setclipboard(tmp, pos);
|
||||
free(tmp);
|
||||
#ifdef PDC_WIDE
|
||||
free(wtmp);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int _paste(void)
|
||||
{
|
||||
#ifdef PDC_WIDE
|
||||
wchar_t *wpaste;
|
||||
# define PASTE wpaste
|
||||
#else
|
||||
# define PASTE paste
|
||||
#endif
|
||||
char *paste;
|
||||
long len, newmax;
|
||||
int key;
|
||||
|
||||
key = PDC_getclipboard(&paste, &len);
|
||||
if (PDC_CLIP_SUCCESS != key || !len)
|
||||
return -1;
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
wpaste = malloc(len * sizeof(wchar_t));
|
||||
len = 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));
|
||||
if (!SP->c_ungch)
|
||||
return -1;
|
||||
SP->c_ungmax = newmax;
|
||||
}
|
||||
while (len > 1)
|
||||
PDC_ungetch(PASTE[--len]);
|
||||
key = *PASTE;
|
||||
#ifdef PDC_WIDE
|
||||
free(wpaste);
|
||||
#endif
|
||||
PDC_freeclipboard(paste);
|
||||
SP->key_modifiers = 0;
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static int _mouse_key(void)
|
||||
{
|
||||
int i, key = KEY_MOUSE, changes = SP->mouse_status.changes;
|
||||
unsigned long mbe = SP->_trap_mbe;
|
||||
|
||||
/* Selection highlighting? */
|
||||
|
||||
if ((!mbe || SP->mouse_status.button[0] & BUTTON_SHIFT) && changes & 1)
|
||||
{
|
||||
i = SP->mouse_status.y * COLS + SP->mouse_status.x;
|
||||
switch (SP->mouse_status.button[0] & BUTTON_ACTION_MASK)
|
||||
{
|
||||
case BUTTON_PRESSED:
|
||||
_highlight();
|
||||
SP->sel_start = SP->sel_end = i;
|
||||
return -1;
|
||||
case BUTTON_MOVED:
|
||||
_highlight();
|
||||
SP->sel_end = i;
|
||||
_highlight();
|
||||
return -1;
|
||||
case BUTTON_RELEASED:
|
||||
_copy();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if ((!mbe || SP->mouse_status.button[1] & BUTTON_SHIFT) &&
|
||||
changes & 2 && (SP->mouse_status.button[1] &
|
||||
BUTTON_ACTION_MASK) == BUTTON_CLICKED)
|
||||
{
|
||||
SP->key_code = FALSE;
|
||||
return _paste();
|
||||
}
|
||||
|
||||
/* Filter unwanted mouse events */
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (changes & (1 << i))
|
||||
{
|
||||
int shf = i * 5;
|
||||
short button = SP->mouse_status.button[i] & BUTTON_ACTION_MASK;
|
||||
|
||||
if ( (!(mbe & (BUTTON1_PRESSED << shf)) &&
|
||||
(button == BUTTON_PRESSED))
|
||||
|
||||
|| (!(mbe & (BUTTON1_CLICKED << shf)) &&
|
||||
(button == BUTTON_CLICKED))
|
||||
|
||||
|| (!(mbe & (BUTTON1_DOUBLE_CLICKED << shf)) &&
|
||||
(button == BUTTON_DOUBLE_CLICKED))
|
||||
|
||||
|| (!(mbe & (BUTTON1_MOVED << shf)) &&
|
||||
(button == BUTTON_MOVED))
|
||||
|
||||
|| (!(mbe & (BUTTON1_RELEASED << shf)) &&
|
||||
(button == BUTTON_RELEASED))
|
||||
)
|
||||
SP->mouse_status.changes ^= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
if (changes & PDC_MOUSE_MOVED)
|
||||
{
|
||||
if (!(mbe & (BUTTON1_MOVED|BUTTON2_MOVED|BUTTON3_MOVED)))
|
||||
SP->mouse_status.changes ^= PDC_MOUSE_MOVED;
|
||||
}
|
||||
|
||||
if (changes & (PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN))
|
||||
{
|
||||
if (!(mbe & MOUSE_WHEEL_SCROLL))
|
||||
SP->mouse_status.changes &=
|
||||
~(PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN);
|
||||
}
|
||||
|
||||
if (!changes)
|
||||
return -1;
|
||||
|
||||
/* Check for click in slk area */
|
||||
|
||||
i = PDC_mouse_in_slk(SP->mouse_status.y, SP->mouse_status.x);
|
||||
|
||||
if (i)
|
||||
{
|
||||
if (SP->mouse_status.button[0] & (BUTTON_PRESSED|BUTTON_CLICKED))
|
||||
key = KEY_F(i);
|
||||
else
|
||||
key = -1;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
int wgetch(WINDOW *win)
|
||||
{
|
||||
int key, waitcount;
|
||||
|
||||
PDC_LOG(("wgetch() - called\n"));
|
||||
|
||||
if (!win || !SP)
|
||||
return ERR;
|
||||
|
||||
waitcount = 0;
|
||||
|
||||
/* set the number of 1/20th second napms() calls */
|
||||
|
||||
if (SP->delaytenths)
|
||||
waitcount = 2 * SP->delaytenths;
|
||||
else
|
||||
if (win->_delayms)
|
||||
{
|
||||
/* Can't really do millisecond intervals, so delay in
|
||||
1/20ths of a second (50ms) */
|
||||
|
||||
waitcount = win->_delayms / 50;
|
||||
if (!waitcount)
|
||||
waitcount = 1;
|
||||
}
|
||||
|
||||
/* refresh window when wgetch is called if there have been changes
|
||||
to it and it is not a pad */
|
||||
|
||||
if (!(win->_flags & _PAD) && ((!win->_leaveit &&
|
||||
(win->_begx + win->_curx != SP->curscol ||
|
||||
win->_begy + win->_cury != SP->cursrow)) || is_wintouched(win)))
|
||||
wrefresh(win);
|
||||
|
||||
/* if ungotten char exists, remove and return it */
|
||||
|
||||
if (SP->c_ungind)
|
||||
return 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++];
|
||||
|
||||
/* prepare to buffer data */
|
||||
|
||||
SP->c_pindex = 0;
|
||||
SP->c_gindex = 0;
|
||||
|
||||
/* to get here, no keys are buffered. go and get one. */
|
||||
|
||||
for (;;) /* loop for any buffering */
|
||||
{
|
||||
/* is there a keystroke ready? */
|
||||
|
||||
if (!PDC_check_key())
|
||||
{
|
||||
/* if not, handle timeout() and halfdelay() */
|
||||
|
||||
if (SP->delaytenths || win->_delayms)
|
||||
{
|
||||
if (!waitcount)
|
||||
return ERR;
|
||||
|
||||
waitcount--;
|
||||
}
|
||||
else
|
||||
if (win->_nodelay)
|
||||
return ERR;
|
||||
|
||||
napms(50); /* sleep for 1/20th second */
|
||||
continue; /* then check again */
|
||||
}
|
||||
|
||||
/* if there is, fetch it */
|
||||
|
||||
key = PDC_get_key();
|
||||
|
||||
/* copy or paste? */
|
||||
|
||||
if (SP->key_modifiers & PDC_KEY_MODIFIER_SHIFT)
|
||||
{
|
||||
if (0x03 == key)
|
||||
{
|
||||
_copy();
|
||||
continue;
|
||||
}
|
||||
else if (0x16 == key)
|
||||
key = _paste();
|
||||
}
|
||||
|
||||
/* filter mouse events; translate mouse clicks in the slk
|
||||
area to function keys */
|
||||
|
||||
if (SP->key_code && key == KEY_MOUSE)
|
||||
key = _mouse_key();
|
||||
|
||||
/* filter special keys if not in keypad mode */
|
||||
|
||||
if (SP->key_code && !win->_use_keypad)
|
||||
key = -1;
|
||||
|
||||
/* unwanted key? loop back */
|
||||
|
||||
if (key == -1)
|
||||
continue;
|
||||
|
||||
_highlight();
|
||||
SP->sel_start = SP->sel_end = -1;
|
||||
|
||||
/* translate CR */
|
||||
|
||||
if (key == '\r' && SP->autocr && !SP->raw_inp)
|
||||
key = '\n';
|
||||
|
||||
/* if echo is enabled */
|
||||
|
||||
if (SP->echo && !SP->key_code)
|
||||
{
|
||||
waddch(win, key);
|
||||
wrefresh(win);
|
||||
}
|
||||
|
||||
/* if no buffering */
|
||||
|
||||
if (SP->raw_inp || SP->cbreak)
|
||||
return key;
|
||||
|
||||
/* if no overflow, put data in buffer */
|
||||
|
||||
if (key == '\b')
|
||||
{
|
||||
if (SP->c_pindex > SP->c_gindex)
|
||||
SP->c_pindex--;
|
||||
}
|
||||
else
|
||||
if (SP->c_pindex < _INBUFSIZ - 2)
|
||||
SP->c_buffer[SP->c_pindex++] = key;
|
||||
|
||||
/* if we got a line */
|
||||
|
||||
if (key == '\n' || key == '\r')
|
||||
return SP->c_buffer[SP->c_gindex++];
|
||||
}
|
||||
}
|
||||
|
||||
int mvgetch(int y, int x)
|
||||
{
|
||||
PDC_LOG(("mvgetch() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wgetch(stdscr);
|
||||
}
|
||||
|
||||
int mvwgetch(WINDOW *win, int y, int x)
|
||||
{
|
||||
PDC_LOG(("mvwgetch() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wgetch(win);
|
||||
}
|
||||
|
||||
int PDC_ungetch(int ch)
|
||||
{
|
||||
PDC_LOG(("ungetch() - called\n"));
|
||||
|
||||
if (SP->c_ungind >= SP->c_ungmax) /* pushback stack full */
|
||||
return ERR;
|
||||
|
||||
SP->c_ungch[SP->c_ungind++] = ch;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int flushinp(void)
|
||||
{
|
||||
PDC_LOG(("flushinp() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
PDC_flushinp();
|
||||
|
||||
SP->c_gindex = 1; /* set indices to kill buffer */
|
||||
SP->c_pindex = 0;
|
||||
SP->c_ungind = 0; /* clear SP->c_ungch array */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
unsigned long PDC_get_key_modifiers(void)
|
||||
{
|
||||
PDC_LOG(("PDC_get_key_modifiers() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
return SP->key_modifiers;
|
||||
}
|
||||
|
||||
int PDC_return_key_modifiers(bool flag)
|
||||
{
|
||||
PDC_LOG(("PDC_return_key_modifiers() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
SP->return_key_modifiers = flag;
|
||||
return PDC_modifiers_set();
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int wget_wch(WINDOW *win, wint_t *wch)
|
||||
{
|
||||
int key;
|
||||
|
||||
PDC_LOG(("wget_wch() - called\n"));
|
||||
|
||||
if (!wch)
|
||||
return ERR;
|
||||
|
||||
key = wgetch(win);
|
||||
|
||||
if (key == ERR)
|
||||
return ERR;
|
||||
|
||||
*wch = key;
|
||||
|
||||
return SP->key_code ? KEY_CODE_YES : OK;
|
||||
}
|
||||
|
||||
int get_wch(wint_t *wch)
|
||||
{
|
||||
PDC_LOG(("get_wch() - called\n"));
|
||||
|
||||
return wget_wch(stdscr, wch);
|
||||
}
|
||||
|
||||
int mvget_wch(int y, int x, wint_t *wch)
|
||||
{
|
||||
PDC_LOG(("mvget_wch() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wget_wch(stdscr, wch);
|
||||
}
|
||||
|
||||
int mvwget_wch(WINDOW *win, int y, int x, wint_t *wch)
|
||||
{
|
||||
PDC_LOG(("mvwget_wch() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wget_wch(win, wch);
|
||||
}
|
||||
|
||||
int unget_wch(const wchar_t wch)
|
||||
{
|
||||
return PDC_ungetch(wch);
|
||||
}
|
||||
#endif
|
||||
473
pdcurses/getstr.c
Normal file
473
pdcurses/getstr.c
Normal file
@@ -0,0 +1,473 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
getstr
|
||||
------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int getstr(char *str);
|
||||
int wgetstr(WINDOW *win, char *str);
|
||||
int mvgetstr(int y, int x, char *str);
|
||||
int mvwgetstr(WINDOW *win, int y, int x, char *str);
|
||||
int getnstr(char *str, int n);
|
||||
int wgetnstr(WINDOW *win, char *str, int n);
|
||||
int mvgetnstr(int y, int x, char *str, int n);
|
||||
int mvwgetnstr(WINDOW *win, int y, int x, char *str, int n);
|
||||
|
||||
int get_wstr(wint_t *wstr);
|
||||
int wget_wstr(WINDOW *win, wint_t *wstr);
|
||||
int mvget_wstr(int y, int x, wint_t *wstr);
|
||||
int mvwget_wstr(WINDOW *win, int, int, wint_t *wstr);
|
||||
int getn_wstr(wint_t *wstr, int n);
|
||||
int wgetn_wstr(WINDOW *win, wint_t *wstr, int n);
|
||||
int mvgetn_wstr(int y, int x, wint_t *wstr, int n);
|
||||
int mvwgetn_wstr(WINDOW *win, int y, int x, wint_t *wstr, int n);
|
||||
|
||||
### Description
|
||||
|
||||
These routines call wgetch() repeatedly to build a string,
|
||||
interpreting erase and kill characters along the way, until a newline
|
||||
or carriage return is received. When PDCurses is built with wide-
|
||||
character support enabled, the narrow-character functions convert the
|
||||
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.
|
||||
|
||||
Note that there's no way to know how long the buffer passed to
|
||||
wgetstr() is, so use wgetnstr() to avoid buffer overflows.
|
||||
|
||||
### Return Value
|
||||
|
||||
These functions return ERR on failure or any other value on success.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
getstr Y Y Y
|
||||
wgetstr Y Y Y
|
||||
mvgetstr Y Y Y
|
||||
mvwgetstr Y Y Y
|
||||
getnstr Y Y Y
|
||||
wgetnstr Y Y Y
|
||||
mvgetnstr Y Y Y
|
||||
mvwgetnstr Y Y Y
|
||||
get_wstr Y Y Y
|
||||
wget_wstr Y Y Y
|
||||
mvget_wstr Y Y Y
|
||||
mvwget_wstr Y Y Y
|
||||
getn_wstr Y Y Y
|
||||
wgetn_wstr Y Y Y
|
||||
mvgetn_wstr Y Y Y
|
||||
mvwgetn_wstr Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#define MAXLINE 255
|
||||
|
||||
int wgetnstr(WINDOW *win, char *str, int n)
|
||||
{
|
||||
#ifdef PDC_WIDE
|
||||
wchar_t wstr[MAXLINE + 1];
|
||||
|
||||
if (n < 0 || n > MAXLINE)
|
||||
n = MAXLINE;
|
||||
|
||||
if (wgetn_wstr(win, (wint_t *)wstr, n) == ERR)
|
||||
return ERR;
|
||||
|
||||
return PDC_wcstombs(str, wstr, n);
|
||||
#else
|
||||
int ch, i, num, x, chars;
|
||||
char *p;
|
||||
bool stop, oldecho, oldcbreak, oldnodelay;
|
||||
|
||||
PDC_LOG(("wgetnstr() - called\n"));
|
||||
|
||||
if (!win || !str)
|
||||
return ERR;
|
||||
|
||||
chars = 0;
|
||||
p = str;
|
||||
stop = FALSE;
|
||||
|
||||
x = win->_curx;
|
||||
|
||||
oldcbreak = SP->cbreak; /* remember states */
|
||||
oldecho = SP->echo;
|
||||
oldnodelay = win->_nodelay;
|
||||
|
||||
SP->echo = FALSE; /* we do echo ourselves */
|
||||
cbreak(); /* ensure each key is returned immediately */
|
||||
win->_nodelay = FALSE; /* don't return -1 */
|
||||
|
||||
wrefresh(win);
|
||||
|
||||
while (!stop)
|
||||
{
|
||||
ch = wgetch(win);
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
|
||||
case '\t':
|
||||
ch = ' ';
|
||||
num = TABSIZE - (win->_curx - x) % TABSIZE;
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
if (chars < n)
|
||||
{
|
||||
if (oldecho)
|
||||
waddch(win, ch);
|
||||
*p++ = ch;
|
||||
++chars;
|
||||
}
|
||||
else
|
||||
beep();
|
||||
}
|
||||
break;
|
||||
|
||||
case _ECHAR: /* CTRL-H -- Delete character */
|
||||
if (p > str)
|
||||
{
|
||||
if (oldecho)
|
||||
waddstr(win, "\b \b");
|
||||
ch = (unsigned char)(*--p);
|
||||
if ((ch < ' ') && (oldecho))
|
||||
waddstr(win, "\b \b");
|
||||
chars--;
|
||||
}
|
||||
break;
|
||||
|
||||
case _DLCHAR: /* CTRL-U -- Delete line */
|
||||
while (p > str)
|
||||
{
|
||||
if (oldecho)
|
||||
waddstr(win, "\b \b");
|
||||
ch = (unsigned char)(*--p);
|
||||
if ((ch < ' ') && (oldecho))
|
||||
waddstr(win, "\b \b");
|
||||
}
|
||||
chars = 0;
|
||||
break;
|
||||
|
||||
case _DWCHAR: /* CTRL-W -- Delete word */
|
||||
|
||||
while ((p > str) && (*(p - 1) == ' '))
|
||||
{
|
||||
if (oldecho)
|
||||
waddstr(win, "\b \b");
|
||||
|
||||
--p; /* remove space */
|
||||
chars--;
|
||||
}
|
||||
while ((p > str) && (*(p - 1) != ' '))
|
||||
{
|
||||
if (oldecho)
|
||||
waddstr(win, "\b \b");
|
||||
|
||||
ch = (unsigned char)(*--p);
|
||||
if ((ch < ' ') && (oldecho))
|
||||
waddstr(win, "\b \b");
|
||||
chars--;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
case '\r':
|
||||
stop = TRUE;
|
||||
if (oldecho)
|
||||
waddch(win, '\n');
|
||||
break;
|
||||
|
||||
default:
|
||||
if (chars < n)
|
||||
{
|
||||
if (!SP->key_code && ch < 0x100)
|
||||
{
|
||||
*p++ = ch;
|
||||
if (oldecho)
|
||||
waddch(win, ch);
|
||||
chars++;
|
||||
}
|
||||
}
|
||||
else
|
||||
beep();
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
wrefresh(win);
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
SP->echo = oldecho; /* restore old settings */
|
||||
SP->cbreak = oldcbreak;
|
||||
win->_nodelay = oldnodelay;
|
||||
|
||||
return OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
int getstr(char *str)
|
||||
{
|
||||
PDC_LOG(("getstr() - called\n"));
|
||||
|
||||
return wgetnstr(stdscr, str, MAXLINE);
|
||||
}
|
||||
|
||||
int wgetstr(WINDOW *win, char *str)
|
||||
{
|
||||
PDC_LOG(("wgetstr() - called\n"));
|
||||
|
||||
return wgetnstr(win, str, MAXLINE);
|
||||
}
|
||||
|
||||
int mvgetstr(int y, int x, char *str)
|
||||
{
|
||||
PDC_LOG(("mvgetstr() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wgetnstr(stdscr, str, MAXLINE);
|
||||
}
|
||||
|
||||
int mvwgetstr(WINDOW *win, int y, int x, char *str)
|
||||
{
|
||||
PDC_LOG(("mvwgetstr() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wgetnstr(win, str, MAXLINE);
|
||||
}
|
||||
|
||||
int getnstr(char *str, int n)
|
||||
{
|
||||
PDC_LOG(("getnstr() - called\n"));
|
||||
|
||||
return wgetnstr(stdscr, str, n);
|
||||
}
|
||||
|
||||
int mvgetnstr(int y, int x, char *str, int n)
|
||||
{
|
||||
PDC_LOG(("mvgetnstr() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wgetnstr(stdscr, str, n);
|
||||
}
|
||||
|
||||
int mvwgetnstr(WINDOW *win, int y, int x, char *str, int n)
|
||||
{
|
||||
PDC_LOG(("mvwgetnstr() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wgetnstr(win, str, n);
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int wgetn_wstr(WINDOW *win, wint_t *wstr, int n)
|
||||
{
|
||||
int ch, i, num, x, chars;
|
||||
wint_t *p;
|
||||
bool stop, oldecho, oldcbreak, oldnodelay;
|
||||
|
||||
PDC_LOG(("wgetn_wstr() - called\n"));
|
||||
|
||||
if (!win || !wstr)
|
||||
return ERR;
|
||||
|
||||
chars = 0;
|
||||
p = wstr;
|
||||
stop = FALSE;
|
||||
|
||||
x = win->_curx;
|
||||
|
||||
oldcbreak = SP->cbreak; /* remember states */
|
||||
oldecho = SP->echo;
|
||||
oldnodelay = win->_nodelay;
|
||||
|
||||
SP->echo = FALSE; /* we do echo ourselves */
|
||||
cbreak(); /* ensure each key is returned immediately */
|
||||
win->_nodelay = FALSE; /* don't return -1 */
|
||||
|
||||
wrefresh(win);
|
||||
|
||||
while (!stop)
|
||||
{
|
||||
ch = wgetch(win);
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
|
||||
case '\t':
|
||||
ch = ' ';
|
||||
num = TABSIZE - (win->_curx - x) % TABSIZE;
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
if (chars < n)
|
||||
{
|
||||
if (oldecho)
|
||||
waddch(win, ch);
|
||||
*p++ = ch;
|
||||
++chars;
|
||||
}
|
||||
else
|
||||
beep();
|
||||
}
|
||||
break;
|
||||
|
||||
case _ECHAR: /* CTRL-H -- Delete character */
|
||||
if (p > wstr)
|
||||
{
|
||||
if (oldecho)
|
||||
waddstr(win, "\b \b");
|
||||
ch = *--p;
|
||||
if ((ch < ' ') && (oldecho))
|
||||
waddstr(win, "\b \b");
|
||||
chars--;
|
||||
}
|
||||
break;
|
||||
|
||||
case _DLCHAR: /* CTRL-U -- Delete line */
|
||||
while (p > wstr)
|
||||
{
|
||||
if (oldecho)
|
||||
waddstr(win, "\b \b");
|
||||
ch = *--p;
|
||||
if ((ch < ' ') && (oldecho))
|
||||
waddstr(win, "\b \b");
|
||||
}
|
||||
chars = 0;
|
||||
break;
|
||||
|
||||
case _DWCHAR: /* CTRL-W -- Delete word */
|
||||
|
||||
while ((p > wstr) && (*(p - 1) == ' '))
|
||||
{
|
||||
if (oldecho)
|
||||
waddstr(win, "\b \b");
|
||||
|
||||
--p; /* remove space */
|
||||
chars--;
|
||||
}
|
||||
while ((p > wstr) && (*(p - 1) != ' '))
|
||||
{
|
||||
if (oldecho)
|
||||
waddstr(win, "\b \b");
|
||||
|
||||
ch = *--p;
|
||||
if ((ch < ' ') && (oldecho))
|
||||
waddstr(win, "\b \b");
|
||||
chars--;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
case '\r':
|
||||
stop = TRUE;
|
||||
if (oldecho)
|
||||
waddch(win, '\n');
|
||||
break;
|
||||
|
||||
default:
|
||||
if (chars < n)
|
||||
{
|
||||
if (!SP->key_code)
|
||||
{
|
||||
*p++ = ch;
|
||||
if (oldecho)
|
||||
waddch(win, ch);
|
||||
chars++;
|
||||
}
|
||||
}
|
||||
else
|
||||
beep();
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
wrefresh(win);
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
SP->echo = oldecho; /* restore old settings */
|
||||
SP->cbreak = oldcbreak;
|
||||
win->_nodelay = oldnodelay;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int get_wstr(wint_t *wstr)
|
||||
{
|
||||
PDC_LOG(("get_wstr() - called\n"));
|
||||
|
||||
return wgetn_wstr(stdscr, wstr, MAXLINE);
|
||||
}
|
||||
|
||||
int wget_wstr(WINDOW *win, wint_t *wstr)
|
||||
{
|
||||
PDC_LOG(("wget_wstr() - called\n"));
|
||||
|
||||
return wgetn_wstr(win, wstr, MAXLINE);
|
||||
}
|
||||
|
||||
int mvget_wstr(int y, int x, wint_t *wstr)
|
||||
{
|
||||
PDC_LOG(("mvget_wstr() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wgetn_wstr(stdscr, wstr, MAXLINE);
|
||||
}
|
||||
|
||||
int mvwget_wstr(WINDOW *win, int y, int x, wint_t *wstr)
|
||||
{
|
||||
PDC_LOG(("mvwget_wstr() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wgetn_wstr(win, wstr, MAXLINE);
|
||||
}
|
||||
|
||||
int getn_wstr(wint_t *wstr, int n)
|
||||
{
|
||||
PDC_LOG(("getn_wstr() - called\n"));
|
||||
|
||||
return wgetn_wstr(stdscr, wstr, n);
|
||||
}
|
||||
|
||||
int mvgetn_wstr(int y, int x, wint_t *wstr, int n)
|
||||
{
|
||||
PDC_LOG(("mvgetn_wstr() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wgetn_wstr(stdscr, wstr, n);
|
||||
}
|
||||
|
||||
int mvwgetn_wstr(WINDOW *win, int y, int x, wint_t *wstr, int n)
|
||||
{
|
||||
PDC_LOG(("mvwgetn_wstr() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wgetn_wstr(win, wstr, n);
|
||||
}
|
||||
#endif
|
||||
142
pdcurses/getyx.c
Normal file
142
pdcurses/getyx.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
getyx
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
void getyx(WINDOW *win, int y, int x);
|
||||
void getparyx(WINDOW *win, int y, int x);
|
||||
void getbegyx(WINDOW *win, int y, int x);
|
||||
void getmaxyx(WINDOW *win, int y, int x);
|
||||
|
||||
void getsyx(int y, int x);
|
||||
void setsyx(int y, int x);
|
||||
|
||||
int getbegy(WINDOW *win);
|
||||
int getbegx(WINDOW *win);
|
||||
int getcury(WINDOW *win);
|
||||
int getcurx(WINDOW *win);
|
||||
int getpary(WINDOW *win);
|
||||
int getparx(WINDOW *win);
|
||||
int getmaxy(WINDOW *win);
|
||||
int getmaxx(WINDOW *win);
|
||||
|
||||
### Description
|
||||
|
||||
The getyx() macro (defined in curses.h -- the prototypes here are
|
||||
merely illustrative) puts the current cursor position of the
|
||||
specified window into y and x. getbegyx() and getmaxyx() return the
|
||||
starting coordinates and size of the specified window, respectively.
|
||||
getparyx() returns the starting coordinates of the parent's window,
|
||||
if the specified window is a subwindow; otherwise it sets y and x to
|
||||
-1. These are all macros.
|
||||
|
||||
getsyx() gets the coordinates of the virtual screen cursor, and
|
||||
stores them in y and x. If leaveok() is TRUE, it returns -1, -1. If
|
||||
lines have been removed with ripoffline(), then getsyx() includes
|
||||
these lines in its count; so, the returned y and x values should only
|
||||
be used with setsyx().
|
||||
|
||||
setsyx() sets the virtual screen cursor to the y, x coordinates. If
|
||||
either y or x is -1, leaveok() is set TRUE, else it's set FALSE.
|
||||
|
||||
getsyx() and setsyx() are meant to be used by a library routine that
|
||||
manipulates curses windows without altering the position of the
|
||||
cursor. Note that getsyx() is defined only as a macro.
|
||||
|
||||
getbegy(), getbegx(), getcurx(), getcury(), getmaxy(), getmaxx(),
|
||||
getpary(), and getparx() return the appropriate coordinate or size
|
||||
values, or ERR in the case of a NULL window.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
getyx Y Y Y
|
||||
getparyx Y Y Y
|
||||
getbegyx Y Y Y
|
||||
getmaxyx Y Y Y
|
||||
getsyx - Y Y
|
||||
setsyx - Y Y
|
||||
getbegy - Y Y
|
||||
getbegx - Y Y
|
||||
getcury - Y Y
|
||||
getcurx - Y Y
|
||||
getpary - Y Y
|
||||
getparx - Y Y
|
||||
getmaxy - Y Y
|
||||
getmaxx - Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int getbegy(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("getbegy() - called\n"));
|
||||
|
||||
return win ? win->_begy : ERR;
|
||||
}
|
||||
|
||||
int getbegx(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("getbegx() - called\n"));
|
||||
|
||||
return win ? win->_begx : ERR;
|
||||
}
|
||||
|
||||
int getcury(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("getcury() - called\n"));
|
||||
|
||||
return win ? win->_cury : ERR;
|
||||
}
|
||||
|
||||
int getcurx(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("getcurx() - called\n"));
|
||||
|
||||
return win ? win->_curx : ERR;
|
||||
}
|
||||
|
||||
int getpary(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("getpary() - called\n"));
|
||||
|
||||
return win ? win->_pary : ERR;
|
||||
}
|
||||
|
||||
int getparx(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("getparx() - called\n"));
|
||||
|
||||
return win ? win->_parx : ERR;
|
||||
}
|
||||
|
||||
int getmaxy(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("getmaxy() - called\n"));
|
||||
|
||||
return win ? win->_maxy : ERR;
|
||||
}
|
||||
|
||||
int getmaxx(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("getmaxx() - called\n"));
|
||||
|
||||
return win ? win->_maxx : ERR;
|
||||
}
|
||||
|
||||
void setsyx(int y, int x)
|
||||
{
|
||||
PDC_LOG(("setsyx() - called\n"));
|
||||
|
||||
if (curscr)
|
||||
{
|
||||
curscr->_leaveit = y == -1 || x == -1;
|
||||
|
||||
if (!curscr->_leaveit)
|
||||
wmove(curscr, y, x);
|
||||
}
|
||||
}
|
||||
126
pdcurses/inch.c
Normal file
126
pdcurses/inch.c
Normal file
@@ -0,0 +1,126 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
inch
|
||||
----
|
||||
|
||||
### Synopsis
|
||||
|
||||
chtype inch(void);
|
||||
chtype winch(WINDOW *win);
|
||||
chtype mvinch(int y, int x);
|
||||
chtype mvwinch(WINDOW *win, int y, int x);
|
||||
|
||||
int in_wch(cchar_t *wcval);
|
||||
int win_wch(WINDOW *win, cchar_t *wcval);
|
||||
int mvin_wch(int y, int x, cchar_t *wcval);
|
||||
int mvwin_wch(WINDOW *win, int y, int x, cchar_t *wcval);
|
||||
|
||||
### Description
|
||||
|
||||
The inch() functions retrieve the character and attribute from the
|
||||
current or specified window position, in the form of a chtype. If a
|
||||
NULL window is specified, (chtype)ERR is returned.
|
||||
|
||||
The in_wch() functions are the wide-character versions; instead of
|
||||
returning a chtype, they store a cchar_t at the address specified by
|
||||
wcval, and return OK or ERR. (No value is stored when ERR is
|
||||
returned.) Note that in PDCurses, chtype and cchar_t are the same.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
inch Y Y Y
|
||||
winch Y Y Y
|
||||
mvinch Y Y Y
|
||||
mvwinch Y Y Y
|
||||
in_wch Y Y Y
|
||||
win_wch Y Y Y
|
||||
mvin_wch Y Y Y
|
||||
mvwin_wch Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
chtype winch(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("winch() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return (chtype)ERR;
|
||||
|
||||
return win->_y[win->_cury][win->_curx];
|
||||
}
|
||||
|
||||
chtype inch(void)
|
||||
{
|
||||
PDC_LOG(("inch() - called\n"));
|
||||
|
||||
return winch(stdscr);
|
||||
}
|
||||
|
||||
chtype mvinch(int y, int x)
|
||||
{
|
||||
PDC_LOG(("mvinch() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return (chtype)ERR;
|
||||
|
||||
return stdscr->_y[stdscr->_cury][stdscr->_curx];
|
||||
}
|
||||
|
||||
chtype mvwinch(WINDOW *win, int y, int x)
|
||||
{
|
||||
PDC_LOG(("mvwinch() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return (chtype)ERR;
|
||||
|
||||
return win->_y[win->_cury][win->_curx];
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int win_wch(WINDOW *win, cchar_t *wcval)
|
||||
{
|
||||
PDC_LOG(("win_wch() - called\n"));
|
||||
|
||||
if (!win || !wcval)
|
||||
return ERR;
|
||||
|
||||
*wcval = win->_y[win->_cury][win->_curx];
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int in_wch(cchar_t *wcval)
|
||||
{
|
||||
PDC_LOG(("in_wch() - called\n"));
|
||||
|
||||
return win_wch(stdscr, wcval);
|
||||
}
|
||||
|
||||
int mvin_wch(int y, int x, cchar_t *wcval)
|
||||
{
|
||||
PDC_LOG(("mvin_wch() - called\n"));
|
||||
|
||||
if (!wcval || (move(y, x) == ERR))
|
||||
return ERR;
|
||||
|
||||
*wcval = stdscr->_y[stdscr->_cury][stdscr->_curx];
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int mvwin_wch(WINDOW *win, int y, int x, cchar_t *wcval)
|
||||
{
|
||||
PDC_LOG(("mvwin_wch() - called\n"));
|
||||
|
||||
if (!wcval || (wmove(win, y, x) == ERR))
|
||||
return ERR;
|
||||
|
||||
*wcval = win->_y[win->_cury][win->_curx];
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
213
pdcurses/inchstr.c
Normal file
213
pdcurses/inchstr.c
Normal file
@@ -0,0 +1,213 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
inchstr
|
||||
-------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int inchstr(chtype *ch);
|
||||
int inchnstr(chtype *ch, int n);
|
||||
int winchstr(WINDOW *win, chtype *ch);
|
||||
int winchnstr(WINDOW *win, chtype *ch, int n);
|
||||
int mvinchstr(int y, int x, chtype *ch);
|
||||
int mvinchnstr(int y, int x, chtype *ch, int n);
|
||||
int mvwinchstr(WINDOW *, int y, int x, chtype *ch);
|
||||
int mvwinchnstr(WINDOW *, int y, int x, chtype *ch, int n);
|
||||
|
||||
int in_wchstr(cchar_t *wch);
|
||||
int in_wchnstr(cchar_t *wch, int n);
|
||||
int win_wchstr(WINDOW *win, cchar_t *wch);
|
||||
int win_wchnstr(WINDOW *win, cchar_t *wch, int n);
|
||||
int mvin_wchstr(int y, int x, cchar_t *wch);
|
||||
int mvin_wchnstr(int y, int x, cchar_t *wch, int n);
|
||||
int mvwin_wchstr(WINDOW *win, int y, int x, cchar_t *wch);
|
||||
int mvwin_wchnstr(WINDOW *win, int y, int x, cchar_t *wch, int n);
|
||||
|
||||
### Description
|
||||
|
||||
These routines read a chtype or cchar_t string from the window,
|
||||
starting at the current or specified position, and ending at the
|
||||
right margin, or after n elements, whichever is less.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return the number of elements read, or ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
inchstr Y Y Y
|
||||
winchstr Y Y Y
|
||||
mvinchstr Y Y Y
|
||||
mvwinchstr Y Y Y
|
||||
inchnstr Y Y Y
|
||||
winchnstr Y Y Y
|
||||
mvinchnstr Y Y Y
|
||||
mvwinchnstr Y Y Y
|
||||
in_wchstr Y Y Y
|
||||
win_wchstr Y Y Y
|
||||
mvin_wchstr Y Y Y
|
||||
mvwin_wchstr Y Y Y
|
||||
in_wchnstr Y Y Y
|
||||
win_wchnstr Y Y Y
|
||||
mvin_wchnstr Y Y Y
|
||||
mvwin_wchnstr Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int winchnstr(WINDOW *win, chtype *ch, int n)
|
||||
{
|
||||
chtype *src;
|
||||
int i;
|
||||
|
||||
PDC_LOG(("winchnstr() - called\n"));
|
||||
|
||||
if (!win || !ch || n < 0)
|
||||
return ERR;
|
||||
|
||||
if ((win->_curx + n) > win->_maxx)
|
||||
n = win->_maxx - win->_curx;
|
||||
|
||||
src = win->_y[win->_cury] + win->_curx;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
*ch++ = *src++;
|
||||
|
||||
*ch = (chtype)0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int inchstr(chtype *ch)
|
||||
{
|
||||
PDC_LOG(("inchstr() - called\n"));
|
||||
|
||||
return winchnstr(stdscr, ch, stdscr->_maxx - stdscr->_curx);
|
||||
}
|
||||
|
||||
int winchstr(WINDOW *win, chtype *ch)
|
||||
{
|
||||
PDC_LOG(("winchstr() - called\n"));
|
||||
|
||||
return winchnstr(win, ch, win->_maxx - win->_curx);
|
||||
}
|
||||
|
||||
int mvinchstr(int y, int x, chtype *ch)
|
||||
{
|
||||
PDC_LOG(("mvinchstr() - called: y %d x %d\n", y, x));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winchnstr(stdscr, ch, stdscr->_maxx - stdscr->_curx);
|
||||
}
|
||||
|
||||
int mvwinchstr(WINDOW *win, int y, int x, chtype *ch)
|
||||
{
|
||||
PDC_LOG(("mvwinchstr() - called:\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winchnstr(win, ch, win->_maxx - win->_curx);
|
||||
}
|
||||
|
||||
int inchnstr(chtype *ch, int n)
|
||||
{
|
||||
PDC_LOG(("inchnstr() - called\n"));
|
||||
|
||||
return winchnstr(stdscr, ch, n);
|
||||
}
|
||||
|
||||
int mvinchnstr(int y, int x, chtype *ch, int n)
|
||||
{
|
||||
PDC_LOG(("mvinchnstr() - called: y %d x %d n %d\n", y, x, n));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winchnstr(stdscr, ch, n);
|
||||
}
|
||||
|
||||
int mvwinchnstr(WINDOW *win, int y, int x, chtype *ch, int n)
|
||||
{
|
||||
PDC_LOG(("mvwinchnstr() - called: y %d x %d n %d \n", y, x, n));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winchnstr(win, ch, n);
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int win_wchnstr(WINDOW *win, cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("win_wchnstr() - called\n"));
|
||||
|
||||
return winchnstr(win, wch, n);
|
||||
}
|
||||
|
||||
int in_wchstr(cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("in_wchstr() - called\n"));
|
||||
|
||||
return win_wchnstr(stdscr, wch, stdscr->_maxx - stdscr->_curx);
|
||||
}
|
||||
|
||||
int win_wchstr(WINDOW *win, cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("win_wchstr() - called\n"));
|
||||
|
||||
return win_wchnstr(win, wch, win->_maxx - win->_curx);
|
||||
}
|
||||
|
||||
int mvin_wchstr(int y, int x, cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("mvin_wchstr() - called: y %d x %d\n", y, x));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return win_wchnstr(stdscr, wch, stdscr->_maxx - stdscr->_curx);
|
||||
}
|
||||
|
||||
int mvwin_wchstr(WINDOW *win, int y, int x, cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("mvwin_wchstr() - called:\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return win_wchnstr(win, wch, win->_maxx - win->_curx);
|
||||
}
|
||||
|
||||
int in_wchnstr(cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("in_wchnstr() - called\n"));
|
||||
|
||||
return win_wchnstr(stdscr, wch, n);
|
||||
}
|
||||
|
||||
int mvin_wchnstr(int y, int x, cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("mvin_wchnstr() - called: y %d x %d n %d\n", y, x, n));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return win_wchnstr(stdscr, wch, n);
|
||||
}
|
||||
|
||||
int mvwin_wchnstr(WINDOW *win, int y, int x, cchar_t *wch, int n)
|
||||
{
|
||||
PDC_LOG(("mvwinchnstr() - called: y %d x %d n %d \n", y, x, n));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return win_wchnstr(win, wch, n);
|
||||
}
|
||||
#endif
|
||||
431
pdcurses/initscr.c
Normal file
431
pdcurses/initscr.c
Normal file
@@ -0,0 +1,431 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
initscr
|
||||
-------
|
||||
|
||||
### Synopsis
|
||||
|
||||
WINDOW *initscr(void);
|
||||
WINDOW *Xinitscr(int argc, char **argv);
|
||||
int endwin(void);
|
||||
bool isendwin(void);
|
||||
SCREEN *newterm(const char *type, FILE *outfd, FILE *infd);
|
||||
SCREEN *set_term(SCREEN *new);
|
||||
void delscreen(SCREEN *sp);
|
||||
|
||||
int resize_term(int nlines, int ncols);
|
||||
bool is_termresized(void);
|
||||
const char *curses_version(void);
|
||||
void PDC_get_version(PDC_VERSION *ver);
|
||||
|
||||
int set_tabsize(int tabsize);
|
||||
|
||||
### Description
|
||||
|
||||
initscr() should be the first curses routine called. It will
|
||||
initialize all curses data structures, and arrange that the first
|
||||
call to refresh() will clear the screen. In case of error, initscr()
|
||||
will write a message to standard error and end the program.
|
||||
|
||||
endwin() should be called before exiting or escaping from curses mode
|
||||
temporarily. It will restore tty modes, move the cursor to the lower
|
||||
left corner of the screen and reset the terminal into the proper
|
||||
non-visual mode. To resume curses after a temporary escape, call
|
||||
refresh() or doupdate().
|
||||
|
||||
isendwin() returns TRUE if endwin() has been called without a
|
||||
subsequent refresh, unless SP is NULL.
|
||||
|
||||
In some implementations of curses, newterm() allows the use of
|
||||
multiple terminals. Here, it's just an alternative interface for
|
||||
initscr(). It always returns SP, or NULL.
|
||||
|
||||
delscreen() frees the memory allocated by newterm() or initscr(),
|
||||
since it's not freed by endwin(). This function is usually not
|
||||
needed. In PDCurses, the parameter must be the value of SP, and
|
||||
delscreen() sets SP to NULL.
|
||||
|
||||
set_term() does nothing meaningful in PDCurses, but is included for
|
||||
compatibility with other curses implementations.
|
||||
|
||||
resize_term() is effectively two functions: When called with nonzero
|
||||
values for nlines and ncols, it attempts to resize the screen to the
|
||||
given size. When called with (0, 0), it merely adjusts the internal
|
||||
structures to match the current size after the screen is resized by
|
||||
the user. On the currently supported platforms, SDL, Windows console,
|
||||
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() returns TRUE if the curses screen has been resized
|
||||
by the user, and a call to resize_term() is needed. Checking for
|
||||
KEY_RESIZE is generally preferable, unless you're not handling the
|
||||
keyboard.
|
||||
|
||||
curses_version() returns a string describing the version of PDCurses.
|
||||
|
||||
PDC_get_version() fills a PDC_VERSION structure provided by the user
|
||||
with more detailed version info (see curses.h).
|
||||
|
||||
set_tabsize() sets the tab interval, stored in TABSIZE.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return NULL on error, except endwin(), which always
|
||||
returns OK, and resize_term(), which returns either OK or ERR.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
initscr Y Y Y
|
||||
endwin Y Y Y
|
||||
isendwin Y Y Y
|
||||
newterm Y Y Y
|
||||
set_term Y Y Y
|
||||
delscreen Y Y Y
|
||||
resize_term - Y Y
|
||||
set_tabsize - Y Y
|
||||
curses_version - Y -
|
||||
is_termresized - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
char ttytype[128];
|
||||
|
||||
const char *_curses_notice = "PDCurses " PDC_VERDOT " - " __DATE__;
|
||||
|
||||
SCREEN *SP = (SCREEN*)NULL; /* curses variables */
|
||||
WINDOW *curscr = (WINDOW *)NULL; /* the current screen image */
|
||||
WINDOW *stdscr = (WINDOW *)NULL; /* the default screen window */
|
||||
|
||||
int LINES = 0; /* current terminal height */
|
||||
int COLS = 0; /* current terminal width */
|
||||
int TABSIZE = 8;
|
||||
|
||||
MOUSE_STATUS Mouse_status;
|
||||
|
||||
extern RIPPEDOFFLINE linesripped[5];
|
||||
extern char linesrippedoff;
|
||||
|
||||
WINDOW *initscr(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
PDC_LOG(("initscr() - called\n"));
|
||||
|
||||
if (SP && SP->alive)
|
||||
return NULL;
|
||||
|
||||
SP = calloc(1, sizeof(SCREEN));
|
||||
if (!SP)
|
||||
return NULL;
|
||||
|
||||
if (PDC_scr_open() == ERR)
|
||||
{
|
||||
fprintf(stderr, "initscr(): Unable to create SP\n");
|
||||
exit(8);
|
||||
}
|
||||
|
||||
SP->autocr = TRUE; /* cr -> lf by default */
|
||||
SP->raw_out = FALSE; /* tty I/O modes */
|
||||
SP->raw_inp = FALSE; /* tty I/O modes */
|
||||
SP->cbreak = TRUE;
|
||||
SP->key_modifiers = 0L;
|
||||
SP->return_key_modifiers = FALSE;
|
||||
SP->echo = TRUE;
|
||||
SP->visibility = 1;
|
||||
SP->resized = FALSE;
|
||||
SP->_trap_mbe = 0L;
|
||||
SP->linesrippedoff = 0;
|
||||
SP->linesrippedoffontop = 0;
|
||||
SP->delaytenths = 0;
|
||||
SP->line_color = -1;
|
||||
SP->lastscr = (WINDOW *)NULL;
|
||||
SP->dbfp = NULL;
|
||||
SP->color_started = FALSE;
|
||||
SP->dirty = FALSE;
|
||||
SP->sel_start = -1;
|
||||
SP->sel_end = -1;
|
||||
|
||||
SP->orig_cursor = PDC_get_cursor_mode();
|
||||
|
||||
LINES = SP->lines = PDC_get_rows();
|
||||
COLS = SP->cols = PDC_get_columns();
|
||||
|
||||
if (LINES < 2 || COLS < 2)
|
||||
{
|
||||
fprintf(stderr, "initscr(): LINES=%d COLS=%d: too small.\n",
|
||||
LINES, COLS);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
curscr = newwin(LINES, COLS, 0, 0);
|
||||
if (!curscr)
|
||||
{
|
||||
fprintf(stderr, "initscr(): Unable to create curscr.\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
SP->lastscr = newwin(LINES, COLS, 0, 0);
|
||||
if (!SP->lastscr)
|
||||
{
|
||||
fprintf(stderr, "initscr(): Unable to create SP->lastscr.\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
wattrset(SP->lastscr, (chtype)(-1));
|
||||
werase(SP->lastscr);
|
||||
|
||||
PDC_slk_initialize();
|
||||
LINES -= SP->slklines;
|
||||
|
||||
/* We have to sort out ripped off lines here, and reduce the height
|
||||
of stdscr by the number of lines ripped off */
|
||||
|
||||
for (i = 0; i < linesrippedoff; i++)
|
||||
{
|
||||
if (linesripped[i].line < 0)
|
||||
(*linesripped[i].init)(newwin(1, COLS, LINES - 1, 0), COLS);
|
||||
else
|
||||
(*linesripped[i].init)(newwin(1, COLS,
|
||||
SP->linesrippedoffontop++, 0), COLS);
|
||||
|
||||
SP->linesrippedoff++;
|
||||
LINES--;
|
||||
}
|
||||
|
||||
linesrippedoff = 0;
|
||||
|
||||
stdscr = newwin(LINES, COLS, SP->linesrippedoffontop, 0);
|
||||
if (!stdscr)
|
||||
{
|
||||
fprintf(stderr, "initscr(): Unable to create stdscr.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
wclrtobot(stdscr);
|
||||
|
||||
/* If preserving the existing screen, don't allow a screen clear */
|
||||
|
||||
if (SP->_preserve)
|
||||
{
|
||||
untouchwin(curscr);
|
||||
untouchwin(stdscr);
|
||||
stdscr->_clear = FALSE;
|
||||
curscr->_clear = FALSE;
|
||||
}
|
||||
else
|
||||
curscr->_clear = TRUE;
|
||||
|
||||
SP->atrtab = calloc(PDC_COLOR_PAIRS, sizeof(PDC_PAIR));
|
||||
if (!SP->atrtab)
|
||||
return NULL;
|
||||
PDC_init_atrtab(); /* set up default colors */
|
||||
|
||||
MOUSE_X_POS = MOUSE_Y_POS = -1;
|
||||
BUTTON_STATUS(1) = BUTTON_RELEASED;
|
||||
BUTTON_STATUS(2) = BUTTON_RELEASED;
|
||||
BUTTON_STATUS(3) = BUTTON_RELEASED;
|
||||
Mouse_status.changes = 0;
|
||||
|
||||
SP->alive = TRUE;
|
||||
|
||||
def_shell_mode();
|
||||
|
||||
sprintf(ttytype, "pdcurses|PDCurses for %s", PDC_sysname());
|
||||
|
||||
SP->c_buffer = malloc(_INBUFSIZ * sizeof(int));
|
||||
if (!SP->c_buffer)
|
||||
return NULL;
|
||||
SP->c_pindex = 0;
|
||||
SP->c_gindex = 1;
|
||||
|
||||
SP->c_ungch = malloc(NUNGETCH * sizeof(int));
|
||||
if (!SP->c_ungch)
|
||||
return NULL;
|
||||
SP->c_ungind = 0;
|
||||
SP->c_ungmax = NUNGETCH;
|
||||
|
||||
return stdscr;
|
||||
}
|
||||
|
||||
#ifdef XCURSES
|
||||
WINDOW *Xinitscr(int argc, char **argv)
|
||||
{
|
||||
PDC_LOG(("Xinitscr() - called\n"));
|
||||
|
||||
PDC_set_args(argc, argv);
|
||||
return initscr();
|
||||
}
|
||||
#endif
|
||||
|
||||
int endwin(void)
|
||||
{
|
||||
PDC_LOG(("endwin() - called\n"));
|
||||
|
||||
/* Allow temporary exit from curses using endwin() */
|
||||
|
||||
def_prog_mode();
|
||||
PDC_scr_close();
|
||||
|
||||
SP->alive = FALSE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
bool isendwin(void)
|
||||
{
|
||||
PDC_LOG(("isendwin() - called\n"));
|
||||
|
||||
return SP ? !(SP->alive) : FALSE;
|
||||
}
|
||||
|
||||
SCREEN *newterm(const char *type, FILE *outfd, FILE *infd)
|
||||
{
|
||||
PDC_LOG(("newterm() - called\n"));
|
||||
|
||||
return initscr() ? SP : NULL;
|
||||
}
|
||||
|
||||
SCREEN *set_term(SCREEN *new)
|
||||
{
|
||||
PDC_LOG(("set_term() - called\n"));
|
||||
|
||||
/* We only support one screen */
|
||||
|
||||
return (new == SP) ? SP : NULL;
|
||||
}
|
||||
|
||||
void delscreen(SCREEN *sp)
|
||||
{
|
||||
PDC_LOG(("delscreen() - called\n"));
|
||||
|
||||
if (!SP || sp != SP)
|
||||
return;
|
||||
|
||||
free(SP->c_ungch);
|
||||
free(SP->c_buffer);
|
||||
free(SP->atrtab);
|
||||
|
||||
PDC_slk_free(); /* free the soft label keys, if needed */
|
||||
|
||||
delwin(stdscr);
|
||||
delwin(curscr);
|
||||
delwin(SP->lastscr);
|
||||
stdscr = (WINDOW *)NULL;
|
||||
curscr = (WINDOW *)NULL;
|
||||
SP->lastscr = (WINDOW *)NULL;
|
||||
|
||||
SP->alive = FALSE;
|
||||
|
||||
PDC_scr_free();
|
||||
|
||||
free(SP);
|
||||
SP = (SCREEN *)NULL;
|
||||
}
|
||||
|
||||
int resize_term(int nlines, int ncols)
|
||||
{
|
||||
PDC_LOG(("resize_term() - called: nlines %d\n", nlines));
|
||||
|
||||
if (!stdscr || PDC_resize_screen(nlines, ncols) == ERR)
|
||||
return ERR;
|
||||
|
||||
SP->resized = FALSE;
|
||||
|
||||
SP->lines = PDC_get_rows();
|
||||
LINES = SP->lines - SP->linesrippedoff - SP->slklines;
|
||||
SP->cols = COLS = PDC_get_columns();
|
||||
|
||||
if (SP->cursrow >= SP->lines)
|
||||
SP->cursrow = SP->lines - 1;
|
||||
if (SP->curscol >= SP->cols)
|
||||
SP->curscol = SP->cols - 1;
|
||||
|
||||
if (wresize(curscr, SP->lines, SP->cols) == ERR ||
|
||||
wresize(stdscr, LINES, COLS) == ERR ||
|
||||
wresize(SP->lastscr, SP->lines, SP->cols) == ERR)
|
||||
return ERR;
|
||||
|
||||
werase(SP->lastscr);
|
||||
curscr->_clear = TRUE;
|
||||
|
||||
if (SP->slk_winptr)
|
||||
{
|
||||
if (wresize(SP->slk_winptr, SP->slklines, COLS) == ERR)
|
||||
return ERR;
|
||||
|
||||
wmove(SP->slk_winptr, 0, 0);
|
||||
wclrtobot(SP->slk_winptr);
|
||||
PDC_slk_initialize();
|
||||
slk_noutrefresh();
|
||||
}
|
||||
|
||||
touchwin(stdscr);
|
||||
wnoutrefresh(stdscr);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
bool is_termresized(void)
|
||||
{
|
||||
PDC_LOG(("is_termresized() - called\n"));
|
||||
|
||||
return SP->resized;
|
||||
}
|
||||
|
||||
const char *curses_version(void)
|
||||
{
|
||||
return _curses_notice;
|
||||
}
|
||||
|
||||
void PDC_get_version(PDC_VERSION *ver)
|
||||
{
|
||||
if (!ver)
|
||||
return;
|
||||
|
||||
ver->flags = 0
|
||||
#ifdef PDCDEBUG
|
||||
| PDC_VFLAG_DEBUG
|
||||
#endif
|
||||
#ifdef PDC_WIDE
|
||||
| PDC_VFLAG_WIDE
|
||||
#endif
|
||||
#ifdef PDC_FORCE_UTF8
|
||||
| PDC_VFLAG_UTF8
|
||||
#endif
|
||||
#ifdef PDC_DLL_BUILD
|
||||
| PDC_VFLAG_DLL
|
||||
#endif
|
||||
#ifdef PDC_RGB
|
||||
| PDC_VFLAG_RGB
|
||||
#endif
|
||||
;
|
||||
|
||||
ver->build = PDC_BUILD;
|
||||
ver->major = PDC_VER_MAJOR;
|
||||
ver->minor = PDC_VER_MINOR;
|
||||
ver->csize = sizeof(chtype);
|
||||
ver->bsize = sizeof(bool);
|
||||
}
|
||||
|
||||
int set_tabsize(int tabsize)
|
||||
{
|
||||
PDC_LOG(("set_tabsize() - called: tabsize %d\n", tabsize));
|
||||
|
||||
if (tabsize < 1)
|
||||
return ERR;
|
||||
|
||||
TABSIZE = tabsize;
|
||||
|
||||
return OK;
|
||||
}
|
||||
368
pdcurses/inopts.c
Normal file
368
pdcurses/inopts.c
Normal file
@@ -0,0 +1,368 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
inopts
|
||||
------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int cbreak(void);
|
||||
int nocbreak(void);
|
||||
int echo(void);
|
||||
int noecho(void);
|
||||
int halfdelay(int tenths);
|
||||
int intrflush(WINDOW *win, bool bf);
|
||||
int keypad(WINDOW *win, bool bf);
|
||||
int meta(WINDOW *win, bool bf);
|
||||
int nl(void);
|
||||
int nonl(void);
|
||||
int nodelay(WINDOW *win, bool bf);
|
||||
int notimeout(WINDOW *win, bool bf);
|
||||
int raw(void);
|
||||
int noraw(void);
|
||||
void noqiflush(void);
|
||||
void qiflush(void);
|
||||
void timeout(int delay);
|
||||
void wtimeout(WINDOW *win, int delay);
|
||||
int typeahead(int fildes);
|
||||
|
||||
int crmode(void);
|
||||
int nocrmode(void);
|
||||
|
||||
bool is_keypad(const WINDOW *win);
|
||||
|
||||
### Description
|
||||
|
||||
cbreak() and nocbreak() toggle cbreak mode. In cbreak mode,
|
||||
characters typed by the user are made available immediately, and
|
||||
erase/kill character processing is not performed. In nocbreak mode,
|
||||
typed characters are buffered until a newline or carriage return.
|
||||
Interrupt and flow control characters are unaffected by this mode.
|
||||
PDCurses always starts in cbreak mode.
|
||||
|
||||
echo() and noecho() control whether typed characters are echoed by
|
||||
the input routine. Initially, input characters are echoed. Subsequent
|
||||
calls to echo() and noecho() do not flush type-ahead.
|
||||
|
||||
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
|
||||
must be between 1 and 255.
|
||||
|
||||
keypad() controls whether getch() returns function/special keys as
|
||||
single key codes (e.g., the left arrow key as KEY_LEFT). Per X/Open,
|
||||
the default for keypad mode is OFF. You'll probably want it on. With
|
||||
keypad mode off, if a special key is pressed, getch() does nothing or
|
||||
returns ERR.
|
||||
|
||||
nodelay() controls whether wgetch() is a non-blocking call. If the
|
||||
option is enabled, and no input is ready, wgetch() will return ERR.
|
||||
If disabled, wgetch() will hang until input is ready.
|
||||
|
||||
nl() enables the translation of a carriage return into a newline on
|
||||
input. nonl() disables this. Initially, the translation does occur.
|
||||
|
||||
raw() and noraw() toggle raw mode. Raw mode is similar to cbreak
|
||||
mode, in that characters typed are immediately passed through to the
|
||||
user program. The difference is that in raw mode, the INTR, QUIT,
|
||||
SUSP, and STOP characters are passed through without being
|
||||
interpreted, and without generating a signal.
|
||||
|
||||
In PDCurses, the meta() function sets raw mode on or off.
|
||||
|
||||
timeout() and wtimeout() set blocking or non-blocking reads for the
|
||||
specified window. If the delay is negative, a blocking read is used;
|
||||
if zero, then non-blocking reads are done -- if no input is waiting,
|
||||
ERR is returned immediately. If the delay is positive, the read
|
||||
blocks for the delay period; if the period expires, ERR is returned.
|
||||
The delay is given in milliseconds, but this is rounded down to 50ms
|
||||
(1/20th sec) intervals, with a minimum of one interval if a postive
|
||||
delay is given; i.e., 1-99 will wait 50ms, 100-149 will wait 100ms,
|
||||
etc.
|
||||
|
||||
intrflush(), notimeout(), noqiflush(), qiflush() and typeahead() do
|
||||
nothing in PDCurses, but are included for compatibility with other
|
||||
curses implementations.
|
||||
|
||||
crmode() and nocrmode() are archaic equivalents to cbreak() and
|
||||
nocbreak(), respectively.
|
||||
|
||||
is_keypad() reports whether the specified window is in keypad mode.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions except is_keypad() and the void functions return OK on
|
||||
success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
cbreak Y Y Y
|
||||
nocbreak Y Y Y
|
||||
echo Y Y Y
|
||||
noecho Y Y Y
|
||||
halfdelay Y Y Y
|
||||
intrflush Y Y Y
|
||||
keypad Y Y Y
|
||||
meta Y Y Y
|
||||
nl Y Y Y
|
||||
nonl Y Y Y
|
||||
nodelay Y Y Y
|
||||
notimeout Y Y Y
|
||||
raw Y Y Y
|
||||
noraw Y Y Y
|
||||
noqiflush Y Y Y
|
||||
qiflush Y Y Y
|
||||
timeout Y Y Y
|
||||
wtimeout Y Y Y
|
||||
typeahead Y Y Y
|
||||
crmode Y Y Y
|
||||
nocrmode Y Y Y
|
||||
is_keypad - Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int cbreak(void)
|
||||
{
|
||||
PDC_LOG(("cbreak() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
SP->cbreak = TRUE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int nocbreak(void)
|
||||
{
|
||||
PDC_LOG(("nocbreak() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
SP->cbreak = FALSE;
|
||||
SP->delaytenths = 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int echo(void)
|
||||
{
|
||||
PDC_LOG(("echo() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
SP->echo = TRUE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int noecho(void)
|
||||
{
|
||||
PDC_LOG(("noecho() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
SP->echo = FALSE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int halfdelay(int tenths)
|
||||
{
|
||||
PDC_LOG(("halfdelay() - called\n"));
|
||||
|
||||
if (!SP || tenths < 1 || tenths > 255)
|
||||
return ERR;
|
||||
|
||||
SP->delaytenths = tenths;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int intrflush(WINDOW *win, bool bf)
|
||||
{
|
||||
PDC_LOG(("intrflush() - called\n"));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int keypad(WINDOW *win, bool bf)
|
||||
{
|
||||
PDC_LOG(("keypad() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
win->_use_keypad = bf;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int meta(WINDOW *win, bool bf)
|
||||
{
|
||||
PDC_LOG(("meta() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
SP->raw_inp = bf;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int nl(void)
|
||||
{
|
||||
PDC_LOG(("nl() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
SP->autocr = TRUE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int nonl(void)
|
||||
{
|
||||
PDC_LOG(("nonl() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
SP->autocr = FALSE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int nodelay(WINDOW *win, bool flag)
|
||||
{
|
||||
PDC_LOG(("nodelay() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
win->_nodelay = flag;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int notimeout(WINDOW *win, bool flag)
|
||||
{
|
||||
PDC_LOG(("notimeout() - called\n"));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int raw(void)
|
||||
{
|
||||
PDC_LOG(("raw() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
PDC_set_keyboard_binary(TRUE);
|
||||
SP->raw_inp = TRUE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int noraw(void)
|
||||
{
|
||||
PDC_LOG(("noraw() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
PDC_set_keyboard_binary(FALSE);
|
||||
SP->raw_inp = FALSE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void noqiflush(void)
|
||||
{
|
||||
PDC_LOG(("noqiflush() - called\n"));
|
||||
}
|
||||
|
||||
void qiflush(void)
|
||||
{
|
||||
PDC_LOG(("qiflush() - called\n"));
|
||||
}
|
||||
|
||||
int typeahead(int fildes)
|
||||
{
|
||||
PDC_LOG(("typeahead() - called\n"));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void wtimeout(WINDOW *win, int delay)
|
||||
{
|
||||
PDC_LOG(("wtimeout() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return;
|
||||
|
||||
if (delay < 0)
|
||||
{
|
||||
/* This causes a blocking read on the window, so turn on delay
|
||||
mode */
|
||||
|
||||
win->_nodelay = FALSE;
|
||||
win->_delayms = 0;
|
||||
}
|
||||
else if (!delay)
|
||||
{
|
||||
/* This causes a non-blocking read on the window, so turn off
|
||||
delay mode */
|
||||
|
||||
win->_nodelay = TRUE;
|
||||
win->_delayms = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This causes the read on the window to delay for the number of
|
||||
milliseconds. Also forces the window into non-blocking read
|
||||
mode */
|
||||
|
||||
/*win->_nodelay = TRUE;*/
|
||||
win->_delayms = delay;
|
||||
}
|
||||
}
|
||||
|
||||
void timeout(int delay)
|
||||
{
|
||||
PDC_LOG(("timeout() - called\n"));
|
||||
|
||||
wtimeout(stdscr, delay);
|
||||
}
|
||||
|
||||
int crmode(void)
|
||||
{
|
||||
PDC_LOG(("crmode() - called\n"));
|
||||
|
||||
return cbreak();
|
||||
}
|
||||
|
||||
int nocrmode(void)
|
||||
{
|
||||
PDC_LOG(("nocrmode() - called\n"));
|
||||
|
||||
return nocbreak();
|
||||
}
|
||||
|
||||
bool is_keypad(const WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("is_keypad() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return FALSE;
|
||||
|
||||
return win->_use_keypad;
|
||||
}
|
||||
270
pdcurses/insch.c
Normal file
270
pdcurses/insch.c
Normal file
@@ -0,0 +1,270 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
insch
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int insch(chtype ch);
|
||||
int winsch(WINDOW *win, chtype ch);
|
||||
int mvinsch(int y, int x, chtype ch);
|
||||
int mvwinsch(WINDOW *win, int y, int x, chtype ch);
|
||||
|
||||
int insrawch(chtype ch);
|
||||
int winsrawch(WINDOW *win, chtype ch);
|
||||
int mvinsrawch(int y, int x, chtype ch);
|
||||
int mvwinsrawch(WINDOW *win, int y, int x, chtype ch);
|
||||
|
||||
int ins_wch(const cchar_t *wch);
|
||||
int wins_wch(WINDOW *win, const cchar_t *wch);
|
||||
int mvins_wch(int y, int x, const cchar_t *wch);
|
||||
int mvwins_wch(WINDOW *win, int y, int x, const cchar_t *wch);
|
||||
|
||||
### Description
|
||||
|
||||
The insch() functions insert a chtype into the window at the current
|
||||
or specified cursor position. The cursor is NOT advanced. A newline
|
||||
is equivalent to clrtoeol(); tabs are expanded; other control
|
||||
characters are converted as with unctrl().
|
||||
|
||||
The ins_wch() functions are the wide-character equivalents, taking
|
||||
cchar_t pointers rather than chtypes.
|
||||
|
||||
Video attributes can be combined with a character by ORing them into
|
||||
the parameter. Text, including attributes, can be copied from one
|
||||
place to another using inch() and insch().
|
||||
|
||||
insrawch() etc. are PDCurses-specific wrappers for insch() etc. that
|
||||
disable the translation of control characters.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
insch Y Y Y
|
||||
winsch Y Y Y
|
||||
mvinsch Y Y Y
|
||||
mvwinsch Y Y Y
|
||||
ins_wch Y Y Y
|
||||
wins_wch Y Y Y
|
||||
mvins_wch Y Y Y
|
||||
mvwins_wch Y Y Y
|
||||
insrawch - - -
|
||||
winsrawch - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int winsch(WINDOW *win, chtype ch)
|
||||
{
|
||||
int x, y;
|
||||
chtype attr;
|
||||
bool xlat;
|
||||
|
||||
PDC_LOG(("winsch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
|
||||
win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
x = win->_curx;
|
||||
y = win->_cury;
|
||||
|
||||
if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0)
|
||||
return ERR;
|
||||
|
||||
xlat = !SP->raw_out && !(ch & A_ALTCHARSET);
|
||||
attr = ch & A_ATTRIBUTES;
|
||||
ch &= A_CHARTEXT;
|
||||
|
||||
if (xlat && (ch < ' ' || ch == 0x7f))
|
||||
{
|
||||
int x2;
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case '\t':
|
||||
for (x2 = ((x / TABSIZE) + 1) * TABSIZE; x < x2; x++)
|
||||
{
|
||||
if (winsch(win, attr | ' ') == ERR)
|
||||
return ERR;
|
||||
}
|
||||
return OK;
|
||||
|
||||
case '\n':
|
||||
wclrtoeol(win);
|
||||
break;
|
||||
|
||||
case 0x7f:
|
||||
if (winsch(win, attr | '?') == ERR)
|
||||
return ERR;
|
||||
|
||||
return winsch(win, attr | '^');
|
||||
|
||||
default:
|
||||
/* handle control chars */
|
||||
|
||||
if (winsch(win, attr | (ch + '@')) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winsch(win, attr | '^');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int maxx;
|
||||
chtype *temp;
|
||||
|
||||
/* If the incoming character doesn't have its own attribute,
|
||||
then use the current attributes for the window. If it has
|
||||
attributes but not a color component, OR the attributes to
|
||||
the current attributes for the window. If it has a color
|
||||
component, use the attributes solely from the incoming
|
||||
character. */
|
||||
|
||||
if (!(attr & A_COLOR))
|
||||
attr |= win->_attrs;
|
||||
|
||||
/* wrs (4/10/93): Apply the same sort of logic for the window
|
||||
background, in that it only takes precedence if other color
|
||||
attributes are not there and that the background character
|
||||
will only print if the printing character is blank. */
|
||||
|
||||
if (!(attr & A_COLOR))
|
||||
attr |= win->_bkgd & A_ATTRIBUTES;
|
||||
else
|
||||
attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR);
|
||||
|
||||
if (ch == ' ')
|
||||
ch = win->_bkgd & A_CHARTEXT;
|
||||
|
||||
/* Add the attribute back into the character. */
|
||||
|
||||
ch |= attr;
|
||||
|
||||
maxx = win->_maxx;
|
||||
temp = &win->_y[y][x];
|
||||
|
||||
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;
|
||||
|
||||
*temp = ch;
|
||||
}
|
||||
|
||||
PDC_sync(win);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int insch(chtype ch)
|
||||
{
|
||||
PDC_LOG(("insch() - called\n"));
|
||||
|
||||
return winsch(stdscr, ch);
|
||||
}
|
||||
|
||||
int mvinsch(int y, int x, chtype ch)
|
||||
{
|
||||
PDC_LOG(("mvinsch() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winsch(stdscr, ch);
|
||||
}
|
||||
|
||||
int mvwinsch(WINDOW *win, int y, int x, chtype ch)
|
||||
{
|
||||
PDC_LOG(("mvwinsch() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winsch(win, ch);
|
||||
}
|
||||
|
||||
int winsrawch(WINDOW *win, chtype ch)
|
||||
{
|
||||
PDC_LOG(("winsrawch() - called: win=%p ch=%x "
|
||||
"(char=%c attr=0x%x)\n", win, ch,
|
||||
ch & A_CHARTEXT, ch & A_ATTRIBUTES));
|
||||
|
||||
if ((ch & A_CHARTEXT) < ' ' || (ch & A_CHARTEXT) == 0x7f)
|
||||
ch |= A_ALTCHARSET;
|
||||
|
||||
return winsch(win, ch);
|
||||
}
|
||||
|
||||
int insrawch(chtype ch)
|
||||
{
|
||||
PDC_LOG(("insrawch() - called\n"));
|
||||
|
||||
return winsrawch(stdscr, ch);
|
||||
}
|
||||
|
||||
int mvinsrawch(int y, int x, chtype ch)
|
||||
{
|
||||
PDC_LOG(("mvinsrawch() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winsrawch(stdscr, ch);
|
||||
}
|
||||
|
||||
int mvwinsrawch(WINDOW *win, int y, int x, chtype ch)
|
||||
{
|
||||
PDC_LOG(("mvwinsrawch() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winsrawch(win, ch);
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int wins_wch(WINDOW *win, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("wins_wch() - called\n"));
|
||||
|
||||
return wch ? winsch(win, *wch) : ERR;
|
||||
}
|
||||
|
||||
int ins_wch(const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("ins_wch() - called\n"));
|
||||
|
||||
return wins_wch(stdscr, wch);
|
||||
}
|
||||
|
||||
int mvins_wch(int y, int x, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("mvins_wch() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wins_wch(stdscr, wch);
|
||||
}
|
||||
|
||||
int mvwins_wch(WINDOW *win, int y, int x, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("mvwins_wch() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wins_wch(win, wch);
|
||||
}
|
||||
#endif
|
||||
263
pdcurses/insstr.c
Normal file
263
pdcurses/insstr.c
Normal file
@@ -0,0 +1,263 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
insstr
|
||||
------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int insstr(const char *str);
|
||||
int insnstr(const char *str, int n);
|
||||
int winsstr(WINDOW *win, const char *str);
|
||||
int winsnstr(WINDOW *win, const char *str, int n);
|
||||
int mvinsstr(int y, int x, const char *str);
|
||||
int mvinsnstr(int y, int x, const char *str, int n);
|
||||
int mvwinsstr(WINDOW *win, int y, int x, const char *str);
|
||||
int mvwinsnstr(WINDOW *win, int y, int x, const char *str, int n);
|
||||
|
||||
int ins_wstr(const wchar_t *wstr);
|
||||
int ins_nwstr(const wchar_t *wstr, int n);
|
||||
int wins_wstr(WINDOW *win, const wchar_t *wstr);
|
||||
int wins_nwstr(WINDOW *win, const wchar_t *wstr, int n);
|
||||
int mvins_wstr(int y, int x, const wchar_t *wstr);
|
||||
int mvins_nwstr(int y, int x, const wchar_t *wstr, int n);
|
||||
int mvwins_wstr(WINDOW *win, int y, int x, const wchar_t *wstr);
|
||||
int mvwins_nwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n);
|
||||
|
||||
### Description
|
||||
|
||||
The insstr() functions insert a character string into a window at the
|
||||
current cursor position, by repeatedly calling winsch(). When
|
||||
PDCurses is built with wide-character support enabled, the narrow-
|
||||
character functions treat the string as a multibyte string in the
|
||||
current locale, and convert it first. All characters to the right of
|
||||
the cursor are moved to the right, with the possibility of the
|
||||
rightmost characters on the line being lost. The cursor position
|
||||
does not change (after moving to y, x, if specified). The routines
|
||||
with n as the last argument insert at most n characters; if n is
|
||||
negative, then the entire string is inserted.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
insstr Y Y Y
|
||||
winsstr Y Y Y
|
||||
mvinsstr Y Y Y
|
||||
mvwinsstr Y Y Y
|
||||
insnstr Y Y Y
|
||||
winsnstr Y Y Y
|
||||
mvinsnstr Y Y Y
|
||||
mvwinsnstr Y Y Y
|
||||
ins_wstr Y Y Y
|
||||
wins_wstr Y Y Y
|
||||
mvins_wstr Y Y Y
|
||||
mvwins_wstr Y Y Y
|
||||
ins_nwstr Y Y Y
|
||||
wins_nwstr Y Y Y
|
||||
mvins_nwstr Y Y Y
|
||||
mvwins_nwstr Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int winsnstr(WINDOW *win, const char *str, int n)
|
||||
{
|
||||
#ifdef PDC_WIDE
|
||||
wchar_t wstr[513], *p;
|
||||
int i;
|
||||
#endif
|
||||
int len;
|
||||
|
||||
PDC_LOG(("winsnstr() - called: string=\"%s\" n %d \n", str, n));
|
||||
|
||||
if (!win || !str)
|
||||
return ERR;
|
||||
|
||||
len = strlen(str);
|
||||
|
||||
if (n < 0 || n > len)
|
||||
n = len;
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
if (n > 512)
|
||||
n = 512;
|
||||
|
||||
p = wstr;
|
||||
i = 0;
|
||||
|
||||
while (str[i] && i < n)
|
||||
{
|
||||
int retval = PDC_mbtowc(p, str + i, n - i);
|
||||
|
||||
if (retval <= 0)
|
||||
break;
|
||||
p++;
|
||||
i += retval;
|
||||
}
|
||||
|
||||
while (p > wstr)
|
||||
if (winsch(win, *--p) == ERR)
|
||||
#else
|
||||
while (n)
|
||||
if (winsch(win, (unsigned char)(str[--n])) == ERR)
|
||||
#endif
|
||||
return ERR;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int insstr(const char *str)
|
||||
{
|
||||
PDC_LOG(("insstr() - called: string=\"%s\"\n", str));
|
||||
|
||||
return winsnstr(stdscr, str, -1);
|
||||
}
|
||||
|
||||
int winsstr(WINDOW *win, const char *str)
|
||||
{
|
||||
PDC_LOG(("winsstr() - called: string=\"%s\"\n", str));
|
||||
|
||||
return winsnstr(win, str, -1);
|
||||
}
|
||||
|
||||
int mvinsstr(int y, int x, const char *str)
|
||||
{
|
||||
PDC_LOG(("mvinsstr() - called: y %d x %d string=\"%s\"\n", y, x, str));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winsnstr(stdscr, str, -1);
|
||||
}
|
||||
|
||||
int mvwinsstr(WINDOW *win, int y, int x, const char *str)
|
||||
{
|
||||
PDC_LOG(("mvwinsstr() - called: string=\"%s\"\n", str));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winsnstr(win, str, -1);
|
||||
}
|
||||
|
||||
int insnstr(const char *str, int n)
|
||||
{
|
||||
PDC_LOG(("insnstr() - called: string=\"%s\" n %d \n", str, n));
|
||||
|
||||
return winsnstr(stdscr, str, n);
|
||||
}
|
||||
|
||||
int mvinsnstr(int y, int x, const char *str, int n)
|
||||
{
|
||||
PDC_LOG(("mvinsnstr() - called: y %d x %d string=\"%s\" n %d \n",
|
||||
y, x, str, n));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winsnstr(stdscr, str, n);
|
||||
}
|
||||
|
||||
int mvwinsnstr(WINDOW *win, int y, int x, const char *str, int n)
|
||||
{
|
||||
PDC_LOG(("mvwinsnstr() - called: y %d x %d string=\"%s\" n %d \n",
|
||||
y, x, str, n));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winsnstr(win, str, n);
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int wins_nwstr(WINDOW *win, const wchar_t *wstr, int n)
|
||||
{
|
||||
const wchar_t *p;
|
||||
int len;
|
||||
|
||||
PDC_LOG(("wins_nwstr() - called\n"));
|
||||
|
||||
if (!win || !wstr)
|
||||
return ERR;
|
||||
|
||||
for (len = 0, p = wstr; *p; p++)
|
||||
len++;
|
||||
|
||||
if (n < 0 || n > len)
|
||||
n = len;
|
||||
|
||||
while (n)
|
||||
if (winsch(win, wstr[--n]) == ERR)
|
||||
return ERR;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int ins_wstr(const wchar_t *wstr)
|
||||
{
|
||||
PDC_LOG(("ins_wstr() - called\n"));
|
||||
|
||||
return wins_nwstr(stdscr, wstr, -1);
|
||||
}
|
||||
|
||||
int wins_wstr(WINDOW *win, const wchar_t *wstr)
|
||||
{
|
||||
PDC_LOG(("wins_wstr() - called\n"));
|
||||
|
||||
return wins_nwstr(win, wstr, -1);
|
||||
}
|
||||
|
||||
int mvins_wstr(int y, int x, const wchar_t *wstr)
|
||||
{
|
||||
PDC_LOG(("mvins_wstr() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wins_nwstr(stdscr, wstr, -1);
|
||||
}
|
||||
|
||||
int mvwins_wstr(WINDOW *win, int y, int x, const wchar_t *wstr)
|
||||
{
|
||||
PDC_LOG(("mvwinsstr() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wins_nwstr(win, wstr, -1);
|
||||
}
|
||||
|
||||
int ins_nwstr(const wchar_t *wstr, int n)
|
||||
{
|
||||
PDC_LOG(("ins_nwstr() - called\n"));
|
||||
|
||||
return wins_nwstr(stdscr, wstr, n);
|
||||
}
|
||||
|
||||
int mvins_nwstr(int y, int x, const wchar_t *wstr, int n)
|
||||
{
|
||||
PDC_LOG(("mvinsnstr() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wins_nwstr(stdscr, wstr, n);
|
||||
}
|
||||
|
||||
int mvwins_nwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n)
|
||||
{
|
||||
PDC_LOG(("mvwinsnstr() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return wins_nwstr(win, wstr, n);
|
||||
}
|
||||
#endif
|
||||
245
pdcurses/instr.c
Normal file
245
pdcurses/instr.c
Normal file
@@ -0,0 +1,245 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
instr
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int instr(char *str);
|
||||
int innstr(char *str, int n);
|
||||
int winstr(WINDOW *win, char *str);
|
||||
int winnstr(WINDOW *win, char *str, int n);
|
||||
int mvinstr(int y, int x, char *str);
|
||||
int mvinnstr(int y, int x, char *str, int n);
|
||||
int mvwinstr(WINDOW *win, int y, int x, char *str);
|
||||
int mvwinnstr(WINDOW *win, int y, int x, char *str, int n);
|
||||
|
||||
int inwstr(wchar_t *wstr);
|
||||
int innwstr(wchar_t *wstr, int n);
|
||||
int winwstr(WINDOW *win, wchar_t *wstr);
|
||||
int winnwstr(WINDOW *win, wchar_t *wstr, int n);
|
||||
int mvinwstr(int y, int x, wchar_t *wstr);
|
||||
int mvinnwstr(int y, int x, wchar_t *wstr, int n);
|
||||
int mvwinwstr(WINDOW *win, int y, int x, wchar_t *wstr);
|
||||
int mvwinnwstr(WINDOW *win, int y, int x, wchar_t *wstr, int n);
|
||||
|
||||
### Description
|
||||
|
||||
These functions take characters (or wide characters) from the current
|
||||
or specified position in the window, and return them as a string in
|
||||
str (or wstr). Attributes are ignored. The functions with n as the
|
||||
last argument return a string at most n characters long.
|
||||
|
||||
### Return Value
|
||||
|
||||
Upon successful completion, innstr(), mvinnstr(), mvwinnstr() and
|
||||
winnstr() return the number of characters actually read into the
|
||||
string; instr(), mvinstr(), mvwinstr() and winstr() return OK.
|
||||
Otherwise, all these functions return ERR.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
instr Y Y Y
|
||||
winstr Y Y Y
|
||||
mvinstr Y Y Y
|
||||
mvwinstr Y Y Y
|
||||
innstr Y Y Y
|
||||
winnstr Y Y Y
|
||||
mvinnstr Y Y Y
|
||||
mvwinnstr Y Y Y
|
||||
inwstr Y Y Y
|
||||
winwstr Y Y Y
|
||||
mvinwstr Y Y Y
|
||||
mvwinwstr Y Y Y
|
||||
innwstr Y Y Y
|
||||
winnwstr Y Y Y
|
||||
mvinnwstr Y Y Y
|
||||
mvwinnwstr Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int winnstr(WINDOW *win, char *str, int n)
|
||||
{
|
||||
#ifdef PDC_WIDE
|
||||
wchar_t wstr[513];
|
||||
|
||||
if (n < 0 || n > 512)
|
||||
n = 512;
|
||||
|
||||
if (winnwstr(win, wstr, n) == ERR)
|
||||
return ERR;
|
||||
|
||||
return PDC_wcstombs(str, wstr, n);
|
||||
#else
|
||||
chtype *src;
|
||||
int i;
|
||||
|
||||
PDC_LOG(("winnstr() - called: n %d \n", n));
|
||||
|
||||
if (!win || !str)
|
||||
return ERR;
|
||||
|
||||
if (n < 0 || (win->_curx + n) > win->_maxx)
|
||||
n = win->_maxx - win->_curx;
|
||||
|
||||
src = win->_y[win->_cury] + win->_curx;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
str[i] = src[i] & A_CHARTEXT;
|
||||
|
||||
str[i] = '\0';
|
||||
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
|
||||
int instr(char *str)
|
||||
{
|
||||
PDC_LOG(("instr() - called: string=\"%s\"\n", str));
|
||||
|
||||
return (ERR == winnstr(stdscr, str, stdscr->_maxx)) ? ERR : OK;
|
||||
}
|
||||
|
||||
int winstr(WINDOW *win, char *str)
|
||||
{
|
||||
PDC_LOG(("winstr() - called: \n"));
|
||||
|
||||
return (ERR == winnstr(win, str, win->_maxx)) ? ERR : OK;
|
||||
}
|
||||
|
||||
int mvinstr(int y, int x, char *str)
|
||||
{
|
||||
PDC_LOG(("mvinstr() - called: y %d x %d \n", y, x));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return (ERR == winnstr(stdscr, str, stdscr->_maxx)) ? ERR : OK;
|
||||
}
|
||||
|
||||
int mvwinstr(WINDOW *win, int y, int x, char *str)
|
||||
{
|
||||
PDC_LOG(("mvwinstr() - called: y %d x %d \n", y, x));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return (ERR == winnstr(win, str, win->_maxx)) ? ERR : OK;
|
||||
}
|
||||
|
||||
int innstr(char *str, int n)
|
||||
{
|
||||
PDC_LOG(("innstr() - called: n %d \n", n));
|
||||
|
||||
return winnstr(stdscr, str, n);
|
||||
}
|
||||
|
||||
int mvinnstr(int y, int x, char *str, int n)
|
||||
{
|
||||
PDC_LOG(("mvinnstr() - called: y %d x %d n %d \n", y, x, n));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winnstr(stdscr, str, n);
|
||||
}
|
||||
|
||||
int mvwinnstr(WINDOW *win, int y, int x, char *str, int n)
|
||||
{
|
||||
PDC_LOG(("mvwinnstr() - called: y %d x %d n %d \n", y, x, n));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winnstr(win, str, n);
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int winnwstr(WINDOW *win, wchar_t *wstr, int n)
|
||||
{
|
||||
chtype *src;
|
||||
int i;
|
||||
|
||||
PDC_LOG(("winnstr() - called: n %d \n", n));
|
||||
|
||||
if (!win || !wstr)
|
||||
return ERR;
|
||||
|
||||
if (n < 0 || (win->_curx + n) > win->_maxx)
|
||||
n = win->_maxx - win->_curx;
|
||||
|
||||
src = win->_y[win->_cury] + win->_curx;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
wstr[i] = src[i] & A_CHARTEXT;
|
||||
|
||||
wstr[i] = L'\0';
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int inwstr(wchar_t *wstr)
|
||||
{
|
||||
PDC_LOG(("inwstr() - called\n"));
|
||||
|
||||
return (ERR == winnwstr(stdscr, wstr, stdscr->_maxx)) ? ERR : OK;
|
||||
}
|
||||
|
||||
int winwstr(WINDOW *win, wchar_t *wstr)
|
||||
{
|
||||
PDC_LOG(("winwstr() - called\n"));
|
||||
|
||||
return (ERR == winnwstr(win, wstr, win->_maxx)) ? ERR : OK;
|
||||
}
|
||||
|
||||
int mvinwstr(int y, int x, wchar_t *wstr)
|
||||
{
|
||||
PDC_LOG(("mvinwstr() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return (ERR == winnwstr(stdscr, wstr, stdscr->_maxx)) ? ERR : OK;
|
||||
}
|
||||
|
||||
int mvwinwstr(WINDOW *win, int y, int x, wchar_t *wstr)
|
||||
{
|
||||
PDC_LOG(("mvwinstr() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return (ERR == winnwstr(win, wstr, win->_maxx)) ? ERR : OK;
|
||||
}
|
||||
|
||||
int innwstr(wchar_t *wstr, int n)
|
||||
{
|
||||
PDC_LOG(("innwstr() - called\n"));
|
||||
|
||||
return winnwstr(stdscr, wstr, n);
|
||||
}
|
||||
|
||||
int mvinnwstr(int y, int x, wchar_t *wstr, int n)
|
||||
{
|
||||
PDC_LOG(("mvinnstr() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winnwstr(stdscr, wstr, n);
|
||||
}
|
||||
|
||||
int mvwinnwstr(WINDOW *win, int y, int x, wchar_t *wstr, int n)
|
||||
{
|
||||
PDC_LOG(("mvwinnwstr() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
return winnwstr(win, wstr, n);
|
||||
}
|
||||
#endif
|
||||
297
pdcurses/kernel.c
Normal file
297
pdcurses/kernel.c
Normal file
@@ -0,0 +1,297 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
kernel
|
||||
------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int def_prog_mode(void);
|
||||
int def_shell_mode(void);
|
||||
int reset_prog_mode(void);
|
||||
int reset_shell_mode(void);
|
||||
int resetty(void);
|
||||
int savetty(void);
|
||||
int ripoffline(int line, int (*init)(WINDOW *, int));
|
||||
int curs_set(int visibility);
|
||||
int napms(int ms);
|
||||
|
||||
int draino(int ms);
|
||||
int resetterm(void);
|
||||
int fixterm(void);
|
||||
int saveterm(void);
|
||||
|
||||
### Description
|
||||
|
||||
def_prog_mode() and def_shell_mode() save the current terminal modes
|
||||
as the "program" (in curses) or "shell" (not in curses) state for use
|
||||
by the reset_prog_mode() and reset_shell_mode() functions. This is
|
||||
done automatically by initscr().
|
||||
|
||||
reset_prog_mode() and reset_shell_mode() restore the terminal to
|
||||
"program" (in curses) or "shell" (not in curses) state. These are
|
||||
done automatically by endwin() and doupdate() after an endwin(), so
|
||||
they would normally not be called before these functions.
|
||||
|
||||
savetty() and resetty() save and restore the state of the terminal
|
||||
modes. savetty() saves the current state in a buffer, and resetty()
|
||||
restores the state to what it was at the last call to savetty().
|
||||
|
||||
curs_set() alters the appearance of the cursor. A visibility of 0
|
||||
makes it disappear; 1 makes it appear "normal" (usually an underline)
|
||||
and 2 makes it "highly visible" (usually a block).
|
||||
|
||||
ripoffline() reduces the size of stdscr by one line. If the "line"
|
||||
parameter is positive, the line is removed from the top of the
|
||||
screen; if negative, from the bottom. Up to 5 lines can be ripped off
|
||||
stdscr by calling ripoffline() repeatedly. The function argument,
|
||||
init, is called from within initscr() or newterm(), so ripoffline()
|
||||
must be called before either of these functions. The init function
|
||||
receives a pointer to a one-line WINDOW, and the width of the window.
|
||||
Calling ripoffline() with a NULL init function pointer is an error.
|
||||
|
||||
napms() suspends the program for the specified number of
|
||||
milliseconds. draino() is an archaic equivalent. Note that since
|
||||
napms() attempts to give up a time slice and yield control back to
|
||||
the OS, all times are approximate. (In DOS, the delay is actually
|
||||
rounded down to 50ms (1/20th sec) intervals, with a minimum of one
|
||||
interval; i.e., 1-99 will wait 50ms, 100-149 will wait 100ms, etc.)
|
||||
0 returns immediately.
|
||||
|
||||
resetterm(), fixterm() and saveterm() are archaic equivalents for
|
||||
reset_shell_mode(), reset_prog_mode() and def_prog_mode(),
|
||||
respectively.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error, except
|
||||
curs_set(), which returns the previous visibility.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
def_prog_mode Y Y Y
|
||||
def_shell_mode Y Y Y
|
||||
reset_prog_mode Y Y Y
|
||||
reset_shell_mode Y Y Y
|
||||
resetty Y Y Y
|
||||
savetty Y Y Y
|
||||
ripoffline Y Y Y
|
||||
curs_set Y Y Y
|
||||
napms Y Y Y
|
||||
fixterm - Y -
|
||||
resetterm - Y -
|
||||
saveterm - Y -
|
||||
draino - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
RIPPEDOFFLINE linesripped[5];
|
||||
char linesrippedoff = 0;
|
||||
|
||||
static struct cttyset
|
||||
{
|
||||
bool been_set;
|
||||
SCREEN saved;
|
||||
} ctty[3];
|
||||
|
||||
enum { PDC_SH_TTY, PDC_PR_TTY, PDC_SAVE_TTY };
|
||||
|
||||
static void _save_mode(int i)
|
||||
{
|
||||
ctty[i].been_set = TRUE;
|
||||
|
||||
memcpy(&(ctty[i].saved), SP, sizeof(SCREEN));
|
||||
|
||||
PDC_save_screen_mode(i);
|
||||
}
|
||||
|
||||
static int _restore_mode(int i)
|
||||
{
|
||||
if (ctty[i].been_set == TRUE)
|
||||
{
|
||||
memcpy(SP, &(ctty[i].saved), sizeof(SCREEN));
|
||||
|
||||
if (ctty[i].saved.raw_out)
|
||||
raw();
|
||||
|
||||
PDC_restore_screen_mode(i);
|
||||
|
||||
if ((LINES != ctty[i].saved.lines) ||
|
||||
(COLS != ctty[i].saved.cols))
|
||||
resize_term(ctty[i].saved.lines, ctty[i].saved.cols);
|
||||
|
||||
PDC_curs_set(ctty[i].saved.visibility);
|
||||
|
||||
PDC_gotoyx(ctty[i].saved.cursrow, ctty[i].saved.curscol);
|
||||
}
|
||||
|
||||
return ctty[i].been_set ? OK : ERR;
|
||||
}
|
||||
|
||||
int def_prog_mode(void)
|
||||
{
|
||||
PDC_LOG(("def_prog_mode() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
_save_mode(PDC_PR_TTY);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int def_shell_mode(void)
|
||||
{
|
||||
PDC_LOG(("def_shell_mode() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
_save_mode(PDC_SH_TTY);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int reset_prog_mode(void)
|
||||
{
|
||||
PDC_LOG(("reset_prog_mode() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
_restore_mode(PDC_PR_TTY);
|
||||
PDC_reset_prog_mode();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int reset_shell_mode(void)
|
||||
{
|
||||
PDC_LOG(("reset_shell_mode() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
_restore_mode(PDC_SH_TTY);
|
||||
PDC_reset_shell_mode();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int resetty(void)
|
||||
{
|
||||
PDC_LOG(("resetty() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
return _restore_mode(PDC_SAVE_TTY);
|
||||
}
|
||||
|
||||
int savetty(void)
|
||||
{
|
||||
PDC_LOG(("savetty() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
_save_mode(PDC_SAVE_TTY);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int curs_set(int visibility)
|
||||
{
|
||||
int ret_vis;
|
||||
|
||||
PDC_LOG(("curs_set() - called: visibility=%d\n", visibility));
|
||||
|
||||
if (!SP || visibility < 0 || visibility > 2)
|
||||
return ERR;
|
||||
|
||||
ret_vis = PDC_curs_set(visibility);
|
||||
|
||||
/* If the cursor is changing from invisible to visible, update
|
||||
its position */
|
||||
|
||||
if (visibility && !ret_vis)
|
||||
PDC_gotoyx(SP->cursrow, SP->curscol);
|
||||
|
||||
return ret_vis;
|
||||
}
|
||||
|
||||
int napms(int ms)
|
||||
{
|
||||
PDC_LOG(("napms() - called: ms=%d\n", ms));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
if (SP->dirty)
|
||||
{
|
||||
int curs_state = SP->visibility;
|
||||
bool leave_state = is_leaveok(curscr);
|
||||
|
||||
SP->dirty = FALSE;
|
||||
|
||||
leaveok(curscr, TRUE);
|
||||
|
||||
wrefresh(curscr);
|
||||
|
||||
leaveok(curscr, leave_state);
|
||||
curs_set(curs_state);
|
||||
}
|
||||
|
||||
if (ms)
|
||||
PDC_napms(ms);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int ripoffline(int line, int (*init)(WINDOW *, int))
|
||||
{
|
||||
PDC_LOG(("ripoffline() - called: line=%d\n", line));
|
||||
|
||||
if (linesrippedoff < 5 && line && init)
|
||||
{
|
||||
linesripped[(int)linesrippedoff].line = line;
|
||||
linesripped[(int)linesrippedoff++].init = init;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
return ERR;
|
||||
}
|
||||
|
||||
int draino(int ms)
|
||||
{
|
||||
PDC_LOG(("draino() - called\n"));
|
||||
|
||||
return napms(ms);
|
||||
}
|
||||
|
||||
int resetterm(void)
|
||||
{
|
||||
PDC_LOG(("resetterm() - called\n"));
|
||||
|
||||
return reset_shell_mode();
|
||||
}
|
||||
|
||||
int fixterm(void)
|
||||
{
|
||||
PDC_LOG(("fixterm() - called\n"));
|
||||
|
||||
return reset_prog_mode();
|
||||
}
|
||||
|
||||
int saveterm(void)
|
||||
{
|
||||
PDC_LOG(("saveterm() - called\n"));
|
||||
|
||||
return def_prog_mode();
|
||||
}
|
||||
129
pdcurses/keyname.c
Normal file
129
pdcurses/keyname.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
keyname
|
||||
-------
|
||||
|
||||
### Synopsis
|
||||
|
||||
char *keyname(int key);
|
||||
|
||||
char *key_name(wchar_t c);
|
||||
|
||||
bool has_key(int key);
|
||||
|
||||
### Description
|
||||
|
||||
keyname() returns a string corresponding to the argument key. key may
|
||||
be any key returned by wgetch().
|
||||
|
||||
key_name() is the wide-character version. It takes a wchar_t
|
||||
parameter, but still returns a char *.
|
||||
|
||||
has_key() returns TRUE for recognized keys, FALSE otherwise. This
|
||||
function is an ncurses extension.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
keyname Y Y Y
|
||||
key_name Y Y Y
|
||||
has_key - Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static const char *names[] =
|
||||
{
|
||||
"KEY_BREAK", "KEY_DOWN", "KEY_UP", "KEY_LEFT", "KEY_RIGHT",
|
||||
"KEY_HOME", "KEY_BACKSPACE", "KEY_F0", "KEY_F(1)", "KEY_F(2)",
|
||||
"KEY_F(3)", "KEY_F(4)", "KEY_F(5)", "KEY_F(6)", "KEY_F(7)",
|
||||
"KEY_F(8)", "KEY_F(9)", "KEY_F(10)", "KEY_F(11)", "KEY_F(12)",
|
||||
"KEY_F(13)", "KEY_F(14)", "KEY_F(15)", "KEY_F(16)", "KEY_F(17)",
|
||||
"KEY_F(18)", "KEY_F(19)", "KEY_F(20)", "KEY_F(21)", "KEY_F(22)",
|
||||
"KEY_F(23)", "KEY_F(24)", "KEY_F(25)", "KEY_F(26)", "KEY_F(27)",
|
||||
"KEY_F(28)", "KEY_F(29)", "KEY_F(30)", "KEY_F(31)", "KEY_F(32)",
|
||||
"KEY_F(33)", "KEY_F(34)", "KEY_F(35)", "KEY_F(36)", "KEY_F(37)",
|
||||
"KEY_F(38)", "KEY_F(39)", "KEY_F(40)", "KEY_F(41)", "KEY_F(42)",
|
||||
"KEY_F(43)", "KEY_F(44)", "KEY_F(45)", "KEY_F(46)", "KEY_F(47)",
|
||||
"KEY_F(48)", "KEY_F(49)", "KEY_F(50)", "KEY_F(51)", "KEY_F(52)",
|
||||
"KEY_F(53)", "KEY_F(54)", "KEY_F(55)", "KEY_F(56)", "KEY_F(57)",
|
||||
"KEY_F(58)", "KEY_F(59)", "KEY_F(60)", "KEY_F(61)", "KEY_F(62)",
|
||||
"KEY_F(63)", "KEY_DL", "KEY_IL", "KEY_DC", "KEY_IC", "KEY_EIC",
|
||||
"KEY_CLEAR", "KEY_EOS", "KEY_EOL", "KEY_SF", "KEY_SR", "KEY_NPAGE",
|
||||
"KEY_PPAGE", "KEY_STAB", "KEY_CTAB", "KEY_CATAB", "KEY_ENTER",
|
||||
"KEY_SRESET", "KEY_RESET", "KEY_PRINT", "KEY_LL", "KEY_ABORT",
|
||||
"KEY_SHELP", "KEY_LHELP", "KEY_BTAB", "KEY_BEG", "KEY_CANCEL",
|
||||
"KEY_CLOSE", "KEY_COMMAND", "KEY_COPY", "KEY_CREATE", "KEY_END",
|
||||
"KEY_EXIT", "KEY_FIND", "KEY_HELP", "KEY_MARK", "KEY_MESSAGE",
|
||||
"KEY_MOVE", "KEY_NEXT", "KEY_OPEN", "KEY_OPTIONS", "KEY_PREVIOUS",
|
||||
"KEY_REDO", "KEY_REFERENCE", "KEY_REFRESH", "KEY_REPLACE",
|
||||
"KEY_RESTART", "KEY_RESUME", "KEY_SAVE", "KEY_SBEG", "KEY_SCANCEL",
|
||||
"KEY_SCOMMAND", "KEY_SCOPY", "KEY_SCREATE", "KEY_SDC", "KEY_SDL",
|
||||
"KEY_SELECT", "KEY_SEND", "KEY_SEOL", "KEY_SEXIT", "KEY_SFIND",
|
||||
"KEY_SHOME", "KEY_SIC", "UNKNOWN KEY", "KEY_SLEFT", "KEY_SMESSAGE",
|
||||
"KEY_SMOVE", "KEY_SNEXT", "KEY_SOPTIONS", "KEY_SPREVIOUS",
|
||||
"KEY_SPRINT", "KEY_SREDO", "KEY_SREPLACE", "KEY_SRIGHT",
|
||||
"KEY_SRSUME", "KEY_SSAVE", "KEY_SSUSPEND", "KEY_SUNDO",
|
||||
"KEY_SUSPEND", "KEY_UNDO", "ALT_0", "ALT_1", "ALT_2", "ALT_3",
|
||||
"ALT_4", "ALT_5", "ALT_6", "ALT_7", "ALT_8", "ALT_9", "ALT_A",
|
||||
"ALT_B", "ALT_C", "ALT_D", "ALT_E", "ALT_F", "ALT_G", "ALT_H",
|
||||
"ALT_I", "ALT_J", "ALT_K", "ALT_L", "ALT_M", "ALT_N", "ALT_O",
|
||||
"ALT_P", "ALT_Q", "ALT_R", "ALT_S", "ALT_T", "ALT_U", "ALT_V",
|
||||
"ALT_W", "ALT_X", "ALT_Y", "ALT_Z", "CTL_LEFT", "CTL_RIGHT",
|
||||
"CTL_PGUP", "CTL_PGDN", "CTL_HOME", "CTL_END", "KEY_A1", "KEY_A2",
|
||||
"KEY_A3", "KEY_B1", "KEY_B2", "KEY_B3", "KEY_C1", "KEY_C2",
|
||||
"KEY_C3", "PADSLASH", "PADENTER", "CTL_PADENTER", "ALT_PADENTER",
|
||||
"PADSTOP", "PADSTAR", "PADMINUS", "PADPLUS", "CTL_PADSTOP",
|
||||
"CTL_PADCENTER", "CTL_PADPLUS", "CTL_PADMINUS", "CTL_PADSLASH",
|
||||
"CTL_PADSTAR", "ALT_PADPLUS", "ALT_PADMINUS", "ALT_PADSLASH",
|
||||
"ALT_PADSTAR", "ALT_PADSTOP", "CTL_INS", "ALT_DEL", "ALT_INS",
|
||||
"CTL_UP", "CTL_DOWN", "CTL_TAB", "ALT_TAB", "ALT_MINUS",
|
||||
"ALT_EQUAL", "ALT_HOME", "ALT_PGUP", "ALT_PGDN", "ALT_END",
|
||||
"ALT_UP", "ALT_DOWN", "ALT_RIGHT", "ALT_LEFT", "ALT_ENTER",
|
||||
"ALT_ESC", "ALT_BQUOTE", "ALT_LBRACKET", "ALT_RBRACKET",
|
||||
"ALT_SEMICOLON", "ALT_FQUOTE", "ALT_COMMA", "ALT_STOP",
|
||||
"ALT_FSLASH", "ALT_BKSP", "CTL_BKSP", "PAD0", "CTL_PAD0",
|
||||
"CTL_PAD1", "CTL_PAD2", "CTL_PAD3", "CTL_PAD4", "CTL_PAD5",
|
||||
"CTL_PAD6", "CTL_PAD7","CTL_PAD8", "CTL_PAD9", "ALT_PAD0",
|
||||
"ALT_PAD1", "ALT_PAD2", "ALT_PAD3", "ALT_PAD4", "ALT_PAD5",
|
||||
"ALT_PAD6", "ALT_PAD7", "ALT_PAD8", "ALT_PAD9", "CTL_DEL",
|
||||
"ALT_BSLASH", "CTL_ENTER", "SHF_PADENTER", "SHF_PADSLASH",
|
||||
"SHF_PADSTAR", "SHF_PADPLUS", "SHF_PADMINUS", "SHF_UP", "SHF_DOWN",
|
||||
"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"
|
||||
};
|
||||
|
||||
char *keyname(int key)
|
||||
{
|
||||
static char _keyname[14];
|
||||
|
||||
/* Key names must be in exactly the same order as in curses.h */
|
||||
|
||||
PDC_LOG(("keyname() - called: key %d\n", key));
|
||||
|
||||
strcpy(_keyname, ((key >= 0) && (key < 0x80)) ? unctrl((chtype)key) :
|
||||
has_key(key) ? names[key - KEY_MIN] : "UNKNOWN KEY");
|
||||
|
||||
return _keyname;
|
||||
}
|
||||
|
||||
bool has_key(int key)
|
||||
{
|
||||
PDC_LOG(("has_key() - called: key %d\n", key));
|
||||
|
||||
return (key >= KEY_MIN && key <= KEY_MAX);
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
char *key_name(wchar_t c)
|
||||
{
|
||||
PDC_LOG(("key_name() - called\n"));
|
||||
|
||||
return keyname((int)c);
|
||||
}
|
||||
#endif
|
||||
421
pdcurses/mouse.c
Normal file
421
pdcurses/mouse.c
Normal file
@@ -0,0 +1,421 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
mouse
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int mouse_set(mmask_t mbe);
|
||||
int mouse_on(mmask_t mbe);
|
||||
int mouse_off(mmask_t mbe);
|
||||
int request_mouse_pos(void);
|
||||
void wmouse_position(WINDOW *win, int *y, int *x);
|
||||
mmask_t getmouse(void);
|
||||
|
||||
int mouseinterval(int wait);
|
||||
bool wenclose(const WINDOW *win, int y, int x);
|
||||
bool wmouse_trafo(const WINDOW *win, int *y, int *x, bool to_screen);
|
||||
bool mouse_trafo(int *y, int *x, bool to_screen);
|
||||
mmask_t mousemask(mmask_t mask, mmask_t *oldmask);
|
||||
int nc_getmouse(MEVENT *event);
|
||||
int ungetmouse(MEVENT *event);
|
||||
bool has_mouse(void);
|
||||
|
||||
### Description
|
||||
|
||||
As of PDCurses 3.0, there are two separate mouse interfaces: the
|
||||
classic interface, which is based on the undocumented Sys V mouse
|
||||
functions; and an ncurses-compatible interface. Both are active at
|
||||
all times, and you can mix and match functions from each, though it's
|
||||
not recommended. The ncurses interface is essentially an emulation
|
||||
layer built on top of the classic interface; it's here to allow
|
||||
easier porting of ncurses apps.
|
||||
|
||||
The classic interface: mouse_set(), mouse_on(), mouse_off(),
|
||||
request_mouse_pos(), wmouse_position(), and getmouse(). An
|
||||
application using this interface would start by calling mouse_set()
|
||||
or mouse_on() with a non-zero value, often ALL_MOUSE_EVENTS. Then it
|
||||
would check for a KEY_MOUSE return from getch(). If found, it would
|
||||
call request_mouse_pos() to get the current mouse status.
|
||||
|
||||
mouse_set(), mouse_on() and mouse_off() are analagous to attrset(),
|
||||
attron() and attroff(). These functions set the mouse button events
|
||||
to trap. The button masks used in these functions are defined in
|
||||
curses.h and can be or'ed together. They are the group of masks
|
||||
starting with BUTTON1_RELEASED.
|
||||
|
||||
request_mouse_pos() requests curses to fill in the Mouse_status
|
||||
structure with the current state of the mouse.
|
||||
|
||||
wmouse_position() determines if the current mouse position is within
|
||||
the window passed as an argument. If the mouse is outside the current
|
||||
window, -1 is returned in the y and x arguments; otherwise the y and
|
||||
x coordinates of the mouse (relative to the top left corner of the
|
||||
window) are returned in y and x.
|
||||
|
||||
getmouse() returns the current status of the trapped mouse buttons as
|
||||
set by mouse_set() or mouse_on().
|
||||
|
||||
The ncurses interface: mouseinterval(), wenclose(), wmouse_trafo(),
|
||||
mouse_trafo(), mousemask(), nc_getmouse(), ungetmouse() and
|
||||
has_mouse(). A typical application using this interface would start
|
||||
by calling mousemask() with a non-zero value, often ALL_MOUSE_EVENTS.
|
||||
Then it would check for a KEY_MOUSE return from getch(). If found, it
|
||||
would call nc_getmouse() to get the current mouse status.
|
||||
|
||||
mouseinterval() sets the timeout for a mouse click. On all current
|
||||
platforms, PDCurses receives mouse button press and release events,
|
||||
but must synthesize click events. It does this by checking whether a
|
||||
release event is queued up after a press event. If it gets a press
|
||||
event, and there are no more events waiting, it will wait for the
|
||||
timeout interval, then check again for a release. A press followed by
|
||||
a release is reported as BUTTON_CLICKED; otherwise it's passed
|
||||
through as BUTTON_PRESSED. The default timeout is 150ms; valid values
|
||||
are 0 (no clicks reported) through 1000ms. In x11, the timeout can
|
||||
also be set via the clickPeriod resource. The return value from
|
||||
mouseinterval() is the old timeout. To check the old value without
|
||||
setting a new one, call it with a parameter of -1. Note that although
|
||||
there's no classic equivalent for this function (apart from the
|
||||
clickPeriod resource), the value set applies in both interfaces.
|
||||
|
||||
wenclose() reports whether the given screen-relative y, x coordinates
|
||||
fall within the given window.
|
||||
|
||||
wmouse_trafo() converts between screen-relative and window-relative
|
||||
coordinates. A to_screen parameter of TRUE means to convert from
|
||||
window to screen; otherwise the reverse. The function returns FALSE
|
||||
if the coordinates aren't within the window, or if any of the
|
||||
parameters are NULL. The coordinates have been converted when the
|
||||
function returns TRUE.
|
||||
|
||||
mouse_trafo() is the stdscr version of wmouse_trafo().
|
||||
|
||||
mousemask() is nearly equivalent to mouse_set(), but instead of
|
||||
OK/ERR, it returns the value of the mask after setting it. (This
|
||||
isn't necessarily the same value passed in, since the mask could be
|
||||
altered on some platforms.) And if the second parameter is a non-null
|
||||
pointer, mousemask() stores the previous mask value there. Also,
|
||||
since the ncurses interface doesn't work with PDCurses' BUTTON_MOVED
|
||||
events, mousemask() filters them out.
|
||||
|
||||
nc_getmouse() returns the current mouse status in an MEVENT struct.
|
||||
This is equivalent to ncurses' getmouse(), renamed to avoid conflict
|
||||
with PDCurses' getmouse(). But if you define PDC_NCMOUSE before
|
||||
including curses.h, it defines getmouse() to nc_getmouse(), along
|
||||
with a few other redefintions needed for compatibility with ncurses
|
||||
code. nc_getmouse() calls request_mouse_pos(), which (not getmouse())
|
||||
is the classic equivalent.
|
||||
|
||||
ungetmouse() is the mouse equivalent of ungetch(). However, PDCurses
|
||||
doesn't maintain a queue of mouse events; only one can be pushed
|
||||
back, and it can overwrite or be overwritten by real mouse events.
|
||||
|
||||
has_mouse() reports whether the mouse is available at all on the
|
||||
current platform.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
mouse_set - - -
|
||||
mouse_on - - -
|
||||
mouse_off - - -
|
||||
request_mouse_pos - - -
|
||||
wmouse_position - - -
|
||||
getmouse - * -
|
||||
mouseinterval - Y -
|
||||
wenclose - Y -
|
||||
wmouse_trafo - Y -
|
||||
mouse_trafo - Y -
|
||||
mousemask - Y -
|
||||
nc_getmouse - * -
|
||||
ungetmouse - Y -
|
||||
has_mouse - Y -
|
||||
|
||||
* See above, under Description
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static bool ungot = FALSE;
|
||||
|
||||
int mouse_set(mmask_t mbe)
|
||||
{
|
||||
PDC_LOG(("mouse_set() - called: event %x\n", mbe));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
SP->_trap_mbe = mbe;
|
||||
return PDC_mouse_set();
|
||||
}
|
||||
|
||||
int mouse_on(mmask_t mbe)
|
||||
{
|
||||
PDC_LOG(("mouse_on() - called: event %x\n", mbe));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
SP->_trap_mbe |= mbe;
|
||||
return PDC_mouse_set();
|
||||
}
|
||||
|
||||
int mouse_off(mmask_t mbe)
|
||||
{
|
||||
PDC_LOG(("mouse_off() - called: event %x\n", mbe));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
SP->_trap_mbe &= ~mbe;
|
||||
return PDC_mouse_set();
|
||||
}
|
||||
|
||||
int request_mouse_pos(void)
|
||||
{
|
||||
PDC_LOG(("request_mouse_pos() - called\n"));
|
||||
|
||||
Mouse_status = SP->mouse_status;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void wmouse_position(WINDOW *win, int *y, int *x)
|
||||
{
|
||||
PDC_LOG(("wmouse_position() - called\n"));
|
||||
|
||||
if (win && wenclose(win, MOUSE_Y_POS, MOUSE_X_POS))
|
||||
{
|
||||
if (y)
|
||||
*y = MOUSE_Y_POS - win->_begy;
|
||||
if (x)
|
||||
*x = MOUSE_X_POS - win->_begx;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y)
|
||||
*y = -1;
|
||||
if (x)
|
||||
*x = -1;
|
||||
}
|
||||
}
|
||||
|
||||
mmask_t getmouse(void)
|
||||
{
|
||||
PDC_LOG(("getmouse() - called\n"));
|
||||
|
||||
return SP ? SP->_trap_mbe : (mmask_t)0;
|
||||
}
|
||||
|
||||
/* ncurses mouse interface */
|
||||
|
||||
int mouseinterval(int wait)
|
||||
{
|
||||
int old_wait;
|
||||
|
||||
PDC_LOG(("mouseinterval() - called: %d\n", wait));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
old_wait = SP->mouse_wait;
|
||||
|
||||
if (wait >= 0 && wait <= 1000)
|
||||
SP->mouse_wait = wait;
|
||||
|
||||
return old_wait;
|
||||
}
|
||||
|
||||
bool wenclose(const WINDOW *win, int y, int x)
|
||||
{
|
||||
PDC_LOG(("wenclose() - called: %p %d %d\n", win, y, x));
|
||||
|
||||
return (win && y >= win->_begy && y < win->_begy + win->_maxy
|
||||
&& x >= win->_begx && x < win->_begx + win->_maxx);
|
||||
}
|
||||
|
||||
bool wmouse_trafo(const WINDOW *win, int *y, int *x, bool to_screen)
|
||||
{
|
||||
int newy, newx;
|
||||
|
||||
PDC_LOG(("wmouse_trafo() - called\n"));
|
||||
|
||||
if (!win || !y || !x)
|
||||
return FALSE;
|
||||
|
||||
newy = *y;
|
||||
newx = *x;
|
||||
|
||||
if (to_screen)
|
||||
{
|
||||
newy += win->_begy;
|
||||
newx += win->_begx;
|
||||
|
||||
if (!wenclose(win, newy, newx))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wenclose(win, newy, newx))
|
||||
{
|
||||
newy -= win->_begy;
|
||||
newx -= win->_begx;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*y = newy;
|
||||
*x = newx;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool mouse_trafo(int *y, int *x, bool to_screen)
|
||||
{
|
||||
PDC_LOG(("mouse_trafo() - called\n"));
|
||||
|
||||
return wmouse_trafo(stdscr, y, x, to_screen);
|
||||
}
|
||||
|
||||
mmask_t mousemask(mmask_t mask, mmask_t *oldmask)
|
||||
{
|
||||
PDC_LOG(("mousemask() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return (mmask_t)0;
|
||||
|
||||
if (oldmask)
|
||||
*oldmask = SP->_trap_mbe;
|
||||
|
||||
/* The ncurses interface doesn't work with our move events, so
|
||||
filter them here */
|
||||
|
||||
mask &= ~(BUTTON1_MOVED | BUTTON2_MOVED | BUTTON3_MOVED);
|
||||
|
||||
mouse_set(mask);
|
||||
|
||||
return SP->_trap_mbe;
|
||||
}
|
||||
|
||||
int nc_getmouse(MEVENT *event)
|
||||
{
|
||||
int i;
|
||||
mmask_t bstate = 0;
|
||||
|
||||
PDC_LOG(("nc_getmouse() - called\n"));
|
||||
|
||||
if (!event || !SP)
|
||||
return ERR;
|
||||
|
||||
ungot = FALSE;
|
||||
|
||||
request_mouse_pos();
|
||||
|
||||
event->id = 0;
|
||||
|
||||
event->x = Mouse_status.x;
|
||||
event->y = Mouse_status.y;
|
||||
event->z = 0;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (Mouse_status.changes & (1 << i))
|
||||
{
|
||||
int shf = i * 5;
|
||||
short button = Mouse_status.button[i] & BUTTON_ACTION_MASK;
|
||||
|
||||
if (button == BUTTON_RELEASED)
|
||||
bstate |= (BUTTON1_RELEASED << shf);
|
||||
else if (button == BUTTON_PRESSED)
|
||||
bstate |= (BUTTON1_PRESSED << shf);
|
||||
else if (button == BUTTON_CLICKED)
|
||||
bstate |= (BUTTON1_CLICKED << shf);
|
||||
else if (button == BUTTON_DOUBLE_CLICKED)
|
||||
bstate |= (BUTTON1_DOUBLE_CLICKED << shf);
|
||||
|
||||
button = Mouse_status.button[i] & BUTTON_MODIFIER_MASK;
|
||||
|
||||
if (button & PDC_BUTTON_SHIFT)
|
||||
bstate |= BUTTON_MODIFIER_SHIFT;
|
||||
if (button & PDC_BUTTON_CONTROL)
|
||||
bstate |= BUTTON_MODIFIER_CONTROL;
|
||||
if (button & PDC_BUTTON_ALT)
|
||||
bstate |= BUTTON_MODIFIER_ALT;
|
||||
}
|
||||
}
|
||||
|
||||
if (MOUSE_WHEEL_UP)
|
||||
bstate |= BUTTON4_PRESSED;
|
||||
else if (MOUSE_WHEEL_DOWN)
|
||||
bstate |= BUTTON5_PRESSED;
|
||||
|
||||
/* extra filter pass -- mainly for button modifiers */
|
||||
|
||||
event->bstate = bstate & SP->_trap_mbe;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int ungetmouse(MEVENT *event)
|
||||
{
|
||||
int i;
|
||||
mmask_t bstate;
|
||||
|
||||
PDC_LOG(("ungetmouse() - called\n"));
|
||||
|
||||
if (!event || ungot)
|
||||
return ERR;
|
||||
|
||||
ungot = TRUE;
|
||||
|
||||
SP->mouse_status.x = event->x;
|
||||
SP->mouse_status.y = event->y;
|
||||
|
||||
SP->mouse_status.changes = 0;
|
||||
bstate = event->bstate;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
int shf = i * 5;
|
||||
short button = 0;
|
||||
|
||||
if (bstate & ((BUTTON1_RELEASED | BUTTON1_PRESSED |
|
||||
BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED) << shf))
|
||||
{
|
||||
SP->mouse_status.changes |= 1 << i;
|
||||
|
||||
if (bstate & (BUTTON1_PRESSED << shf))
|
||||
button = BUTTON_PRESSED;
|
||||
if (bstate & (BUTTON1_CLICKED << shf))
|
||||
button = BUTTON_CLICKED;
|
||||
if (bstate & (BUTTON1_DOUBLE_CLICKED << shf))
|
||||
button = BUTTON_DOUBLE_CLICKED;
|
||||
|
||||
if (bstate & BUTTON_MODIFIER_SHIFT)
|
||||
button |= PDC_BUTTON_SHIFT;
|
||||
if (bstate & BUTTON_MODIFIER_CONTROL)
|
||||
button |= PDC_BUTTON_CONTROL;
|
||||
if (bstate & BUTTON_MODIFIER_ALT)
|
||||
button |= PDC_BUTTON_ALT;
|
||||
}
|
||||
|
||||
SP->mouse_status.button[i] = button;
|
||||
}
|
||||
|
||||
if (bstate & BUTTON4_PRESSED)
|
||||
SP->mouse_status.changes |= PDC_MOUSE_WHEEL_UP;
|
||||
else if (bstate & BUTTON5_PRESSED)
|
||||
SP->mouse_status.changes |= PDC_MOUSE_WHEEL_DOWN;
|
||||
|
||||
return PDC_ungetch(KEY_MOUSE);
|
||||
}
|
||||
|
||||
bool has_mouse(void)
|
||||
{
|
||||
return PDC_has_mouse();
|
||||
}
|
||||
77
pdcurses/move.c
Normal file
77
pdcurses/move.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
move
|
||||
----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int move(int y, int x);
|
||||
int mvcur(int oldrow, int oldcol, int newrow, int newcol);
|
||||
int wmove(WINDOW *win, int y, int x);
|
||||
|
||||
### Description
|
||||
|
||||
move() and wmove() move the cursor associated with the window to the
|
||||
given location. This does not move the physical cursor of the
|
||||
terminal until refresh() is called. The position specified is
|
||||
relative to the upper left corner of the window, which is (0,0).
|
||||
|
||||
mvcur() moves the physical cursor without updating any window cursor
|
||||
positions.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
move Y Y Y
|
||||
mvcur Y Y Y
|
||||
wmove Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int move(int y, int x)
|
||||
{
|
||||
PDC_LOG(("move() - called: y=%d x=%d\n", y, x));
|
||||
|
||||
if (!stdscr || x < 0 || y < 0 || x >= stdscr->_maxx || y >= stdscr->_maxy)
|
||||
return ERR;
|
||||
|
||||
stdscr->_curx = x;
|
||||
stdscr->_cury = y;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int mvcur(int oldrow, int oldcol, int newrow, int newcol)
|
||||
{
|
||||
PDC_LOG(("mvcur() - called: oldrow %d oldcol %d newrow %d newcol %d\n",
|
||||
oldrow, oldcol, newrow, newcol));
|
||||
|
||||
if (!SP || newrow < 0 || newrow >= LINES || newcol < 0 || newcol >= COLS)
|
||||
return ERR;
|
||||
|
||||
PDC_gotoyx(newrow, newcol);
|
||||
SP->cursrow = newrow;
|
||||
SP->curscol = newcol;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int wmove(WINDOW *win, int y, int x)
|
||||
{
|
||||
PDC_LOG(("wmove() - called: y=%d x=%d\n", y, x));
|
||||
|
||||
if (!win || x < 0 || y < 0 || x >= win->_maxx || y >= win->_maxy)
|
||||
return ERR;
|
||||
|
||||
win->_curx = x;
|
||||
win->_cury = y;
|
||||
|
||||
return OK;
|
||||
}
|
||||
175
pdcurses/outopts.c
Normal file
175
pdcurses/outopts.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
outopts
|
||||
-------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int clearok(WINDOW *win, bool bf);
|
||||
int idlok(WINDOW *win, bool bf);
|
||||
void idcok(WINDOW *win, bool bf);
|
||||
void immedok(WINDOW *win, bool bf);
|
||||
int leaveok(WINDOW *win, bool bf);
|
||||
int setscrreg(int top, int bot);
|
||||
int wsetscrreg(WINDOW *win, int top, int bot);
|
||||
int scrollok(WINDOW *win, bool bf);
|
||||
|
||||
int raw_output(bool bf);
|
||||
|
||||
bool is_leaveok(const WINDOW *win);
|
||||
|
||||
### Description
|
||||
|
||||
With clearok(), if bf is TRUE, the next call to wrefresh() with this
|
||||
window will clear the screen completely and redraw the entire screen.
|
||||
|
||||
immedok(), called with a second argument of TRUE, causes an automatic
|
||||
wrefresh() every time a change is made to the specified window.
|
||||
|
||||
Normally, the hardware cursor is left at the location of the window
|
||||
being refreshed. leaveok() allows the cursor to be left wherever the
|
||||
update happens to leave it. It's useful for applications where the
|
||||
cursor is not used, since it reduces the need for cursor motions. If
|
||||
possible, the cursor is made invisible when this option is enabled.
|
||||
|
||||
wsetscrreg() sets a scrolling region in a window; "top" and "bot" are
|
||||
the line numbers for the top and bottom margins. If this option and
|
||||
scrollok() are enabled, any attempt to move off the bottom margin
|
||||
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.
|
||||
|
||||
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_leaveok() reports whether the specified window is in leaveok mode.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions except is_leaveok() return OK on success and ERR on
|
||||
error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
clearok Y Y Y
|
||||
idlok Y Y Y
|
||||
idcok Y Y Y
|
||||
immedok Y Y Y
|
||||
leaveok Y Y Y
|
||||
setscrreg Y Y Y
|
||||
wsetscrreg Y Y Y
|
||||
scrollok Y Y Y
|
||||
is_leaveok - Y Y
|
||||
raw_output - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int clearok(WINDOW *win, bool bf)
|
||||
{
|
||||
PDC_LOG(("clearok() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
win->_clear = bf;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int idlok(WINDOW *win, bool bf)
|
||||
{
|
||||
PDC_LOG(("idlok() - called\n"));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void idcok(WINDOW *win, bool bf)
|
||||
{
|
||||
PDC_LOG(("idcok() - called\n"));
|
||||
}
|
||||
|
||||
void immedok(WINDOW *win, bool bf)
|
||||
{
|
||||
PDC_LOG(("immedok() - called\n"));
|
||||
|
||||
if (win)
|
||||
win->_immed = bf;
|
||||
}
|
||||
|
||||
int leaveok(WINDOW *win, bool bf)
|
||||
{
|
||||
PDC_LOG(("leaveok() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
win->_leaveit = bf;
|
||||
|
||||
curs_set(!bf);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int setscrreg(int top, int bottom)
|
||||
{
|
||||
PDC_LOG(("setscrreg() - called: top %d bottom %d\n", top, bottom));
|
||||
|
||||
return wsetscrreg(stdscr, top, bottom);
|
||||
}
|
||||
|
||||
int wsetscrreg(WINDOW *win, int top, int bottom)
|
||||
{
|
||||
PDC_LOG(("wsetscrreg() - called: top %d bottom %d\n", top, bottom));
|
||||
|
||||
if (win && 0 <= top && top <= win->_cury &&
|
||||
win->_cury <= bottom && bottom < win->_maxy)
|
||||
{
|
||||
win->_tmarg = top;
|
||||
win->_bmarg = bottom;
|
||||
|
||||
return OK;
|
||||
}
|
||||
else
|
||||
return ERR;
|
||||
}
|
||||
|
||||
int scrollok(WINDOW *win, bool bf)
|
||||
{
|
||||
PDC_LOG(("scrollok() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
win->_scroll = bf;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int raw_output(bool bf)
|
||||
{
|
||||
PDC_LOG(("raw_output() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
SP->raw_out = bf;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
bool is_leaveok(const WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("is_leaveok() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return FALSE;
|
||||
|
||||
return win->_leaveit;
|
||||
}
|
||||
214
pdcurses/overlay.c
Normal file
214
pdcurses/overlay.c
Normal file
@@ -0,0 +1,214 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
overlay
|
||||
-------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int overlay(const WINDOW *src_w, WINDOW *dst_w)
|
||||
int overwrite(const WINDOW *src_w, WINDOW *dst_w)
|
||||
int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr,
|
||||
int src_tc, int dst_tr, int dst_tc, int dst_br,
|
||||
int dst_bc, int _overlay)
|
||||
|
||||
### Description
|
||||
|
||||
overlay() and overwrite() copy all the text from src_w into dst_w.
|
||||
The windows need not be the same size. Those characters in the source
|
||||
window that intersect with the destination window are copied, so that
|
||||
the characters appear in the same physical position on the screen.
|
||||
The difference between the two functions is that overlay() is non-
|
||||
destructive (blanks are not copied) while overwrite() is destructive
|
||||
(blanks are copied).
|
||||
|
||||
copywin() is similar, but doesn't require that the two windows
|
||||
overlap. The arguments src_tc and src_tr specify the top left corner
|
||||
of the region to be copied. dst_tc, dst_tr, dst_br, and dst_bc
|
||||
specify the region within the destination window to copy to. The
|
||||
argument "overlay", if TRUE, indicates that the copy is done non-
|
||||
destructively (as in overlay()); blanks in the source window are not
|
||||
copied to the destination window. When overlay is FALSE, blanks are
|
||||
copied.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
overlay Y Y Y
|
||||
overwrite Y Y Y
|
||||
copywin Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
/* Thanks to Andreas Otte <venn@@uni-paderborn.de> for the
|
||||
corrected overlay()/overwrite() behavior. */
|
||||
|
||||
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;
|
||||
chtype *w1ptr, *w2ptr;
|
||||
|
||||
int lc = 0;
|
||||
int xdiff = src_bc - src_tc;
|
||||
int ydiff = src_br - src_tr;
|
||||
|
||||
if (!src_w || !dst_w)
|
||||
return ERR;
|
||||
|
||||
minchng = dst_w->_firstch;
|
||||
maxchng = dst_w->_lastch;
|
||||
|
||||
for (y1 = 0; y1 < dst_tr; y1++)
|
||||
{
|
||||
minchng++;
|
||||
maxchng++;
|
||||
}
|
||||
|
||||
for (line = 0; line < ydiff; line++)
|
||||
{
|
||||
w1ptr = src_w->_y[line + src_tr] + src_tc;
|
||||
w2ptr = dst_w->_y[line + dst_tr] + dst_tc;
|
||||
|
||||
fc = _NO_CHANGE;
|
||||
|
||||
for (col = 0; col < xdiff; col++)
|
||||
{
|
||||
if ((*w1ptr) != (*w2ptr) &&
|
||||
!((*w1ptr & A_CHARTEXT) == ' ' && _overlay))
|
||||
{
|
||||
*w2ptr = *w1ptr;
|
||||
|
||||
if (fc == _NO_CHANGE)
|
||||
fc = col + dst_tc;
|
||||
|
||||
lc = col + dst_tc;
|
||||
}
|
||||
|
||||
w1ptr++;
|
||||
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++;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int _copy_overlap(const WINDOW *src_w, WINDOW *dst_w, bool overlay)
|
||||
{
|
||||
int first_line, first_col, last_line, last_col;
|
||||
int src_start_x, src_start_y, dst_start_x, dst_start_y;
|
||||
int xdiff, ydiff;
|
||||
|
||||
if (!src_w || !dst_w)
|
||||
return ERR;
|
||||
|
||||
first_col = max(dst_w->_begx, src_w->_begx);
|
||||
first_line = max(dst_w->_begy, src_w->_begy);
|
||||
|
||||
last_col = min(src_w->_begx + src_w->_maxx, dst_w->_begx + dst_w->_maxx);
|
||||
last_line = min(src_w->_begy + src_w->_maxy, dst_w->_begy + dst_w->_maxy);
|
||||
|
||||
/* determine the overlapping region of the two windows in real
|
||||
coordinates */
|
||||
|
||||
/* if no overlapping region, do nothing */
|
||||
|
||||
if ((last_col < first_col) || (last_line < first_line))
|
||||
return OK;
|
||||
|
||||
/* size of overlapping region */
|
||||
|
||||
xdiff = last_col - first_col;
|
||||
ydiff = last_line - first_line;
|
||||
|
||||
if (src_w->_begx <= dst_w->_begx)
|
||||
{
|
||||
src_start_x = dst_w->_begx - src_w->_begx;
|
||||
dst_start_x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_start_x = src_w->_begx - dst_w->_begx;
|
||||
src_start_x = 0;
|
||||
}
|
||||
|
||||
if (src_w->_begy <= dst_w->_begy)
|
||||
{
|
||||
src_start_y = dst_w->_begy - src_w->_begy;
|
||||
dst_start_y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_start_y = src_w->_begy - dst_w->_begy;
|
||||
src_start_y = 0;
|
||||
}
|
||||
|
||||
return _copy_win(src_w, dst_w, src_start_y, src_start_x,
|
||||
src_start_y + ydiff, src_start_x + xdiff,
|
||||
dst_start_y, dst_start_x, overlay);
|
||||
}
|
||||
|
||||
int overlay(const WINDOW *src_w, WINDOW *dst_w)
|
||||
{
|
||||
PDC_LOG(("overlay() - called\n"));
|
||||
|
||||
return _copy_overlap(src_w, dst_w, TRUE);
|
||||
}
|
||||
|
||||
int overwrite(const WINDOW *src_w, WINDOW *dst_w)
|
||||
{
|
||||
PDC_LOG(("overwrite() - called\n"));
|
||||
|
||||
return _copy_overlap(src_w, dst_w, FALSE);
|
||||
}
|
||||
|
||||
int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr, int src_tc,
|
||||
int dst_tr, int dst_tc, int dst_br, int dst_bc, int _overlay)
|
||||
{
|
||||
int src_end_x, src_end_y;
|
||||
int src_rows, src_cols, dst_rows, dst_cols;
|
||||
int min_rows, min_cols;
|
||||
|
||||
PDC_LOG(("copywin() - called\n"));
|
||||
|
||||
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;
|
||||
|
||||
src_rows = src_w->_maxy - src_tr;
|
||||
src_cols = src_w->_maxx - src_tc;
|
||||
dst_rows = dst_br - dst_tr + 1;
|
||||
dst_cols = dst_bc - dst_tc + 1;
|
||||
|
||||
min_rows = min(src_rows, dst_rows);
|
||||
min_cols = min(src_cols, dst_cols);
|
||||
|
||||
src_end_y = src_tr + min_rows;
|
||||
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);
|
||||
}
|
||||
280
pdcurses/pad.c
Normal file
280
pdcurses/pad.c
Normal file
@@ -0,0 +1,280 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
pad
|
||||
---
|
||||
|
||||
### Synopsis
|
||||
|
||||
WINDOW *newpad(int nlines, int ncols);
|
||||
WINDOW *subpad(WINDOW *orig, int nlines, int ncols,
|
||||
int begy, int begx);
|
||||
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 pechochar(WINDOW *pad, chtype ch);
|
||||
int pecho_wchar(WINDOW *pad, const cchar_t *wch);
|
||||
|
||||
bool is_pad(const WINDOW *pad);
|
||||
|
||||
### Description
|
||||
|
||||
A pad is a special kind of window, which is not restricted by the
|
||||
screen size, and is not necessarily associated with a particular part
|
||||
of the screen. You can use a pad when you need a large window, and
|
||||
only a part of the window will be on the screen at one time. Pads are
|
||||
not refreshed automatically (e.g., from scrolling or echoing of
|
||||
input). You can't call wrefresh() with a pad as an argument; use
|
||||
prefresh() or pnoutrefresh() instead. Note that these routines
|
||||
require additional parameters to specify the part of the pad to be
|
||||
displayed, and the location to use on the screen.
|
||||
|
||||
newpad() creates a new pad data structure.
|
||||
|
||||
subpad() creates a new sub-pad within a pad, at position (begy,
|
||||
begx), with dimensions of nlines lines and ncols columns. This
|
||||
position is relative to the pad, and not to the screen as with
|
||||
subwin. Changes to either the parent pad or sub-pad will affect both.
|
||||
When using sub-pads, you may need to call touchwin() before calling
|
||||
prefresh().
|
||||
|
||||
pnoutrefresh() copies the specified pad to the virtual screen.
|
||||
|
||||
prefresh() calls pnoutrefresh(), followed by doupdate().
|
||||
|
||||
These routines are analogous to wnoutrefresh() and wrefresh(). (py,
|
||||
px) specifies the upper left corner of the part of the pad to be
|
||||
displayed; (sy1, sx1) and (sy2, sx2) describe the screen rectangle
|
||||
that will contain the selected part of the pad.
|
||||
|
||||
pechochar() is functionally equivalent to addch() followed by a call
|
||||
to prefresh(), with the last-used coordinates and dimensions.
|
||||
pecho_wchar() is the wide-character version.
|
||||
|
||||
is_pad() reports whether the specified window is a pad.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions except is_pad() return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
newpad Y Y Y
|
||||
subpad Y Y Y
|
||||
prefresh Y Y Y
|
||||
pnoutrefresh Y Y Y
|
||||
pechochar Y Y Y
|
||||
pecho_wchar Y Y Y
|
||||
is_pad - Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* 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;
|
||||
|
||||
PDC_LOG(("newpad() - called: lines=%d cols=%d\n", nlines, ncols));
|
||||
|
||||
win = PDC_makenew(nlines, ncols, 0, 0);
|
||||
if (win)
|
||||
win = PDC_makelines(win);
|
||||
|
||||
if (!win)
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
werase(win);
|
||||
|
||||
win->_flags = _PAD;
|
||||
|
||||
/* 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;
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
WINDOW *subpad(WINDOW *orig, int nlines, int ncols, int begy, int begx)
|
||||
{
|
||||
WINDOW *win;
|
||||
int i;
|
||||
|
||||
PDC_LOG(("subpad() - called: lines=%d cols=%d begy=%d begx=%d\n",
|
||||
nlines, ncols, begy, begx));
|
||||
|
||||
if (!orig || !(orig->_flags & _PAD))
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
/* make sure window fits inside the original one */
|
||||
|
||||
if (begy < 0 || begx < 0 ||
|
||||
(begy + nlines) > orig->_maxy ||
|
||||
(begx + ncols) > orig->_maxx)
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
if (!nlines)
|
||||
nlines = orig->_maxy - begy;
|
||||
|
||||
if (!ncols)
|
||||
ncols = orig->_maxx - begx;
|
||||
|
||||
win = PDC_makenew(nlines, ncols, begy, begx);
|
||||
if (!win)
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
/* initialize window variables */
|
||||
|
||||
win->_attrs = orig->_attrs;
|
||||
win->_leaveit = orig->_leaveit;
|
||||
win->_scroll = orig->_scroll;
|
||||
win->_nodelay = orig->_nodelay;
|
||||
win->_use_keypad = orig->_use_keypad;
|
||||
win->_parent = orig;
|
||||
|
||||
for (i = 0; i < nlines; i++)
|
||||
win->_y[i] = orig->_y[begy + i] + begx;
|
||||
|
||||
win->_flags = _SUBPAD;
|
||||
|
||||
/* 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;
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
int prefresh(WINDOW *win, int py, int px, int sy1, int sx1, int sy2, int sx2)
|
||||
{
|
||||
PDC_LOG(("prefresh() - called\n"));
|
||||
|
||||
if (pnoutrefresh(win, py, px, sy1, sx1, sy2, sx2) == ERR)
|
||||
return ERR;
|
||||
|
||||
doupdate();
|
||||
return OK;
|
||||
}
|
||||
|
||||
int pnoutrefresh(WINDOW *w, int py, int px, int sy1, int sx1, int sy2, int sx2)
|
||||
{
|
||||
int num_cols;
|
||||
int sline;
|
||||
int pline;
|
||||
|
||||
PDC_LOG(("pnoutrefresh() - called\n"));
|
||||
|
||||
if (py < 0)
|
||||
py = 0;
|
||||
if (px < 0)
|
||||
px = 0;
|
||||
if (sy1 < 0)
|
||||
sy1 = 0;
|
||||
if (sx1 < 0)
|
||||
sx1 = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
if (pline < w->_maxy)
|
||||
{
|
||||
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 */
|
||||
}
|
||||
|
||||
sline++;
|
||||
pline++;
|
||||
}
|
||||
|
||||
if (w->_clear)
|
||||
{
|
||||
w->_clear = FALSE;
|
||||
curscr->_clear = TRUE;
|
||||
}
|
||||
|
||||
/* position the cursor to the pad's current position if possible --
|
||||
is the pad current position going to end up displayed? if not,
|
||||
then don't move the cursor; if so, move it to the correct place */
|
||||
|
||||
if (!w->_leaveit && w->_cury >= py && w->_curx >= px &&
|
||||
w->_cury <= py + (sy2 - sy1) && w->_curx <= px + (sx2 - sx1))
|
||||
{
|
||||
curscr->_cury = (w->_cury - py) + sy1;
|
||||
curscr->_curx = (w->_curx - px) + sx1;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int pechochar(WINDOW *pad, chtype ch)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int pecho_wchar(WINDOW *pad, const cchar_t *wch)
|
||||
{
|
||||
PDC_LOG(("pecho_wchar() - called\n"));
|
||||
|
||||
if (!wch || (waddch(pad, *wch) == ERR))
|
||||
return ERR;
|
||||
|
||||
return prefresh(pad, save_pminrow, save_pmincol, save_sminrow,
|
||||
save_smincol, save_smaxrow, save_smaxcol);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool is_pad(const WINDOW *pad)
|
||||
{
|
||||
PDC_LOG(("is_pad() - called\n"));
|
||||
|
||||
if (!pad)
|
||||
return FALSE;
|
||||
|
||||
return (pad->_flags & _PAD) ? TRUE : FALSE;
|
||||
}
|
||||
633
pdcurses/panel.c
Normal file
633
pdcurses/panel.c
Normal file
@@ -0,0 +1,633 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
panel
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int bottom_panel(PANEL *pan);
|
||||
int del_panel(PANEL *pan);
|
||||
int hide_panel(PANEL *pan);
|
||||
int move_panel(PANEL *pan, int starty, int startx);
|
||||
PANEL *new_panel(WINDOW *win);
|
||||
PANEL *panel_above(const PANEL *pan);
|
||||
PANEL *panel_below(const PANEL *pan);
|
||||
int panel_hidden(const PANEL *pan);
|
||||
const void *panel_userptr(const PANEL *pan);
|
||||
WINDOW *panel_window(const PANEL *pan);
|
||||
int replace_panel(PANEL *pan, WINDOW *win);
|
||||
int set_panel_userptr(PANEL *pan, const void *uptr);
|
||||
int show_panel(PANEL *pan);
|
||||
int top_panel(PANEL *pan);
|
||||
void update_panels(void);
|
||||
|
||||
### Description
|
||||
|
||||
For historic reasons, and for compatibility with other versions of
|
||||
curses, the panel functions are prototyped in a separate header,
|
||||
panel.h. In many implementations, they're also in a separate library,
|
||||
but PDCurses incorporates them.
|
||||
|
||||
The panel functions provide a way to have depth relationships between
|
||||
curses windows. Panels can overlap without making visible the
|
||||
overlapped portions of underlying windows. The initial curses window,
|
||||
stdscr, lies beneath all panels. The set of currently visible panels
|
||||
is the 'deck' of panels.
|
||||
|
||||
You can create panels, fetch and set their associated windows,
|
||||
shuffle panels in the deck, and manipulate them in other ways.
|
||||
|
||||
bottom_panel() places pan at the bottom of the deck. The size,
|
||||
location and contents of the panel are unchanged.
|
||||
|
||||
del_panel() deletes pan, but not its associated winwow.
|
||||
|
||||
hide_panel() removes a panel from the deck and thus hides it from
|
||||
view.
|
||||
|
||||
move_panel() moves the curses window associated with pan, so that its
|
||||
upper lefthand corner is at the supplied coordinates. (Don't use
|
||||
mvwin() on the window.)
|
||||
|
||||
new_panel() creates a new panel associated with win and returns the
|
||||
panel pointer. The new panel is placed at the top of the deck.
|
||||
|
||||
panel_above() returns a pointer to the panel in the deck above pan,
|
||||
or NULL if pan is the top panel. If the value of pan passed is NULL,
|
||||
this function returns a pointer to the bottom panel in the deck.
|
||||
|
||||
panel_below() returns a pointer to the panel in the deck below pan,
|
||||
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.
|
||||
|
||||
panel_hidden() returns OK if pan is hidden and ERR if it is not.
|
||||
|
||||
panel_userptr() - Each panel has a user pointer available for
|
||||
maintaining relevant information. This function returns a pointer to
|
||||
that information previously set up by set_panel_userptr().
|
||||
|
||||
panel_window() returns a pointer to the curses window associated with
|
||||
the panel.
|
||||
|
||||
replace_panel() replaces the current window of pan with win.
|
||||
|
||||
set_panel_userptr() - Each panel has a user pointer available for
|
||||
maintaining relevant information. This function sets the value of
|
||||
that information.
|
||||
|
||||
show_panel() makes a previously hidden panel visible and places it
|
||||
back in the deck on top.
|
||||
|
||||
top_panel() places pan on the top of the deck. The size, location and
|
||||
contents of the panel are unchanged.
|
||||
|
||||
update_panels() refreshes the virtual screen to reflect the depth
|
||||
relationships between the panels in the deck. The user must use
|
||||
doupdate() to refresh the physical screen.
|
||||
|
||||
### Return Value
|
||||
|
||||
Each routine that returns a pointer to an object returns NULL if an
|
||||
error occurs. Each panel routine that returns an integer, returns OK
|
||||
if it executes successfully and ERR if it does not.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
bottom_panel - Y Y
|
||||
del_panel - Y Y
|
||||
hide_panel - Y Y
|
||||
move_panel - Y Y
|
||||
new_panel - Y Y
|
||||
panel_above - Y Y
|
||||
panel_below - Y Y
|
||||
panel_hidden - Y Y
|
||||
panel_userptr - Y Y
|
||||
panel_window - Y Y
|
||||
replace_panel - Y Y
|
||||
set_panel_userptr - Y Y
|
||||
show_panel - Y Y
|
||||
top_panel - Y Y
|
||||
update_panels - Y Y
|
||||
|
||||
Credits:
|
||||
Original Author - Warren Tucker <wht@n4hgf.mt-park.ga.us>
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <panel.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
PANEL *_bottom_panel = (PANEL *)0;
|
||||
PANEL *_top_panel = (PANEL *)0;
|
||||
PANEL _stdscr_pseudo_panel = { (WINDOW *)0 };
|
||||
|
||||
#ifdef PANEL_DEBUG
|
||||
|
||||
static void dPanel(char *text, PANEL *pan)
|
||||
{
|
||||
PDC_LOG(("%s id=%s b=%s a=%s y=%d x=%d", text, pan->user,
|
||||
pan->below ? pan->below->user : "--",
|
||||
pan->above ? pan->above->user : "--",
|
||||
pan->wstarty, pan->wstartx));
|
||||
}
|
||||
|
||||
static void dStack(char *fmt, int num, PANEL *pan)
|
||||
{
|
||||
char s80[80];
|
||||
|
||||
sprintf(s80, fmt, num, pan);
|
||||
PDC_LOG(("%s b=%s t=%s", s80, _bottom_panel ? _bottom_panel->user : "--",
|
||||
_top_panel ? _top_panel->user : "--"));
|
||||
|
||||
if (pan)
|
||||
PDC_LOG(("pan id=%s", pan->user));
|
||||
|
||||
pan = _bottom_panel;
|
||||
|
||||
while (pan)
|
||||
{
|
||||
dPanel("stk", pan);
|
||||
pan = pan->above;
|
||||
}
|
||||
}
|
||||
|
||||
/* debugging hook for wnoutrefresh */
|
||||
|
||||
static void Wnoutrefresh(PANEL *pan)
|
||||
{
|
||||
dPanel("wnoutrefresh", pan);
|
||||
wnoutrefresh(pan->win);
|
||||
}
|
||||
|
||||
static void Touchpan(PANEL *pan)
|
||||
{
|
||||
dPanel("Touchpan", pan);
|
||||
touchwin(pan->win);
|
||||
}
|
||||
|
||||
static void Touchline(PANEL *pan, int start, int count)
|
||||
{
|
||||
char s80[80];
|
||||
|
||||
sprintf(s80, "Touchline s=%d c=%d", start, count);
|
||||
dPanel(s80, pan);
|
||||
touchline(pan->win, start, count);
|
||||
}
|
||||
|
||||
#else /* PANEL_DEBUG */
|
||||
|
||||
#define dPanel(text, pan)
|
||||
#define dStack(fmt, num, pan)
|
||||
#define Wnoutrefresh(pan) wnoutrefresh((pan)->win)
|
||||
#define Touchpan(pan) touchwin((pan)->win)
|
||||
#define Touchline(pan, start, count) touchline((pan)->win, start, count)
|
||||
|
||||
#endif /* PANEL_DEBUG */
|
||||
|
||||
static bool _panels_overlapped(PANEL *pan1, PANEL *pan2)
|
||||
{
|
||||
if (!pan1 || !pan2)
|
||||
return FALSE;
|
||||
|
||||
return ((pan1->wstarty >= pan2->wstarty && pan1->wstarty < pan2->wendy)
|
||||
|| (pan2->wstarty >= pan1->wstarty && pan2->wstarty < pan1->wendy))
|
||||
&& ((pan1->wstartx >= pan2->wstartx && pan1->wstartx < pan2->wendx)
|
||||
|| (pan2->wstartx >= pan1->wstartx && pan2->wstartx < pan1->wendx));
|
||||
}
|
||||
|
||||
static void _free_obscure(PANEL *pan)
|
||||
{
|
||||
PANELOBS *tobs = pan->obscure; /* "this" one */
|
||||
PANELOBS *nobs; /* "next" one */
|
||||
|
||||
while (tobs)
|
||||
{
|
||||
nobs = tobs->above;
|
||||
free((char *)tobs);
|
||||
tobs = nobs;
|
||||
}
|
||||
pan->obscure = (PANELOBS *)0;
|
||||
}
|
||||
|
||||
static void _override(PANEL *pan, int show)
|
||||
{
|
||||
int y;
|
||||
PANEL *pan2;
|
||||
PANELOBS *tobs = pan->obscure; /* "this" one */
|
||||
|
||||
if (show == 1)
|
||||
Touchpan(pan);
|
||||
else if (!show)
|
||||
{
|
||||
Touchpan(pan);
|
||||
Touchpan(&_stdscr_pseudo_panel);
|
||||
}
|
||||
else if (show == -1)
|
||||
while (tobs && (tobs->pan != pan))
|
||||
tobs = tobs->above;
|
||||
|
||||
while (tobs)
|
||||
{
|
||||
if ((pan2 = tobs->pan) != pan)
|
||||
for (y = pan->wstarty; y < pan->wendy; y++)
|
||||
if ((y >= pan2->wstarty) && (y < pan2->wendy) &&
|
||||
((is_linetouched(pan->win, y - pan->wstarty)) ||
|
||||
(is_linetouched(stdscr, y))))
|
||||
Touchline(pan2, y - pan2->wstarty, 1);
|
||||
|
||||
tobs = tobs->above;
|
||||
}
|
||||
}
|
||||
|
||||
static void _calculate_obscure(void)
|
||||
{
|
||||
PANEL *pan, *pan2;
|
||||
PANELOBS *tobs; /* "this" one */
|
||||
PANELOBS *lobs; /* last one */
|
||||
|
||||
pan = _bottom_panel;
|
||||
|
||||
while (pan)
|
||||
{
|
||||
if (pan->obscure)
|
||||
_free_obscure(pan);
|
||||
|
||||
lobs = (PANELOBS *)0;
|
||||
pan2 = _bottom_panel;
|
||||
|
||||
while (pan2)
|
||||
{
|
||||
if (_panels_overlapped(pan, pan2))
|
||||
{
|
||||
if ((tobs = malloc(sizeof(PANELOBS))) == NULL)
|
||||
return;
|
||||
|
||||
tobs->pan = pan2;
|
||||
dPanel("obscured", pan2);
|
||||
tobs->above = (PANELOBS *)0;
|
||||
|
||||
if (lobs)
|
||||
lobs->above = tobs;
|
||||
else
|
||||
pan->obscure = tobs;
|
||||
|
||||
lobs = tobs;
|
||||
}
|
||||
|
||||
pan2 = pan2->above;
|
||||
}
|
||||
|
||||
_override(pan, 1);
|
||||
pan = pan->above;
|
||||
}
|
||||
}
|
||||
|
||||
/* check to see if panel is in the stack */
|
||||
|
||||
static bool _panel_is_linked(const PANEL *pan)
|
||||
{
|
||||
PANEL *pan2 = _bottom_panel;
|
||||
|
||||
while (pan2)
|
||||
{
|
||||
if (pan2 == pan)
|
||||
return TRUE;
|
||||
|
||||
pan2 = pan2->above;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* link panel into stack at top */
|
||||
|
||||
static void _panel_link_top(PANEL *pan)
|
||||
{
|
||||
#ifdef PANEL_DEBUG
|
||||
dStack("<lt%d>", 1, pan);
|
||||
if (_panel_is_linked(pan))
|
||||
return;
|
||||
#endif
|
||||
pan->above = (PANEL *)0;
|
||||
pan->below = (PANEL *)0;
|
||||
|
||||
if (_top_panel)
|
||||
{
|
||||
_top_panel->above = pan;
|
||||
pan->below = _top_panel;
|
||||
}
|
||||
|
||||
_top_panel = pan;
|
||||
|
||||
if (!_bottom_panel)
|
||||
_bottom_panel = pan;
|
||||
|
||||
_calculate_obscure();
|
||||
dStack("<lt%d>", 9, pan);
|
||||
}
|
||||
|
||||
/* link panel into stack at bottom */
|
||||
|
||||
static void _panel_link_bottom(PANEL *pan)
|
||||
{
|
||||
#ifdef PANEL_DEBUG
|
||||
dStack("<lb%d>", 1, pan);
|
||||
if (_panel_is_linked(pan))
|
||||
return;
|
||||
#endif
|
||||
pan->above = (PANEL *)0;
|
||||
pan->below = (PANEL *)0;
|
||||
|
||||
if (_bottom_panel)
|
||||
{
|
||||
_bottom_panel->below = pan;
|
||||
pan->above = _bottom_panel;
|
||||
}
|
||||
|
||||
_bottom_panel = pan;
|
||||
|
||||
if (!_top_panel)
|
||||
_top_panel = pan;
|
||||
|
||||
_calculate_obscure();
|
||||
dStack("<lb%d>", 9, pan);
|
||||
}
|
||||
|
||||
static void _panel_unlink(PANEL *pan)
|
||||
{
|
||||
PANEL *prev;
|
||||
PANEL *next;
|
||||
|
||||
#ifdef PANEL_DEBUG
|
||||
dStack("<u%d>", 1, pan);
|
||||
if (!_panel_is_linked(pan))
|
||||
return;
|
||||
#endif
|
||||
_override(pan, 0);
|
||||
_free_obscure(pan);
|
||||
|
||||
prev = pan->below;
|
||||
next = pan->above;
|
||||
|
||||
/* if non-zero, we will not update the list head */
|
||||
|
||||
if (prev)
|
||||
{
|
||||
prev->above = next;
|
||||
if(next)
|
||||
next->below = prev;
|
||||
}
|
||||
else if (next)
|
||||
next->below = prev;
|
||||
|
||||
if (pan == _bottom_panel)
|
||||
_bottom_panel = next;
|
||||
|
||||
if (pan == _top_panel)
|
||||
_top_panel = prev;
|
||||
|
||||
_calculate_obscure();
|
||||
|
||||
pan->above = (PANEL *)0;
|
||||
pan->below = (PANEL *)0;
|
||||
dStack("<u%d>", 9, pan);
|
||||
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* The following are the public functions for the panels library. *
|
||||
************************************************************************/
|
||||
|
||||
int bottom_panel(PANEL *pan)
|
||||
{
|
||||
if (!pan)
|
||||
return ERR;
|
||||
|
||||
if (pan == _bottom_panel)
|
||||
return OK;
|
||||
|
||||
if (_panel_is_linked(pan))
|
||||
hide_panel(pan);
|
||||
|
||||
_panel_link_bottom(pan);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int del_panel(PANEL *pan)
|
||||
{
|
||||
if (pan)
|
||||
{
|
||||
if (_panel_is_linked(pan))
|
||||
hide_panel(pan);
|
||||
|
||||
free((char *)pan);
|
||||
return OK;
|
||||
}
|
||||
|
||||
return ERR;
|
||||
}
|
||||
|
||||
int hide_panel(PANEL *pan)
|
||||
{
|
||||
if (!pan)
|
||||
return ERR;
|
||||
|
||||
if (!_panel_is_linked(pan))
|
||||
{
|
||||
pan->above = (PANEL *)0;
|
||||
pan->below = (PANEL *)0;
|
||||
return ERR;
|
||||
}
|
||||
|
||||
_panel_unlink(pan);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int move_panel(PANEL *pan, int starty, int startx)
|
||||
{
|
||||
WINDOW *win;
|
||||
int maxy, maxx;
|
||||
|
||||
if (!pan)
|
||||
return ERR;
|
||||
|
||||
if (_panel_is_linked(pan))
|
||||
_override(pan, 0);
|
||||
|
||||
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;
|
||||
|
||||
if (_panel_is_linked(pan))
|
||||
_calculate_obscure();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
PANEL *new_panel(WINDOW *win)
|
||||
{
|
||||
PANEL *pan;
|
||||
|
||||
if (!win)
|
||||
return (PANEL *)NULL;
|
||||
|
||||
pan = malloc(sizeof(PANEL));
|
||||
|
||||
if (!_stdscr_pseudo_panel.win)
|
||||
{
|
||||
_stdscr_pseudo_panel.win = stdscr;
|
||||
_stdscr_pseudo_panel.wstarty = 0;
|
||||
_stdscr_pseudo_panel.wstartx = 0;
|
||||
_stdscr_pseudo_panel.wendy = LINES;
|
||||
_stdscr_pseudo_panel.wendx = COLS;
|
||||
_stdscr_pseudo_panel.user = "stdscr";
|
||||
_stdscr_pseudo_panel.obscure = (PANELOBS *)0;
|
||||
}
|
||||
|
||||
if (pan)
|
||||
{
|
||||
int maxy, maxx;
|
||||
|
||||
pan->win = win;
|
||||
pan->above = (PANEL *)0;
|
||||
pan->below = (PANEL *)0;
|
||||
getbegyx(win, pan->wstarty, pan->wstartx);
|
||||
getmaxyx(win, maxy, maxx);
|
||||
pan->wendy = pan->wstarty + maxy;
|
||||
pan->wendx = pan->wstartx + maxx;
|
||||
#ifdef PANEL_DEBUG
|
||||
pan->user = "new";
|
||||
#else
|
||||
pan->user = (char *)0;
|
||||
#endif
|
||||
pan->obscure = (PANELOBS *)0;
|
||||
show_panel(pan);
|
||||
}
|
||||
|
||||
return pan;
|
||||
}
|
||||
|
||||
PANEL *panel_above(const PANEL *pan)
|
||||
{
|
||||
return pan ? pan->above : _bottom_panel;
|
||||
}
|
||||
|
||||
PANEL *panel_below(const PANEL *pan)
|
||||
{
|
||||
return pan ? pan->below : _top_panel;
|
||||
}
|
||||
|
||||
int panel_hidden(const PANEL *pan)
|
||||
{
|
||||
if (!pan)
|
||||
return ERR;
|
||||
|
||||
return _panel_is_linked(pan) ? ERR : OK;
|
||||
}
|
||||
|
||||
const void *panel_userptr(const PANEL *pan)
|
||||
{
|
||||
return pan ? pan->user : NULL;
|
||||
}
|
||||
|
||||
WINDOW *panel_window(const PANEL *pan)
|
||||
{
|
||||
PDC_LOG(("panel_window() - called\n"));
|
||||
|
||||
if (!pan)
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
return pan->win;
|
||||
}
|
||||
|
||||
int replace_panel(PANEL *pan, WINDOW *win)
|
||||
{
|
||||
int maxy, maxx;
|
||||
|
||||
if (!pan)
|
||||
return ERR;
|
||||
|
||||
if (_panel_is_linked(pan))
|
||||
_override(pan, 0);
|
||||
|
||||
pan->win = win;
|
||||
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;
|
||||
}
|
||||
|
||||
int set_panel_userptr(PANEL *pan, const void *uptr)
|
||||
{
|
||||
if (!pan)
|
||||
return ERR;
|
||||
|
||||
pan->user = uptr;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int show_panel(PANEL *pan)
|
||||
{
|
||||
if (!pan)
|
||||
return ERR;
|
||||
|
||||
if (pan == _top_panel)
|
||||
return OK;
|
||||
|
||||
if (_panel_is_linked(pan))
|
||||
hide_panel(pan);
|
||||
|
||||
_panel_link_top(pan);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int top_panel(PANEL *pan)
|
||||
{
|
||||
return show_panel(pan);
|
||||
}
|
||||
|
||||
void update_panels(void)
|
||||
{
|
||||
PANEL *pan;
|
||||
|
||||
PDC_LOG(("update_panels() - called\n"));
|
||||
|
||||
pan = _bottom_panel;
|
||||
|
||||
while (pan)
|
||||
{
|
||||
_override(pan, -1);
|
||||
pan = pan->above;
|
||||
}
|
||||
|
||||
if (is_wintouched(stdscr))
|
||||
Wnoutrefresh(&_stdscr_pseudo_panel);
|
||||
|
||||
pan = _bottom_panel;
|
||||
|
||||
while (pan)
|
||||
{
|
||||
if (is_wintouched(pan->win) || !pan->above)
|
||||
Wnoutrefresh(pan);
|
||||
|
||||
pan = pan->above;
|
||||
}
|
||||
}
|
||||
129
pdcurses/printw.c
Normal file
129
pdcurses/printw.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
printw
|
||||
------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int printw(const char *fmt, ...);
|
||||
int wprintw(WINDOW *win, const char *fmt, ...);
|
||||
int mvprintw(int y, int x, const char *fmt, ...);
|
||||
int mvwprintw(WINDOW *win, int y, int x, const char *fmt,...);
|
||||
int vwprintw(WINDOW *win, const char *fmt, va_list varglist);
|
||||
int vw_printw(WINDOW *win, const char *fmt, va_list varglist);
|
||||
|
||||
### Description
|
||||
|
||||
The printw() functions add a formatted string to the window at the
|
||||
current or specified cursor position. The format strings are the same
|
||||
as used in the standard C library's printf(). (printw() can be used
|
||||
as a drop-in replacement for printf().)
|
||||
|
||||
The duplication between vwprintw() and vw_printw() is for historic
|
||||
reasons. In PDCurses, they're the same.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return the number of characters printed, or ERR on
|
||||
error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
printw Y Y Y
|
||||
wprintw Y Y Y
|
||||
mvprintw Y Y Y
|
||||
mvwprintw Y Y Y
|
||||
vwprintw Y Y Y
|
||||
vw_printw Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int vwprintw(WINDOW *win, const char *fmt, va_list varglist)
|
||||
{
|
||||
char printbuf[513];
|
||||
int len;
|
||||
|
||||
PDC_LOG(("vwprintw() - called\n"));
|
||||
|
||||
#ifdef HAVE_VSNPRINTF
|
||||
len = vsnprintf(printbuf, 512, fmt, varglist);
|
||||
#else
|
||||
len = vsprintf(printbuf, fmt, varglist);
|
||||
#endif
|
||||
return (waddstr(win, printbuf) == ERR) ? ERR : len;
|
||||
}
|
||||
|
||||
int printw(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int retval;
|
||||
|
||||
PDC_LOG(("printw() - called\n"));
|
||||
|
||||
va_start(args, fmt);
|
||||
retval = vwprintw(stdscr, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int wprintw(WINDOW *win, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int retval;
|
||||
|
||||
PDC_LOG(("wprintw() - called\n"));
|
||||
|
||||
va_start(args, fmt);
|
||||
retval = vwprintw(win, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int mvprintw(int y, int x, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int retval;
|
||||
|
||||
PDC_LOG(("mvprintw() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
va_start(args, fmt);
|
||||
retval = vwprintw(stdscr, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int mvwprintw(WINDOW *win, int y, int x, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int retval;
|
||||
|
||||
PDC_LOG(("mvwprintw() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
va_start(args, fmt);
|
||||
retval = vwprintw(win, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int vw_printw(WINDOW *win, const char *fmt, va_list varglist)
|
||||
{
|
||||
PDC_LOG(("vw_printw() - called\n"));
|
||||
|
||||
return vwprintw(win, fmt, varglist);
|
||||
}
|
||||
279
pdcurses/refresh.c
Normal file
279
pdcurses/refresh.c
Normal file
@@ -0,0 +1,279 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
refresh
|
||||
-------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int refresh(void);
|
||||
int wrefresh(WINDOW *win);
|
||||
int wnoutrefresh(WINDOW *win);
|
||||
int doupdate(void);
|
||||
int redrawwin(WINDOW *win);
|
||||
int wredrawln(WINDOW *win, int beg_line, int num_lines);
|
||||
|
||||
### Description
|
||||
|
||||
wrefresh() copies the named window to the physical terminal screen,
|
||||
taking into account what is already there in order to optimize cursor
|
||||
movement. refresh() does the same, using stdscr. These routines must
|
||||
be called to get any output on the terminal, as other routines only
|
||||
manipulate data structures. Unless leaveok() has been enabled, the
|
||||
physical cursor of the terminal is left at the location of the
|
||||
window's cursor.
|
||||
|
||||
wnoutrefresh() and doupdate() allow multiple updates with more
|
||||
efficiency than wrefresh() alone. wrefresh() works by first calling
|
||||
wnoutrefresh(), which copies the named window to the virtual screen.
|
||||
It then calls doupdate(), which compares the virtual screen to the
|
||||
physical screen and does the actual update. A series of calls to
|
||||
wrefresh() will result in alternating calls to wnoutrefresh() and
|
||||
doupdate(), causing several bursts of output to the screen. By first
|
||||
calling wnoutrefresh() for each window, it is then possible to call
|
||||
doupdate() only once.
|
||||
|
||||
In PDCurses, redrawwin() is equivalent to touchwin(), and wredrawln()
|
||||
is the same as touchline(). In some other curses implementations,
|
||||
there's a subtle distinction, but it has no meaning in PDCurses.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
refresh Y Y Y
|
||||
wrefresh Y Y Y
|
||||
wnoutrefresh Y Y Y
|
||||
doupdate Y Y Y
|
||||
redrawwin Y Y Y
|
||||
wredrawln Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int wnoutrefresh(WINDOW *win)
|
||||
{
|
||||
int begy, begx; /* window's place on screen */
|
||||
int i, j;
|
||||
|
||||
PDC_LOG(("wnoutrefresh() - called: win=%p\n", win));
|
||||
|
||||
if ( !win || (win->_flags & (_PAD|_SUBPAD)) )
|
||||
return ERR;
|
||||
|
||||
begy = win->_begy;
|
||||
begx = win->_begx;
|
||||
|
||||
for (i = 0, j = begy; i < win->_maxy; i++, j++)
|
||||
{
|
||||
if (win->_firstch[i] != _NO_CHANGE)
|
||||
{
|
||||
chtype *src = win->_y[i];
|
||||
chtype *dest = curscr->_y[j] + begx;
|
||||
|
||||
int first = win->_firstch[i]; /* first changed */
|
||||
int last = win->_lastch[i]; /* last changed */
|
||||
|
||||
/* ignore areas on the outside that are marked as changed,
|
||||
but really aren't */
|
||||
|
||||
while (first <= last && src[first] == dest[first])
|
||||
first++;
|
||||
|
||||
while (last >= first && src[last] == dest[last])
|
||||
last--;
|
||||
|
||||
/* if any have really changed... */
|
||||
|
||||
if (first <= last)
|
||||
{
|
||||
memcpy(dest + first, src + first,
|
||||
(last - first + 1) * sizeof(chtype));
|
||||
|
||||
first += begx;
|
||||
last += begx;
|
||||
|
||||
if (first < curscr->_firstch[j] ||
|
||||
curscr->_firstch[j] == _NO_CHANGE)
|
||||
curscr->_firstch[j] = first;
|
||||
|
||||
if (last > curscr->_lastch[j])
|
||||
curscr->_lastch[j] = last;
|
||||
}
|
||||
|
||||
win->_firstch[i] = _NO_CHANGE; /* updated now */
|
||||
}
|
||||
|
||||
win->_lastch[i] = _NO_CHANGE; /* updated now */
|
||||
}
|
||||
|
||||
if (win->_clear)
|
||||
win->_clear = FALSE;
|
||||
|
||||
if (!win->_leaveit)
|
||||
{
|
||||
curscr->_cury = win->_cury + begy;
|
||||
curscr->_curx = win->_curx + begx;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int doupdate(void)
|
||||
{
|
||||
int y;
|
||||
bool clearall;
|
||||
|
||||
PDC_LOG(("doupdate() - called\n"));
|
||||
|
||||
if (!SP || !curscr)
|
||||
return ERR;
|
||||
|
||||
if (isendwin()) /* coming back after endwin() called */
|
||||
{
|
||||
reset_prog_mode();
|
||||
clearall = TRUE;
|
||||
SP->alive = TRUE; /* so isendwin() result is correct */
|
||||
}
|
||||
else
|
||||
clearall = curscr->_clear;
|
||||
|
||||
for (y = 0; y < SP->lines; y++)
|
||||
{
|
||||
PDC_LOG(("doupdate() - Transforming line %d of %d: %s\n",
|
||||
y, SP->lines, (curscr->_firstch[y] != _NO_CHANGE) ?
|
||||
"Yes" : "No"));
|
||||
|
||||
if (clearall || curscr->_firstch[y] != _NO_CHANGE)
|
||||
{
|
||||
int first, last;
|
||||
|
||||
chtype *src = curscr->_y[y];
|
||||
chtype *dest = SP->lastscr->_y[y];
|
||||
|
||||
if (clearall)
|
||||
{
|
||||
first = 0;
|
||||
last = COLS - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = curscr->_firstch[y];
|
||||
last = curscr->_lastch[y];
|
||||
}
|
||||
|
||||
while (first <= last)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
/* build up a run of changed cells; if two runs are
|
||||
separated by a single unchanged cell, ignore the
|
||||
break */
|
||||
|
||||
if (clearall)
|
||||
len = last - first + 1;
|
||||
else
|
||||
while (first + len <= last &&
|
||||
(src[first + len] != dest[first + len] ||
|
||||
(len && first + len < last &&
|
||||
src[first + len + 1] != dest[first + len + 1])
|
||||
)
|
||||
)
|
||||
len++;
|
||||
|
||||
/* update the screen, and SP->lastscr */
|
||||
|
||||
if (len)
|
||||
{
|
||||
PDC_transform_line(y, first, len, src + first);
|
||||
memcpy(dest + first, src + first, len * sizeof(chtype));
|
||||
first += len;
|
||||
}
|
||||
|
||||
/* skip over runs of unchanged cells */
|
||||
|
||||
while (first <= last && src[first] == dest[first])
|
||||
first++;
|
||||
}
|
||||
|
||||
curscr->_firstch[y] = _NO_CHANGE;
|
||||
curscr->_lastch[y] = _NO_CHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
curscr->_clear = FALSE;
|
||||
|
||||
if (SP->visibility)
|
||||
PDC_gotoyx(curscr->_cury, curscr->_curx);
|
||||
|
||||
SP->cursrow = curscr->_cury;
|
||||
SP->curscol = curscr->_curx;
|
||||
|
||||
PDC_doupdate();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int wrefresh(WINDOW *win)
|
||||
{
|
||||
bool save_clear;
|
||||
|
||||
PDC_LOG(("wrefresh() - called\n"));
|
||||
|
||||
if ( !win || (win->_flags & (_PAD|_SUBPAD)) )
|
||||
return ERR;
|
||||
|
||||
save_clear = win->_clear;
|
||||
|
||||
if (win == curscr)
|
||||
curscr->_clear = TRUE;
|
||||
else
|
||||
wnoutrefresh(win);
|
||||
|
||||
if (save_clear && win->_maxy == SP->lines && win->_maxx == SP->cols)
|
||||
curscr->_clear = TRUE;
|
||||
|
||||
return doupdate();
|
||||
}
|
||||
|
||||
int refresh(void)
|
||||
{
|
||||
PDC_LOG(("refresh() - called\n"));
|
||||
|
||||
return wrefresh(stdscr);
|
||||
}
|
||||
|
||||
int wredrawln(WINDOW *win, int start, int num)
|
||||
{
|
||||
int i;
|
||||
|
||||
PDC_LOG(("wredrawln() - called: win=%p start=%d num=%d\n",
|
||||
win, start, num));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int redrawwin(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("redrawwin() - called: win=%p\n", win));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
return wredrawln(win, 0, win->_maxy);
|
||||
}
|
||||
581
pdcurses/scanw.c
Normal file
581
pdcurses/scanw.c
Normal file
@@ -0,0 +1,581 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
scanw
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int scanw(const char *fmt, ...);
|
||||
int wscanw(WINDOW *win, const char *fmt, ...);
|
||||
int mvscanw(int y, int x, const char *fmt, ...);
|
||||
int mvwscanw(WINDOW *win, int y, int x, const char *fmt, ...);
|
||||
int vwscanw(WINDOW *win, const char *fmt, va_list varglist);
|
||||
int vw_scanw(WINDOW *win, const char *fmt, va_list varglist);
|
||||
|
||||
### Description
|
||||
|
||||
These routines correspond to the standard C library's scanf() family.
|
||||
Each gets a string from the window via wgetnstr(), and uses the
|
||||
resulting line as input for the scan.
|
||||
|
||||
The duplication between vwscanw() and vw_scanw() is for historic
|
||||
reasons. In PDCurses, they're the same.
|
||||
|
||||
### Return Value
|
||||
|
||||
On successful completion, these functions return the number of items
|
||||
successfully matched. Otherwise they return ERR.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
scanw Y Y Y
|
||||
wscanw Y Y Y
|
||||
mvscanw Y Y Y
|
||||
mvwscanw Y Y Y
|
||||
vwscanw Y Y Y
|
||||
vw_scanw Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef HAVE_VSSCANF
|
||||
# include <stdlib.h>
|
||||
# include <ctype.h>
|
||||
# include <limits.h>
|
||||
|
||||
static int _pdc_vsscanf(const char *, const char *, va_list);
|
||||
|
||||
# define vsscanf _pdc_vsscanf
|
||||
#endif
|
||||
|
||||
int vwscanw(WINDOW *win, const char *fmt, va_list varglist)
|
||||
{
|
||||
char scanbuf[256];
|
||||
|
||||
PDC_LOG(("vwscanw() - called\n"));
|
||||
|
||||
if (wgetnstr(win, scanbuf, 255) == ERR)
|
||||
return ERR;
|
||||
|
||||
return vsscanf(scanbuf, fmt, varglist);
|
||||
}
|
||||
|
||||
int scanw(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int retval;
|
||||
|
||||
PDC_LOG(("scanw() - called\n"));
|
||||
|
||||
va_start(args, fmt);
|
||||
retval = vwscanw(stdscr, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int wscanw(WINDOW *win, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int retval;
|
||||
|
||||
PDC_LOG(("wscanw() - called\n"));
|
||||
|
||||
va_start(args, fmt);
|
||||
retval = vwscanw(win, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int mvscanw(int y, int x, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int retval;
|
||||
|
||||
PDC_LOG(("mvscanw() - called\n"));
|
||||
|
||||
if (move(y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
va_start(args, fmt);
|
||||
retval = vwscanw(stdscr, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int mvwscanw(WINDOW *win, int y, int x, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int retval;
|
||||
|
||||
PDC_LOG(("mvscanw() - called\n"));
|
||||
|
||||
if (wmove(win, y, x) == ERR)
|
||||
return ERR;
|
||||
|
||||
va_start(args, fmt);
|
||||
retval = vwscanw(win, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int vw_scanw(WINDOW *win, const char *fmt, va_list varglist)
|
||||
{
|
||||
PDC_LOG(("vw_scanw() - called\n"));
|
||||
|
||||
return vwscanw(win, fmt, varglist);
|
||||
}
|
||||
|
||||
#ifndef HAVE_VSSCANF
|
||||
|
||||
/* _pdc_vsscanf() - Internal routine to parse and format an input
|
||||
buffer. It scans a series of input fields; each field is formatted
|
||||
according to a supplied format string and the formatted input is
|
||||
stored in the variable number of addresses passed. Returns the number
|
||||
of input fields or EOF on error.
|
||||
|
||||
Don't compile this unless required. Some compilers (at least Borland
|
||||
C++ 3.0) have to link with math libraries due to the use of floats.
|
||||
|
||||
Based on vsscanf.c and input.c from emx 0.8f library source,
|
||||
Copyright (c) 1990-1992 by Eberhard Mattes, who has kindly agreed to
|
||||
its inclusion in PDCurses. */
|
||||
|
||||
#define WHITE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n')
|
||||
|
||||
#define NEXT(x) \
|
||||
do { \
|
||||
x = *buf++; \
|
||||
if (!x) \
|
||||
return (count ? count : EOF); \
|
||||
++chars; \
|
||||
} while (0)
|
||||
|
||||
#define UNGETC() \
|
||||
do { \
|
||||
--buf; --chars; \
|
||||
} while (0)
|
||||
|
||||
static int _pdc_vsscanf(const char *buf, const char *fmt, va_list arg_ptr)
|
||||
{
|
||||
int count, chars, c, width, radix, d, i;
|
||||
int *int_ptr;
|
||||
long *long_ptr;
|
||||
short *short_ptr;
|
||||
char *char_ptr;
|
||||
unsigned char f;
|
||||
char neg, assign, ok, size;
|
||||
long n;
|
||||
char map[256], end;
|
||||
double dx, dd, *dbl_ptr;
|
||||
float *flt_ptr;
|
||||
int exp;
|
||||
char eneg;
|
||||
|
||||
count = 0;
|
||||
chars = 0;
|
||||
c = 0;
|
||||
while ((f = *fmt) != 0)
|
||||
{
|
||||
if (WHITE(f))
|
||||
{
|
||||
do
|
||||
{
|
||||
++fmt;
|
||||
f = *fmt;
|
||||
}
|
||||
while (WHITE(f));
|
||||
do
|
||||
{
|
||||
c = *buf++;
|
||||
if (!c)
|
||||
{
|
||||
if (!f || count)
|
||||
return count;
|
||||
else
|
||||
return EOF;
|
||||
} else
|
||||
++chars;
|
||||
}
|
||||
while (WHITE(c));
|
||||
UNGETC();
|
||||
} else if (f != '%')
|
||||
{
|
||||
NEXT(c);
|
||||
if (c != f)
|
||||
return count;
|
||||
++fmt;
|
||||
} else
|
||||
{
|
||||
assign = TRUE;
|
||||
width = INT_MAX;
|
||||
char_ptr = NULL;
|
||||
++fmt;
|
||||
if (*fmt == '*')
|
||||
{
|
||||
assign = FALSE;
|
||||
++fmt;
|
||||
}
|
||||
if (isdigit(*fmt))
|
||||
{
|
||||
width = 0;
|
||||
while (isdigit(*fmt))
|
||||
width = width * 10 + (*fmt++ - '0');
|
||||
if (!width)
|
||||
width = INT_MAX;
|
||||
}
|
||||
size = 0;
|
||||
if (*fmt == 'h' || *fmt == 'l')
|
||||
size = *fmt++;
|
||||
f = *fmt;
|
||||
switch (f)
|
||||
{
|
||||
case 'c':
|
||||
if (width == INT_MAX)
|
||||
width = 1;
|
||||
if (assign)
|
||||
char_ptr = va_arg(arg_ptr, char *);
|
||||
while (width > 0)
|
||||
{
|
||||
--width;
|
||||
NEXT(c);
|
||||
if (assign)
|
||||
{
|
||||
*char_ptr++ = (char) c;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
memset(map, 0, 256);
|
||||
end = 0;
|
||||
++fmt;
|
||||
if (*fmt == '^')
|
||||
{
|
||||
++fmt;
|
||||
end = 1;
|
||||
}
|
||||
i = 0;
|
||||
for (;;)
|
||||
{
|
||||
f = (unsigned char) *fmt;
|
||||
switch (f)
|
||||
{
|
||||
case 0:
|
||||
/* avoid skipping past 0 */
|
||||
--fmt;
|
||||
NEXT(c);
|
||||
goto string;
|
||||
case ']':
|
||||
if (i > 0)
|
||||
{
|
||||
NEXT(c);
|
||||
goto string;
|
||||
}
|
||||
/* no break */
|
||||
default:
|
||||
if (fmt[1] == '-' && fmt[2]
|
||||
&& f < (unsigned char)fmt[2])
|
||||
{
|
||||
memset(map + f, 1, (unsigned char)fmt[2] - f);
|
||||
fmt += 2;
|
||||
}
|
||||
else
|
||||
map[f] = 1;
|
||||
break;
|
||||
}
|
||||
++fmt;
|
||||
++i;
|
||||
}
|
||||
case 's':
|
||||
memset(map, 0, 256);
|
||||
map[' '] = 1;
|
||||
map['\n'] = 1;
|
||||
map['\r'] = 1;
|
||||
map['\t'] = 1;
|
||||
end = 1;
|
||||
do
|
||||
{
|
||||
NEXT(c);
|
||||
}
|
||||
while (WHITE(c));
|
||||
string:
|
||||
if (assign)
|
||||
char_ptr = va_arg(arg_ptr, char *);
|
||||
while (width > 0 && map[(unsigned char) c] != end)
|
||||
{
|
||||
--width;
|
||||
if (assign)
|
||||
*char_ptr++ = (char) c;
|
||||
c = *buf++;
|
||||
if (!c)
|
||||
break;
|
||||
else
|
||||
++chars;
|
||||
}
|
||||
if (assign)
|
||||
{
|
||||
*char_ptr = 0;
|
||||
++count;
|
||||
}
|
||||
if (!c)
|
||||
return count;
|
||||
else
|
||||
UNGETC();
|
||||
break;
|
||||
case 'f':
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'g':
|
||||
case 'G':
|
||||
neg = ok = FALSE;
|
||||
dx = 0.0;
|
||||
do
|
||||
{
|
||||
NEXT(c);
|
||||
}
|
||||
while (WHITE(c));
|
||||
if (c == '+')
|
||||
{
|
||||
NEXT(c);
|
||||
--width;
|
||||
} else if (c == '-')
|
||||
{
|
||||
neg = TRUE;
|
||||
NEXT(c);
|
||||
--width;
|
||||
}
|
||||
while (width > 0 && isdigit(c))
|
||||
{
|
||||
--width;
|
||||
dx = dx * 10.0 + (double) (c - '0');
|
||||
ok = TRUE;
|
||||
c = *buf++;
|
||||
if (!c)
|
||||
break;
|
||||
else
|
||||
++chars;
|
||||
}
|
||||
if (width > 0 && c == '.')
|
||||
{
|
||||
--width;
|
||||
dd = 10.0;
|
||||
NEXT(c);
|
||||
while (width > 0 && isdigit(c))
|
||||
{
|
||||
--width;
|
||||
dx += (double) (c - '0') / dd;
|
||||
dd *= 10.0;
|
||||
ok = TRUE;
|
||||
c = *buf++;
|
||||
if (!c)
|
||||
break;
|
||||
else
|
||||
++chars;
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
return count;
|
||||
if (width > 0 && (c == 'e' || c == 'E'))
|
||||
{
|
||||
eneg = FALSE;
|
||||
exp = 0;
|
||||
NEXT(c);
|
||||
--width;
|
||||
if (width > 0 && c == '+')
|
||||
{
|
||||
NEXT(c);
|
||||
--width;
|
||||
} else if (width > 0 && c == '-')
|
||||
{
|
||||
eneg = TRUE;
|
||||
NEXT(c);
|
||||
--width;
|
||||
}
|
||||
if (!(width > 0 && isdigit(c)))
|
||||
{
|
||||
UNGETC();
|
||||
return count;
|
||||
}
|
||||
while (width > 0 && isdigit(c))
|
||||
{
|
||||
--width;
|
||||
exp = exp * 10 + (c - '0');
|
||||
c = *buf++;
|
||||
if (!c)
|
||||
break;
|
||||
else
|
||||
++chars;
|
||||
}
|
||||
if (eneg)
|
||||
exp = -exp;
|
||||
while (exp > 0)
|
||||
{
|
||||
dx *= 10.0;
|
||||
--exp;
|
||||
}
|
||||
while (exp < 0)
|
||||
{
|
||||
dx /= 10.0;
|
||||
++exp;
|
||||
}
|
||||
}
|
||||
if (assign)
|
||||
{
|
||||
if (neg)
|
||||
dx = -dx;
|
||||
if (size == 'l')
|
||||
{
|
||||
dbl_ptr = va_arg(arg_ptr, double *);
|
||||
*dbl_ptr = dx;
|
||||
}
|
||||
else
|
||||
{
|
||||
flt_ptr = va_arg(arg_ptr, float *);
|
||||
*flt_ptr = (float)dx;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
if (!c)
|
||||
return count;
|
||||
else
|
||||
UNGETC();
|
||||
break;
|
||||
case 'i':
|
||||
neg = FALSE;
|
||||
radix = 10;
|
||||
do
|
||||
{
|
||||
NEXT(c);
|
||||
}
|
||||
while (WHITE(c));
|
||||
if (!(width > 0 && c == '0'))
|
||||
goto scan_complete_number;
|
||||
NEXT(c);
|
||||
--width;
|
||||
if (width > 0 && (c == 'x' || c == 'X'))
|
||||
{
|
||||
NEXT(c);
|
||||
radix = 16;
|
||||
--width;
|
||||
}
|
||||
else if (width > 0 && (c >= '0' && c <= '7'))
|
||||
radix = 8;
|
||||
goto scan_unsigned_number;
|
||||
case 'd':
|
||||
case 'u':
|
||||
case 'o':
|
||||
case 'x':
|
||||
case 'X':
|
||||
do
|
||||
{
|
||||
NEXT(c);
|
||||
}
|
||||
while (WHITE(c));
|
||||
switch (f)
|
||||
{
|
||||
case 'o':
|
||||
radix = 8;
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
radix = 16;
|
||||
break;
|
||||
default:
|
||||
radix = 10;
|
||||
break;
|
||||
}
|
||||
scan_complete_number:
|
||||
neg = FALSE;
|
||||
if (width > 0 && c == '+')
|
||||
{
|
||||
NEXT(c);
|
||||
--width;
|
||||
}
|
||||
else if (width > 0 && c == '-' && radix == 10)
|
||||
{
|
||||
neg = TRUE;
|
||||
NEXT(c);
|
||||
--width;
|
||||
}
|
||||
scan_unsigned_number:
|
||||
n = 0;
|
||||
ok = FALSE;
|
||||
while (width > 0)
|
||||
{
|
||||
--width;
|
||||
if (isdigit(c))
|
||||
d = c - '0';
|
||||
else if (isupper(c))
|
||||
d = c - 'A' + 10;
|
||||
else if (islower(c))
|
||||
d = c - 'a' + 10;
|
||||
else
|
||||
break;
|
||||
if (d < 0 || d >= radix)
|
||||
break;
|
||||
ok = TRUE;
|
||||
n = n * radix + d;
|
||||
c = *buf++;
|
||||
if (!c)
|
||||
break;
|
||||
else
|
||||
++chars;
|
||||
}
|
||||
if (!ok)
|
||||
return count;
|
||||
if (assign)
|
||||
{
|
||||
if (neg)
|
||||
n = -n;
|
||||
switch (size)
|
||||
{
|
||||
case 'h':
|
||||
short_ptr = va_arg(arg_ptr, short *);
|
||||
*short_ptr = (short) n;
|
||||
break;
|
||||
case 'l':
|
||||
long_ptr = va_arg(arg_ptr, long *);
|
||||
*long_ptr = (long) n;
|
||||
break;
|
||||
default:
|
||||
int_ptr = va_arg(arg_ptr, int *);
|
||||
*int_ptr = (int) n;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
if (!c)
|
||||
return count;
|
||||
else
|
||||
UNGETC();
|
||||
break;
|
||||
case 'n':
|
||||
if (assign)
|
||||
{
|
||||
int_ptr = va_arg(arg_ptr, int *);
|
||||
*int_ptr = chars;
|
||||
++count;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!f) /* % at end of string */
|
||||
return count;
|
||||
NEXT(c);
|
||||
if (c != f)
|
||||
return count;
|
||||
break;
|
||||
}
|
||||
++fmt;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
#endif /* HAVE_VSSCANF */
|
||||
217
pdcurses/scr_dump.c
Normal file
217
pdcurses/scr_dump.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
scr_dump
|
||||
--------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int putwin(WINDOW *win, FILE *filep);
|
||||
WINDOW *getwin(FILE *filep);
|
||||
int scr_dump(const char *filename);
|
||||
int scr_init(const char *filename);
|
||||
int scr_restore(const char *filename);
|
||||
int scr_set(const char *filename);
|
||||
|
||||
### Description
|
||||
|
||||
getwin() reads window-related data previously stored in a file by
|
||||
putwin(). It then creates and initialises a new window using that
|
||||
data.
|
||||
|
||||
putwin() writes all data associated with a window into a file, using
|
||||
an unspecified format. This information can be retrieved later using
|
||||
getwin().
|
||||
|
||||
scr_dump() writes the current contents of the virtual screen to the
|
||||
file named by filename in an unspecified format.
|
||||
|
||||
scr_restore() function sets the virtual screen to the contents of the
|
||||
file named by filename, which must have been written using
|
||||
scr_dump(). The next refresh operation restores the screen to the way
|
||||
it looked in the dump file.
|
||||
|
||||
In PDCurses, scr_init() does nothing, and scr_set() is a synonym for
|
||||
scr_restore(). Also, scr_dump() and scr_restore() save and load from
|
||||
curscr. This differs from some other implementations, where
|
||||
scr_init() works with curscr, and scr_restore() works with newscr;
|
||||
but the effect should be the same. (PDCurses has no newscr.)
|
||||
|
||||
### Return Value
|
||||
|
||||
On successful completion, getwin() returns a pointer to the window it
|
||||
created. Otherwise, it returns a null pointer. Other functions return
|
||||
OK or ERR.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
putwin Y Y Y
|
||||
getwin Y Y Y
|
||||
scr_dump Y Y -
|
||||
scr_init Y Y -
|
||||
scr_restore Y Y -
|
||||
scr_set Y Y -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DUMPVER 1 /* Should be updated whenever the WINDOW struct is
|
||||
changed */
|
||||
|
||||
int putwin(WINDOW *win, FILE *filep)
|
||||
{
|
||||
static const char *marker = "PDC";
|
||||
static const unsigned char version = DUMPVER;
|
||||
|
||||
PDC_LOG(("putwin() - called\n"));
|
||||
|
||||
/* 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;
|
||||
|
||||
/* write each line */
|
||||
|
||||
for (i = 0; i < win->_maxy && win->_y[i]; i++)
|
||||
if (!fwrite(win->_y[i], win->_maxx * sizeof(chtype), 1, filep))
|
||||
return ERR;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
return ERR;
|
||||
}
|
||||
|
||||
WINDOW *getwin(FILE *filep)
|
||||
{
|
||||
WINDOW *win;
|
||||
char marker[4];
|
||||
int i, nlines, ncols;
|
||||
|
||||
PDC_LOG(("getwin() - called\n"));
|
||||
|
||||
win = malloc(sizeof(WINDOW));
|
||||
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))
|
||||
{
|
||||
free(win);
|
||||
return (WINDOW *)NULL;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
win = PDC_makelines(win);
|
||||
if (!win)
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
/* read them */
|
||||
|
||||
for (i = 0; i < nlines; i++)
|
||||
{
|
||||
if (!fread(win->_y[i], ncols * sizeof(chtype), 1, filep))
|
||||
{
|
||||
delwin(win);
|
||||
return (WINDOW *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
touchwin(win);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
int scr_dump(const char *filename)
|
||||
{
|
||||
FILE *filep;
|
||||
|
||||
PDC_LOG(("scr_dump() - called: filename %s\n", filename));
|
||||
|
||||
if (filename && (filep = fopen(filename, "wb")) != NULL)
|
||||
{
|
||||
int result = putwin(curscr, filep);
|
||||
fclose(filep);
|
||||
return result;
|
||||
}
|
||||
|
||||
return ERR;
|
||||
}
|
||||
|
||||
int scr_init(const char *filename)
|
||||
{
|
||||
PDC_LOG(("scr_init() - called: filename %s\n", filename));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int scr_restore(const char *filename)
|
||||
{
|
||||
FILE *filep;
|
||||
|
||||
PDC_LOG(("scr_restore() - called: filename %s\n", filename));
|
||||
|
||||
if (filename && (filep = fopen(filename, "rb")) != NULL)
|
||||
{
|
||||
WINDOW *replacement = getwin(filep);
|
||||
fclose(filep);
|
||||
|
||||
if (replacement)
|
||||
{
|
||||
int result = overwrite(replacement, curscr);
|
||||
delwin(replacement);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR;
|
||||
}
|
||||
|
||||
int scr_set(const char *filename)
|
||||
{
|
||||
PDC_LOG(("scr_set() - called: filename %s\n", filename));
|
||||
|
||||
return scr_restore(filename);
|
||||
}
|
||||
101
pdcurses/scroll.c
Normal file
101
pdcurses/scroll.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
scroll
|
||||
------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int scroll(WINDOW *win);
|
||||
int scrl(int n);
|
||||
int wscrl(WINDOW *win, int n);
|
||||
|
||||
### Description
|
||||
|
||||
scroll() causes the window to scroll up one line. This involves
|
||||
moving the lines in the window data strcture.
|
||||
|
||||
With a positive n, scrl() and wscrl() scroll the window up n lines
|
||||
(line i + n becomes i); otherwise they scroll the window down n
|
||||
lines.
|
||||
|
||||
For these functions to work, scrolling must be enabled via
|
||||
scrollok(). Note also that scrolling is not allowed if the supplied
|
||||
window is a pad.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
scroll Y Y Y
|
||||
scrl Y Y Y
|
||||
wscrl Y Y Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int wscrl(WINDOW *win, int n)
|
||||
{
|
||||
int i, l, dir, start, end;
|
||||
chtype blank, *temp;
|
||||
|
||||
/* Check if window scrolls. Valid for window AND pad */
|
||||
|
||||
if (!win || !win->_scroll || !n)
|
||||
return ERR;
|
||||
|
||||
blank = win->_bkgd;
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
start = win->_tmarg;
|
||||
end = win->_bmarg;
|
||||
dir = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = win->_bmarg;
|
||||
end = win->_tmarg;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
for (l = 0; l < (n * dir); l++)
|
||||
{
|
||||
temp = win->_y[start];
|
||||
|
||||
/* re-arrange line pointers */
|
||||
|
||||
for (i = start; i != end; i += dir)
|
||||
win->_y[i] = win->_y[i + dir];
|
||||
|
||||
win->_y[end] = temp;
|
||||
|
||||
/* make a blank line */
|
||||
|
||||
for (i = 0; i < win->_maxx; i++)
|
||||
*temp++ = blank;
|
||||
}
|
||||
|
||||
touchline(win, win->_tmarg, win->_bmarg - win->_tmarg + 1);
|
||||
|
||||
PDC_sync(win);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int scrl(int n)
|
||||
{
|
||||
PDC_LOG(("scrl() - called\n"));
|
||||
|
||||
return wscrl(stdscr, n);
|
||||
}
|
||||
|
||||
int scroll(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("scroll() - called\n"));
|
||||
|
||||
return wscrl(win, 1);
|
||||
}
|
||||
671
pdcurses/slk.c
Normal file
671
pdcurses/slk.c
Normal file
@@ -0,0 +1,671 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
slk
|
||||
---
|
||||
|
||||
### Synopsis
|
||||
|
||||
int slk_init(int fmt);
|
||||
int slk_set(int labnum, const char *label, int justify);
|
||||
int slk_refresh(void);
|
||||
int slk_noutrefresh(void);
|
||||
char *slk_label(int labnum);
|
||||
int slk_clear(void);
|
||||
int slk_restore(void);
|
||||
int slk_touch(void);
|
||||
int slk_attron(const chtype attrs);
|
||||
int slk_attr_on(const attr_t attrs, void *opts);
|
||||
int slk_attrset(const chtype attrs);
|
||||
int slk_attr_set(const attr_t attrs, short color_pair, void *opts);
|
||||
int slk_attroff(const chtype attrs);
|
||||
int slk_attr_off(const attr_t attrs, void *opts);
|
||||
int slk_color(short color_pair);
|
||||
|
||||
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)
|
||||
|
||||
### Description
|
||||
|
||||
These functions manipulate a window that contain Soft Label Keys
|
||||
(SLK). To use the SLK functions, a call to slk_init() must be made
|
||||
BEFORE initscr() or newterm(). slk_init() removes 1 or 2 lines from
|
||||
the useable screen, depending on the format selected.
|
||||
|
||||
The line(s) removed from the screen are used as a separate window, in
|
||||
which SLKs are displayed.
|
||||
|
||||
slk_init() requires a single parameter which describes the format of
|
||||
the SLKs as follows:
|
||||
|
||||
0 3-2-3 format
|
||||
1 4-4 format
|
||||
2 4-4-4 format (ncurses extension)
|
||||
3 4-4-4 format with index line (ncurses extension)
|
||||
2 lines used
|
||||
55 5-5 format (pdcurses format)
|
||||
|
||||
slk_refresh(), slk_noutrefresh() and slk_touch() are analogous to
|
||||
refresh(), noutrefresh() and touch().
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
slk_init Y Y Y
|
||||
slk_set Y Y Y
|
||||
slk_refresh Y Y Y
|
||||
slk_noutrefresh Y Y Y
|
||||
slk_label Y Y Y
|
||||
slk_clear Y Y Y
|
||||
slk_restore Y Y Y
|
||||
slk_touch Y Y Y
|
||||
slk_attron Y Y Y
|
||||
slk_attrset Y Y Y
|
||||
slk_attroff Y Y Y
|
||||
slk_attr_on Y Y Y
|
||||
slk_attr_set Y Y Y
|
||||
slk_attr_off Y Y Y
|
||||
slk_wset Y Y Y
|
||||
PDC_mouse_in_slk - - -
|
||||
PDC_slk_free - - -
|
||||
PDC_slk_initialize - - -
|
||||
slk_wlabel - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
enum { LABEL_NORMAL = 8, LABEL_EXTENDED = 10, LABEL_NCURSES_EXTENDED = 12 };
|
||||
|
||||
static int label_length = 0;
|
||||
static int labels = 0;
|
||||
static int label_fmt = 0;
|
||||
static int label_line = 0;
|
||||
static bool hidden = FALSE;
|
||||
|
||||
static struct SLK {
|
||||
chtype label[32];
|
||||
int len;
|
||||
int format;
|
||||
int start_col;
|
||||
} *slk = (struct SLK *)NULL;
|
||||
|
||||
/* slk_init() is the slk initialization routine.
|
||||
This must be called before initscr().
|
||||
|
||||
label_fmt = 0, 1 or 55.
|
||||
0 = 3-2-3 format
|
||||
1 = 4 - 4 format
|
||||
2 = 4-4-4 format (ncurses extension for PC 12 function keys)
|
||||
3 = 4-4-4 format (ncurses extension for PC 12 function keys -
|
||||
with index line)
|
||||
55 = 5 - 5 format (extended for PC, 10 function keys) */
|
||||
|
||||
int slk_init(int fmt)
|
||||
{
|
||||
PDC_LOG(("slk_init() - called\n"));
|
||||
|
||||
if (SP)
|
||||
return ERR;
|
||||
|
||||
switch (fmt)
|
||||
{
|
||||
case 0: /* 3 - 2 - 3 */
|
||||
labels = LABEL_NORMAL;
|
||||
break;
|
||||
|
||||
case 1: /* 4 - 4 */
|
||||
labels = LABEL_NORMAL;
|
||||
break;
|
||||
|
||||
case 2: /* 4 4 4 */
|
||||
labels = LABEL_NCURSES_EXTENDED;
|
||||
break;
|
||||
|
||||
case 3: /* 4 4 4 with index */
|
||||
labels = LABEL_NCURSES_EXTENDED;
|
||||
break;
|
||||
|
||||
case 55: /* 5 - 5 */
|
||||
labels = LABEL_EXTENDED;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERR;
|
||||
}
|
||||
|
||||
label_fmt = fmt;
|
||||
|
||||
slk = calloc(labels, sizeof(struct SLK));
|
||||
|
||||
if (!slk)
|
||||
labels = 0;
|
||||
|
||||
return slk ? OK : ERR;
|
||||
}
|
||||
|
||||
/* draw a single button */
|
||||
|
||||
static void _drawone(int num)
|
||||
{
|
||||
int i, col, slen;
|
||||
|
||||
if (hidden)
|
||||
return;
|
||||
|
||||
slen = slk[num].len;
|
||||
|
||||
switch (slk[num].format)
|
||||
{
|
||||
case 0: /* LEFT */
|
||||
col = 0;
|
||||
break;
|
||||
|
||||
case 1: /* CENTER */
|
||||
col = (label_length - slen) / 2;
|
||||
|
||||
if (col + slen > label_length)
|
||||
--col;
|
||||
break;
|
||||
|
||||
default: /* RIGHT */
|
||||
col = label_length - slen;
|
||||
}
|
||||
|
||||
wmove(SP->slk_winptr, label_line, slk[num].start_col);
|
||||
|
||||
for (i = 0; i < label_length; ++i)
|
||||
waddch(SP->slk_winptr, (i >= col && i < (col + slen)) ?
|
||||
slk[num].label[i - col] : ' ');
|
||||
}
|
||||
|
||||
/* redraw each button */
|
||||
|
||||
static void _redraw(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < labels; ++i)
|
||||
_drawone(i);
|
||||
}
|
||||
|
||||
/* slk_set() Used to set a slk label to a string.
|
||||
|
||||
labnum = 1 - 8 (or 10) (number of the label)
|
||||
label = string (8 or 7 bytes total), or NULL
|
||||
justify = 0 : left, 1 : center, 2 : right */
|
||||
|
||||
int slk_set(int labnum, const char *label, int justify)
|
||||
{
|
||||
#ifdef PDC_WIDE
|
||||
wchar_t wlabel[32];
|
||||
|
||||
PDC_mbstowcs(wlabel, label, 31);
|
||||
return slk_wset(labnum, wlabel, justify);
|
||||
#else
|
||||
PDC_LOG(("slk_set() - called\n"));
|
||||
|
||||
if (labnum < 1 || labnum > labels || justify < 0 || justify > 2)
|
||||
return ERR;
|
||||
|
||||
labnum--;
|
||||
|
||||
if (!label || !(*label))
|
||||
{
|
||||
/* Clear the label */
|
||||
|
||||
*slk[labnum].label = 0;
|
||||
slk[labnum].format = 0;
|
||||
slk[labnum].len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, j = 0;
|
||||
|
||||
/* Skip leading spaces */
|
||||
|
||||
while (label[j] == ' ')
|
||||
j++;
|
||||
|
||||
/* Copy it */
|
||||
|
||||
for (i = 0; i < label_length; i++)
|
||||
{
|
||||
chtype ch = label[i + j];
|
||||
|
||||
slk[labnum].label[i] = ch;
|
||||
|
||||
if (!ch)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Drop trailing spaces */
|
||||
|
||||
while ((i + j) && (label[i + j - 1] == ' '))
|
||||
i--;
|
||||
|
||||
slk[labnum].label[i] = 0;
|
||||
slk[labnum].format = justify;
|
||||
slk[labnum].len = i;
|
||||
}
|
||||
|
||||
_drawone(labnum);
|
||||
|
||||
return OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
int slk_refresh(void)
|
||||
{
|
||||
PDC_LOG(("slk_refresh() - called\n"));
|
||||
|
||||
return (slk_noutrefresh() == ERR) ? ERR : doupdate();
|
||||
}
|
||||
|
||||
int slk_noutrefresh(void)
|
||||
{
|
||||
PDC_LOG(("slk_noutrefresh() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
return wnoutrefresh(SP->slk_winptr);
|
||||
}
|
||||
|
||||
char *slk_label(int labnum)
|
||||
{
|
||||
static char temp[33];
|
||||
#ifdef PDC_WIDE
|
||||
wchar_t *wtemp = slk_wlabel(labnum);
|
||||
|
||||
PDC_wcstombs(temp, wtemp, 32);
|
||||
#else
|
||||
chtype *p;
|
||||
int i;
|
||||
|
||||
PDC_LOG(("slk_label() - called\n"));
|
||||
|
||||
if (labnum < 1 || labnum > labels)
|
||||
return (char *)0;
|
||||
|
||||
for (i = 0, p = slk[labnum - 1].label; *p; i++)
|
||||
temp[i] = *p++;
|
||||
|
||||
temp[i] = '\0';
|
||||
#endif
|
||||
return temp;
|
||||
}
|
||||
|
||||
int slk_clear(void)
|
||||
{
|
||||
PDC_LOG(("slk_clear() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
hidden = TRUE;
|
||||
werase(SP->slk_winptr);
|
||||
return wrefresh(SP->slk_winptr);
|
||||
}
|
||||
|
||||
int slk_restore(void)
|
||||
{
|
||||
PDC_LOG(("slk_restore() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
hidden = FALSE;
|
||||
_redraw();
|
||||
return wrefresh(SP->slk_winptr);
|
||||
}
|
||||
|
||||
int slk_touch(void)
|
||||
{
|
||||
PDC_LOG(("slk_touch() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
return touchwin(SP->slk_winptr);
|
||||
}
|
||||
|
||||
int slk_attron(const chtype attrs)
|
||||
{
|
||||
int rc;
|
||||
|
||||
PDC_LOG(("slk_attron() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
rc = wattron(SP->slk_winptr, attrs);
|
||||
_redraw();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int slk_attr_on(const attr_t attrs, void *opts)
|
||||
{
|
||||
PDC_LOG(("slk_attr_on() - called\n"));
|
||||
|
||||
return slk_attron(attrs);
|
||||
}
|
||||
|
||||
int slk_attroff(const chtype attrs)
|
||||
{
|
||||
int rc;
|
||||
|
||||
PDC_LOG(("slk_attroff() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
rc = wattroff(SP->slk_winptr, attrs);
|
||||
_redraw();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int slk_attr_off(const attr_t attrs, void *opts)
|
||||
{
|
||||
PDC_LOG(("slk_attr_off() - called\n"));
|
||||
|
||||
return slk_attroff(attrs);
|
||||
}
|
||||
|
||||
int slk_attrset(const chtype attrs)
|
||||
{
|
||||
int rc;
|
||||
|
||||
PDC_LOG(("slk_attrset() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
rc = wattrset(SP->slk_winptr, attrs);
|
||||
_redraw();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int slk_color(short color_pair)
|
||||
{
|
||||
int rc;
|
||||
|
||||
PDC_LOG(("slk_color() - called\n"));
|
||||
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
rc = wcolor_set(SP->slk_winptr, color_pair, NULL);
|
||||
_redraw();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int slk_attr_set(const attr_t attrs, short color_pair, void *opts)
|
||||
{
|
||||
PDC_LOG(("slk_attr_set() - called\n"));
|
||||
|
||||
return slk_attrset(attrs | COLOR_PAIR(color_pair));
|
||||
}
|
||||
|
||||
static void _slk_calc(void)
|
||||
{
|
||||
int i, center, col = 0;
|
||||
label_length = COLS / labels;
|
||||
|
||||
if (label_length > 31)
|
||||
label_length = 31;
|
||||
|
||||
switch (label_fmt)
|
||||
{
|
||||
case 0: /* 3 - 2 - 3 F-Key layout */
|
||||
|
||||
--label_length;
|
||||
|
||||
slk[0].start_col = col;
|
||||
slk[1].start_col = (col += label_length);
|
||||
slk[2].start_col = (col += label_length);
|
||||
|
||||
center = COLS / 2;
|
||||
|
||||
slk[3].start_col = center - label_length + 1;
|
||||
slk[4].start_col = center + 1;
|
||||
|
||||
col = COLS - (label_length * 3) + 1;
|
||||
|
||||
slk[5].start_col = col;
|
||||
slk[6].start_col = (col += label_length);
|
||||
slk[7].start_col = (col += label_length);
|
||||
break;
|
||||
|
||||
case 1: /* 4 - 4 F-Key layout */
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
slk[i].start_col = col;
|
||||
col += label_length;
|
||||
|
||||
if (i == 3)
|
||||
col = COLS - (label_length * 4) + 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2: /* 4 4 4 F-Key layout */
|
||||
case 3: /* 4 4 4 F-Key layout with index */
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
slk[i].start_col = col;
|
||||
col += label_length;
|
||||
}
|
||||
|
||||
center = COLS / 2;
|
||||
|
||||
slk[4].start_col = center - (label_length * 2) + 1;
|
||||
slk[5].start_col = center - label_length + 1;
|
||||
slk[6].start_col = center + 1;
|
||||
slk[7].start_col = center + label_length + 1;
|
||||
|
||||
col = COLS - (label_length * 4) + 1;
|
||||
|
||||
for (i = 8; i < 12; i++)
|
||||
{
|
||||
slk[i].start_col = col;
|
||||
col += label_length;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default: /* 5 - 5 F-Key layout */
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
slk[i].start_col = col;
|
||||
col += label_length;
|
||||
|
||||
if (i == 4)
|
||||
col = COLS - (label_length * 5) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
--label_length;
|
||||
|
||||
/* make sure labels are all in window */
|
||||
|
||||
_redraw();
|
||||
}
|
||||
|
||||
void PDC_slk_initialize(void)
|
||||
{
|
||||
if (slk)
|
||||
{
|
||||
if (label_fmt == 3)
|
||||
{
|
||||
SP->slklines = 2;
|
||||
label_line = 1;
|
||||
}
|
||||
else
|
||||
SP->slklines = 1;
|
||||
|
||||
if (!SP->slk_winptr)
|
||||
{
|
||||
SP->slk_winptr = newwin(SP->slklines, COLS,
|
||||
LINES - SP->slklines, 0);
|
||||
if (!SP->slk_winptr)
|
||||
return;
|
||||
|
||||
wattrset(SP->slk_winptr, A_REVERSE);
|
||||
}
|
||||
|
||||
_slk_calc();
|
||||
|
||||
/* if we have an index line, display it now */
|
||||
|
||||
if (label_fmt == 3)
|
||||
{
|
||||
chtype save_attr;
|
||||
int i;
|
||||
|
||||
save_attr = SP->slk_winptr->_attrs;
|
||||
wattrset(SP->slk_winptr, A_NORMAL);
|
||||
wmove(SP->slk_winptr, 0, 0);
|
||||
whline(SP->slk_winptr, 0, COLS);
|
||||
|
||||
for (i = 0; i < labels; i++)
|
||||
mvwprintw(SP->slk_winptr, 0, slk[i].start_col, "F%d", i + 1);
|
||||
|
||||
SP->slk_winptr->_attrs = save_attr;
|
||||
}
|
||||
|
||||
touchwin(SP->slk_winptr);
|
||||
}
|
||||
}
|
||||
|
||||
void PDC_slk_free(void)
|
||||
{
|
||||
if (slk)
|
||||
{
|
||||
if (SP->slk_winptr)
|
||||
{
|
||||
delwin(SP->slk_winptr);
|
||||
SP->slk_winptr = (WINDOW *)NULL;
|
||||
}
|
||||
|
||||
free(slk);
|
||||
slk = (struct SLK *)NULL;
|
||||
|
||||
label_length = 0;
|
||||
labels = 0;
|
||||
label_fmt = 0;
|
||||
label_line = 0;
|
||||
hidden = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int PDC_mouse_in_slk(int y, int x)
|
||||
{
|
||||
int i;
|
||||
|
||||
PDC_LOG(("PDC_mouse_in_slk() - called: y->%d x->%d\n", y, x));
|
||||
|
||||
/* If the line on which the mouse was clicked is NOT the last line
|
||||
of the screen, we are not interested in it. */
|
||||
|
||||
if (!slk || !SP->slk_winptr || (y != SP->slk_winptr->_begy + label_line))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < labels; i++)
|
||||
if (x >= slk[i].start_col && x < (slk[i].start_col + label_length))
|
||||
return i + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int slk_wset(int labnum, const wchar_t *label, int justify)
|
||||
{
|
||||
PDC_LOG(("slk_wset() - called\n"));
|
||||
|
||||
if (labnum < 1 || labnum > labels || justify < 0 || justify > 2)
|
||||
return ERR;
|
||||
|
||||
labnum--;
|
||||
|
||||
if (!label || !(*label))
|
||||
{
|
||||
/* Clear the label */
|
||||
|
||||
*slk[labnum].label = 0;
|
||||
slk[labnum].format = 0;
|
||||
slk[labnum].len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, j = 0;
|
||||
|
||||
/* Skip leading spaces */
|
||||
|
||||
while (label[j] == L' ')
|
||||
j++;
|
||||
|
||||
/* Copy it */
|
||||
|
||||
for (i = 0; i < label_length; i++)
|
||||
{
|
||||
chtype ch = label[i + j];
|
||||
|
||||
slk[labnum].label[i] = ch;
|
||||
|
||||
if (!ch)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Drop trailing spaces */
|
||||
|
||||
while ((i + j) && (label[i + j - 1] == L' '))
|
||||
i--;
|
||||
|
||||
slk[labnum].label[i] = 0;
|
||||
slk[labnum].format = justify;
|
||||
slk[labnum].len = i;
|
||||
}
|
||||
|
||||
_drawone(labnum);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
wchar_t *slk_wlabel(int labnum)
|
||||
{
|
||||
static wchar_t temp[33];
|
||||
chtype *p;
|
||||
int i;
|
||||
|
||||
PDC_LOG(("slk_wlabel() - called\n"));
|
||||
|
||||
if (labnum < 1 || labnum > labels)
|
||||
return (wchar_t *)0;
|
||||
|
||||
for (i = 0, p = slk[labnum - 1].label; *p; i++)
|
||||
temp[i] = *p++;
|
||||
|
||||
temp[i] = '\0';
|
||||
|
||||
return temp;
|
||||
}
|
||||
#endif
|
||||
172
pdcurses/termattr.c
Normal file
172
pdcurses/termattr.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
termattr
|
||||
--------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int baudrate(void);
|
||||
char erasechar(void);
|
||||
bool has_ic(void);
|
||||
bool has_il(void);
|
||||
char killchar(void);
|
||||
char *longname(void);
|
||||
chtype termattrs(void);
|
||||
attr_t term_attrs(void);
|
||||
char *termname(void);
|
||||
|
||||
int erasewchar(wchar_t *ch);
|
||||
int killwchar(wchar_t *ch);
|
||||
|
||||
char wordchar(void);
|
||||
|
||||
### Description
|
||||
|
||||
baudrate() is supposed to return the output speed of the terminal. In
|
||||
PDCurses, it simply returns INT_MAX.
|
||||
|
||||
has_ic and has_il() return TRUE. These functions have meaning in some
|
||||
other implementations of curses.
|
||||
|
||||
erasechar() and killchar() return ^H and ^U, respectively -- the
|
||||
ERASE and KILL characters. In other curses implementations, these may
|
||||
vary by terminal type. erasewchar() and killwchar() are the wide-
|
||||
character versions; they take a pointer to a location in which to
|
||||
store the character, and return OK or ERR.
|
||||
|
||||
longname() returns a pointer to a static area containing a verbose
|
||||
description of the current terminal. The maximum length of the string
|
||||
is 128 characters. It is defined only after the call to initscr() or
|
||||
newterm().
|
||||
|
||||
termname() returns a pointer to a static area containing a short
|
||||
description of the current terminal (14 characters).
|
||||
|
||||
termattrs() returns a logical OR of all video attributes supported by
|
||||
the terminal.
|
||||
|
||||
wordchar() is a PDCurses extension of the concept behind the
|
||||
functions erasechar() and killchar(), returning the "delete word"
|
||||
character, ^W.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
baudrate Y Y Y
|
||||
erasechar Y Y Y
|
||||
has_ic Y Y Y
|
||||
has_il Y Y Y
|
||||
killchar Y Y Y
|
||||
longname Y Y Y
|
||||
termattrs Y Y Y
|
||||
termname Y Y Y
|
||||
erasewchar Y Y Y
|
||||
killwchar Y Y Y
|
||||
term_attrs Y Y Y
|
||||
wordchar - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
int baudrate(void)
|
||||
{
|
||||
PDC_LOG(("baudrate() - called\n"));
|
||||
|
||||
return INT_MAX;
|
||||
}
|
||||
|
||||
char erasechar(void)
|
||||
{
|
||||
PDC_LOG(("erasechar() - called\n"));
|
||||
|
||||
return _ECHAR; /* character delete char (^H) */
|
||||
}
|
||||
|
||||
bool has_ic(void)
|
||||
{
|
||||
PDC_LOG(("has_ic() - called\n"));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool has_il(void)
|
||||
{
|
||||
PDC_LOG(("has_il() - called\n"));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char killchar(void)
|
||||
{
|
||||
PDC_LOG(("killchar() - called\n"));
|
||||
|
||||
return _DLCHAR; /* line delete char (^U) */
|
||||
}
|
||||
|
||||
char *longname(void)
|
||||
{
|
||||
PDC_LOG(("longname() - called\n"));
|
||||
|
||||
return ttytype + 9; /* skip "pdcurses|" */
|
||||
}
|
||||
|
||||
chtype termattrs(void)
|
||||
{
|
||||
PDC_LOG(("termattrs() - called\n"));
|
||||
|
||||
return SP ? SP->termattrs : (chtype)0;
|
||||
}
|
||||
|
||||
attr_t term_attrs(void)
|
||||
{
|
||||
PDC_LOG(("term_attrs() - called\n"));
|
||||
|
||||
return SP ? SP->termattrs : (attr_t)0;
|
||||
}
|
||||
|
||||
char *termname(void)
|
||||
{
|
||||
static char _termname[14] = "pdcurses";
|
||||
|
||||
PDC_LOG(("termname() - called\n"));
|
||||
|
||||
return _termname;
|
||||
}
|
||||
|
||||
char wordchar(void)
|
||||
{
|
||||
PDC_LOG(("wordchar() - called\n"));
|
||||
|
||||
return _DWCHAR; /* word delete char */
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int erasewchar(wchar_t *ch)
|
||||
{
|
||||
PDC_LOG(("erasewchar() - called\n"));
|
||||
|
||||
if (!ch)
|
||||
return ERR;
|
||||
|
||||
*ch = (wchar_t)_ECHAR;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int killwchar(wchar_t *ch)
|
||||
{
|
||||
PDC_LOG(("killwchar() - called\n"));
|
||||
|
||||
if (!ch)
|
||||
return ERR;
|
||||
|
||||
*ch = (wchar_t)_DLCHAR;
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
199
pdcurses/touch.c
Normal file
199
pdcurses/touch.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
touch
|
||||
-----
|
||||
|
||||
### Synopsis
|
||||
|
||||
int touchwin(WINDOW *win);
|
||||
int touchline(WINDOW *win, int start, int count);
|
||||
int untouchwin(WINDOW *win);
|
||||
int wtouchln(WINDOW *win, int y, int n, int changed);
|
||||
bool is_linetouched(WINDOW *win, int line);
|
||||
bool is_wintouched(WINDOW *win);
|
||||
|
||||
int touchoverlap(const WINDOW *win1, WINDOW *win2);
|
||||
|
||||
### Description
|
||||
|
||||
touchwin() and touchline() throw away all information about which
|
||||
parts of the window have been touched, pretending that the entire
|
||||
window has been drawn on. This is sometimes necessary when using
|
||||
overlapping windows, since a change to one window will affect the
|
||||
other window, but the records of which lines have been changed in the
|
||||
other window will not reflect the change.
|
||||
|
||||
untouchwin() marks all lines in the window as unchanged since the
|
||||
last call to wrefresh().
|
||||
|
||||
wtouchln() makes n lines in the window, starting at line y, look as
|
||||
if they have (changed == 1) or have not (changed == 0) been changed
|
||||
since the last call to wrefresh().
|
||||
|
||||
is_linetouched() returns TRUE if the specified line in the specified
|
||||
window has been changed since the last call to wrefresh().
|
||||
|
||||
is_wintouched() returns TRUE if the specified window has been changed
|
||||
since the last call to wrefresh().
|
||||
|
||||
touchoverlap(win1, win2) marks the portion of win2 which overlaps
|
||||
with win1 as modified.
|
||||
|
||||
### Return Value
|
||||
|
||||
All functions return OK on success and ERR on error except
|
||||
is_wintouched() and is_linetouched().
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
touchwin Y Y Y
|
||||
touchline Y Y Y
|
||||
untouchwin Y Y Y
|
||||
wtouchln Y Y Y
|
||||
is_linetouched Y Y Y
|
||||
is_wintouched Y Y Y
|
||||
touchoverlap - - Y
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int touchwin(WINDOW *win)
|
||||
{
|
||||
int i;
|
||||
|
||||
PDC_LOG(("touchwin() - called: Win=%x\n", win));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
for (i = 0; i < win->_maxy; i++)
|
||||
{
|
||||
win->_firstch[i] = 0;
|
||||
win->_lastch[i] = win->_maxx - 1;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int touchline(WINDOW *win, int start, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
PDC_LOG(("touchline() - called: win=%p start %d count %d\n",
|
||||
win, start, count));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int untouchwin(WINDOW *win)
|
||||
{
|
||||
int i;
|
||||
|
||||
PDC_LOG(("untouchwin() - called: win=%p", win));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
for (i = 0; i < win->_maxy; i++)
|
||||
{
|
||||
win->_firstch[i] = _NO_CHANGE;
|
||||
win->_lastch[i] = _NO_CHANGE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int wtouchln(WINDOW *win, int y, int n, int changed)
|
||||
{
|
||||
int i;
|
||||
|
||||
PDC_LOG(("wtouchln() - called: win=%p y=%d n=%d changed=%d\n",
|
||||
win, y, n, changed));
|
||||
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
win->_firstch[i] = _NO_CHANGE;
|
||||
win->_lastch[i] = _NO_CHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
bool is_linetouched(WINDOW *win, int line)
|
||||
{
|
||||
PDC_LOG(("is_linetouched() - called: win=%p line=%d\n", win, line));
|
||||
|
||||
if (!win || line > win->_maxy || line < 0)
|
||||
return FALSE;
|
||||
|
||||
return (win->_firstch[line] != _NO_CHANGE) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
bool is_wintouched(WINDOW *win)
|
||||
{
|
||||
int i;
|
||||
|
||||
PDC_LOG(("is_wintouched() - called: win=%p\n", win));
|
||||
|
||||
if (win)
|
||||
for (i = 0; i < win->_maxy; i++)
|
||||
if (win->_firstch[i] != _NO_CHANGE)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int touchoverlap(const WINDOW *win1, WINDOW *win2)
|
||||
{
|
||||
int y, endy, endx, starty, startx;
|
||||
|
||||
PDC_LOG(("touchoverlap() - called: win1=%p win2=%p\n", win1, win2));
|
||||
|
||||
if (!win1 || !win2)
|
||||
return ERR;
|
||||
|
||||
starty = max(win1->_begy, win2->_begy);
|
||||
startx = max(win1->_begx, win2->_begx);
|
||||
endy = min(win1->_maxy + win1->_begy, win2->_maxy + win2->_begy);
|
||||
endx = min(win1->_maxx + win1->_begx, win2->_maxx + win2->_begx);
|
||||
|
||||
if (starty >= endy || startx >= endx)
|
||||
return OK;
|
||||
|
||||
starty -= win2->_begy;
|
||||
startx -= win2->_begx;
|
||||
endy -= win2->_begy;
|
||||
endx -= win2->_begx;
|
||||
endx -= 1;
|
||||
|
||||
for (y = starty; y < endy; y++)
|
||||
{
|
||||
win2->_firstch[y] = startx;
|
||||
win2->_lastch[y] = endx;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
308
pdcurses/util.c
Normal file
308
pdcurses/util.c
Normal file
@@ -0,0 +1,308 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
util
|
||||
----
|
||||
|
||||
### Synopsis
|
||||
|
||||
char *unctrl(chtype c);
|
||||
void filter(void);
|
||||
void use_env(bool x);
|
||||
int delay_output(int ms);
|
||||
|
||||
int getcchar(const cchar_t *wcval, wchar_t *wch, attr_t *attrs,
|
||||
short *color_pair, void *opts);
|
||||
int setcchar(cchar_t *wcval, const wchar_t *wch, const attr_t attrs,
|
||||
short color_pair, const void *opts);
|
||||
wchar_t *wunctrl(cchar_t *wc);
|
||||
|
||||
int PDC_mbtowc(wchar_t *pwc, const char *s, size_t n);
|
||||
size_t PDC_mbstowcs(wchar_t *dest, const char *src, size_t n);
|
||||
size_t PDC_wcstombs(char *dest, const wchar_t *src, size_t n);
|
||||
|
||||
### Description
|
||||
|
||||
unctrl() expands the text portion of the chtype c into a printable
|
||||
string. Control characters are changed to the "^X" notation; others
|
||||
are passed through. wunctrl() is the wide-character version of the
|
||||
function.
|
||||
|
||||
filter() and use_env() are no-ops in PDCurses.
|
||||
|
||||
delay_output() inserts an ms millisecond pause in output.
|
||||
|
||||
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.
|
||||
|
||||
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).
|
||||
|
||||
### Return Value
|
||||
|
||||
wunctrl() returns NULL on failure. delay_output() always returns OK.
|
||||
|
||||
getcchar() returns the number of wide characters wcval points to when
|
||||
wch is NULL; when it's not, getcchar() returns OK or ERR.
|
||||
|
||||
setcchar() returns OK or ERR.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
unctrl Y Y Y
|
||||
filter Y Y Y
|
||||
use_env Y Y Y
|
||||
delay_output Y Y Y
|
||||
getcchar Y Y Y
|
||||
setcchar Y Y Y
|
||||
wunctrl Y Y Y
|
||||
PDC_mbtowc - - -
|
||||
PDC_mbstowcs - - -
|
||||
PDC_wcstombs - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
char *unctrl(chtype c)
|
||||
{
|
||||
static char strbuf[3] = {0, 0, 0};
|
||||
|
||||
chtype ic;
|
||||
|
||||
PDC_LOG(("unctrl() - called\n"));
|
||||
|
||||
ic = c & A_CHARTEXT;
|
||||
|
||||
if (ic >= 0x20 && ic != 0x7f) /* normal characters */
|
||||
{
|
||||
strbuf[0] = (char)ic;
|
||||
strbuf[1] = '\0';
|
||||
return strbuf;
|
||||
}
|
||||
|
||||
strbuf[0] = '^'; /* '^' prefix */
|
||||
|
||||
if (ic == 0x7f) /* 0x7f == DEL */
|
||||
strbuf[1] = '?';
|
||||
else /* other control */
|
||||
strbuf[1] = (char)(ic + '@');
|
||||
|
||||
return strbuf;
|
||||
}
|
||||
|
||||
void filter(void)
|
||||
{
|
||||
PDC_LOG(("filter() - called\n"));
|
||||
}
|
||||
|
||||
void use_env(bool x)
|
||||
{
|
||||
PDC_LOG(("use_env() - called: x %d\n", x));
|
||||
}
|
||||
|
||||
int delay_output(int ms)
|
||||
{
|
||||
PDC_LOG(("delay_output() - called: ms %d\n", ms));
|
||||
|
||||
return napms(ms);
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int getcchar(const cchar_t *wcval, wchar_t *wch, attr_t *attrs,
|
||||
short *color_pair, void *opts)
|
||||
{
|
||||
if (!wcval)
|
||||
return ERR;
|
||||
|
||||
if (wch)
|
||||
{
|
||||
if (!attrs || !color_pair)
|
||||
return ERR;
|
||||
|
||||
*wch = (*wcval & A_CHARTEXT);
|
||||
*attrs = (*wcval & (A_ATTRIBUTES & ~A_COLOR));
|
||||
*color_pair = PAIR_NUMBER(*wcval & A_COLOR);
|
||||
|
||||
if (*wch)
|
||||
*++wch = L'\0';
|
||||
|
||||
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)
|
||||
{
|
||||
if (!wcval || !wch)
|
||||
return ERR;
|
||||
|
||||
*wcval = *wch | attrs | COLOR_PAIR(color_pair);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
wchar_t *wunctrl(cchar_t *wc)
|
||||
{
|
||||
static wchar_t strbuf[3] = {0, 0, 0};
|
||||
|
||||
cchar_t ic;
|
||||
|
||||
PDC_LOG(("wunctrl() - called\n"));
|
||||
|
||||
if (!wc)
|
||||
return NULL;
|
||||
|
||||
ic = *wc & A_CHARTEXT;
|
||||
|
||||
if (ic >= 0x20 && ic != 0x7f) /* normal characters */
|
||||
{
|
||||
strbuf[0] = (wchar_t)ic;
|
||||
strbuf[1] = L'\0';
|
||||
return strbuf;
|
||||
}
|
||||
|
||||
strbuf[0] = '^'; /* '^' prefix */
|
||||
|
||||
if (ic == 0x7f) /* 0x7f == DEL */
|
||||
strbuf[1] = '?';
|
||||
else /* other control */
|
||||
strbuf[1] = (wchar_t)(ic + '@');
|
||||
|
||||
return strbuf;
|
||||
}
|
||||
|
||||
int PDC_mbtowc(wchar_t *pwc, const char *s, size_t n)
|
||||
{
|
||||
# ifdef PDC_FORCE_UTF8
|
||||
wchar_t key;
|
||||
int i = -1;
|
||||
const unsigned char *string;
|
||||
|
||||
if (!s || (n < 1))
|
||||
return -1;
|
||||
|
||||
if (!*s)
|
||||
return 0;
|
||||
|
||||
string = (const unsigned char *)s;
|
||||
|
||||
key = string[0];
|
||||
|
||||
/* Simplistic UTF-8 decoder -- only does the BMP, minimal validation */
|
||||
|
||||
if (key & 0x80)
|
||||
{
|
||||
if ((key & 0xe0) == 0xc0)
|
||||
{
|
||||
if (1 < n)
|
||||
{
|
||||
key = ((key & 0x1f) << 6) | (string[1] & 0x3f);
|
||||
i = 2;
|
||||
}
|
||||
}
|
||||
else if ((key & 0xe0) == 0xe0)
|
||||
{
|
||||
if (2 < n)
|
||||
{
|
||||
key = ((key & 0x0f) << 12) | ((string[1] & 0x3f) << 6) |
|
||||
(string[2] & 0x3f);
|
||||
i = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
i = 1;
|
||||
|
||||
if (i)
|
||||
*pwc = key;
|
||||
|
||||
return i;
|
||||
# else
|
||||
return mbtowc(pwc, s, n);
|
||||
# endif
|
||||
}
|
||||
|
||||
size_t PDC_mbstowcs(wchar_t *dest, const char *src, size_t n)
|
||||
{
|
||||
# ifdef PDC_FORCE_UTF8
|
||||
size_t i = 0, len;
|
||||
|
||||
if (!src || !dest)
|
||||
return 0;
|
||||
|
||||
len = strlen(src);
|
||||
|
||||
while (*src && i < n)
|
||||
{
|
||||
int retval = PDC_mbtowc(dest + i, src, len);
|
||||
|
||||
if (retval < 1)
|
||||
return -1;
|
||||
|
||||
src += retval;
|
||||
len -= retval;
|
||||
i++;
|
||||
}
|
||||
# else
|
||||
size_t i = mbstowcs(dest, src, n);
|
||||
# endif
|
||||
dest[i] = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
size_t PDC_wcstombs(char *dest, const wchar_t *src, size_t n)
|
||||
{
|
||||
# ifdef PDC_FORCE_UTF8
|
||||
size_t i = 0;
|
||||
|
||||
if (!src || !dest)
|
||||
return 0;
|
||||
|
||||
while (*src && i < n)
|
||||
{
|
||||
chtype code = *src++;
|
||||
|
||||
if (code < 0x80)
|
||||
{
|
||||
dest[i] = code;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
if (code < 0x800)
|
||||
{
|
||||
dest[i] = ((code & 0x07c0) >> 6) | 0xc0;
|
||||
dest[i + 1] = (code & 0x003f) | 0x80;
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
dest[i] = ((code & 0xf000) >> 12) | 0xe0;
|
||||
dest[i + 1] = ((code & 0x0fc0) >> 6) | 0x80;
|
||||
dest[i + 2] = (code & 0x003f) | 0x80;
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
# else
|
||||
size_t i = wcstombs(dest, src, n);
|
||||
# endif
|
||||
dest[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
582
pdcurses/window.c
Normal file
582
pdcurses/window.c
Normal file
@@ -0,0 +1,582 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include <curspriv.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
window
|
||||
------
|
||||
|
||||
### Synopsis
|
||||
|
||||
WINDOW *newwin(int nlines, int ncols, int begy, int begx);
|
||||
WINDOW *derwin(WINDOW* orig, int nlines, int ncols,
|
||||
int begy, int begx);
|
||||
WINDOW *subwin(WINDOW* orig, int nlines, int ncols,
|
||||
int begy, int begx);
|
||||
WINDOW *dupwin(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);
|
||||
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
|
||||
|
||||
newwin() creates a new window with the given number of lines, nlines
|
||||
and columns, ncols. The upper left corner of the window is at line
|
||||
begy, column begx. If nlines is zero, it defaults to LINES - begy;
|
||||
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.
|
||||
|
||||
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
|
||||
screen, it is an error and the window is not moved. Moving subwindows
|
||||
is allowed.
|
||||
|
||||
subwin() creates a new subwindow within a window. The dimensions of
|
||||
the subwindow are nlines lines and ncols columns. The subwindow is at
|
||||
position (begy, begx) on the screen. This position is relative to the
|
||||
screen, and not to the window orig. Changes made to either window
|
||||
will affect both. When using this routine, you will often need to
|
||||
call touchwin() before calling wrefresh().
|
||||
|
||||
derwin() is the same as subwin(), except that begy and begx are
|
||||
relative to the origin of the window orig rather than the screen.
|
||||
There is no difference between subwindows and derived windows.
|
||||
|
||||
mvderwin() moves a derived window (or subwindow) inside its parent
|
||||
window. The screen-relative parameters of the window are not changed.
|
||||
This routine is used to display different parts of the parent window
|
||||
at the same physical position on the screen.
|
||||
|
||||
dupwin() creates an exact duplicate of the window win.
|
||||
|
||||
wsyncup() causes a touchwin() of all of the window's parents.
|
||||
|
||||
If wsyncok() is called with a second argument of TRUE, this causes a
|
||||
wsyncup() to be called every time the window is changed.
|
||||
|
||||
wcursyncup() causes the current cursor position of all of a window's
|
||||
ancestors to reflect the current cursor position of the current
|
||||
window.
|
||||
|
||||
wsyncdown() causes a touchwin() of the current window if any of its
|
||||
parent's windows have been touched.
|
||||
|
||||
resize_window() allows the user to resize an existing window. It
|
||||
returns the pointer to the new window, or NULL on failure.
|
||||
|
||||
wresize() is an ncurses-compatible wrapper for resize_window(). Note
|
||||
that, unlike ncurses, it will NOT process any subwindows of the
|
||||
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
|
||||
window, or NULL on failure. delwin(), mvwin(), mvderwin() and
|
||||
syncok() return OK or ERR. wsyncup(), wcursyncup() and wsyncdown()
|
||||
return nothing.
|
||||
|
||||
### Errors
|
||||
|
||||
It is an error to call resize_window() before calling initscr().
|
||||
Also, an error will be generated if we fail to create a newly sized
|
||||
replacement window for curscr, or stdscr. This could happen when
|
||||
increasing the window size. NOTE: If this happens, the previously
|
||||
successfully allocated windows are left alone; i.e., the resize is
|
||||
NOT cancelled for those windows.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
newwin Y Y Y
|
||||
delwin Y Y Y
|
||||
mvwin Y Y Y
|
||||
subwin Y Y Y
|
||||
derwin Y Y Y
|
||||
mvderwin Y Y Y
|
||||
dupwin Y Y Y
|
||||
wsyncup Y Y Y
|
||||
syncok Y Y 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>
|
||||
|
||||
WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx)
|
||||
{
|
||||
WINDOW *win;
|
||||
|
||||
PDC_LOG(("PDC_makenew() - called: lines %d cols %d begy %d begx %d\n",
|
||||
nlines, ncols, begy, begx));
|
||||
|
||||
/* allocate the window structure itself */
|
||||
|
||||
win = calloc(1, sizeof(WINDOW));
|
||||
if (!win)
|
||||
return win;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* initialize window variables */
|
||||
|
||||
win->_maxy = nlines; /* real max screen size */
|
||||
win->_maxx = ncols; /* real max screen size */
|
||||
win->_begy = begy;
|
||||
win->_begx = begx;
|
||||
win->_bkgd = ' '; /* wrs 4/10/93 -- initialize background to blank */
|
||||
win->_clear = (bool) ((nlines == LINES) && (ncols == COLS));
|
||||
win->_bmarg = nlines - 1;
|
||||
win->_parx = win->_pary = -1;
|
||||
|
||||
/* init to say window all changed */
|
||||
|
||||
touchwin(win);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
WINDOW *PDC_makelines(WINDOW *win)
|
||||
{
|
||||
int i, j, nlines, ncols;
|
||||
|
||||
PDC_LOG(("PDC_makelines() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
nlines = win->_maxy;
|
||||
ncols = win->_maxx;
|
||||
|
||||
for (i = 0; i < nlines; i++)
|
||||
{
|
||||
win->_y[i] = malloc(ncols * sizeof(chtype));
|
||||
if (!win->_y[i])
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
void PDC_sync(WINDOW *win)
|
||||
{
|
||||
PDC_LOG(("PDC_sync() - called:\n"));
|
||||
|
||||
if (win->_immed)
|
||||
wrefresh(win);
|
||||
if (win->_sync)
|
||||
wsyncup(win);
|
||||
}
|
||||
|
||||
WINDOW *newwin(int nlines, int ncols, int begy, int begx)
|
||||
{
|
||||
WINDOW *win;
|
||||
|
||||
PDC_LOG(("newwin() - called:lines=%d cols=%d begy=%d begx=%d\n",
|
||||
nlines, ncols, begy, begx));
|
||||
|
||||
if (!nlines)
|
||||
nlines = LINES - begy;
|
||||
if (!ncols)
|
||||
ncols = COLS - begx;
|
||||
|
||||
if (!SP || begy + nlines > SP->lines || begx + ncols > SP->cols)
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
win = PDC_makenew(nlines, ncols, begy, begx);
|
||||
if (win)
|
||||
win = PDC_makelines(win);
|
||||
|
||||
if (win)
|
||||
werase(win);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
int delwin(WINDOW *win)
|
||||
{
|
||||
int i;
|
||||
|
||||
PDC_LOG(("delwin() - called\n"));
|
||||
|
||||
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]);
|
||||
|
||||
free(win->_firstch);
|
||||
free(win->_lastch);
|
||||
free(win->_y);
|
||||
free(win);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int mvwin(WINDOW *win, int y, int x)
|
||||
{
|
||||
PDC_LOG(("mvwin() - called\n"));
|
||||
|
||||
if (!win || (y + win->_maxy > LINES || y < 0)
|
||||
|| (x + win->_maxx > COLS || x < 0))
|
||||
return ERR;
|
||||
|
||||
win->_begy = y;
|
||||
win->_begx = x;
|
||||
touchwin(win);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
WINDOW *subwin(WINDOW *orig, int nlines, int ncols, int begy, int begx)
|
||||
{
|
||||
WINDOW *win;
|
||||
int i, j, k;
|
||||
|
||||
PDC_LOG(("subwin() - called: lines %d cols %d begy %d begx %d\n",
|
||||
nlines, ncols, begy, begx));
|
||||
|
||||
/* make sure window fits inside the original one */
|
||||
|
||||
if (!orig || (begy < orig->_begy) || (begx < orig->_begx) ||
|
||||
(begy + nlines) > (orig->_begy + orig->_maxy) ||
|
||||
(begx + ncols) > (orig->_begx + orig->_maxx))
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
j = begy - orig->_begy;
|
||||
k = begx - orig->_begx;
|
||||
|
||||
if (!nlines)
|
||||
nlines = orig->_maxy - 1 - j;
|
||||
if (!ncols)
|
||||
ncols = orig->_maxx - 1 - k;
|
||||
|
||||
win = PDC_makenew(nlines, ncols, begy, begx);
|
||||
if (!win)
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
/* initialize window variables */
|
||||
|
||||
win->_attrs = orig->_attrs;
|
||||
win->_bkgd = orig->_bkgd;
|
||||
win->_leaveit = orig->_leaveit;
|
||||
win->_scroll = orig->_scroll;
|
||||
win->_nodelay = orig->_nodelay;
|
||||
win->_delayms = orig->_delayms;
|
||||
win->_use_keypad = orig->_use_keypad;
|
||||
win->_immed = orig->_immed;
|
||||
win->_sync = orig->_sync;
|
||||
win->_pary = j;
|
||||
win->_parx = k;
|
||||
win->_parent = orig;
|
||||
|
||||
for (i = 0; i < nlines; i++, j++)
|
||||
win->_y[i] = orig->_y[j] + k;
|
||||
|
||||
win->_flags |= _SUBWIN;
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
WINDOW *derwin(WINDOW *orig, int nlines, int ncols, int begy, int begx)
|
||||
{
|
||||
return subwin(orig, nlines, ncols, begy + orig->_begy, begx + orig->_begx);
|
||||
}
|
||||
|
||||
int mvderwin(WINDOW *win, int pary, int parx)
|
||||
{
|
||||
int i, j;
|
||||
WINDOW *mypar;
|
||||
|
||||
if (!win || !(win->_parent))
|
||||
return ERR;
|
||||
|
||||
mypar = win->_parent;
|
||||
|
||||
if (pary < 0 || parx < 0 || (pary + win->_maxy) > mypar->_maxy ||
|
||||
(parx + win->_maxx) > mypar->_maxx)
|
||||
return ERR;
|
||||
|
||||
j = pary;
|
||||
|
||||
for (i = 0; i < win->_maxy; i++)
|
||||
win->_y[i] = (mypar->_y[j++]) + parx;
|
||||
|
||||
win->_pary = pary;
|
||||
win->_parx = parx;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
WINDOW *dupwin(WINDOW *win)
|
||||
{
|
||||
WINDOW *new;
|
||||
chtype *ptr, *ptr1;
|
||||
int nlines, ncols, begy, begx, i;
|
||||
|
||||
if (!win)
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
nlines = win->_maxy;
|
||||
ncols = win->_maxx;
|
||||
begy = win->_begy;
|
||||
begx = win->_begx;
|
||||
|
||||
new = PDC_makenew(nlines, ncols, begy, begx);
|
||||
if (new)
|
||||
new = PDC_makelines(new);
|
||||
|
||||
if (!new)
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
/* copy the contents of win into new */
|
||||
|
||||
for (i = 0; i < nlines; i++)
|
||||
{
|
||||
for (ptr = new->_y[i], ptr1 = win->_y[i];
|
||||
ptr < new->_y[i] + ncols; ptr++, ptr1++)
|
||||
*ptr = *ptr1;
|
||||
|
||||
new->_firstch[i] = 0;
|
||||
new->_lastch[i] = ncols - 1;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
WINDOW *resize_window(WINDOW *win, int nlines, int ncols)
|
||||
{
|
||||
WINDOW *new;
|
||||
int i, save_cury, save_curx, new_begy, new_begx;
|
||||
|
||||
PDC_LOG(("resize_window() - called: nlines %d ncols %d\n",
|
||||
nlines, ncols));
|
||||
|
||||
if (!win || !SP)
|
||||
return (WINDOW *)NULL;
|
||||
|
||||
if (win->_flags & _SUBPAD)
|
||||
{
|
||||
new = subpad(win->_parent, nlines, ncols, win->_begy, win->_begx);
|
||||
if (!new)
|
||||
return (WINDOW *)NULL;
|
||||
}
|
||||
else if (win->_flags & _SUBWIN)
|
||||
{
|
||||
new = subwin(win->_parent, nlines, ncols, win->_begy, win->_begx);
|
||||
if (!new)
|
||||
return (WINDOW *)NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (win == SP->slk_winptr)
|
||||
{
|
||||
new_begy = SP->lines - SP->slklines;
|
||||
new_begx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_begy = win->_begy;
|
||||
new_begx = win->_begx;
|
||||
}
|
||||
|
||||
new = PDC_makenew(nlines, ncols, new_begy, new_begx);
|
||||
if (!new)
|
||||
return (WINDOW *)NULL;
|
||||
}
|
||||
|
||||
save_curx = min(win->_curx, (new->_maxx - 1));
|
||||
save_cury = min(win->_cury, (new->_maxy - 1));
|
||||
|
||||
if (!(win->_flags & (_SUBPAD|_SUBWIN)))
|
||||
{
|
||||
new = PDC_makelines(new);
|
||||
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]);
|
||||
}
|
||||
|
||||
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->_curx = save_curx;
|
||||
new->_cury = save_cury;
|
||||
|
||||
free(win->_firstch);
|
||||
free(win->_lastch);
|
||||
free(win->_y);
|
||||
|
||||
*win = *new;
|
||||
free(new);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
int wresize(WINDOW *win, int nlines, int ncols)
|
||||
{
|
||||
return (resize_window(win, nlines, ncols) ? OK : ERR);
|
||||
}
|
||||
|
||||
void wsyncup(WINDOW *win)
|
||||
{
|
||||
WINDOW *tmp;
|
||||
|
||||
PDC_LOG(("wsyncup() - called\n"));
|
||||
|
||||
for (tmp = win; tmp; tmp = tmp->_parent)
|
||||
touchwin(tmp);
|
||||
}
|
||||
|
||||
int syncok(WINDOW *win, bool bf)
|
||||
{
|
||||
PDC_LOG(("syncok() - called\n"));
|
||||
|
||||
if (!win)
|
||||
return ERR;
|
||||
|
||||
win->_sync = bf;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void wcursyncup(WINDOW *win)
|
||||
{
|
||||
WINDOW *tmp;
|
||||
|
||||
PDC_LOG(("wcursyncup() - called\n"));
|
||||
|
||||
for (tmp = win; tmp && tmp->_parent; tmp = tmp->_parent)
|
||||
wmove(tmp->_parent, tmp->_pary + tmp->_cury, tmp->_parx + tmp->_curx);
|
||||
}
|
||||
|
||||
void wsyncdown(WINDOW *win)
|
||||
{
|
||||
WINDOW *tmp;
|
||||
|
||||
PDC_LOG(("wsyncdown() - called\n"));
|
||||
|
||||
for (tmp = win; tmp; tmp = tmp->_parent)
|
||||
{
|
||||
if (is_wintouched(tmp))
|
||||
{
|
||||
touchwin(win);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
76
wincon/README.md
Normal file
76
wincon/README.md
Normal file
@@ -0,0 +1,76 @@
|
||||
PDCurses for Windows console
|
||||
============================
|
||||
|
||||
This directory contains PDCurses source code files specific to the
|
||||
Microsoft Windows console. Although historically called "Win32", this
|
||||
port can just as easily be built for 64-bit systems. Windows 95 through
|
||||
Windows 10 are covered. (Some features require later versions.)
|
||||
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
- Choose the appropriate makefile for your compiler:
|
||||
|
||||
Makefile - GCC (MinGW or Cygnus)
|
||||
Makefile.bcc - Borland C++
|
||||
Makefile.vc - Microsoft Visual C++
|
||||
Makefile.wcc - Watcom
|
||||
|
||||
- Optionally, you can build in a different directory than the platform
|
||||
directory by setting PDCURSES_SRCDIR to point to the directory where
|
||||
you unpacked PDCurses, and changing to your target directory:
|
||||
|
||||
set PDCURSES_SRCDIR=c:\pdcurses
|
||||
|
||||
- Build it:
|
||||
|
||||
make -f makefilename
|
||||
|
||||
(For Watcom, use "wmake" instead of "make"; for MSVC, "nmake"; for
|
||||
MinGW, "mingw32-make".) You'll get the library (pdcurses.lib or .a,
|
||||
depending on your compiler) and a lot of object files.
|
||||
|
||||
You can also give the optional parameter "WIDE=Y", to build the
|
||||
library with wide-character (Unicode) support:
|
||||
|
||||
wmake -f Makefile.wcc WIDE=Y
|
||||
|
||||
When built this way, the library is not compatible with Windows 9x,
|
||||
unless you also link with the Microsoft Layer for Unicode (not
|
||||
tested).
|
||||
|
||||
Another option, "UTF8=Y", makes PDCurses ignore the system locale, and
|
||||
treat all narrow-character strings as UTF-8. This option has no effect
|
||||
unless WIDE=Y is also set. Use it to get around the poor support for
|
||||
UTF-8 in the Windows console:
|
||||
|
||||
make -f Makefile.bcc WIDE=Y UTF8=Y
|
||||
|
||||
You can also use the optional parameter "DLL=Y" with Visual C++,
|
||||
MinGW or Cygwin, to build the library as a DLL:
|
||||
|
||||
nmake -f Makefile.vc WIDE=Y DLL=Y
|
||||
|
||||
When you build the library as a Windows DLL, you must always define
|
||||
PDC_DLL_BUILD when linking against it. (Or, if you only want to use
|
||||
the DLL, you could add this definition to your curses.h.)
|
||||
|
||||
Add the target "demos" to build the sample programs.
|
||||
|
||||
- If your build stops with errors about PCONSOLE_SCREEN_BUFFER_INFOEX,
|
||||
add the parameter "INFOEX=N" to your make command line and try again.
|
||||
(This will happen with older compile environments.)
|
||||
|
||||
|
||||
Distribution Status
|
||||
-------------------
|
||||
|
||||
The files in this directory are released to the public domain.
|
||||
|
||||
|
||||
Acknowledgements
|
||||
----------------
|
||||
|
||||
Windows console port was originally provided by Chris Szurgot
|
||||
<szurgot@itribe.net>
|
||||
149
wincon/pdcclip.c
Normal file
149
wincon/pdcclip.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include "pdcwin.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
clipboard
|
||||
---------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int PDC_getclipboard(char **contents, long *length);
|
||||
int PDC_setclipboard(const char *contents, long length);
|
||||
int PDC_freeclipboard(char *contents);
|
||||
int PDC_clearclipboard(void);
|
||||
|
||||
### Description
|
||||
|
||||
PDC_getclipboard() gets the textual contents of the system's
|
||||
clipboard. This function returns the contents of the clipboard in the
|
||||
contents argument. It is the responsibility of the caller to free the
|
||||
memory returned, via PDC_freeclipboard(). The length of the clipboard
|
||||
contents is returned in the length argument.
|
||||
|
||||
PDC_setclipboard copies the supplied text into the system's
|
||||
clipboard, emptying the clipboard prior to the copy.
|
||||
|
||||
PDC_clearclipboard() clears the internal clipboard.
|
||||
|
||||
### Return Values
|
||||
|
||||
indicator of success/failure of call.
|
||||
PDC_CLIP_SUCCESS the call was successful
|
||||
PDC_CLIP_MEMORY_ERROR unable to allocate sufficient memory for
|
||||
the clipboard contents
|
||||
PDC_CLIP_EMPTY the clipboard contains no text
|
||||
PDC_CLIP_ACCESS_ERROR no clipboard support
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
PDC_getclipboard - - -
|
||||
PDC_setclipboard - - -
|
||||
PDC_freeclipboard - - -
|
||||
PDC_clearclipboard - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
# define PDC_TEXT CF_UNICODETEXT
|
||||
#else
|
||||
# define PDC_TEXT CF_OEMTEXT
|
||||
#endif
|
||||
|
||||
int PDC_getclipboard(char **contents, long *length)
|
||||
{
|
||||
HANDLE handle;
|
||||
long len;
|
||||
|
||||
PDC_LOG(("PDC_getclipboard() - called\n"));
|
||||
|
||||
if (!OpenClipboard(NULL))
|
||||
return PDC_CLIP_ACCESS_ERROR;
|
||||
|
||||
if ((handle = GetClipboardData(PDC_TEXT)) == NULL)
|
||||
{
|
||||
CloseClipboard();
|
||||
return PDC_CLIP_EMPTY;
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
len = wcslen((wchar_t *)handle) * 3;
|
||||
#else
|
||||
len = strlen((char *)handle);
|
||||
#endif
|
||||
*contents = (char *)GlobalAlloc(GMEM_FIXED, len + 1);
|
||||
|
||||
if (!*contents)
|
||||
{
|
||||
CloseClipboard();
|
||||
return PDC_CLIP_MEMORY_ERROR;
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
len = PDC_wcstombs((char *)*contents, (wchar_t *)handle, len);
|
||||
#else
|
||||
strcpy((char *)*contents, (char *)handle);
|
||||
#endif
|
||||
*length = len;
|
||||
CloseClipboard();
|
||||
|
||||
return PDC_CLIP_SUCCESS;
|
||||
}
|
||||
|
||||
int PDC_setclipboard(const char *contents, long length)
|
||||
{
|
||||
HGLOBAL ptr1;
|
||||
LPTSTR ptr2;
|
||||
|
||||
PDC_LOG(("PDC_setclipboard() - called\n"));
|
||||
|
||||
if (!OpenClipboard(NULL))
|
||||
return PDC_CLIP_ACCESS_ERROR;
|
||||
|
||||
ptr1 = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
|
||||
(length + 1) * sizeof(TCHAR));
|
||||
|
||||
if (!ptr1)
|
||||
return PDC_CLIP_MEMORY_ERROR;
|
||||
|
||||
ptr2 = GlobalLock(ptr1);
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
PDC_mbstowcs((wchar_t *)ptr2, contents, length);
|
||||
#else
|
||||
memcpy((char *)ptr2, contents, length + 1);
|
||||
#endif
|
||||
GlobalUnlock(ptr1);
|
||||
EmptyClipboard();
|
||||
|
||||
if (!SetClipboardData(PDC_TEXT, ptr1))
|
||||
{
|
||||
GlobalFree(ptr1);
|
||||
return PDC_CLIP_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
CloseClipboard();
|
||||
GlobalFree(ptr1);
|
||||
|
||||
return PDC_CLIP_SUCCESS;
|
||||
}
|
||||
|
||||
int PDC_freeclipboard(char *contents)
|
||||
{
|
||||
PDC_LOG(("PDC_freeclipboard() - called\n"));
|
||||
|
||||
GlobalFree(contents);
|
||||
return PDC_CLIP_SUCCESS;
|
||||
}
|
||||
|
||||
int PDC_clearclipboard(void)
|
||||
{
|
||||
PDC_LOG(("PDC_clearclipboard() - called\n"));
|
||||
|
||||
EmptyClipboard();
|
||||
|
||||
return PDC_CLIP_SUCCESS;
|
||||
}
|
||||
329
wincon/pdcdisp.c
Normal file
329
wincon/pdcdisp.c
Normal file
@@ -0,0 +1,329 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include "pdcwin.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
# include "../common/acsuni.h"
|
||||
#else
|
||||
# include "../common/acs437.h"
|
||||
#endif
|
||||
|
||||
DWORD pdc_last_blink;
|
||||
static bool blinked_off = FALSE;
|
||||
static bool in_italic = FALSE;
|
||||
|
||||
/* position hardware cursor at (y, x) */
|
||||
|
||||
void PDC_gotoyx(int row, int col)
|
||||
{
|
||||
COORD coord;
|
||||
|
||||
PDC_LOG(("PDC_gotoyx() - called: row %d col %d from row %d col %d\n",
|
||||
row, col, SP->cursrow, SP->curscol));
|
||||
|
||||
coord.X = col;
|
||||
coord.Y = row;
|
||||
|
||||
SetConsoleCursorPosition(pdc_con_out, coord);
|
||||
}
|
||||
|
||||
void _set_ansi_color(short f, short b, attr_t attr)
|
||||
{
|
||||
char esc[64], *p;
|
||||
short tmp, underline;
|
||||
bool italic;
|
||||
|
||||
if (f < 16 && !pdc_color[f].mapped)
|
||||
f = pdc_curstoansi[f];
|
||||
|
||||
if (b < 16 && !pdc_color[b].mapped)
|
||||
b = pdc_curstoansi[b];
|
||||
|
||||
if (attr & A_REVERSE)
|
||||
{
|
||||
tmp = f;
|
||||
f = b;
|
||||
b = tmp;
|
||||
}
|
||||
attr &= SP->termattrs;
|
||||
italic = !!(attr & A_ITALIC);
|
||||
underline = !!(attr & A_UNDERLINE);
|
||||
|
||||
p = esc + sprintf(esc, "\x1b[");
|
||||
|
||||
if (f != pdc_oldf)
|
||||
{
|
||||
if (f < 8 && !pdc_color[f].mapped)
|
||||
p += sprintf(p, "%d", f + 30);
|
||||
else if (f < 16 && !pdc_color[f].mapped)
|
||||
p += sprintf(p, "%d", f + 82);
|
||||
else if (f < 256 && !pdc_color[f].mapped)
|
||||
p += sprintf(p, "38;5;%d", f);
|
||||
else
|
||||
{
|
||||
short red = DIVROUND(pdc_color[f].r * 255, 1000);
|
||||
short green = DIVROUND(pdc_color[f].g * 255, 1000);
|
||||
short blue = DIVROUND(pdc_color[f].b * 255, 1000);
|
||||
|
||||
p += sprintf(p, "38;2;%d;%d;%d", red, green, blue);
|
||||
}
|
||||
|
||||
pdc_oldf = f;
|
||||
}
|
||||
|
||||
if (b != pdc_oldb)
|
||||
{
|
||||
if (strlen(esc) > 2)
|
||||
p += sprintf(p, ";");
|
||||
|
||||
if (b < 8 && !pdc_color[b].mapped)
|
||||
p += sprintf(p, "%d", b + 40);
|
||||
else if (b < 16 && !pdc_color[b].mapped)
|
||||
p += sprintf(p, "%d", b + 92);
|
||||
else if (b < 256 && !pdc_color[b].mapped)
|
||||
p += sprintf(p, "48;5;%d", b);
|
||||
else
|
||||
{
|
||||
short red = DIVROUND(pdc_color[b].r * 255, 1000);
|
||||
short green = DIVROUND(pdc_color[b].g * 255, 1000);
|
||||
short blue = DIVROUND(pdc_color[b].b * 255, 1000);
|
||||
|
||||
p += sprintf(p, "48;2;%d;%d;%d", red, green, blue);
|
||||
}
|
||||
|
||||
pdc_oldb = b;
|
||||
}
|
||||
|
||||
if (italic != in_italic)
|
||||
{
|
||||
if (strlen(esc) > 2)
|
||||
p += sprintf(p, ";");
|
||||
|
||||
if (italic)
|
||||
p += sprintf(p, "3");
|
||||
else
|
||||
p += sprintf(p, "23");
|
||||
|
||||
in_italic = italic;
|
||||
}
|
||||
|
||||
if (underline != pdc_oldu)
|
||||
{
|
||||
if (strlen(esc) > 2)
|
||||
p += sprintf(p, ";");
|
||||
|
||||
if (underline)
|
||||
p += sprintf(p, "4");
|
||||
else
|
||||
p += sprintf(p, "24");
|
||||
|
||||
pdc_oldu = underline;
|
||||
}
|
||||
|
||||
if (strlen(esc) > 2)
|
||||
{
|
||||
sprintf(p, "m");
|
||||
if (!pdc_conemu)
|
||||
SetConsoleMode(pdc_con_out, 0x0015);
|
||||
|
||||
WriteConsoleA(pdc_con_out, esc, strlen(esc), NULL, NULL);
|
||||
|
||||
if (!pdc_conemu)
|
||||
SetConsoleMode(pdc_con_out, 0x0010);
|
||||
}
|
||||
}
|
||||
|
||||
void _new_packet(attr_t attr, int lineno, int x, int len, const chtype *srcp)
|
||||
{
|
||||
int j;
|
||||
short fore, back;
|
||||
bool blink, ansi;
|
||||
|
||||
if (pdc_ansi && (lineno == (SP->lines - 1)) && ((x + len) == SP->cols))
|
||||
{
|
||||
len--;
|
||||
if (len)
|
||||
_new_packet(attr, lineno, x, len, srcp);
|
||||
pdc_ansi = FALSE;
|
||||
_new_packet(attr, lineno, x + len, 1, srcp + len);
|
||||
pdc_ansi = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
pair_content(PAIR_NUMBER(attr), &fore, &back);
|
||||
ansi = pdc_ansi || (fore >= 16 || back >= 16);
|
||||
blink = (SP->termattrs & A_BLINK) && (attr & A_BLINK);
|
||||
|
||||
if (blink)
|
||||
{
|
||||
attr &= ~A_BLINK;
|
||||
if (blinked_off)
|
||||
attr &= ~(A_UNDERLINE | A_RIGHT | A_LEFT);
|
||||
}
|
||||
|
||||
if (attr & A_BOLD)
|
||||
fore |= 8;
|
||||
if (attr & A_BLINK)
|
||||
back |= 8;
|
||||
|
||||
if (ansi)
|
||||
{
|
||||
#ifdef PDC_WIDE
|
||||
WCHAR buffer[512];
|
||||
#else
|
||||
char buffer[512];
|
||||
#endif
|
||||
for (j = 0; j < len; j++)
|
||||
{
|
||||
chtype ch = srcp[j];
|
||||
|
||||
if (ch & A_ALTCHARSET && !(ch & 0xff80))
|
||||
{
|
||||
ch = acs_map[ch & 0x7f];
|
||||
|
||||
if (pdc_wt && (ch & A_CHARTEXT) < ' ')
|
||||
goto NONANSI;
|
||||
}
|
||||
|
||||
if (blink && blinked_off)
|
||||
ch = ' ';
|
||||
|
||||
buffer[j] = ch & A_CHARTEXT;
|
||||
}
|
||||
|
||||
PDC_gotoyx(lineno, x);
|
||||
_set_ansi_color(fore, back, attr);
|
||||
#ifdef PDC_WIDE
|
||||
WriteConsoleW(pdc_con_out, buffer, len, NULL, NULL);
|
||||
#else
|
||||
WriteConsoleA(pdc_con_out, buffer, len, NULL, NULL);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
NONANSI:
|
||||
{
|
||||
CHAR_INFO buffer[512];
|
||||
COORD bufSize, bufPos;
|
||||
SMALL_RECT sr;
|
||||
WORD mapped_attr;
|
||||
|
||||
fore = pdc_curstoreal[fore];
|
||||
back = pdc_curstoreal[back];
|
||||
|
||||
if (attr & A_REVERSE)
|
||||
mapped_attr = back | (fore << 4);
|
||||
else
|
||||
mapped_attr = fore | (back << 4);
|
||||
|
||||
if (attr & A_UNDERLINE)
|
||||
mapped_attr |= 0x8000; /* COMMON_LVB_UNDERSCORE */
|
||||
if (attr & A_LEFT)
|
||||
mapped_attr |= 0x0800; /* COMMON_LVB_GRID_LVERTICAL */
|
||||
if (attr & A_RIGHT)
|
||||
mapped_attr |= 0x1000; /* COMMON_LVB_GRID_RVERTICAL */
|
||||
|
||||
for (j = 0; j < len; j++)
|
||||
{
|
||||
chtype ch = srcp[j];
|
||||
|
||||
if (ch & A_ALTCHARSET && !(ch & 0xff80))
|
||||
ch = acs_map[ch & 0x7f];
|
||||
|
||||
if (blink && blinked_off)
|
||||
ch = ' ';
|
||||
|
||||
buffer[j].Attributes = mapped_attr;
|
||||
buffer[j].Char.UnicodeChar = ch & A_CHARTEXT;
|
||||
}
|
||||
|
||||
bufPos.X = bufPos.Y = 0;
|
||||
bufSize.X = len;
|
||||
bufSize.Y = 1;
|
||||
|
||||
sr.Top = sr.Bottom = lineno;
|
||||
sr.Left = x;
|
||||
sr.Right = x + len - 1;
|
||||
|
||||
WriteConsoleOutput(pdc_con_out, buffer, bufSize, bufPos, &sr);
|
||||
}
|
||||
}
|
||||
|
||||
/* update the given physical line to look like the corresponding line in
|
||||
curscr */
|
||||
|
||||
void PDC_transform_line(int lineno, int x, int len, const chtype *srcp)
|
||||
{
|
||||
attr_t old_attr, attr;
|
||||
int i, j;
|
||||
|
||||
PDC_LOG(("PDC_transform_line() - called: lineno=%d\n", lineno));
|
||||
|
||||
old_attr = *srcp & (A_ATTRIBUTES ^ A_ALTCHARSET);
|
||||
|
||||
for (i = 1, j = 1; j < len; i++, j++)
|
||||
{
|
||||
attr = srcp[i] & (A_ATTRIBUTES ^ A_ALTCHARSET);
|
||||
|
||||
if (attr != old_attr)
|
||||
{
|
||||
_new_packet(old_attr, lineno, x, i, srcp);
|
||||
old_attr = attr;
|
||||
srcp += i;
|
||||
x += i;
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_new_packet(old_attr, lineno, x, i, srcp);
|
||||
}
|
||||
|
||||
void PDC_blink_text(void)
|
||||
{
|
||||
CONSOLE_CURSOR_INFO cci;
|
||||
int i, j, k;
|
||||
bool oldvis;
|
||||
|
||||
GetConsoleCursorInfo(pdc_con_out, &cci);
|
||||
oldvis = cci.bVisible;
|
||||
if (oldvis)
|
||||
{
|
||||
cci.bVisible = FALSE;
|
||||
SetConsoleCursorInfo(pdc_con_out, &cci);
|
||||
}
|
||||
|
||||
if (!(SP->termattrs & A_BLINK))
|
||||
blinked_off = FALSE;
|
||||
else
|
||||
blinked_off = !blinked_off;
|
||||
|
||||
for (i = 0; i < SP->lines; i++)
|
||||
{
|
||||
const chtype *srcp = curscr->_y[i];
|
||||
|
||||
for (j = 0; j < SP->cols; j++)
|
||||
if (srcp[j] & A_BLINK)
|
||||
{
|
||||
k = j;
|
||||
while (k < SP->cols && (srcp[k] & A_BLINK))
|
||||
k++;
|
||||
PDC_transform_line(i, j, k - j, srcp + j);
|
||||
j = k;
|
||||
}
|
||||
}
|
||||
|
||||
PDC_gotoyx(SP->cursrow, SP->curscol);
|
||||
if (oldvis)
|
||||
{
|
||||
cci.bVisible = TRUE;
|
||||
SetConsoleCursorInfo(pdc_con_out, &cci);
|
||||
}
|
||||
|
||||
pdc_last_blink = GetTickCount();
|
||||
}
|
||||
|
||||
void PDC_doupdate(void)
|
||||
{
|
||||
}
|
||||
42
wincon/pdcgetsc.c
Normal file
42
wincon/pdcgetsc.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include "pdcwin.h"
|
||||
|
||||
/* get the cursor size/shape */
|
||||
|
||||
int PDC_get_cursor_mode(void)
|
||||
{
|
||||
CONSOLE_CURSOR_INFO ci;
|
||||
|
||||
PDC_LOG(("PDC_get_cursor_mode() - called\n"));
|
||||
|
||||
GetConsoleCursorInfo(pdc_con_out, &ci);
|
||||
|
||||
return ci.dwSize;
|
||||
}
|
||||
|
||||
/* return number of screen rows */
|
||||
|
||||
int PDC_get_rows(void)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO scr;
|
||||
|
||||
PDC_LOG(("PDC_get_rows() - called\n"));
|
||||
|
||||
GetConsoleScreenBufferInfo(pdc_con_out, &scr);
|
||||
|
||||
return scr.srWindow.Bottom - scr.srWindow.Top + 1;
|
||||
}
|
||||
|
||||
/* return width of screen/viewport */
|
||||
|
||||
int PDC_get_columns(void)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO scr;
|
||||
|
||||
PDC_LOG(("PDC_get_columns() - called\n"));
|
||||
|
||||
GetConsoleScreenBufferInfo(pdc_con_out, &scr);
|
||||
|
||||
return scr.srWindow.Right - scr.srWindow.Left + 1;
|
||||
}
|
||||
699
wincon/pdckbd.c
Normal file
699
wincon/pdckbd.c
Normal file
@@ -0,0 +1,699 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include "pdcwin.h"
|
||||
|
||||
/* These variables are used to store information about the next
|
||||
Input Event. */
|
||||
|
||||
static INPUT_RECORD save_ip;
|
||||
static MOUSE_STATUS old_mouse_status;
|
||||
static DWORD event_count = 0;
|
||||
static SHORT left_key;
|
||||
static int key_count = 0;
|
||||
static int save_press = 0;
|
||||
|
||||
#define KEV save_ip.Event.KeyEvent
|
||||
#define MEV save_ip.Event.MouseEvent
|
||||
#define REV save_ip.Event.WindowBufferSizeEvent
|
||||
|
||||
/************************************************************************
|
||||
* Table for key code translation of function keys in keypad mode *
|
||||
* These values are for strict IBM keyboard compatibles only *
|
||||
************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short normal;
|
||||
unsigned short shift;
|
||||
unsigned short control;
|
||||
unsigned short alt;
|
||||
unsigned short extended;
|
||||
} KPTAB;
|
||||
|
||||
static KPTAB kptab[] =
|
||||
{
|
||||
{0, 0, 0, 0, 0 }, /* 0 */
|
||||
{0, 0, 0, 0, 0 }, /* 1 VK_LBUTTON */
|
||||
{0, 0, 0, 0, 0 }, /* 2 VK_RBUTTON */
|
||||
{0, 0, 0, 0, 0 }, /* 3 VK_CANCEL */
|
||||
{0, 0, 0, 0, 0 }, /* 4 VK_MBUTTON */
|
||||
{0, 0, 0, 0, 0 }, /* 5 */
|
||||
{0, 0, 0, 0, 0 }, /* 6 */
|
||||
{0, 0, 0, 0, 0 }, /* 7 */
|
||||
{0x08, 0x08, 0x7F, ALT_BKSP, 0 }, /* 8 VK_BACK */
|
||||
{0x09, KEY_BTAB, CTL_TAB, ALT_TAB, 999 }, /* 9 VK_TAB */
|
||||
{0, 0, 0, 0, 0 }, /* 10 */
|
||||
{0, 0, 0, 0, 0 }, /* 11 */
|
||||
{KEY_B2, 0x35, CTL_PAD5, ALT_PAD5, 0 }, /* 12 VK_CLEAR */
|
||||
{0x0D, 0x0D, CTL_ENTER, ALT_ENTER, 1 }, /* 13 VK_RETURN */
|
||||
{0, 0, 0, 0, 0 }, /* 14 */
|
||||
{0, 0, 0, 0, 0 }, /* 15 */
|
||||
{0, 0, 0, 0, 0 }, /* 16 VK_SHIFT HANDLED SEPARATELY */
|
||||
{0, 0, 0, 0, 0 }, /* 17 VK_CONTROL HANDLED SEPARATELY */
|
||||
{0, 0, 0, 0, 0 }, /* 18 VK_MENU HANDLED SEPARATELY */
|
||||
{0, 0, 0, 0, 0 }, /* 19 VK_PAUSE */
|
||||
{0, 0, 0, 0, 0 }, /* 20 VK_CAPITAL HANDLED SEPARATELY */
|
||||
{0, 0, 0, 0, 0 }, /* 21 VK_HANGUL */
|
||||
{0, 0, 0, 0, 0 }, /* 22 */
|
||||
{0, 0, 0, 0, 0 }, /* 23 VK_JUNJA */
|
||||
{0, 0, 0, 0, 0 }, /* 24 VK_FINAL */
|
||||
{0, 0, 0, 0, 0 }, /* 25 VK_HANJA */
|
||||
{0, 0, 0, 0, 0 }, /* 26 */
|
||||
{0x1B, 0x1B, 0x1B, ALT_ESC, 0 }, /* 27 VK_ESCAPE */
|
||||
{0, 0, 0, 0, 0 }, /* 28 VK_CONVERT */
|
||||
{0, 0, 0, 0, 0 }, /* 29 VK_NONCONVERT */
|
||||
{0, 0, 0, 0, 0 }, /* 30 VK_ACCEPT */
|
||||
{0, 0, 0, 0, 0 }, /* 31 VK_MODECHANGE */
|
||||
{0x20, 0x20, 0x20, 0x20, 0 }, /* 32 VK_SPACE */
|
||||
{KEY_A3, 0x39, CTL_PAD9, ALT_PAD9, 3 }, /* 33 VK_PRIOR */
|
||||
{KEY_C3, 0x33, CTL_PAD3, ALT_PAD3, 4 }, /* 34 VK_NEXT */
|
||||
{KEY_C1, 0x31, CTL_PAD1, ALT_PAD1, 5 }, /* 35 VK_END */
|
||||
{KEY_A1, 0x37, CTL_PAD7, ALT_PAD7, 6 }, /* 36 VK_HOME */
|
||||
{KEY_B1, 0x34, CTL_PAD4, ALT_PAD4, 7 }, /* 37 VK_LEFT */
|
||||
{KEY_A2, 0x38, CTL_PAD8, ALT_PAD8, 8 }, /* 38 VK_UP */
|
||||
{KEY_B3, 0x36, CTL_PAD6, ALT_PAD6, 9 }, /* 39 VK_RIGHT */
|
||||
{KEY_C2, 0x32, CTL_PAD2, ALT_PAD2, 10 }, /* 40 VK_DOWN */
|
||||
{0, 0, 0, 0, 0 }, /* 41 VK_SELECT */
|
||||
{0, 0, 0, 0, 0 }, /* 42 VK_PRINT */
|
||||
{0, 0, 0, 0, 0 }, /* 43 VK_EXECUTE */
|
||||
{0, 0, 0, 0, 0 }, /* 44 VK_SNAPSHOT*/
|
||||
{PAD0, 0x30, CTL_PAD0, ALT_PAD0, 11 }, /* 45 VK_INSERT */
|
||||
{PADSTOP, 0x2E, CTL_PADSTOP, ALT_PADSTOP,12 }, /* 46 VK_DELETE */
|
||||
{0, 0, 0, 0, 0 }, /* 47 VK_HELP */
|
||||
{0x30, 0x29, 0, ALT_0, 0 }, /* 48 */
|
||||
{0x31, 0x21, 0, ALT_1, 0 }, /* 49 */
|
||||
{0x32, 0x40, 0, ALT_2, 0 }, /* 50 */
|
||||
{0x33, 0x23, 0, ALT_3, 0 }, /* 51 */
|
||||
{0x34, 0x24, 0, ALT_4, 0 }, /* 52 */
|
||||
{0x35, 0x25, 0, ALT_5, 0 }, /* 53 */
|
||||
{0x36, 0x5E, 0, ALT_6, 0 }, /* 54 */
|
||||
{0x37, 0x26, 0, ALT_7, 0 }, /* 55 */
|
||||
{0x38, 0x2A, 0, ALT_8, 0 }, /* 56 */
|
||||
{0x39, 0x28, 0, ALT_9, 0 }, /* 57 */
|
||||
{0, 0, 0, 0, 0 }, /* 58 */
|
||||
{0, 0, 0, 0, 0 }, /* 59 */
|
||||
{0, 0, 0, 0, 0 }, /* 60 */
|
||||
{0, 0, 0, 0, 0 }, /* 61 */
|
||||
{0, 0, 0, 0, 0 }, /* 62 */
|
||||
{0, 0, 0, 0, 0 }, /* 63 */
|
||||
{0, 0, 0, 0, 0 }, /* 64 */
|
||||
{0x61, 0x41, 0x01, ALT_A, 0 }, /* 65 */
|
||||
{0x62, 0x42, 0x02, ALT_B, 0 }, /* 66 */
|
||||
{0x63, 0x43, 0x03, ALT_C, 0 }, /* 67 */
|
||||
{0x64, 0x44, 0x04, ALT_D, 0 }, /* 68 */
|
||||
{0x65, 0x45, 0x05, ALT_E, 0 }, /* 69 */
|
||||
{0x66, 0x46, 0x06, ALT_F, 0 }, /* 70 */
|
||||
{0x67, 0x47, 0x07, ALT_G, 0 }, /* 71 */
|
||||
{0x68, 0x48, 0x08, ALT_H, 0 }, /* 72 */
|
||||
{0x69, 0x49, 0x09, ALT_I, 0 }, /* 73 */
|
||||
{0x6A, 0x4A, 0x0A, ALT_J, 0 }, /* 74 */
|
||||
{0x6B, 0x4B, 0x0B, ALT_K, 0 }, /* 75 */
|
||||
{0x6C, 0x4C, 0x0C, ALT_L, 0 }, /* 76 */
|
||||
{0x6D, 0x4D, 0x0D, ALT_M, 0 }, /* 77 */
|
||||
{0x6E, 0x4E, 0x0E, ALT_N, 0 }, /* 78 */
|
||||
{0x6F, 0x4F, 0x0F, ALT_O, 0 }, /* 79 */
|
||||
{0x70, 0x50, 0x10, ALT_P, 0 }, /* 80 */
|
||||
{0x71, 0x51, 0x11, ALT_Q, 0 }, /* 81 */
|
||||
{0x72, 0x52, 0x12, ALT_R, 0 }, /* 82 */
|
||||
{0x73, 0x53, 0x13, ALT_S, 0 }, /* 83 */
|
||||
{0x74, 0x54, 0x14, ALT_T, 0 }, /* 84 */
|
||||
{0x75, 0x55, 0x15, ALT_U, 0 }, /* 85 */
|
||||
{0x76, 0x56, 0x16, ALT_V, 0 }, /* 86 */
|
||||
{0x77, 0x57, 0x17, ALT_W, 0 }, /* 87 */
|
||||
{0x78, 0x58, 0x18, ALT_X, 0 }, /* 88 */
|
||||
{0x79, 0x59, 0x19, ALT_Y, 0 }, /* 89 */
|
||||
{0x7A, 0x5A, 0x1A, ALT_Z, 0 }, /* 90 */
|
||||
{0, 0, 0, 0, 0 }, /* 91 VK_LWIN */
|
||||
{0, 0, 0, 0, 0 }, /* 92 VK_RWIN */
|
||||
{0, 0, 0, 0, 0 }, /* 93 VK_APPS */
|
||||
{0, 0, 0, 0, 0 }, /* 94 */
|
||||
{0, 0, 0, 0, 0 }, /* 95 */
|
||||
{0x30, 0, CTL_PAD0, ALT_PAD0, 0 }, /* 96 VK_NUMPAD0 */
|
||||
{0x31, 0, CTL_PAD1, ALT_PAD1, 0 }, /* 97 VK_NUMPAD1 */
|
||||
{0x32, 0, CTL_PAD2, ALT_PAD2, 0 }, /* 98 VK_NUMPAD2 */
|
||||
{0x33, 0, CTL_PAD3, ALT_PAD3, 0 }, /* 99 VK_NUMPAD3 */
|
||||
{0x34, 0, CTL_PAD4, ALT_PAD4, 0 }, /* 100 VK_NUMPAD4 */
|
||||
{0x35, 0, CTL_PAD5, ALT_PAD5, 0 }, /* 101 VK_NUMPAD5 */
|
||||
{0x36, 0, CTL_PAD6, ALT_PAD6, 0 }, /* 102 VK_NUMPAD6 */
|
||||
{0x37, 0, CTL_PAD7, ALT_PAD7, 0 }, /* 103 VK_NUMPAD7 */
|
||||
{0x38, 0, CTL_PAD8, ALT_PAD8, 0 }, /* 104 VK_NUMPAD8 */
|
||||
{0x39, 0, CTL_PAD9, ALT_PAD9, 0 }, /* 105 VK_NUMPAD9 */
|
||||
{PADSTAR, SHF_PADSTAR,CTL_PADSTAR, ALT_PADSTAR,999 }, /* 106 VK_MULTIPLY*/
|
||||
{PADPLUS, SHF_PADPLUS,CTL_PADPLUS, ALT_PADPLUS,999 }, /* 107 VK_ADD */
|
||||
{0, 0, 0, 0, 0 }, /* 108 VK_SEPARATOR */
|
||||
{PADMINUS, SHF_PADMINUS,CTL_PADMINUS,ALT_PADMINUS,999}, /* 109 VK_SUBTRACT*/
|
||||
{0x2E, 0, CTL_PADSTOP, ALT_PADSTOP,0 }, /* 110 VK_DECIMAL */
|
||||
{PADSLASH, SHF_PADSLASH,CTL_PADSLASH,ALT_PADSLASH,2 }, /* 111 VK_DIVIDE */
|
||||
{KEY_F(1), KEY_F(13), KEY_F(25), KEY_F(37), 0 }, /* 112 VK_F1 */
|
||||
{KEY_F(2), KEY_F(14), KEY_F(26), KEY_F(38), 0 }, /* 113 VK_F2 */
|
||||
{KEY_F(3), KEY_F(15), KEY_F(27), KEY_F(39), 0 }, /* 114 VK_F3 */
|
||||
{KEY_F(4), KEY_F(16), KEY_F(28), KEY_F(40), 0 }, /* 115 VK_F4 */
|
||||
{KEY_F(5), KEY_F(17), KEY_F(29), KEY_F(41), 0 }, /* 116 VK_F5 */
|
||||
{KEY_F(6), KEY_F(18), KEY_F(30), KEY_F(42), 0 }, /* 117 VK_F6 */
|
||||
{KEY_F(7), KEY_F(19), KEY_F(31), KEY_F(43), 0 }, /* 118 VK_F7 */
|
||||
{KEY_F(8), KEY_F(20), KEY_F(32), KEY_F(44), 0 }, /* 119 VK_F8 */
|
||||
{KEY_F(9), KEY_F(21), KEY_F(33), KEY_F(45), 0 }, /* 120 VK_F9 */
|
||||
{KEY_F(10), KEY_F(22), KEY_F(34), KEY_F(46), 0 }, /* 121 VK_F10 */
|
||||
{KEY_F(11), KEY_F(23), KEY_F(35), KEY_F(47), 0 }, /* 122 VK_F11 */
|
||||
{KEY_F(12), KEY_F(24), KEY_F(36), KEY_F(48), 0 }, /* 123 VK_F12 */
|
||||
|
||||
/* 124 through 218 */
|
||||
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
|
||||
|
||||
{0x5B, 0x7B, 0x1B, ALT_LBRACKET,0 }, /* 219 */
|
||||
{0x5C, 0x7C, 0x1C, ALT_BSLASH, 0 }, /* 220 */
|
||||
{0x5D, 0x7D, 0x1D, ALT_RBRACKET,0 }, /* 221 */
|
||||
{0, 0, 0x27, ALT_FQUOTE, 0 }, /* 222 */
|
||||
{0, 0, 0, 0, 0 }, /* 223 */
|
||||
{0, 0, 0, 0, 0 }, /* 224 */
|
||||
{0, 0, 0, 0, 0 }, /* 225 */
|
||||
{0, 0, 0, 0, 0 }, /* 226 */
|
||||
{0, 0, 0, 0, 0 }, /* 227 */
|
||||
{0, 0, 0, 0, 0 }, /* 228 */
|
||||
{0, 0, 0, 0, 0 }, /* 229 */
|
||||
{0, 0, 0, 0, 0 }, /* 230 */
|
||||
{0, 0, 0, 0, 0 }, /* 231 */
|
||||
{0, 0, 0, 0, 0 }, /* 232 */
|
||||
{0, 0, 0, 0, 0 }, /* 233 */
|
||||
{0, 0, 0, 0, 0 }, /* 234 */
|
||||
{0, 0, 0, 0, 0 }, /* 235 */
|
||||
{0, 0, 0, 0, 0 }, /* 236 */
|
||||
{0, 0, 0, 0, 0 }, /* 237 */
|
||||
{0, 0, 0, 0, 0 }, /* 238 */
|
||||
{0, 0, 0, 0, 0 }, /* 239 */
|
||||
{0, 0, 0, 0, 0 }, /* 240 */
|
||||
{0, 0, 0, 0, 0 }, /* 241 */
|
||||
{0, 0, 0, 0, 0 }, /* 242 */
|
||||
{0, 0, 0, 0, 0 }, /* 243 */
|
||||
{0, 0, 0, 0, 0 }, /* 244 */
|
||||
{0, 0, 0, 0, 0 }, /* 245 */
|
||||
{0, 0, 0, 0, 0 }, /* 246 */
|
||||
{0, 0, 0, 0, 0 }, /* 247 */
|
||||
{0, 0, 0, 0, 0 }, /* 248 */
|
||||
{0, 0, 0, 0, 0 }, /* 249 */
|
||||
{0, 0, 0, 0, 0 }, /* 250 */
|
||||
{0, 0, 0, 0, 0 }, /* 251 */
|
||||
{0, 0, 0, 0, 0 }, /* 252 */
|
||||
{0, 0, 0, 0, 0 }, /* 253 */
|
||||
{0, 0, 0, 0, 0 }, /* 254 */
|
||||
{0, 0, 0, 0, 0 } /* 255 */
|
||||
};
|
||||
|
||||
static KPTAB ext_kptab[] =
|
||||
{
|
||||
{0, 0, 0, 0, }, /* MUST BE EMPTY */
|
||||
{PADENTER, SHF_PADENTER, CTL_PADENTER, ALT_PADENTER}, /* 13 */
|
||||
{PADSLASH, SHF_PADSLASH, CTL_PADSLASH, ALT_PADSLASH}, /* 111 */
|
||||
{KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP }, /* 33 */
|
||||
{KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN }, /* 34 */
|
||||
{KEY_END, KEY_SEND, CTL_END, ALT_END }, /* 35 */
|
||||
{KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME }, /* 36 */
|
||||
{KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT }, /* 37 */
|
||||
{KEY_UP, KEY_SUP, CTL_UP, ALT_UP }, /* 38 */
|
||||
{KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT }, /* 39 */
|
||||
{KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN }, /* 40 */
|
||||
{KEY_IC, KEY_SIC, CTL_INS, ALT_INS }, /* 45 */
|
||||
{KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL }, /* 46 */
|
||||
{PADSLASH, SHF_PADSLASH, CTL_PADSLASH, ALT_PADSLASH}, /* 191 */
|
||||
};
|
||||
|
||||
/* End of kptab[] */
|
||||
|
||||
void PDC_set_keyboard_binary(bool on)
|
||||
{
|
||||
DWORD mode;
|
||||
|
||||
PDC_LOG(("PDC_set_keyboard_binary() - called\n"));
|
||||
|
||||
GetConsoleMode(pdc_con_in, &mode);
|
||||
SetConsoleMode(pdc_con_in, !on ? (mode | ENABLE_PROCESSED_INPUT) :
|
||||
(mode & ~ENABLE_PROCESSED_INPUT));
|
||||
}
|
||||
|
||||
/* check if a key or mouse event is waiting */
|
||||
|
||||
bool PDC_check_key(void)
|
||||
{
|
||||
if (key_count > 0)
|
||||
return TRUE;
|
||||
|
||||
GetNumberOfConsoleInputEvents(pdc_con_in, &event_count);
|
||||
|
||||
return (event_count != 0);
|
||||
}
|
||||
|
||||
/* _get_key_count returns 0 if save_ip doesn't contain an event which
|
||||
should be passed back to the user. This function filters "useless"
|
||||
events.
|
||||
|
||||
The function returns the number of keys waiting. This may be > 1
|
||||
if the repetition of real keys pressed so far are > 1.
|
||||
|
||||
Returns 0 on NUMLOCK, CAPSLOCK, SCROLLLOCK.
|
||||
|
||||
Returns 1 for SHIFT, ALT, CTRL only if no other key has been pressed
|
||||
in between, and SP->return_key_modifiers is set; these are returned
|
||||
on keyup.
|
||||
|
||||
Normal keys are returned on keydown only. The number of repetitions
|
||||
are returned. Dead keys (diacritics) are omitted. See below for a
|
||||
description.
|
||||
*/
|
||||
|
||||
static int _get_key_count(void)
|
||||
{
|
||||
int num_keys = 0, vk;
|
||||
|
||||
PDC_LOG(("_get_key_count() - called\n"));
|
||||
|
||||
vk = KEV.wVirtualKeyCode;
|
||||
|
||||
if (KEV.bKeyDown)
|
||||
{
|
||||
/* key down */
|
||||
|
||||
save_press = 0;
|
||||
|
||||
if (vk == VK_CAPITAL || vk == VK_NUMLOCK || vk == VK_SCROLL)
|
||||
{
|
||||
/* throw away these modifiers */
|
||||
}
|
||||
else if (vk == VK_SHIFT || vk == VK_CONTROL || vk == VK_MENU)
|
||||
{
|
||||
/* These keys are returned on keyup only. */
|
||||
|
||||
save_press = vk;
|
||||
switch (vk)
|
||||
{
|
||||
case VK_SHIFT:
|
||||
left_key = GetKeyState(VK_LSHIFT);
|
||||
break;
|
||||
case VK_CONTROL:
|
||||
left_key = GetKeyState(VK_LCONTROL);
|
||||
break;
|
||||
case VK_MENU:
|
||||
left_key = GetKeyState(VK_LMENU);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check for diacritics. These are dead keys. Some locales
|
||||
have modified characters like umlaut-a, which is an "a"
|
||||
with two dots on it. In some locales you have to press a
|
||||
special key (the dead key) immediately followed by the
|
||||
"a" to get a composed umlaut-a. The special key may have
|
||||
a normal meaning with different modifiers. */
|
||||
|
||||
if (KEV.uChar.UnicodeChar || !(MapVirtualKey(vk, 2) & 0x80000000))
|
||||
num_keys = KEV.wRepeatCount;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* key up */
|
||||
|
||||
/* Only modifier keys or the results of ALT-numpad entry are
|
||||
returned on keyup */
|
||||
|
||||
if ((vk == VK_MENU && KEV.uChar.UnicodeChar) ||
|
||||
((vk == VK_SHIFT || vk == VK_CONTROL || vk == VK_MENU) &&
|
||||
vk == save_press))
|
||||
{
|
||||
save_press = 0;
|
||||
num_keys = 1;
|
||||
}
|
||||
}
|
||||
|
||||
PDC_LOG(("_get_key_count() - returning: num_keys %d\n", num_keys));
|
||||
|
||||
return num_keys;
|
||||
}
|
||||
|
||||
/* _process_key_event returns -1 if the key in save_ip should be
|
||||
ignored. Otherwise it returns the keycode which should be returned
|
||||
by PDC_get_key(). save_ip must be a key event.
|
||||
|
||||
CTRL-ALT support has been disabled, when is it emitted plainly? */
|
||||
|
||||
static int _process_key_event(void)
|
||||
{
|
||||
int key =
|
||||
#ifdef PDC_WIDE
|
||||
KEV.uChar.UnicodeChar;
|
||||
#else
|
||||
KEV.uChar.AsciiChar;
|
||||
#endif
|
||||
WORD vk = KEV.wVirtualKeyCode;
|
||||
DWORD state = KEV.dwControlKeyState;
|
||||
|
||||
int idx;
|
||||
BOOL enhanced;
|
||||
|
||||
SP->key_code = TRUE;
|
||||
|
||||
/* Save the key modifiers. Do this first to allow to detect e.g. a
|
||||
pressed CTRL key after a hit of NUMLOCK. */
|
||||
|
||||
if (state & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED))
|
||||
SP->key_modifiers |= PDC_KEY_MODIFIER_ALT;
|
||||
|
||||
if (state & SHIFT_PRESSED)
|
||||
SP->key_modifiers |= PDC_KEY_MODIFIER_SHIFT;
|
||||
|
||||
if (state & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
|
||||
SP->key_modifiers |= PDC_KEY_MODIFIER_CONTROL;
|
||||
|
||||
if (state & NUMLOCK_ON)
|
||||
SP->key_modifiers |= PDC_KEY_MODIFIER_NUMLOCK;
|
||||
|
||||
/* Handle modifier keys hit by themselves */
|
||||
|
||||
switch (vk)
|
||||
{
|
||||
case VK_SHIFT: /* shift */
|
||||
if (!SP->return_key_modifiers)
|
||||
return -1;
|
||||
|
||||
return (left_key & 0x8000) ? KEY_SHIFT_L : KEY_SHIFT_R;
|
||||
|
||||
case VK_CONTROL: /* control */
|
||||
if (!SP->return_key_modifiers)
|
||||
return -1;
|
||||
|
||||
return (left_key & 0x8000) ? KEY_CONTROL_L : KEY_CONTROL_R;
|
||||
|
||||
case VK_MENU: /* alt */
|
||||
if (!key)
|
||||
{
|
||||
if (!SP->return_key_modifiers)
|
||||
return -1;
|
||||
|
||||
return (left_key & 0x8000) ? KEY_ALT_L : KEY_ALT_R;
|
||||
}
|
||||
}
|
||||
|
||||
/* The system may emit Ascii or Unicode characters depending on
|
||||
whether ReadConsoleInputA or ReadConsoleInputW is used.
|
||||
|
||||
Normally, if key != 0 then the system did the translation
|
||||
successfully. But this is not true for LEFT_ALT (different to
|
||||
RIGHT_ALT). In case of LEFT_ALT we can get key != 0. So
|
||||
check for this first. */
|
||||
|
||||
if (key && ( !(state & LEFT_ALT_PRESSED) ||
|
||||
(state & RIGHT_ALT_PRESSED) ))
|
||||
{
|
||||
/* This code should catch all keys returning a printable
|
||||
character. Characters above 0x7F should be returned as
|
||||
positive codes. */
|
||||
|
||||
if (kptab[vk].extended == 0)
|
||||
{
|
||||
SP->key_code = FALSE;
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
/* This case happens if a functional key has been entered. */
|
||||
|
||||
if ((state & ENHANCED_KEY) && (kptab[vk].extended != 999))
|
||||
{
|
||||
enhanced = TRUE;
|
||||
idx = kptab[vk].extended;
|
||||
}
|
||||
else
|
||||
{
|
||||
enhanced = FALSE;
|
||||
idx = vk;
|
||||
}
|
||||
|
||||
if (state & SHIFT_PRESSED)
|
||||
key = enhanced ? ext_kptab[idx].shift : kptab[idx].shift;
|
||||
|
||||
else if (state & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
|
||||
key = enhanced ? ext_kptab[idx].control : kptab[idx].control;
|
||||
|
||||
else if (state & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED))
|
||||
key = enhanced ? ext_kptab[idx].alt : kptab[idx].alt;
|
||||
|
||||
else
|
||||
key = enhanced ? ext_kptab[idx].normal : kptab[idx].normal;
|
||||
|
||||
if (key < KEY_CODE_YES)
|
||||
SP->key_code = FALSE;
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static int _process_mouse_event(void)
|
||||
{
|
||||
static const DWORD button_mask[] = {1, 4, 2};
|
||||
short action, shift_flags = 0;
|
||||
int i;
|
||||
|
||||
save_press = 0;
|
||||
SP->key_code = TRUE;
|
||||
|
||||
memset(&SP->mouse_status, 0, sizeof(MOUSE_STATUS));
|
||||
|
||||
/* Handle scroll wheel */
|
||||
|
||||
if (MEV.dwEventFlags == 4)
|
||||
{
|
||||
SP->mouse_status.changes = (MEV.dwButtonState & 0xFF000000) ?
|
||||
PDC_MOUSE_WHEEL_DOWN : PDC_MOUSE_WHEEL_UP;
|
||||
|
||||
SP->mouse_status.x = -1;
|
||||
SP->mouse_status.y = -1;
|
||||
|
||||
memset(&old_mouse_status, 0, sizeof(old_mouse_status));
|
||||
|
||||
return KEY_MOUSE;
|
||||
}
|
||||
|
||||
if (MEV.dwEventFlags == 8)
|
||||
{
|
||||
SP->mouse_status.changes = (MEV.dwButtonState & 0xFF000000) ?
|
||||
PDC_MOUSE_WHEEL_RIGHT : PDC_MOUSE_WHEEL_LEFT;
|
||||
|
||||
SP->mouse_status.x = -1;
|
||||
SP->mouse_status.y = -1;
|
||||
|
||||
memset(&old_mouse_status, 0, sizeof(old_mouse_status));
|
||||
|
||||
return KEY_MOUSE;
|
||||
}
|
||||
|
||||
action = (MEV.dwEventFlags == 2) ? BUTTON_DOUBLE_CLICKED :
|
||||
((MEV.dwEventFlags == 1) ? BUTTON_MOVED : BUTTON_PRESSED);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
SP->mouse_status.button[i] =
|
||||
(MEV.dwButtonState & button_mask[i]) ? action : 0;
|
||||
|
||||
if (action == BUTTON_PRESSED && MEV.dwButtonState & 7 && SP->mouse_wait)
|
||||
{
|
||||
/* Check for a click -- a PRESS followed immediately by a release */
|
||||
|
||||
if (!event_count)
|
||||
{
|
||||
napms(SP->mouse_wait);
|
||||
|
||||
GetNumberOfConsoleInputEvents(pdc_con_in, &event_count);
|
||||
}
|
||||
|
||||
if (event_count)
|
||||
{
|
||||
INPUT_RECORD ip;
|
||||
DWORD count;
|
||||
bool have_click = FALSE;
|
||||
|
||||
PeekConsoleInput(pdc_con_in, &ip, 1, &count);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (SP->mouse_status.button[i] == BUTTON_PRESSED &&
|
||||
!(ip.Event.MouseEvent.dwButtonState & button_mask[i]))
|
||||
{
|
||||
SP->mouse_status.button[i] = BUTTON_CLICKED;
|
||||
have_click = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If a click was found, throw out the event */
|
||||
|
||||
if (have_click)
|
||||
ReadConsoleInput(pdc_con_in, &ip, 1, &count);
|
||||
}
|
||||
}
|
||||
|
||||
SP->mouse_status.x = MEV.dwMousePosition.X;
|
||||
SP->mouse_status.y = MEV.dwMousePosition.Y;
|
||||
|
||||
SP->mouse_status.changes = 0;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (old_mouse_status.button[i] != SP->mouse_status.button[i])
|
||||
SP->mouse_status.changes |= (1 << i);
|
||||
|
||||
if (SP->mouse_status.button[i] == BUTTON_MOVED)
|
||||
{
|
||||
/* Discard non-moved "moves" */
|
||||
|
||||
if (SP->mouse_status.x == old_mouse_status.x &&
|
||||
SP->mouse_status.y == old_mouse_status.y)
|
||||
return -1;
|
||||
|
||||
/* Motion events always flag the button as changed */
|
||||
|
||||
SP->mouse_status.changes |= (1 << i);
|
||||
SP->mouse_status.changes |= PDC_MOUSE_MOVED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
old_mouse_status = SP->mouse_status;
|
||||
|
||||
/* Treat click events as release events for comparison purposes */
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (old_mouse_status.button[i] == BUTTON_CLICKED ||
|
||||
old_mouse_status.button[i] == BUTTON_DOUBLE_CLICKED)
|
||||
old_mouse_status.button[i] = BUTTON_RELEASED;
|
||||
}
|
||||
|
||||
/* Check for SHIFT/CONTROL/ALT */
|
||||
|
||||
if (MEV.dwControlKeyState & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED))
|
||||
shift_flags |= BUTTON_ALT;
|
||||
|
||||
if (MEV.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
|
||||
shift_flags |= BUTTON_CONTROL;
|
||||
|
||||
if (MEV.dwControlKeyState & SHIFT_PRESSED)
|
||||
shift_flags |= BUTTON_SHIFT;
|
||||
|
||||
if (shift_flags)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (SP->mouse_status.changes & (1 << i))
|
||||
SP->mouse_status.button[i] |= shift_flags;
|
||||
}
|
||||
}
|
||||
|
||||
return KEY_MOUSE;
|
||||
}
|
||||
|
||||
/* return the next available key or mouse event */
|
||||
|
||||
int PDC_get_key(void)
|
||||
{
|
||||
SP->key_modifiers = 0L;
|
||||
|
||||
if (!key_count)
|
||||
{
|
||||
DWORD count;
|
||||
|
||||
ReadConsoleInput(pdc_con_in, &save_ip, 1, &count);
|
||||
event_count--;
|
||||
|
||||
if (save_ip.EventType == MOUSE_EVENT ||
|
||||
save_ip.EventType == WINDOW_BUFFER_SIZE_EVENT)
|
||||
key_count = 1;
|
||||
else if (save_ip.EventType == KEY_EVENT)
|
||||
key_count = _get_key_count();
|
||||
}
|
||||
|
||||
if (key_count)
|
||||
{
|
||||
key_count--;
|
||||
|
||||
switch (save_ip.EventType)
|
||||
{
|
||||
case KEY_EVENT:
|
||||
return _process_key_event();
|
||||
|
||||
case MOUSE_EVENT:
|
||||
return _process_mouse_event();
|
||||
|
||||
case WINDOW_BUFFER_SIZE_EVENT:
|
||||
if (REV.dwSize.Y != LINES || REV.dwSize.X != COLS)
|
||||
{
|
||||
if (!SP->resized)
|
||||
{
|
||||
SP->resized = TRUE;
|
||||
SP->key_code = TRUE;
|
||||
return KEY_RESIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* discard any pending keyboard or mouse input -- this is the core
|
||||
routine for flushinp() */
|
||||
|
||||
void PDC_flushinp(void)
|
||||
{
|
||||
PDC_LOG(("PDC_flushinp() - called\n"));
|
||||
|
||||
FlushConsoleInputBuffer(pdc_con_in);
|
||||
}
|
||||
|
||||
bool PDC_has_mouse(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int PDC_mouse_set(void)
|
||||
{
|
||||
DWORD mode;
|
||||
|
||||
/* If turning on mouse input: Set ENABLE_MOUSE_INPUT, and clear
|
||||
all other flags, except processed input mode;
|
||||
If turning off the mouse: Set QuickEdit Mode to the status it
|
||||
had on startup, and clear all other flags, except etc. */
|
||||
|
||||
GetConsoleMode(pdc_con_in, &mode);
|
||||
mode = (mode & 1) | 0x0088;
|
||||
SetConsoleMode(pdc_con_in, mode | (SP->_trap_mbe ?
|
||||
ENABLE_MOUSE_INPUT : pdc_quick_edit));
|
||||
|
||||
memset(&old_mouse_status, 0, sizeof(old_mouse_status));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int PDC_modifiers_set(void)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
686
wincon/pdcscrn.c
Normal file
686
wincon/pdcscrn.c
Normal file
@@ -0,0 +1,686 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include "pdcwin.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Color component table */
|
||||
|
||||
PDCCOLOR pdc_color[PDC_MAXCOL];
|
||||
|
||||
HANDLE std_con_out = INVALID_HANDLE_VALUE;
|
||||
HANDLE pdc_con_out = INVALID_HANDLE_VALUE;
|
||||
HANDLE pdc_con_in = INVALID_HANDLE_VALUE;
|
||||
|
||||
DWORD pdc_quick_edit;
|
||||
|
||||
static short realtocurs[16] =
|
||||
{
|
||||
COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_RED,
|
||||
COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE, COLOR_BLACK + 8,
|
||||
COLOR_BLUE + 8, COLOR_GREEN + 8, COLOR_CYAN + 8, COLOR_RED + 8,
|
||||
COLOR_MAGENTA + 8, COLOR_YELLOW + 8, COLOR_WHITE + 8
|
||||
};
|
||||
|
||||
static short ansitocurs[16] =
|
||||
{
|
||||
COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE,
|
||||
COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE, COLOR_BLACK + 8,
|
||||
COLOR_RED + 8, COLOR_GREEN + 8, COLOR_YELLOW + 8, COLOR_BLUE + 8,
|
||||
COLOR_MAGENTA + 8, COLOR_CYAN + 8, COLOR_WHITE + 8
|
||||
};
|
||||
|
||||
short pdc_curstoreal[16], pdc_curstoansi[16];
|
||||
short pdc_oldf, pdc_oldb, pdc_oldu;
|
||||
bool pdc_conemu, pdc_wt, pdc_ansi;
|
||||
|
||||
enum { PDC_RESTORE_NONE, PDC_RESTORE_BUFFER };
|
||||
|
||||
/* Struct for storing console registry keys, and for use with the
|
||||
undocumented WM_SETCONSOLEINFO message. Originally by James Brown,
|
||||
www.catch22.net. */
|
||||
|
||||
static struct
|
||||
{
|
||||
ULONG Length;
|
||||
COORD ScreenBufferSize;
|
||||
COORD WindowSize;
|
||||
ULONG WindowPosX;
|
||||
ULONG WindowPosY;
|
||||
|
||||
COORD FontSize;
|
||||
ULONG FontFamily;
|
||||
ULONG FontWeight;
|
||||
WCHAR FaceName[32];
|
||||
|
||||
ULONG CursorSize;
|
||||
ULONG FullScreen;
|
||||
ULONG QuickEdit;
|
||||
ULONG AutoPosition;
|
||||
ULONG InsertMode;
|
||||
|
||||
USHORT ScreenColors;
|
||||
USHORT PopupColors;
|
||||
ULONG HistoryNoDup;
|
||||
ULONG HistoryBufferSize;
|
||||
ULONG NumberOfHistoryBuffers;
|
||||
|
||||
COLORREF ColorTable[16];
|
||||
|
||||
ULONG CodePage;
|
||||
HWND Hwnd;
|
||||
|
||||
WCHAR ConsoleTitle[0x100];
|
||||
} console_info;
|
||||
|
||||
#ifdef HAVE_NO_INFOEX
|
||||
/* Console screen buffer information (extended version) */
|
||||
typedef struct _CONSOLE_SCREEN_BUFFER_INFOEX {
|
||||
ULONG cbSize;
|
||||
COORD dwSize;
|
||||
COORD dwCursorPosition;
|
||||
WORD wAttributes;
|
||||
SMALL_RECT srWindow;
|
||||
COORD dwMaximumWindowSize;
|
||||
WORD wPopupAttributes;
|
||||
BOOL bFullscreenSupported;
|
||||
COLORREF ColorTable[16];
|
||||
} CONSOLE_SCREEN_BUFFER_INFOEX;
|
||||
typedef CONSOLE_SCREEN_BUFFER_INFOEX *PCONSOLE_SCREEN_BUFFER_INFOEX;
|
||||
#endif
|
||||
|
||||
typedef BOOL (WINAPI *SetConsoleScreenBufferInfoExFn)(HANDLE hConsoleOutput,
|
||||
PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx);
|
||||
typedef BOOL (WINAPI *GetConsoleScreenBufferInfoExFn)(HANDLE hConsoleOutput,
|
||||
PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx);
|
||||
|
||||
static SetConsoleScreenBufferInfoExFn pSetConsoleScreenBufferInfoEx = NULL;
|
||||
static GetConsoleScreenBufferInfoExFn pGetConsoleScreenBufferInfoEx = NULL;
|
||||
|
||||
static CONSOLE_SCREEN_BUFFER_INFO orig_scr;
|
||||
static CONSOLE_SCREEN_BUFFER_INFOEX console_infoex;
|
||||
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER xcpt_filter;
|
||||
|
||||
static DWORD old_console_mode = 0;
|
||||
|
||||
static bool is_nt;
|
||||
|
||||
static void _reset_old_colors(void)
|
||||
{
|
||||
pdc_oldf = -1;
|
||||
pdc_oldb = -1;
|
||||
pdc_oldu = 0;
|
||||
}
|
||||
|
||||
static HWND _find_console_handle(void)
|
||||
{
|
||||
TCHAR orgtitle[1024], temptitle[1024];
|
||||
HWND wnd;
|
||||
|
||||
GetConsoleTitle(orgtitle, 1024);
|
||||
|
||||
wsprintf(temptitle, TEXT("%d/%d"), GetTickCount(), GetCurrentProcessId());
|
||||
SetConsoleTitle(temptitle);
|
||||
|
||||
Sleep(40);
|
||||
|
||||
wnd = FindWindow(NULL, temptitle);
|
||||
|
||||
SetConsoleTitle(orgtitle);
|
||||
|
||||
return wnd;
|
||||
}
|
||||
|
||||
/* Undocumented console message */
|
||||
|
||||
#define WM_SETCONSOLEINFO (WM_USER + 201)
|
||||
|
||||
/* Wrapper around WM_SETCONSOLEINFO. We need to create the necessary
|
||||
section (file-mapping) object in the context of the process which
|
||||
owns the console, before posting the message. Originally by JB. */
|
||||
|
||||
static void _set_console_info(void)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
CONSOLE_CURSOR_INFO cci;
|
||||
DWORD dwConsoleOwnerPid;
|
||||
HANDLE hProcess;
|
||||
HANDLE hSection, hDupSection;
|
||||
PVOID ptrView;
|
||||
|
||||
/* Each-time initialization for console_info */
|
||||
|
||||
GetConsoleCursorInfo(pdc_con_out, &cci);
|
||||
console_info.CursorSize = cci.dwSize;
|
||||
|
||||
GetConsoleScreenBufferInfo(pdc_con_out, &csbi);
|
||||
console_info.ScreenBufferSize = csbi.dwSize;
|
||||
|
||||
console_info.WindowSize.X = csbi.srWindow.Right - csbi.srWindow.Left + 1;
|
||||
console_info.WindowSize.Y = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
|
||||
|
||||
console_info.WindowPosX = csbi.srWindow.Left;
|
||||
console_info.WindowPosY = csbi.srWindow.Top;
|
||||
|
||||
/* Open the process which "owns" the console */
|
||||
|
||||
GetWindowThreadProcessId(console_info.Hwnd, &dwConsoleOwnerPid);
|
||||
|
||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwConsoleOwnerPid);
|
||||
|
||||
/* Create a SECTION object backed by page-file, then map a view of
|
||||
this section into the owner process so we can write the contents
|
||||
of the CONSOLE_INFO buffer into it */
|
||||
|
||||
hSection = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE,
|
||||
0, sizeof(console_info), 0);
|
||||
|
||||
/* Copy our console structure into the section-object */
|
||||
|
||||
ptrView = MapViewOfFile(hSection, FILE_MAP_WRITE|FILE_MAP_READ,
|
||||
0, 0, sizeof(console_info));
|
||||
|
||||
memcpy(ptrView, &console_info, sizeof(console_info));
|
||||
|
||||
UnmapViewOfFile(ptrView);
|
||||
|
||||
/* Map the memory into owner process */
|
||||
|
||||
DuplicateHandle(GetCurrentProcess(), hSection, hProcess, &hDupSection,
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS);
|
||||
|
||||
/* Send console window the "update" message */
|
||||
|
||||
SendMessage(console_info.Hwnd, WM_SETCONSOLEINFO, (WPARAM)hDupSection, 0);
|
||||
|
||||
CloseHandle(hSection);
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
|
||||
static int _set_console_infoex(void)
|
||||
{
|
||||
if (!pSetConsoleScreenBufferInfoEx(pdc_con_out, &console_infoex))
|
||||
return ERR;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int _set_colors(void)
|
||||
{
|
||||
SetConsoleTextAttribute(pdc_con_out, 7);
|
||||
_reset_old_colors();
|
||||
|
||||
if (pSetConsoleScreenBufferInfoEx)
|
||||
return _set_console_infoex();
|
||||
else
|
||||
{
|
||||
_set_console_info();
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* One-time initialization for console_info -- color table and font info
|
||||
from the registry; other values from functions. */
|
||||
|
||||
static void _init_console_info(void)
|
||||
{
|
||||
DWORD scrnmode, len;
|
||||
HKEY reghnd;
|
||||
int i;
|
||||
|
||||
console_info.Hwnd = _find_console_handle();
|
||||
console_info.Length = sizeof(console_info);
|
||||
|
||||
GetConsoleMode(pdc_con_in, &scrnmode);
|
||||
console_info.QuickEdit = !!(scrnmode & 0x0040);
|
||||
console_info.InsertMode = !!(scrnmode & 0x0020);
|
||||
|
||||
console_info.FullScreen = FALSE;
|
||||
console_info.AutoPosition = 0x10000;
|
||||
console_info.ScreenColors = SP->orig_back << 4 | SP->orig_fore;
|
||||
console_info.PopupColors = 0xf5;
|
||||
|
||||
console_info.HistoryNoDup = FALSE;
|
||||
console_info.HistoryBufferSize = 50;
|
||||
console_info.NumberOfHistoryBuffers = 4;
|
||||
|
||||
console_info.CodePage = GetConsoleOutputCP();
|
||||
|
||||
RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Console"), 0,
|
||||
KEY_QUERY_VALUE, ®hnd);
|
||||
|
||||
len = sizeof(DWORD);
|
||||
|
||||
/* Default color table */
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
char tname[13];
|
||||
|
||||
sprintf(tname, "ColorTable%02d", i);
|
||||
RegQueryValueExA(reghnd, tname, NULL, NULL,
|
||||
(LPBYTE)(&(console_info.ColorTable[i])), &len);
|
||||
}
|
||||
|
||||
/* Font info */
|
||||
|
||||
RegQueryValueEx(reghnd, TEXT("FontSize"), NULL, NULL,
|
||||
(LPBYTE)(&console_info.FontSize), &len);
|
||||
RegQueryValueEx(reghnd, TEXT("FontFamily"), NULL, NULL,
|
||||
(LPBYTE)(&console_info.FontFamily), &len);
|
||||
RegQueryValueEx(reghnd, TEXT("FontWeight"), NULL, NULL,
|
||||
(LPBYTE)(&console_info.FontWeight), &len);
|
||||
|
||||
len = sizeof(WCHAR) * 32;
|
||||
RegQueryValueExW(reghnd, L"FaceName", NULL, NULL,
|
||||
(LPBYTE)(console_info.FaceName), &len);
|
||||
|
||||
RegCloseKey(reghnd);
|
||||
}
|
||||
|
||||
static int _init_console_infoex(void)
|
||||
{
|
||||
console_infoex.cbSize = sizeof(console_infoex);
|
||||
|
||||
if (!pGetConsoleScreenBufferInfoEx(pdc_con_out, &console_infoex))
|
||||
return ERR;
|
||||
|
||||
console_infoex.srWindow.Right++;
|
||||
console_infoex.srWindow.Bottom++;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static COLORREF *_get_colors(void)
|
||||
{
|
||||
if (pGetConsoleScreenBufferInfoEx)
|
||||
{
|
||||
int status = OK;
|
||||
if (!console_infoex.cbSize)
|
||||
status = _init_console_infoex();
|
||||
return (status == ERR) ? NULL :
|
||||
(COLORREF *)(&(console_infoex.ColorTable));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!console_info.Hwnd)
|
||||
_init_console_info();
|
||||
return (COLORREF *)(&(console_info.ColorTable));
|
||||
}
|
||||
}
|
||||
|
||||
/* restore the original console buffer in the event of a crash */
|
||||
|
||||
static LONG WINAPI _restore_console(LPEXCEPTION_POINTERS ep)
|
||||
{
|
||||
PDC_scr_close();
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
/* restore the original console buffer on Ctrl+Break (or Ctrl+C,
|
||||
if it gets re-enabled) */
|
||||
|
||||
static BOOL WINAPI _ctrl_break(DWORD dwCtrlType)
|
||||
{
|
||||
if (dwCtrlType == CTRL_BREAK_EVENT || dwCtrlType == CTRL_C_EVENT)
|
||||
PDC_scr_close();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* close the physical screen -- may restore the screen to its state
|
||||
before PDC_scr_open(); miscellaneous cleanup */
|
||||
|
||||
void PDC_scr_close(void)
|
||||
{
|
||||
PDC_LOG(("PDC_scr_close() - called\n"));
|
||||
|
||||
if (SP->visibility != 1)
|
||||
curs_set(1);
|
||||
|
||||
PDC_reset_shell_mode();
|
||||
|
||||
/* Position cursor to the bottom left of the screen. */
|
||||
|
||||
if (SP->_restore == PDC_RESTORE_NONE)
|
||||
{
|
||||
SMALL_RECT win;
|
||||
|
||||
win.Left = orig_scr.srWindow.Left;
|
||||
win.Right = orig_scr.srWindow.Right;
|
||||
win.Top = 0;
|
||||
win.Bottom = orig_scr.srWindow.Bottom - orig_scr.srWindow.Top;
|
||||
SetConsoleWindowInfo(pdc_con_out, TRUE, &win);
|
||||
PDC_gotoyx(win.Bottom, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void PDC_scr_free(void)
|
||||
{
|
||||
if (pdc_con_out != std_con_out)
|
||||
{
|
||||
CloseHandle(pdc_con_out);
|
||||
pdc_con_out = std_con_out;
|
||||
}
|
||||
|
||||
SetUnhandledExceptionFilter(xcpt_filter);
|
||||
SetConsoleCtrlHandler(_ctrl_break, FALSE);
|
||||
}
|
||||
|
||||
/* open the physical screen -- miscellaneous initialization, may save
|
||||
the existing screen for later restoration */
|
||||
|
||||
int PDC_scr_open(void)
|
||||
{
|
||||
const char *str;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
HMODULE h_kernel;
|
||||
BOOL result;
|
||||
int i;
|
||||
|
||||
PDC_LOG(("PDC_scr_open() - called\n"));
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
pdc_curstoreal[realtocurs[i]] = i;
|
||||
pdc_curstoansi[ansitocurs[i]] = i;
|
||||
}
|
||||
_reset_old_colors();
|
||||
|
||||
std_con_out =
|
||||
pdc_con_out = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
pdc_con_in = GetStdHandle(STD_INPUT_HANDLE);
|
||||
|
||||
if (GetFileType(pdc_con_in) != FILE_TYPE_CHAR)
|
||||
{
|
||||
fprintf(stderr, "\nRedirection is not supported.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
is_nt = !(GetVersion() & 0x80000000);
|
||||
|
||||
pdc_wt = !!getenv("WT_SESSION");
|
||||
str = pdc_wt ? NULL : getenv("ConEmuANSI");
|
||||
pdc_conemu = !!str;
|
||||
pdc_ansi = pdc_wt ? TRUE : pdc_conemu ? !strcmp(str, "ON") : FALSE;
|
||||
|
||||
GetConsoleScreenBufferInfo(pdc_con_out, &csbi);
|
||||
GetConsoleScreenBufferInfo(pdc_con_out, &orig_scr);
|
||||
GetConsoleMode(pdc_con_in, &old_console_mode);
|
||||
|
||||
/* preserve QuickEdit Mode setting for use in PDC_mouse_set() when
|
||||
the mouse is not enabled -- other console input settings are
|
||||
cleared */
|
||||
|
||||
pdc_quick_edit = old_console_mode & 0x0040;
|
||||
|
||||
SP->mouse_wait = PDC_CLICK_PERIOD;
|
||||
SP->audible = TRUE;
|
||||
|
||||
SP->termattrs = A_COLOR | A_REVERSE;
|
||||
if (pdc_ansi)
|
||||
SP->termattrs |= A_UNDERLINE | A_ITALIC;
|
||||
|
||||
SP->orig_fore = csbi.wAttributes & 0x0f;
|
||||
SP->orig_back = (csbi.wAttributes & 0xf0) >> 4;
|
||||
|
||||
SP->orig_attr = TRUE;
|
||||
|
||||
SP->_restore = PDC_RESTORE_NONE;
|
||||
|
||||
if ((str = getenv("PDC_RESTORE_SCREEN")) == NULL || *str != '0')
|
||||
{
|
||||
/* Create a new console buffer */
|
||||
|
||||
pdc_con_out =
|
||||
CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
|
||||
|
||||
if (pdc_con_out == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
PDC_LOG(("PDC_scr_open() - screen buffer failure\n"));
|
||||
|
||||
pdc_con_out = std_con_out;
|
||||
}
|
||||
else
|
||||
SP->_restore = PDC_RESTORE_BUFFER;
|
||||
}
|
||||
|
||||
xcpt_filter = SetUnhandledExceptionFilter(_restore_console);
|
||||
SetConsoleCtrlHandler(_ctrl_break, TRUE);
|
||||
|
||||
SP->_preserve = (getenv("PDC_PRESERVE_SCREEN") != NULL);
|
||||
|
||||
/* ENABLE_LVB_GRID_WORLDWIDE */
|
||||
result = SetConsoleMode(pdc_con_out, 0x0010);
|
||||
if (result)
|
||||
SP->termattrs |= A_UNDERLINE | A_LEFT | A_RIGHT;
|
||||
|
||||
PDC_reset_prog_mode();
|
||||
|
||||
SP->mono = FALSE;
|
||||
|
||||
h_kernel = GetModuleHandleA("kernel32.dll");
|
||||
pGetConsoleScreenBufferInfoEx =
|
||||
(GetConsoleScreenBufferInfoExFn)GetProcAddress(h_kernel,
|
||||
"GetConsoleScreenBufferInfoEx");
|
||||
pSetConsoleScreenBufferInfoEx =
|
||||
(SetConsoleScreenBufferInfoExFn)GetProcAddress(h_kernel,
|
||||
"SetConsoleScreenBufferInfoEx");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Calls SetConsoleWindowInfo with the given parameters, but fits them
|
||||
if a scoll bar shrinks the maximum possible value. The rectangle
|
||||
must at least fit in a half-sized window. */
|
||||
|
||||
static BOOL _fit_console_window(HANDLE con_out, CONST SMALL_RECT *rect)
|
||||
{
|
||||
SMALL_RECT run;
|
||||
SHORT mx, my;
|
||||
|
||||
if (SetConsoleWindowInfo(con_out, TRUE, rect))
|
||||
return TRUE;
|
||||
|
||||
run = *rect;
|
||||
run.Right /= 2;
|
||||
run.Bottom /= 2;
|
||||
|
||||
mx = run.Right;
|
||||
my = run.Bottom;
|
||||
|
||||
if (!SetConsoleWindowInfo(con_out, TRUE, &run))
|
||||
return FALSE;
|
||||
|
||||
for (run.Right = rect->Right; run.Right >= mx; run.Right--)
|
||||
if (SetConsoleWindowInfo(con_out, TRUE, &run))
|
||||
break;
|
||||
|
||||
if (run.Right < mx)
|
||||
return FALSE;
|
||||
|
||||
for (run.Bottom = rect->Bottom; run.Bottom >= my; run.Bottom--)
|
||||
if (SetConsoleWindowInfo(con_out, TRUE, &run))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* the core of resize_term() */
|
||||
|
||||
int PDC_resize_screen(int nlines, int ncols)
|
||||
{
|
||||
SMALL_RECT rect;
|
||||
COORD size, max;
|
||||
|
||||
bool prog_resize = nlines || ncols;
|
||||
|
||||
if (!prog_resize)
|
||||
{
|
||||
nlines = PDC_get_rows();
|
||||
ncols = PDC_get_columns();
|
||||
}
|
||||
|
||||
if (nlines < 2 || ncols < 2)
|
||||
return ERR;
|
||||
|
||||
max = GetLargestConsoleWindowSize(pdc_con_out);
|
||||
|
||||
rect.Left = rect.Top = 0;
|
||||
rect.Right = ncols - 1;
|
||||
|
||||
if (rect.Right > max.X)
|
||||
rect.Right = max.X;
|
||||
|
||||
rect.Bottom = nlines - 1;
|
||||
|
||||
if (rect.Bottom > max.Y)
|
||||
rect.Bottom = max.Y;
|
||||
|
||||
size.X = rect.Right + 1;
|
||||
size.Y = rect.Bottom + 1;
|
||||
|
||||
_fit_console_window(pdc_con_out, &rect);
|
||||
SetConsoleScreenBufferSize(pdc_con_out, size);
|
||||
|
||||
if (prog_resize)
|
||||
{
|
||||
_fit_console_window(pdc_con_out, &rect);
|
||||
SetConsoleScreenBufferSize(pdc_con_out, size);
|
||||
}
|
||||
SetConsoleActiveScreenBuffer(pdc_con_out);
|
||||
|
||||
PDC_flushinp();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void PDC_reset_prog_mode(void)
|
||||
{
|
||||
PDC_LOG(("PDC_reset_prog_mode() - called.\n"));
|
||||
|
||||
if (pdc_con_out != std_con_out)
|
||||
SetConsoleActiveScreenBuffer(pdc_con_out);
|
||||
else if (is_nt)
|
||||
{
|
||||
COORD bufsize;
|
||||
SMALL_RECT rect;
|
||||
|
||||
bufsize.X = orig_scr.srWindow.Right - orig_scr.srWindow.Left + 1;
|
||||
bufsize.Y = orig_scr.srWindow.Bottom - orig_scr.srWindow.Top + 1;
|
||||
|
||||
rect.Top = rect.Left = 0;
|
||||
rect.Bottom = bufsize.Y - 1;
|
||||
rect.Right = bufsize.X - 1;
|
||||
|
||||
SetConsoleScreenBufferSize(pdc_con_out, bufsize);
|
||||
SetConsoleWindowInfo(pdc_con_out, TRUE, &rect);
|
||||
SetConsoleScreenBufferSize(pdc_con_out, bufsize);
|
||||
SetConsoleActiveScreenBuffer(pdc_con_out);
|
||||
}
|
||||
|
||||
PDC_mouse_set();
|
||||
}
|
||||
|
||||
void PDC_reset_shell_mode(void)
|
||||
{
|
||||
PDC_LOG(("PDC_reset_shell_mode() - called.\n"));
|
||||
|
||||
if (pdc_con_out != std_con_out)
|
||||
SetConsoleActiveScreenBuffer(std_con_out);
|
||||
else if (is_nt)
|
||||
{
|
||||
SetConsoleScreenBufferSize(pdc_con_out, orig_scr.dwSize);
|
||||
SetConsoleWindowInfo(pdc_con_out, TRUE, &orig_scr.srWindow);
|
||||
SetConsoleScreenBufferSize(pdc_con_out, orig_scr.dwSize);
|
||||
SetConsoleWindowInfo(pdc_con_out, TRUE, &orig_scr.srWindow);
|
||||
SetConsoleActiveScreenBuffer(pdc_con_out);
|
||||
}
|
||||
|
||||
SetConsoleMode(pdc_con_in, old_console_mode | 0x0080);
|
||||
}
|
||||
|
||||
void PDC_restore_screen_mode(int i)
|
||||
{
|
||||
}
|
||||
|
||||
void PDC_save_screen_mode(int i)
|
||||
{
|
||||
}
|
||||
|
||||
bool PDC_can_change_color(void)
|
||||
{
|
||||
return is_nt;
|
||||
}
|
||||
|
||||
int PDC_color_content(short color, short *red, short *green, short *blue)
|
||||
{
|
||||
if (color < 16 && !(pdc_conemu || pdc_wt))
|
||||
{
|
||||
COLORREF *color_table = _get_colors();
|
||||
|
||||
if (color_table)
|
||||
{
|
||||
DWORD col = color_table[pdc_curstoreal[color]];
|
||||
|
||||
*red = DIVROUND(GetRValue(col) * 1000, 255);
|
||||
*green = DIVROUND(GetGValue(col) * 1000, 255);
|
||||
*blue = DIVROUND(GetBValue(col) * 1000, 255);
|
||||
}
|
||||
else
|
||||
return ERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pdc_color[color].mapped)
|
||||
{
|
||||
*red = *green = *blue = -1;
|
||||
return ERR;
|
||||
}
|
||||
|
||||
*red = pdc_color[color].r;
|
||||
*green = pdc_color[color].g;
|
||||
*blue = pdc_color[color].b;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int PDC_init_color(short color, short red, short green, short blue)
|
||||
{
|
||||
if (red == -1 && green == -1 && blue == -1)
|
||||
{
|
||||
pdc_color[color].mapped = FALSE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (color < 16 && !(pdc_conemu || pdc_wt))
|
||||
{
|
||||
COLORREF *color_table = _get_colors();
|
||||
|
||||
if (color_table)
|
||||
{
|
||||
color_table[pdc_curstoreal[color]] =
|
||||
RGB(DIVROUND(red * 255, 1000),
|
||||
DIVROUND(green * 255, 1000),
|
||||
DIVROUND(blue * 255, 1000));
|
||||
|
||||
return _set_colors();
|
||||
}
|
||||
|
||||
return ERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdc_color[color].r = red;
|
||||
pdc_color[color].g = green;
|
||||
pdc_color[color].b = blue;
|
||||
pdc_color[color].mapped = TRUE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
130
wincon/pdcsetsc.c
Normal file
130
wincon/pdcsetsc.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include "pdcwin.h"
|
||||
|
||||
/*man-start**************************************************************
|
||||
|
||||
pdcsetsc
|
||||
--------
|
||||
|
||||
### Synopsis
|
||||
|
||||
int PDC_set_blink(bool blinkon);
|
||||
int PDC_set_bold(bool boldon);
|
||||
void PDC_set_title(const char *title);
|
||||
|
||||
### Description
|
||||
|
||||
PDC_set_blink() toggles whether the A_BLINK attribute sets an actual
|
||||
blink mode (TRUE), or sets the background color to high intensity
|
||||
(FALSE). The default is platform-dependent (FALSE in most cases). It
|
||||
returns OK if it could set the state to match the given parameter,
|
||||
ERR otherwise.
|
||||
|
||||
PDC_set_bold() toggles whether the A_BOLD attribute selects an actual
|
||||
bold font (TRUE), or sets the foreground color to high intensity
|
||||
(FALSE). It returns OK if it could set the state to match the given
|
||||
parameter, ERR otherwise.
|
||||
|
||||
PDC_set_title() sets the title of the window in which the curses
|
||||
program is running. This function may not do anything on some
|
||||
platforms.
|
||||
|
||||
### Portability
|
||||
X/Open ncurses NetBSD
|
||||
PDC_set_blink - - -
|
||||
PDC_set_title - - -
|
||||
|
||||
**man-end****************************************************************/
|
||||
|
||||
int PDC_curs_set(int visibility)
|
||||
{
|
||||
CONSOLE_CURSOR_INFO cci;
|
||||
int ret_vis;
|
||||
|
||||
PDC_LOG(("PDC_curs_set() - called: visibility=%d\n", visibility));
|
||||
|
||||
ret_vis = SP->visibility;
|
||||
|
||||
if (GetConsoleCursorInfo(pdc_con_out, &cci) == FALSE)
|
||||
return ERR;
|
||||
|
||||
switch(visibility)
|
||||
{
|
||||
case 0: /* invisible */
|
||||
cci.bVisible = FALSE;
|
||||
break;
|
||||
case 2: /* highly visible */
|
||||
cci.bVisible = TRUE;
|
||||
cci.dwSize = 95;
|
||||
break;
|
||||
default: /* normal visibility */
|
||||
cci.bVisible = TRUE;
|
||||
cci.dwSize = SP->orig_cursor;
|
||||
break;
|
||||
}
|
||||
|
||||
if (SetConsoleCursorInfo(pdc_con_out, &cci) == FALSE)
|
||||
return ERR;
|
||||
|
||||
SP->visibility = visibility;
|
||||
return ret_vis;
|
||||
}
|
||||
|
||||
void PDC_set_title(const char *title)
|
||||
{
|
||||
#ifdef PDC_WIDE
|
||||
wchar_t wtitle[512];
|
||||
#endif
|
||||
PDC_LOG(("PDC_set_title() - called:<%s>\n", title));
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
PDC_mbstowcs(wtitle, title, 511);
|
||||
SetConsoleTitleW(wtitle);
|
||||
#else
|
||||
SetConsoleTitleA(title);
|
||||
#endif
|
||||
}
|
||||
|
||||
int PDC_set_blink(bool blinkon)
|
||||
{
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
if (SP->color_started)
|
||||
{
|
||||
COLORS = 16;
|
||||
if (PDC_can_change_color()) /* is_nt */
|
||||
{
|
||||
if (pdc_conemu || SetConsoleMode(pdc_con_out, 0x0004)) /* VT */
|
||||
COLORS = PDC_MAXCOL;
|
||||
|
||||
if (!pdc_conemu)
|
||||
SetConsoleMode(pdc_con_out, 0x0010); /* LVB */
|
||||
}
|
||||
}
|
||||
|
||||
if (blinkon)
|
||||
{
|
||||
if (!(SP->termattrs & A_BLINK))
|
||||
{
|
||||
SP->termattrs |= A_BLINK;
|
||||
pdc_last_blink = GetTickCount();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SP->termattrs & A_BLINK)
|
||||
{
|
||||
SP->termattrs &= ~A_BLINK;
|
||||
PDC_blink_text();
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int PDC_set_bold(bool boldon)
|
||||
{
|
||||
return boldon ? ERR : OK;
|
||||
}
|
||||
26
wincon/pdcutil.c
Normal file
26
wincon/pdcutil.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/* PDCurses */
|
||||
|
||||
#include "pdcwin.h"
|
||||
|
||||
void PDC_beep(void)
|
||||
{
|
||||
PDC_LOG(("PDC_beep() - called\n"));
|
||||
|
||||
/* MessageBeep(MB_OK); */
|
||||
MessageBeep(0XFFFFFFFF);
|
||||
}
|
||||
|
||||
void PDC_napms(int ms)
|
||||
{
|
||||
PDC_LOG(("PDC_napms() - called: ms=%d\n", ms));
|
||||
|
||||
if ((SP->termattrs & A_BLINK) && (GetTickCount() >= pdc_last_blink + 500))
|
||||
PDC_blink_text();
|
||||
|
||||
Sleep(ms);
|
||||
}
|
||||
|
||||
const char *PDC_sysname(void)
|
||||
{
|
||||
return "Windows";
|
||||
}
|
||||
27
wincon/pdcwin.h
Normal file
27
wincon/pdcwin.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/* PDCurses */
|
||||
|
||||
#if defined(PDC_WIDE) && !defined(UNICODE)
|
||||
# define UNICODE
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef MOUSE_MOVED
|
||||
#include <curspriv.h>
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
|
||||
# define _CRT_SECURE_NO_DEPRECATE 1 /* kill nonsense warnings */
|
||||
#endif
|
||||
|
||||
typedef struct {short r, g, b; bool mapped;} PDCCOLOR;
|
||||
|
||||
extern PDCCOLOR pdc_color[PDC_MAXCOL];
|
||||
|
||||
extern HANDLE pdc_con_out, pdc_con_in;
|
||||
extern DWORD pdc_quick_edit;
|
||||
extern DWORD pdc_last_blink;
|
||||
extern short pdc_curstoreal[16], pdc_curstoansi[16];
|
||||
extern short pdc_oldf, pdc_oldb, pdc_oldu;
|
||||
extern bool pdc_conemu, pdc_wt, pdc_ansi;
|
||||
|
||||
extern void PDC_blink_text(void);
|
||||
Reference in New Issue
Block a user