Cleanup
[cl-gtk2.git] / doc / gobject.ref.texi
index 082e628..a14ccfd 100644 (file)
@@ -1074,11 +1074,18 @@ Example:
 
 @node Closures
 @chapter Closures
+@menu
+* create-signal-handler-closure::
+* Object-bound foreign functions::
+@end menu
 
 Closure are anonymous functions that capture their lexical environment.
 
 GObject supports using closures (as instances of type GClosure) as signal handlers and in some other places where a function is expected. Function @code{create-signal-handler-closure} create closure from lisp function that can be used a signal handler. The GClosure is finalized automatically when GObject no longer needs it (e.g., when GClosure is disconnected from signal).
 
+(TODO: GObject defines finer closure API: g_closure_ref, g_closure_unref, g_closure_invoke. It should be bound.)
+
+@node create-signal-handler-closure
 @section create-signal-handler-closure
 @Function create-signal-handler-closure
 @lisp
@@ -1112,7 +1119,45 @@ Example of usage from GObject binding code:
                             after))
 @end lisp
 
-(TODO: GObject defines finer closure API: g_closure_ref, g_closure_unref, g_closure_invoke. It should be bound.)
+@node Object-bound foreign functions
+@section Object-bound foreign functions
+
+A common idiom for Gtk+ for passing user-defined function is as follows. Callback function has (besides its 'useful' arguments) an additional argument at the end - the 'data' pointer. This 'data' pointer, along with the pointer to 'destroy-notify' function is specified when passing the function. Destroy-notify function allows to free the function object (the Lisp closure) when it is not used by an object.
+
+@RMacro define-cb-methods
+@lisp
+(define-cb-methods name return-type ((arg-1 type-1) ... (arg-n type-n)))
+@end lisp
+
+Defines two CFFI callbacks assosiated with the callback function type @var{name}. Creates @var{name}-cb - a callback to be passed as an function and create @var{name}-destroy-notify - a callback to be passed as 'destroy-notify' function. These callbacks are intended to work together with @ref{create-fn-ref}.
+
+Arguments and return-type are the same as CFFI arguments and return-type for callbacks. Arguments do not include the last 'data' pointer.
+
+@RFunction create-fn-ref
+@lisp
+(create-fn-ref object function) @result{} foreign-pointer
+@end lisp
+
+This function creates a foreign structure containing the data neccesary for callbacks defined by @ref{define-cb-methods} to call and dispose of the @var{function}. The @var{function} is bound to the @var{object}. This is neccesary for correct work of garbage collector. The created structure is freed by 'destroy-notify' function.
+
+Example:
+@lisp
+(defcfun gtk-assistant-set-forward-page-func :void
+  (assistant (g-object assistant))
+  (page-func :pointer)
+  (data :pointer)
+  (destroy-notify :pointer))
+
+(define-cb-methods assistant-page-func :int ((current-page :int)))
+
+(defun set-assistant-forward-page-function (assistant function)
+  (if function
+      (gtk-assistant-set-forward-page-func assistant
+                                           (callback assistant-page-func-cb)
+                                           (create-fn-ref assistant function)
+                                           (callback assistant-page-func-destroy-notify))
+      (gtk-assistant-set-forward-page-func assistant (null-pointer) (null-pointer) (null-pointer))))
+@end lisp
 
 @node GObject low-level
 @chapter GObject low-level
@@ -1518,7 +1563,7 @@ Example:
 
 Function @code{emit-signal} is used to emit signals on objects.
 
-@Function emit-signal
+@RFunction emit-signal
 @code{(emit-signal object signal-name &rest args) @result{} return-value}
 
 @table @var
@@ -1629,36 +1674,43 @@ Unfortunately, GObject does not provide information about vtables, and does not
 
 @Macro define-vtable
 @lisp
-(define-vtable (type-name cstruct-name)
+(define-vtable (g-type-name type-name)
   &body item*)
 
-item ::= (name callback-name return-type &rest arg*)
 item ::= (:skip cffi-structure-item)
+item ::= (method-name (return-type &rest arg*) &key impl-call)
 arg ::= (arg-name arg-type)
+impl-call ::= ((arg-name*) &body call-code)
 @end lisp
 
 @table @var
-@item @var{type-name}
+@item @var{g-type-name}
 A string naming the GObject type of interface
-@item @var{cstruct-name}
-A name for a generated CFFI foreign structure
-@item @var{name}
+@item @var{cffi-structure-item}
+A structure item that is inserted verbatim into foreign structure definition of vtable and is not used as a pointer to method
+@item @var{method-name}
 A name for implementation generic function
-@item @var{callback-name}
-A name for generated callback function
 @item @var{return-type}
 A CFFI specifier for foreign function return type
 @item @var{arg-name}
 A symbol naming the argument of interface method
 @item @var{arg-type}
 A CFFI specifier for foreign function argument type
+@item @var{call-code}
+A body of code that is used to convert arguments and return values between interface signature and desired implementor generic function signature
 @end table
 
-Macro that specifies the vtable for an interface. This macro defines generic functions (named by @code{name}) that correspond to methods of an interface. On these generic functions methods should be defined that implement the interface method. @code{item}s specify the CFFI foreign structure for vtable. Vtable contains not only function pointers, but other slots. Such slots should be specified here with @code{:skip} prepended to them. This is needed to be able to correctly calculate offsets to function pointers in vtable.
+Macro that specifies the vtable for an interface. Vtable for an interface is a structure that contains pointer to implementations of interface methods. Vtable is used to dispach method calls to corresponding method implementations. In cl-gtk2-gobject, vtables are needed to create classes that implement GObject interfaces.
+
+GObject interfaces are implemented in the following way. For every method, an implementor generic function is defined. This generic function is called by interface method callback, and CLOS classes specialize on this generic function to implement an interface. The generic function has the same signature as the interface's function, but signatures may differ.
+
+This macro defines generic functions (named by concatenatinag @var{type-name}, @var{name} and @code{impl}; e.g., @code{get-flags} method of class @code{tree-model} will have generic function named @code{tree-model-get-flags-impl}) that correspond to methods of an interface. On these generic functions methods should be defined that implement the interface method. @code{item}s specify the CFFI foreign structure for vtable. Vtable contains not only function pointers, but other slots. Such slots should be specified here with @code{:skip} prepended to them. This is needed to be able to correctly calculate offsets to function pointers in vtable.
+
+In some cases, the signature of interface method is not very lispy: it may pass @code{void*} pointers, pointers to places where return values should be stored. To conceal such unlispy things, you specify your own code that will call the generic function and translate arguments for implementor generic function. This is implemented by specifying @var{impl-call} method option. @var{impl-call} specifies the signature of implementor function and code that calls the generic function and returns its result. The code is put in return position of callback, and it has access to the arguments of callback and its return value becomes the return value of callback.
 
 Example:
 @lisp
-(define-vtable ("GtkTreeModel" c-gtk-tree-model)
+(define-vtable ("GtkTreeModel" tree-model)
   (:skip parent-instance g-type-interface)
   ;;some signals
   (:skip tree-model-row-changed :pointer)
@@ -1667,48 +1719,25 @@ Example:
   (:skip tree-model-row-deleted :pointer)
   (:skip tree-model-rows-reordered :pointer)
   ;;methods
-  (tree-model-get-flags-impl tree-model-get-flags-cb
-    tree-model-flags
-    (tree-model g-object))
-  (tree-model-get-n-columns-impl tree-model-get-n-columns-cb
-    :int
-    (tree-model g-object))
-  (tree-model-get-column-type-impl tree-model-get-column-type-cb
-    g-type-designator
-    (tree-model g-object) (index :int))
-  (tree-model-get-iter-impl tree-model-get-iter-cb
-    :boolean
-    (tree-model g-object) (iter (g-boxed-foreign tree-iter)) (path (g-boxed-foreign tree-path)))
-  (tree-model-get-path-impl tree-model-get-path-cb
-    (g-boxed-foreign tree-path :return)
-    (tree-model g-object) (iter (g-boxed-foreign tree-iter)))
-  (tree-model-get-value-impl tree-model-get-value-cb
-    :void
-    (tree-model g-object) (iter (g-boxed-foreign tree-iter)) (n :int) (value (:pointer g-value)))
-  (tree-model-iter-next-impl tree-model-iter-next-cb
-    :boolean
-    (tree-model g-object) (iter (g-boxed-foreign tree-iter)))
-  (tree-model-iter-children-impl tree-model-iter-children-cb
-    :boolean
-    (tree-model g-object) (iter (g-boxed-foreign tree-iter)) (parent (g-boxed-foreign tree-iter)))
-  (tree-model-iter-has-child-impl tree-model-iter-has-child-cb
-    :boolean
-    (tree-model g-object) (iter (g-boxed-foreign tree-iter)))
-  (tree-model-iter-n-children-impl tree-model-iter-n-children-cb
-    :int
-    (tree-model g-object) (iter (g-boxed-foreign tree-iter)))
-  (tree-model-iter-nth-child-impl tree-model-iter-nth-child-cb
-    :boolean
-    (tree-model g-object) (iter (g-boxed-foreign tree-iter)) (parent (g-boxed-foreign tree-iter)) (n :int))
-  (tree-model-iter-parent-impl tree-model-iter-parent-cb
-    :boolean
-    (tree-model g-object) (iter (g-boxed-foreign tree-iter)) (child (g-boxed-foreign tree-iter)))
-  (tree-model-ref-node-impl tree-model-ref-node-cb
-    :void
-    (tree-model g-object) (iter (g-boxed-foreign tree-iter)))
-  (tree-model-unref-node-impl tree-model-unref-node-cb
-    :void
-    (tree-model g-object) (iter (g-boxed-foreign tree-iter))))
+  (get-flags (tree-model-flags (tree-model g-object)))
+  (get-value (:void
+              (tree-model g-object)
+              (iter (g-boxed-foreign tree-iter))
+              (n :int)
+              (value (:pointer g-value)))
+             :impl-call
+             ((tree-model iter n)
+              (multiple-value-bind (v type) (tree-model-get-value-impl tree-model iter n)
+                (set-g-value value v type)))))
+
+(defmethod tree-model-get-flags-impl ((model array-list-store))
+  '(:list-only))
+
+(defmethod tree-model-get-value-impl ((model array-list-store) iter n)
+  (let ((n-row (tree-iter-user-data iter)))
+    (values (funcall (aref (store-getters model) n) 
+                     (aref (store-items model) n-row))
+            (aref (store-types model) n))))
 @end lisp
 
 @node register-object-type-implementation
@@ -1797,7 +1826,7 @@ A form that is the initform of Lisp structure slot
 A boolean. If it is true, then the slot contains GBoxed structure whose name is @code{slot-type}.
 @end table
 
-Defines the ``simple'' GBoxed structure corresponding to C structure. The slot specification is analogous to CFFI @code{defstruct} slot specification with the addition of @code{inline} option.
+Defines the ``simple'' GBoxed structure corresponding to C structure. The slot specification is analogous to CFFI @code{defstruct} slot specification with the addition of @code{inline} option. This also defines the @var{name}-cstruct CFFI structure definition with equivalent structure.
 
 Example of usage:
 @lisp
@@ -1861,6 +1890,8 @@ Variant structure is represented in Lisp via a hierarchy on structures. For exam
 
 It is assumed that the variant of structures can be represented as C structures with fields of their ``parent'' structures prepended to them. This assumption breaks when structures include their ``parent'' structure as a first field (this changes the memory alignment and changes offsets of fields).
 
+This also defines the @var{name}-cstruct, @var{structure-name}-cstruct, @var{structure-name}-cunion CFFI structures definitions with equivalent structures (unions).
+
 For example, for these structures this assumption holds:
 @example
 union GdkEvent