[GB.NCURSES]

* BUG: Do not call refresh routines when endwin() has already been called.
* NEW: Add an error hook that calls endwin() so that the terminal is reset
  and the error message is visible.


git-svn-id: svn://localhost/gambas/trunk@4622 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2012-04-13 22:11:24 +00:00
parent 572d7aa9e4
commit 643d230193
6 changed files with 81 additions and 34 deletions

View File

@ -8,7 +8,7 @@ AC_PROG_LIBTOOL
GB_COMPONENT(
ncurses,
NCURSES,
[NCURSES component],
[NCurses component],
[src],
[GB_FIND(ncurses.h panel.h, /usr/lib /usr, include)],
[GB_FIND(libncurses.$SHLIBEXT libpanel.$SHLIBEXT, /usr/local /usr, lib)],

View File

@ -53,9 +53,61 @@ DECLARE_EVENT(EVENT_Resize);
void nc_sigwinch_handler(int signum)
{
/* TODO: I wonder if this works... */
/* BM: Of course not! :-) You can't raise an event from a signal handler
* and moreover you have no sender! */
if (signum == SIGWINCH) GB.Raise(NULL, EVENT_Resize, 0);
}
static bool _init = FALSE;
bool NCURSES_running()
{
return _init && (!isendwin() || stdscr);
}
void NCURSES_init(void)
{
struct sigaction sa;
if (_init)
return;
initscr();
/* global variable default setup */
nc_cursor = CURSOR_VISIBLE;
nc_input = INPUT_CBREAK;
nc_echo = 0;
/* accordingly... */
curs_set(1);
cbreak();
noecho();
sa.sa_handler = nc_sigwinch_handler;
sigemptyset(&(sa.sa_mask));
sa.sa_flags = 0;
if (sigaction(SIGWINCH, &sa, NULL) == -1)
{
fprintf(stderr, "gb.ncurses: Could not install SIGWINCH signal handler");
}
refresh();
_init = TRUE;
}
void NCURSES_exit()
{
if (_init)
{
endwin();
_init = FALSE;
}
}
BEGIN_PROPERTY(CNCurses_cursor)
if (READ_PROPERTY)
@ -137,36 +189,13 @@ END_PROPERTY
BEGIN_METHOD_VOID(CNCurses_init)
struct sigaction sa;
initscr();
/* global variable default setup */
nc_cursor = CURSOR_VISIBLE;
nc_input = INPUT_CBREAK;
nc_echo = 0;
/* accordingly... */
curs_set(1);
cbreak();
noecho();
sa.sa_handler = nc_sigwinch_handler;
sigemptyset(&(sa.sa_mask));
sa.sa_flags = 0;
if (sigaction(SIGWINCH, &sa, NULL) == -1)
{
fprintf(stderr, "gb.ncurses: Could not install SIGWINCH signal handler");
}
refresh();
NCURSES_init();
END_METHOD
DECLARE_METHOD(CNCurses_off);
BEGIN_METHOD_VOID(CNCurses_exit)
CALL_METHOD_VOID(CNCurses_off);
NCURSES_exit();
END_METHOD
@ -179,8 +208,7 @@ END_METHOD
BEGIN_METHOD_VOID(CNCurses_off)
if (!NCURSES_RUNNING) return;
if (endwin() == ERR) GB.Error(E_END);
NCURSES_exit();
END_METHOD

View File

@ -27,10 +27,14 @@
#include "gambas.h"
#include "gb_common.h"
#define NCURSES_RUNNING (!isendwin() || stdscr)
#define NCURSES_RUNNING NCURSES_running()
#ifndef __C_NCURSES_C
extern GB_DESC CNCursesDesc[];
#endif
void NCURSES_init(void);
void NCURSES_exit(void);
bool NCURSES_running(void);
#endif /* __C_NCURSES_H */

View File

@ -66,6 +66,14 @@ DECLARE_EVENT(EVENT_Read);
#define E_COORDS "Coordinates out of range"
#define E_DIMENSION "Dimensions do not fit on screen"
void WINDOW_refresh()
{
if (!NCURSES_running())
return;
update_panels();
doupdate();
}
/**
* Copies text with attributes from a window to a newly malloced array as if the window
* was linear memory, too (line by line).

View File

@ -35,10 +35,7 @@
#define IS_WRAPPED (THIS->wrap)
/* This will produce final output on terminal screen, shall be called only by Gambas functions
as they assemble all changes for a single functionality and may then output once. */
#define REFRESH() { \
update_panels(); \
doupdate(); \
}
#define REFRESH() WINDOW_refresh()
/* Translate linear (absolute) memory addresses and x,y coordinates into each other
most useful when wrapping is needed. */
@ -136,4 +133,6 @@ extern GB_DESC CCharAttrsDesc[];
getmaxx(THIS->content), \
getmaxy(THIS->content), 0, 0))
void WINDOW_refresh(void);
#endif /* __C_WINDOW_C */

View File

@ -36,14 +36,22 @@ GB_DESC *GB_CLASSES[] EXPORT =
NULL
};
static void hook_error(int code, char *error, char *where)
{
NCURSES_exit();
}
int EXPORT GB_INIT()
{
return 0;
GB.Hook(GB_HOOK_ERROR, (void *)hook_error);
return 0;
}
void EXPORT GB_EXIT()
{
NCURSES_exit();
}