From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Neil Jerram Newsgroups: gmane.lisp.guile.user Subject: Re: guile as extension language Date: 07 Apr 2002 15:38:14 +0100 Sender: guile-user-admin@gnu.org Message-ID: References: <200204062347.g36Nl7l21986@mr-ed.jpl.nasa.gov> <1018150155.1544.17.camel@maybelline> NNTP-Posting-Host: localhost.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1018190762 3137 127.0.0.1 (7 Apr 2002 14:46:02 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Sun, 7 Apr 2002 14:46:02 +0000 (UTC) Cc: guile-user@gnu.org Original-Received: from fencepost.gnu.org ([199.232.76.164]) by main.gmane.org with esmtp (Exim 3.33 #1 (Debian)) id 16uDvd-0000oU-00 for ; Sun, 07 Apr 2002 16:46:02 +0200 Original-Received: from localhost ([127.0.0.1] helo=fencepost.gnu.org) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 16uDuq-0007ip-00; Sun, 07 Apr 2002 10:45:12 -0400 Original-Received: from mail.uklinux.net ([80.84.72.21] helo=s1.uklinux.net) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 16uDtl-0007fo-00 for ; Sun, 07 Apr 2002 10:44:05 -0400 Original-Received: from portalet.ossau.uklinux.net (IDENT:root@ppp-1a-5.3com.telinco.net [212.159.128.5]) by s1.uklinux.net (8.11.6/8.11.6) with ESMTP id g37Ehr809778; Sun, 7 Apr 2002 15:43:55 +0100 Original-Received: from laruns.ossau.uklinux.net.ossau.uklinux.net (neil@laruns.ossau.uklinux.net [192.168.1.3]) by portalet.ossau.uklinux.net (8.9.3/8.8.7) with ESMTP id PAA17587; Sun, 7 Apr 2002 15:41:49 +0100 Original-To: Paul Emsley Original-Lines: 160 User-Agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7 Errors-To: guile-user-admin@gnu.org X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.0.8 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.lisp.guile.user:145 X-Report-Spam: http://spam.gmane.org/gmane.lisp.guile.user:145 >>>>> "Paul" == Paul Emsley writes: Paul> On Sun, 2002-04-07 at 00:47, Matthew R Wette wrote: >> Matthew R Wette writes ... >> > >> > How is Guile intended to be used as an extension language? >> > >> My interest here was in exploring the scope of work required to >> make a Guile extension for Dia (the gnome graphics app). >> Paul> This is not a reply really, more of a me-too. I've replied separately to Matthew's question, and most of what I say there should apply to your case as well, when it comes to deciding what you want your script to be able to control, and how to achieve that. Which just leaves ... Paul> I have recently written a program in C/C++ using gtk [1] and now want to Paul> type a script (say) (or commands) at the console/terminal. I would like Paul> this to be interpreted by guile but cannot see how since gtk has the Paul> control passed completely to it using gtk_main(). This question keeps cropping up, so this time I'll try my best to give a definitive answer. 1. Do you really want this I/O at the console? You could choose instead to use a GtkEntry widget for typing in, and a GtkText for the output, and include these widgets in your overall GUI. Then everything would be under the control of gtk_main(), so you avoid the main issue. If you followed this route, the basic mechanism for getting commands evaluated would be to add an "activate" signal handler to the GtkEntry widget that calls scm_c_eval_string to evaluate the line of input in the widget. 2. If you definitely want I/O at the console, you can use gtk_idle_add to register a function that gtk_main should call when nothing is happening in the GUI. The function that you register should - do a non-blocking select on standard input to find whether there's anything to read - read characters 1 at a time into an input buffer - when newline is read, call scm_c_eval_string to evaluate the buffered input. 3. However, both the above are suboptimal for two main reasons: 3.1. They only work if the expression entered on a line is always balanced. 3.2. They don't support the reading of input that is not meant to be evaluated, or that should be evaluated in a different way. (e.g. input for the Guile debugger). What you really want, IMO, to overcome these issues, is for the GtkEntry widget (case 1) or the console (case 2) to act like input ports with two properties: - From the point of view of code like `(top-repl)' (which implements the standard Guile REPL), they can be used as input ports just like any others. - But, whenever there isn't any immediate input available, they call gtk_main. The good news is that Scheme continuations make it possible to do exactly this! Suppose in C that you - define and export a Scheme primitive `call-gtk-main', which just calls gtk_main - define and export a Scheme primitive `store-continuation', which saves its continuation argument in a global variable - write a Gtk idle function `check_stdin', which checks for input available on standard input and, if there is any, calls the continuation stored above - use gtk_idle_add to register this idle function with gtk_main. Now you can make a soft input port with this read-char procedure: (lambda () (call-with-current-continuation (lambda (cont) (store-continuation cont) (call-gtk-main))) (read-char standard-input)) (This is for case 2. For case 1 you need something a bit trickier, where the continuation is called from the "activate" handler, and the read-char procedure uses an input buffer.) Finally, to get everything rolling, you need to - do all your usual application initialization - define the soft port as shown above, and call it, say, `soft-port' - evaluate `(set-current-input-port soft-port)' - evaluate `(top-repl)'. (Probably the last 3 steps are most conveniently achieved by loading a Scheme file.) For a working example of approach 3, using guile-gtk and the GtkEntry widget, you might like to grab my guile-gui distro from http://www.ossau.uklinux.net/guile. Paul> Is scm_init_guile() really the way to do it? I got the impression that Paul> it was not, if I wanted portability (and I do). scm_init_guile is mostly a red herring. Since you have control of your source code's main function, you can just as easily do the scm_boot_guile structure: - main () - scm_boot_guile (..., inner_main, ...) - inner_main () - rest of application as the scm_init_guile structure: - main () - scm_init_guile () - rest of application It may be true that scm_init_guile is marginally less portable; I don't know for sure. (scm_init_guile is designed for libraries that don't have access to main().) Paul> I initially thought that that guile + gtk (not guile-gtk) would be Paul> common combination and tried to find examples to see how they did it, Paul> but I could not. Can you recommend anything? Bill Schottstaedt has previously posted examples using both Motif and Gtk, and Ariel Rios has written a `GuileRepl' widget using Gtk. All of these are examples of case 1 above. I'd guess that Bill's example is available in the Snd source, and Ariel's in Gnome CVS. Paul> I thought that converting to guile-gtk, but since I was using glade and Paul> gtkglarea, I was a bit nervous about doing that. Should I have been? Suggest looking at guile-gtk (and perhaps also my guile-gui) to see what guile-gtk can do for you. Given that you're already using glade, it might be that the only thing of use to you would be calling `gtk-main' from Scheme instead of `gtk_main' from C - i.e. not much difference! Neil _______________________________________________ Guile-user mailing list Guile-user@gnu.org http://mail.gnu.org/mailman/listinfo/guile-user