diff --git a/gb.ncurses/configure.ac b/gb.ncurses/configure.ac index 55c2fe3c3..03410bb2c 100644 --- a/gb.ncurses/configure.ac +++ b/gb.ncurses/configure.ac @@ -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)], diff --git a/gb.ncurses/src/c_ncurses.c b/gb.ncurses/src/c_ncurses.c index 36339b67b..564de7dc2 100644 --- a/gb.ncurses/src/c_ncurses.c +++ b/gb.ncurses/src/c_ncurses.c @@ -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 diff --git a/gb.ncurses/src/c_ncurses.h b/gb.ncurses/src/c_ncurses.h index 638ab6f3e..8bcf082d5 100644 --- a/gb.ncurses/src/c_ncurses.h +++ b/gb.ncurses/src/c_ncurses.h @@ -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 */ diff --git a/gb.ncurses/src/c_window.c b/gb.ncurses/src/c_window.c index aa218b93c..62df69160 100644 --- a/gb.ncurses/src/c_window.c +++ b/gb.ncurses/src/c_window.c @@ -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). diff --git a/gb.ncurses/src/c_window.h b/gb.ncurses/src/c_window.h index 300f13660..fd28783b9 100644 --- a/gb.ncurses/src/c_window.h +++ b/gb.ncurses/src/c_window.h @@ -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 */ diff --git a/gb.ncurses/src/main.c b/gb.ncurses/src/main.c index 5bca08f77..e45f44d57 100644 --- a/gb.ncurses/src/main.c +++ b/gb.ncurses/src/main.c @@ -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(); }