added respondsTo: and perform:with:
fixed a bug in Dictionary>>__remove_at: added gc callback to external modules
This commit is contained in:
246
moo/mod/x11.c
246
moo/mod/x11.c
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user