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

34
moo/configure vendored
View File

@ -660,6 +660,8 @@ ENABLE_LIBLTDL_FALSE
ENABLE_LIBLTDL_TRUE ENABLE_LIBLTDL_TRUE
ENABLE_STATIC_MODULE_FALSE ENABLE_STATIC_MODULE_FALSE
ENABLE_STATIC_MODULE_TRUE ENABLE_STATIC_MODULE_TRUE
ENABLE_DYNAMIC_MODULE_FALSE
ENABLE_DYNAMIC_MODULE_TRUE
ENABLE_CXX_FALSE ENABLE_CXX_FALSE
ENABLE_CXX_TRUE ENABLE_CXX_TRUE
BUILD_MODE BUILD_MODE
@ -832,6 +834,7 @@ with_ltdl_lib
enable_ltdl_install enable_ltdl_install
enable_debug enable_debug
enable_cxx enable_cxx
enable_dynamic_module
enable_static_module enable_static_module
enable_libltdl enable_libltdl
' '
@ -1482,6 +1485,7 @@ Optional Features:
--enable-debug build the library in the debug mode (default. no) --enable-debug build the library in the debug mode (default. no)
--enable-cxx build the library for C++ if a C++ compiler is --enable-cxx build the library for C++ if a C++ compiler is
available (default. yes) available (default. yes)
--enable-dynamic-module enable dynamic module capability(default. yes)
--enable-static-module build modules statically into the main --enable-static-module build modules statically into the main
library(default. no) library(default. no)
--enable-libltdl use libltdl(default. yes) --enable-libltdl use libltdl(default. yes)
@ -20588,6 +20592,31 @@ else
fi fi
# Check whether --enable-dynamic-module was given.
if test "${enable_dynamic_module+set}" = set; then :
enableval=$enable_dynamic_module; enable_dynamic_module_is=$enableval
else
enable_dynamic_module_is=yes
fi
test "${enable_shared}" = "no" && enable_dynamic_module_is="no"
if test "${enable_dynamic_module_is}" = "yes"
then
$as_echo "#define MOO_ENABLE_DYNAMIC_MODULE /**/" >>confdefs.h
fi
if test "${enable_dynamic_module_is}" = "yes"; then
ENABLE_DYNAMIC_MODULE_TRUE=
ENABLE_DYNAMIC_MODULE_FALSE='#'
else
ENABLE_DYNAMIC_MODULE_TRUE='#'
ENABLE_DYNAMIC_MODULE_FALSE=
fi
# Check whether --enable-static-module was given. # Check whether --enable-static-module was given.
if test "${enable_static_module+set}" = set; then : if test "${enable_static_module+set}" = set; then :
enableval=$enable_static_module; enable_static_module_is=$enableval enableval=$enable_static_module; enable_static_module_is=$enableval
@ -20613,7 +20642,6 @@ else
fi fi
# Check whether --enable-libltdl was given. # Check whether --enable-libltdl was given.
if test "${enable_libltdl+set}" = set; then : if test "${enable_libltdl+set}" = set; then :
enableval=$enable_libltdl; enable_libltdl_is=$enableval enableval=$enable_libltdl; enable_libltdl_is=$enableval
@ -20844,6 +20872,10 @@ if test -z "${ENABLE_CXX_TRUE}" && test -z "${ENABLE_CXX_FALSE}"; then
as_fn_error $? "conditional \"ENABLE_CXX\" was never defined. as_fn_error $? "conditional \"ENABLE_CXX\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5 Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi fi
if test -z "${ENABLE_DYNAMIC_MODULE_TRUE}" && test -z "${ENABLE_DYNAMIC_MODULE_FALSE}"; then
as_fn_error $? "conditional \"ENABLE_DYNAMIC_MODULE\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${ENABLE_STATIC_MODULE_TRUE}" && test -z "${ENABLE_STATIC_MODULE_FALSE}"; then if test -z "${ENABLE_STATIC_MODULE_TRUE}" && test -z "${ENABLE_STATIC_MODULE_FALSE}"; then
as_fn_error $? "conditional \"ENABLE_STATIC_MODULE\" was never defined. as_fn_error $? "conditional \"ENABLE_STATIC_MODULE\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5 Usually this means the macro was only invoked conditionally." "$LINENO" 5

View File

@ -420,6 +420,20 @@ test "${ax_cv_cxx_have_std_namespace}" = "yes" || enable_cxx_is="no"
AM_CONDITIONAL(ENABLE_CXX, test "${enable_cxx_is}" = "yes" ) AM_CONDITIONAL(ENABLE_CXX, test "${enable_cxx_is}" = "yes" )
dnl ===== enable-dynamic-module =====
AC_ARG_ENABLE([dynamic-module],
[AS_HELP_STRING([--enable-dynamic-module],[enable dynamic module capability(default. yes)])],
enable_dynamic_module_is=$enableval,
enable_dynamic_module_is=yes
)
test "${enable_shared}" = "no" && enable_dynamic_module_is="no"
if test "${enable_dynamic_module_is}" = "yes"
then
AC_DEFINE([MOO_ENABLE_DYNAMIC_MODULE],[],[enable dynamic module capability])
fi
AM_CONDITIONAL(ENABLE_DYNAMIC_MODULE, test "${enable_dynamic_module_is}" = "yes")
dnl ===== enable-static-module ===== dnl ===== enable-static-module =====
AC_ARG_ENABLE([static-module], AC_ARG_ENABLE([static-module],
[AS_HELP_STRING([--enable-static-module],[build modules statically into the main library(default. no)])], [AS_HELP_STRING([--enable-static-module],[build modules statically into the main library(default. no)])],
@ -434,7 +448,6 @@ then
fi fi
AM_CONDITIONAL(ENABLE_STATIC_MODULE, test "${enable_static_module_is}" = "yes") AM_CONDITIONAL(ENABLE_STATIC_MODULE, test "${enable_static_module_is}" = "yes")
dnl ===== enable-libltdl ===== dnl ===== enable-libltdl =====
AC_ARG_ENABLE([libltdl], AC_ARG_ENABLE([libltdl],
[AS_HELP_STRING([--enable-libltdl],[use libltdl(default. yes)])], [AS_HELP_STRING([--enable-libltdl],[use libltdl(default. yes)])],
@ -443,7 +456,7 @@ AC_ARG_ENABLE([libltdl],
) )
if test "${enable_libltdl_is}" = "yes" if test "${enable_libltdl_is}" = "yes"
then then
AC_DEFINE([MOO_ENABLE_LIBLTDL],[],[use libltdl]) AC_DEFINE([MOO_ENABLE_LIBLTDL],[],[use libltdl when loading a dynamic module])
fi fi
AM_CONDITIONAL(ENABLE_LIBLTDL, test "${enable_libltdl_is}" = "yes") AM_CONDITIONAL(ENABLE_LIBLTDL, test "${enable_libltdl_is}" = "yes")

View File

@ -312,17 +312,86 @@ class Apex(nil)
^(self isMemberOf: aClass) or: [self class inheritsFrom: aClass]. ^(self isMemberOf: aClass) or: [self class inheritsFrom: aClass].
} }
(* ----------------- ## -------------------------------------------------------
method(#class) respondsTo: selectorSymbol ## -------------------------------------------------------
method(#class) respondsTo: selector
{ {
TODO: find selectorSymbol in the class method dictionary... <primitive: #_responds_to>
self primitiveFailed
} }
method respondsTo: selectorSymbol method respondsTo: selector
{ {
TODO: find selectorSymbol in the method dictionary... <primitive: #_responds_to>
self primitiveFailed
} }
------------ *)
## -------------------------------------------------------
## -------------------------------------------------------
method(#class) perform()
{
<primitive: #_perform>
self primitiveFailed
}
method perform()
{
<primitive: #_perform>
self primitiveFailed
}
method(#class) perform: selector
{
<primitive: #_perform>
self primitiveFailed
}
method perform: selector
{
<primitive: #_perform>
self primitiveFailed
}
method(#class) perform: selector with: arg1
{
<primitive: #_perform>
self primitiveFailed
}
method perform: selector with: arg1
{
<primitive: #_perform>
self primitiveFailed
}
method(#class) perform: selector with: arg1 with: arg2
{
<primitive: #_perform>
self primitiveFailed
}
method perform: selector with: arg1 with: arg2
{
<primitive: #_perform>
self primitiveFailed
}
method(#class) perform: selector with: arg1 with: arg2 with: arg3
{
<primitive: #_perform>
self primitiveFailed
}
method perform: selector with: arg1 with: arg2 with: arg3
{
<primitive: #_perform>
self primitiveFailed
}
## -------------------------------------------------------
## -------------------------------------------------------
method exceptionizeError: trueOrFalse method exceptionizeError: trueOrFalse
{ {

View File

@ -321,27 +321,21 @@ class Set(Collection)
method __remove_at: index method __remove_at: index
{ {
| bs x y i v | | bs x y i v ass z |
bs := self.bucket size. bs := self.bucket size.
v := self.bucket basicAt: index. v := self.bucket at: index.
x := index. x := index.
y := index. y := index.
i := 0. i := 0.
[i < self.tally] whileTrue: [ while (i < self.tally)
| ass z | {
y := (y + 1) rem: bs. y := (y + 1) rem: bs.
ass := self.bucket at: i. ass := self.bucket at: y.
if (ass isNil) if (ass isNil) { (* done. the slot at the current index is nil *) break }.
{
(* done. the slot at the current index is nil *)
i := self.tally
}
else
{
(* get the natural hash index *) (* get the natural hash index *)
z := (ass key hash) rem: bs. z := (ass key hash) rem: bs.
@ -352,9 +346,8 @@ class Set(Collection)
x := y. x := y.
}. }.
i := i + 1 i := i + 1.
}. }.
].
self.bucket at: x put: nil. self.bucket at: x put: nil.
self.tally := self.tally - 1. self.tally := self.tally - 1.
@ -744,14 +737,15 @@ class LinkedList(Collection)
else { self.first := link next }. else { self.first := link next }.
self.tally := self.tally - 1. self.tally := self.tally - 1.
^link.
} }
method removeFirst method removeFirstLink
{ {
^self removeLink: self.first ^self removeLink: self.first
} }
method removeLast method removeLastLink
{ {
^self removeLink: self.last ^self removeLink: self.last
} }
@ -767,4 +761,22 @@ class LinkedList(Collection)
link := next. link := next.
} }
} }
method doOverLink: block
{
| link next |
link := self.first.
while (link notNil)
{
next := link next.
block value: link.
link := next.
}
}
method findLink: value
{
self doOverLink: [:el | if (el value = value) { ^el }].
^Error.Code.ENOENT
}
} }

View File

@ -108,6 +108,7 @@
#endif #endif
static void signal_io_semaphore (moo_t* moo, int mask, void* ctx); static void signal_io_semaphore (moo_t* moo, int mask, void* ctx);
static int send_message (moo_t* moo, moo_oop_char_t selector, int to_super, moo_ooi_t nargs);
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
static MOO_INLINE int vm_startup (moo_t* moo) static MOO_INLINE int vm_startup (moo_t* moo)
@ -1521,6 +1522,7 @@ static moo_pfrc_t pf_basic_at (moo_t* moo, moo_ooi_t nargs)
if (!MOO_OOP_IS_POINTER(rcv)) if (!MOO_OOP_IS_POINTER(rcv))
{ {
/* the receiver is a special numeric object, not a normal pointer */ /* the receiver is a special numeric object, not a normal pointer */
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
@ -1528,11 +1530,13 @@ static moo_pfrc_t pf_basic_at (moo_t* moo, moo_ooi_t nargs)
if (moo_inttooow (moo, pos, &idx) <= 0) if (moo_inttooow (moo, pos, &idx) <= 0)
{ {
/* negative integer or not integer */ /* negative integer or not integer */
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
if (idx >= MOO_OBJ_GET_SIZE(rcv)) if (idx >= MOO_OBJ_GET_SIZE(rcv))
{ {
/* index out of range */ /* index out of range */
moo->errnum = MOO_ERANGE;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
@ -1580,6 +1584,7 @@ static moo_pfrc_t pf_basic_at_put (moo_t* moo, moo_ooi_t nargs)
if (!MOO_OOP_IS_POINTER(rcv)) if (!MOO_OOP_IS_POINTER(rcv))
{ {
/* the receiver is a special numeric object, not a normal pointer */ /* the receiver is a special numeric object, not a normal pointer */
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
pos = MOO_STACK_GETARG(moo, nargs, 0); pos = MOO_STACK_GETARG(moo, nargs, 0);
@ -1588,11 +1593,13 @@ static moo_pfrc_t pf_basic_at_put (moo_t* moo, moo_ooi_t nargs)
if (moo_inttooow (moo, pos, &idx) <= 0) if (moo_inttooow (moo, pos, &idx) <= 0)
{ {
/* negative integer or not integer */ /* negative integer or not integer */
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
if (idx >= MOO_OBJ_GET_SIZE(rcv)) if (idx >= MOO_OBJ_GET_SIZE(rcv))
{ {
/* index out of range */ /* index out of range */
moo->errnum = MOO_ERANGE;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
@ -1601,6 +1608,7 @@ static moo_pfrc_t pf_basic_at_put (moo_t* moo, moo_ooi_t nargs)
/* TODO: disallow change of some key kernel objects???? */ /* TODO: disallow change of some key kernel objects???? */
/* TODO: is it better to introduct a read-only mark in the object header instead of this class check??? */ /* TODO: is it better to introduct a read-only mark in the object header instead of this class check??? */
/* read-only object */ /* TODO: DEVISE A WAY TO PASS a proper error from the primitive handler to MOO */ /* read-only object */ /* TODO: DEVISE A WAY TO PASS a proper error from the primitive handler to MOO */
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
@ -1610,6 +1618,7 @@ static moo_pfrc_t pf_basic_at_put (moo_t* moo, moo_ooi_t nargs)
if (!MOO_OOP_IS_SMOOI(val)) if (!MOO_OOP_IS_SMOOI(val))
{ {
/* the value is not a character */ /* the value is not a character */
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
/* TOOD: must I check the range of the value? */ /* TOOD: must I check the range of the value? */
@ -1620,6 +1629,7 @@ static moo_pfrc_t pf_basic_at_put (moo_t* moo, moo_ooi_t nargs)
if (!MOO_OOP_IS_CHAR(val)) if (!MOO_OOP_IS_CHAR(val))
{ {
/* the value is not a character */ /* the value is not a character */
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
((moo_oop_char_t)rcv)->slot[idx] = MOO_OOP_TO_CHAR(val); ((moo_oop_char_t)rcv)->slot[idx] = MOO_OOP_TO_CHAR(val);
@ -1629,6 +1639,7 @@ static moo_pfrc_t pf_basic_at_put (moo_t* moo, moo_ooi_t nargs)
if (!MOO_OOP_IS_SMOOI(val)) if (!MOO_OOP_IS_SMOOI(val))
{ {
/* the value is not a number */ /* the value is not a number */
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
@ -1643,6 +1654,7 @@ static moo_pfrc_t pf_basic_at_put (moo_t* moo, moo_ooi_t nargs)
if (moo_inttooow (moo, val, &w) <= 0) if (moo_inttooow (moo, val, &w) <= 0)
{ {
/* the value is not a number, out of range, or negative */ /* the value is not a number, out of range, or negative */
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
((moo_oop_word_t)rcv)->slot[idx] = w; ((moo_oop_word_t)rcv)->slot[idx] = w;
@ -1712,6 +1724,7 @@ static moo_pfrc_t pf_hash (moo_t* moo, moo_ooi_t nargs)
default: default:
/* MOO_OBJ_TYPE_OOP, ... */ /* MOO_OBJ_TYPE_OOP, ... */
MOO_DEBUG1 (moo, "<pf_hash> Cannot hash an object of type %d\n", type); MOO_DEBUG1 (moo, "<pf_hash> Cannot hash an object of type %d\n", type);
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
break; break;
@ -1726,6 +1739,65 @@ static moo_pfrc_t pf_hash (moo_t* moo, moo_ooi_t nargs)
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
} }
static moo_pfrc_t pf_responds_to (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, selector;
moo_oocs_t mthname;
rcv = MOO_STACK_GETRCV(moo, nargs);
selector = MOO_STACK_GETARG(moo, nargs, 0);
if (MOO_CLASSOF(moo,selector) != moo->_symbol)
{
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE;
}
mthname.ptr = MOO_OBJ_GET_CHAR_SLOT(selector);
mthname.len = MOO_OBJ_GET_SIZE(selector);
if (find_method (moo, rcv, &mthname, 0))
{
MOO_STACK_SETRET (moo, nargs, moo->_true);
}
else
{
MOO_STACK_SETRET (moo, nargs, moo->_false);
}
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_perform (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t /*rcv,*/ selector;
moo_oow_t ssp, esp, i;
/*rcv = MOO_STACK_GETRCV(moo, nargs);*/
selector = MOO_STACK_GETARG(moo, nargs, 0);
if (MOO_CLASSOF(moo,selector) != moo->_symbol)
{
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE;
}
/* remove the selector from the stack */
ssp = MOO_STACK_GETARGSP (moo, nargs, 0);
esp = MOO_STACK_GETARGSP (moo, nargs, nargs - 1);
for (i = ssp; i < esp;)
{
moo_oop_t t;
t = MOO_STACK_GET (moo, i);
i++;
MOO_STACK_SET(moo, i, t);
}
MOO_STACK_POP (moo);
/* emulate message sending */
if (send_message (moo, (moo_oop_char_t)selector, 0, nargs - 1) <= -1) return MOO_PF_HARD_FAILURE;
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_exceptionize_error (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t pf_exceptionize_error (moo_t* moo, moo_ooi_t nargs)
{ {
moo_oop_t rcv; moo_oop_t rcv;
@ -2719,12 +2791,15 @@ static pf_t pftab[] =
{ 0, 0, pf_hash, "_hash" }, { 0, 0, pf_hash, "_hash" },
{ 1, 1, pf_responds_to, "_responds_to" },
{ 1, MAX_NARGS, pf_perform, "_perform" },
{ 1, 1, pf_exceptionize_error, "_exceptionize_error" }, { 1, 1, pf_exceptionize_error, "_exceptionize_error" },
{ 1, 1, pf_context_goto, "_context_goto" }, { 1, 1, pf_context_goto, "_context_goto" },
{ 0, MAX_NARGS, pf_block_value, "_block_value" }, { 0, MAX_NARGS, pf_block_value, "_block_value" },
{ 0, MAX_NARGS, pf_block_new_process, "_block_new_process" }, { 0, MAX_NARGS, pf_block_new_process, "_block_new_process" },
{ 0, 0, pf_process_resume, "_process_resume" }, { 0, 0, pf_process_resume, "_process_resume" },
{ 0, 0, pf_process_terminate, "_process_terminate" }, { 0, 0, pf_process_terminate, "_process_terminate" },
{ 0, 0, pf_process_yield, "_process_yield" }, { 0, 0, pf_process_yield, "_process_yield" },
@ -3043,7 +3118,7 @@ static int send_message (moo_t* moo, moo_oop_char_t selector, int to_super, moo_
receiver = MOO_STACK_GET(moo, moo->sp - nargs); receiver = MOO_STACK_GET(moo, moo->sp - nargs);
mthname.ptr = selector->slot; mthname.ptr = MOO_OBJ_GET_CHAR_SLOT(selector);
mthname.len = MOO_OBJ_GET_SIZE(selector); mthname.len = MOO_OBJ_GET_SIZE(selector);
method = find_method (moo, receiver, &mthname, to_super); method = find_method (moo, receiver, &mthname, to_super);
if (!method) if (!method)

View File

@ -562,6 +562,19 @@ static moo_uint8_t* scan_new_heap (moo_t* moo, moo_uint8_t* ptr)
return ptr; return ptr;
} }
static moo_rbt_walk_t call_module_gc (moo_rbt_t* rbt, moo_rbt_pair_t* pair, void* ctx)
{
moo_t* moo = (moo_t*)ctx;
moo_mod_data_t* mdp;
mdp = MOO_RBT_VPTR(pair);
MOO_ASSERT (moo, mdp != MOO_NULL);
if (mdp->mod.gc) mdp->mod.gc (moo, &mdp->mod);
return MOO_RBT_WALK_FORWARD;
}
void moo_gc (moo_t* moo) void moo_gc (moo_t* moo)
{ {
/* /*
@ -643,6 +656,8 @@ void moo_gc (moo_t* moo)
if (moo->active_method) if (moo->active_method)
moo->active_method = (moo_oop_method_t)moo_moveoop (moo, (moo_oop_t)moo->active_method); moo->active_method = (moo_oop_method_t)moo_moveoop (moo, (moo_oop_t)moo->active_method);
moo_rbt_walk (&moo->modtab, call_module_gc, moo);
for (cb = moo->cblist; cb; cb = cb->next) for (cb = moo->cblist; cb; cb = cb->next)
{ {
if (cb->gc) cb->gc (moo); if (cb->gc) cb->gc (moo);

View File

@ -462,6 +462,9 @@ static void* dl_open (moo_t* moo, const moo_ooch_t* name, int flags)
return handle; return handle;
#else #else
/* TODO: support various platforms */ /* TODO: support various platforms */
/* TODO: implemenent this */ /* TODO: implemenent this */
MOO_DEBUG1 (moo, "Dynamic loading not implemented - cannot open %js\n", name); MOO_DEBUG1 (moo, "Dynamic loading not implemented - cannot open %js\n", name);
@ -1320,11 +1323,12 @@ int main (int argc, char* argv[])
} }
#endif #endif
memset (&vmprim, 0, MOO_SIZEOF(vmprim));
vmprim.dl_open = dl_open; vmprim.dl_open = dl_open;
vmprim.dl_close = dl_close; vmprim.dl_close = dl_close;
vmprim.dl_getsym = dl_getsym; vmprim.dl_getsym = dl_getsym;
vmprim.log_write = log_write; vmprim.log_write = log_write;
vmprim.vm_startup = vm_startup; vmprim.vm_startup = vm_startup;
vmprim.vm_cleanup = vm_cleanup; vmprim.vm_cleanup = vm_cleanup;
vmprim.vm_gettime = vm_gettime; vmprim.vm_gettime = vm_gettime;

View File

@ -326,7 +326,10 @@
/* Define to the shared archive member specification, say "(shr.o)". */ /* Define to the shared archive member specification, say "(shr.o)". */
#undef LT_SHARED_LIB_MEMBER #undef LT_SHARED_LIB_MEMBER
/* use libltdl */ /* enable dynamic module capability */
#undef MOO_ENABLE_DYNAMIC_MODULE
/* use libltdl when loading a dynamic module */
#undef MOO_ENABLE_LIBLTDL #undef MOO_ENABLE_LIBLTDL
/* link modules statically into the main library */ /* link modules statically into the main library */

View File

@ -925,15 +925,6 @@ void* moo_allocheapmem (
moo_oow_t size moo_oow_t size
); );
/* ========================================================================= */
/* gc.c */
/* ========================================================================= */
moo_oop_t moo_moveoop (
moo_t* moo,
moo_oop_t oop
);
/* ========================================================================= */ /* ========================================================================= */
/* obj.c */ /* obj.c */
/* ========================================================================= */ /* ========================================================================= */
@ -1191,7 +1182,8 @@ int moo_getpfnum (
moo_mod_data_t* moo_openmod ( moo_mod_data_t* moo_openmod (
moo_t* moo, moo_t* moo,
const moo_ooch_t* name, const moo_ooch_t* name,
moo_oow_t namelen moo_oow_t namelen,
int hints /* 0 or bitwise-ORed of moo_mod_hint_t enumerators */
); );
void moo_closemod ( void moo_closemod (

View File

@ -378,7 +378,7 @@ static_modtab[] =
}; };
#endif #endif
moo_mod_data_t* moo_openmod (moo_t* moo, const moo_ooch_t* name, moo_oow_t namelen) moo_mod_data_t* moo_openmod (moo_t* moo, const moo_ooch_t* name, moo_oow_t namelen, int hints)
{ {
moo_rbt_pair_t* pair; moo_rbt_pair_t* pair;
moo_mod_data_t* mdp; moo_mod_data_t* mdp;
@ -423,14 +423,6 @@ moo_mod_data_t* moo_openmod (moo_t* moo, const moo_ooch_t* name, moo_oow_t namel
} }
} }
if (n >= MOO_COUNTOF(static_modtab))
{
MOO_DEBUG2 (moo, "Cannot find a static module [%.*js]\n", namelen, name);
moo->errnum = MOO_ENOENT;
return MOO_NULL;
/* TODO: fall back to find dynamic module further on supported platforms instead of returning error here... */
}
if (load) if (load)
{ {
/* found the module in the staic module table */ /* found the module in the staic module table */
@ -449,17 +441,36 @@ moo_mod_data_t* moo_openmod (moo_t* moo, const moo_ooch_t* name, moo_oow_t namel
} }
mdp = (moo_mod_data_t*)MOO_RBT_VPTR(pair); mdp = (moo_mod_data_t*)MOO_RBT_VPTR(pair);
MOO_ASSERT (moo, MOO_SIZEOF(mdp->mod.hints) == MOO_SIZEOF(int));
*(int*)&mdp->mod.hints = hints;
if (load (moo, &mdp->mod) <= -1) if (load (moo, &mdp->mod) <= -1)
{ {
moo_rbt_delete (&moo->modtab, (moo_ooch_t*)name, namelen); moo_rbt_delete (&moo->modtab, (moo_ooch_t*)name, namelen);
return MOO_NULL; return MOO_NULL;
} }
mdp->pair = pair;
MOO_DEBUG1 (moo, "Opened a static module [%js]\n", mdp->mod.name);
return mdp; return mdp;
} }
else
{
#if !defined(MOO_ENABLE_DYNAMIC_MODULE)
MOO_DEBUG2 (moo, "Cannot find a static module [%.*js]\n", namelen, name);
moo->errnum = MOO_ENOENT;
return MOO_NULL;
#endif
}
#endif #endif
/* attempt to find an external module */ #if !defined(MOO_ENABLE_DYNAMIC_MODULE)
MOO_DEBUG2 (moo, "Cannot open module [%.*js] - module loading disabled\n", namelen, name);
moo->errnum = MOO_ENOIMPL; /* TODO: is it a good error number for disabled module loading? */
return MOO_NULL;
#endif
/* attempt to find a dynamic external module */
MOO_MEMSET (&md, 0, MOO_SIZEOF(md)); MOO_MEMSET (&md, 0, MOO_SIZEOF(md));
moo_copyoochars ((moo_ooch_t*)md.mod.name, name, namelen); moo_copyoochars ((moo_ooch_t*)md.mod.name, name, namelen);
if (moo->vmprim.dl_open && moo->vmprim.dl_getsym && moo->vmprim.dl_close) if (moo->vmprim.dl_open && moo->vmprim.dl_getsym && moo->vmprim.dl_close)
@ -496,6 +507,8 @@ moo_mod_data_t* moo_openmod (moo_t* moo, const moo_ooch_t* name, moo_oow_t namel
} }
mdp = (moo_mod_data_t*)MOO_RBT_VPTR(pair); mdp = (moo_mod_data_t*)MOO_RBT_VPTR(pair);
MOO_ASSERT (moo, MOO_SIZEOF(mdp->mod.hints) == MOO_SIZEOF(int));
*(int*)&mdp->mod.hints = hints;
if (load (moo, &mdp->mod) <= -1) if (load (moo, &mdp->mod) <= -1)
{ {
MOO_DEBUG3 (moo, "Module function [%js] returned failure in [%.*js]\n", buf, namelen, name); MOO_DEBUG3 (moo, "Module function [%js] returned failure in [%.*js]\n", buf, namelen, name);
@ -525,6 +538,10 @@ void moo_closemod (moo_t* moo, moo_mod_data_t* mdp)
MOO_DEBUG2 (moo, "Closed a module [%js] - %p\n", mdp->mod.name, mdp->handle); MOO_DEBUG2 (moo, "Closed a module [%js] - %p\n", mdp->mod.name, mdp->handle);
mdp->handle = MOO_NULL; mdp->handle = MOO_NULL;
} }
else
{
MOO_DEBUG1 (moo, "Closed a static module [%js] - %p\n", mdp->mod.name);
}
if (mdp->pair) if (mdp->pair)
{ {
@ -537,7 +554,7 @@ int moo_importmod (moo_t* moo, moo_oop_class_t _class, const moo_ooch_t* name, m
{ {
moo_rbt_pair_t* pair; moo_rbt_pair_t* pair;
moo_mod_data_t* mdp; moo_mod_data_t* mdp;
int r = 0; int r = -1;
/* moo_openmod(), moo_closemod(), etc call a user-defined callback. /* moo_openmod(), moo_closemod(), etc call a user-defined callback.
* i need to protect _class in case the user-defined callback allocates * i need to protect _class in case the user-defined callback allocates
@ -550,38 +567,36 @@ int moo_importmod (moo_t* moo, moo_oop_class_t _class, const moo_ooch_t* name, m
{ {
mdp = (moo_mod_data_t*)MOO_RBT_VPTR(pair); mdp = (moo_mod_data_t*)MOO_RBT_VPTR(pair);
MOO_ASSERT (moo, mdp != MOO_NULL); MOO_ASSERT (moo, mdp != MOO_NULL);
}
else MOO_DEBUG1 (moo, "Cannot import module [%js] - already active\n", mdp->mod.name);
{ moo->errnum = MOO_EPERM;
mdp = moo_openmod (moo, name, len);
if (!mdp)
{
r = -1;
goto done2; goto done2;
} }
}
mdp = moo_openmod (moo, name, len, MOO_MOD_LOAD_FOR_IMPORT);
if (!mdp) goto done2;
if (!mdp->mod.import) if (!mdp->mod.import)
{ {
MOO_DEBUG1 (moo, "Cannot import module [%js] - importing not supported by the module\n", mdp->mod.name); MOO_DEBUG1 (moo, "Cannot import module [%js] - importing not supported by the module\n", mdp->mod.name);
moo->errnum = MOO_ENOIMPL; moo->errnum = MOO_ENOIMPL;
r = -1;
goto done; goto done;
} }
if (mdp->mod.import (moo, &mdp->mod, _class) <= -1) if (mdp->mod.import (moo, &mdp->mod, _class) <= -1)
{ {
MOO_DEBUG1 (moo, "Cannot import module [%js] - module's import() returned failure\n", mdp->mod.name); MOO_DEBUG1 (moo, "Cannot import module [%js] - module's import() returned failure\n", mdp->mod.name);
r = -1;
goto done; goto done;
} }
r = 0; /* everything successful */
done: done:
if (!pair) /* close the module opened above.
{ * [NOTE] if the import callback calls the moo_querymod(), the returned
/* close the module if it has been opened in this function. */ * function pointers will get all invalidated here. so never do
* anything like that */
moo_closemod (moo, mdp); moo_closemod (moo, mdp);
}
done2: done2:
moo_poptmp (moo); moo_poptmp (moo);
@ -615,8 +630,8 @@ moo_pfimpl_t moo_querymod (moo_t* moo, const moo_ooch_t* pfid, moo_oow_t pfidlen
mod_name_len = sep - pfid; mod_name_len = sep - pfid;
/* the first through the segment before the last compose a module id. /* the first segment through the segment before the last compose a
* the last segment is the primitive function name. * module id. the last segment is the primitive function name.
* for instance, in con.window.open, con.window is a module id and * for instance, in con.window.open, con.window is a module id and
* open is the primitive function name. */ * open is the primitive function name. */
pair = moo_rbt_search (&moo->modtab, pfid, mod_name_len); pair = moo_rbt_search (&moo->modtab, pfid, mod_name_len);
@ -628,7 +643,7 @@ moo_pfimpl_t moo_querymod (moo_t* moo, const moo_ooch_t* pfid, moo_oow_t pfidlen
else else
{ {
/* open a module using the part before the last period */ /* open a module using the part before the last period */
mdp = moo_openmod (moo, pfid, mod_name_len); mdp = moo_openmod (moo, pfid, mod_name_len, 0);
if (!mdp) return MOO_NULL; if (!mdp) return MOO_NULL;
} }
@ -873,3 +888,22 @@ void* moo_getobjtrailer (moo_t* moo, moo_oop_t obj, moo_oow_t* size)
if (size) *size = MOO_OBJ_GET_TRAILER_SIZE(obj); if (size) *size = MOO_OBJ_GET_TRAILER_SIZE(obj);
return MOO_OBJ_GET_TRAILER_BYTE(obj); return MOO_OBJ_GET_TRAILER_BYTE(obj);
} }
moo_oop_t moo_findclass (moo_t* moo, moo_oop_set_t nsdic, const moo_ooch_t* name)
{
moo_oop_association_t ass;
moo_oocs_t n;
n.ptr = (moo_ooch_t*)name;
n.len = moo_countoocstr(name);
ass = moo_lookupdic (moo, nsdic, &n);
if (!ass || MOO_CLASSOF(moo,ass->value) != moo->_class)
{
moo->errnum = MOO_ENOENT;
return MOO_NULL;
}
return ass->value;
}

View File

@ -840,9 +840,14 @@ struct moo_pfinfo_t
moo_pfimpl_t handler; moo_pfimpl_t handler;
}; };
typedef struct moo_mod_t moo_mod_t; typedef struct moo_mod_t moo_mod_t;
enum moo_mod_hint_t
{
MOO_MOD_LOAD_FOR_IMPORT = (1 << 0)
};
typedef enum moo_mod_hint_t moo_mod_hint_t;
typedef int (*moo_mod_load_t) ( typedef int (*moo_mod_load_t) (
moo_t* moo, moo_t* moo,
moo_mod_t* mod moo_mod_t* mod
@ -865,12 +870,22 @@ typedef void (*moo_mod_unload_t) (
moo_mod_t* mod moo_mod_t* mod
); );
typedef void (*moo_mod_gc_t) (
moo_t* moo,
moo_mod_t* mod
);
struct moo_mod_t struct moo_mod_t
{ {
/* input */
const moo_ooch_t name[MOO_MOD_NAME_LEN_MAX + 1]; const moo_ooch_t name[MOO_MOD_NAME_LEN_MAX + 1];
const int hints; /* bitwised-ORed of moo_mod_hint_t enumerators */
/* user-defined data */
moo_mod_import_t import; moo_mod_import_t import;
moo_mod_query_t query; moo_mod_query_t query;
moo_mod_unload_t unload; moo_mod_unload_t unload;
moo_mod_gc_t gc;
void* ctx; void* ctx;
}; };
@ -883,7 +898,6 @@ struct moo_mod_data_t
typedef struct moo_mod_data_t moo_mod_data_t; typedef struct moo_mod_data_t moo_mod_data_t;
struct moo_sbuf_t struct moo_sbuf_t
{ {
moo_ooch_t* ptr; moo_ooch_t* ptr;
@ -1065,6 +1079,7 @@ struct moo_t
#define MOO_STACK_POPS(moo,count) ((moo)->sp = (moo)->sp - (count)) #define MOO_STACK_POPS(moo,count) ((moo)->sp = (moo)->sp - (count))
#define MOO_STACK_ISEMPTY(moo) ((moo)->sp <= -1) #define MOO_STACK_ISEMPTY(moo) ((moo)->sp <= -1)
#define MOO_STACK_GETARGSP(moo,nargs,idx) ((moo)->sp - ((nargs) - (idx) - 1))
#define MOO_STACK_GETARG(moo,nargs,idx) MOO_STACK_GET(moo, (moo)->sp - ((nargs) - (idx) - 1)) #define MOO_STACK_GETARG(moo,nargs,idx) MOO_STACK_GET(moo, (moo)->sp - ((nargs) - (idx) - 1))
#define MOO_STACK_GETRCV(moo,nargs) MOO_STACK_GET(moo, (moo)->sp - nargs) #define MOO_STACK_GETRCV(moo,nargs) MOO_STACK_GET(moo, (moo)->sp - nargs)
@ -1348,6 +1363,15 @@ MOO_EXPORT void moo_gc (
); );
/**
* The moo_moveoop() function moves an object and returns an updated pointer
* after having moved. it must be called in the GC callback context only.
*/
MOO_EXPORT moo_oop_t moo_moveoop (
moo_t* moo,
moo_oop_t oop
);
/** /**
* The moo_instantiate() function creates a new object instance of the class * The moo_instantiate() function creates a new object instance of the class
* \a _class. The size of the fixed part is taken from the information * \a _class. The size of the fixed part is taken from the information
@ -1457,6 +1481,11 @@ MOO_EXPORT int moo_inttoooi (
moo_ooi_t* i moo_ooi_t* i
); );
MOO_EXPORT moo_oop_t moo_findclass (
moo_t* moo,
moo_oop_set_t nsdic,
const moo_ooch_t* name
);
/* ========================================================================= /* =========================================================================
* TRAILER MANAGEMENT * TRAILER MANAGEMENT

View File

@ -34,12 +34,21 @@
#define C MOO_METHOD_CLASS #define C MOO_METHOD_CLASS
#define I MOO_METHOD_INSTANCE #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; typedef struct x11_t x11_t;
struct x11_t struct x11_t
{ {
xcb_connection_t* c; xcb_connection_t* c;
xcb_screen_t* screen; xcb_screen_t* screen;
xcb_generic_event_t* curevt; /* most recent event received */
}; };
typedef struct x11_win_t x11_win_t; typedef struct x11_win_t x11_win_t;
@ -49,6 +58,7 @@ struct x11_win_t
xcb_intern_atom_reply_t* dwcr; xcb_intern_atom_reply_t* dwcr;
}; };
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs) 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; x11_t* x11;
xcb_connection_t* c; xcb_connection_t* c;
x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
/* TODO: accept display target as a parameter */ /* TODO: accept display target as a parameter */
if (nargs != 0) if (nargs != 0)
{ {
@ -63,8 +75,6 @@ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs)
goto softfail; goto softfail;
} }
x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
if (x11->c) if (x11->c)
{ {
MOO_DEBUG0 (moo, "<x11.connect> Unable to connect multiple times\n"); 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); MOO_DEBUG1 (moo, "<x11.disconnect> %p\n", x11->c);
if (x11->curevt)
{
free (x11->curevt);
x11->curevt = MOO_NULL;
}
if (x11->c) if (x11->c)
{ {
xcb_disconnect (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); MOO_STACK_SETRETTORCV (moo, nargs);
return MOO_PF_SUCCESS; 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_t* x11;
x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); 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) if (x11->c)
{ {
@ -146,38 +157,73 @@ static moo_pfrc_t pf_getfd (moo_t* moo, moo_ooi_t nargs)
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
} }
static moo_pfrc_t pf_getevent (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t pf_getevent (moo_t* moo, moo_ooi_t nargs)
{ {
x11_t* x11; x11_t* x11;
xcb_generic_event_t* evt; xcb_generic_event_t* evt;
x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); 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); evt = xcb_poll_for_event(x11->c);
if (x11->curevt) free (x11->curevt);
x11->curevt = evt;
if (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 (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 */ MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(9999)); /* TODO: translate evt to the event object */
} }
else else
{ {
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(evttype)); /* TODO: translate evt to the event object */ 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); free (evt);
#endif
}
else if (xcb_connection_has_error(x11->c))
{
/* TODO: to be specific about the error */
MOO_STACK_SETRETTOERROR (moo, nargs);
} }
else 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) static moo_pfrc_t pf_win_make_on (moo_t* moo, moo_ooi_t nargs)
{ {
x11_t* x11; x11_t* x11;
x11_win_t* win; x11_win_t* win;
moo_oop_t id;
uint32_t mask; uint32_t mask;
uint32_t values[2]; uint32_t values[2];
xcb_intern_atom_cookie_t cookie; xcb_intern_atom_cookie_t cookie;
xcb_intern_atom_reply_t* reply; 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); 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); 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); 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; mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
values[0] = x11->screen->white_pixel; values[0] = x11->screen->white_pixel;
values[1] = XCB_EVENT_MASK_KEY_RELEASE | 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_map_window (x11->c, win->id);
xcb_flush (x11->c); xcb_flush (x11->c);
MOO_STACK_SETRETTORCV (moo, nargs); MOO_STACK_SETRET (moo, nargs, id);
return MOO_PF_SUCCESS; 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[] = 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, { '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, { '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_getfd } { 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) 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) 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) 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->import = x11_import;
mod->query = x11_query; mod->query = x11_query;
mod->unload = x11_unload; mod->unload = x11_unload;
mod->ctx = MOO_NULL;
return 0; return 0;
} }
@ -307,8 +440,9 @@ int moo_mod_x11 (moo_t* moo, moo_mod_t* mod)
static moo_pfinfo_t x11_win_pfinfo[] = static moo_pfinfo_t x11_win_pfinfo[] =
{ {
{ I, { '_','m','a','k','e','_','o','n',':','\0' }, 0, pf_win_make_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, { '_','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) 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) 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) 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->import = x11_win_import;
mod->query = x11_win_query; mod->query = x11_win_query;
mod->unload = x11_win_unload; mod->unload = x11_win_unload;
mod->gc = MOO_NULL;
mod->ctx = MOO_NULL; mod->ctx = MOO_NULL;
return 0; return 0;
} }