Moved "Shell" code into a "Glob" type/namespace, and removed FormatSpecification...
[cslatevm.git] / src / plugins / glib-wrapper.c
blobbbda5c0a85d2a18dc6389b7ba9ceb0b67b58ad43
1 #ifdef WIN32
2 # define EXPORT __declspec(dllexport)
3 #else
4 # define EXPORT
5 #endif
7 #include <glib.h>
8 #include <glib-object.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <stdint.h>
12 #include <inttypes.h>
15 typedef intptr_t slate_int_t;
18 EXPORT gint wrapper_g_value_type( GValue *gValueOop ) {
19 return G_VALUE_TYPE(gValueOop);
22 EXPORT gint wrapper_g_type_fundamental( gint gType ) {
23 return G_TYPE_FUNDAMENTAL(gType);
26 EXPORT gboolean wrapper_g_type_is_fundamental( gint gType ) {
27 return G_TYPE_IS_FUNDAMENTAL(gType);
30 EXPORT GValue *wrapper_g_value_new(void) {
31 return g_new0(GValue, 1);
34 EXPORT GType wrapper_g_type_from_instance( GObject *object ) {
35 return G_TYPE_FROM_INSTANCE( object );
38 GAsyncQueue* callbackQueue;
40 EXPORT void wrapper_g_callback_queue_init( void ) {
41 callbackQueue = g_async_queue_new();
44 EXPORT void wrapper_g_callback_queue_shutdown( void ) {
45 g_async_queue_unref( callbackQueue );
48 typedef struct{
49 gint blockID;
50 gint parameterCount;
51 GValue *parameters[];
52 } CallbackData;
54 EXPORT CallbackData *wrapper_g_callback_wait_next(void) {
55 return (CallbackData *)g_async_queue_pop(callbackQueue);
58 EXPORT void wrapper_g_callback_end( CallbackData* data ) {
59 int index;
60 for(index = 0; index < data->parameterCount; index++) {
61 g_value_unset( data->parameters[index] );
62 g_free( data->parameters[index] );
64 g_free(data);
67 EXPORT gint wrapper_g_callback_data_get_block_id( CallbackData* data ) {
68 return data->blockID;
71 EXPORT slate_int_t wrapper_g_value_get_int(void* data ) {
72 return (slate_int_t)g_value_get_int(data);
75 EXPORT gint wrapper_g_callback_data_get_parameter_count( CallbackData* data ) {
76 return data->parameterCount;
79 EXPORT GValue *wrapper_g_callback_data_get_parameter_at( CallbackData* data, gint index ) {
80 return data->parameters[index];
83 static gboolean callback(GObject* object, gpointer blockID, gint parameterCount, const GValue* parameters) {
84 int index;
85 CallbackData *data = g_malloc0( sizeof(CallbackData) + sizeof(GValue *) * (parameterCount + 1) );
86 data->blockID = (gint)blockID;
87 data->parameterCount = parameterCount + 1;
88 //Copy the emitter as the first argument
89 data->parameters[0] = wrapper_g_value_new();
90 g_value_init( data->parameters[0], G_TYPE_OBJECT );
91 g_value_set_object( data->parameters[0], object );
92 for(index = 0; index < parameterCount; index++) {
93 //We copy the parameters because we may return from the callback before even using this values, the callback generator destorys the data on return
94 data->parameters[index + 1] = wrapper_g_value_new();
95 g_value_init( data->parameters[index + 1], G_VALUE_TYPE((GValue *)parameters + index) );
96 g_value_copy( (GValue *)parameters + index, data->parameters[index + 1] );
98 g_async_queue_push( callbackQueue, data );
99 return TRUE;
102 void callback_marshal (GClosure *closure, GValue *return_value, guint n_param_values,
103 const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) {
105 typedef gboolean (*SignalCallbackFunc) (GObject *object, gpointer data, gint paramValuesSize, const GValue *paramValues);
106 register SignalCallbackFunc callback;
107 register GCClosure *cc = (GCClosure*) closure;
108 register gpointer data1, data2;
109 gboolean retVal;
111 if (G_CCLOSURE_SWAP_DATA (closure)) {
112 data1 = closure->data;
113 data2 = g_value_peek_pointer (param_values + 0);
115 else {
116 data1 = g_value_peek_pointer (param_values + 0);
117 data2 = closure->data;
120 callback = (SignalCallbackFunc) (marshal_data ? marshal_data : cc->callback);
121 retVal = callback (data1, data2, (gint) (n_param_values - 1), param_values + 1);
122 if (return_value)
123 g_value_set_boolean (return_value, retVal);
126 void callback_finalize_notifier( gpointer blockID, GClosure *closure ) {
127 //callbacks with parameter count=0 signal the finalization of a callback, which means that it is no longer valid, ie: the object was destroyed
128 CallbackData *data = g_malloc0( sizeof(CallbackData) );
129 data->blockID = (gint)blockID;
130 data->parameterCount = 0;
131 g_async_queue_push( callbackQueue, data );
134 EXPORT void wrapper_g_object_connect_to_block_id( gpointer instance, char* aSignalName, gint blockID ) {
135 GClosure *closure = g_cclosure_new( G_CALLBACK(callback), (gpointer)blockID, NULL);
136 g_closure_set_marshal( closure, callback_marshal);
137 g_closure_add_finalize_notifier( closure, (gpointer)blockID, callback_finalize_notifier );
138 g_signal_connect_closure(instance, aSignalName, closure, FALSE);
141 EXPORT GClosure *wrapper_g_cclosure_new(gint blockID) {
142 GClosure *closure = g_cclosure_new( G_CALLBACK(callback), (gpointer)blockID, callback_finalize_notifier);
143 g_closure_set_marshal( closure, callback_marshal);
144 return closure;
147 EXPORT gchar *wraper_g_pointer_as_string( gpointer *pointer ) {
148 return (gchar *)pointer;