cl-gtk2-gobject
***************

Introduction
************

GObject is a part of GLib library that implements the type system. The CL-GTK2-GObject is a Common Lisp binding for relevant parts of GObject.

The purpose of CL-GTK2-GObject is to ease the creation of binding for libraries based on GObject.

Please bear in mind that this is the documentation for a work-in-progress library and is a snapshot of current situation. API and functionality may (and will) change. Largely unfinished parts are working with GBoxed types, subclassing GObjects and implementing GInterfaces.

CL-GTK2-GObject is logically split into several layers:

  * FFI code. FFI (foreign functions interface) layer is a glue between Lisp code and libglib, libgobject, libgthread. This code includes basic wrapper around GType designator (it is used everywhere and should be defined first) and definitions of foreign structures and imports foreign functions.

  * Low-level GObject integration. These are facilities provided by GObject that capture specific aspects of type system, object system and cross-language runtime. This includes types information, GValues (generic containers for value of any type supported by GObject type system), closures, means to create and use objects. This layer also includes some non-GObject facilities: stable pointers.

  * High-level GObject integration. This layer includes support for interoperability between CLOS and GObject and automatic generation of corresponding definitions.

Naturally, users of CL-GTK2-GObject should use the high-level GObject integration, but occasionaly it may be necessary to use lower-level functionality.

Installation
************

CL-GTK2-GObject comes as a part of CL-GTK2 bindings that are avaiable at its website.

To use the CL-GTK2-GObject, download and install CL-GTK2 bindings and load the ASDF system cl-gtk2-glib.

CL-GTK2-GObject defines two packages: gobject and gobject.ffi. The gobject.ffi package contains definitions for low-level CFFI imports. The gobject package contains symbols for external API of this GObject binding.

GType designator
****************

GObject is an object system based on GType type system. Types in it are identified by an integer value of type GType. In cl-gtk2-gobject, types are identified by GType designators. GType designator is an integer (equal to corresponding GType identifier) or a string (equal to the name of corresponding type). The important difference between GType and GType designator is that GType values may change between program runs (all GTypes except fundamental GTypes will change values), but string GType designators do not change (because names of types do not change). As such, if ever GType must be saved in a code, string GType designator should be preferred.

An example of GType designator is a string "GObject" and the numeric value 80 that corresponds to it.

Some of the types are fundamental and have constant integer values. They are identified by constants (strings in parentheses are corresponding type names):

  * +g-type-invalid+. An invalid GType used as error return value in some functions which return a GType.

  * +g-type-void+ ("void"). A fundamental type which is used as a replacement for the C void return type.

  * +g-type-interface+ ("GInterface"). The fundamental type from which all interfaces are derived.

  * +g-type-char+ ("gchar"). The fundamental type corresponding to gchar. The type designated by +g-type-char+ is unconditionally an 8-bit signed integer. This may or may not be the same type a the C type gchar.

  * +g-type-uchar+ ("guchar"). The fundamental type corresponding to guchar.

  * +g-type-boolean+ ("gboolean"). The fundamental type corresponding to gboolean.

  * +g-type-int+ ("gint"). The fundamental type corresponding to gint.

  * +g-type-uint+ ("guint"). The fundamental type corresponding to guint.

  * +g-type-long+ ("glong"). The fundamental type corresponding to glong.

  * +g-type-ulong+ ("gulong"). The fundamental type corresponding to gulong.

  * +g-type-int64+ ("gint64"). The fundamental type corresponding to gint64.

  * +g-type-uint64+ ("guint64"). The fundamental type corresponding to guint64.

  * +g-type-enum+ ("GEnum"). The fundamental type from which all enumeration types are derived.

  * +g-type-flags+ ("GFlags"). The fundamental type from which all flags types are derived.

  * +g-type-float+ ("gfloat"). The fundamental type corresponding to gfloat.

  * +g-type-double+ ("gdouble"). The fundamental type corresponding to gdouble.

  * +g-type-string+ ("gchararray"). The fundamental type corresponding to null-terminated C strings.

  * +g-type-pointer+ ("gpointer"). The fundamental type corresponding to gpointer.

  * +g-type-boxed+ ("GBoxed"). The fundamental type from which all boxed types are derived.

  * +g-type-param+ ("GParam"). The fundamental type from which all GParamSpec types are derived.

  * +g-type-object+ ("GObject"). The fundamental type for GObject.

Functions g-type-string and g-type-numeric return the numeric and string representations of GType designators (given any of them). Functions g-type= and g-type/= check types for equality.

Invalid type (the GType that does not exist) is identified as a 0 or NIL.

     (g-type-numeric "GObject") => 80
     (g-type-numeric 80) => 80
     (g-type-string "GObject") => "GObject"
     (g-type-string 80) => "GObject"
     (g-type-numeric "GtkWidget") => 6905648 ;;Will be different on each run

g-type-string
=============

(g-type-string g-type-designator) => name

G-TYPE-DESIGNATOR
     The GType designator for the GType

NAME
     The name of GType

Returns the name of GType.

g-type-numeric
==============

(g-type-numeric g-type-designator) => GType

G-TYPE-DESIGNATOR.
     The GType designator for the GType.

GTYPE
     The numeric identifier of GType

Returns the numeric identifier of GType

g-type=
=======

(g-type= type-1 type-2) => eq

TYPE-1
     A GType designator

TYPE-2
     A GType designator

EQ
     A boolean that is true if type-1 and type-2 designate the same type.

g-type/=
========

(g-type/= type-1 type-2) => eq

TYPE-1
     A GType designator

TYPE-2
     A GType designator

EQ
     A boolean that is true if type-1 and type-2 designate different types.

Type hierarchy and type relations
*********************************

GTypes are organized into hierarchy. Each GType (except fundamental types) has a parent type and zero or more children types. Parent of GType identified by g-type-parent function and its children are identified by g-type-children function.

There are functions to query some specific information:

  * g-type-fundamental retrieves the fundamental type for given type

  * g-type-depth calculates the depth of the type in type hierarchy

  * g-type-next-base calculates the first step in the path from base type to descendent type

g-type-children
===============

(g-type-children type) => children

TYPE
     A GType designator

CHILDREN
     A list of GType designators

Returns the list of descendent types.

Example:

     (g-type-children "GtkButton")
     =>
     ("GtkToggleButton" "GtkColorButton" "GtkFontButton" "GtkLinkButton" "GtkScaleButton")

g-type-parent
=============

(g-type-parent type) => parent

TYPE
     A GType designator

PARENT
     A GType designator

Returns the parent of type.

Example:

     (g-type-parent "GtkToggleButton")
     =>
     "GtkButton"

g-type-fundamental
==================

(g-type-fundamental type) => fundamental-type

TYPE
     A GType designator

FUNDAMENTAL-TYPE
     A GType designator for one of the fundamental types

Returns the fundamental type that is the ancestor of type.

Example:

     (g-type-fundamental "GtkButton") => "GObject"

     (g-type-fundamental "GtkWindowType") => "GEnum"

     (g-type-fundamental "GdkEvent") => "GBoxed"

g-type-depth
============

(g-type-depth type) => depth

TYPE
     A GType designator

DEPTH
     An integer

Returns the depth of the type. Depth is the number of types between the type and its fundamental types (including both type and its fundamental type). Depth of a fundamental type equals to 1.

Example:

     (g-type-depth "GObject") => 1
     (g-type-depth "GInitiallyUnowned") => 2

g-type-next-base
================

(g-type-next-base leaf-type root-type) => base-type

LEAF-TYPE
     A GType designator

ROOT-TYPE
     A GType designator

BASE-TYPE
     A GType designator

Returns the next type that should be traversed from root-type in order to reach leaf-type. E.g., given type hierarchy:

     + GObject
      \
       + GInitiallyUnowned
        \
         + GtkObject
         |\
         | + GtkAdjustment
          \
           + GtkWidget
            \
             + GtkContainer
              \
               + GtkTable

the following will be returned:

     (g-type-next-base "GtkTable" "GObject") => "GInitiallyUnowned"
     (g-type-next-base "GtkTable" "GInitiallyUnowned") => "GtkObject"
     (g-type-next-base "GtkTable" "GtkObject") => "GtkWidget"
     (g-type-next-base "GtkTable" "GtkWidget") => "GtkContainer"
     (g-type-next-base "GtkTable" "GtkContainer") => "GtkTable"

Object types information
************************

GObject classes and interfaces have properties that can be queried with class-properties, class-property-info and interface-properties. These functions represent information about properties with instances of g-class-property-definition structure.

Information about signals can be queries with type-signals, parse-signal-name and query-signal-info functions. Information is returned within instances of signal-info structures.

g-class-property-definition
===========================

     (defstruct g-class-property-definition
       name
       type
       readable
       writable
       constructor
       constructor-only
       owner-type)

NAME
     A string that names the property

TYPE
     A GType designator. Identifies the type of the property

READABLE
     A boolean. Identifies whether the property can be read

WRITABLE
     A boolean. Identifies whether the property can be assigned

CONSTRUCTOR
     A boolean. Identifies whether constructor of object accepts this property

CONSTRUCTOR-ONLY
     A boolean. Identifies whether this property may only be set in constructor, not in property setter

OWNER-TYPE
     A GType designator. Identifies the type on which the property was defined.

This structure identifies a single property. Its field specify attributes of a property.

Structures of this type have shortened print syntax:

     #<PROPERTY gchararray GtkButton.label (flags: readable writable constructor)>

(When *print-readably* is T, usual defstruct print syntax is used)

This syntax specifies:

  * type of property

  * the owner type of property

  * name of property

  * additional flags of property

class-properties
================

(class-properties type) => properties

TYPE
     A GType designator. Specifies the object type (class)

PROPERTIES
     A list of g-property-definition structures.

This function returns the list of properties that are available in class type.

Example:

     (class-properties "GtkWidget")
     =>
     (#<PROPERTY gpointer GtkObject.user-data (flags: readable writable)>
      #<PROPERTY gchararray GtkWidget.name (flags: readable writable)>
      #<PROPERTY GtkContainer GtkWidget.parent (flags: readable writable)>
      #<PROPERTY gint GtkWidget.width-request (flags: readable writable)>
      #<PROPERTY gint GtkWidget.height-request (flags: readable writable)>
      #<PROPERTY gboolean GtkWidget.visible (flags: readable writable)>
      #<PROPERTY gboolean GtkWidget.sensitive (flags: readable writable)>
      #<PROPERTY gboolean GtkWidget.app-paintable (flags: readable writable)>
      #<PROPERTY gboolean GtkWidget.can-focus (flags: readable writable)>
      #<PROPERTY gboolean GtkWidget.has-focus (flags: readable writable)>
      #<PROPERTY gboolean GtkWidget.is-focus (flags: readable writable)>
      #<PROPERTY gboolean GtkWidget.can-default (flags: readable writable)>
      #<PROPERTY gboolean GtkWidget.has-default (flags: readable writable)>
      #<PROPERTY gboolean GtkWidget.receives-default (flags: readable writable)>
      #<PROPERTY gboolean GtkWidget.composite-child (flags: readable)>
      #<PROPERTY GtkStyle GtkWidget.style (flags: readable writable)>
      #<PROPERTY GdkEventMask GtkWidget.events (flags: readable writable)>
      #<PROPERTY GdkExtensionMode GtkWidget.extension-events (flags: readable writable)>
      #<PROPERTY gboolean GtkWidget.no-show-all (flags: readable writable)>
      #<PROPERTY gboolean GtkWidget.has-tooltip (flags: readable writable)>
      #<PROPERTY gchararray GtkWidget.tooltip-markup (flags: readable writable)>
      #<PROPERTY gchararray GtkWidget.tooltip-text (flags: readable writable)>
      #<PROPERTY GdkWindow GtkWidget.window (flags: readable)>)

class-property-info
===================

(class-property-info type property-name) => property

TYPE
     A GType designator

PROPERTY-NAME
     A string naming the property

PROPERTY
     An instance of g-property-definition structure

Returns the property information for a single property.

Example:

     (class-property-info "GtkButton" "label")
     =>
     #<PROPERTY gchararray GtkButton.label (flags: readable writable constructor)>

interface-properties
====================

(interface-properties type) => properties

TYPE
     A GType designator

PROPERTIES
     A list of g-property-definition structures

This function returns the list of properties that are available in interface type.

Example:

     (interface-properties "GtkFileChooser")
     =>
     (#<PROPERTY GtkWidget GtkFileChooser.extra-widget (flags: readable writable)>
      #<PROPERTY gboolean GtkFileChooser.use-preview-label (flags: readable writable)>
      #<PROPERTY gboolean GtkFileChooser.preview-widget-active (flags: readable writable)>
      #<PROPERTY gboolean GtkFileChooser.show-hidden (flags: readable writable)>
      #<PROPERTY gchararray GtkFileChooser.file-system-backend (flags: writable constructor-only)>
      #<PROPERTY GtkFileChooserAction GtkFileChooser.action (flags: readable writable)>
      #<PROPERTY GtkFileFilter GtkFileChooser.filter (flags: readable writable)>
      #<PROPERTY gboolean GtkFileChooser.select-multiple (flags: readable writable)>
      #<PROPERTY GtkWidget GtkFileChooser.preview-widget (flags: readable writable)>
      #<PROPERTY gboolean GtkFileChooser.local-only (flags: readable writable)>
      #<PROPERTY gboolean GtkFileChooser.do-overwrite-confirmation (flags: readable writable)>)

signal-info
===========

     (defstruct signal-info
       id
       name
       owner-type
       flags
       return-type
       param-types
       detail)

ID
     An integer - the identifier of a signal

NAME
     Name of a signal

OWNER-TYPE
     A GType designator identifying the type on which the signal was defined

FLAGS
     A list of keywords of type '(member :run-first :run-last :run-cleanup :no-recurse :detailed :action :no-hooks). Specifies the attributes of a signals

RETURN-TYPE
     The return type of a signal (and signal handlers)

PARAM-TYPES
     A list of GType designators that specify the types of signal parameters

DETAIL
     A string. Specifies the "detail" part of a signal name. E.g., "label" for signal "notify::label".

When *print-readably* is nil, the following print syntax is used:

     #<Signal [#1] void GObject.notify::label(GParam) [RUN-FIRST, NO-RECURSE, DETAILED, ACTION, NO-HOOKS]>
     #<Signal [#54] gboolean GtkWidget.proximity-in-event(GdkEvent) [RUN-LAST]>
     #<Signal [#64] void GtkWidget.drag-data-received(GdkDragContext, gint, gint, GtkSelectionData, guint, guint) [RUN-LAST]>
     #<Signal [#8] void GtkObject.destroy() [RUN-CLEANUP, NO-RECURSE, NO-HOOKS]>

This syntax specifies:

  * the signal id

  * signal return type

  * owner type

  * signal name

  * detail

  * list of types of parameters

  * flags

type-signals
============

(type-signals type &key (include-inherited t)) => signals

TYPE
     A GType designator

SIGNALS
     A list of signal-info structures

INCLUDE-INHERITED
     A boolean that specifies whether to include signals defined on this type or also on ancestor types.

Returns the list of signals that are available in type type.

Example:

     (type-signals "GtkLabel" :include-inherited nil)
     =>
     (#<Signal [#138] void GtkLabel.move-cursor(GtkMovementStep, gint, gboolean) [RUN-LAST, ACTION]>
      #<Signal [#139] void GtkLabel.copy-clipboard() [RUN-LAST, ACTION]>
      #<Signal [#140] void GtkLabel.populate-popup(GtkMenu) [RUN-LAST]>)

parse-signal-name
=================

(parse-signal-name type signal-name) => signal

TYPE
     A GType designator that has the signal.

SIGNAL-NAME
     A string that identifies the signal.

SIGNAL
     A list signal-info structures.

Parses the signal name and returns the corresponding information. signal-name may include the detail part.

Example:

     (parse-signal-name "GObject" "notify::label")
     =>
     #<Signal [#1] void GObject.notify::label(GParam) [RUN-FIRST, NO-RECURSE, DETAILED, ACTION, NO-HOOKS]>

query-signal-info
=================

(query-signal-info signal-id) => signal

SIGNAL-ID
     An integer identifying the signal

SIGNAL
     An instance of signal-info structure

Retrieves the signal information by its id.

Example:

     (query-signal-info 73)
     =>
     #<Signal [#73] gboolean GtkWidget.show-help(GtkWidgetHelpType) [RUN-LAST, ACTION]>

g-type-interfaces
=================

(g-type-interfaces type) => interfaces

TYPE
     A GType designator

INTERFACES
     A list of GType designators

Returns the list of interfaces that type implements.

Example:

     (g-type-interfaces "GtkButton")
     =>
     ("AtkImplementorIface" "GtkBuildable" "GtkActivatable")

g-type-interface-prerequisites
==============================

(g-type-interface-prerequisites type) => types

TYPE
     A GType designator of interface

TYPES
     A list of GType designators specifying the interface prerequisites

Returns the prerequisites of an interface type. Prerequisite is a type that should be an ancestor of a type implementing interface type.

Example:

     (g-type-interface-prerequisites "GtkCellEditable")
     =>
     ("GtkObject" "GtkWidget")

Enum types information
**********************

Enum types have items that can be listed with get-enum-items function. This information is exposed within instances of enum-item structure.

Flags types (flags is a kind of enum whose values can be combined) have items that can be queried with get-flags-items function. This information is exposed within instances of flags-item structure.

enum-item
=========

     (defstruct enum-item
       name value nick)

NAME
     A string - name of enum item

VALUE
     An integer - numeric value of enum item

NICK
     A string - short name of an enum item

Structure enum-item represents a single item of an enumeration type.

Example:

     #S(ENUM-ITEM :NAME "GTK_WINDOW_TOPLEVEL" :VALUE 0 :NICK "toplevel")

flags-item
==========

     (defstruct flags-item
       name value nick)

NAME
     A string - name of flags item

VALUE
     An integer - numeric value of flags item

NICK
     A string - short name of an flags item

Structure flags-item represents a single item of an flags type.

Example:

     #S(FLAGS-ITEM
        :NAME "GDK_POINTER_MOTION_HINT_MASK"
        :VALUE 8
        :NICK "pointer-motion-hint-mask")

get-enum-items
==============

(get-enum-items type) => items

TYPE
     A GType designator of an enum type

ITEMS
     A list of enum-item structures

Returns a list of items in an enumeration

Example:

     (get-enum-items "GtkScrollType")
     =>
     (#S(ENUM-ITEM :NAME "GTK_SCROLL_NONE" :VALUE 0 :NICK "none")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_JUMP" :VALUE 1 :NICK "jump")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_STEP_BACKWARD" :VALUE 2 :NICK "step-backward")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_STEP_FORWARD" :VALUE 3 :NICK "step-forward")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_PAGE_BACKWARD" :VALUE 4 :NICK "page-backward")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_PAGE_FORWARD" :VALUE 5 :NICK "page-forward")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_STEP_UP" :VALUE 6 :NICK "step-up")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_STEP_DOWN" :VALUE 7 :NICK "step-down")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_PAGE_UP" :VALUE 8 :NICK "page-up")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_PAGE_DOWN" :VALUE 9 :NICK "page-down")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_STEP_LEFT" :VALUE 10 :NICK "step-left")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_STEP_RIGHT" :VALUE 11 :NICK "step-right")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_PAGE_LEFT" :VALUE 12 :NICK "page-left")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_PAGE_RIGHT" :VALUE 13 :NICK "page-right")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_START" :VALUE 14 :NICK "start")
      #S(ENUM-ITEM :NAME "GTK_SCROLL_END" :VALUE 15 :NICK "end"))

get-flags-items
===============

(get-flags-items type) => items

TYPE
     A GType designator of an flags type

ITEMS
     A list of flags-item structures

Returns a list of items in an flags type

Example:

     (get-flags-items "GtkAttachOptions")
     =>
     (#S(FLAGS-ITEM :NAME "GTK_EXPAND" :VALUE 1 :NICK "expand")
      #S(FLAGS-ITEM :NAME "GTK_SHRINK" :VALUE 2 :NICK "shrink")
      #S(FLAGS-ITEM :NAME "GTK_FILL" :VALUE 4 :NICK "fill"))

Using GValues
*************

GValue is a generic container for arbitrary value of type supported by GType system. Refer to GObject documentation for more detailed information.

CL-GTK2-GOBJECT works with GValue as a foreign type g-value. Functions g-value-zero, g-value-type, g-value-init, parse-g-value, set-g-value are used to inspect and assign GValues. g-value is a CFFI foreign type that is used by all these functions. Pointer to foreign instance of this type is passed to them.

GValue is used whenever a value of unkown type should be passed. It is used in:

  * Closure marshal functions

  * Property get and set functions

Example of usage:

     (cffi:with-foreign-object (gval 'g-value)
       (set-g-value gval "Hello" "gchararray" :zero-g-value t)
       (format t "~S~%" (parse-g-value gval))
       (g-value-unset gval))
     =>
     "Hello"

g-value-zero
============

(g-value-zero g-value)

G-VALUE
     A foreign pointer to GValue structure.

Initializes the GValue to "unset" state. Equivalent of the following initializer in C:

     GValue value = { 0 };

Must be called before other functions that work with GValue (except set-g-value with keyword argument :zero-g-value set to true).

g-value-init
============

(g-value-init value type)

VALUE
     A foreign pointer to GValue structure

TYPE
     A GType designator

Initializes the GValue to store instances of type type. Must be called before other functions operate on GValue (except g-value-zero and set-g-value with keyword argument :g-value-init set to true).

g-value-unset
=============

(g-value-unset value)

VALUE
     A foreign pointer to GValue structure.

Unsets the GValue. This frees all resources associated with GValue.

parse-g-value
=============

(parse-g-value value) => object

VALUE
     A foreign pointer to GValue structure

OBJECT
     A Lisp object

Retrieves the object from GValue structure.

set-g-value
===========

(set-g-value gvalue object type &key zero-g-value unset-g-value (g-value-init t))

GVALUE
     A foreign pointer to GValue structure

OBJECT
     An object that is to be assigned to gvalue

TYPE
     A GType designator specifying what GType should be set

UNSET-G-VALUE
     A boolean specifying whether to call g-value-unset before assigment.

ZERO-G-VALUE
     A boolean specifying whether to call g-value-zero before assignment

G-VALUE-INIT
     A boolean specifying whether to call g-value-init before assignment

Assigns the object to the gvalue. When GValue is not used, call g-value-unset to deinitialize the GValue.

Registering types
=================

In order to be able to parse GValues and set them, it is necessary for GValue binding to know type mapping between GObject types and Lisp types. Type registration serves to this purpose.

GEnum and GFlags are mapped to CFFI defcenum and defbitfield types. Functions register-enum-type and register-flags-type add the type to the mapping.

(register-enum-type name type)

NAME
     A string naming the GEnum type

TYPE
     A symbol - name of CFFI foreign enum type

Registers the type to be used for passing value of GEnum type name between GObject and Lisp.

Example:

     (defcenum text-direction
       :none :ltr :rtl)
     (register-enum-type "GtkTextDirection" 'text-direction)

(register-flags-type name type)

NAME
     A string naming the GFlags type

TYPE
     A symbol - name of CFFI foreign flags type

Registers the type to be used for passing value of GFlags type name between GObject and Lisp.

Example:

     (defcenum state-type
       :normal :active :prelight :selected :insensitive)
     (register-enum-type "GtkStateType" 'state-type)

Stable pointers
***************

Sometimes it is necessary to pass arbitrary Lisp object to C code and then receive it back. Stable pointer serve to this purpose. Stable pointer is an integer (that is passed to C code as a void* pointer) that is created on Lisp side by call to allocate-stable-pointer and can be dereferenced by Lisp side at any time by calling stable-pointer-value. Stable pointer exists and does not change its value until explicitly freed by calling free-stable-poitner. Convenience macro with-stable-pointer binds the stable pointer for the duration of its body.

allocate-stable-pointer
=======================

(allocate-stable-pointer thing) => stable-pointer

THING
     An arbitrary Lisp object

STABLE-POINTER
     A foreign pointer

Allocates a stable pointer to thing.

(Note: STABLE-POINTER should not be dereferenced with cffi:mem-ref. It should only be dereferenced with stable-pointer-value)

Example:

     (allocate-stable-pointer (lambda (x) (+ x 10)))
     =>
     #.(SB-SYS:INT-SAP #X00000002)

     (stable-pointer-value *)
     =>
     #<FUNCTION (LAMBDA (X)) {1004D016F9}>

     (free-stable-pointer **)
     =>
     NIL

free-stable-pointer
===================

(free-stable-pointer stable-pointer)

STABLE-POINTER
     A foreign pointer that was created with allocate-stable-pointer.

Frees the stable pointer, enabling the garbage collector to reclaim the object.

Example:

     (allocate-stable-pointer (lambda (x) (+ x 10)))
     =>
     #.(SB-SYS:INT-SAP #X00000002)

     (stable-pointer-value *)
     =>
     #<FUNCTION (LAMBDA (X)) {1004D016F9}>

     (free-stable-pointer **)
     =>
     NIL

stable-pointer-value
====================

     (stable-pointer-value stable-pointer) => thing
     (setf (stable-pointer-value stable-pointer) thing)

STABLE-POINTER
     A foreign pointer created by allocate-stable-pointer

THING
     A Lisp object

Dereferences a stable-pointer, returning the stable pointer value. stable-pointer-value is a SETFable form, SETFing it sets the stable pointer's value to new value.

with-stable-pointer
===================

(with-stable-pointer (ptr expr) &body body)

PTR
     A variable that will be bound to the stable pointer

EXPR
     An expression that will be evaluated once and its value will be bound to stable pointer's value

Executes the body with the ptr variable being bound to a stable pointer whose value is determined by expr.

Example:

     (with-stable-pointer (ptr (lambda (x) (+ x 10)))
       (print (stable-pointer-value ptr)))
     ;;Prints:
     #<FUNCTION (LAMBDA (X)) {1004807E79}>

Closures
********

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 create-g-closure create closure from lisp function. The GClosure is finalized automatically when GObject no longer needs it (e.g., when GClosure is disconnected from signal).

create-g-closure
================

(create-g-closure fn) => closure

FN
     A function that will be called by closure invokation

CLOSURE
     A foreign pointer to allocated closure

Allocates the closure. The closure is destroyed automatically by GObject.

Example:

     (create-g-closure (lambda (x) (+ x 10)))
     =>
     #.(SB-SYS:INT-SAP #X006D7B20)

Example of usage from GObject binding code:

     (defun connect-signal (object signal handler &key after)
       (g-signal-connect-closure (ensure-object-pointer object)
                                 signal
                                 (create-g-closure handler)
                                 after))

(TODO: GObject defines finer closure API: g_closure_ref, g_closure_unref, g_closure_invoke. It should be bound.)

GObject low-level
*****************

GObject low-level support includes facilities for working with objects as foreign pointers and using explicit function to get and set properties. This low-level support does not deal with integration of GObject with CLOS; GObject high-level support does that.

Function g-type-from-object identifies the type of the object. Function g-object-call-get-property retrieves the value of the property and function g-object-call-set-property sets the value of the property. Function g-object-call-constructor calls the constructor of the GObject type.

g-object-call-constructor
=========================

(g-object-call-constructor object-type args-names args-values &optional args-types) => object-ptr

OBJECT-TYPE
     A GType designator that specifies the object type that is to be created

ARGS-NAMES
     A list of strings naming the arguments to constructor

ARGS-VALUE
     A list of arguments values (in the same order as args-names)

ARGS-TYPES
     Optional list of arguments types (in the same order as args-names). If not specified, it is detected automatically

OBJECT-PTR
     A foreign pointer to newly created instance

Creates the object of type object-type by calling its constructors with arguments specified by args-names, args-values, args-types.

Example:

     (g-object-call-constructor "GtkButton" '("label" "use-underline") '("Hello" t) '("gchararray" "gboolean"))
     =>
     #.(SB-SYS:INT-SAP #X006D8900)

     (g-object-call-get-property * "label")
     =>
     "Hello"

     (g-object-call-get-property ** "use-underline")
     =>
     T

g-type-from-object
==================

(g-type-from-object object-ptr) => type

OBJECT-PTR
     A foreign pointer to a GObject instance

TYPE
     A GType designator

Returns the type of an object by a pointer to its instance

Example:

     (g-type-from-object (g-object-call-constructor "GtkButton" nil nil))
     =>
     "GtkButton"

g-object-call-get-property
==========================

(g-object-call-get-property object-ptr property-name &optional property-type) => property-value

OBJECT-PTR
     A foreign pointer to a GObject instance

PROPERTY-NAME
     A string naming the property

PROPERTY-TYPE
     Optional GType designator specifying the type of a property

PROPERTY-VALUE
     The value of a property

Retrieves the value of a property property-name of object pointed to by object-ptr. property-type specifies the type of a property; it may be omitted.

Example:

     (g-object-call-constructor "GtkButton" '("label" "use-underline") '("Hello" t) '("gchararray" "gboolean"))
     =>
     #.(SB-SYS:INT-SAP #X006D8900)

     (g-object-call-get-property * "label")
     =>
     "Hello"

     (g-object-call-get-property ** "use-underline")
     =>
     T

g-object-call-set-property
==========================

(g-object-call-set-property object-ptr property-name new-value &optional property-type)

OBJECT-PTR
     A foreign pointer to a GObject instance

PROPERTY-NAME
     A string naming the property

NEW-VALUE
     A new value of a property

PROPERTY-TYPE
     Optional GType designator specifying the type of a property

Sets the property value of property property-name of object object-ptr to new-value.

Example:

     (g-object-call-constructor "GtkButton" nil nil)
     =>
     #.(SB-SYS:INT-SAP #X006D8B40)

     (g-object-call-set-property * "label" "Hello")
     =>
     ; No value

     (g-object-call-get-property ** "label")
     =>
     "Hello"

GObject high-level
******************

GObject high-level support includes integration of GObject and CLOS systems. This enables to use GObjects classes as CLOS classes (with support from gobject-class metaclass):

  * objects are created with make-instance

  * properties are used as regular slots

GObjects are reference counted, and CL-GTK2-GOBJECT manages its own reference to GObjects. This enables to have transparent garbage collection of unreferenced GObjects.

To be able to use particular GObject class with CLOS, it should be defined and registered. This is accomplished by defclass'ing it with gobject-class metaclass. After GObject class is defined, it may be used as CLOS class.

Example GObject class of definition:

     (defclass dialog (gtk-window atk-implementor-iface buildable)
       ((has-separator :accessor dialog-has-separator
                       :initarg :has-separator
                       :allocation :gobject-property
                       :g-property-type "gboolean"
                       :g-property-name "has-separator"))
       (:metaclass gobject-class)
       (:g-type-name . "GtkDialog")
       (:g-type-initializer . "gtk_dialog_get_type"))

This example defines the CLOS class dialog that corresponds to GObject class GtkDialog. Whenever object of GObject type GtkDialog are to be received from foreign functions or passed to foreign functions, it will be mapped to CLOS class dialog. Properties that have :allocation of :gobject-property are mapped to GObject properties, and reading or writing this slot reads or writes corresponding GObject class property.

GObject does not expose objects methods. Because of this, methods are not automatically mapped to CLOS generic functions and methods. Methods should be manually wrapped with CFFI as foreign functions. Foreign type g-object aids in it. This type automatically wraps (and unwraps) the GObject class instances and handles the reference counting.

GObject high-level support enables connect signals to signal handlers. Any function may be connected as a signal handler, and GObject will release the reference on signal handler whenever it become unneded (e.g., when object is destroyed or handler is disconnected).

GObject metaclass
=================

See MOP for information what metaclass is and why is it useful.

GObject metaclass gobject-class bridges two object systems: GObject and CLOS.

Classes that correspond to GObject classes are instances of this class.

Defining the class with metaclass gobject-class registers the type :g-type-name for conversions using GValue and CFFI foreign type g-object.

This class has the following slots:

  * G-TYPE-NAME (accessor gobject-class-g-type-name, initarg :g-type-name)

     Specifies the name of GObject class

  * G-TYPE-INITIALIZER (accessor gobject-class-g-type-initializer, initarg :g-type-initializer)

     Name of type initializer function. This function initializes the class and returns its GType. Typically it is named class_get_type.

  * INTERFACE-P (accessor gobject-class-interface-p, initarg :interface-p)

     A boolean specifying whether this CLOS class corresponds to GInterface.

This metaclass defines the GObject classes.

Slots which have :allocation of :gobject-property are mapped to GObject properties. Such slots have following attributes:

  * :G-PROPERTY-TYPE

     A string naming GType of property

  * :G-PROPERTY-NAME

     A name of a property

Slots which have :allocation of :gobject-fn are mapped to a pair of accessor functions (usually named class_get_property and class_set_property). This is included because some properties are not exposed as GObject properties. Such slots have following attributes:

  * :G-PROPERTY-TYPE A CFFI foreign type of property

  * :G-GETTER A string naming foreign getter function of a property or a symbol designating Lisp getter function. Foreign getter function should have signature type class_get_property(object *). Lisp function should be of type (function (class) type).

  * :G-SETTER A string naming foreign setter function of a property or a symbol designating Lisp setter function. Foreign setter function should have signature void class_set_property(object *, type). Lisp function should be of type (function (class type)).

Initargs of a slot are used to construct the GObject class.

Example:

     (defclass container (widget atk-implementor-iface buildable)
         ((border-width :allocation :gobject-property
                        :g-property-type "guint"
                        :accessor container-border-width
                        :initarg :border-width
                        :g-property-name "border-width")
          (resize-mode :allocation :gobject-property
                       :g-property-type "GtkResizeMode"
                       :accessor container-resize-mode
                       :initarg :resize-mode
                       :g-property-name "resize-mode")
          (child :allocation :gobject-property
                 :g-property-type "GtkWidget"
                 :accessor container-child
                 :initarg :child
                 :g-property-name "child")
          (focus-child :allocation :gobject-fn
                       :g-property-type g-object
                       :accessor container-focus-child
                       :initarg :focus-child
                       :g-getter "gtk_container_get_focus_child"
                       :g-setter "gtk_container_set_focus_child")
          (focus-vadjustment :allocation :gobject-fn
                             :g-property-type (g-object adjustment)
                             :accessor container-focus-vadjustment
                             :initarg :focus-vadjustment
                             :g-getter "gtk_container_get_focus_vadjustment"
                             :g-setter "gtk_container_set_focus_vadjustment")
          (focus-hadjustment :allocation :gobject-fn
                             :g-property-type (g-object adjustment)
                             :accessor container-focus-hadjustment
                             :initarg :focus-hadjustment
                             :g-getter "gtk_container_get_focus_hadjustment"
                             :g-setter "gtk_container_set_focus_hadjustment"))
         (:metaclass gobject-class)
         (:g-type-name . "GtkContainer")
         (:g-type-initializer . "gtk_container_get_type"))

(note the dot in (:g-type-name . "GtkContainer") and in (:g-type-initializer . "gtk_container_get_type"). It should be present)

Using objects
=============

Instances are created with make-instance. If initargs of GObject properties are supplied, they are passed to constructor. Some slots (properties) may only be set at construction time (e.g., type property of GtkWindow). Properties may be accessed (read or assigned) with defined :accessor, :reader or :writer functions.

Example:

     (make-instance 'gtk:dialog :has-separator t)
     =>
     #<GTK:DIALOG {10036C5A71}>

     (defvar *d* (make-instance 'gtk:dialog :has-separator t))
     =>
     *D*

     (gtk:dialog-has-separator *d*)
     =>
     T

     (setf (gtk:dialog-has-separator *d*) nil)
     =>
     NIL

     (gtk:dialog-has-separator *d*)
     =>
     NIL

Signals
=======

To connect handler to a signal, connect-signal function is used.

(connect-signal object signal handler &key after)

OBJECT
     An instance of GObject object

SIGNAL
     A signal name

HANDLER
     A function

AFTER
     A boolean specifying whether the handler should be called after the default handler

Connects the handler to signal signal on object object. Signature of handler should comply with signature of a signal. handler will be called with arguments of type specified by signal with the object (on which the signal was emitted) prepended to them and it should return the value of the signal's return type.

Example:

     (defvar *d* (make-instance 'gtk:dialog))
     =>
     *D*

     *d*
     =>
     #<GTK:DIALOG {1002D866F1}>

     (parse-signal-name "GtkDialog" "response")
     =>
     #<Signal [#86] void GtkDialog.response(gint) [RUN-LAST]>

     (connect-signal *d* "response" (lambda (dialog response-value) (print dialog) (print response-value)))

     (emit-signal *d* "response" 14)
     =>
     ;; Prints:
     #<GTK:DIALOG {1002D866F1}>
     14

Function emit-signal is used to emit signals on objects.

(emit-signal object signal-name &rest args) => return-value

OBJECT
     An object on which the signal should be emitted

SIGNAL-NAME
     A string naming the signal

ARGS
     Arguments for a signal

RETURN-VALUE
     Return value of a signal

Emits the signal and calls all handlers of the signal. If signal returns a value, it is returned from emit-signal.

Example:

     (defvar *d* (make-instance 'gtk:dialog))
     =>
     *D*

     *d*
     =>
     #<GTK:DIALOG {1002D866F1}>

     (parse-signal-name "GtkDialog" "response")
     =>
     #<Signal [#86] void GtkDialog.response(gint) [RUN-LAST]>

     (connect-signal *d* "response" (lambda (dialog response-value) (print dialog) (print response-value)))

     (emit-signal *d* "response" 14)
     =>
     ;; Prints:
     #<GTK:DIALOG {1002D866F1}>
     14

GObject foreign class
=====================

To enable passing GObject instance between Lisp code and foreign code, g-object foreign type is introduced.

This type has the following syntax: (g-object &optional type) or g-object.

When the g-object foreign type is specified as a return type of a function, the value is converted to instance of corresponding CLOS class. If type is specified then it is checked that object is of this type.

When the g-object foreign type is specified as a type of function's argument, the value is converted to pointer to GObject. If type is specified then it is checked that the object is of this type.

This defines the function that may be called with instances of types container and widget:

     (defcfun (container-add "gtk_container_add") :void
       (container (g-object container))
       (widget (g-object widget)))

     (let ((window (make-instance 'gtk-window))
           (widget (make-instance 'button)))
       (container-add window widget))

(gtk-window is a subclass of container; button is a subclass of widget)

This defines the function that returns an instance of GObject class:

     (defcfun (bin-child "gtk_bin_get_child") (g-object widget)
       (bin (g-object bin)))

     (let ((window (make-instance 'gtk-window))
           (widget (make-instance 'button)))
       (container-add window widget)
       (bin-child window))
     =>
     #<GTK:BUTTON {1002DE74B1}>

Subclassing GObjects and implementing GInterfaces
*************************************************

GBoxed
******

GObject manual defines this type in the following way:

``GBoxed is a generic wrapper mechanism for arbitrary C structures. The only thing the type system needs to know about the structures is how to copy and free them, beyond that they are treated as opaque chunks of memory.

Boxed types are useful for simple value-holder structures like rectangles or points. They can also be used for wrapping structures defined in non-GObject based libraries.''

Naturally, it is quite hard to provide support for such structures. At the moment, support for GBoxed is pretty bad.

Basically, two use cases of GBoxed structures are provided:

  * structure is mapped to Lisp structure defined with defstruct. This is complex scenario and it supports inheritance between structure. Its main use is to define the GdkEvent structure wrapper. Macro define-g-boxed-class supports this use case.

  * structure is mapped to Lisp wrapper that contains pointer to structure and provides accessor functions (by calling foreign function or calling Lisp function). Macro define-g-boxed-ref supports this use case.

In both scenarios, foreign functions and GValue type registrations are provided that provide wrapping and unwrapping behaivour (it yet remains to be proven that the behaviour is correct in all cases with regard to issues of memory management, ownership, lifetime). In both cases it is possible to pass the structure by reference, allowing the foreign function (or the callback code) to change the contents of GBoxed.

It is expected that the support for GBoxed structures will be improved.

define-g-boxed-class
====================

     (define-g-boxed-class g-name-and-c-name name (&optional superclass-and-dispatch (export t))
       &body slot*)

     g-name-and-c-name ::= nil
     g-name-and-c-name ::= (g-name c-name)
     superclass-and-dispatch ::= (&optional superclass dispatch-slot dispatch-values)
     slot ::= slot-name slot-type &key initform parser unparser

G-NAME
     A string naming the type of this GBoxed; for inherited classes, it should be NIL

C-NAME
     A symbol naming the generated CFFI foreign structure definition corresponding to this GBoxed. This name should not conflict with other CFFI types.

NAME
     A symbol naming the Lisp structure that will be generated

SUPERCLASS
     A symbol naming the structure defined with define-g-boxed-class that is the superclass of this structure

DISPATCH-SLOT
     A slot of the superclass structure that identifies the specific type of structure (``discriminator'')

DISPATCH-VALUES
     A value or a list of values of the dispatch-slot that correspond to this GBoxed class

SLOT-NAME
     Name of a slot

SLOT-TYPE
     CFFI foreign type of a slot

INITFORM
     An optional initform for defstruct slot

PARSER
     An optional parser function designator for slot. Parser function is called to get the value for slot when the GBoxed is passed to Lisp with the following arguments: (name pointer) where the name is the name of a structure being defined and the pointer is a foreign pointer to the C structure.

UNPARSER
     An optional unparser function designator for a slot. Unparser function is called to write the slot value to GBoxed structure. It is called with arguments (name pointer object) where name is the name of a structure being defined, pointer is the pointer to the C structure and the object is object whose slot value should be written to structure.

Defines the defstruct wrapper for GBoxed type. Various parameters control how the structure is converted between C and Lisp representations.

define-g-boxed-class supports basic single inheritance. This is provided to support ``generic'' C structures like GdkEvent that contain a ``type'' field and a union of other substructures. The natural mapping of such structure to Lisp is not one, but several structures that are inherited one from another. This supports e.g. method dispatching on GdkEvent types (if it is ever necessary).

The only use of define-g-boxed-class that involves inheritance is the GdkEvent structure. It is defined as follows.

     (define-g-boxed-class ("GdkEvent" event-struct) event ()
       (type event-type)
       (window (g-object gdk-window))
       (send-event (:boolean :int8)))

     (define-g-boxed-class nil event-key ((event type (:key-press :key-release)))
       (time :uint32)
       (state modifier-type)
       (keyval :uint)
       (length :int)
       (string (:string :free-from-foreign nil :free-to-foreign nil))
       (hardware-keycode :uint16)
       (group :uint8)
       (is-modifier :uint))

     (define-g-boxed-class nil event-button ((event type (:button-press :2button-press :3button-press :button-release)))
       (time :uint32)
       (x :double)
       (y :double)
       (axes (fixed-array :double 2))
       (state :uint)
       (button :uint)
       (device (g-object device))
       (x-root :double)
       (y-root :double))

Some simpler uses include following examples:

     (define-g-boxed-class "GdkFont" font ()
       (type font-type :initform :font)
       (ascent :int :initform 0)
       (descent :int :initform 0))

     (define-g-boxed-class "GdkColor" color ()
       (pixel :uint32 :initform 0)
       (red :uint16 :initform 0)
       (green :uint16 :initform 0)
       (blue :uint16 :initform 0))

     (define-g-boxed-class "GdkGeometry" geometry ()
       (min-width :int :initform 0)
       (min-height :int :initform 0)
       (max-width :int :initform 0)
       (max-height :int :initform 0)
       (base-width :int :initform 0)
       (base-height :int :initform 0)
       (width-increment :int :initform 0)
       (height-increment :int :initform 0)
       (min-aspect :double :initform 0.0d0)
       (max-aspect :double :initform 0.0d0)
       (gravity gravity :initform :north-west))

define-g-boxed-ref
==================

g-boxed-ref class is defined:

     (defclass g-boxed-ref ()
       ((pointer :accessor pointer :initarg :pointer)))

This class holds the pointer to structure. GBoxed-ref types are subclasses of this class.

     (define-g-boxed-ref g-name name
       &rest property*)

     property ::= (:free-function free-function)
     property ::= (:alloc-function alloc-function)
     property ::= (:slots &rest slot*)
     slot ::= (slot-name &key reader writer type (accessor slot-name))

G-NAME
     A string that names the GBoxed type

NAME
     A symbol that is the name for generated class

FREE-FUNCTION
     Mandatory designator for a function that frees the allocated object. This function accepts a single argument - CFFI foreign pointer.

ALLOC-FUNCTION
     Mandatory designator for a function that allocates the object. This function accepts zero arguments and returns CFFI foreign pointer to fresh object.

SLOT-NAME
     A symbol naming the slot

TYPE
     A CFFI foreign type of a slot

READER
     NIL or a string or a function designator. If it is NIL the the slot is not readable. If it is a string then it names the C function that accepts the pointer to structure and returns the value of a slot of specified CFFI type. If it is a function designator that it designates a function that accepts the Lisp object and returns its slot value.

WRITER
     NIL or string or a function designator. If it is a NIL then the slot is not writable. If it is a string then it names the C function that accepts the pointer to C structure and a value (of specified CFFI type) and assigns it to the slot of a structure. If it is a function designator then it specifies a function that accepts the new slot value and a Lisp object and assigns it to the slot.

ACCESSOR
     A symbol namin the accessor function for slot.

Defines a class corresponding to GBoxed type that is passed by reference (e.g., GtkTextIter). Class is made a subclass of g-boxed-ref.

The memory occupied by this class is managed automatically: after the GC collects the Lisp instance, free-function is used to free the structure.

Example:

     (defcstruct tree-iter
       (stamp :int)
       (user-data :pointer)
       (user-data-2 :pointer)
       (user-data-3 :pointer))

     (defun tree-iter-get-stamp (i) (foreign-slot-value (pointer i) 'tree-iter 'stamp))
     (defun tree-iter-set-stamp (value i) (setf (foreign-slot-value (pointer i) 'tree-iter 'stamp) value))
     (defun tree-iter-get-user-data (i) (pointer-address (foreign-slot-value (pointer i) 'tree-iter 'user-data)))
     (defun tree-iter-set-user-data (value i) (setf (foreign-slot-value (pointer i) 'tree-iter 'user-data) (make-pointer value)))

     (defun tree-iter-alloc () (glib:g-malloc (foreign-type-size 'tree-iter)))
     (defun tree-iter-free (v) (glib:g-free v))

     (define-g-boxed-ref "GtkTreeIter" tree-iter
       (:slots (stamp :reader tree-iter-get-stamp :writer tree-iter-set-stamp :accessor tree-iter-stamp)
               (user-data :reader tree-iter-get-user-data :writer tree-iter-set-user-data :accessor tree-iter-user-data))
       (:alloc-function tree-iter-alloc)
       (:free-function tree-iter-free))

Another example:

     (define-foreign-type unichar ()
       ()
       (:actual-type :uint32)
       (:simple-parser unichar))

     (defmethod translate-from-foreign (value (type unichar))
       (code-char value))

     (defmethod translate-to-foreign (value (type unichar))
       (char-code value))

     (define-g-boxed-ref "GtkTextIter" text-iter
       (:free-function gtk-text-iter-free)
       (:alloc-function gtk-text-iter-alloc)
       (:slots (text-iter-buffer :reader "gtk_text_iter_get_buffer" :type (g-object text-buffer))
               (text-iter-offset :reader "gtk_text_iter_get_offset" :writer "gtk_text_iter_set_offset" :type :int)
               (text-iter-line :reader "gtk_text_iter_get_line" :writer "gtk_text_iter_set_line" :type :int)
               (text-iter-line-offset :reader "gtk_text_iter_get_line_offset" :writer "gtk_text_iter_set_line_offset" :type :int)
               (text-iter-visible-line-offset :reader "gtk_text_iter_get_visible_line_offset" :writer "gtk_text_iter_set_visible_line_offset" :type :int)
               (text-iter-char :reader "gtk_text_iter_get_char" :type unichar)
               (text-iter-pixbuf :reader "gtk_text_iter_get_pixbuf" :type (g-object pixbuf))
               (text-iter-marks :reader "gtk_text_iter_get_marks" :type (gslist (g-object text-mark) :free-from-foreign t))
               (text-iter-child-anchor :reader "gtk_text_iter_get_child_anchor" :type (g-object text-child-anchor))
               (text-iter-tags :reader "gtk_text_iter_get_tags" :type (gslist (g-object text-tag) :free-from-foreign t))
               (text-iter-chars-in-line :reader "gtk_text_iter_get_chars_in_line" :type :int)
               (text-iter-language :reader "gtk_text_iter_get_language" :type :pointer)
               (text-iter-is-end :reader "gtk_text_iter_is_end" :type :boolean)
               (text-iter-is-start :reader "gtk_text_iter_is_start" :type :boolean)
               (text-iter-can-insert :reader "gtk_text_iter_can_insert" :type :boolean)
               (text-iter-starts-word :reader "gtk_text_iter_starts_word" :type :boolean)
               (text-iter-ends-word :reader "gtk_text_iter_ends_word" :type :boolean)
               (text-iter-inside-word :reader "gtk_text_iter_inside_word" :type :boolean)
               (text-iter-starts-line :reader "gtk_text_iter_starts_line" :type :boolean)
               (text-iter-ends-line :reader "gtk_text_iter_ends_line" :type :boolean)
               (text-iter-starts-sentence :reader "gtk_text_iter_starts_sentence" :type :boolean)
               (text-iter-ends-sentence :reader "gtk_text_iter_ends_sentence" :type :boolean)
               (text-iter-inside-sentence :reader "gtk_text_iter_inside_sentence" :type :boolean)
               (text-iter-is-cursor-position :reader "gtk_text_iter_is_cursor_position" :type :boolean)))

     (defcstruct %text-iter
       (dummy1 :pointer)
       (dummy2 :pointer)
       (dummy3 :int)
       (dummy4 :int)
       (dummy5 :int)
       (dummy6 :int)
       (dummy7 :int)
       (dummy8 :int)
       (dummy9 :pointer)
       (dummy10 :pointer)
       (dummy11 :int)
       (dummy12 :int)
       (dummy13 :int)
       (dummy14 :pointer))

     (defcfun gtk-text-iter-copy :pointer
       (iter :pointer))

     (defcfun gtk-text-iter-free :void
       (iter :pointer))

     (defun gtk-text-iter-alloc ()
       (with-foreign-object (iter '%text-iter)
         (gtk-text-iter-copy iter)))

Generating type definitions by introspection
********************************************

CL-GTK2-GOBJECT includes facilities for automatically generating parts of bindings for libraries that use GObject type system.

define-g-object-class
=====================

     (define-g-object-class g-type-name name
       (&key (superclass 'g-object) (export t) interfaces type-initializer)
       (&rest property*))

     property ::= (name accessor gname type readable writable)
     property ::= (:cffi name acessor type reader writer)

Parameters of define-g-object-class

SUPERCLASS
     A symbol naming the superclass of this class

EXPORT
     Whether to export the name of the class and names of autogenerated properties names from the current package.

INTERFACES
     A list of interfaces the this class implements

TYPE-INITIALIZER
     A string naming the type initiliazer function. It is usually named class_get_type.

PROPERTIES
     A list of slots of a class

Parameters of property:

NAME
     A symbol naming the slot

ACCESSOR
     A symbol naming the accessor function for this slot

GNAME
     A string naming the property of GObject

TYPE
     A string naming the type of property of GObject (for GObject properties); or a symbol naming CFFI foreign type (for slots mapped to foreign accessors)

READABLE
     A boolean specifying whether the slot can be read

WRITABLE
     A boolean specifying whether the slot can be assigned to

READER
     A string or a symbol naming getter function. See description of gobject-class metaclass for information.

WRITTER
     A string or a symbol naming setter function. See description of gobject-class metaclass for information.

Macro that expands to defclass for specified class. Additionally, if export is true, it exports accessor names and name of a class.

Example:

     (define-g-object-class "GtkContainer" container
       (:superclass widget :export t :interfaces
                    ("AtkImplementorIface" "GtkBuildable")
                    :type-initializer "gtk_container_get_type")
       ((border-width container-border-width "border-width" "guint" t t)
        (resize-mode container-resize-mode "resize-mode" "GtkResizeMode" t t)
        (child container-child "child" "GtkWidget" nil t)
        (:cffi focus-child container-focus-child g-object "gtk_container_get_focus_child" "gtk_container_set_focus_child")
        (:cffi focus-vadjustment container-focus-vadjustment (g-object adjustment) "gtk_container_get_focus_vadjustment" "gtk_container_set_focus_vadjustment")
        (:cffi focus-hadjustment container-focus-hadjustment (g-object adjustment) "gtk_container_get_focus_hadjustment" "gtk_container_set_focus_hadjustment")))

define-g-interface
==================

     (define-g-interface g-type-name name (&key (export t) type-initializer)
       &body property*)

     property ::= (name accessor gname type readable writable)
     property ::= (:cffi name acessor type reader writer)

Parameters of define-g-interface

EXPORT
     Whether to export the name of the interface and names of autogenerated properties names from the current package.

TYPE-INITIALIZER
     A string naming the type initiliazer function. It is usually named interface_get_type.

PROPERTIES
     A list of slots of a interface

Parameters of property:

NAME
     A symbol naming the slot

ACCESSOR
     A symbol naming the accessor function for this slot

GNAME
     A string naming the property of GObject

TYPE
     A string naming the type of property of GObject (for GObject properties); or a symbol naming CFFI foreign type (for slots mapped to foreign accessors)

READABLE
     A boolean specifying whether the slot can be read

WRITABLE
     A boolean specifying whether the slot can be assigned to

READER
     A string or a symbol naming getter function. See description of gobject-class metaclass for information.

WRITTER
     A string or a symbol naming setter function. See description of gobject-class metaclass for information.

Macro that expands to defclass for specified interface. Additionally, if export is true, it exports accessor names and name of a interface.

Example:

     (define-g-interface "GtkFileChooser" file-chooser
       (:export t :type-initializer "gtk_file_chooser_get_type")
       (do-overwrite-confirmation file-chooser-do-overwrite-confirmation "do-overwrite-confirmation" "gboolean" t t)
       (select-multiple file-chooser-select-multiple "select-multiple" "gboolean" t t)
       (filter file-chooser-filter "filter" "GtkFileFilter" t t)
       (local-only file-chooser-local-only "local-only" "gboolean" t t)
       (preview-widget file-chooser-preview-widget "preview-widget" "GtkWidget" t t)
       (use-preview-label file-chooser-use-preview-label "use-preview-label" "gboolean" t t)
       (preview-widget-active file-chooser-preview-widget-active "preview-widget-active" "gboolean" t t)
       (file-system-backend file-chooser-file-system-backend "file-system-backend" "gchararray" nil nil)
       (extra-widget file-chooser-extra-widget "extra-widget" "GtkWidget" t t)
       (show-hidden file-chooser-show-hidden "show-hidden" "gboolean" t t)
       (action file-chooser-action "action" "GtkFileChooserAction" t t)
       (:cffi current-name file-chooser-current-name
        (:string :free-to-foreign t :encoding :utf-8) nil "gtk_file_chooser_set_current_name")
       (:cffi filename file-chooser-filename
        (g-string :free-from-foreign t :free-to-foreign t)
        "gtk_file_chooser_get_filename" "gtk_file_chooser_set_filename")
       (:cffi current-folder file-chooser-current-folder
        (g-string :free-from-foreign t :free-to-foreign t)
        "gtk_file_chooser_get_current_folder"
        "gtk_file_chooser_set_current_folder")
       (:cffi uri file-chooser-uri
        (g-string :free-from-foreign t :free-to-foreign t)
        "gtk_file_chooser_get_uri" "gtk_file_chooser_set_uri")
       (:cffi current-folder-uri file-chooser-current-folder-uri
        (g-string :free-from-foreign t :free-to-foreign t)
        "gtk_file_chooser_get_current_folder_uri"
        "gtk_file_chooser_set_current_folder_uri")
       (:cffi preview-filename file-chooser-preview-filename
        (g-string :free-from-foreign t :free-to-foreign t)
        "gtk_file_chooser_get_preview_filename" nil)
       (:cffi preview-uri file-chooser-preview-uri
        (g-string :free-from-foreign t :free-to-foreign t)
        "gtk_file_chooser_get_preview_uri" nil))

define-g-enum
=============

     (define-g-enum g-name name (&key (export t) type-initializer) &body value*)

     value ::= :keyword
     value ::= (:keyword integer)

G-NAME
     A string naming the GEnum type

NAME
     A symbol naming the CFFI enumeration type

EXPORT
     A boolean indicating whether to export name

TYPE-INITIALIZER
     A string naming the foreign type initializer function. Usually named enum_get_type.

Macro that defines CFFI enumeration, registers it with GValue, and calls the type initializer.

Example:

     (define-g-enum "GtkTextDirection" text-direction
       (:export t :type-initializer "gtk_text_direction_get_type")
       (:none 0) (:ltr 1) (:rtl 2))

     (define-g-enum "GtkSizeGroupMode" size-group-mode
      (:export t :type-initializer "gtk_size_group_mode_get_type")
      :none :horizontal :vertical :both)

define-g-flags
==============

     (define-g-flags g-name name (&key (export t) type-initializer) &body value*)

     value ::= :keyword
     value ::= (:keyword integer)

G-NAME
     A string naming the GFlags type

NAME
     A symbol naming the CFFI flags type

EXPORT
     A boolean indicating whether to export name

TYPE-INITIALIZER
     A string naming the foreign type initializer function. Usually named flags_get_type.

Macro that defines CFFI bitfield, registers it with GValue, and calls the type initializer.

Example:

     (define-g-flags "GtkAttachOptions" attach-options
       (:export t :type-initializer "gtk_attach_options_get_type")
       (:expand 1) (:shrink 2) (:fill 4))

     (define-g-flags "GtkButtonAction" button-action
       (:export t :type-initializer "gtk_button_action_get_type")
       :ignored :selects :drags :expands)

get-g-enum-definition
=====================

(get-g-enum-definition type &optional lisp-name-package) => definition

TYPE
     A string naming the GEnum type

LISP-NAME-PACKAGE
     A package that will be used as a package for generated symbols (enum name). If not specified, symbols are interned in *package*

DEFINITION
     A Lisp form that when evaluated defines the GEnum.

Uses GObject introspection capabilities to automatically produce the definition of GEnum. The foreign library that defines the enum type should be loaded.

See Generating names for CLOS classes and accessors for information about used method for generating names.

Example:

     (get-g-enum-definition "GtkDirectionType")
     =>
     (DEFINE-G-ENUM "GtkDirectionType" GTK-DIRECTION-TYPE
                    (:EXPORT T :TYPE-INITIALIZER "gtk_direction_type_get_type")
                    (:TAB-FORWARD 0) (:TAB-BACKWARD 1) (:UP 2) (:DOWN 3) (:LEFT 4)
                    (:RIGHT 5))

get-g-flags-definition
======================

(get-g-flags-definition type &optional lisp-name-package) => definition

TYPE
     A string naming the GFlags type

LISP-NAME-PACKAGE
     A package that will be used as a package for generated symbols (flags name). If not specified, symbols are interned in *package*

DEFINITION
     A Lisp form that when evaluated defines the GFlags.

Uses GObject introspection capabilities to automatically produce the definition of GFlags. The foreign library that defines the flags type should be loaded.

See Generating names for CLOS classes and accessors for information about used method for generating names.

Example:

     (get-g-flags-definition "GtkCalendarDisplayOptions")
     =>
     (DEFINE-G-FLAGS "GtkCalendarDisplayOptions" GTK-CALENDAR-DISPLAY-OPTIONS
                     (:EXPORT T :TYPE-INITIALIZER
                      "gtk_calendar_display_options_get_type")
                     (:SHOW-HEADING 1) (:SHOW-DAY-NAMES 2) (:NO-MONTH-CHANGE 4)
                     (:SHOW-WEEK-NUMBERS 8) (:WEEK-START-MONDAY 16)
                     (:SHOW-DETAILS 32))

get-g-interface-definition
==========================

get-g-interface-definition type &optional lisp-name-package) => definition

TYPE
     A string naming the GInterface type

LISP-NAME-PACKAGE
     A package that will be used as a package for generated symbols (type name, accessor names). If not specified, symbols are interned in *package*

DEFINITION
     A Lisp form that when evaluated defines the GInterface.

Uses GObject introspection capabilities to automatically produce the definition of GInterface. The foreign library that defines the GInterface type should be loaded.

See Generating names for CLOS classes and accessors for information about used method for generating names.

Example:

     (get-g-interface-definition "GtkActivatable")
     =>
     (DEFINE-G-INTERFACE "GtkActivatable" GTK-ACTIVATABLE
                         (:EXPORT T :TYPE-INITIALIZER "gtk_activatable_get_type")
                         (USE-ACTION-APPEARANCE
                          GTK-ACTIVATABLE-USE-ACTION-APPEARANCE
                          "use-action-appearance" "gboolean" T T)
                         (RELATED-ACTION GTK-ACTIVATABLE-RELATED-ACTION
                          "related-action" "GtkAction" T T))

get-g-class-definition
======================

get-g-class-definition type &optional lisp-name-package) => definition

TYPE
     A string naming the GObject type

LISP-NAME-PACKAGE
     A package that will be used as a package for generated symbols (type name, accessor names). If not specified, symbols are interned in *package*

DEFINITION
     A Lisp form that when evaluated defines the GObject.

Uses GObject introspection capabilities to automatically produce the definition of GClass. The foreign library that defines the GObject type should be loaded.

See Generating names for CLOS classes and accessors for information about used method for generating names.

Example:

     (get-g-class-definition "GtkButton")
     =>
     (DEFINE-G-OBJECT-CLASS "GtkButton" GTK-BUTTON
                            (:SUPERCLASS GTK-BIN :EXPORT T :INTERFACES
                             ("AtkImplementorIface" "GtkActivatable" "GtkBuildable")
                             :TYPE-INITIALIZER "gtk_button_get_type")
                            ((LABEL GTK-BUTTON-LABEL "label" "gchararray" T T)
                             (IMAGE GTK-BUTTON-IMAGE "image" "GtkWidget" T T)
                             (RELIEF GTK-BUTTON-RELIEF "relief" "GtkReliefStyle" T
                              T)
                             (USE-UNDERLINE GTK-BUTTON-USE-UNDERLINE "use-underline"
                              "gboolean" T T)
                             (USE-STOCK GTK-BUTTON-USE-STOCK "use-stock" "gboolean"
                              T T)
                             (FOCUS-ON-CLICK GTK-BUTTON-FOCUS-ON-CLICK
                              "focus-on-click" "gboolean" T T)
                             (XALIGN GTK-BUTTON-XALIGN "xalign" "gfloat" T T)
                             (YALIGN GTK-BUTTON-YALIGN "yalign" "gfloat" T T)
                             (IMAGE-POSITION GTK-BUTTON-IMAGE-POSITION
                              "image-position" "GtkPositionType" T T)))

Specifying additional properties for CLOS classes
=================================================

Some properties are not exposed through GObject introspection facilities, but are rather present as a pair of functions (class_get_property, class_set_property). gobject-class metaclass supports such properties. For these properties to be included in automatically generated class definitions, they should be made known to the generator.

Definitions generator uses variable *additional-properties* to get this information.

Variable *additional-properties* contains a plist that maps GType names to a list of properties definitions (See define-g-object-class for syntax of properties definitions).

To supply the bindings generator with this information, bind *additional-properties* to such list when the generator is run.

Example:

     (("GtkTreeViewColumn"
       (:cffi gtk::tree-view
              gtk::tree-view-column-tree-view
              g-object "gtk_tree_view_column_get_tree_view" nil)
       (:cffi gtk::sort-column-id
              gtk::tree-view-column-sort-column-id
              :int "gtk_tree_view_column_get_sort_column_id" "gtk_tree_view_column_set_sort_column_id")
       (:cffi gtk::cell-renderers
              gtk::tree-view-column-cell-renderers
              (glist g-object  :free-from-foreign t) "gtk_tree_view_column_get_cell_renderers" nil))
      ("GtkTreeSelection"
       (:cffi gtk::mode
              gtk::tree-selection-mode
              gtk::selection-mode "gtk_tree_selection_get_mode" "gtk_tree_selection_set_mode")
       (:cffi gtk::select-function
              gtk::tree-selection-select-function
              nil gtk::tree-selection-get-selection-function gtk::tree-selection-set-select-function)))

Generating names for CLOS classes and accessors
===============================================

Names of types are generated by mapping CamelCaseNames to dash-separated-names and interning them in specified package. Additionally, prefix from beginning of the name may be stripped ("GtkWidget" has prefix "Gtk", after stripping it maps to widget). Some names may require special processing (e.g., "GObject", "GInitiallyUnowned" should map to class names in gobject package; "GtkWindow" and "GdkWindow" should receive different symbol-names so that they can both be imported in one package).

Accessors for slots are generated by concatenating class name, dash and slot name, producing names like class-slot: container-child, button-label, etc.

Name generation affected by following variables:

  * *STRIP-PREFIX* A string variable specifying the prefix that should to be stripped from the names to generate symbols (e.g., if (equal "Gtk" *strip-prefix*), then type named "GtkWidget" will map to class named widget.

  * *LISP-NAME-EXCEPTIONS* A plist mapping from strings (type names) to symbols (class names) that have special name processing. Example:

          `(("GObject" gobject:g-object)
            ("GtkObject" ,(intern "GTK-OBJECT" (find-package :gtk)))
            ("GInitiallyUnowned" gobject::g-initially-unowned)
            ("GtkWindow" ,(intern "GTK-WINDOW" (find-package :gtk)))
            ("GtkUIManager" ,(intern "UI-MANAGER" (find-package :gtk)))
            ("GtkUIManagerItemType" ,(intern "UI-MANAGER-ITEM-TYPE" (find-package :gtk))))

generate-types-hierarchy-to-file
================================

     (generate-types-hierarchy-to-file file
                                       root-type
                                       &key include-referenced
                                       prefix
                                       package
                                       exceptions
                                       prologue
                                       interfaces
                                       enums
                                       flags
                                       objects
                                       exclusions
                                       additional-properties)

FILE
     A string or pathname naming the file, or a stream.

ROOT-TYPE
     A GType designator for a root type. All types that inherit from this type will be defined.

&KEY INCLUDE-REFERENCED
     A boolean. Specifies whether referenced types should be included. Type is referenced if it is an interface or a type of property of type included in generation

PREFIX
     A string naming the prefix that should be removed from the beginning of names

PACKAGE
     A package which will contain generated names of types, slots and accessors. It will also be the current package when the definitions are written to file

EXCEPTIONS
     A plist that maps GType names to their Lisp names. See Generating names for CLOS classes and accessors for more info on exceptions from name generation mechanism

PROLOGUE
     A string that will be included verbatim in generated code file

INTERFACES
     Additional list of interfaces that will also be included in generation

ENUMS
     Additional list of enums that will also be included in generation

FLAGS
     Additional list of flags that will also be included in generation

OBJECTS
     Additional list of object types that will also be included in generation

EXCLUSIONS
     A list of GType names that will be excluded from generation

ADDITIONAL-PROPERTIES
     A plist of properties definitions that will be added to generated classes. See Specifying additional properties for CLOS classes for more information.

Generates definitions for all types in a type hierarchy. Recursively scan types hierarchy (starting from root and objects and interfaces) (except types that were specifically excluded) and generate defintion for every mentioned type. Parameters control various aspects of definition generation.

Example of usage:

     (generate-types-hierarchy-to-file
      "gtk.generated-classes.lisp"
      "GtkObject"
      :include-referenced t
      :prefix "Gtk"
      :package (or (find-package :gtk) (make-package :gtk))
      :exceptions `(("GObject" gobject:g-object)
                    ("GtkObject" ,(intern "GTK-OBJECT" (find-package :gtk)))
                    ("GInitiallyUnowned" gobject::g-initially-unowned)
                    ("GtkWindow" ,(intern "GTK-WINDOW" (find-package :gtk)))
                    ("GtkUIManager" ,(intern "UI-MANAGER" (find-package :gtk)))
                    ("GtkUIManagerItemType" ,(intern "UI-MANAGER-ITEM-TYPE" (find-package :gtk))))
      :prologue (format nil "(in-package :gtk)")
      :interfaces '("GtkBuildable" "GtkCellEditable" ...)
      :objects '("GtkSettings" "GtkRcStyle" ...)
      :flags '("GtkTextSearchFlags" "GtkAccelFlags" ...)
      :enums '("GtkTextDirection" "GtkSizeGroupMode" ...)
      :exclusions '("PangoStretch" "PangoVariant" ...)
      :additional-properties
      '(("GtkTreeViewColumn"
         (:cffi
          gtk::tree-view
          gtk::tree-view-column-tree-view
          g-object
          "gtk_tree_view_column_get_tree_view"
          nil)
         ...)
        ...))