(in-package :cl-user) (use-package :noffi) ;; Install noffi syntax. The `T' here says, that we want to clobber #\_ ;; as a non-terminating character instead of the more polite dispatch ;; macro character for "#_". (noffi-syntax t) ;; PKG-USE invokes pkg-config for us to figure out where to find ;; includes and libs. (pkg-use ("gtk+-2.0") "#include ") ;; Define the callback function that we want to install on a button; ;; BUTTON-CLICKED-CALLBACK becomes something that can be passed around ;; as a Pascal^WC function pointer. (defcfun (button-clicked-callback _) ((widget _) (data _)) (declare (ignore data)) (warn "~S was hit. Quch!" widget)) (defun run () ;; We need to call gtk_init with some fake argc/argv (clet ((argc _ 1) (argv _ (list "noffi-demo"))) (_gtk_init (c-addr-of argc) (c-addr-of argv))) ;; Make a window and a butten (let ((window (_gtk_window_new _GTK_WINDOW_TOPLEVEL)) (button (_gtk_button_new_with_label "Hit me"))) ;; Connect the "clicked" signal. Note that gtk_signal_connect really is ;; a C macro inside. As are those GTK_FOO() runtime checks. (_gtk_signal_connect (_GTK_OBJECT button) "clicked" (_GTK_SIGNAL_FUNC button-clicked-callback) _NULL) (_gtk_container_add (#_GTK_CONTAINER window) button) (_gtk_widget_show button) (_gtk_widget_show window) ;; Let the main loop run in a different thread (ccl:process-run-function "gtk event loop" (lambda () (_gtk_main)))))