Re: GTK data types (BOXED)



Andreas Kostyrka <andreas@ag.or.at> writes:

> I've been just wondering if someone could describe all the GTK types
> in gtktypeutils.h and what they are intended to store?  e.g.: What
> is a GTK_TYPE_BOXED? *wonder* (A pointer for a GDK type?
> *who-knows?*)

A GTK_TYPE_BOXED is the fundamental type for pointers to random
structs.

Here is the original proposal I wrote for this stuff, it could be out
of date by now.  [Yeah, I know, I should really work this over and put
it into the Gtk reference manual...]

ONCE AGAIN, THIS IS OLD STUFF.  DON'T BELIEVE IT, ESPECIALLY THE
SECTION ABOUT GtkObject REFCOUNTS.

---------------------------------------------------------------------

I'd like to propose the following type system for Gtk.  It will be
used at runtime to construct argument lists for signal handlers and
for setting object slots (with gtk_type_set_arg).  It will also be
used to statically describe most of the functions that should be
exported to an interpreter.  Basically, it should reflect the needs
and capabilities of the typical high-level language that wants to
interface to Gtk.

The primary issue here is robustness.  Ideally, it should not be
possible to crash your program from the high-level language.  The
second issue is to allow mostly automatic stub generation for the
interpreter glue.

I have evolved it from the current system by unifying the GTK_ARG_*
types with the GtkObject types and then adding support for the new
things.

PLEASE NOTE:

    In the following I often say that something `will be done' or
    describe things as being already finished.  This only means that I
    -- in the moment that I have written them down -- would like these
    things to be done that way.  It does not imply any official
    commitment from the Gtk developers or likely further directions of
    Gtk development.

The master plan is to:

- find a set of fundamental types and their precise semantics so that
  they blend well with the implementation of high-level languages.

- describe most `interesting' types that are defined by Gtk in terms
  of these fundamental types.

- describe as much functions of Gtk as possible with these types.

The set of the fundamental types will be fairly heterogenous and their
semantics will be written down in prose.

The remaining types will be derived from the fundamental types in a
very restrictede way.  That allows us to describe them in a highly
stylized manner so that they can be automatically translated into
whatever glue code is required by the high-level language.

Most of the functions that can be exported to the high-level language
will likewise be described in a stylized manner to allow automatic
stub generation.

This system will probably not cover all features of Gtk that we might
want to export to the high-level language, but it could help avoid
gratuitous definition of features that cannot be exported cleanly
because they use the full `power' of C.

The preceding paragraphs all address a static interface.  When glue
code is generated for a particular high-level language implementation,
the description of the types and the functions is read from some files
that have been installed alongside with the rest of Gtk.

There will also be a run-time type system that mirrors the fundamental
and derived types.  This is needed by Gtk itself for the signal
mechanism and the generic object interface (gtk_object_new,
gtk_object_set, ...) and can also be used to advantage by the glue
code.

But the type information that is available from Gtk does only cover
what Gtk needs for itself.  If you need more information for your glue
code (for example, a mapping between the actual names of enumeration
literals and their values) you have to implement it yourself (by using
the static description files, of course).


The Fundamental Types
---------------------

Whenever I say "interpreter" in this text, I mean the implementation
of the particular high-level language.

Only a few types are allowed to travel between Gtk land and
interpreter land.  Some of them can be converted (each in its own
special way) and some need to be wrapped.

There exist some strict conventions to ensure proper memory handling.
Objects that escape into the interpreter must have a (potentially)
unlimited life-time or must be able to inform the interpreter when
they have been destroyed.  When Gtk can not guarantee this (by not
respecting a reference count for example), the object must be copied.

At runtime, a type is identified by its numerical id.  These ids are
essentially determined dynamically, so you can't count on a certain
type to always be represented by the same id.  The fundamental types
(see below), however, are assigned constant ids to blend well with the
established usage of the GTK_ARG_* types.

For the static function descriptions, a type is identified by its
name.  That name is also available at runtime, mostly for error
reporting.

Some types can be arranged in a hierarchy to express (single)
inheritance relationships.  Types without a base class are called
`fundamental' types in this text.  The set of fundamental types is
fixed, because each fundamental type has its own very special
semantics and they probably need to be handled individually by the
interpreter glue.  Adding a new fundamental type generally means
writing new glue code for each interpreter.

Each fundamental type has a precise description of its semantics.
Every type that (ultimately) inherits from a certain fundamental type
must exactly adhere to this semantics.  The description of the
semantics include:

- How to pass it to a function.

  This includes stating the types and order of all `primitive' C types
  that carry the information as well as detailing the things that the
  called function is allowed to do with the values and how the
  associated memory is managed.

  This is expressed below as a line that looks like:

    pass: ctype1, ctype2, ...

  followed by the description.  When it is not allowed to pass this type
  to functions, the line looks like this:

    pass: n.a.

- How to get it back from a function as the return value.

  This means stating the C type of the return value, if it is at all
  possible to return the type from a function. [etc...]

  Expressed as

    return: ctype

- Whether this type can be inherited.

  Some types can not be inherited (like "int"), other must be
  inherited to become meaningful (like "enum"), some can but don't
  have to (like "GtkObject").

  Expressed as

    inherit: no
    inherit: must
    inherit: yes

These descriptions are only written down in English and must be
enforced by carefully implementing both the interpreter glue and the
Gtk functions.

Because of this, the number of fundamental types should be kept to a
minimum.  There is no way to add new fundamental types to the system
short of hacking the Gtk sources (and the table below).

If a prototype of a function can not be described with the fundamental
types, it can still be exported to the interpreter, but requires more
attention by the glue writers.  Therefore, try to design your
functions so that they follow these conventions.

The first line of each type states the symbolic name of the run-time
numerical type id and the textual name (in double quotes).

- GTK_TYPE_INVALID, "invalid"

        pass: n.a.
      return: n.a.
     inherit: no

    No valid type has this id. Use this only as the `base type' for
    new fundamental types or for expressing other exceptional
    situations.

- GTK_TYPE_NONE, "none"

        pass: n.a.
      return: void
     inherit: no
    
    The "void" type.  There is no data associated with it.  It is
    illegal to use it for a function parameter.  If it is used as a
    return type, it means that the function does not return any useful
    value.

- GTK_TYPE_CHAR, "char"

        pass: gchar
      return: gchar
     inherit: no

    A character.  In good C tradition, this is represented as a
    "gchar".  [Maybe we can come up with something more
    international?]

- GTK_TYPE_BOOL, "bool"

        pass: gint [gbool?]
      return: gint
     inherit: no

    An boolean value, zero is false, non-zero is true.  The canonical
    true value is 1.

- GTK_TYPE_INT, "int"

        pass: gint
      return: gint
     inherit: no

- GTK_TYPE_UINT, "uint"

        pass: guint
      return: guint
     inherit: no

- GTK_TYPE_LONG, "long"

        pass: glong
      return: glong
     inherit: no

- GTK_TYPE_ULONG, "ulong"

        pass: gulong
      return: gulong
     inherit: no

- GTK_TYPE_FLOAT, "double"

        pass: gdouble
      return: gdouble
     inherit: no

- GTK_TYPE_STRING, "string"

        pass: gchar*
      return: gchar*
     inherit: no

    For passing read only nul-terminated strings of "gchar"s and
    returning newly allocated strings.

    When passed to a function, the string is only valid for the
    duration of the call.  The callee is not allowed to retain the
    pointer or to modify the string.  It has to copy the whole string
    to new storage.

    When returned from a function, the string sits in malloced memory
    that must eventually be freed by the caller (with g_free).

- GTK_TYPE_STATIC_STRING, "static_string"

        pass: n.a.       (use GTK_TYPE_STRING instead)
      return: gchar*
     inherit: no

    For returning a read-only string that should not be freed by the
    caller.

    The caller does not assume ownership of the memory of the string
    The returned pointer is only valid until the next Gtk or Gdk
    function is called, so the whole string should be immediately
    copied into new storage if needs be.

- GTK_TYPE_OBJECT, "GtkObject"

        pass: GtkObject*      (or derived)
      return: GtkObject*      (or derived)
     inherit: yes

    A pointer to a GtkObject or some derived type.

    There are two possible mechanism to manage the lifetime of
    GtkObjects.  First, they maintain a reference count that can be
    controlled with gtk_object_ref and gtk_object_unref.  The
    GtkObject is not deleted as long as the reference count is greater
    than 0.

    The second possibility is to receive a notification when a
    GtkObject is about to be deleted.  Install a signal handler for
    the "destroy" signal.  Upon receiving the notification, you must
    invalidate all references you have stored to the GtkObject.

    The second method is preferable because it does not run the risk
    of creating cyclic references which would completely prevent the
    GtkObject from being destroyed.

    When a GtkObject is returned from a function the returned pointer
    is *not* reflected in the reference count.  That is, a widget
    returned by gtk_new_button, for example, has a reference count of
    zero.

    [A cyclic reference is very easy to produce from Scheme.  Just
    register a callback that has the object in its closure.  Happens
    all the time.]

- GTK_TYPE_ENUM, "enum"

        pass: gint
      return: gint
     inherit: must

    An enumeration that represents separate cases, like GtkWindowType.

- GTK_TYPE_FLAGS, "flags"

        pass: gint
      return: gint
     inherit: must

    An enumeration that represent options that can be combined by
    oring them together.  The values of such an enumeration are not
    required to be single bits.  They can also contain common
    combinations with their own names.  Such combinations are required
    to be listed after all the single bit `fundamental' values in the
    enumeration info (see below [but not yet]).

- GTK_TYPE_BOXED, "boxed"

        pass: gpointer
      return: gpointer
     inherit: must

    A pointer to some structure.  You have to explicitely manage the
    lifetime of those structures by invoking some functions at the
    right times.

    Boxed values that are passed to a function are only valid for the
    duration of that function call.  If the function wants to retain a
    reference to the boxed value, it needs to invoke the "copy"
    function (see below).  If the copy is no longer needed, the
    "destroy" function has to be invoked.

    When a boxed value is returned from a function, the caller of the
    function assumes ownership of the value.  When it is no longer
    needed, the "destroy" function has to be invoked.

    The "copy" and "destroy" functions are listed in the static
    description file.

    [I have not completely made my mind up about thie reference
    counting issues and the implementation is probably very
    inconsistent (but conservative) right now.]

- GTK_TYPE_FOREIGN, "foreign"

        pass: gpointer, GtkDestroyNotify notify
      return: gpointer
     inherit: no

    An arbitrary value that fits into a "gpointer" plus a function
    that has to be called when the value is no longer needed.  This
    allows the interpreter to protect the value from its garbage
    collector.

- GTK_TYPE_CALLBACK, "callback"

        pass: GtkCallbackMarshal, gpointer, GtkDestroyNotify notify
      return: n.a.
     inherit: no

    An arbitrary value from the interpreter that can be somehow
    invoked plus a destroy notification function.

    [The GtkCallbackMarshal function is called with enough information
     to invoke the real callback.  This includes a GtkArg array, etc.
     Details follow.]

- GTK_TYPE_VALUES

        pass: gint, GtkArg*
      return: n.a.
     inherit: no

    An array of GtkArg structures plus its size.  Memory is managed
    just like for a GTK_TYPE_STRING.

- GTK_TYPE_POINTER

        pass: gpointer
      return: gpointer
     inherit: no

    A untyped "gpointer".  Probably not useful to the interpreter.

- GTK_TYPE_C_CALLBACK

        pass: GtkFunction, gpointer data
      return: n.a.

    To handle the GtkContainer::foreach signal.  Tough, tough.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]