public inbox for guile-gtk@sourceware.org
 help / color / mirror / Atom feed
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


  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).