From: Steve Tell <tell@telltronics.org>
To: Guile-GTK List <guile-gtk@sourceware.cygnus.com>,
Guile Mailing List <guile@sourceware.cygnus.com>
Subject: Re: select+read on socket in guile,guile-gtk
Date: Wed, 21 Jun 2000 21:50:00 -0000 [thread overview]
Message-ID: <Pine.LNX.4.21.0006220031560.31348-100000@ariel.lan.telltronics.org> (raw)
In-Reply-To: <Pine.LNX.4.21.0006210022070.30497-100000@ariel.lan.telltronics.org>
While mulling over the comments from Chris C. and Gary H. (thanks!), and
poking about the source code preparing to write some guile port
extensions, I found a couple of read-made ways to accomplish what I need
for now.
On Wed, 21 Jun 2000, I wrote:
> if guile's cooperative threads play nice with guile-gtk -
> Can I create and maniuplate Gtk+ GUIs from any thread?
Turns out that with a little fiddling, this works after a fashion;
example program attached.
> On Mon, 19 Jun 2000, I wrote:
> > Does guile-gtk provide a way to hook (file descriptors from) guile ports
> > into the Gtk+ select loop? Glib's GIOChannel's perhaps?
Turns out that Gtk+ has such a facility, and guile-gtk already exposes it:
gtk-input-add
> > What I'm ultimately trying to do is arrange for a procedure to get called
> > with complete lines read from a connected TCP socket, so that information
> > recieved from the server at the other end can be used to update
> > items in a guile-gtk interface.
Two short example programs in this direction are attached, tested with a
freshly-compiled guile-1.4 and guile-gtk-0.18 (with Greg Badros' patch for
smob creation)
The first one coaxes guile cooperative threads and guile-gtk into running
together. It ends up burning a lot of CPU time; probably both gtk and
guile are doing nonblocking reads and yielding back and forth.
The second uses gtk-input-add.
Along the way, both illustrate creating a simple TCP client.
Steve
#!/tmp/ggtest/bin/guile-gtk -s
!#
;
; Test 3 using guile to write a simple network client
; that displays results in a Gtk+ window.
; This one uses guile cooperative threads.
;
(use-modules (ice-9 threads))
(use-modules (gtk gtk))
(read-set! keywords 'prefix)
(define (print-to-port port . l)
(for-each (lambda (elem) (display elem port)) l))
(define (print . l)
(apply print-to-port (cons (current-output-port) l)))
; Use any TCP server that periodicly spits back lines of text.
(define IRMP3_PORT 9232)
(define IRMP3_HOST "localhost")
(define mysock (socket AF_INET SOCK_STREAM 0))
(connect mysock AF_INET (car (hostent:addr-list
(gethostbyname IRMP3_HOST)))
IRMP3_PORT)
(define (process-lines p lab) ; loop forever reading and processing lines
(do ((line (read-line mysock) (read-line mysock)))
(#f)
(print "line=\"" line "\"\n")
(gtk-label-set-text lab line)))
(define (make-button parent txt func)
(let* ((btn (gtk-button-new-with-label txt)))
(gtk-container-add parent btn)
(gtk-widget-show btn)
(gtk-signal-connect btn "clicked" func)))
(define (make-label parent txt)
(let* ((lab (gtk-label-new txt)))
(gtk-container-add parent lab)
(gtk-widget-show lab)
lab))
(let* ((window (gtk-widget-new 'GtkWindow
:type 'toplevel
:title "hello world"
:GtkContainer::border_width 10))
(vbox (gtk-vbox-new #f 10))
(statlabel (make-label vbox "(no status yet)")))
(make-button vbox "test me" (lambda () (display "tested.") (newline)))
(make-button vbox "quit" (lambda () (gtk-widget-destroy window)))
(gtk-container-add window vbox)
(gtk-widget-show vbox)
(gtk-widget-show window)
(call-with-new-thread (lambda ()
(print "thread started\n")
(process-lines mysock statlabel)
(print "process-lines returns\n")
(close-port mysock))
(lambda (e) (print "thread error " e "\n")))
; Unless we call guile's thread-yield in the gtk idle loop,
; our thread doesn't run. And unless we call (gtk-update) inside the
; idle procedure, the gtk stuff never gets drawn properly.
; Somthing tells me this isn't the way things are supposed to work...
(gtk-idle-add (lambda ()
(yield)
(gtk-update)
))
(gtk-standalone-main window))
; end of net3g.scm
#!/tmp/ggtest/bin/guile-gtk -s
!#
;
; Test 4 using guile to write a simple network client
; that displays results in a Gtk+ window
; This one uses gtk-input-add
;
(use-modules (gtk gtk))
(use-modules (gtk gdk))
(read-set! keywords 'prefix)
; Use any TCP server that periodicly spits back lines of text.
(define IRMP3_PORT 9232)
(define IRMP3_HOST "localhost")
(define mysock (socket AF_INET SOCK_STREAM 0))
(connect mysock AF_INET (car (hostent:addr-list
(gethostbyname IRMP3_HOST)))
IRMP3_PORT)
(define (read-process-line p lab) ; process single line recieved over socket
(let ((line (read-line p)))
(gtk-label-set-text lab line)
))
(define (make-button parent txt func) ; gtk helpers
(let* ((btn (gtk-button-new-with-label txt)))
(gtk-container-add parent btn)
(gtk-widget-show btn)
(gtk-signal-connect btn "clicked" func)))
(define (make-label parent txt)
(let* ((lab (gtk-label-new txt)))
(gtk-container-add parent lab)
(gtk-widget-show lab)
lab))
(let* ((window (gtk-widget-new 'GtkWindow
:type 'toplevel
:title "hello world"
:GtkContainer::border_width 10))
(vbox (gtk-vbox-new #f 10))
(statlabel (make-label vbox "(no status yet)")))
(make-button vbox "test me" (lambda () (display "tested.") (newline)))
(make-button vbox "quit" (lambda () (gtk-widget-destroy window)))
(gtk-container-add window vbox)
(gtk-widget-show vbox)
(gtk-widget-show window)
(gtk-input-add mysock
1 ; should be 'read (for GDK_INPUT_READ)
; but that causes errors
(lambda (source condition)
(read-process-line mysock statlabel)
))
(gtk-standalone-main window))
; end of net4g.scm
next prev parent reply other threads:[~2000-06-21 21:50 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-06-19 20:17 select+read on socket in gtk,guile-gtk Steve Tell
2000-06-20 21:25 ` select+read on socket in guile,guile-gtk Steve Tell
2000-06-21 21:50 ` Steve Tell [this message]
2000-06-22 2:19 ` Mikael Djurfeldt
2000-06-21 15:27 ` select+read on socket in gtk,guile-gtk Gary Houston
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.21.0006220031560.31348-100000@ariel.lan.telltronics.org \
--to=tell@telltronics.org \
--cc=guile-gtk@sourceware.cygnus.com \
--cc=guile@sourceware.cygnus.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).