[seed] Adding GjsPrivate module to Seed
- From: Danilo Cesar Lemes de Paula <danilocesar src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seed] Adding GjsPrivate module to Seed
- Date: Fri, 3 Jun 2016 14:07:20 +0000 (UTC)
commit b8bd0859870d00a29ea33775e5cf7f73f1f4b8e8
Author: Danilo Cesar Lemes de Paula <danilo cesar collabora co uk>
Date: Thu Mar 3 15:34:05 2016 -0300
Adding GjsPrivate module to Seed
This GjsPrivate module will be accessed via GI for modules
inside the gjs extension in Seed.
Makefile.am | 2 +
configure.ac | 3 +
extensions/Seed.js.in | 6 +
libgjs-private/Makefile.am | 54 ++++++
libgjs-private/gjs-gdbus-wrapper.c | 336 ++++++++++++++++++++++++++++++++++++
libgjs-private/gjs-gdbus-wrapper.h | 74 ++++++++
libgjs-private/gjs-gtk-util.c | 63 +++++++
libgjs-private/gjs-gtk-util.h | 37 ++++
libgjs-private/gjs-util.c | 110 ++++++++++++
libgjs-private/gjs-util.h | 58 ++++++
10 files changed, 743 insertions(+), 0 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index c7be24b..15c4472 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,9 +1,11 @@
## Process this file with automake to produce Makefile.in
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
+DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
SUBDIRS = po \
libseed \
+ libgjs-private \
src \
extensions \
modules \
diff --git a/configure.ac b/configure.ac
index a82027d..bfa7351 100644
--- a/configure.ac
+++ b/configure.ac
@@ -112,6 +112,7 @@ AC_SUBST(WEBKIT_LDFLAGS)
AC_SUBST(SEED_GTK_VERSION)
dnl =========================Introspection=====================================
+GOBJECT_INTROSPECTION_CHECK([1.41.4])
PKG_CHECK_MODULES(GOBJECT_INTROSPECTION, gobject-introspection-1.0 >= 0.6.3)
AC_SUBST(GOBJECT_INTROSPECTION_CFLAGS)
@@ -485,6 +486,8 @@ doc/modules/sandbox/Makefile
doc/mapping/mapping.html
libseed/Makefile
+libgjs-private/Makefile
+
po/Makefile.in
src/Makefile
extensions/Makefile
diff --git a/extensions/Seed.js.in b/extensions/Seed.js.in
index b5b7c6c..3d576d0 100644
--- a/extensions/Seed.js.in
+++ b/extensions/Seed.js.in
@@ -35,6 +35,12 @@ if(!imports.searchPath || (imports.searchPath.length == 0))
imports.searchPath.unshift(".");
}
+// TODO: This will work, but won't work if not installed
+// that's a bit OK at the moment, as Seed doesn't work properly uninstalled anyway.
+// But it should be fixed soon!
+const GIRepository = imports.gi.GIRepository;
+GIRepository.Repository.prepend_search_path("%pkglibdir%/girepository-1.0/");
+
Seed.sprintf = function ()
{
if (typeof arguments == "undefined") { return null; }
diff --git a/libgjs-private/Makefile.am b/libgjs-private/Makefile.am
new file mode 100644
index 0000000..9d8bcc2
--- /dev/null
+++ b/libgjs-private/Makefile.am
@@ -0,0 +1,54 @@
+-include $(INTROSPECTION_MAKEFILE)
+INTROSPECTION_GIRS =
+
+lib_LTLIBRARIES = \
+ libseed_gjsprivate.la
+
+libgjs_private_source_files = \
+ gjs-gdbus-wrapper.c \
+ gjs-gdbus-wrapper.h \
+ gjs-util.c \
+ gjs-util.h \
+ gjs-gtk-util.h \
+ gjs-gtk-util.c \
+ $(NULL)
+
+libseed_gjsprivate_la_SOURCES = $(libgjs_private_source_files)
+
+AM_CPPFLAGS = \
+ -I top_srcdir@/libseed/ \
+ $(GOBJECT_INTROSPECTION_CFLAGS) \
+ $(SEED_DEBUG_CFLAGS) \
+ $(GTK_CFLAGS) \
+ $(SEED_PROFILE_CFLAGS)
+
+libseed_gjsprivate_la_LDFLAGS = \
+ -module -avoid-version \
+ $(GOBJECT_INTROSPECTION_LDFLAGS)
+
+libseed_gjsprivate_la_LIBADD = \
+ $(top_builddir)/libseed/libseed SEED_GTK_VERSION@.la \
+ $(GTK_LIBS) \
+ $(SEED_PROFILE_LIBS)
+
+INTROSPECTION_SCANNER_ARGS = \
+ --add-include-path= top_srcdir@ --add-include-path=$(GTK_CFLAGS) --warn-all
+INTROSPECTION_COMPILER_ARGS = \
+ --includedir= top_srcdir@
+
+GjsPrivate-1.0.gir: libseed_gjsprivate.la
+GjsPrivate_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0
+GjsPrivate_1_0_gir_CFLAGS = $(INCLUDES)
+GjsPrivate_1_0_gir_LIBS = libseed_gjsprivate.la
+GjsPrivate_1_0_gir_FILES = $(libgjs_private_source_files)
+INTROSPECTION_GIRS += GjsPrivate-1.0.gir
+
+GjsPrivate_1_0_gir_SCANNERFLAGS = --identifier-prefix=Gjs --symbol-prefix=gjs_ --warn-all
+girdir = $(datadir)/gir-1.0
+gir_DATA = $(INTROSPECTION_GIRS)
+
+typelibdir = $(pkglibdir)@SEED_GTK_VERSION@/girepository-1.0
+typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+
+CLEANFILES = $(gir_DATA) $(typelib_DATA)
+
diff --git a/libgjs-private/gjs-gdbus-wrapper.c b/libgjs-private/gjs-gdbus-wrapper.c
new file mode 100644
index 0000000..f01d629
--- /dev/null
+++ b/libgjs-private/gjs-gdbus-wrapper.c
@@ -0,0 +1,336 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* Copyright 2011 Giovanni Campagna. All Rights Reserved. */
+
+#include <config.h>
+#include <string.h>
+
+#include "gjs-gdbus-wrapper.h"
+
+enum
+{
+ PROP_0,
+ PROP_G_INTERFACE_INFO,
+ PROP_LAST
+};
+
+enum
+{
+ SIGNAL_HANDLE_METHOD,
+ SIGNAL_HANDLE_PROPERTY_GET,
+ SIGNAL_HANDLE_PROPERTY_SET,
+ SIGNAL_LAST,
+};
+
+static guint signals[SIGNAL_LAST];
+
+struct _GjsDBusImplementationPrivate
+{
+ GDBusInterfaceVTable vtable;
+ GDBusInterfaceInfo* ifaceinfo;
+
+ // from gchar* to GVariant*
+ GHashTable* outstanding_properties;
+ guint idle_id;
+};
+
+G_DEFINE_TYPE(GjsDBusImplementation,
+ gjs_dbus_implementation,
+ G_TYPE_DBUS_INTERFACE_SKELETON)
+
+static void
+gjs_dbus_implementation_method_call(GDBusConnection* connection,
+ const char* sender,
+ const char* object_path,
+ const char* interface_name,
+ const char* method_name,
+ GVariant* parameters,
+ GDBusMethodInvocation* invocation,
+ gpointer user_data)
+{
+ GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(user_data);
+
+ g_signal_emit(self, signals[SIGNAL_HANDLE_METHOD], 0, method_name,
+ parameters, invocation);
+ g_object_unref(invocation);
+}
+
+static GVariant*
+gjs_dbus_implementation_property_get(GDBusConnection* connection,
+ const char* sender,
+ const char* object_path,
+ const char* interface_name,
+ const char* property_name,
+ GError** error,
+ gpointer user_data)
+{
+ GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(user_data);
+ GVariant* value;
+
+ g_signal_emit(self, signals[SIGNAL_HANDLE_PROPERTY_GET], 0, property_name,
+ &value);
+
+ /* Marshaling GErrors is not supported, so this is the best we can do
+ (GIO will assert if value is NULL and error is not set) */
+ if (!value)
+ g_set_error(error, g_quark_from_static_string("gjs-error-domain"), 0,
+ "Property retrieval failed");
+
+ return value;
+}
+
+static gboolean
+gjs_dbus_implementation_property_set(GDBusConnection* connection,
+ const char* sender,
+ const char* object_path,
+ const char* interface_name,
+ const char* property_name,
+ GVariant* value,
+ GError** error,
+ gpointer user_data)
+{
+ GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(user_data);
+
+ g_signal_emit(self, signals[SIGNAL_HANDLE_PROPERTY_SET], 0, property_name,
+ value);
+
+ return TRUE;
+}
+
+static void
+gjs_dbus_implementation_init(GjsDBusImplementation* self)
+{
+ GjsDBusImplementationPrivate* priv
+ = G_TYPE_INSTANCE_GET_PRIVATE(self, GJS_TYPE_DBUS_IMPLEMENTATION,
+ GjsDBusImplementationPrivate);
+
+ self->priv = priv;
+
+ priv->vtable.method_call = gjs_dbus_implementation_method_call;
+ priv->vtable.get_property = gjs_dbus_implementation_property_get;
+ priv->vtable.set_property = gjs_dbus_implementation_property_set;
+
+ priv->outstanding_properties
+ = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify) g_variant_unref);
+}
+
+static void
+gjs_dbus_implementation_finalize(GObject* object)
+{
+ GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(object);
+
+ g_dbus_interface_info_unref(self->priv->ifaceinfo);
+ g_hash_table_unref(self->priv->outstanding_properties);
+
+ G_OBJECT_CLASS(gjs_dbus_implementation_parent_class)->finalize(object);
+}
+
+static void
+gjs_dbus_implementation_set_property(GObject* object,
+ guint property_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(object);
+
+ switch (property_id) {
+ case PROP_G_INTERFACE_INFO:
+ self->priv->ifaceinfo
+ = (GDBusInterfaceInfo*) g_value_dup_boxed(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ }
+}
+
+static GDBusInterfaceInfo*
+gjs_dbus_implementation_get_info(GDBusInterfaceSkeleton* skeleton)
+{
+ GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(skeleton);
+
+ return self->priv->ifaceinfo;
+}
+
+static GDBusInterfaceVTable*
+gjs_dbus_implementation_get_vtable(GDBusInterfaceSkeleton* skeleton)
+{
+ GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(skeleton);
+
+ return &(self->priv->vtable);
+}
+
+static GVariant*
+gjs_dbus_implementation_get_properties(GDBusInterfaceSkeleton* skeleton)
+{
+ GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(skeleton);
+
+ GDBusInterfaceInfo* info = self->priv->ifaceinfo;
+ GDBusPropertyInfo** props;
+ GVariantBuilder builder;
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
+
+ for (props = info->properties; *props; ++props) {
+ GDBusPropertyInfo* prop = *props;
+ GVariant* value;
+
+ /* If we have a cached value, we use that instead of querying again */
+ if ((value = (GVariant*) g_hash_table_lookup(
+ self->priv->outstanding_properties, prop->name))) {
+ g_variant_builder_add(&builder, "{sv}", prop->name, value);
+ continue;
+ }
+
+ g_signal_emit(self, signals[SIGNAL_HANDLE_PROPERTY_GET], 0, prop->name,
+ &value);
+ g_variant_builder_add(&builder, "{sv}", prop->name, value);
+ }
+
+ return g_variant_builder_end(&builder);
+}
+
+static void
+gjs_dbus_implementation_flush(GDBusInterfaceSkeleton* skeleton)
+{
+ GjsDBusImplementation* self = GJS_DBUS_IMPLEMENTATION(skeleton);
+
+ GVariantBuilder changed_props;
+ GVariantBuilder invalidated_props;
+ GHashTableIter iter;
+ GVariant* val;
+ gchar* prop_name;
+
+ g_variant_builder_init(&changed_props, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_init(&invalidated_props, G_VARIANT_TYPE_STRING_ARRAY);
+
+ g_hash_table_iter_init(&iter, self->priv->outstanding_properties);
+ while (g_hash_table_iter_next(&iter, (void**) &prop_name, (void**) &val)) {
+ if (val)
+ g_variant_builder_add(&changed_props, "{sv}", prop_name, val);
+ else
+ g_variant_builder_add(&invalidated_props, "s", prop_name);
+ }
+
+ g_dbus_connection_emit_signal(
+ g_dbus_interface_skeleton_get_connection(skeleton), NULL, /* bus name */
+ g_dbus_interface_skeleton_get_object_path(skeleton),
+ "org.freedesktop.DBus.Properties", "PropertiesChanged",
+ g_variant_new("(s a{sv}@as)", self->priv->ifaceinfo->name,
+ g_variant_builder_end(&changed_props),
+ g_variant_builder_end(&invalidated_props)),
+ NULL /* error */);
+
+ g_hash_table_remove_all(self->priv->outstanding_properties);
+ if (self->priv->idle_id) {
+ g_source_remove(self->priv->idle_id);
+ self->priv->idle_id = 0;
+ }
+}
+
+void
+gjs_dbus_implementation_class_init(GjsDBusImplementationClass* klass)
+{
+ GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
+ GDBusInterfaceSkeletonClass* skeleton_class
+ = G_DBUS_INTERFACE_SKELETON_CLASS(klass);
+
+ g_type_class_add_private(klass, sizeof(GjsDBusImplementationPrivate));
+
+ gobject_class->finalize = gjs_dbus_implementation_finalize;
+ gobject_class->set_property = gjs_dbus_implementation_set_property;
+
+ skeleton_class->get_info = gjs_dbus_implementation_get_info;
+ skeleton_class->get_vtable = gjs_dbus_implementation_get_vtable;
+ skeleton_class->get_properties = gjs_dbus_implementation_get_properties;
+ skeleton_class->flush = gjs_dbus_implementation_flush;
+
+ g_object_class_install_property(
+ gobject_class, PROP_G_INTERFACE_INFO,
+ g_param_spec_boxed("g-interface-info", "Interface Info",
+ "A DBusInterfaceInfo representing the exported object",
+ G_TYPE_DBUS_INTERFACE_INFO,
+ (GParamFlags)(G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE
+ | G_PARAM_CONSTRUCT_ONLY)));
+
+ signals[SIGNAL_HANDLE_METHOD]
+ = g_signal_new("handle-method-call", G_TYPE_FROM_CLASS(klass),
+ (GSignalFlags) 0, /* flags */
+ 0, /* closure */
+ NULL, /* accumulator */
+ NULL, /* accumulator data */
+ NULL, /* C marshal */
+ G_TYPE_NONE, 3, G_TYPE_STRING, /* method name */
+ G_TYPE_VARIANT, /* parameters */
+ G_TYPE_DBUS_METHOD_INVOCATION);
+
+ signals[SIGNAL_HANDLE_PROPERTY_GET]
+ = g_signal_new("handle-property-get", G_TYPE_FROM_CLASS(klass),
+ (GSignalFlags) 0, /* flags */
+ 0, /* closure */
+ g_signal_accumulator_first_wins,
+ NULL, /* accumulator data */
+ NULL, /* C marshal */
+ G_TYPE_VARIANT, 1, G_TYPE_STRING /* property name */);
+
+ signals[SIGNAL_HANDLE_PROPERTY_SET]
+ = g_signal_new("handle-property-set", G_TYPE_FROM_CLASS(klass),
+ (GSignalFlags) 0, /* flags */
+ 0, /* closure */
+ NULL, /* accumulator */
+ NULL, /* accumulator data */
+ NULL, /* C marshal */
+ G_TYPE_NONE, 2, G_TYPE_STRING, /* property name */
+ G_TYPE_VARIANT /* parameters */);
+}
+
+static gboolean
+idle_cb(gpointer data)
+{
+ GDBusInterfaceSkeleton* skeleton = G_DBUS_INTERFACE_SKELETON(data);
+
+ g_dbus_interface_skeleton_flush(skeleton);
+ return FALSE;
+}
+
+/**
+ * gjs_dbus_implementation_emit_property_changed:
+ * @self: a #GjsDBusImplementation
+ * @property: the name of the property that changed
+ * @newvalue: (allow-none): the new value, or %NULL to just invalidate it
+ *
+ * Queue a PropertyChanged signal for emission, or update the one queued
+ * adding @property
+ */
+void
+gjs_dbus_implementation_emit_property_changed(GjsDBusImplementation* self,
+ gchar* property,
+ GVariant* newvalue)
+{
+ g_hash_table_replace(self->priv->outstanding_properties, g_strdup(property),
+ g_variant_ref(newvalue));
+
+ if (!self->priv->idle_id)
+ self->priv->idle_id = g_idle_add(idle_cb, self);
+}
+
+/**
+ * gjs_dbus_implementation_emit_signal:
+ * @self: a #GjsDBusImplementation
+ * @signal_name: the name of the signal
+ * @parameters: (allow-none): signal parameters, or %NULL for none
+ *
+ * Emits a signal named @signal_name from the object and interface represented
+ * by @self. This signal has no destination.
+ */
+void
+gjs_dbus_implementation_emit_signal(GjsDBusImplementation* self,
+ gchar* signal_name,
+ GVariant* parameters)
+{
+ GDBusInterfaceSkeleton* skeleton = G_DBUS_INTERFACE_SKELETON(self);
+
+ g_dbus_connection_emit_signal(
+ g_dbus_interface_skeleton_get_connection(skeleton), NULL,
+ g_dbus_interface_skeleton_get_object_path(skeleton),
+ self->priv->ifaceinfo->name, signal_name, parameters, NULL);
+}
diff --git a/libgjs-private/gjs-gdbus-wrapper.h b/libgjs-private/gjs-gdbus-wrapper.h
new file mode 100644
index 0000000..3d55b09
--- /dev/null
+++ b/libgjs-private/gjs-gdbus-wrapper.h
@@ -0,0 +1,74 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* Copyright 2011 Giovanni Campagna
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __GJS_UTIL_DBUS_H__
+#define __GJS_UTIL_DBUS_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GjsDBusImplementation GjsDBusImplementation;
+typedef struct _GjsDBusImplementationClass GjsDBusImplementationClass;
+typedef struct _GjsDBusImplementationPrivate GjsDBusImplementationPrivate;
+
+#define GJS_TYPE_DBUS_IMPLEMENTATION (gjs_dbus_implementation_get_type())
+#define GJS_DBUS_IMPLEMENTATION(object) \
+ (G_TYPE_CHECK_INSTANCE_CAST((object), GJS_TYPE_DBUS_IMPLEMENTATION, \
+ GjsDBusImplementation))
+#define GJS_DBUS_IMPLEMENTATION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), GJS_TYPE_DBUS_IMPLEMENTATION, \
+ GjsDBusImplementationClass))
+#define GJS_IS_DBUS_IMPLEMENTATION(object) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((object), GJS_TYPE_DBUS_IMPLEMENTATION))
+#define GJS_IS_DBUS_IMPLEMENTATION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), GJS_TYPE_DBUS_IMPLEMENTATION))
+#define GJS_DBUS_IMPLEMENTATION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), GJS_TYPE_DBUS_IMPLEMENTATION, \
+ GjsDBusImplementationClass))
+
+struct _GjsDBusImplementation
+{
+ GDBusInterfaceSkeleton parent;
+
+ GjsDBusImplementationPrivate* priv;
+};
+
+struct _GjsDBusImplementationClass
+{
+ GDBusInterfaceSkeletonClass parent_class;
+};
+
+GType gjs_dbus_implementation_get_type(void);
+
+void gjs_dbus_implementation_emit_property_changed(GjsDBusImplementation* self,
+ gchar* property,
+ GVariant* newvalue);
+void gjs_dbus_implementation_emit_signal(GjsDBusImplementation* self,
+ gchar* signal_name,
+ GVariant* parameters);
+
+G_END_DECLS
+
+#endif /* __GJS_UTIL_DBUS_H__ */
diff --git a/libgjs-private/gjs-gtk-util.c b/libgjs-private/gjs-gtk-util.c
new file mode 100644
index 0000000..4a6cebf
--- /dev/null
+++ b/libgjs-private/gjs-gtk-util.c
@@ -0,0 +1,63 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* Copyright 2014 Endless Mobile, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+
+#include "gjs-gtk-util.h"
+
+void
+gjs_gtk_container_child_set_property(GtkContainer* container,
+ GtkWidget* child,
+ const gchar* property,
+ const GValue* value)
+{
+ GParamSpec* pspec;
+
+ pspec
+ = gtk_container_class_find_child_property(G_OBJECT_GET_CLASS(container),
+ property);
+ if (pspec == NULL) {
+ g_warning("%s does not have a property called %s",
+ g_type_name(G_OBJECT_TYPE(container)), property);
+ return;
+ }
+
+ if ((G_VALUE_TYPE(value) == G_TYPE_POINTER)
+ && (g_value_get_pointer(value) == NULL)
+ && !g_value_type_transformable(G_VALUE_TYPE(value),
+ pspec->value_type)) {
+ /* Set an empty value. This will happen when we set a NULL value from
+ * JS.
+ * Since GJS doesn't know the GParamSpec for this property, it
+ * will just put NULL into a G_TYPE_POINTER GValue, which will later
+ * fail when trying to transform it to the GParamSpec's GType.
+ */
+ GValue null_value = G_VALUE_INIT;
+ g_value_init(&null_value, pspec->value_type);
+ gtk_container_child_set_property(container, child, property,
+ &null_value);
+ g_value_unset(&null_value);
+ } else {
+ gtk_container_child_set_property(container, child, property, value);
+ }
+}
diff --git a/libgjs-private/gjs-gtk-util.h b/libgjs-private/gjs-gtk-util.h
new file mode 100644
index 0000000..0f048aa
--- /dev/null
+++ b/libgjs-private/gjs-gtk-util.h
@@ -0,0 +1,37 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* Copyright 2014 Endless Mobile, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __GJS_PRIVATE_GTK_UTIL_H__
+#define __GJS_PRIVATE_GTK_UTIL_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+void gjs_gtk_container_child_set_property(GtkContainer* container,
+ GtkWidget* child,
+ const gchar* property,
+ const GValue* value);
+
+G_END_DECLS
+
+#endif /* __GJS_PRIVATE_GTK_UTIL_H__ */
diff --git a/libgjs-private/gjs-util.c b/libgjs-private/gjs-util.c
new file mode 100644
index 0000000..9bda1c9
--- /dev/null
+++ b/libgjs-private/gjs-util.c
@@ -0,0 +1,110 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* Copyright 2012 Giovanni Campagna <scampa giovanni gmail com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <config.h>
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include "gjs-util.h"
+
+char*
+gjs_format_int_alternative_output(int n)
+{
+ return g_strdup_printf("%Id", n);
+}
+
+GType
+gjs_locale_category_get_type(void)
+{
+ static volatile size_t g_define_type_id__volatile = 0;
+ if (g_once_init_enter(&g_define_type_id__volatile)) {
+ static const GEnumValue v[]
+ = { { GJS_LOCALE_CATEGORY_ALL, "GJS_LOCALE_CATEGORY_ALL", "all" },
+ { GJS_LOCALE_CATEGORY_COLLATE, "GJS_LOCALE_CATEGORY_COLLATE",
+ "collate" },
+ { GJS_LOCALE_CATEGORY_CTYPE, "GJS_LOCALE_CATEGORY_CTYPE",
+ "ctype" },
+ { GJS_LOCALE_CATEGORY_MESSAGES, "GJS_LOCALE_CATEGORY_MESSAGES",
+ "messages" },
+ { GJS_LOCALE_CATEGORY_MONETARY, "GJS_LOCALE_CATEGORY_MONETARY",
+ "monetary" },
+ { GJS_LOCALE_CATEGORY_NUMERIC, "GJS_LOCALE_CATEGORY_NUMERIC",
+ "numeric" },
+ { GJS_LOCALE_CATEGORY_TIME, "GJS_LOCALE_CATEGORY_TIME", "time" },
+ { 0, NULL, NULL } };
+ GType g_define_type_id
+ = g_enum_register_static(g_intern_static_string("GjsLocaleCategory"),
+ v);
+
+ g_once_init_leave(&g_define_type_id__volatile, g_define_type_id);
+ }
+ return g_define_type_id__volatile;
+}
+
+/**
+ * gjs_setlocale:
+ * @category:
+ * @locale: (allow-none):
+ *
+ * Returns:
+ */
+const char*
+gjs_setlocale(GjsLocaleCategory category, const char* locale)
+{
+ /* According to man setlocale(3), the return value may be allocated in
+ * static storage. */
+ return (const char*) setlocale(category, locale);
+}
+
+void
+gjs_textdomain(const char* domain)
+{
+ textdomain(domain);
+}
+
+void
+gjs_bindtextdomain(const char* domain, const char* location)
+{
+ bindtextdomain(domain, location);
+ /* Always use UTF-8; we assume it internally here */
+ bind_textdomain_codeset(domain, "UTF-8");
+}
+
+GParamFlags
+gjs_param_spec_get_flags(GParamSpec* pspec)
+{
+ return pspec->flags;
+}
+
+GType
+gjs_param_spec_get_value_type(GParamSpec* pspec)
+{
+ return pspec->value_type;
+}
+
+GType
+gjs_param_spec_get_owner_type(GParamSpec* pspec)
+{
+ return pspec->owner_type;
+}
diff --git a/libgjs-private/gjs-util.h b/libgjs-private/gjs-util.h
new file mode 100644
index 0000000..ae09733
--- /dev/null
+++ b/libgjs-private/gjs-util.h
@@ -0,0 +1,58 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* Copyright 2012 Giovanni Campagna <scampa giovanni gmail com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __GJS_PRIVATE_UTIL_H__
+#define __GJS_PRIVATE_UTIL_H__
+
+#include <locale.h>
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* For imports.format */
+char* gjs_format_int_alternative_output(int n);
+
+/* For imports.gettext */
+typedef enum {
+ GJS_LOCALE_CATEGORY_ALL = LC_ALL,
+ GJS_LOCALE_CATEGORY_COLLATE = LC_COLLATE,
+ GJS_LOCALE_CATEGORY_CTYPE = LC_CTYPE,
+ GJS_LOCALE_CATEGORY_MESSAGES = LC_MESSAGES,
+ GJS_LOCALE_CATEGORY_MONETARY = LC_MONETARY,
+ GJS_LOCALE_CATEGORY_NUMERIC = LC_NUMERIC,
+ GJS_LOCALE_CATEGORY_TIME = LC_TIME
+} GjsLocaleCategory;
+
+const char* gjs_setlocale(GjsLocaleCategory category, const char* locale);
+void gjs_textdomain(const char* domain);
+void gjs_bindtextdomain(const char* domain, const char* location);
+GType gjs_locale_category_get_type(void) G_GNUC_CONST;
+
+/* For imports.overrides.GObject */
+GParamFlags gjs_param_spec_get_flags(GParamSpec* pspec);
+GType gjs_param_spec_get_value_type(GParamSpec* pspec);
+GType gjs_param_spec_get_owner_type(GParamSpec* pspec);
+
+G_END_DECLS
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]