{"id":13803755,"url":"https://github.com/andy128k/cl-gobject-introspection","last_synced_at":"2025-04-11T06:54:31.423Z","repository":{"id":54891164,"uuid":"1480647","full_name":"andy128k/cl-gobject-introspection","owner":"andy128k","description":null,"archived":false,"fork":false,"pushed_at":"2024-05-19T16:06:13.000Z","size":251,"stargazers_count":51,"open_issues_count":9,"forks_count":15,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-25T04:48:55.779Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andy128k.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2011-03-14T23:41:17.000Z","updated_at":"2024-12-08T19:49:03.000Z","dependencies_parsed_at":"2024-02-25T12:47:51.419Z","dependency_job_id":null,"html_url":"https://github.com/andy128k/cl-gobject-introspection","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andy128k%2Fcl-gobject-introspection","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andy128k%2Fcl-gobject-introspection/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andy128k%2Fcl-gobject-introspection/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andy128k%2Fcl-gobject-introspection/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andy128k","download_url":"https://codeload.github.com/andy128k/cl-gobject-introspection/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248358555,"owners_count":21090402,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T01:00:37.600Z","updated_at":"2025-04-11T06:54:31.403Z","avatar_url":"https://github.com/andy128k.png","language":"Common Lisp","funding_links":[],"categories":["C ##"],"sub_categories":[],"readme":"# cl-gobject-introspection\n\nCommon Lisp bindings to [gobject-introspection](https://gitlab.gnome.org/GNOME/gobject-introspection).\n\n## Motivational examples\n\n### GTK+ 3\n\n```lisp\n(defvar *gtk* (gir:require-namespace \"Gtk\" \"3.0\"))\n(gir:invoke (*gtk* 'init) nil)\n(let ((window (gir:invoke (*gtk* \"Window\" 'new)\n                          (gir:nget *gtk* \"WindowType\" :toplevel))))\n  (gir:invoke (window 'show))\n  (gir:invoke (*gtk* 'main)))\n```\n\n### Gtk 4\n\n```lisp\n(defvar *gio* (gir:require-namespace \"Gio\"))\n(defvar *gtk* (gir:require-namespace \"Gtk\" \"4.0\"))\n\n(let ((app (gir:invoke (*gtk* \"Application\" 'new)\n\t\t       \"org.gtk.example\"\n\t\t       (gir:nget *gio* \"ApplicationFlags\" :default-flags))))\n  (gir:connect app \"activate\"\n\t       (lambda (app)\n\t\t (let ((window (gir:invoke (*gtk* \"ApplicationWindow\" 'new) app)))\n\t\t   (gir:invoke (window 'show)))))\n  (gir:invoke (app 'run) nil))\n```\n\nMore examples may be found in an `examples` directory.\n\n### Hello, World!\n\n![Hello, World screenshot](https://raw.githubusercontent.com/andy128k/cl-gobject-introspection/master/examples/screenshots/screenshot-hello-world.png)\n\n### Flood Game\n\n![Flood Game screenshot](https://raw.githubusercontent.com/andy128k/cl-gobject-introspection/master/examples/screenshots/screenshot-flood-game.png)\n\n### Maze\n\n![Maze screenshot](https://raw.githubusercontent.com/andy128k/cl-gobject-introspection/master/examples/screenshots/screenshot-maze.png)\n\n## 1. Main interface\n\nInterface with the GObjectIntrospection is based on repositories. Main\nfunction which creates an instance of a repository is\n\n```lisp\n(gir:require-namespace repository-name [version])\n```\n\nExamples:\n\n```lisp\n(gir:require-namespace \"GLib\")\n\n(gir:require-namespace \"Gtk\" \"4.0\")\n```\n\nReturns interface to repository with name `repository-name`.\n\n## 2. Using interface objects\n\nIn gobject object system, repository, class, enumeration are all kind\nof namespace.  To get a function/const/enum/class from the repository\nis kind of namespace access, to get a method from object is kind of\nnamespace access too.  So that concept is introduced into\ncl-gobject-introspection too.  A function named nget (namespace get)\nis use to do namespace accessing as follow,\n\n```lisp\n(gir:nget *gtk* \"WindowType\" :toplevel) ; get enum value\n(gir:nget *gtk* \"Window\" 'new)          ; get a class constructor function\n(gir:nget *window* 'add)                ; get a method\n```\n\nTo call a method of object, we need to get the method from function,\nthen call it.\n\n```lisp\n(funcall (gir:nget *gtk* \"Window\" 'new) 0)\n```\n\nTo save some typing, a macro named `invoke` is introduced as follow,\n\n```lisp\n(gir:invoke (*gtk* \"Window\" 'new) 0)\n```\n\nIn this way, `(*gtk* \"Window\" 'new)` can be seen as function and `0` can\nbe seen as parameters.\n\n## 3. Get FFI element\n\n```lisp\n(gir:invoke (repository func-name) func-arg ...) -\u003e any\n  repositry : repository\n  func-name : (or string symbol)\n  func-arg : any\n(gir:nget repository const-name) -\u003e any\n  repository : repository\n  const-name : (or string symbol)\n(gir:nget repository enum-name enum-value-name) -\u003e integer\n  repositry : repository\n  enum-name : (or string symbol)\n  enum-value-name : keyword\n(gir:nget repository class-name constructor-name) -\u003e function\n  repositry : repository\n  class-name : (or string symbol)\n  constructor-name : (or string symbol)\n```\n\nThe `nget` takes all arguments except the first one as names of foreign\nobjects. Name could be a `string` or a `symbol`. In both cases it is\nallowed to replace `_` with `-`. So you can write either `\"get_name\"`\nor `’get-name` with the same result. If you use symbol its name is\ndowncased.\n\nIf second argument of nget is a name of function, nget will get the\nfunction object.  And we can use invoke macro for more concise syntax.\n\n```lisp\n(defvar *gtk* (gir:require-namespace \"Gtk\" \"3.0\"))\n(gir:invoke (*gtk* 'init) nil)\n```\n\ngtk\\_init is called with an empty array.\n\nIf second argument of nget is a name of constant, then it returns\nvalue of the constant. For example,\n\n```lisp\n(gir:nget *gtk* \"MAJOR-VERSION\")\n```\n\nreturns 2 for GTK2 or 3 for GTK3.\n\nIf second argument of nget is a name of enumeration, then third\nargument should be value name. It returns integer value. Value name\nmust be `keyword`.  Any other symbol or string will mean, that you\nwant get a method with that name.\n\nFor example,\n\n```lisp\n(gir:nget *gtk* \"WindowType\" :toplevel)\n```\n\nReturns 0.\n\nIf second argument of nget is a name of class (or struct), then the\nthird argument should be a name of class constructor (in GTK it is\nusually \"new\"), and we can use invoke here too. In GTK classes have\nnames beginning with capital char, so you have to use either string\nor symbol like ’|Window|.\n\n```lisp\n(defvar *window* (gir:invoke (*gtk* \"Window\" 'new) 0))\n```\n\nThis call will return a representation of object.\n\n## 4. Foreign objects\n\n```lisp\n(gir:invoke (object method-name) method-arg ...) -\u003e any\n  object : gir-object\n  method-name : (or string symbol)\n  method-arg : any\n```\n\nTo get the method of an object, the second argument of nget should be\neither name of method (`string` or `symbol`) or keyword with special\nmeaning.  Invoke can be used for the more concise syntax.\n\n```lisp\n(gir:invoke (*window* 'add) button)\n```\n\nwill call method \"add\" with argument in variable \"button\".\n\n### 4.1. Pointer to object\n\nTo get C pointer to an object, use `this-of`.\n\n```lisp\n(gir::this-of *window*)\n```\n\nIt is possible to make an object from a pointer:\n\n```lisp\n(defvar *window-from-ptr* (gir:build-object-ptr (gir:nget *gtk* \"Window\") window-ptr))\n```\n\n`window-ptr` should be `cffi:foreign-pointer` here.\n\n### 4.2. Fields\n\nGetting and setting field values are done with field and setf.\n\n```lisp\n(defvar *entry* (gir:invoke (*gtk* \"TargetEntry\" 'new) \"ok\" 0 0))\n                                                         \n\u003e (gir:field *entry* 'flags)\n0\n\u003e (setf (gir:field *entry* 'flags) 1)\n\u003e (gir:field *entry* 'flags)\n1\n```\n\nBut you cannot set with :set-field! complex types such as structs,\nunions or even strings. It is a restriction of GObjectIntrospection.\n\n### 4.3. Properties\n\nGetting and setting property are done with property and setf.\n\n```lisp\n(gir:property *window* 'width-request)\n(setf (gir:property *window* 'width-request) 100)\n```\n\n## 5. Signals\n\n```lisp\n(gir:connect object signal-name handler) -\u003e void?\n  object : gir-object\n  signal-name : (or symbol string)\n  handler : (or function cffi:foreign-pointer string symbol)\n```\n\nConnects signal handler to object. If handler is a string o symbol, then\nit denotes C-function.\n\n## 6. Description\n\nVarious description information, such as a signature of a function, can be\ngotten via the description functions.\n\n```lisp\n(gir:nget-desc *gtk* 'init)\n#F\u003cinit(#V\u003cargv: (SEQUENCE STRING)\u003e): (#V\u003cRETURN-VALUE: VOID\u003e\n                                       #V\u003cargv: (SEQUENCE STRING)\u003e)\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandy128k%2Fcl-gobject-introspection","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandy128k%2Fcl-gobject-introspection","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandy128k%2Fcl-gobject-introspection/lists"}