[INTERPRETER]

* NEW: Stream.Term.Width and Stream.Term.Height are two new properties that return the size of the terminal associated with the stream, if any.
* NEW: As soon as the terminal size is read on any stream with the previous properties, the SIGWINCH signal is watched, and the Application_Resize() public method of the startup class is called each time this signal is catched, meaning that the terminal has been resized.


git-svn-id: svn://localhost/gambas/trunk@7735 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2016-04-10 13:10:25 +00:00
parent 229928614e
commit f73ceed778
5 changed files with 99 additions and 37 deletions

View File

@ -32,6 +32,7 @@
#include <grp.h> #include <grp.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <pty.h> #include <pty.h>
#include <termios.h>
#include "gb_common.h" #include "gb_common.h"
#include "gb_list.h" #include "gb_list.h"
@ -46,6 +47,7 @@
#include "gbx_string.h" #include "gbx_string.h"
#include "gbx_date.h" #include "gbx_date.h"
#include "gbx_watch.h" #include "gbx_watch.h"
#include "gbx_signal.h"
#include "gbx_c_file.h" #include "gbx_c_file.h"
@ -56,10 +58,18 @@ CFILE *CFILE_in, *CFILE_out, *CFILE_err;
DECLARE_EVENT(EVENT_Read); DECLARE_EVENT(EVENT_Read);
DECLARE_EVENT(EVENT_Write); DECLARE_EVENT(EVENT_Write);
static GB_FUNCTION read_func; static GB_FUNCTION _read_func;
static char _buffer[16]; static char _buffer[16];
static bool _term_init = FALSE;
static bool _has_term_func = FALSE;
static ushort _term_width = 0;
static ushort _term_height = 0;
static SIGNAL_CALLBACK *_SIGWINCH_callback = NULL;
static GB_FUNCTION _term_resize_func;
static void callback_read(int fd, int type, CFILE *file) static void callback_read(int fd, int type, CFILE *file)
{ {
if (!STREAM_read_ahead(CSTREAM_stream(file))) if (!STREAM_read_ahead(CSTREAM_stream(file)))
@ -68,12 +78,18 @@ static void callback_read(int fd, int type, CFILE *file)
WATCH_little_sleep(); WATCH_little_sleep();
} }
static void callback_write(int fd, int type, CFILE *file) static void callback_write(int fd, int type, CFILE *file)
{ {
GB_Raise(file, EVENT_Write, 0); GB_Raise(file, EVENT_Write, 0);
} }
static void cb_term_resize(int signum, intptr_t data)
{
_term_width = _term_height = 0;
if (_has_term_func)
GB_Call(&_term_resize_func, 0, FALSE);
}
CFILE *CFILE_create(STREAM *stream, int mode) CFILE *CFILE_create(STREAM *stream, int mode)
{ {
@ -134,11 +150,14 @@ void CFILE_exit(void)
OBJECT_UNREF(CFILE_in); OBJECT_UNREF(CFILE_in);
OBJECT_UNREF(CFILE_out); OBJECT_UNREF(CFILE_out);
OBJECT_UNREF(CFILE_err); OBJECT_UNREF(CFILE_err);
if (_term_init)
SIGNAL_unregister(SIGWINCH, _SIGWINCH_callback);
} }
void CFILE_init_watch(void) void CFILE_init_watch(void)
{ {
if (GB_GetFunction(&read_func, PROJECT_class, "Application_Read", "", "") == 0) if (GB_GetFunction(&_read_func, PROJECT_class, "Application_Read", "", "") == 0)
{ {
//fprintf(stderr, "watch stdin\n"); //fprintf(stderr, "watch stdin\n");
OBJECT_attach((OBJECT *)CFILE_in, (OBJECT *)PROJECT_class, "Application"); OBJECT_attach((OBJECT *)CFILE_in, (OBJECT *)PROJECT_class, "Application");
@ -852,6 +871,8 @@ BEGIN_METHOD_VOID(StreamLines_next)
END_METHOD END_METHOD
//---------------------------------------------------------------------------
BEGIN_PROPERTY(StreamTerm_Name) BEGIN_PROPERTY(StreamTerm_Name)
GB_ReturnNewZeroString(ttyname(STREAM_FD)); GB_ReturnNewZeroString(ttyname(STREAM_FD));
@ -913,30 +934,69 @@ BEGIN_PROPERTY(StreamTerm_FlowControl)
END_PROPERTY END_PROPERTY
static void init_term_size(void *_object)
{
struct winsize winSize;
if (_term_width == 0 || _term_height == 0)
{
if (ioctl(STREAM_FD, TIOCGWINSZ, (char *)&winSize))
THROW_SYSTEM(errno, NULL);
_term_width = winSize.ws_col;
_term_height = winSize.ws_row;
}
if (!_term_init)
{
_SIGWINCH_callback = SIGNAL_register(SIGWINCH, cb_term_resize, 0);
_has_term_func = GB_GetFunction(&_term_resize_func, PROJECT_class, "Application_Resize", "", "") == 0;
_term_init = TRUE;
}
}
BEGIN_PROPERTY(StreamTerm_Width)
init_term_size(_object);
GB_ReturnInteger(_term_width);
END_PROPERTY
BEGIN_PROPERTY(StreamTerm_Height)
init_term_size(_object);
GB_ReturnInteger(_term_height);
END_PROPERTY
#endif #endif
GB_DESC NATIVE_StreamLines[] = GB_DESC StreamLinesDesc[] =
{ {
GB_DECLARE(".Stream.Lines", 0), GB_VIRTUAL_CLASS(), GB_DECLARE_VIRTUAL(".Stream.Lines"),
GB_METHOD("_next", "s", StreamLines_next, NULL), GB_METHOD("_next", "s", StreamLines_next, NULL),
GB_END_DECLARE GB_END_DECLARE
}; };
GB_DESC NATIVE_StreamTerm[] = GB_DESC StreamTermDesc[] =
{ {
GB_DECLARE(".Stream.Term", 0), GB_VIRTUAL_CLASS(), GB_DECLARE_VIRTUAL(".Stream.Term"),
GB_PROPERTY_READ("Name", "s", StreamTerm_Name), GB_PROPERTY_READ("Name", "s", StreamTerm_Name),
GB_PROPERTY("Echo", "b", StreamTerm_Echo), GB_PROPERTY("Echo", "b", StreamTerm_Echo),
GB_PROPERTY("FlowControl", "b", StreamTerm_FlowControl), GB_PROPERTY("FlowControl", "b", StreamTerm_FlowControl),
GB_PROPERTY_READ("Width", "i", StreamTerm_Width),
GB_PROPERTY_READ("W", "i", StreamTerm_Width),
GB_PROPERTY_READ("Height", "i", StreamTerm_Height),
GB_PROPERTY_READ("H", "i", StreamTerm_Height),
GB_METHOD("Resize", NULL, StreamTerm_Resize, "(Width)i(Height)i"), GB_METHOD("Resize", NULL, StreamTerm_Resize, "(Width)i(Height)i"),
GB_END_DECLARE GB_END_DECLARE
}; };
GB_DESC NATIVE_Stream[] = GB_DESC StreamDesc[] =
{ {
GB_DECLARE("Stream", sizeof(CSTREAM)), GB_DECLARE("Stream", sizeof(CSTREAM)),
GB_NOT_CREATABLE(), GB_NOT_CREATABLE(),
@ -964,10 +1024,9 @@ GB_DESC NATIVE_Stream[] =
}; };
GB_DESC NATIVE_StatPerm[] = GB_DESC StatPermDesc[] =
{ {
GB_DECLARE(".Stat.Perm", 0), GB_DECLARE_VIRTUAL(".Stat.Perm"),
GB_VIRTUAL_CLASS(),
GB_METHOD("_get", "s", CFILE_perm_get, "(UserOrGroup)s"), GB_METHOD("_get", "s", CFILE_perm_get, "(UserOrGroup)s"),
GB_PROPERTY_READ("User", "s", CFILE_perm_user), GB_PROPERTY_READ("User", "s", CFILE_perm_user),
@ -978,7 +1037,7 @@ GB_DESC NATIVE_StatPerm[] =
}; };
GB_DESC NATIVE_Stat[] = GB_DESC StatDesc[] =
{ {
GB_DECLARE("Stat", sizeof(CSTAT)), GB_DECLARE("Stat", sizeof(CSTAT)),
GB_NOT_CREATABLE(), GB_NOT_CREATABLE(),
@ -1007,7 +1066,7 @@ GB_DESC NATIVE_Stat[] =
}; };
GB_DESC NATIVE_File[] = GB_DESC FileDesc[] =
{ {
GB_DECLARE("File", sizeof(CFILE)), GB_DECLARE("File", sizeof(CFILE)),
GB_INHERITS("Stream"), GB_INHERITS("Stream"),

View File

@ -55,12 +55,13 @@ typedef
CSTAT; CSTAT;
#ifndef __GBX_C_FILE_C #ifndef __GBX_C_FILE_C
extern GB_DESC NATIVE_StreamLines[]; extern GB_DESC StreamLinesDesc[];
extern GB_DESC NATIVE_StreamTerm[]; extern GB_DESC StreamTermDesc[];
extern GB_DESC NATIVE_Stream[]; extern GB_DESC StreamDesc[];
extern GB_DESC NATIVE_File[]; extern GB_DESC FileDesc[];
extern GB_DESC NATIVE_Stat[]; extern GB_DESC StatDesc[];
extern GB_DESC NATIVE_StatPerm[]; extern GB_DESC StatPermDesc[];
extern CFILE *CFILE_in; extern CFILE *CFILE_in;
extern CFILE *CFILE_out; extern CFILE *CFILE_out;
extern CFILE *CFILE_err; extern CFILE *CFILE_err;

View File

@ -358,12 +358,12 @@ extern GB_DESC NATIVE_Components[];
extern GB_DESC NATIVE_Object[]; extern GB_DESC NATIVE_Object[];
extern GB_DESC NATIVE_Collection[]; extern GB_DESC NATIVE_Collection[];
extern GB_DESC NATIVE_Error[]; extern GB_DESC NATIVE_Error[];
extern GB_DESC NATIVE_Stream[]; extern GB_DESC StreamDesc[];
extern GB_DESC NATIVE_StreamLines[]; extern GB_DESC StreamLinesDesc[];
extern GB_DESC NATIVE_StreamTerm[]; extern GB_DESC StreamTermDesc[];
extern GB_DESC NATIVE_StatPerm[]; extern GB_DESC StatPermDesc[];
extern GB_DESC NATIVE_Stat[]; extern GB_DESC StatDesc[];
extern GB_DESC NATIVE_File[]; extern GB_DESC FileDesc[];
extern GB_DESC NATIVE_AppEnv[]; extern GB_DESC NATIVE_AppEnv[];
extern GB_DESC NATIVE_AppArgs[]; extern GB_DESC NATIVE_AppArgs[];
extern GB_DESC NATIVE_App[]; extern GB_DESC NATIVE_App[];
@ -406,12 +406,12 @@ GB_DESC *GB_CLASSES[] EXPORT =
NATIVE_Object, NATIVE_Object,
NATIVE_Collection, NATIVE_Collection,
NATIVE_Error, NATIVE_Error,
NATIVE_StreamLines, StreamLinesDesc,
NATIVE_StreamTerm, StreamTermDesc,
NATIVE_Stream, StreamDesc,
NATIVE_StatPerm, StatPermDesc,
NATIVE_Stat, StatDesc,
NATIVE_File, FileDesc,
NATIVE_AppEnv, NATIVE_AppEnv,
NATIVE_AppArgs, NATIVE_AppArgs,
NATIVE_App, NATIVE_App,

View File

@ -100,12 +100,12 @@ static const CLASS_INIT init_list[] =
{ NATIVE_Object, NULL }, { NATIVE_Object, NULL },
{ NATIVE_Collection, &CLASS_Collection, CQA_COLLECTION }, { NATIVE_Collection, &CLASS_Collection, CQA_COLLECTION },
{ NATIVE_Error, NULL }, { NATIVE_Error, NULL },
{ NATIVE_StreamLines, NULL }, { StreamLinesDesc, NULL },
{ NATIVE_StreamTerm, NULL }, { StreamTermDesc, NULL },
{ NATIVE_Stream, &CLASS_Stream }, { StreamDesc, &CLASS_Stream },
{ NATIVE_StatPerm, NULL }, { StatPermDesc, NULL },
{ NATIVE_Stat, &CLASS_Stat }, { StatDesc, &CLASS_Stat },
{ NATIVE_File, &CLASS_File }, { FileDesc, &CLASS_File },
{ NATIVE_AppEnv, &CLASS_AppEnv }, { NATIVE_AppEnv, &CLASS_AppEnv },
{ NATIVE_AppArgs, &CLASS_AppArgs }, { NATIVE_AppArgs, &CLASS_AppArgs },
{ NATIVE_App, &CLASS_Application }, { NATIVE_App, &CLASS_Application },

View File

@ -3751,6 +3751,8 @@ static void _break(ushort code)
TC = PC + 1; TC = PC + 1;
TP = SP; TP = SP;
//fprintf(stderr, "%s\n", DEBUG_get_current_position());
if (CP && CP->component == COMPONENT_main) if (CP && CP->component == COMPONENT_main)
{ {
if (EXEC_profile_instr) if (EXEC_profile_instr)