added respondsTo: and perform:with:
fixed a bug in Dictionary>>__remove_at: added gc callback to external modules
This commit is contained in:
parent
6a2add620b
commit
46ba3bb3f5
34
moo/configure
vendored
34
moo/configure
vendored
@ -660,6 +660,8 @@ ENABLE_LIBLTDL_FALSE
|
||||
ENABLE_LIBLTDL_TRUE
|
||||
ENABLE_STATIC_MODULE_FALSE
|
||||
ENABLE_STATIC_MODULE_TRUE
|
||||
ENABLE_DYNAMIC_MODULE_FALSE
|
||||
ENABLE_DYNAMIC_MODULE_TRUE
|
||||
ENABLE_CXX_FALSE
|
||||
ENABLE_CXX_TRUE
|
||||
BUILD_MODE
|
||||
@ -832,6 +834,7 @@ with_ltdl_lib
|
||||
enable_ltdl_install
|
||||
enable_debug
|
||||
enable_cxx
|
||||
enable_dynamic_module
|
||||
enable_static_module
|
||||
enable_libltdl
|
||||
'
|
||||
@ -1482,6 +1485,7 @@ Optional Features:
|
||||
--enable-debug build the library in the debug mode (default. no)
|
||||
--enable-cxx build the library for C++ if a C++ compiler is
|
||||
available (default. yes)
|
||||
--enable-dynamic-module enable dynamic module capability(default. yes)
|
||||
--enable-static-module build modules statically into the main
|
||||
library(default. no)
|
||||
--enable-libltdl use libltdl(default. yes)
|
||||
@ -20588,6 +20592,31 @@ else
|
||||
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.
|
||||
if test "${enable_static_module+set}" = set; then :
|
||||
enableval=$enable_static_module; enable_static_module_is=$enableval
|
||||
@ -20613,7 +20642,6 @@ else
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Check whether --enable-libltdl was given.
|
||||
if test "${enable_libltdl+set}" = set; then :
|
||||
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.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
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
|
||||
as_fn_error $? "conditional \"ENABLE_STATIC_MODULE\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
|
@ -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" )
|
||||
|
||||
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 =====
|
||||
AC_ARG_ENABLE([static-module],
|
||||
[AS_HELP_STRING([--enable-static-module],[build modules statically into the main library(default. no)])],
|
||||
@ -434,7 +448,6 @@ then
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_STATIC_MODULE, test "${enable_static_module_is}" = "yes")
|
||||
|
||||
|
||||
dnl ===== enable-libltdl =====
|
||||
AC_ARG_ENABLE([libltdl],
|
||||
[AS_HELP_STRING([--enable-libltdl],[use libltdl(default. yes)])],
|
||||
@ -443,7 +456,7 @@ AC_ARG_ENABLE([libltdl],
|
||||
)
|
||||
if test "${enable_libltdl_is}" = "yes"
|
||||
then
|
||||
AC_DEFINE([MOO_ENABLE_LIBLTDL],[],[use libltdl])
|
||||
AC_DEFINE([MOO_ENABLE_LIBLTDL],[],[use libltdl when loading a dynamic module])
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_LIBLTDL, test "${enable_libltdl_is}" = "yes")
|
||||
|
||||
|
@ -312,17 +312,86 @@ class Apex(nil)
|
||||
^(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
|
||||
{
|
||||
|
@ -321,40 +321,33 @@ class Set(Collection)
|
||||
|
||||
method __remove_at: index
|
||||
{
|
||||
| bs x y i v |
|
||||
| bs x y i v ass z |
|
||||
|
||||
bs := self.bucket size.
|
||||
v := self.bucket basicAt: index.
|
||||
v := self.bucket at: index.
|
||||
|
||||
x := index.
|
||||
y := index.
|
||||
i := 0.
|
||||
[i < self.tally] whileTrue: [
|
||||
| ass z |
|
||||
|
||||
while (i < self.tally)
|
||||
{
|
||||
y := (y + 1) rem: bs.
|
||||
|
||||
ass := self.bucket at: i.
|
||||
if (ass isNil)
|
||||
{
|
||||
(* done. the slot at the current index is nil *)
|
||||
i := self.tally
|
||||
}
|
||||
else
|
||||
{
|
||||
(* get the natural hash index *)
|
||||
z := (ass key hash) rem: bs.
|
||||
ass := self.bucket at: y.
|
||||
if (ass isNil) { (* done. the slot at the current index is nil *) break }.
|
||||
|
||||
(* move an element if necessary *)
|
||||
if ((y > x and: [(z <= x) or: [z > y]]) or: [(y < x) and: [(z <= x) and: [z > y]]])
|
||||
{
|
||||
self.bucket at: x put: (self.bucket at: y).
|
||||
x := y.
|
||||
}.
|
||||
(* get the natural hash index *)
|
||||
z := (ass key hash) rem: bs.
|
||||
|
||||
i := i + 1
|
||||
(* move an element if necessary *)
|
||||
if ((y > x and: [(z <= x) or: [z > y]]) or: [(y < x) and: [(z <= x) and: [z > y]]])
|
||||
{
|
||||
self.bucket at: x put: (self.bucket at: y).
|
||||
x := y.
|
||||
}.
|
||||
].
|
||||
|
||||
i := i + 1.
|
||||
}.
|
||||
|
||||
self.bucket at: x put: nil.
|
||||
self.tally := self.tally - 1.
|
||||
@ -744,14 +737,15 @@ class LinkedList(Collection)
|
||||
else { self.first := link next }.
|
||||
|
||||
self.tally := self.tally - 1.
|
||||
^link.
|
||||
}
|
||||
|
||||
method removeFirst
|
||||
method removeFirstLink
|
||||
{
|
||||
^self removeLink: self.first
|
||||
}
|
||||
|
||||
method removeLast
|
||||
method removeLastLink
|
||||
{
|
||||
^self removeLink: self.last
|
||||
}
|
||||
@ -767,4 +761,22 @@ class LinkedList(Collection)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +108,7 @@
|
||||
#endif
|
||||
|
||||
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)
|
||||
@ -1521,6 +1522,7 @@ static moo_pfrc_t pf_basic_at (moo_t* moo, moo_ooi_t nargs)
|
||||
if (!MOO_OOP_IS_POINTER(rcv))
|
||||
{
|
||||
/* the receiver is a special numeric object, not a normal pointer */
|
||||
moo->errnum = MOO_EINVAL;
|
||||
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)
|
||||
{
|
||||
/* negative integer or not integer */
|
||||
moo->errnum = MOO_EINVAL;
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
if (idx >= MOO_OBJ_GET_SIZE(rcv))
|
||||
{
|
||||
/* index out of range */
|
||||
moo->errnum = MOO_ERANGE;
|
||||
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))
|
||||
{
|
||||
/* the receiver is a special numeric object, not a normal pointer */
|
||||
moo->errnum = MOO_EINVAL;
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
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)
|
||||
{
|
||||
/* negative integer or not integer */
|
||||
moo->errnum = MOO_EINVAL;
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
if (idx >= MOO_OBJ_GET_SIZE(rcv))
|
||||
{
|
||||
/* index out of range */
|
||||
moo->errnum = MOO_ERANGE;
|
||||
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: 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 */
|
||||
moo->errnum = MOO_EINVAL;
|
||||
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))
|
||||
{
|
||||
/* the value is not a character */
|
||||
moo->errnum = MOO_EINVAL;
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
/* 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))
|
||||
{
|
||||
/* the value is not a character */
|
||||
moo->errnum = MOO_EINVAL;
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
((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))
|
||||
{
|
||||
/* the value is not a number */
|
||||
moo->errnum = MOO_EINVAL;
|
||||
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)
|
||||
{
|
||||
/* the value is not a number, out of range, or negative */
|
||||
moo->errnum = MOO_EINVAL;
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
((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:
|
||||
/* MOO_OBJ_TYPE_OOP, ... */
|
||||
MOO_DEBUG1 (moo, "<pf_hash> Cannot hash an object of type %d\n", type);
|
||||
moo->errnum = MOO_EINVAL;
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
break;
|
||||
@ -1726,6 +1739,65 @@ static moo_pfrc_t pf_hash (moo_t* moo, moo_ooi_t nargs)
|
||||
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)
|
||||
{
|
||||
moo_oop_t rcv;
|
||||
@ -2719,12 +2791,15 @@ static pf_t pftab[] =
|
||||
|
||||
{ 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_context_goto, "_context_goto" },
|
||||
{ 0, MAX_NARGS, pf_block_value, "_block_value" },
|
||||
{ 0, MAX_NARGS, pf_block_new_process, "_block_new_process" },
|
||||
|
||||
|
||||
{ 0, 0, pf_process_resume, "_process_resume" },
|
||||
{ 0, 0, pf_process_terminate, "_process_terminate" },
|
||||
{ 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);
|
||||
|
||||
mthname.ptr = selector->slot;
|
||||
mthname.ptr = MOO_OBJ_GET_CHAR_SLOT(selector);
|
||||
mthname.len = MOO_OBJ_GET_SIZE(selector);
|
||||
method = find_method (moo, receiver, &mthname, to_super);
|
||||
if (!method)
|
||||
|
15
moo/lib/gc.c
15
moo/lib/gc.c
@ -562,6 +562,19 @@ static moo_uint8_t* scan_new_heap (moo_t* moo, moo_uint8_t* 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)
|
||||
{
|
||||
/*
|
||||
@ -643,6 +656,8 @@ void moo_gc (moo_t* moo)
|
||||
if (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)
|
||||
{
|
||||
if (cb->gc) cb->gc (moo);
|
||||
|
@ -462,6 +462,9 @@ static void* dl_open (moo_t* moo, const moo_ooch_t* name, int flags)
|
||||
return handle;
|
||||
|
||||
#else
|
||||
|
||||
|
||||
|
||||
/* TODO: support various platforms */
|
||||
/* TODO: implemenent this */
|
||||
MOO_DEBUG1 (moo, "Dynamic loading not implemented - cannot open %js\n", name);
|
||||
@ -1320,11 +1323,12 @@ int main (int argc, char* argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
memset (&vmprim, 0, MOO_SIZEOF(vmprim));
|
||||
vmprim.dl_open = dl_open;
|
||||
vmprim.dl_close = dl_close;
|
||||
vmprim.dl_getsym = dl_getsym;
|
||||
vmprim.log_write = log_write;
|
||||
|
||||
vmprim.vm_startup = vm_startup;
|
||||
vmprim.vm_cleanup = vm_cleanup;
|
||||
vmprim.vm_gettime = vm_gettime;
|
||||
|
@ -326,7 +326,10 @@
|
||||
/* Define to the shared archive member specification, say "(shr.o)". */
|
||||
#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
|
||||
|
||||
/* link modules statically into the main library */
|
||||
|
@ -925,15 +925,6 @@ void* moo_allocheapmem (
|
||||
moo_oow_t size
|
||||
);
|
||||
|
||||
|
||||
/* ========================================================================= */
|
||||
/* gc.c */
|
||||
/* ========================================================================= */
|
||||
moo_oop_t moo_moveoop (
|
||||
moo_t* moo,
|
||||
moo_oop_t oop
|
||||
);
|
||||
|
||||
/* ========================================================================= */
|
||||
/* obj.c */
|
||||
/* ========================================================================= */
|
||||
@ -1185,13 +1176,14 @@ int moo_getpfnum (
|
||||
|
||||
|
||||
/* ========================================================================= */
|
||||
/* moo.c */
|
||||
/* moo.c */
|
||||
/* ========================================================================= */
|
||||
|
||||
moo_mod_data_t* moo_openmod (
|
||||
moo_t* moo,
|
||||
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 (
|
||||
|
@ -378,7 +378,7 @@ static_modtab[] =
|
||||
};
|
||||
#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_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)
|
||||
{
|
||||
/* 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);
|
||||
MOO_ASSERT (moo, MOO_SIZEOF(mdp->mod.hints) == MOO_SIZEOF(int));
|
||||
*(int*)&mdp->mod.hints = hints;
|
||||
if (load (moo, &mdp->mod) <= -1)
|
||||
{
|
||||
moo_rbt_delete (&moo->modtab, (moo_ooch_t*)name, namelen);
|
||||
return MOO_NULL;
|
||||
}
|
||||
|
||||
mdp->pair = pair;
|
||||
|
||||
MOO_DEBUG1 (moo, "Opened a static module [%js]\n", mdp->mod.name);
|
||||
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
|
||||
|
||||
/* 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_copyoochars ((moo_ooch_t*)md.mod.name, name, namelen);
|
||||
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);
|
||||
MOO_ASSERT (moo, MOO_SIZEOF(mdp->mod.hints) == MOO_SIZEOF(int));
|
||||
*(int*)&mdp->mod.hints = hints;
|
||||
if (load (moo, &mdp->mod) <= -1)
|
||||
{
|
||||
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);
|
||||
mdp->handle = MOO_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
MOO_DEBUG1 (moo, "Closed a static module [%js] - %p\n", mdp->mod.name);
|
||||
}
|
||||
|
||||
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_mod_data_t* mdp;
|
||||
int r = 0;
|
||||
int r = -1;
|
||||
|
||||
/* moo_openmod(), moo_closemod(), etc call a user-defined callback.
|
||||
* 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);
|
||||
MOO_ASSERT (moo, mdp != MOO_NULL);
|
||||
|
||||
MOO_DEBUG1 (moo, "Cannot import module [%js] - already active\n", mdp->mod.name);
|
||||
moo->errnum = MOO_EPERM;
|
||||
goto done2;
|
||||
}
|
||||
else
|
||||
{
|
||||
mdp = moo_openmod (moo, name, len);
|
||||
if (!mdp)
|
||||
{
|
||||
r = -1;
|
||||
goto done2;
|
||||
}
|
||||
}
|
||||
|
||||
mdp = moo_openmod (moo, name, len, MOO_MOD_LOAD_FOR_IMPORT);
|
||||
if (!mdp) goto done2;
|
||||
|
||||
if (!mdp->mod.import)
|
||||
{
|
||||
MOO_DEBUG1 (moo, "Cannot import module [%js] - importing not supported by the module\n", mdp->mod.name);
|
||||
moo->errnum = MOO_ENOIMPL;
|
||||
r = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
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);
|
||||
r = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
r = 0; /* everything successful */
|
||||
|
||||
done:
|
||||
if (!pair)
|
||||
{
|
||||
/* close the module if it has been opened in this function. */
|
||||
moo_closemod (moo, mdp);
|
||||
}
|
||||
/* close the module opened above.
|
||||
* [NOTE] if the import callback calls the moo_querymod(), the returned
|
||||
* function pointers will get all invalidated here. so never do
|
||||
* anything like that */
|
||||
moo_closemod (moo, mdp);
|
||||
|
||||
done2:
|
||||
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;
|
||||
|
||||
/* the first through the segment before the last compose a module id.
|
||||
* the last segment is the primitive function name.
|
||||
/* the first segment through the segment before the last compose a
|
||||
* module id. the last segment is the primitive function name.
|
||||
* for instance, in con.window.open, con.window is a module id and
|
||||
* open is the primitive function name. */
|
||||
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
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
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;
|
||||
}
|
||||
|
@ -840,9 +840,14 @@ struct moo_pfinfo_t
|
||||
moo_pfimpl_t handler;
|
||||
};
|
||||
|
||||
|
||||
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) (
|
||||
moo_t* moo,
|
||||
moo_mod_t* mod
|
||||
@ -865,12 +870,22 @@ typedef void (*moo_mod_unload_t) (
|
||||
moo_mod_t* mod
|
||||
);
|
||||
|
||||
typedef void (*moo_mod_gc_t) (
|
||||
moo_t* moo,
|
||||
moo_mod_t* mod
|
||||
);
|
||||
|
||||
struct moo_mod_t
|
||||
{
|
||||
/* input */
|
||||
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_query_t query;
|
||||
moo_mod_unload_t unload;
|
||||
moo_mod_gc_t gc;
|
||||
void* ctx;
|
||||
};
|
||||
|
||||
@ -883,7 +898,6 @@ struct moo_mod_data_t
|
||||
typedef struct moo_mod_data_t moo_mod_data_t;
|
||||
|
||||
|
||||
|
||||
struct moo_sbuf_t
|
||||
{
|
||||
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_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_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
|
||||
* \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_EXPORT moo_oop_t moo_findclass (
|
||||
moo_t* moo,
|
||||
moo_oop_set_t nsdic,
|
||||
const moo_ooch_t* name
|
||||
);
|
||||
|
||||
/* =========================================================================
|
||||
* TRAILER MANAGEMENT
|
||||
|
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user