[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:
parent
229928614e
commit
f73ceed778
@ -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"),
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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 },
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user