static SeedValue seed_xml_parse_file (SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException * exception) { SeedObject ret; xmlDocPtr doc; gchar *path; if (argument_count != 1) { seed_make_exception (ctx, exception, "ArgumentError", "parseFile expected 1 argument, got %zd", argument_count); return seed_make_null (ctx); } path = seed_value_to_string (ctx, arguments[0], exception); doc = xmlParseFile (path); if (!doc) { seed_make_exception (ctx, exception, "XMLError", "Document not parsed successfully"); g_free (path); return seed_make_null (ctx); } ret = seed_make_xml_doc (ctx, doc); g_free (path); return ret; }
static gboolean seed_ffi_set_signature (SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException *exception) { seed_ffi_function_priv *priv = seed_object_get_private (this_object); if (priv->signature_obj) { seed_make_exception (ctx, exception, "FFIError", "Can not reset signature of function once set"); return FALSE; } else if (!seed_value_is_object (ctx, value)) { seed_make_exception (ctx, exception, "FFIError", "Signature must be an object"); return FALSE; } else { if (!seed_ffi_build_signature (ctx, priv, (SeedObject) value, exception)) return FALSE; } return TRUE; }
static JSValueRef seed_gobject_signal_connect_on_property (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef * exception) { gulong id = 0; JSObjectRef this_obj; signal_privates *privates; privates = (signal_privates *) JSObjectGetPrivate (thisObject); if (!privates) g_error ("Signal constructed with invalid parameters" "in namespace import \n"); this_obj = (JSObjectRef) seed_value_from_object (ctx, privates->object, exception); if ((argumentCount > 2) || (argumentCount == 0)) { seed_make_exception (ctx, exception, "ArgumentError", "Signal connection expected" " 1, or 2 arguments. Got " "%zd", argumentCount); return JSValueMakeNull (ctx); } if (JSValueIsNull (ctx, arguments[0]) || !JSValueIsObject (ctx, arguments[0]) || !JSObjectIsFunction (ctx, (JSObjectRef) arguments[0])) { seed_make_exception (ctx, exception, "ArgumentError", "Signal connection requires a function" " as first argument"); return JSValueMakeNull (ctx); } if (argumentCount == 1) { id = seed_gobject_signal_connect (ctx, privates->signal_name, privates->object, (JSObjectRef) arguments[0], this_obj, NULL); } else if (argumentCount == 2) { id = seed_gobject_signal_connect (ctx, privates->signal_name, privates->object, (JSObjectRef) arguments[0], this_obj, (JSObjectRef) arguments[1]); } return seed_value_from_ulong (ctx, id, exception); }
static JSValueRef seed_gobject_signal_connect_by_name (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef * exception) { GType obj_type; JSObjectRef user_data = NULL; gchar *signal_name; GObject *obj; gulong id; if (argumentCount < 2 || argumentCount > 3) { seed_make_exception (ctx, exception, "ArgumentError", "Signal connection expected" " 2 or 3 arguments. Got " "%zd", argumentCount); return JSValueMakeNull (ctx); } if (JSValueIsNull (ctx, arguments[1]) || !JSValueIsObject (ctx, arguments[1]) || !JSObjectIsFunction (ctx, (JSObjectRef) arguments[1])) { seed_make_exception (ctx, exception, "ArgumentError", "Signal connection by name " "requires a function" " as second argument"); return JSValueMakeNull (ctx); } if (argumentCount == 3) { user_data = (JSObjectRef) arguments[2]; } signal_name = seed_value_to_string (ctx, arguments[0], exception); obj = (GObject *) JSObjectGetPrivate (thisObject); obj_type = G_OBJECT_TYPE (obj); id = seed_gobject_signal_connect (ctx, signal_name, obj, (JSObjectRef) arguments[1], NULL, user_data); g_free (signal_name); return seed_value_from_ulong (ctx, id, exception); }
static SeedObject seed_ffi_construct_library (SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException *exception) { GModule *mod; SeedObject ret; gchar *filename; seed_ffi_library_priv *priv; if (argument_count != 1 && argument_count != 0) { seed_make_exception (ctx, exception, "ArgumentError", "ffi.Library constructor expects 1 argument (filename, or none to use NULL GModule), got %zd", argument_count); return seed_make_null (ctx); } if (argument_count == 1) filename = seed_value_to_string (ctx, arguments[0], exception); else filename = NULL; mod = g_module_open (filename, G_MODULE_BIND_LOCAL | G_MODULE_BIND_LAZY); if (!mod) { seed_make_exception (ctx, exception, "GModuleError", "Opening module (%s) failed with: %s", filename, g_module_error ()); g_free (filename); return seed_make_null (ctx); } priv = g_slice_alloc (sizeof (seed_ffi_library_priv)); priv->mod = mod; // TODO: Value destroy function. priv->symbols = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); ret = seed_make_object (ctx, ffi_library_class, priv); g_free (filename); return ret; }
static JSValueRef seed_gobject_signal_emit (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef * exception) { JSValueRef ret; GValue *params; GValue ret_value = { 0 }; GSignalQuery query; signal_privates *privates; guint i, signal_id; privates = JSObjectGetPrivate (thisObject); signal_id = g_signal_lookup (privates->signal_name, G_OBJECT_TYPE (privates->object)); g_signal_query (signal_id, &query); if (argumentCount != query.n_params) { seed_make_exception (ctx, exception, "ArgumentError", "Signal: %s for type %s expected %u " "arguments, got %zd", query.signal_name, g_type_name (query.itype), query.n_params, argumentCount); return JSValueMakeNull (ctx); } params = g_new0 (GValue, argumentCount + 1); g_value_init (¶ms[0], G_TYPE_OBJECT); g_value_set_object (¶ms[0], privates->object); for (i = 0; i < argumentCount; i++) seed_value_to_gvalue (ctx, arguments[i], query.param_types[i], ¶ms[i + 1], exception); if (query.return_type != G_TYPE_NONE) g_value_init (&ret_value, query.return_type); g_signal_emitv (params, signal_id, 0, &ret_value); for (i = 0; i < argumentCount; i++) g_value_unset (¶ms[i]); g_free (params); ret = seed_value_from_gvalue (ctx, &ret_value, exception); if (query.return_type != G_TYPE_NONE) g_value_unset (&ret_value); return ret; }
/** * seed_make_exception_from_gerror: * @ctx: A #SeedContext. * @exception: A reference to a #SeedException in which to store the exception. * @error: A #GError* from which to copy the properties of the exception. * * Generates @exception with the name and description of @error. * */ void seed_make_exception_from_gerror (JSContextRef ctx, JSValueRef * exception, GError * error) { const gchar *domain = g_quark_to_string (error->domain); GString *string = g_string_new (domain); guint i; gsize len = string->len; *(string->str) = g_unichar_toupper (*(string->str)); for (i = 0; i < len; i++) { if (*(string->str + i) == '-') { *(string->str + i + 1) = g_unichar_toupper (*(string->str + i + 1)); g_string_erase (string, i, 1); } else if (!g_strcmp0 (string->str + i - 1, "Quark")) g_string_truncate (string, i - 1); } seed_make_exception (ctx, exception, string->str, error->message, NULL); g_string_free (string, TRUE); }
static SeedValue seed_xml_xpath_register_ns (SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException * exception) { xmlXPathContextPtr xpath; guchar *prefix; guchar *ns_uri; if (argument_count != 2) { seed_make_exception (ctx, exception, "ArgumentError", "xpathRegisterNs expects 2 arguments, got %zd", argument_count); return seed_make_undefined (ctx); } xpath = XML_XPATH_PRIV (this_object); prefix = (guchar *)seed_value_to_string (ctx, arguments[0], exception); ns_uri = (guchar *)seed_value_to_string (ctx, arguments[1], exception); xmlXPathRegisterNs (xpath, prefix, ns_uri); g_free (prefix); g_free (ns_uri); return seed_make_undefined (ctx); }
static SeedValue seed_xml_xpath_eval (SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException * exception) { xmlXPathObjectPtr xpath_obj; xmlXPathContextPtr xpath_ctx; guchar *xpath; if (argument_count != 1) { seed_make_exception (ctx, exception, "ArgumentError", "xpathEval expected 1 argument, got %zd", argument_count); return seed_make_null (ctx); } xpath_ctx = XML_XPATH_PRIV (this_object); xpath = (guchar *)seed_value_to_string (ctx, arguments[0], exception); xpath_obj = xmlXPathEval (xpath, xpath_ctx); g_free (xpath); return seed_make_object (ctx, xml_xpathobj_class, xpath_obj); }
SeedObject sqlite_construct_database(SeedContext ctx, SeedObject constructor, size_t argument_count, const SeedValue arguments[], SeedException * exception) { SeedObject ret; gchar *file; sqlite3 *db; int rc; if (argument_count != 1) { seed_make_exception(ctx, exception, "ArgumentError", "sqlite.Database constructor expected 1 argument"); return (SeedObject) seed_make_null(ctx); } file = seed_value_to_string(ctx, arguments[0], exception); rc = sqlite3_open(file, &db); g_free(file); ret = seed_make_object(ctx, sqlite_class, db); seed_object_set_property(ctx, ret, "status", seed_value_from_int(ctx, rc, exception)); return ret; }
SeedValue seed_gtk_builder_connect_signals(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException *exception) { builder_ud ud; GtkBuilder *b; CHECK_ARG_COUNT("GtkBuilder.connect_signals", 1); if (!seed_value_is_object (ctx, arguments[0])) { seed_make_exception (ctx, exception, "TypeError", "connect_signals expects one object as the first argument"); return seed_make_undefined (ctx); } b = GTK_BUILDER (seed_value_to_object (ctx, this_object, exception)); ud.ctx = ctx; ud.obj = arguments[0]; if (argument_count == 2) ud.user_data = arguments[1]; else ud.user_data = NULL; gtk_builder_connect_signals_full(b, seed_builder_connect_func, &ud); return seed_make_undefined (ctx); }
static SeedValue seed_cairo_matrix_rotate (SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException *exception) { gdouble angle; cairo_matrix_t m; if (argument_count != 2) { EXPECTED_EXCEPTION("rotate", "2 arguments"); } if (!seed_value_to_cairo_matrix (ctx, arguments[0], &m, exception)) { seed_make_exception (ctx, exception, "ArgumentError", "rotate needs an array [xx, yx, xy, yy, x0, y0]"); } angle = seed_value_to_double (ctx, arguments[1], exception); cairo_matrix_rotate (&m, angle); return seed_value_from_cairo_matrix (ctx, &m, exception); }
static gboolean seed_cairo_surface_set_fallback_resolution(SeedContext ctx, SeedObject this_object, SeedString property_name, SeedValue value, SeedException *exception) { cairo_surface_t *surf; gdouble x, y; SeedValue jsx, jsy; CHECK_THIS_BOOL(); if (!seed_value_is_object (ctx, value)) { seed_make_exception(ctx, exception, "ArgumentError", "Cairo.Surface.fallback_resolution must be an array [x,y]"); return FALSE; } jsx = seed_object_get_property_at_index (ctx, (SeedObject) value, 0, exception); jsy = seed_object_get_property_at_index (ctx, (SeedObject) value, 1, exception); surf = seed_object_to_cairo_surface (ctx, this_object, exception); x = seed_value_to_double (ctx, jsx, exception); y = seed_value_to_double (ctx, jsy, exception); cairo_surface_set_fallback_resolution (surf, x, y); return TRUE; }
static SeedValue seed_cairo_matrix_transform_point (SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException *exception) { SeedValue ret[2]; gdouble x, y; cairo_matrix_t m; if (argument_count != 3) { EXPECTED_EXCEPTION("transform_point", "3 arguments"); } if (!seed_value_to_cairo_matrix (ctx, arguments[0], &m, exception)) { seed_make_exception (ctx, exception, "ArgumentError", "transform_point needs an array [xx, yx, xy, yy, x0, y0]"); } x = seed_value_to_double (ctx, arguments[1], exception); y = seed_value_to_double (ctx, arguments[2], exception); cairo_matrix_transform_point (&m, &x, &y); ret[0] = seed_value_from_double (ctx, x, exception); ret[1] = seed_value_from_double (ctx, y, exception); return seed_make_array (ctx, ret, 2, exception); }
cairo_pattern_t * seed_object_to_cairo_pattern (SeedContext ctx, SeedObject obj, SeedException *exception) { if (seed_object_is_of_class (ctx, obj, seed_cairo_pattern_class)) return CAIRO_PATTERN_PRIV (obj); seed_make_exception (ctx, exception, "ArgumentError", "Object is not a Cairo Pattern"); return NULL; }
cairo_surface_t * seed_object_to_cairo_surface (SeedContext ctx, SeedObject obj, SeedException *exception) { if (seed_object_is_of_class (ctx, obj, seed_cairo_surface_class)) return CAIRO_SURFACE_PRIV (obj); seed_make_exception (ctx, exception, "ArgumentError", "Object is not a Cairo Surface"); return NULL; }
SeedValue seed_sqlite_exec(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argument_count, const SeedValue arguments[], SeedException * exception) { gchar *statement; gchar *sqlite_error = 0; sqlite3 *db; int rc; if (argument_count < 1) { seed_make_exception(ctx, exception, "ArgumentError", "sqlite.Database.exec expected 1 or 2 arguments"); return seed_make_null(ctx); } statement = seed_value_to_string(ctx, arguments[0], exception); db = seed_object_get_private(this_object); g_assert(db); rc = sqlite3_exec(db, statement, seed_sqlite_exec_callback, argument_count == 2 ? arguments[1] : 0, &sqlite_error); g_free(statement); if (rc != SQLITE_OK) { if (sqlite_error) { seed_make_exception(ctx, exception, "SqliteError", sqlite_error, NULL); sqlite3_free(sqlite_error); } return seed_make_null(ctx); } return seed_value_from_int(ctx, rc, exception); }
SeedValue ghtml_webview_js_window_show (SeedContext ctx, SeedObject function, SeedObject thisObject, size_t argumentCount, SeedValue arguments[], SeedException * exception) { if (argumentCount) { seed_make_exception (ctx, exception, GHTML_JS_INVALID_PARAMS, "window.show expected 0 arguments, got %zd", argumentCount ); return seed_make_null (ctx); } gtk_widget_show_all(ghtml_window); return seed_make_null (ctx); }
static SeedValue gjs_hook_up_vfunc(SeedContext ctx, SeedObject function, SeedObject this_object, size_t argumentCount, const SeedValue arguments[], SeedException* exception) { // TODO: to be implemented. seed_make_exception(ctx, exception, "ImplementationError", "Not implemented yet"); return seed_make_undefined(ctx); }
SeedValue ghtml_webview_js_chdir (SeedContext ctx, SeedObject function, SeedObject thisObject, size_t argumentCount, SeedValue arguments[], SeedException * exception) { if (argumentCount != 1) { seed_make_exception (ctx, exception, GHTML_JS_INVALID_PARAMS, "chdir expected 1 argument, got %zd", argumentCount ); return seed_make_null (ctx); } gchar * val = seed_value_to_string(ctx, arguments[0], exception); SeedValue result = (SeedValue) JSValueMakeNumber(ctx, g_chdir(val)); g_free(val); return result; }
SeedValue ghtml_webview_js_console_print (SeedContext ctx, SeedObject function, SeedObject thisObject, size_t argumentCount, SeedValue arguments[], SeedException * exception) { if (argumentCount != 1){ seed_make_exception (ctx, exception, GHTML_JS_INVALID_PARAMS, "print expected 1 argument, got %zd", argumentCount ); return seed_make_null (ctx); } gchar * buf = seed_value_to_string (ctx, arguments[0], exception); g_print ("%s\n", buf); g_free (buf); return seed_make_undefined (ctx); }
SeedValue ghtml_webview_js_quit (SeedContext ctx, SeedObject function, SeedObject thisObject, gsize argumentCount, const SeedValue arguments[], SeedException * exception) { if (argumentCount == 1) { ghtml_die(seed_value_to_int(ctx, arguments[0], exception)); return NULL; } else if (argumentCount > 1) { seed_make_exception( ctx, exception, GHTML_JS_INVALID_PARAMS, "quit expected 1 argument, got %zd", argumentCount ); return NULL; } ghtml_die(EXIT_SUCCESS); }
static SeedValue seed_ffi_function_call (SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException *exception) { GArgument rvalue; GArgument *gargs; ffi_type *rtype; ffi_type **atypes; gpointer *args; int i; ffi_cif cif; seed_ffi_function_priv *priv = seed_object_get_private (function); if (argument_count != priv->n_args) { seed_make_exception (ctx, exception, "ArgumentError", "%s expected %d arguments got %zd", priv->name, priv->n_args, argument_count); return seed_make_null (ctx); } atypes = g_alloca (sizeof (ffi_type *) * (argument_count)); args = g_alloca (sizeof (gpointer) * (argument_count)); gargs = g_alloca (sizeof (GArgument) * (argument_count)); for (i = 0; i < argument_count; i++) { atypes[i] = gtype_to_ffi_type (ctx, arguments[i], priv->args[i], &(gargs[i]), &args[i],exception); } rtype = return_type_to_ffi_type (priv->ret_val); if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, argument_count, rtype, atypes) != FFI_OK) g_assert_not_reached(); ffi_call (&cif, priv->symbol, &rvalue, args); return value_from_ffi_type (ctx, priv->ret_val, &rvalue, exception); }
static JSValueRef seed_signal_holder_get_property (JSContextRef ctx, JSObjectRef object, JSStringRef property_name, JSValueRef * exception) { GObject *gobj = JSObjectGetPrivate (object); signal_privates *priv; guint length = JSStringGetMaximumUTF8CStringSize (property_name); gchar *signal_name = g_malloc (length * sizeof (gchar)); JSObjectRef signal_ref; JSStringGetUTF8CString (property_name, signal_name, length); if (! (g_strcmp0 (signal_name, "connect") && g_strcmp0 (signal_name, "disconnect"))) { g_free (signal_name); return NULL; } if (!g_str_has_prefix (signal_name, "notify::") && !g_signal_lookup (signal_name, G_OBJECT_TYPE (gobj))) { seed_make_exception (ctx, exception, "InvalidSignalName", "Failed to connect to %s. " "Invalid signal name.", signal_name); g_free (signal_name); return NULL; } priv = g_slice_alloc (sizeof (signal_privates)); priv->object = gobj; priv->signal_name = signal_name; signal_ref = JSObjectMake (ctx, gobject_signal_class, priv); return signal_ref; }
static JSValueRef seed_gobject_signal_disconnect (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef * exception) { gulong id; if (argumentCount != 1) { seed_make_exception (ctx, exception, "ArgumentError", "Signal disconnection expects 1 argument" " got %zd", argumentCount); return JSValueMakeUndefined (ctx); } id = seed_value_to_ulong (ctx, arguments[0], exception); g_signal_handler_disconnect (JSObjectGetPrivate (thisObject), id); return JSValueMakeUndefined (ctx); }
static gboolean seed_ffi_build_signature (SeedContext ctx, seed_ffi_function_priv *priv, SeedObject sig, SeedException *exception) { SeedObject arguments; SeedValue ret_type_ref, length_ref; guint length, i; arguments = seed_object_get_property (ctx, sig, "arguments"); ret_type_ref = seed_object_get_property (ctx, sig, "returns"); if (!seed_value_is_object (ctx, arguments)) { seed_make_exception (ctx, exception, "FFIError", "Signature arguments member must be an array describing argument types"); return FALSE; } length_ref = seed_object_get_property (ctx, arguments, "length"); length = seed_value_to_uint (ctx, length_ref, exception); priv->n_args = length; priv->args = g_slice_alloc (length * sizeof (GType)); for (i = 0; i < length; i++) { SeedValue type = seed_object_get_property_at_index (ctx, arguments, i, exception); priv->args[i] = seed_value_to_int (ctx, type, exception); } priv->ret_val = seed_value_to_int (ctx, ret_type_ref, exception); priv->signature_obj = sig; seed_value_protect (ctx, sig); return TRUE; }
static SeedValue async_call_callback(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException *exception) { DBusConnection *connection; DBusBusType which_bus; DBusMessage *reply; const char *sender; dbus_uint32_t serial; SeedValue prop_value, retval; const char *signature; gboolean thrown; retval = seed_make_undefined (ctx); reply = NULL; thrown = FALSE; prop_value = seed_object_get_property (ctx, function, "_dbusSender"); sender = seed_value_to_string (ctx, prop_value, exception); if (!sender) return FALSE; prop_value = seed_object_get_property(ctx, function, "_dbusSerial"); serial = seed_value_to_uint (ctx, prop_value, exception); prop_value = seed_object_get_property(ctx, function, "_dbusBusType"); which_bus = seed_value_to_int(ctx, prop_value, exception); /* From now we have enough information to * send the exception back to the callee so we'll do so */ prop_value = seed_object_get_property(ctx, function, "_dbusOutSignature"); signature = seed_value_to_string (ctx, prop_value, exception); if (!signature) return FALSE; if (argument_count != 1) { seed_make_exception(ctx, exception, "ArgumentError", "The callback to async DBus calls takes one argument, " "the return value or array of return values"); thrown = TRUE; goto out; } reply = build_reply_from_jsval(ctx, signature, sender, serial, arguments[0], exception); out: if (!reply && thrown) { if (!dbus_reply_from_exception_and_sender(ctx, sender, serial, &reply, exception)) g_warning("dbus method invocation failed but no exception was set?"); } if (reply) { big_dbus_add_bus_weakref(which_bus, &connection); if (!connection) { seed_make_exception(ctx, exception, "DBusError", "We were disconnected from the bus before the callback " "to some async remote call was called"); dbus_message_unref(reply); big_dbus_remove_bus_weakref(which_bus, &connection); return FALSE; } dbus_connection_send(connection, reply, NULL); big_dbus_remove_bus_weakref(which_bus, &connection); dbus_message_unref(reply); } return retval; }