37
37
* ***** END LICENSE BLOCK ***** */
39
const { utils: Cu } = Components;
39
41
var EXPORTED_SYMBOLS = [ "gobject" ];
41
43
const GOBJECT_LIBNAME = "gobject-2.0";
42
44
const GOBJECT_ABIS = [ 0 ];
44
const Cu = Components.utils;
46
46
Cu.import("resource://gre/modules/ctypes.jsm");
47
Cu.import("resource://ubufox/libs/ctypes-utils.jsm");
47
Cu.import("resource://ubufox/modules/utils.jsm");
48
48
Cu.import("resource://ubufox/libs/glib.jsm");
50
["LOG", "WARN", "ERROR"].forEach(function(aName) {
51
this.__defineGetter__(aName, function() {
52
Components.utils.import("resource://gre/modules/AddonLogging.jsm");
54
LogManager.getLogger("ubufox.gobject", this);
59
var signalHandlers = {};
61
function GSignalCbData(cb, ccb) {
50
var gSignalHandlers = {};
66
53
function gobject_defines(lib) {
69
this.GConnectFlags = ctypes.int;
70
this.G_CONNECT_AFTER = (1<<0);
71
this.G_CONNECT_SWAPPED = (1<<1);
55
CTypesUtils.defineFlags(this, "GConnectFlags", 0, [
74
this.GObject = ctypes.StructType("GObject");
75
this.GClosure = ctypes.StructType("GClosure");
76
this.GCallback = ctypes.voidptr_t;
61
CTypesUtils.defineSimple(this, "GObject", ctypes.StructType("GObject"));
62
CTypesUtils.defineSimple(this, "GClosure", ctypes.StructType("GClosure"));
63
CTypesUtils.defineSimple(this, "GCallback", ctypes.voidptr_t);
79
this.GClosureNotify = ctypes.FunctionType(ctypes.default_abi, ctypes.void_t,
80
[glib.gpointer, this.GClosure.ptr]).ptr;
66
CTypesUtils.defineSimple(this, "GClosureNotify",
67
ctypes.FunctionType(ctypes.default_abi, ctypes.void_t,
69
this.GClosure.ptr]).ptr);
83
lib.lazy_bind("g_object_ref", glib.gpointer, glib.gpointer);
84
lib.lazy_bind("g_object_unref", ctypes.void_t, glib.gpointer);
85
lib.lazy_bind("g_signal_connect_data", glib.gulong, glib.gpointer,
86
glib.gchar.ptr, this.GCallback, glib.gpointer,
87
this.GClosureNotify, this.GConnectFlags);
88
lib.lazy_bind("g_signal_handler_disconnect", ctypes.void_t, glib.gpointer,
92
this.g_signal_connect = function(aInstance, aSignal, aHandler, aData) {
93
return gobject.g_signal_connect_data(aInstance, aSignal, aHandler, aData, null, 0);
96
this.GSignalConnect = function(aInstance, aSignal, aHandler, aRetType, aArgTypes) {
99
return aHandler.apply(null, Array.prototype.slice.call(arguments, 0));
104
let ccb = ctypes.FunctionType(ctypes.default_abi, aRetType, aArgTypes).ptr(cb);
106
let id = gobject.g_signal_connect(aInstance, aSignal, ccb, null);
107
signalHandlers[id] = new GSignalCbData(cb, ccb);
72
lib.lazy_bind("g_object_ref", glib.gpointer, [glib.gpointer]);
73
lib.lazy_bind("g_object_unref", ctypes.void_t, [glib.gpointer]);
74
lib.lazy_bind_with_wrapper("g_signal_connect", function(aWrappee, aInstance,
76
if (!aInstance.constructor.targetType) {
77
throw Error("Instance must be a pointer type");
80
if (!(aInstance.constructor.targetType in gSignals) ||
81
!(aSignal in gSignals[aInstance.constructor.targetType])) {
82
throw Error("No prototype available for signal");
85
var ccw = CTypesUtils.wrapCallback(aHandler,
86
{type: gSignals[aInstance.constructor.targetType][aSignal],
88
var id = aWrappee(aInstance, aSignal, ccw, null, null, 0);
90
gSignalHandlers[id] = ccw;
112
this.GSignalHandlerDisconnect = function(aInstance, aId) {
113
gobject.g_signal_handler_disconnect(aInstance, aId);
114
delete signalHandlers[aId];
93
}, glib.gulong, [glib.gpointer, glib.gchar.ptr, this.GCallback,
94
glib.gpointer, this.GClosureNotify, this.GConnectFlags],
95
"g_signal_connect_data");
97
lib.lazy_bind_with_wrapper("g_signal_handler_disconnect", function(aWrappee,
100
aWrappee(aInstance, aId);
101
// Unroot the callback
102
delete gSignalHandlers[aId];
103
}, ctypes.void_t, [glib.gpointer, glib.gulong]);
105
Object.defineProperty(this, "createSignal", {
106
value: function(aType, aName, aRetType, aArgTypes) {
107
if (!aType || "targetType" in aType) {
108
throw Error("Must specify a concrete C type");
111
if (typeof(aName) != "string") {
112
throw Error("Must specify a signal name");
115
if (!(aType in gSignals)) {
116
gSignals[aType] = {};
119
if (aName in gSignals[aType]) {
120
throw Error("Cannot redefine signal");
123
gSignals[aType][aName] =
124
ctypes.FunctionType(ctypes.default_abi, aRetType, aArgTypes).ptr;
118
new ctypes_library(GOBJECT_LIBNAME, GOBJECT_ABIS, gobject_defines, this);
130
var gobject = new CTypesUtils.newLibrary(GOBJECT_LIBNAME, GOBJECT_ABIS, gobject_defines);