PyGTK-Codegen

From OLPC
Jump to: navigation, search

PyGTK-Codegen is a system for automatically generating wrappers for interfacing GTK code with Python.

Notes on how the GTK-codegen the interface generation stuff works.

Put this into your configure.ac:

AC_PATH_PROG(PYGTK_CODEGEN, pygtk-codegen-2.0, no)

Put this into your Makefile.am:

.defs.c:
        (cd $(srcdir)\
         && $(PYGTK_CODEGEN) \
            --override $*.override \
            --prefix py$* $*.defs) > gen-$*.c \
        && cp gen-$*.c $*.c \
        && rm -f gen-$*.c

Write the files _<module>.override and _<MODULE>.defs

I think there is a script that helps you write the .defs file by scanning a header file.

TODO: tell what that is and how to use it, and describe its limitations.

Here is the source code for the pygtk code generator:

sugar-jhbuild/build/share/pygtk/2.0/codegen/

sugar-jhbuild/build/share/pygtk/2.0/codegen/definitions.py

Here are some examples of the types of definitions you can write in the defs file. (Not tested -- these are just notes taken while reading through the code, that need to be verified and explained. There may be some Lisp quoting syntax issues that need to be tweaked.)

Defs files:

(define-object name
  (in-module "module")
  (docstring "doc")
  (parent "parent")
  (c-name "name")
  (gtype-id "id")
  (fields
    '("type" "name")
    ...
  )
  (implements "interface")
)
(define-interface name
  (in-module "module")
  (docstring "doc")
  (c-name "name")
  (gtype-id "id")
  (vtable "vtable")
)
(define-enum name
  (in-module "module")
  (c-name "name")
  (gtype-d "id")
  (values
    '("name" "val")
    ...
  )
)
(define-flags name
  (in-module "module")
  (c-name "name")
  (gtype-id "id")
  (values
    '("name" "val")
    ...
  )
)
(define-boxed name
  (in-module "module")
  (c-name "name")
  (gtype-id "id")
  (copy-func "func")
  (release-func "func")
  (fields
    '("type1" "name1")
    ...
  )
)
(define-pointer name
  (in-module "module")
  (c-name "name")
  (gtype-id "id")
  (fields
    '("type1" "name1")
    ...
  )
)
(define-method name
  (of-object "object")
  (docstring "doc")
  (c-name "name")
  (gtype-id "id")
  (return-type "type")
  (caller-owns-return #t)
  (unblock-threads #t)
  (return-type "type")
  (deprecated "val")
  (parameters
    '("type" "name" (default "val") (null-ok))
    ...
  )
  (varargs #t)
)
(define-virtual name
  [same as define-method]
)
(define-function name
  (in-module "module")
  (docstring "doc")
  (is-constructor-of "object")
  (c-name "name")
  (gtype-id "type")
  (return-type "type")
  (caller-owns-return #t)
  (unblock-threads #t)
  (parameters
    '("type" "name" (default "val") (null-ok))
    ...
  )
  (properties
    '("name" (optional) (argname "name"))
    ...
  )
  (varargs #t)
  (deprecated "val")
)


Override files:

ignore/ignore-platform [functions...]
ignore-glob/ignore-glob-platform [globs...]
ignore-type/ignore-type-platform [typenames...]
override function/method [kwargs|noargs|onearg] [staticmethod|classmethod]
override-attr Class.attr
override-slot Class.slot
headers
body
init
modulename name
include filename
import module1 [, module2, module3 ...]
define funcname [kwargs|noargs|onearg] [classmethod|staticmethod]
define Class.method [kwargs|noargs|onearg] [classmethod|staticmethod]
new-constructor GType
options [dynamicnamespace]