Next: , Previous: , Up: FFI


7 Hello World

This node includes the C declarations and Scheme code required to implement Havoc Pennington’s Hello World example from GGAD. For an extra, Schemely treat, its delete_event callback is a Scheme procedure closed over a binding of counter that is used to implement some impertinent behavior.

#| -*-Scheme-*-
This is Havoc Pennington's Hello World example from GGAD, in the raw
FFI. Note that no arrangements have been made to de-register the
callbacks. |#
(declare (usual-integrations))
(C-include "prhello")
(define (hello)
 (C-call "gtk_init" 0 null-alien)
 (let ((window (let ((alien (make-alien '|GtkWidget|)))
		 (C-call "gtk_window_new" alien
			 (C-enum "GTK_WINDOW_TOPLEVEL"))
		 (if (alien-null? alien) (error "Could not create window."))
		 alien))
	(button (let ((alien (make-alien '|GtkWidget|)))
		 (C-call "gtk_button_new" alien)
		 (if (alien-null? alien) (error "Could not create button."))
		 alien))
	(label (let ((alien (make-alien '|GtkWidget|)))
		 (C-call "gtk_label_new" alien "Hello, World!")
		 (if (alien-null? alien) (error "Could not create label."))
		 alien)))
 (C-call "gtk_container_add" button label)
 (C-call "gtk_container_add" window button)
 (C-call "gtk_window_set_title" window "Hello")
 (C-call "gtk_container_set_border_width" button 10)
 (let ((counter 0))
 (C-call "g_signal_connect" window "delete_event"
	 (C-callback "delete_event")	;trampoline
	 (C-callback			;callback ID
	 (lambda (w e)
		 (outf-error ";Delete me "(- 2 counter)" times.\n")
		 (set! counter (1+ counter))
		 ;; Three or more is the charm.
		 (if (> counter 2)
		 (begin
		 (C-call "gtk_main_quit")
		 0)
		 1))))
 (C-call "g_signal_connect" button "clicked"
	 (C-callback "clicked")	;trampoline
	 (C-callback			;callback ID
	 (lambda (w)
		 (let ((gstring (make-alien '(* |gchar|))))
		 (C-call "gtk_label_get_text" gstring label)
		 (let ((text (c-peek-cstring gstring)))
		 (C-call "gtk_label_set_text" label
			 (list->string (reverse! (string->list text))))))
		 unspecific))))
 (C-call "gtk_widget_show_all" window)
 (C-call "gtk_main")
 window))

Here are the C declarations.

#| -*-Scheme-*-
C declarations for prhello.scm. |#
(typedef gint int)
(typedef guint uint)
(typedef gchar char)
(typedef gboolean gint)
(typedef gpointer (* mumble))
(extern void
	gtk_init
	(argc (* int))
	(argv (* (* (* char)))))
(extern (* GtkWidget)
	gtk_window_new
	(type GtkWindowType))
(typedef GtkWindowType
	 (enum
	 (GTK_WINDOW_TOPLEVEL)
	 (GTK_WINDOW_POPUP)))
(extern (* GtkWidget)
	gtk_button_new)
(extern (* GtkWidget)
	gtk_label_new
	(str (* (const char))))
(extern void
	gtk_container_add
	(container (* GtkContainer))
	(widget (* GtkWidget)))
(extern void
	gtk_window_set_title
	(window (* GtkWindow))
	(title (* (const gchar))))
(extern void
	gtk_container_set_border_width
	(container (* GtkContainer))
	(border_width guint))
(extern void
	gtk_widget_show_all
	(widget (* GtkWidget)))
(extern void
	g_signal_connect
	(instance gpointer)
	(name (* gchar))
	(CALLBACK GCallback)
	(ID gpointer))
(typedef GCallback (* mumble))
(callback gboolean
	 delete_event
	 (window (* GtkWidget))
	 (event (* GdkEventAny))
	 (ID gpointer))
(callback void
	 clicked
	 (widget (* GtkWidget))
	 (ID gpointer))
(extern void
	gtk_widget_destroy
	(widget (* GtkWidget)))
(extern (* (const gchar))
	gtk_label_get_text
	(label (* GtkLabel)))
(extern void
	gtk_label_set_text
	(label (* GtkLabel))
	(str (* (const char))))
(extern void gtk_main)
(extern void gtk_main_quit)

Next: GNU Free Documentation License, Previous: Compiling and Linking, Up: FFI

AltStyle によって変換されたページ (->オリジナル) /