From bc88ef7bcda59b15988d27517a4f4f7e0672e33b Mon Sep 17 00:00:00 2001 From: Andreas Rottmann Date: Sat, 3 Jan 2009 13:44:42 +0000 Subject: =?UTF-8?q?Bug=20556489=20=E2=80=93=20callback=20annotations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-01-03 Andreas Rottmann Bug 556489 – callback annotations * giscanner/transformer.py * tools/generate.c (write_callable_info): Write out the new scope, closure and destroy attributes. * giscanner/transformer.py (Transformer._type_is_callback): New method, checking if a given type is a callback. (Transformer._augment_callback_params): New method; adds information (closure, destroy) to callback parameters. (Transformer._handle_closure, Transformer._handle_destroy): New methods, auxiliary to _augment_callback_params. (Transformer._create_function): Call _augment_callback_params(). (Transformer._create_parameter): Handle scope option. (Transformer._create_typedef_callback): New method, creates a callback, and registers it in the typedef namespace (Transformer._create_typedef): Use _create_typedef_callback() instead of the plain _create_callback(). * giscanner/ast.py (Parameter): Added callback-related fields. * giscanner/girwriter.py: Write out new Parameter fields. * girepository/girnode.h (GIrNodeParam): Added fields scope, closure and destroy. * girepository/gtypelib.h (ArgBlob): Ditto. * girepository/girparser.c (start_parameter): Handle new fields. * girepository/girmodule.c (g_ir_module_build_typelib): Adjust arg_blob_size, bump major version due to this change. * girepository/girnode.c (g_ir_node_get_full_size_internal) (g_ir_node_build_typelib) * girepository/gtypelib.c (g_typelib_check_sanity): ArgBlob size adjustments. (g_ir_node_build_typelib): Fill in new ArgBlob flags from param. * girepository/girepository.h (GIScope): New enumeration, listing the different possible scopes for callbacks. * girepository/ginfo.c (g_arg_info_get_scope) (g_arg_info_get_closure, g_arg_info_get_destroy): Accessors for callback-related argument indices (callback scope, closure for a callback, destroy notification for a callback). * tests/scanner/: Added testcases for new features. svn path=/trunk/; revision=998 --- ChangeLog | 49 ++++++++++++++++++++++++++ docs/typelib-format.txt | 32 +++++++++++++++-- girepository/ginfo.c | 29 +++++++++++++++- girepository/girepository.h | 11 ++++++ girepository/girmodule.c | 4 +-- girepository/girnode.c | 9 +++-- girepository/girnode.h | 4 +++ girepository/girparser.c | 22 +++++++++++- girepository/gtypelib.c | 6 ++-- girepository/gtypelib.h | 6 +++- giscanner/ast.py | 5 ++- giscanner/girwriter.py | 6 ++++ giscanner/transformer.py | 56 +++++++++++++++++++++++++++++- tests/scanner/annotation-1.0-expected.gir | 32 +++++++++++++++++ tests/scanner/annotation-1.0-expected.tgir | 29 ++++++++++++++++ tests/scanner/annotation.c | 16 +++++++++ tests/scanner/annotation.h | 7 ++++ tests/scanner/utility-1.0-expected.gir | 51 +++++++++++++++++++++++++++ tests/scanner/utility-1.0-expected.tgir | 48 +++++++++++++++++++++++++ tests/scanner/utility.c | 15 ++++++++ tests/scanner/utility.h | 11 +++++- tools/generate.c | 24 +++++++++++++ 22 files changed, 456 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8bf8a3bd..bae3d7a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,52 @@ +2008-01-03 Andreas Rottmann + + Bug 556489 – callback annotations + + * giscanner/transformer.py + + * tools/generate.c (write_callable_info): Write out the new scope, + closure and destroy attributes. + + * giscanner/transformer.py (Transformer._type_is_callback): New + method, checking if a given type is a callback. + (Transformer._augment_callback_params): New method; adds + information (closure, destroy) to callback parameters. + (Transformer._handle_closure, Transformer._handle_destroy): New methods, + auxiliary to _augment_callback_params. + (Transformer._create_function): Call _augment_callback_params(). + (Transformer._create_parameter): Handle scope option. + + (Transformer._create_typedef_callback): New method, creates a + callback, and registers it in the typedef namespace + (Transformer._create_typedef): Use _create_typedef_callback() + instead of the plain _create_callback(). + + * giscanner/ast.py (Parameter): Added callback-related fields. + * giscanner/girwriter.py: Write out new Parameter fields. + + * girepository/girnode.h (GIrNodeParam): Added fields scope, + closure and destroy. + * girepository/gtypelib.h (ArgBlob): Ditto. + * girepository/girparser.c (start_parameter): Handle new fields. + + * girepository/girmodule.c (g_ir_module_build_typelib): Adjust + arg_blob_size, bump major version due to this change. + * girepository/girnode.c (g_ir_node_get_full_size_internal) + (g_ir_node_build_typelib) + * girepository/gtypelib.c (g_typelib_check_sanity): ArgBlob size + adjustments. + (g_ir_node_build_typelib): Fill in new ArgBlob flags from param. + + * girepository/girepository.h (GIScope): New enumeration, listing + the different possible scopes for callbacks. + + * girepository/ginfo.c (g_arg_info_get_scope) + (g_arg_info_get_closure, g_arg_info_get_destroy): Accessors for + callback-related argument indices (callback scope, closure for a + callback, destroy notification for a callback). + + * tests/scanner/: Added testcases for new features. + 2009-01-03 Jürg Billeter * giscanner/ast.py: diff --git a/docs/typelib-format.txt b/docs/typelib-format.txt index 895c1f0d..a47a9f78 100644 --- a/docs/typelib-format.txt +++ b/docs/typelib-format.txt @@ -391,7 +391,11 @@ struct ArgBlob guint transfer_ownership : 1; guint transfer_container_ownership : 1; guint is_return_value : 1; - guint reserved :24: + guint scope : 3; + guint reserved :21: + + gint8 closure; + gint8 destroy; SimpleTypeBlob arg_type; } @@ -437,7 +441,31 @@ is_return_value: at most one per function call. If an out parameter is marked as return value, the actual return value of the function should be either void or a boolean indicating the success of the call. - + +scope: + If the parameter is of a callback type, this denotes the scope + of the user_data and the callback function pointer itself + (for languages that emit code at run-time). + + 0 invalid -- the argument is not of callback type + 1 call -- the callback and associated user_data is + only used during the call to this function + 2 object -- the callback and associated user_data is + used until the object containing this method is destroyed + 3 async -- the callback and associated user_data is + only used until the callback is invoked, and the callback + is invoked always exactly once. + 4 notified -- the callback and and associated user_data is + used until the caller is notfied via the destroy_notify + +closure: + Index of the closure (user_data) parameter associated with the callback, + or -1. + +destroy: + Index of the destroy notfication callback parameter associated with + the callback, or -1. + arg_type: Describes the type of the parameter. See details below. diff --git a/girepository/ginfo.c b/girepository/ginfo.c index 5df1e3f8..8324c05b 100644 --- a/girepository/ginfo.c +++ b/girepository/ginfo.c @@ -741,12 +741,39 @@ g_arg_info_get_ownership_transfer (GIArgInfo *info) return GI_TRANSFER_NOTHING; } +GIScopeType +g_arg_info_get_scope (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + + return blob->scope; +} + +gint +g_arg_info_get_closure (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + + return blob->closure; +} + +gint +g_arg_info_get_destroy (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + + return blob->destroy; +} + GITypeInfo * g_arg_info_get_type (GIArgInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - return g_type_info_new (base, base->typelib, base->offset + 8); + return g_type_info_new (base, base->typelib, base->offset + 12); } /* GITypeInfo functions */ diff --git a/girepository/girepository.h b/girepository/girepository.h index abeb8570..38697c69 100644 --- a/girepository/girepository.h +++ b/girepository/girepository.h @@ -269,12 +269,23 @@ typedef enum { GI_DIRECTION_INOUT } GIDirection; +typedef enum { + GI_SCOPE_TYPE_INVALID, + GI_SCOPE_TYPE_CALL, + GI_SCOPE_TYPE_OBJECT, + GI_SCOPE_TYPE_ASYNC, + GI_SCOPE_TYPE_NOTIFIED +} GIScopeType; + GIDirection g_arg_info_get_direction (GIArgInfo *info); gboolean g_arg_info_is_dipper (GIArgInfo *info); gboolean g_arg_info_is_return_value (GIArgInfo *info); gboolean g_arg_info_is_optional (GIArgInfo *info); gboolean g_arg_info_may_be_null (GIArgInfo *info); GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info); +GIScopeType g_arg_info_get_scope (GIArgInfo *info); +gint g_arg_info_get_closure (GIArgInfo *info); +gint g_arg_info_get_destroy (GIArgInfo *info); GITypeInfo * g_arg_info_get_type (GIArgInfo *info); diff --git a/girepository/girmodule.c b/girepository/girmodule.c index be41a1ed..85103bff 100644 --- a/girepository/girmodule.c +++ b/girepository/girmodule.c @@ -190,7 +190,7 @@ g_ir_module_build_typelib (GIrModule *module, /* fill in header */ header = (Header *)data; memcpy (header, G_IR_MAGIC, 16); - header->major_version = 1; + header->major_version = 2; header->minor_version = 0; header->reserved = 0; header->n_entries = n_entries; @@ -213,7 +213,7 @@ g_ir_module_build_typelib (GIrModule *module, header->callback_blob_size = 12; header->signal_blob_size = 12; header->vfunc_blob_size = 16; - header->arg_blob_size = 12; + header->arg_blob_size = 16; header->property_blob_size = 12; header->field_blob_size = 12; header->value_blob_size = 12; diff --git a/girepository/girnode.c b/girepository/girnode.c index 61e4f0b6..c4045ef7 100644 --- a/girepository/girnode.c +++ b/girepository/girnode.c @@ -582,7 +582,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeParam *param = (GIrNodeParam *)node; - size = 12; + size = 16; if (node->name) size += ALIGN_VALUE (strlen (node->name) + 1, 4); size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type); @@ -1764,7 +1764,7 @@ g_ir_node_build_typelib (GIrNode *node, ArgBlob *blob = (ArgBlob *)&data[*offset]; GIrNodeParam *param = (GIrNodeParam *)node; - *offset += 8; + *offset += 12; blob->name = write_string (node->name, strings, data, offset2); blob->in = param->in; @@ -1775,8 +1775,11 @@ g_ir_node_build_typelib (GIrNode *node, blob->transfer_ownership = param->transfer; blob->transfer_container_ownership = param->shallow_transfer; blob->return_value = param->retval; + blob->scope = param->scope; blob->reserved = 0; - + blob->closure = param->closure; + blob->destroy = param->destroy; + g_ir_node_build_typelib ((GIrNode *)param->type, module, modules, strings, types, data, offset, offset2); } diff --git a/girepository/girnode.h b/girepository/girnode.h index 674594d8..a1b8f0dc 100644 --- a/girepository/girnode.h +++ b/girepository/girnode.h @@ -143,6 +143,10 @@ struct _GIrNodeParam gboolean allow_none; gboolean transfer; gboolean shallow_transfer; + GIScopeType scope; + + gint8 closure; + gint8 destroy; GIrNodeType *type; }; diff --git a/girepository/girparser.c b/girepository/girparser.c index e6d59b4c..1072ecc5 100644 --- a/girepository/girparser.c +++ b/girepository/girparser.c @@ -837,6 +837,9 @@ start_parameter (GMarkupParseContext *context, const gchar *optional; const gchar *allow_none; const gchar *transfer; + const gchar *scope; + const gchar *closure; + const gchar *destroy; GIrNodeParam *param; if (!(strcmp (element_name, "parameter") == 0 && @@ -850,7 +853,10 @@ start_parameter (GMarkupParseContext *context, optional = find_attribute ("optional", attribute_names, attribute_values); allow_none = find_attribute ("allow-none", attribute_names, attribute_values); transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); - + scope = find_attribute ("scope", attribute_names, attribute_values); + closure = find_attribute ("closure", attribute_names, attribute_values); + destroy = find_attribute ("destroy", attribute_names, attribute_values); + if (name == NULL) name = "unknown"; @@ -899,6 +905,20 @@ start_parameter (GMarkupParseContext *context, parse_param_transfer (param, transfer); + if (scope && strcmp (scope, "call") == 0) + param->scope = GI_SCOPE_TYPE_CALL; + else if (scope && strcmp (scope, "object") == 0) + param->scope = GI_SCOPE_TYPE_OBJECT; + else if (scope && strcmp (scope, "async") == 0) + param->scope = GI_SCOPE_TYPE_ASYNC; + else if (scope && strcmp (scope, "notified") == 0) + param->scope = GI_SCOPE_TYPE_NOTIFIED; + else + param->scope = GI_SCOPE_TYPE_INVALID; + + param->closure = closure ? atoi (closure) : -1; + param->destroy = destroy ? atoi (destroy) : -1; + ((GIrNode *)param)->name = g_strdup (name); switch (ctx->current_node->type) diff --git a/girepository/gtypelib.c b/girepository/gtypelib.c index 51cbafcd..d7b09f21 100644 --- a/girepository/gtypelib.c +++ b/girepository/gtypelib.c @@ -164,7 +164,7 @@ g_typelib_check_sanity (void) CHECK_SIZE (Header, 108); CHECK_SIZE (DirEntry, 12); CHECK_SIZE (SimpleTypeBlob, 4); - CHECK_SIZE (ArgBlob, 12); + CHECK_SIZE (ArgBlob, 16); CHECK_SIZE (SignatureBlob, 8); CHECK_SIZE (CommonBlob, 8); CHECK_SIZE (FunctionBlob, 20); @@ -286,7 +286,7 @@ validate_header (ValidateContext *ctx, } - if (header->major_version != 1 || header->minor_version != 0) + if (header->major_version != 2 || header->minor_version != 0) { g_set_error (error, G_TYPELIB_ERROR, @@ -319,7 +319,7 @@ validate_header (ValidateContext *ctx, header->callback_blob_size != 12 || header->signal_blob_size != 12 || header->vfunc_blob_size != 16 || - header->arg_blob_size != 12 || + header->arg_blob_size != 16 || header->property_blob_size != 12 || header->field_blob_size != 12 || header->value_blob_size != 12 || diff --git a/girepository/gtypelib.h b/girepository/gtypelib.h index 343f9e1b..a68d0080 100644 --- a/girepository/gtypelib.h +++ b/girepository/gtypelib.h @@ -132,7 +132,11 @@ typedef struct guint transfer_ownership : 1; guint transfer_container_ownership : 1; guint return_value : 1; - guint reserved :24; + guint scope : 3; + guint reserved :21; + + gint8 closure; + gint8 destroy; SimpleTypeBlob arg_type; } ArgBlob; diff --git a/giscanner/ast.py b/giscanner/ast.py index 7df1bf69..6bd858b2 100644 --- a/giscanner/ast.py +++ b/giscanner/ast.py @@ -289,7 +289,7 @@ class TypeContainer(Node): class Parameter(TypeContainer): def __init__(self, name, typenode, direction=PARAM_DIRECTION_IN, - transfer=None, allow_none=False): + transfer=None, allow_none=False, scope=None): TypeContainer.__init__(self, name, typenode, transfer) if direction in [PARAM_DIRECTION_IN, PARAM_DIRECTION_OUT, PARAM_DIRECTION_INOUT]: @@ -298,6 +298,9 @@ class Parameter(TypeContainer): self.direction = PARAM_DIRECTION_IN self.allow_none = not not allow_none + self.scope = scope + self.closure_index = -1 + self.destroy_index = -1 def __repr__(self): return 'Parameter(%r, %r)' % (self.name, self.type) diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py index 4468e25b..f82a73e5 100644 --- a/giscanner/girwriter.py +++ b/giscanner/girwriter.py @@ -162,6 +162,12 @@ class GIRWriter(XMLWriter): parameter.transfer)) if parameter.allow_none: attrs.append(('allow-none', '1')) + if parameter.scope: + attrs.append(('scope', parameter.scope)) + if parameter.closure_index >= 0: + attrs.append(('closure', '%d' % parameter.closure_index)) + if parameter.destroy_index >= 0: + attrs.append(('destroy', '%d' % parameter.destroy_index)) with self.tagcontext('parameter', attrs): self._write_type(parameter.type) diff --git a/giscanner/transformer.py b/giscanner/transformer.py index e7c7214a..0ed7ca00 100644 --- a/giscanner/transformer.py +++ b/giscanner/transformer.py @@ -269,6 +269,52 @@ class Transformer(object): if isinstance(return_.type, Array): self._pair_array(params, return_) + def _type_is_callback(self, type): + if (isinstance(type, Callback) or + isinstance(self._typedefs_ns.get(type.name), Callback)): + return True + return False + + def _handle_closure(self, param, closure_idx, closure_param): + if (closure_param.type.name == 'any' and + closure_param.name == 'user_data'): + param.closure_name = closure_param.name + param.closure_index = closure_idx + return True + return False + + def _handle_destroy(self, param, destroy_idx, destroy_param): + if ((self._namespace.name == 'GLib' and + destroy_param.type.name == 'DestroyNotify') or + destroy_param.type.name == 'GLib.DestroyNotify'): + param.destroy_name = destroy_param.name + param.destroy_index = destroy_idx + return True + return False + + def _augment_callback_params(self, params): + for i, param in enumerate(params): + if self._type_is_callback(param.type): + # j is the index where we look for closure/destroy to + # group with the callback param + j = i + 1 + if j == len(params): + continue # no more args -> nothing to group look + # at the param directly following for either a closure + # or a destroy; only one of these will fire + had_closure = self._handle_closure(param, j, params[j]) + had_destroy = self._handle_destroy(param, j, params[j]) + j += 1 + # are we out of params, or did we find neither? + if j == len(params) or (not had_closure and not had_destroy): + continue + # we found either a closure or a destroy; check the + # parameter following for the other + if not had_closure: + self._handle_closure(param, j, params[j]) + if not had_destroy: + self._handle_destroy(param, j, params[j]) + # We take the annotations from the parser as strings; here we # want to split them into components, so: # (transfer full) -> {'transfer' : [ 'full' ]} @@ -286,6 +332,7 @@ class Transformer(object): symbol.base_type, directives)) return_ = self._create_return(symbol.base_type.base_type, directives.get('return', {})) + self._augment_callback_params(parameters) self._pair_annotations(parameters, return_) name = self._strip_namespace_func(symbol.ident) func = Function(name, return_, parameters, symbol.ident) @@ -357,7 +404,7 @@ class Transformer(object): ctype = symbol.base_type.type if (ctype == CTYPE_POINTER and symbol.base_type.base_type.type == CTYPE_FUNCTION): - node = self._create_callback(symbol) + node = self._create_typedef_callback(symbol) elif (ctype == CTYPE_POINTER and symbol.base_type.base_type.type == CTYPE_STRUCT): node = self._create_typedef_struct(symbol, disguised=True) @@ -586,6 +633,8 @@ class Transformer(object): pass elif option in ('transfer', 'transfer-inferred'): pass + elif option == 'scope': + param.scope = data[0] else: print 'Unhandled parameter annotation option: %r' % ( option, ) @@ -642,6 +691,11 @@ class Transformer(object): self._create_union(symbol) return union + def _create_typedef_callback(self, symbol): + callback = self._create_callback(symbol) + self._typedefs_ns[callback.name] = callback + return callback + def _create_struct(self, symbol): directives = symbol.directives() struct = self._typedefs_ns.get(symbol.ident, None) diff --git a/tests/scanner/annotation-1.0-expected.gir b/tests/scanner/annotation-1.0-expected.gir index 88dcdc6a..155b9c4a 100644 --- a/tests/scanner/annotation-1.0-expected.gir +++ b/tests/scanner/annotation-1.0-expected.gir @@ -245,6 +245,22 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/scanner/annotation-1.0-expected.tgir b/tests/scanner/annotation-1.0-expected.tgir index 4fe10bd6..576d6d74 100644 --- a/tests/scanner/annotation-1.0-expected.tgir +++ b/tests/scanner/annotation-1.0-expected.tgir @@ -234,6 +234,19 @@ + + + + + + + + + + + + + @@ -245,6 +258,22 @@ + + + + + + + + + + + + + + + + diff --git a/tests/scanner/annotation.c b/tests/scanner/annotation.c index cbb69b72..6278b6ce 100644 --- a/tests/scanner/annotation.c +++ b/tests/scanner/annotation.c @@ -307,6 +307,22 @@ annotation_object_string_out(AnnotationObject *object, } +/** + * annotation_object_foreach: + * @object: a #AnnotationObject + * @func: (scope call): Callback to invoke + * @user_data: Callback user data + * + * Test taking a call-scoped callback + **/ +void +annotation_object_foreach (AnnotationObject *object, + AnnotationForeachFunc func, + gpointer user_data) +{ + +} + /** * annotation_object_allow_none: * @object: a #GObject diff --git a/tests/scanner/annotation.h b/tests/scanner/annotation.h index 1e83ca23..87946609 100644 --- a/tests/scanner/annotation.h +++ b/tests/scanner/annotation.h @@ -22,6 +22,10 @@ typedef GList* (*AnnotationListCallback) (GList *in); typedef struct _AnnotationObject AnnotationObject; typedef struct _AnnotationObjectClass AnnotationObjectClass; +typedef void (*AnnotationForeachFunc) (AnnotationObject *object, + const char *item, + gpointer user_data); + struct _AnnotationObject { GObject parent_instance; @@ -75,6 +79,9 @@ void annotation_object_parse_args (AnnotationObject *object, char ***argv); gboolean annotation_object_string_out (AnnotationObject *object, char **str_out); +void annotation_object_foreach (AnnotationObject *object, + AnnotationForeachFunc func, + gpointer user_data); GObject* annotation_object_do_not_use (AnnotationObject *object); diff --git a/tests/scanner/utility-1.0-expected.gir b/tests/scanner/utility-1.0-expected.gir index c01ec4cb..6642d2fc 100644 --- a/tests/scanner/utility-1.0-expected.gir +++ b/tests/scanner/utility-1.0-expected.gir @@ -12,6 +12,28 @@ parent="GObject.Object" glib:type-name="UtilityObject" glib:get-type="utility_object_get_type"> + + + + + + + + + + + + + + + + + + + @@ -21,6 +43,19 @@ + + + + + + + + + + + + + @@ -58,5 +93,21 @@ + + + + + + + + + + + + + + + + diff --git a/tests/scanner/utility-1.0-expected.tgir b/tests/scanner/utility-1.0-expected.tgir index 236e2d72..26e6d196 100644 --- a/tests/scanner/utility-1.0-expected.tgir +++ b/tests/scanner/utility-1.0-expected.tgir @@ -10,12 +10,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -53,5 +85,21 @@ + + + + + + + + + + + + + + + + diff --git a/tests/scanner/utility.c b/tests/scanner/utility.c index 45b4bd28..756de178 100644 --- a/tests/scanner/utility.c +++ b/tests/scanner/utility.c @@ -14,3 +14,18 @@ utility_object_init (UtilityObject *object) } +void +utility_object_watch_dir (UtilityObject *object, + const char *path, + UtilityFileFunc func, + gpointer user_data, + GDestroyNotify destroy) +{ + +} + +void +utility_dir_foreach (const char *path, UtilityFileFunc func, gpointer user_data) +{ + +} diff --git a/tests/scanner/utility.h b/tests/scanner/utility.h index a592a96d..a744f037 100644 --- a/tests/scanner/utility.h +++ b/tests/scanner/utility.h @@ -23,7 +23,14 @@ struct _UtilityObjectClass /* This one is similar to Pango.Glyph */ typedef guint32 UtilityGlyph; +typedef void (*UtilityFileFunc)(const char *path, gpointer user_data); + GType utility_object_get_type (void) G_GNUC_CONST; +void utility_object_watch_dir (UtilityObject *object, + const char *path, + UtilityFileFunc func, + gpointer user_data, + GDestroyNotify destroy); typedef enum { @@ -53,5 +60,7 @@ typedef union glong integer; double real; } UtilityUnion; - + +void utility_dir_foreach (const char *path, UtilityFileFunc func, gpointer user_data); + #endif /* __UTILITY_H__ */ diff --git a/tools/generate.c b/tools/generate.c index 7c849bcd..dcc36faf 100644 --- a/tools/generate.c +++ b/tools/generate.c @@ -455,6 +455,30 @@ write_callable_info (const gchar *namespace, if (g_arg_info_is_optional (arg)) xml_printf (file, " optional=\"1\""); + + switch (g_arg_info_get_scope (arg)) + { + case GI_SCOPE_TYPE_INVALID: + break; + case GI_SCOPE_TYPE_CALL: + xml_printf (file, " scope=\"call\""); + break; + case GI_SCOPE_TYPE_OBJECT: + xml_printf (file, " scope=\"object\""); + break; + case GI_SCOPE_TYPE_ASYNC: + xml_printf (file, " scope=\"async\""); + break; + case GI_SCOPE_TYPE_NOTIFIED: + xml_printf (file, " scope=\"notified\""); + break; + } + + if (g_arg_info_get_closure (arg) >= 0) + xml_printf (file, " closure=\"%d\"", g_arg_info_get_closure (arg)); + + if (g_arg_info_get_destroy (arg) >= 0) + xml_printf (file, " destroy=\"%d\"", g_arg_info_get_destroy (arg)); type = g_arg_info_get_type (arg); write_type_info (namespace, type, file); -- cgit v1.2.1