示例#1
0
GClosure*
gjs_closure_new(JSContext  *context,
                JSObject   *callable,
                const char *description,
                gboolean    root_function)
{
    Closure *c;

    c = (Closure*) g_closure_new_simple(sizeof(Closure), NULL);
    c->runtime = JS_GetRuntime(context);
    /* The saved context is used for lifetime management, so that the closure will
     * be torn down with the context that created it. The context could be attached to
     * the default context of the runtime using if we wanted the closure to survive
     * the context that created it.
     */
    c->context = context;
    JS_BeginRequest(context);

    c->obj = callable;
    c->unref_on_global_object_finalized = FALSE;

    GJS_INC_COUNTER(closure);
    /* the finalize notifier right now is purely to track the counter
     * of how many closures are alive.
     */
    g_closure_add_finalize_notifier(&c->base, NULL, closure_finalized);

    if (root_function) {
        /* Fully manage closure lifetime if so asked */
        gjs_keep_alive_add_global_child(context,
                                        global_context_finalized,
                                        c->obj,
                                        c);

        g_closure_add_invalidate_notifier(&c->base, NULL, closure_invalidated);
    } else {
        /* Only mark the closure as invalid if memory is managed
           outside (i.e. by object.c for signals) */
        g_closure_add_invalidate_notifier(&c->base, NULL, closure_set_invalid);
    }

    gjs_debug_closure("Create closure %p which calls object %p '%s'",
                      c, c->obj, description);

    JS_EndRequest(context);

    return &c->base;
}
示例#2
0
/**
 * pyg_closure_new:
 * callback: a Python callable object
 * extra_args: a tuple of extra arguments, or None/NULL.
 * swap_data: an alternative python object to pass first.
 *
 * Creates a GClosure wrapping a Python callable and optionally a set
 * of additional function arguments.  This is needed to attach python
 * handlers to signals, for instance.
 *
 * Returns: the new closure.
 */
GClosure *
pyg_closure_new(PyObject *callback, PyObject *extra_args, PyObject *swap_data)
{
    GClosure *closure;

    g_return_val_if_fail(callback != NULL, NULL);
    closure = g_closure_new_simple(sizeof(PyGClosure), NULL);
    g_closure_add_invalidate_notifier(closure, NULL, pyg_closure_invalidate);
    g_closure_set_marshal(closure, pyg_closure_marshal);
    Py_INCREF(callback);
    ((PyGClosure *)closure)->callback = callback;
    if (extra_args && extra_args != Py_None) {
	Py_INCREF(extra_args);
	if (!PyTuple_Check(extra_args)) {
	    PyObject *tmp = PyTuple_New(1);
	    PyTuple_SetItem(tmp, 0, extra_args);
	    extra_args = tmp;
	}
	((PyGClosure *)closure)->extra_args = extra_args;
    }
    if (swap_data) {
	Py_INCREF(swap_data);
	((PyGClosure *)closure)->swap_data = swap_data;
	closure->derivative_flag = TRUE;
    }
    return closure;
}
示例#3
0
文件: prop-editor.c 项目: 3v1n0/gtk
static void
g_object_connect_property (GObject    *object,
                           GParamSpec *spec,
                           GCallback   func,
                           gpointer    data,
                           GObject    *alive_object)
{
  GClosure *closure;
  gchar *with_detail;
  DisconnectData *dd;

  if (is_child_property (spec))
    with_detail = g_strconcat ("child-notify::", spec->name, NULL);
  else
    with_detail = g_strconcat ("notify::", spec->name, NULL);

  dd = g_new (DisconnectData, 1);

  closure = g_cclosure_new (func, data, NULL);
  g_closure_add_invalidate_notifier (closure, dd, signal_removed);
  dd->id = g_signal_connect_closure (object, with_detail, closure, FALSE);
  dd->instance = object;
  dd->alive_object = alive_object;

  g_object_set_data_full (G_OBJECT (alive_object), "alive-object-data",
                          dd, disconnect_func);

  g_free (with_detail);
}
示例#4
0
GClosure *
gtk2hs_closure_new(HsStablePtr callback)
{
    GClosure *closure;

    WHEN_DEBUG(g_debug("gtk2hs_closure_new: enter, callback=%p", callback));
    closure = g_closure_new_simple(sizeof(Gtk2HsClosure), NULL);
    /* TODO: check if we should be using invalidate or finalise notifier */
    g_closure_add_invalidate_notifier(closure, NULL, gtk2hs_closure_invalidate);
    g_closure_set_marshal(closure, gtk2hs_closure_marshal);

    ((Gtk2HsClosure *)closure)->callback = callback;

    WHEN_DEBUG(g_debug("gtk2hs_closure_new: leave"));

    return closure;
}
示例#5
0
GClosure *
pygi_signal_closure_new (PyGObject *instance,
                         GType g_type,
                         const gchar *signal_name,
                         PyObject *callback,
                         PyObject *extra_args,
                         PyObject *swap_data)
{
    GClosure *closure = NULL;
    PyGISignalClosure *pygi_closure = NULL;
    GISignalInfo *signal_info = NULL;

    g_return_val_if_fail(callback != NULL, NULL);

    signal_info = _pygi_lookup_signal_from_g_type (g_type, signal_name);
    if (signal_info == NULL)
        return NULL;

    closure = g_closure_new_simple(sizeof(PyGISignalClosure), NULL);
    g_closure_add_invalidate_notifier(closure, NULL, pygi_signal_closure_invalidate);
    g_closure_set_marshal(closure, pygi_signal_closure_marshal);

    pygi_closure = (PyGISignalClosure *)closure;

    pygi_closure->signal_info = signal_info;
    Py_INCREF(callback);
    pygi_closure->pyg_closure.callback = callback;

    if (extra_args != NULL && extra_args != Py_None) {
        Py_INCREF(extra_args);
        if (!PyTuple_Check(extra_args)) {
            PyObject *tmp = PyTuple_New(1);
            PyTuple_SetItem(tmp, 0, extra_args);
            extra_args = tmp;
        }
        pygi_closure->pyg_closure.extra_args = extra_args;
    }
    if (swap_data) {
        Py_INCREF(swap_data);
        pygi_closure->pyg_closure.swap_data = swap_data;
        closure->derivative_flag = TRUE;
    }

    return closure;
}
示例#6
0
文件: mainloop.c 项目: sjokkis/gjs
static JSBool
gjs_timeout_add(JSContext *context,
                   JSObject  *obj,
                   uintN      argc,
                   jsval     *argv,
                   jsval     *retval)
{
    GClosure *closure;
    JSObject *callback;
    guint32 interval;
    guint id;

    /* Best I can tell, there is no way to know if argv[1] is really
     * callable other than to just try it. Checking whether it's a
     * function will not detect native objects that provide
     * JSClass::call, for example.
     */
    if (!gjs_parse_args(context, "timeout_add", "uo", argc, argv,
                        "interval", &interval, "callback", &callback))
      return JS_FALSE;

    closure = gjs_closure_new(context, callback, "timeout");
    if (closure == NULL)
        return JS_FALSE;

    g_closure_ref(closure);
    g_closure_sink(closure);

    id = g_timeout_add_full(G_PRIORITY_DEFAULT,
                            interval,
                            closure_source_func,
                            closure,
                            closure_destroy_notify);

    /* this is needed to remove the timeout if the JSContext is
     * destroyed.
     */
    g_closure_add_invalidate_notifier(closure, GUINT_TO_POINTER(id),
                                      closure_invalidated);

    if (!JS_NewNumberValue(context, id, retval))
        return JS_FALSE;

    return JS_TRUE;
}
示例#7
0
文件: marshal.c 项目: ntd/lgi
/* This is workaround for missing glib function, which should look
   like this:

   void g_closure_set_marshal_with_data (GClosure        *closure,
					 GClosureMarshal  marshal,
					 gpointer         user_data,
					 GDestroyNotify   destroy_notify);

   Such method would be introspectable.
*/
static int
marshal_closure_set_marshal (lua_State *L)
{
  GClosure *closure;
  gpointer user_data;
  GClosureMarshal marshal;
  GIBaseInfo *ci;

  ci = g_irepository_find_by_name (NULL, "GObject", "ClosureMarshal");
  lgi_type_get_repotype (L, G_TYPE_CLOSURE, NULL);
  lgi_record_2c (L, 1, &closure, FALSE, FALSE, FALSE, FALSE);
  user_data = lgi_closure_allocate (L, 1);
  lgi_callable_create (L, ci, NULL);
  marshal = lgi_closure_create (L, user_data, 2, FALSE);
  g_closure_set_marshal (closure, marshal);
  g_closure_add_invalidate_notifier (closure, user_data, gclosure_destroy);
  return 0;
}
示例#8
0
/**
 * g_source_set_closure:
 * @source: the source
 * @closure: a #GClosure
 *
 * Set the callback for a source as a #GClosure.
 *
 * If the source is not one of the standard GLib types, the @closure_callback
 * and @closure_marshal fields of the #GSourceFuncs structure must have been
 * filled in with pointers to appropriate functions.
 */
void
g_source_set_closure (GSource  *source,
		      GClosure *closure)
{
  g_return_if_fail (source != NULL);
  g_return_if_fail (closure != NULL);

  if (!source->source_funcs->closure_callback &&
#ifdef G_OS_UNIX
      source->source_funcs != &g_unix_fd_source_funcs &&
      source->source_funcs != &g_unix_signal_funcs &&
#endif
      source->source_funcs != &g_child_watch_funcs &&
      source->source_funcs != &g_io_watch_funcs &&
      source->source_funcs != &g_timeout_funcs &&
      source->source_funcs != &g_idle_funcs)
    {
      g_critical (G_STRLOC ": closure cannot be set on GSource without GSourceFuncs::closure_callback\n");
      return;
    }

  g_closure_ref (closure);
  g_closure_sink (closure);
  g_source_set_callback_indirect (source, closure, &closure_callback_funcs);

  g_closure_add_invalidate_notifier (closure, source, closure_invalidated);

  if (G_CLOSURE_NEEDS_MARSHAL (closure))
    {
      GClosureMarshal marshal = (GClosureMarshal)source->source_funcs->closure_marshal;
      if (marshal)
	g_closure_set_marshal (closure, marshal);
      else if (source->source_funcs == &g_idle_funcs ||
#ifdef G_OS_UNIX
               source->source_funcs == &g_unix_signal_funcs ||
#endif
               source->source_funcs == &g_timeout_funcs)
	g_closure_set_marshal (closure, source_closure_marshal_BOOLEAN__VOID);
      else
        g_closure_set_marshal (closure, g_cclosure_marshal_generic);
    }
}
示例#9
0
文件: mainloop.c 项目: sjokkis/gjs
static JSBool
gjs_timeout_add_seconds(JSContext *context,
                           JSObject  *obj,
                           uintN      argc,
                           jsval     *argv,
                           jsval     *retval)
{
    GClosure *closure;
    JSObject *callback;
    guint32 interval;
    guint id;

    /* See comment for timeout_add above */
    if (!gjs_parse_args(context, "timeout_add_seconds", "uo", argc, argv,
                        "interval", &interval, "callback", &callback))
      return JS_FALSE;

    closure = gjs_closure_new(context, callback, "timeout_seconds");
    if (closure == NULL)
        return JS_FALSE;

    g_closure_ref(closure);
    g_closure_sink(closure);

    id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
                                    interval,
                                    closure_source_func,
                                    closure,
                                    closure_destroy_notify);

    /* this is needed to remove the timeout if the JSContext is
     * destroyed.
     */
    g_closure_add_invalidate_notifier(closure, GUINT_TO_POINTER(id),
                                      closure_invalidated);

    if (!JS_NewNumberValue(context, id, retval))
        return JS_FALSE;

    return JS_TRUE;
}
示例#10
0
GClosure*
g_rclosure_new(VALUE callback_proc, VALUE extra_args, GValToRValSignalFunc g2r_func)
{
    GRClosure* closure;

    closure = (GRClosure*)g_closure_new_simple(sizeof(GRClosure), NULL);

    closure->count      = 1;
    closure->g2r_func   = g2r_func;
    closure->objects    = NULL;
    closure->callback   = callback_proc;
    closure->extra_args = extra_args;
    closure->rb_holder  = Data_Wrap_Struct(rb_cData,
                                           gr_closure_holder_mark,
                                           gr_closure_holder_free,
                                           closure);
    closure->tag[0]     = '\0';

    g_closure_set_marshal((GClosure*)closure, &rclosure_marshal);
    g_closure_add_invalidate_notifier((GClosure*)closure, NULL,
                                      &rclosure_invalidate);

    return (GClosure*)closure;
}