added respondsTo: and perform:with:

fixed a bug in Dictionary>>__remove_at:
added gc callback to external modules
This commit is contained in:
hyunghwan.chung
2017-03-19 14:18:37 +00:00
parent 6a2add620b
commit 46ba3bb3f5
12 changed files with 550 additions and 136 deletions

View File

@ -34,12 +34,21 @@
#define C MOO_METHOD_CLASS
#define I MOO_METHOD_INSTANCE
typedef struct x11_modctx_t x11_modctx_t;
struct x11_modctx_t
{
moo_oop_class_t x11_class;
moo_oop_class_t mouse_event_class;
moo_oop_class_t key_event_class;
};
typedef struct x11_t x11_t;
struct x11_t
{
xcb_connection_t* c;
xcb_screen_t* screen;
xcb_generic_event_t* curevt; /* most recent event received */
};
typedef struct x11_win_t x11_win_t;
@ -49,6 +58,7 @@ struct x11_win_t
xcb_intern_atom_reply_t* dwcr;
};
/* ------------------------------------------------------------------------ */
static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs)
@ -56,6 +66,8 @@ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs)
x11_t* x11;
xcb_connection_t* c;
x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
/* TODO: accept display target as a parameter */
if (nargs != 0)
{
@ -63,8 +75,6 @@ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs)
goto softfail;
}
x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
if (x11->c)
{
MOO_DEBUG0 (moo, "<x11.connect> Unable to connect multiple times\n");
@ -108,6 +118,11 @@ static moo_pfrc_t pf_disconnect (moo_t* moo, moo_ooi_t nargs)
MOO_DEBUG1 (moo, "<x11.disconnect> %p\n", x11->c);
if (x11->curevt)
{
free (x11->curevt);
x11->curevt = MOO_NULL;
}
if (x11->c)
{
xcb_disconnect (x11->c);
@ -116,18 +131,14 @@ static moo_pfrc_t pf_disconnect (moo_t* moo, moo_ooi_t nargs)
MOO_STACK_SETRETTORCV (moo, nargs);
return MOO_PF_SUCCESS;
softfail:
MOO_STACK_SETRETTOERROR (moo, nargs);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_getfd (moo_t* moo, moo_ooi_t nargs)
static moo_pfrc_t pf_get_fd (moo_t* moo, moo_ooi_t nargs)
{
x11_t* x11;
x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
MOO_DEBUG1 (moo, "<x11.getfd> %p\n", x11->c);
MOO_DEBUG1 (moo, "<x11.get_fd> %p\n", x11->c);
if (x11->c)
{
@ -146,38 +157,73 @@ static moo_pfrc_t pf_getfd (moo_t* moo, moo_ooi_t nargs)
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_getevent (moo_t* moo, moo_ooi_t nargs)
{
x11_t* x11;
xcb_generic_event_t* evt;
x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
MOO_DEBUG1 (moo, "<x11.__getevent> %p\n", x11->c);
MOO_DEBUG1 (moo, "<x11.getevent> %p\n", x11->c);
evt = xcb_poll_for_event(x11->c);
if (x11->curevt) free (x11->curevt);
x11->curevt = evt;
if (evt)
{
uint8_t evttype = evt->response_type & ~0x80;
uint8_t evttype = evt->response_type & 0x7F;
x11->curevt = evt;
if (evttype == XCB_CLIENT_MESSAGE)
#if 0
&&
((xcb_client_message_event_t*)evt)->data.data32[0] == x11->dwcr->atom)
#endif
{
#if 0
xcb_unmap_window (x11->c, x11->w);
xcb_destroy_window (x11->c, x11->w);
xcb_flush (x11->c);
#endif
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(9999)); /* TODO: translate evt to the event object */
}
else
{
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(evttype)); /* TODO: translate evt to the event object */
}
#if 0
switch (evttype)
{
case XCB_CLIENT_MESSAGE:
#if 0
if (((xcb_client_message_event_t*)evt)->data.data32[0] == x11->dwcr->atom)
{
xcb_unmap_window (x11->c, x11->w);
xcb_destroy_window (x11->c, x11->w);
xcb_flush (x11->c);
}
#endif
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(9999)); /* TODO: translate evt to the event object */
break;
case XCB_BUTTON_PRESS:
case XCB_BUTTON_RELEASE:
{
xcb_button_press_event_t* bpe = (xcb_button_press_event_t*)evt;
MOO_STACK_SETRET (moo, nargs, e);
break;
}
default:
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(evttype)); /* TODO: translate evt to the event object */
break;
}
free (evt);
#endif
}
else if (xcb_connection_has_error(x11->c))
{
/* TODO: to be specific about the error */
MOO_STACK_SETRETTOERROR (moo, nargs);
}
else
{
@ -189,23 +235,72 @@ static moo_pfrc_t pf_getevent (moo_t* moo, moo_ooi_t nargs)
/* ------------------------------------------------------------------------ */
static moo_pfrc_t pf_win_get_id (moo_t* moo, moo_ooi_t nargs)
{
x11_win_t* win;
moo_oop_t x;
win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
x = moo_oowtoint (moo, win->id);
if (!x) return MOO_PF_HARD_FAILURE;
MOO_STACK_SETRET (moo, nargs, x);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_win_kill_on (moo_t* moo, moo_ooi_t nargs)
{
x11_t* x11;
x11_win_t* win;
x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETARG(moo, nargs, 0), MOO_NULL);
win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
if (!x11->c)
{
MOO_STACK_SETRETTOERROR (moo, nargs); /* More specific error code*/
return MOO_PF_SUCCESS;
}
/* TODO: check on windows id */
xcb_unmap_window (x11->c, win->id); /* TODO: check error code */
xcb_destroy_window (x11->c, win->id);
xcb_flush (x11->c);
MOO_STACK_SETRETTORCV (moo, nargs);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_win_make_on (moo_t* moo, moo_ooi_t nargs)
{
x11_t* x11;
x11_win_t* win;
moo_oop_t id;
uint32_t mask;
uint32_t values[2];
xcb_intern_atom_cookie_t cookie;
xcb_intern_atom_reply_t* reply;
MOO_DEBUG0 (moo, "<x11.win._makeon:> %p\n");
MOO_DEBUG0 (moo, "<x11.win._make_on:> %p\n");
x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETARG(moo, nargs, 0), MOO_NULL);
win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
if (!x11->c)
{
MOO_STACK_SETRETTOERROR (moo, nargs); /* TODO: be more specific about error */
return MOO_PF_SUCCESS;
}
win->id = xcb_generate_id (x11->c);
id = moo_oowtoint (moo, win->id);
if (!id) return MOO_PF_HARD_FAILURE;
mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
values[0] = x11->screen->white_pixel;
values[1] = XCB_EVENT_MASK_KEY_RELEASE |
@ -237,44 +332,20 @@ MOO_DEBUG0 (moo, "<x11.win._makeon:> %p\n");
xcb_map_window (x11->c, win->id);
xcb_flush (x11->c);
MOO_STACK_SETRETTORCV (moo, nargs);
MOO_STACK_SETRET (moo, nargs, id);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_win_kill_on (moo_t* moo, moo_ooi_t nargs)
{
x11_t* x11;
x11_win_t* win;
x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETARG(moo, nargs, 0), MOO_NULL);
win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
if (!x11->c)
{
MOO_STACK_SETRETTOERROR (moo, nargs); /* More specific error code*/
return MOO_PF_SUCCESS;
}
/* TODO: check on windows id */
xcb_unmap_window (x11->c, win->id); /* TODO: check error code */
xcb_destroy_window (x11->c, win->id);
xcb_flush (x11->c);
MOO_STACK_SETRETTORCV (moo, nargs);
return MOO_PF_SUCCESS;
}
/* ------------------------------------------------------------------------ */
static moo_pfinfo_t x11_pfinfo[] =
{
{ I, { '_','g','e','t','e','v','e','n','t','\0'}, 0, pf_getevent },
{ I, { 'c','o','n','n','e','c','t','\0' }, 0, pf_connect },
{ I, { 'd','i','s','c','o','n','n','e','c','t','\0' }, 0, pf_disconnect },
{ I, { 'g','e','t','f','d','\0' }, 0, pf_getfd }
{ I, { '_','c','o','n','n','e','c','t','\0' }, 0, pf_connect },
{ I, { '_','d','i','s','c','o','n','n','e','c','t','\0' }, 0, pf_disconnect },
{ I, { '_','g','e','t','_','e','v','e','n','t','\0'}, 0, pf_getevent },
{ I, { '_','g','e','t','_','f','d','\0' }, 0, pf_get_fd }
};
static int x11_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class)
@ -291,15 +362,77 @@ static moo_pfimpl_t x11_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* nam
static void x11_unload (moo_t* moo, moo_mod_t* mod)
{
/* TODO: anything? close open open dll handles? For that, pf_open must store the value it returns to mod->ctx or somewhere..*/
/* TODO: anything else? close all open dll handles? For that, pf_open must store the value it returns to mod->ctx or somewhere..*/
moo_freemem (moo, mod->ctx);
}
static void x11_gc (moo_t* moo, moo_mod_t* mod)
{
x11_modctx_t* ctx = mod->ctx;
MOO_ASSERT (moo, ctx != MOO_NULL);
ctx->mouse_event_class = (moo_oop_class_t)moo_moveoop (moo, (moo_oop_t)ctx->mouse_event_class);
ctx->key_event_class = (moo_oop_class_t)moo_moveoop (moo, (moo_oop_t)ctx->key_event_class);
}
int moo_mod_x11 (moo_t* moo, moo_mod_t* mod)
{
if (mod->hints & MOO_MOD_LOAD_FOR_IMPORT)
{
mod->gc = MOO_NULL;
mod->ctx = MOO_NULL;
}
else
{
x11_modctx_t* ctx;
static moo_ooch_t name_x11[] = { 'X','1','1','\0' };
static moo_ooch_t name_mouse_event[] = { 'M','o','u','s','e','E','v','e','n','t','\0' };
static moo_ooch_t name_key_event[] = { 'K','e','y','E','v','e','n','t','\0' };
ctx = moo_callocmem (moo, MOO_SIZEOF(*ctx));
if (!ctx) return -1;
ctx->x11_class = (moo_oop_class_t)moo_findclass (moo, moo->sysdic, name_x11);
if (!ctx->x11_class)
{
/* Not a single X11.XXX has been defined. */
MOO_DEBUG0 (moo, "X11 class not found\n");
oops:
moo_freemem (moo, ctx);
return -1;
}
if ((moo_oop_t)ctx->x11_class->nsdic == moo->_nil)
{
MOO_DEBUG0 (moo, "No class defined in X11\n");
goto oops;
}
/* TODO: check on instance size... etc */
/* TODO: tabulate key event classes */
ctx->mouse_event_class = (moo_oop_class_t)moo_findclass (moo, ctx->x11_class->nsdic, name_mouse_event);
if (!ctx->mouse_event_class)
{
MOO_DEBUG0 (moo, "X11.MouseEvent class not found\n");
goto oops;
}
ctx->key_event_class = (moo_oop_class_t)moo_findclass (moo, ctx->x11_class->nsdic, name_key_event);
if (!ctx->key_event_class)
{
MOO_DEBUG0 (moo, "X11.KeyEvent class not found\n");
goto oops;
}
mod->gc = x11_gc;
mod->ctx = ctx;
}
mod->import = x11_import;
mod->query = x11_query;
mod->unload = x11_unload;
mod->ctx = MOO_NULL;
return 0;
}
@ -307,8 +440,9 @@ int moo_mod_x11 (moo_t* moo, moo_mod_t* mod)
static moo_pfinfo_t x11_win_pfinfo[] =
{
{ I, { '_','m','a','k','e','_','o','n',':','\0' }, 0, pf_win_make_on },
{ I, { '_','k','i','l','l','_','o','n',':','\0' }, 0, pf_win_kill_on }
{ I, { '_','g','e','t','_','i','d','\0' }, 0, pf_win_get_id },
{ I, { '_','k','i','l','l','_','o','n',':','\0' }, 0, pf_win_kill_on },
{ I, { '_','m','a','k','e','_','o','n',':','\0' }, 0, pf_win_make_on }
};
static int x11_win_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class)
@ -325,7 +459,7 @@ static moo_pfimpl_t x11_win_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t*
static void x11_win_unload (moo_t* moo, moo_mod_t* mod)
{
/* TODO: anything? */
/* anything? */
}
int moo_mod_x11_win (moo_t* moo, moo_mod_t* mod)
@ -333,6 +467,8 @@ int moo_mod_x11_win (moo_t* moo, moo_mod_t* mod)
mod->import = x11_win_import;
mod->query = x11_win_query;
mod->unload = x11_win_unload;
mod->gc = MOO_NULL;
mod->ctx = MOO_NULL;
return 0;
}