andy128k / cl-gobject-introspection Goto Github PK
View Code? Open in Web Editor NEWLicense: BSD 2-Clause "Simplified" License
License: BSD 2-Clause "Simplified" License
Take Gio.Application
for example, (gir:list-signals-desc (gir:nget-desc gio:*ns* "Application"))
will produce:
(#F<activate(): (#V<RETURN-VALUE: VOID>)>
#F<command-line(#V<command_line: INTEGER>): (#V<RETURN-VALUE: INTEGER>)>
#F<handle-local-options(#V<options: #S<VariantDict>>): (#V<RETURN-VALUE: INTEGER>)>
#F<name-lost(): (#V<RETURN-VALUE: BOOLEAN>)>
#F<open(#V<files: (SEQUENCE I<File>)> #V<hint: STRING>): (#V<RETURN-VALUE: VOID>)>
#F<shutdown(): (#V<RETURN-VALUE: VOID>)>
#F<startup(): (#V<RETURN-VALUE: VOID>)>)
where the parameters of signal open
contain a list of GFile
. However, the pointer to the list and the size of the list are passed to Lisp function directly like this:
(connect app "open"
(lambda (app files n-files hint)
(format T "~a~%" files)))
;; This prints "#.(SB-SYS:INT-SAP #X56334FB51140)"
https://sourceforge.net/p/sbcl/mailman/message/58773714/
this line seems to cause problems
cl-gobject-introspection/src/init.lisp
Line 146 in 6b30d05
I wonder how sbcl will respond to that, and at this point, I do not know what else I may need to suggest.
The error is:
[Lock on package SB-EXT violated when interning SET-FLOATING-POINT-MODES while ; in package GIR.]
Still new to gobject-introspection, so I may be doing something stupid :)
Using the hello.lisp example, I'm trying to display a web view next to a widget:
(cl:defpackage #:gir-test-web
(:use #:cl))
(in-package #:gir-test-web)
(defvar *gtk* (gir:ffi "Gtk"))
(defvar *webkit* (gir:require-namespace "WebKit2"))
(cffi:defcallback hello :void ((btn-ptr :pointer))
(let ((button (gir::build-object-ptr (gir:nget *gtk* "Button") btn-ptr)))
(setf (gir:property button 'label) "OK"))
(format t "Hello, pressed~%"))
(defun main ()
(gir:invoke (*gtk* 'init) nil)
(let ((window (gir:invoke (*gtk* "Window" 'new)
(gir:nget *gtk* "WindowType" :toplevel)))
(view (gir:invoke (*webkit* "WebView" 'new)))
(button (gir:invoke (*gtk* "Button" 'new-with-label) "Hello, world!"))
(button2 (gir:invoke (*gtk* "Button" 'new-with-label) "Dummy!"))
(box (gir:invoke (*gtk* "Box" 'new)
(gir:nget *gtk* "Orientation" :vertical)
0)))
(gir::g-signal-connect-data (gir::this-of window)
"destroy"
(cffi:foreign-symbol-pointer "gtk_main_quit")
(cffi:null-pointer)
(cffi:null-pointer)
0)
(gir:connect button :clicked
(lambda (button)
(setf (gir:property button 'label) "OK")))
(gir:invoke (view 'load_uri) "https://gnu.org")
(gir:invoke (box 'add) button)
(gir:invoke (box 'add) view)
(gir:invoke (box 'add) button2)
(gir:invoke (window 'add) box)
(gir:invoke (window 'show-all))
(gir:invoke (*gtk* 'main))))
The above only displays the 2 buttons, but nothing in between.
If I call
(gir:invoke (window 'add) view)
then the view displays (instead of the buttons).
Any idea what's wrong?
I'm trying to run some javascript in a web view. The following works:
(cffi:defcallback javascript-callback :void ((gobject :pointer) (gasyncres :pointer)
(user_data :pointer))
(declare (ignore gasyncres))
(format t "Javascript called on ~a with user data ~a~%" gobject user_data))
(gir:invoke (view 'run-javascript)
"window.scrollBy(0, -20);"
(cffi:null-pointer)
(cffi:get-callback 'javascript-callback)
(cffi:null-pointer))
But having to define the callbacks in advance is not very convenient. It also makes the passing of user data a bit cumbersome compared to closures.
Is there a way to use a lambda instead, as with gir:connect
?
Ideally, I'd like to write something like the following:
(gir:invoke (view 'run-javascript)
"window.scrollBy(0, -20);"
(cffi:null-pointer)
(lambda (gobject gasyncres user_data)
...))
(Note that there would be no need for the last (cffi:null-pointer)
argument of gir:invoke
.)
From the docs
The list is internal to GIRepository and should not be freed, nor should its string elements.
To check this, simply call (gir:repository-get-search-path)
two times. The second one will fail because the pointer was freed.
The issue is that g-slist-to-list
always calls (g-slist-free pointer)
at the end. So a quick solution would be to add a param to g-slist-to-list
that determines if the original list should be freed or not.
Is it possible to create structure which has no constructor function (e.g. GTypeInfo)?
There's no object.lisp
but it's listed in the asd file.
Although I am an experienced programmer, I admit being rather new at both lisp and gtk guis (although the gobject framework much less so), so feel free to call me out if I being an idiot here. Now that that's out of the way, I'm trying to translate one of the python examples of gi into lisp and it's giving me a consistent error. A quick inspection makes it look like an issue in the cffi translation code.
Here's a stripped down example of the problem:
(ql:quickload :cl-gobject-introspection)
(defparameter gtk (gtk:ffi "Gtk"))
(defun test-main ()
(gir:invoke (gtk 'init) nil)
(let ((window (gir:invoke (gtk "Window" 'new) (gir:nget gtk "WindowType" :toplevel)))
(draw-area (gir:invoke (gtk "DrawingArea" 'new))))
(gir:invoke (window 'add) draw-area)
(gir:invoke (draw-area 'set_size_request) 400 400)
(gir:connect draw-area "configure_event" (lambda (widget event) (gir:invoke (widget 'get_allocation))))
(gir:invoke (draw-area 'show))
(gir:invoke (window 'show))
(gir:invoke (gtk 'main))))
The program breaks down in the call to get_allocation in the configure_event with a complaint that something is trying to funcall a nil. The equivalent program in python3:
from gi.repository import Gtk
def main ():
Gtk.init()
window = Gtk.Window(Gtk.WindowType.TOPLEVEL)
draw_area = Gtk.DrawingArea()
window.add(draw_area)
draw_area.set_size_request(400, 400)
draw_area.connect("configure_event", lambda widget, event: widget.get_allocation())
draw_area.show()
window.show()
Gtk.main()
Runs just fine, as far as I can tell.
Also, system info:
I'm running ccl64 on arch 64-bit.
I would like to call gdk_atom_intern
to get the clipboard in my application (specifing the name "CLIPBOARD"
). Is it possible? I try to get a function with
(gir:nget (gir:require-namespace "Gdk") "Atom" 'intern)
but this thows an error "Bad FFI constructor name intern". Maybe there is some other way to get the clipboard?
Hi, nice library!
I'm working a little bit with it and I'm able to get the following code to work:
(ql:quickload :cl-gobject-introspection)
(defvar *gtk* (gir:require-namespace "Gtk"))
(defvar *gio* (gir:ffi "Gio"))
(gir:invoke (*gtk* 'init) nil)
(defvar *result* nil)
(defvar *callback-view* nil)
(defvar *callback-label* nil)
(let* ((window (gir:invoke (*gtk* "Window" 'new) (gir:nget *gtk* "WindowType" :toplevel)))
(box (gir:invoke (*gtk* "Box" 'new) (gir:nget *gtk* "Orientation" :vertical) 0))
(label (gir:invoke (*gtk* "Label" 'new) "Hello GNU, from lisp!")))
(gir:invoke (box 'pack-start) label t t 0)
(gir:invoke (window 'add) box)
(gir:connect window
:destroy (lambda (x)
(declare (ignore x))
(gir:invoke (*gtk* 'main_quit))))
(gir:invoke (window 'show-all))
(gir:invoke (*gtk* 'main)))
This indicates to me that GTK is properly installed and the type libs are getting properly loaded. The problem arises the moment I try to use a different library:
(ql:quickload :cl-gobject-introspection)
(defvar *gtk* (gir:require-namespace "Gtk"))
(defvar *gio* (gir:ffi "Gio"))
;; FIXME: use gtk-application with activate signal instead of gtk_main
(gir:invoke (*gtk* 'init) nil)
(defvar *result* nil)
(defvar *callback-view* nil)
(defvar *callback-label* nil)
(let* ((webkit (gir:require-namespace "WebKit2"))
(window (gir:invoke (*gtk* "Window" 'new) (gir:nget *gtk* "WindowType" :toplevel)))
(box (gir:invoke (*gtk* "Box" 'new)
(gir:nget *gtk* "Orientation" :vertical) 0))
(view (gir:invoke (webkit "WebView" 'new))))
(gir:invoke (box 'pack-start) view t t 0)
(gir:invoke (window 'add) box)
(gir:invoke (view 'load-uri) "https://www.gnu.org")
(gir:connect window :destroy (lambda (x) (gir:invoke (*gtk* 'main_quit))))
(gir:invoke (window 'show-all))
(gir:invoke (*gtk* 'main)))
This results in the following condition being raised:
Could not locate webkit_web_view_new: dlopen(@rpath/libjavascriptcoregtk-4.0.18.dylib, 9): image not found
[Condition of type SIMPLE-ERROR]
Restarts:
0: [RETRY] Retry EVAL of current toplevel form.
1: [CONTINUE] Ignore error and continue loading file "/Users/jmercouris/Source/Lisp/giqt/examples/hello-webview.lisp".
2: [ABORT] Abort loading file "/Users/jmercouris/Source/Lisp/giqt/examples/hello-webview.lisp".
3: [*ABORT] Return to SLIME's top level.
4: [ABORT] abort thread (#<THREAD "worker" RUNNING {1004516E63}>)
Backtrace:
0: ((LAMBDA (&REST GIR::ARGS-IN) :IN GIR::BUILD-FUNCTION))
1: ((LAMBDA NIL :IN "/Users/jmercouris/Source/Lisp/giqt/examples/hello-webview.lisp"))
2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (LET* ((WEBKIT #) (WINDOW #) (BOX #) (VIEW #)) (GIR:INVOKE (BOX #) VIEW T T 0) (GIR:INVOKE (WINDOW #) BOX) (GIR:INVOKE (VIEW #) "https://www.gnu.org") (GIR:CONNECT WINDOW..
3: (EVAL-TLF (LET* ((WEBKIT #) (WINDOW #) (BOX #) (VIEW #)) (GIR:INVOKE (BOX #) VIEW T T 0) (GIR:INVOKE (WINDOW #) BOX) (GIR:INVOKE (VIEW #) "https://www.gnu.org") (GIR:CONNECT WINDOW :DESTROY (LAMBDA # ..
4: ((LABELS SB-FASL::EVAL-FORM :IN SB-INT:LOAD-AS-SOURCE) (LET* ((WEBKIT #) (WINDOW #) (BOX #) (VIEW #)) (GIR:INVOKE (BOX #) VIEW T T 0) (GIR:INVOKE (WINDOW #) BOX) (GIR:INVOKE (VIEW #) "https://www.gnu...
5: ((LAMBDA (SB-KERNEL:FORM &KEY :CURRENT-INDEX &ALLOW-OTHER-KEYS) :IN SB-INT:LOAD-AS-SOURCE) (LET* ((WEBKIT #) (WINDOW #) (BOX #) (VIEW #)) (GIR:INVOKE (BOX #) VIEW T T 0) (GIR:INVOKE (WINDOW #) BOX) (G..
6: (SB-C::%DO-FORMS-FROM-INFO #<CLOSURE (LAMBDA (SB-KERNEL:FORM &KEY :CURRENT-INDEX &ALLOW-OTHER-KEYS) :IN SB-INT:LOAD-AS-SOURCE) {100451B34B}> #<SB-C::SOURCE-INFO {100451B303}> SB-C::INPUT-ERROR-IN-LOAD..
7: (SB-INT:LOAD-AS-SOURCE #<SB-INT:FORM-TRACKING-STREAM for "file /Users/jmercouris/Source/Lisp/giqt/examples/hello-webview.lisp" {10045193C3}> :VERBOSE NIL :PRINT NIL :CONTEXT "loading")
8: ((FLET SB-FASL::THUNK :IN LOAD))
9: (SB-FASL::CALL-WITH-LOAD-BINDINGS #<CLOSURE (FLET SB-FASL::THUNK :IN LOAD) {56410FB}> #<SB-INT:FORM-TRACKING-STREAM for "file /Users/jmercouris/Source/Lisp/giqt/examples/hello-webview.lisp" {10045193C..
10: ((FLET SB-FASL::LOAD-STREAM :IN LOAD) #<SB-INT:FORM-TRACKING-STREAM for "file /Users/jmercouris/Source/Lisp/giqt/examples/hello-webview.lisp" {10045193C3}> NIL)
11: (LOAD #P"/Users/jmercouris/Source/Lisp/giqt/examples/hello-webview.lisp" :VERBOSE NIL :PRINT NIL :IF-DOES-NOT-EXIST T :EXTERNAL-FORMAT :DEFAULT)
--more--
This might lead you to think that I haven't installed libjavascriptcore, however a cursory examination shows that it exists:
/opt/local/lib/:
find . \( -iname libjavascriptcoregtk-4.0.18.dylib \) -ls
8642468553 0 lrwxr-xr-x 1 root admin 38 Nov 11 22:23 libjavascriptcoregtk-4.0.18.dylib -> libjavascriptcoregtk-4.0.18.14.7.dylib
find finished at Fri Dec 13 16:01:16
Additionally the contents of /opt/local/share/gir-1.0
:
/opt/local/share/gir-1.0:
total used in directory 8360 available 142.1 GiB
drwxr-xr-x 66 root admin 2112 Dec 12 15:13 .
drwxr-xr-x 85 root admin 2720 Dec 12 15:12 ..
-rw-r--r-- 1 root admin 765305 Oct 3 2018 Atk-1.0.gir
-rw-r--r-- 1 root admin 385468 Jul 7 09:04 Atspi-2.0.gir
-rw-r--r-- 1 root admin 1185 Sep 11 22:07 DBus-1.0.gir
-rw-r--r-- 1 root admin 797 Sep 11 22:07 DBusGLib-1.0.gir
-rw-r--r-- 1 root admin 15670 Jan 9 2019 GDesktopEnums-3.0.gir
-rw-r--r-- 1 root admin 192354 Sep 11 22:07 GIRepository-2.0.gir
-rw-r--r-- 1 root admin 1122 Sep 11 22:07 GL-1.0.gir
-rw-r--r-- 1 root admin 2324777 Sep 11 22:07 GLib-2.0.gir
-rw-r--r-- 1 root admin 13785 Sep 11 22:07 GModule-2.0.gir
-rw-r--r-- 1 root admin 756165 Sep 11 22:07 GObject-2.0.gir
-rw-r--r-- 1 root admin 46464 Oct 4 2018 GSSDP-1.0.gir
-rw-r--r-- 1 root admin 250232 Oct 4 2018 GUPnP-1.0.gir
-rw-r--r-- 1 root admin 25694 Oct 4 2018 GUPnPIgd-1.0.gir
-rw-r--r-- 1 root admin 1278587 Oct 17 04:54 Gdk-3.0.gir
-rw-r--r-- 1 root admin 196860 Oct 1 2018 GdkPixbuf-2.0.gir
-rw-r--r-- 1 root admin 72262 Oct 17 04:54 GdkX11-3.0.gir
-rw-r--r-- 1 root admin 178551 Dec 11 16:29 Geoclue-2.0.gir
-rw-r--r-- 1 root admin 4314168 Sep 11 22:07 Gio-2.0.gir
-rw-r--r-- 1 root admin 383280 Mar 28 2019 Graphene-1.0.gir
-rw-r--r-- 1 root admin 2315350 Oct 31 06:21 Gst-1.0.gir
-rw-r--r-- 1 root admin 17057 Oct 31 06:32 GstAllocators-1.0.gir
-rw-r--r-- 1 root admin 89599 Oct 31 06:32 GstApp-1.0.gir
-rw-r--r-- 1 root admin 460229 Oct 31 06:32 GstAudio-1.0.gir
-rw-r--r-- 1 root admin 600859 Oct 31 06:21 GstBase-1.0.gir
-rw-r--r-- 1 root admin 175429 Oct 31 06:21 GstCheck-1.0.gir
-rw-r--r-- 1 root admin 42877 Oct 31 06:21 GstController-1.0.gir
-rw-r--r-- 1 root admin 481365 Oct 31 06:32 GstGL-1.0.gir
-rw-r--r-- 1 root admin 19310 Dec 11 16:33 GstInsertBin-1.0.gir
-rw-r--r-- 1 root admin 236758 Dec 11 16:33 GstMpegts-1.0.gir
-rw-r--r-- 1 root admin 40052 Oct 31 06:21 GstNet-1.0.gir
-rw-r--r-- 1 root admin 195560 Oct 31 06:32 GstPbutils-1.0.gir
-rw-r--r-- 1 root admin 105609 Dec 11 16:33 GstPlayer-1.0.gir
-rw-r--r-- 1 root admin 269287 Oct 31 06:32 GstRtp-1.0.gir
-rw-r--r-- 1 root admin 234117 Oct 31 06:32 GstRtsp-1.0.gir
-rw-r--r-- 1 root admin 205210 Oct 31 06:32 GstSdp-1.0.gir
-rw-r--r-- 1 root admin 84453 Oct 31 06:32 GstTag-1.0.gir
-rw-r--r-- 1 root admin 698674 Oct 31 06:32 GstVideo-1.0.gir
-rw-r--r-- 1 root admin 47186 Dec 11 16:33 GstWebRTC-1.0.gir
-rw-r--r-- 1 root admin 7161137 Oct 17 04:54 Gtk-3.0.gir
-rw-r--r-- 1 root admin 163868 Nov 11 21:28 JavaScriptCore-4.0.gir
-rw-r--r-- 1 root admin 241465 Oct 4 2018 Json-1.0.gir
-rw-r--r-- 1 root admin 162970 Dec 11 16:30 Nice-0.1.gir
-rw-r--r-- 1 root admin 34055 Oct 24 06:58 Notify-0.7.gir
-rw-r--r-- 1 root admin 651930 Oct 1 2018 Pango-1.0.gir
-rw-r--r-- 1 root admin 40518 Oct 1 2018 PangoCairo-1.0.gir
-rw-r--r-- 1 root admin 15105 Oct 1 2018 PangoFT2-1.0.gir
-rw-r--r-- 1 root admin 31675 Oct 1 2018 PangoXft-1.0.gir
-rw-r--r-- 1 root admin 416896 Oct 12 14:00 Poppler-0.18.gir
-rw-r--r-- 1 root admin 69453 Oct 29 23:55 Rsvg-2.0.gir
-rw-r--r-- 1 root admin 335738 Oct 24 07:08 Secret-1.gir
-rw-r--r-- 1 root admin 909084 Oct 4 2018 Soup-2.4.gir
-rw-r--r-- 1 root admin 3535 Oct 4 2018 SoupGNOME-2.4.gir
-rw-r--r-- 1 root admin 886109 Nov 11 22:23 WebKit2-4.0.gir
-rw-r--r-- 1 root admin 1358195 Nov 11 22:23 WebKit2WebExtension-4.0.gir
-rw-r--r-- 1 root admin 23122 Sep 11 22:07 cairo-1.0.gir
-rw-r--r-- 1 root admin 620 Sep 11 22:07 fontconfig-2.0.gir
-rw-r--r-- 1 root admin 768 Sep 11 22:07 freetype2-2.0.gir
-rw-r--r-- 1 root admin 10857 Sep 11 22:07 gir-1.2.rnc
-rw-r--r-- 1 root admin 938 Sep 11 22:07 libxml2-2.0.gir
-rw-r--r-- 1 root admin 611 Sep 11 22:07 win32-1.0.gir
-rw-r--r-- 1 root admin 361 Sep 11 22:07 xfixes-4.0.gir
-rw-r--r-- 1 root admin 745 Sep 11 22:07 xft-2.0.gir
-rw-r--r-- 1 root admin 2325 Sep 11 22:07 xlib-2.0.gir
-rw-r--r-- 1 root admin 808 Sep 11 22:07 xrandr-1.3.gir
I'm also able to compile other programs that use WebKitGTK+. Any help or guidance would be greatly appreciated. Thank you!
I'm trying to run some javascript in a webview.
To do this, I'm essentially implemented a simplified version of the example in the documentation: https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#webkit-web-view-run-javascript-finish.
Full example:
(cl:defpackage #:gir-test-web
(:use #:cl))
(in-package #:gir-test-web)
(defvar *gtk* (gir:ffi "Gtk"))
(defvar *gdk* (gir:ffi "Gdk"))
;; (defvar *glib* (gir:ffi "GLib"))
(defvar *gio* (gir:ffi "Gio"))
(defvar *webkit* (gir:require-namespace "WebKit2"))
(defvar *result* nil)
(defvar *callback-view* nil)
(cffi:defcallback javascript-result-callback :void ((gobject :pointer)
(gasyncres :pointer)
(user_data :pointer))
(let ((res (gir::build-object-ptr (gir:nget *gio* "AsyncResult") gasyncres)))
(let ((js-result (gir:invoke (*callback-view* 'run-javascript-finish)
res)))
(setf *result* (gir:invoke (js-result 'get-js-value))))))
(defun get-title (view)
(setf *callback-view* view)
(gir:invoke (view 'run-javascript)
"document.title;"
(cffi:null-pointer)
(cffi:get-callback 'javascript-result-callback)
(cffi:null-pointer)))
(defun event->key (ev)
(let ((k (gir:field ev "keyval"))
(state (gir:field ev "state"))
(modifiers (list)))
(dolist (mdef '((#b1 :shift)
(#b100 :ctrl)
(#b1000 :alt)))
(destructuring-bind (int modifier)
mdef
(unless (zerop (logand int state))
(push modifier modifiers))))
(values (case k
(65361 :left-arrow)
(65362 :up-arrow)
(65363 :right-arrow)
(65364 :down-arrow)
(otherwise k))
modifiers)))
(defun main ()
(gir:invoke (*gtk* 'init) nil)
(let ((window (gir:invoke (*gtk* "Window" 'new)
(gir:nget *gtk* "WindowType" :toplevel)))
(view (gir:invoke (*webkit* "WebView" 'new)))
(button (gir:invoke (*gtk* "Button" 'new-with-label) "Hello, world!"))
(button2 (gir:invoke (*gtk* "Button" 'new-with-label) "Dummy!"))
(box (gir:invoke (*gtk* "Box" 'new)
(gir:nget *gtk* "Orientation" :vertical)
0)))
(gir::g-signal-connect-data (gir::this-of window)
"destroy"
(cffi:foreign-symbol-pointer "gtk_main_quit")
(cffi:null-pointer)
(cffi:null-pointer)
0)
(gir:connect window :key-press-event
(lambda (widget event)
(declare (ignore widget))
(let ((event-object
(gir::build-struct-ptr (gir:nget *gdk* "EventKey")
event)))
(case (nth-value 0 (event->key event-object))
(103 (get-title view))))))
(gir:invoke (view 'load_uri) "https://gnu.org")
(gir:invoke (box 'add) button)
(gir:invoke (box 'pack-start) view t t 0)
(gir:invoke (box 'add) button2)
(gir:invoke (window 'add) box)
(gir:invoke (window 'show-all))
(gir:invoke (*gtk* 'main))))
Compile, switch to this package and call (main)
). It should show a window with a webview. Pressing g
should call the document.title;
javascript.
Sadly, *result*
remains nil after the call, while I'd expect a JSCValue.
Any idea?
And thanks for all the precious help you've given me so far :)
I was wondering if anyone could shed some light on why this is occurring. I am using SBCL v2.0.0.
If I load a REPL, and do this (defparameter *ns* (gir:require-namespace "Arrow"))
, everything works as intended.
If I do (asdf:make :my-system)
(i.e. save-lis-and-die) on a system which utilizes cl-apache-arrow
, all operations involving that *ns*
parameter fail with something like:
** (process:1840): CRITICAL **: 02:02:15.405: g_irepository_find_by_name: assertion 'typelib != NULL' failed
WARNING: No such FFI name ArrowFileWriter
If I replace all instances of *ns*
with (gir:require-namespace "Arrow")
, everything works as expected again. Something is not surviving the persistence of the core, and I was hoping someone more familiar with the internals of this library would know what.
If free-from-foreign
is false, mem-get
will return NIL when it should return the actual object: https://github.com/andy128k/cl-gobject-introspection/blob/master/src/function.lisp#L312
Here's my fix
(if-let ((obj (build-object-ptr gir-class ptr)))
(if free-from-foreign
(object-setup-gc obj :everything)
obj))))))
I think this was just a small mistake with the position of obj, since it was on the ELSE-FORM of the if-let macro. If this was a plain "let", the previous version would be just fine since obj would be returned either way.
IMHO, there is two issues for current cl-gobject-introspection
interface.
For example: (call gtk "WindowType" :toplevel)
According to my understanding of gobject object system, library (gtk
here), class, enumeration are all kind of namespace. To get a
function/const/enum/class from the library is kind of namespace
access, to get a method from object is kind of namespace access too.
So I suggest to introduce that kind of concept into
cl-gobject-introspection too. Add a new function named nget
(namespace get) as follow:
(nget gtk "WindowType" :toplevel) -> get enum value
(nget gtk "Window" 'new) -> get a class constructor function
(nget window 'add) -> get a method
For example:
(call gtk "Window" 'new 0)
Where, "gtk", "Window" "'new" is used to get the constructor
function, "0" is the parameter for the function. I think it may be
better to do some distinguish between them. Such as something like:
(call (nget gtk "Window" 'new) 0)
To save some typing, we can introduce a macro say gcall (gobject call)
as follow:
(gcall (gtk "Window" 'new) 0)
In this way, (gtk "Window" 'new) can be seen as function and "0" can
be seen as parameters.
And after some experiment, I found it is not hard to implement this.
What do you think about this?
I have to use a private function info-of. Is there a better way to do it?
(assert (equal "ApplicationWindow"
(gir:info-get-name (gir::info-of (gir:gir-class-of window)))))
I fix it with this patch:
diff --git a/test/hello.lisp b/test/hello.lisp
index c83812e..9e80b8d 100644
--- a/test/hello.lisp
+++ b/test/hello.lisp
@@ -6,7 +6,7 @@
(cffi:defcallback hello :void ((btn-ptr :pointer))
(let ((button (funcall (gir:nget *gtk* "Button") btn-ptr)))
- (gir:invoke (button :set-properties!) 'label "OK"))
+ (setf (gir:property button 'label) "OK"))
(format t "Hello, pressed~%"))
(defun main ()
@@ -14,7 +14,7 @@
(let ((window (gir:invoke (*gtk* "Window" 'new)
(gir:nget *gtk* "WindowType" :toplevel)))
(button (gir:invoke (*gtk* "Button" 'new-with-label) "Hello, world!")))
- (gir::g-signal-connect-data (gir:nget window :this)
+ (gir::g-signal-connect-data (gir::object-this window)
"destroy"
(cffi:foreign-symbol-pointer "gtk_main_quit")
(cffi:null-pointer)
@@ -28,7 +28,7 @@
;; 0)
(gir:connect button :clicked
(lambda (button)
- (gir:invoke (button :set-properties!) 'label "OK")))
+ (setf (gir:property button 'label) "OK")))
(gir:invoke (window 'add) button)
(gir:invoke (window 'show-all))
(gir:invoke (*gtk* 'main))))
In README.md, there is:
"
(repository class-name constructor-name) -> function
"
But I cannot find the definition of repository in source code. Where is it?
The above line signals TODO ARRAY
error when I try to build the test system.
maze example works well if I use my touchpad. The error does not
occur also if I turn on the mouse but beforehand use the touchpad
some time and only afterwards begin to use the mouse. The error
occurs with high probability if I start
maze-example::edit-maze-in-window! app and begin to interact with
window by the mouse immediately. Backtrace:
0: ((FLET SB-UNIX::RUN-HANDLER :IN SB-SYS:ENABLE-INTERRUPT) 8 #.(SB-SYS:INT-SAP #X7FFFF4B35170) #.(SB-SYS:INT-SAP #X7FFFF4B35040))
Locals:
SB-DEBUG::MORE = (8 #.(SB-SYS:INT-SAP #X7FFFF4B35170) #.(SB-SYS:INT-SAP #X7FFFF4B35040))
1: ("foreign function: call_into_lisp")
[No Locals]
2: ("foreign function: funcall3")
[No Locals]
3: ("foreign function: interrupt_handle_now")
[No Locals]
4: ("foreign function: interrupt_handle_now_handler")
[No Locals]
5: ((LAMBDA (&REST GIR::ARGS-IN) :IN GIR::BUILD-FUNCTION))
Locals:
GIR::ARGS-IN = NIL
GIR::OUT-ARGS = NIL
GIR::PURE-IN-ARGS = NIL
GIR::RET-VAL = #<GIR::RETURN-VALUE {1004D0E163}>
6: (EDIT-MAZE-IN-WINDOW! #S(MAZE :HEIGHT 8 :WIDTH 10 :SN-WALLS #2A((T T T T T T ...) (T NIL NIL T T T ...) (NIL NIL NIL T NIL NIL ...) (NIL NIL T NIL NIL NIL ...) (NIL T NIL T NIL T ...) (NIL T T T NIL N..
Locals:
MAZE = #S(MAZE ..)
7: (SB-INT:SIMPLE-EVAL-IN-LEXENV (EDIT-MAZE-IN-WINDOW! *MAZE*) #<NULL-LEXENV>)
Locals:
SB-KERNEL:LEXENV = #<NULL-LEXENV>
SB-IMPL::ORIGINAL-EXP = (EDIT-MAZE-IN-WINDOW! *MAZE*)
8: (EVAL (EDIT-MAZE-IN-WINDOW! *MAZE*))
Locals:
System info: GNU/Linux, sbcl 1.4.0
I can not find a way to add in radio buttons. I just get the warning:
WARNING: No such FFI name RadioButton
I have tried rewriting this a number of different ways but still nothing works.
Full backtrace:
Unhandled SIMPLE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
{10005604C3}>:
TODO ARRAY
Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {10005604C3}>
0: (SB-DEBUG::DEBUGGER-DISABLED-HOOK #<SIMPLE-ERROR "TODO ~A" {10035133D3}> #<unused argument> :QUIT T)
1: (SB-DEBUG::RUN-HOOK SB-EXT:*INVOKE-DEBUGGER-HOOK* #<SIMPLE-ERROR "TODO ~A" {10035133D3}>)
2: (INVOKE-DEBUGGER #<SIMPLE-ERROR "TODO ~A" {10035133D3}>)
3: (ERROR "TODO ~A" :ARRAY)
4: (TYPE-INFO->CFFI-TYPE #<TYPE-INFO {1003513373}>)
5: ((:METHOD PP-INFO (FUNCTION-INFO)) #<FUNCTION-INFO {10031E40D3}>) [fast-method]
6: ((SB-C::TOP-LEVEL-FORM (LET ((REPO (REPOSITORY-GET-DEFAULT))) (REPOSITORY-REQUIRE REPO #1="GIRepository" "2.0") (ITER (FOR INFO IN (REPOSITORY-GET-INFOS REPO #1#)) (FOR PP = (PP-INFO INFO)) (WHEN PP (PPRINT PP)))))) [toplevel]
7: (SB-FASL::LOAD-FASL-GROUP #S(SB-FASL::FASL-INPUT :STREAM #<SB-SYS:FD-STREAM for #<(SIMPLE-BASE-STRING 230) file /gnu/store/958sg7fsy9fs0kzxjya7n0z6zljm7m1h-sbcl-cl-gobject-introspection-0.3-0.7b703e2/.cache/common-lisp/sbcl-1.5.7-linux-x64/tmp/guix-build-sbcl-cl-gobject-introspection-0.3-0.7b703e2.drv-0/so... {1002E8CECF}> {1002E8D053}> :TABLE #(613 SET *PACKAGE* "GIR-TEST" #<PACKAGE "SB-IMPL"> SB-IMPL::%DEFUN #<PACKAGE "GIR-TEST"> LISPIFY-CLASS CLOSE #<PACKAGE "SB-C"> SB-C:UNWIND WRITE-CHAR ...) :STACK #(0 #<FUNCTION #1=(SB-C::TOP-LEVEL-FORM (LET (#) (REPOSITORY-REQUIRE REPO "GIRepository" "2.0") (ITER # # #))) {52DD8C5B}> 33481 PP-INFO 27465 REPOSITORY-GET-INFOS 19657 REPOSITORY-REQUIRE 13129 REPOSITORY-GET-DEFAULT 6857 #1# ...) :NAME-BUFFER #("\0" "WHENSITORY-GET-DEFAULTRCH-PATHNAME") :DEPRECATED-STUFF NIL :SKIP-UNTIL NIL) NIL)
8: (SB-FASL::LOAD-AS-FASL #<SB-SYS:FD-STREAM for #<(SIMPLE-BASE-STRING 230) file /gnu/store/958sg7fsy9fs0kzxjya7n0z6zljm7m1h-sbcl-cl-gobject-introspection-0.3-0.7b703e2/.cache/common-lisp/sbcl-1.5.7-linux-x64/tmp/guix-build-sbcl-cl-gobject-introspection-0.3-0.7b703e2.drv-0/so... {1002E8CECF}> {1002E8D053}> NIL NIL)
9: ((FLET SB-FASL::THUNK :IN LOAD))
10: (SB-FASL::CALL-WITH-LOAD-BINDINGS #<CLOSURE (FLET SB-FASL::THUNK :IN LOAD) {7FFFF769E75B}> #<SB-SYS:FD-STREAM for #<(SIMPLE-BASE-STRING 230) file /gnu/store/958sg7fsy9fs0kzxjya7n0z6zljm7m1h-sbcl-cl-gobject-introspection-0.3-0.7b703e2/.cache/common-lisp/sbcl-1.5.7-linux-x64/tmp/guix-build-sbcl-cl-gobject-introspection-0.3-0.7b703e2.drv-0/so... {1002E8CECF}> {1002E8D053}>)
11: ((FLET SB-FASL::LOAD-STREAM :IN LOAD) #<SB-SYS:FD-STREAM for #<(SIMPLE-BASE-STRING 230) file /gnu/store/958sg7fsy9fs0kzxjya7n0z6zljm7m1h-sbcl-cl-gobject-introspection-0.3-0.7b703e2/.cache/common-lisp/sbcl-1.5.7-linux-x64/tmp/guix-build-sbcl-cl-gobject-introspection-0.3-0.7b703e2.drv-0/so... {1002E8CECF}> {1002E8D053}> T)
12: (LOAD #P#<(SIMPLE-ARRAY CHARACTER (225)) /gnu/store/958sg7fsy9fs0kzxjya7n0z6zljm7m1h-sbcl-cl-gobject-introspection-0.3-0.7b703e2/.cache/common-lisp/sbcl-1.5.7-linux-x64/tmp/guix-build-sbcl-cl-gobject-introspection-0.3-0.7b703e2.drv-0/source/... {1003536A6F}> :VERBOSE NIL :PRINT NIL :IF-DOES-NOT-EXIST T :EXTERNAL-FORMAT :DEFAULT)
13: (UIOP/UTILITY:CALL-WITH-MUFFLED-CONDITIONS #<CLOSURE (LAMBDA NIL :IN UIOP/LISP-BUILD:LOAD*) {1002E8B0DB}> ("Overwriting already existing readtable ~S." #(#:FINALIZERS-OFF-WARNING :ASDF-FINALIZERS)))
14: ((SB-PCL::EMF ASDF/ACTION:PERFORM) #<unused argument> #<unused argument> #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-gobject-introspection-test" "test/test-generation">)
15: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
16: ((:METHOD ASDF/ACTION:PERFORM :AROUND (ASDF/LISP-ACTION:LOAD-OP ASDF/LISP-ACTION:CL-SOURCE-FILE)) #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-gobject-introspection-test" "test/test-generation">) [fast-method]
17: ((:METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS (ASDF/LISP-ACTION:LOAD-OP ASDF/LISP-ACTION:CL-SOURCE-FILE)) #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-gobject-introspection-test" "test/test-generation">) [fast-method]
18: ((:METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS :AROUND (T T)) #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-gobject-introspection-test" "test/test-generation">) [fast-method]
19: ((:METHOD ASDF/PLAN:PERFORM-PLAN (T)) #<ASDF/PLAN:SEQUENTIAL-PLAN {1001E400F3}>) [fast-method]
20: ((FLET SB-C::WITH-IT :IN SB-C::%WITH-COMPILATION-UNIT))
21: ((:METHOD ASDF/PLAN:PERFORM-PLAN :AROUND (T)) #<ASDF/PLAN:SEQUENTIAL-PLAN {1001E400F3}>) [fast-method]
22: ((:METHOD ASDF/OPERATE:OPERATE (ASDF/OPERATION:OPERATION ASDF/COMPONENT:COMPONENT)) #<ASDF/LISP-ACTION:TEST-OP > #<ASDF/SYSTEM:SYSTEM "cl-gobject-introspection"> :PLAN-CLASS NIL :PLAN-OPTIONS NIL) [fast-method]
23: ((SB-PCL::EMF ASDF/OPERATE:OPERATE) #<unused argument> #<unused argument> #<ASDF/LISP-ACTION:TEST-OP > #<ASDF/SYSTEM:SYSTEM "cl-gobject-introspection">)
24: ((LAMBDA NIL :IN ASDF/OPERATE:OPERATE))
25: ((:METHOD ASDF/OPERATE:OPERATE :AROUND (T T)) #<ASDF/LISP-ACTION:TEST-OP > #<ASDF/SYSTEM:SYSTEM "cl-gobject-introspection">) [fast-method]
26: ((SB-PCL::EMF ASDF/OPERATE:OPERATE) #<unused argument> #<unused argument> ASDF/LISP-ACTION:TEST-OP "cl-gobject-introspection")
27: ((LAMBDA NIL :IN ASDF/OPERATE:OPERATE))
28: ((:METHOD ASDF/OPERATE:OPERATE :AROUND (T T)) ASDF/LISP-ACTION:TEST-OP "cl-gobject-introspection") [fast-method]
29: (ASDF/SESSION:CALL-WITH-ASDF-SESSION #<CLOSURE (LAMBDA NIL :IN ASDF/OPERATE:OPERATE) {1001E3157B}> :OVERRIDE T :KEY NIL :OVERRIDE-CACHE T :OVERRIDE-FORCING NIL)
30: ((LAMBDA NIL :IN ASDF/OPERATE:OPERATE))
31: (ASDF/SESSION:CALL-WITH-ASDF-SESSION #<CLOSURE (LAMBDA NIL :IN ASDF/OPERATE:OPERATE) {1001E2ED0B}> :OVERRIDE NIL :KEY NIL :OVERRIDE-CACHE NIL :OVERRIDE-FORCING NIL)
32: ((:METHOD ASDF/OPERATE:OPERATE :AROUND (T T)) ASDF/LISP-ACTION:TEST-OP "cl-gobject-introspection") [fast-method]
33: (ASDF/OPERATE:TEST-SYSTEM "cl-gobject-introspection")
34: (SB-INT:SIMPLE-EVAL-IN-LEXENV (ASDF/OPERATE:TEST-SYSTEM "cl-gobject-introspection") #<NULL-LEXENV>)
35: (EVAL (ASDF/OPERATE:TEST-SYSTEM "cl-gobject-introspection"))
36: (SB-IMPL::PROCESS-EVAL/LOAD-OPTIONS ((:EVAL . "(require :asdf)") (:EVAL . #<(SIMPLE-ARRAY CHARACTER (233)) (asdf:load-asd (truename "/gnu/store/958sg7fsy9fs0kzxjya7n0z6zljm7m1h-sbcl-cl-gobject-introspection-0.3-0.7b703e2/share/common-lisp/sbcl-source/cl-gobject-introspection/cl-gobject-introspection.asd") ... {100182036F}>) (:EVAL . "(when (uiop:file-exists-p \"cl-gobject-introspection-tests.asd\") (asdf:load-asd (truename \"cl-gobject-introspection-tests.asd\")))") (:EVAL . "(when (uiop:file-exists-p \"cl-gobject-introspection-test.asd\") (asdf:load-asd (truename \"cl-gobject-introspection-test.asd\")))") (:EVAL . "(when (uiop:file-exists-p \"tests.asd\") (asdf:load-asd (truename \"tests.asd\")))") (:EVAL . "(when (uiop:file-exists-p \"test.asd\") (asdf:load-asd (truename \"test.asd\")))") (:EVAL . "(asdf:test-system \"cl-gobject-introspection\")") (:QUIT)))
37: (SB-IMPL::TOPLEVEL-INIT)
38: ((FLET SB-UNIX::BODY :IN SB-EXT:SAVE-LISP-AND-DIE))
39: ((FLET "WITHOUT-INTERRUPTS-BODY-14" :IN SB-EXT:SAVE-LISP-AND-DIE))
40: ((LABELS SB-IMPL::RESTART-LISP :IN SB-EXT:SAVE-LISP-AND-DIE))
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.