cairo: Add a cairo graphics device type. And many fixes...
authorMatt Birkholz <puck@birchwood-abbey.net>
Wed, 28 May 2014 23:04:27 +0000 (16:04 -0700)
committerMatt Birkholz <puck@birchwood-abbey.net>
Wed, 28 May 2014 23:04:27 +0000 (16:04 -0700)
Use the cairo graphics device in the planetarium's mit-snapshot.scm
script to draw the tellurion to a PNG image file without loading Gtk.

Fix the linker commandline(!) and cairo-line-to(!!).  Add cairo-save/
restore around polygon fill options, just because all the rest do.
Punt gtk-graphics/make since a window-less gtk output device is no
longer necessary for planetarium/mit-snapshot.scm.  Clean up some free
variables, other CREF complains, unknown texinfo references, etc.

Rename add-gc-cleanups add-GLIB-cleanups because they are run by the
glib-thread.  Replaced punt-gc-cleanup with execute-glib-cleanup
because you probably should not use the former, rather the latter.

32 files changed:
src/cairo/Makefile.in
src/cairo/cairo-graphics.scm [new file with mode: 0644]
src/cairo/cairo.pkg
src/cairo/cairo.scm
src/cairo/compile.scm
src/gl/check.scm
src/gl/gl-glx.scm
src/gl/gl.pkg
src/glib/gio.scm
src/glib/glib-thread.scm
src/glib/glib.pkg
src/glib/glib.scm
src/glib/glib.texinfo
src/glib/glibio.c
src/glib/gobject.scm
src/gtk/check-doc.scm
src/gtk/fix-layout.scm
src/gtk/gdk.scm
src/gtk/gtk-check.scm
src/gtk/gtk-graphics.scm
src/gtk/gtk-widget.scm
src/gtk/gtk.pkg
src/gtk/gtk.texinfo
src/pango/pango.scm
src/planetarium/Makefile [new file with mode: 0644]
src/planetarium/geometry.scm
src/planetarium/mit-3d.pkg
src/planetarium/mit-cairo.scm [new file with mode: 0644]
src/planetarium/mit-compile.scm
src/planetarium/mit-snapshot.scm
src/planetarium/mit.pkg
src/planetarium/tellurion.scm

index b41e364018eaffd4fe4eae49545cee7376343e74..c4daa61ac72caa7719aec36668cc9492127dde12 100644 (file)
@@ -88,7 +88,7 @@ tags:
 
 cairo-shim.so: cairo-shim.o
        echo "(link-shim)" | $(exe) -- $(LDFLAGS) -o $@ $^ $(LIBS) \
-                       `pkg-config --libs cairo`
+                       `pkg-config --libs pangocairo`
 
 cairo-shim.o: cairo-shim.c
        echo "(compile-shim)" | $(exe) -- $(CPPFLAGS) $(CFLAGS) \
diff --git a/src/cairo/cairo-graphics.scm b/src/cairo/cairo-graphics.scm
new file mode 100644 (file)
index 0000000..f812adc
--- /dev/null
@@ -0,0 +1,315 @@
+#| -*-Scheme-*-
+
+Copyright (C) 2014  Matthew Birkholz
+
+This file is part of an extension to MIT/GNU Scheme.
+
+MIT/GNU Scheme is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+MIT/GNU Scheme is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with MIT/GNU Scheme; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
+USA.
+
+|#
+
+;;;; Scheme Graphics Operations to a Cairo Image Surface.
+;;; package: (cairo graphics)
+
+(define-structure (cairo-graphics
+                  (constructor %make-cairo-graphics
+                               (width height surface context)))
+
+  ;; Cairo Surface -- |cairo_surface_t| alien.
+  surface width height
+
+  ;; Cairo Context -- |cairo_t| alien.
+  context
+
+  ;; Bounds to which context is clipped, scaled, translated...
+  (limits '(-1. -1. 1. 1.))
+  (scale 1.)
+
+  (fgcolor #f)
+  (fgcolor-name #f)
+  (bgcolor #f)
+  (bgcolor-name #f))
+
+(define (make-cairo-graphics width height)
+  (let ((factor (->flonum (/ (min (-1+ width) (-1+ height)) 2))))
+    (if (not (flo:positive? factor))
+       (error "Invalid width x height:" width height))
+    (let* ((surface (cairo-image-surface-create width height))
+          (cr (cairo-create surface))
+          (graphics (%make-cairo-graphics width height surface cr)))
+      (cairo-save cr)
+      (cairo-scale cr factor (flo:negate factor))
+      (set-cairo-graphics-scale! graphics factor)
+      (cairo-set-line-width cr (flo:/ 1.0 factor))
+      (cairo-set-font-matrix cr (let ((k (flo:/ 10.0 factor)))
+                                 (cairo-matrix k 0. 0.
+                                               0. (flo:negate k) 0.)))
+      (cairo-translate cr 1.0 -1.0)
+      (let ((black (->color "black" 'make-cairo-graphics))
+           (white (->color "white" 'make-cairo-graphics)))
+       (cairo-set-source-color cr white)
+       (cairo-paint cr)
+       (cairo-set-source-color cr black)
+       (set-cairo-graphics-bgcolor-name! graphics "white")
+       (set-cairo-graphics-bgcolor! graphics white)
+       (set-cairo-graphics-fgcolor-name! graphics "black")
+       (set-cairo-graphics-fgcolor! graphics black))
+      graphics)))
+
+(define (cairo-graphics/available?) #t)
+
+(define (cairo-graphics/open make-device #!optional width height)
+  (let ((width (if (default-object? width) 512 width))
+       (height (if (default-object? height) 384 height)))
+    (guarantee-positive-fixnum width 'cairo-graphics/open)
+    (guarantee-positive-fixnum height 'cairo-graphics/open)
+    (make-device (make-cairo-graphics width height))))
+
+(define (cairo-graphics/close device)
+  (let ((graphics (graphics-device/descriptor device)))
+    (let ((surface (cairo-graphics-surface graphics)))
+      (if surface
+         (let ((cr (cairo-graphics-context graphics)))
+           (cairo-destroy cr)
+           (set-cairo-graphics-context! graphics #f)
+           (cairo-surface-destroy surface)
+           (set-cairo-graphics-surface! graphics #f))))))
+
+(define (cairo-graphics/device-coordinate-limits device)
+  (let ((graphics (graphics-device/descriptor device)))
+    (values 0 (cairo-graphics-height graphics)
+           (cairo-graphics-width graphics) 0)))
+
+(define (cairo-graphics/coordinate-limits device)
+  (apply values (cairo-graphics-limits (graphics-device/descriptor device))))
+
+(define (cairo-graphics/set-coordinate-limits device x-left y-bottom x-right y-top)
+  (let ((graphics (graphics-device/descriptor device)))
+    (let ((cr (cairo-graphics-context graphics)))
+      (if (zero? (- x-right x-left)) (error "Zero width coordinate limits:" 'x-left x-left 'y-bottom y-bottom 'x-right x-right 'y-top y-top))
+      (if (zero? (- y-bottom y-top)) (error "Zero height coordinate limits:" 'x-left x-left 'y-bottom y-bottom 'x-right x-right 'y-top y-top))
+      (cairo-restore cr)       ;back to device coords.
+      (cairo-save cr)
+      (let ((x-factor (->flonum (/ (-1+ (cairo-graphics-width graphics))
+                                  (- x-right x-left))))
+           (y-factor (->flonum (/ (-1+ (cairo-graphics-height graphics))
+                                  (- y-bottom y-top)))))
+       (cairo-scale cr x-factor y-factor)
+       (let ((factor (flo:min (flo:abs x-factor) (flo:abs y-factor))))
+         (set-cairo-graphics-scale! graphics factor)
+         (cairo-set-line-width cr (flo:/ 1.0 factor))
+         (cairo-set-font-matrix cr (let ((k (flo:/ 10.0 factor)))
+                                     (cairo-matrix k 0. 0.
+                                                   0. (flo:negate k) 0.)))))
+      (cairo-translate cr (- x-left) (- y-top))
+      (let ((fgcolor (cairo-graphics-fgcolor graphics)))
+       (cairo-set-source-color cr fgcolor)))
+    (set-cairo-graphics-limits! graphics (list x-left y-bottom x-right y-top))))
+
+(define (cairo-graphics/clear device)
+  (let ((graphics (graphics-device/descriptor device)))
+    (let ((cr (cairo-graphics-context graphics))
+         (bgcolor (cairo-graphics-bgcolor graphics))
+         (bgcolor-name (cairo-graphics-bgcolor-name graphics)))
+      (set-cairo-graphics-fgcolor! graphics bgcolor)
+      (set-cairo-graphics-fgcolor-name! graphics bgcolor-name)
+      (cairo-set-source-color cr bgcolor)
+      (cairo-reset-clip cr)
+      (cairo-paint cr))))
+
+(define (cairo-graphics/draw-point device x y)
+  (let ((graphics (graphics-device/descriptor device)))
+    (let ((cr (cairo-graphics-context graphics))
+         (x (->flonum x))
+         (y (->flonum y))
+         (radius (/ 3.0 (cairo-graphics-scale device))))
+      (cairo-arc cr x y radius 0. 2pi)
+      (cairo-stroke cr))))
+
+(define (cairo-graphics/draw-line device x-start y-start x-end y-end)
+  (let ((graphics (graphics-device/descriptor device)))
+    (let ((cr (cairo-graphics-context graphics))
+         (x (->flonum x-start))
+         (y (->flonum y-start)))
+      (let ((dx (flo:- (->flonum x-end) x))
+           (dy (flo:- (->flonum y-end) y)))
+       (cairo-move-to cr x y)
+       (cairo-rel-line-to cr dx dy)
+       (cairo-stroke cr)))))
+
+(define (cairo-graphics/draw-text device x y string)
+  (let ((graphics (graphics-device/descriptor device)))
+    (let ((cr (cairo-graphics-context graphics))
+         (x (->flonum x))
+         (y (->flonum y)))
+      (cairo-move-to cr x y)
+      (cairo-show-text cr string))))
+
+(define-integrable 2pi (flo:* 8. (flo:atan2 1. 1.)))
+
+(define (cairo-graphics/draw-circle device x y radius)
+  (let ((graphics (graphics-device/descriptor device)))
+    (let ((cr (cairo-graphics-context graphics))
+         (x (->flonum x))
+         (y (->flonum y))
+         (radius (->flonum radius)))
+      (cairo-arc cr x y radius 0. 2pi)
+      (cairo-stroke cr))))
+
+(define (cairo-graphics/move-cursor device x y)
+  (let ((graphics (graphics-device/descriptor device)))
+    (let ((cr (cairo-graphics-context graphics))
+         (x (->flonum x))
+         (y (->flonum y)))
+      (cairo-move-to cr x y))))
+
+(define (cairo-graphics/drag-cursor device x y)
+  (let ((graphics (graphics-device/descriptor device)))
+    (let ((cr (cairo-graphics-context graphics))
+         (x (->flonum x))
+         (y (->flonum y)))
+      (cairo-line-to cr x y)
+      (cairo-stroke cr))))
+
+(define (cairo-graphics/set-drawing-mode device mode)
+  (let ((operator
+        (case mode
+          ((0) 'CLEAR)                 ;GXclear         0
+          ((1) 'IN)                    ;GXand           src AND dst
+          ((2) 'OUT)                   ;GXandReverse    src AND NOT dst
+          ((3) 'SOURCE)                ;GXcopy          src
+          ((4) 'DEST-OUT)              ;GXandInverted   NOT src AND dst
+          ((5) 'DEST)                  ;GXnoop          dst
+          ((6) 'XOR)                   ;GXxor           src XOR dst
+          ((7) 'OVER)                  ;GXor            src OR dst
+          ((8) (warn "unimplemented:" '|GXnor|) #f)           ;GXnor           NOT src AND NOT dst
+          ((9) (warn "unimplemented:" '|GXequiv|) #f)         ;GXequiv         NOT src XOR dst
+          ((10) (warn "unimplemented:" '|GXinvert|) #f)       ;GXinvert        NOT dst
+          ((11) (warn "unimplemented:" '|GXorReverse|) #f)    ;GXorReverse     src OR NOT dst
+          ((12) (warn "unimplemented:" '|GXcopyInverted|) #f) ;GXcopyInverted  NOT src
+          ((13) (warn "unimplemented:" '|GXorInverted|) #f)   ;GXorInverted    NOT src OR dst
+          ((14) (warn "unimplemented:" '|GXnand|) #f)         ;GXnand          NOT src OR NOT dst
+          ((15) 'SOURCE)               ;GXset           1
+          (else (error:wrong-type-argument mode "a drawing mode"
+                                           'cairo-graphics/set-drawing-mode)))))
+    (if operator
+       (cairo-set-operator
+        (cairo-graphics-context (graphics-device/descriptor device))
+        operator))))
+
+(define (cairo-graphics/set-line-style device style)
+  (let ((graphics (graphics-device/descriptor device))
+       (dashes
+        (case style
+          ((0) '())
+          ((1) '(8.))
+          ((2) '(1.))
+          ((3) '(13. 1. 1. 1.))
+          ((4) '(11. 1. 1. 1. 1. 1.))
+          ((5) '(11. 5.))
+          ((6) '(12. 1. 2. 1))
+          ((7) '( 9. 1. 2. 1. 2. 1.))
+          (else (error:wrong-type-argument style "a line style"
+                                           'cairo-graphics/set-line-style)))))
+    (let ((cr (cairo-graphics-context graphics))
+         (factor (flo:/ 16. (cairo-graphics-scale graphics))))
+      (cairo-set-dash cr (map (lambda (len) (flo:* len factor)) dashes)))))
+
+(define (cairo-graphics/fill-polygon-list device points)
+  ;; POINTS should be a list of flo:vectors each with a length greater than 1.
+  (let ((graphics (graphics-device/descriptor device)))
+    (let ((cr (cairo-graphics-context graphics))
+         (p (car points)))
+      (define-integrable (x p) (flo:vector-ref p 0))
+      (define-integrable (y p) (flo:vector-ref p 1))
+      (cairo-move-to cr (x p) (y p))
+      (for-each (lambda (p)
+                 (cairo-line-to cr (x p) (y p)))
+               (cdr points))
+      (cairo-close-path cr)
+      (cairo-fill cr))))
+
+(define (cairo-graphics/flush device)
+  (cairo-surface-flush
+   (or (cairo-graphics-surface
+       (graphics-device/descriptor device))
+       (error "Cairo graphics device closed:" device))))
+
+(define (cairo-graphics/write-to-png device filename)
+  (cairo-surface-write-to-png
+   (or (cairo-graphics-surface
+       (graphics-device/descriptor device))
+       (error "Cairo graphics device closed:" device))
+   (->namestring filename)))
+
+(define (cairo-graphics/destroy device)
+  (cairo-surface-destroy (cairo-graphics-surface
+                         (graphics-device/descriptor device))))
+
+(define (cairo-graphics/set-background-color device name)
+  (let ((graphics (graphics-device/descriptor device)))
+    (if (not (string=? name (cairo-graphics-bgcolor-name graphics)))
+       (let ((new (->color name 'cairo-graphics/set-background-color)))
+         (set-cairo-graphics-bgcolor! graphics new)
+         (set-cairo-graphics-bgcolor-name! graphics name)))))
+
+(define (cairo-graphics/set-foreground-color device name)
+  (let ((graphics (graphics-device/descriptor device)))
+    (if (not (string=? name (cairo-graphics-fgcolor-name graphics)))
+       (let ((new (->color name 'cairo-graphics/set-foreground-color)))
+         (set-cairo-graphics-fgcolor! graphics new)
+         (set-cairo-graphics-fgcolor-name! graphics name)
+         (cairo-set-source-color (cairo-graphics-context graphics) new)))))
+
+(define (cairo-graphics/set-clip-rectangle device x-left y-bottom x-right y-top)
+  (let ((cr (cairo-graphics-context (graphics-device/descriptor device)))
+       (x (->flonum x-left))
+       (y (->flonum y-top)))
+    (let ((width (flo:- (->flonum x-right) x))
+         (height (flo:- (->flonum y-bottom) y)))
+      (cairo-rectangle cr x y width height)
+      (cairo-clip cr))))
+
+(define (cairo-graphics/reset-clip-rectangle device)
+  (cairo-reset-clip (cairo-graphics-context
+                    (graphics-device/descriptor device))))
+
+(define cairo-graphics-device-type)
+
+(define (initialize-package!)
+  (set! cairo-graphics-device-type
+       (make-graphics-device-type
+        'CAIRO
+        `((available? ,cairo-graphics/available?)
+          (open ,cairo-graphics/open)
+          (clear ,cairo-graphics/clear)
+          (close ,cairo-graphics/close)
+          (coordinate-limits ,cairo-graphics/coordinate-limits)
+          (device-coordinate-limits ,cairo-graphics/device-coordinate-limits)
+          (move-cursor ,cairo-graphics/move-cursor)
+          (drag-cursor ,cairo-graphics/drag-cursor)
+          (draw-line ,cairo-graphics/draw-line)
+          (draw-point ,cairo-graphics/draw-point)
+          (draw-text ,cairo-graphics/draw-text)
+          (draw-circle ,cairo-graphics/draw-circle)
+          (flush ,cairo-graphics/flush)
+          (reset-clip-rectangle ,cairo-graphics/reset-clip-rectangle)
+          (set-clip-rectangle ,cairo-graphics/set-clip-rectangle)
+          (set-coordinate-limits ,cairo-graphics/set-coordinate-limits)
+          (set-drawing-mode ,cairo-graphics/set-drawing-mode)
+          (set-line-style ,cairo-graphics/set-line-style)))))
+
+(initialize-package!)
\ No newline at end of file
index 794ed1e817c3c79496c4cc58e1b8625d7ac9803b..6ecd686f3e4ff862e733317474d62597a341ff56 100644 (file)
@@ -70,4 +70,19 @@ USA.
          cairo-fill cairo-fill-preserve
          cairo-stroke cairo-stroke-preserve
          cairo-set-font-matrix
-         cairo-matrix))
\ No newline at end of file
+         cairo-matrix))
+
+(define-package (cairo graphics)
+  (parent (cairo))
+  (files "cairo-graphics")
+  (export ()
+         cairo-graphics/set-background-color
+         cairo-graphics/set-foreground-color
+         cairo-graphics/draw-line
+         cairo-graphics/draw-text
+         cairo-graphics/draw-circle
+         cairo-graphics/fill-polygon-list
+         cairo-graphics/clear
+         cairo-graphics/flush
+         cairo-graphics/write-to-png
+         cairo-graphics/destroy))
\ No newline at end of file
index b1909ffd6fde6a1599ab96fdf7c79b79f8de2e78..3a9e9d1bd6ffc8e660971e56526daf0341ee0353 100644 (file)
@@ -29,7 +29,7 @@ USA.
 (define (cairo-image-surface-create width height)
   (let ((surface (make-alien '|cairo_surface_t|))
        (copy (make-alien '|cairo_surface_t|)))
-    (add-gc-cleanup surface (make-cairo-surface-cleanup copy))
+    (add-glib-cleanup surface (make-cairo-surface-cleanup copy))
     (C-call "cairo_image_surface_create" copy
            (C-enum "CAIRO_FORMAT_RGB24") width height)
     (copy-alien-address! surface copy)
@@ -50,9 +50,8 @@ USA.
    (lambda ()
      (if (not (alien-null? surface))
         (begin
-          (C-call "cairo_surface_destroy" surface)
-          (alien-null! surface)))))
-  (punt-gc-cleanup surface))
+          (execute-glib-cleanup surface)
+          (alien-null! surface))))))
 
 (define (check-cairo-surface-status surface)
   (let ((status (C-call "cairo_surface_status" surface)))
@@ -79,7 +78,7 @@ USA.
 (define (cairo-pattern-create-linear x1 y1 x2 y2)
   (let ((pattern (make-alien '|cairo_pattern_t|))
        (copy (make-alien '|cairo_pattern_t|)))
-    (add-gc-cleanup pattern (make-cairo-pattern-cleanup copy))
+    (add-glib-cleanup pattern (make-cairo-pattern-cleanup copy))
     (C-call "cairo_pattern_create_linear" copy
            (->flonum x1) (->flonum y1) (->flonum x2) (->flonum y2))
     (copy-alien-address! pattern copy)
@@ -89,7 +88,7 @@ USA.
 (define (cairo-pattern-create-radial cx0 cy0 radius0 cx1 cy1 radius1)
   (let ((pattern (make-alien '|cairo_pattern_t|))
        (copy (make-alien '|cairo_pattern_t|)))
-    (add-gc-cleanup pattern (make-cairo-pattern-cleanup copy))
+    (add-glib-cleanup pattern (make-cairo-pattern-cleanup copy))
     (C-call "cairo_pattern_create_radial" copy
            (->flonum cx0) (->flonum cy0) (->flonum radius0)
            (->flonum cx1) (->flonum cy1) (->flonum radius1))
@@ -111,9 +110,8 @@ USA.
    (lambda ()
      (if (not (alien-null? pattern))
         (begin
-          (C-call "cairo_pattern_destroy" pattern)
-          (alien-null! pattern)))))
-  (punt-gc-cleanup pattern))
+          (execute-glib-cleanup pattern)
+          (alien-null! pattern))))))
 
 (define (check-cairo-pattern-status pattern)
   (let ((status (C-call "cairo_pattern_status" pattern)))
@@ -145,7 +143,7 @@ USA.
   (guarantee-cairo-surface surface 'cairo-create)
   (let ((cairo (make-alien '|cairo_t|))
        (copy (make-alien '|cairo_t|)))
-    (add-gc-cleanup cairo (make-cairo-cleanup copy))
+    (add-glib-cleanup cairo (make-cairo-cleanup copy))
     (C-call "cairo_create" copy surface)
     (copy-alien-address! cairo copy)
     (check-cairo-status cairo)
@@ -165,9 +163,8 @@ USA.
    (lambda ()
      (if (not (alien-null? cairo))
         (begin
-          (C-call "cairo_destroy" cairo)
-          (alien-null! cairo)))))
-  (punt-gc-cleanup cairo))
+          (execute-glib-cleanup cairo)
+          (alien-null! cairo))))))
 
 (define (check-cairo-status cairo)
   (let ((status (C-call "cairo_status" cairo)))
@@ -305,7 +302,7 @@ USA.
   (guarantee-cairo cairo 'cairo-line-to)
   (let ((x (->flonum x))
        (y (->flonum y)))
-    (C-call "cairo_rel_line_to" cairo x y)))
+    (C-call "cairo_line_to" cairo x y)))
 
 (define (cairo-rel-line-to cairo dx dy)
   (guarantee-cairo cairo 'cairo-rel-line-to)
index ff934723111599287f1236ec39cf0861c848cfa7..44c9008dc7ffda842726b153219cfa306680965e 100644 (file)
@@ -41,4 +41,7 @@ USA.
        (compile-file "cairo" '("cairo-const.bin")
                      (->environment '(cairo)))
 
+       (compile-file "cairo-graphics" '("cairo-const.bin")
+                     (->environment '(cairo graphics)))
+
        (cref/generate-constructors "cairo" 'ALL)))))
\ No newline at end of file
index 7379e6a86ed1c5175a439c3f2e19f8659c5f3184..fc10015764aae0a6aa8595687393c1e14ee5df86 100644 (file)
@@ -7,7 +7,7 @@
 (load-option 'FFI)
 (load-option 'GTK)
 
-(if (gtk-thread-running?)
+(if (gtk-initialized?)
     (begin
       (let ((env (->environment '(runtime pathname))))
        (set! (access library-directory-path env)
index 60f08daa8bfa33abea835458a37cd559439e521d..53f9461e9e8251ec635749c9772cdf5d2ebb438f 100644 (file)
@@ -55,9 +55,9 @@ USA.
 
 (define-method initialize-instance ((widget <glx-widget>) width height)
   (call-next-method widget width height)
-  (add-gc-cleanup widget (make-glx-widget-cleanup
-                         (glx-widget-xdisplay widget)
-                         (glx-widget-glxcontext widget)))
+  (add-glib-cleanup widget (make-glx-widget-cleanup
+                           (glx-widget-xdisplay widget)
+                           (glx-widget-glxcontext widget)))
   (C-call "gtk_widget_set_double_buffered" (gobject-alien widget) 0))
 
 (define (make-glx-widget-cleanup xdisplay glxcontext)
@@ -74,9 +74,7 @@ USA.
 (define-method gtk-widget-destroy-callback ((widget <glx-widget>))
   (without-interrupts
    (lambda ()
-     (punt-gc-cleanup widget)
-     (cleanup-glx-widget (glx-widget-xdisplay widget)
-                        (glx-widget-glxcontext widget))))
+     (execute-glib-cleanup widget)))
   (call-next-method widget))
 
 (define-method fix-widget-realize-callback ((widget <glx-widget>))
@@ -146,18 +144,14 @@ USA.
        (copy (make-alien '|GLXFBConfig|))
        (attribs (make-attribs attrib-list))
        (num-configs (malloc (C-sizeof "int") 'int)))
-    (add-gc-cleanup configs (make-fb-configs-cleanup copy))
+    (add-glib-cleanup configs (make-fb-configs-cleanup copy))
     (C-call "glXChooseFBConfig" copy
            display screen-num attribs num-configs)
     (free attribs)
     (free num-configs)
-    (if (alien-null? copy)
-       (begin
-         (punt-gc-cleanup configs)
-         #f)
-       (begin
-         (copy-alien-address! configs copy)
-         configs))))
+    (copy-alien-address! configs copy)
+    (error-if-null configs "Could not find:" configs)
+    configs))
 
 #;(define (make-fb-configs-cleanup alien)
   (named-lambda (fb-configs-cleanup)
@@ -170,14 +164,6 @@ USA.
        (C-call "XFree" alien)
        (alien-null! alien))))
 
-#;(define (xfree alien)
-  (without-interrupts
-   (lambda ()
-     (if (not (alien-null? alien))
-        (let ((cleanup (punt-gc-cleanup alien)))
-          (if cleanup (cleanup))
-          (alien-null! alien))))))
-
 (define (make-attribs attribs)
   (let* ((len (length attribs))
         (alien (malloc (* len (C-sizeof "int")) '|int|)))
@@ -212,38 +198,6 @@ USA.
                      "GError pointer not set.")))
            (gerror-pointer-free gerror*)
            (error message))))))
-
-#;(define (make-gerror-pointer)
-  (let ((alien (make-alien '(* |GError|)))
-       (copy (make-alien '(* |GError|))))
-    (add-gc-cleanup alien (make-gerror-pointer-cleanup copy))
-    (C-call "g_try_malloc0" copy (C-sizeof "* GError"))
-    (if (alien-null? copy)
-       (begin
-         (punt-gc-cleanup alien)
-         (error "Could not create:" alien))
-       (begin
-         (copy-alien-address! alien copy)
-         alien))))
-
-#;(define (make-gerror-pointer-cleanup gerror*)
-  (named-lambda (gerror-pointer-cleanup)
-    ;;without-interrupts
-    (if (not (alien-null? gerror*))
-       (let ((gerror (make-alien '|GError|)))
-         (C-> gerror* "* GError" gerror)
-         (if (not (alien-null? gerror))
-             (C-call "g_error_free" gerror))
-         (C-call "g_free" gerror*)
-         (alien-null! gerror*)))))
-
-#;(define (gerror-pointer-free gerror*)
-  (without-interrupts
-   (lambda ()
-     (if (not (alien-null? gerror*))
-        (let ((cleanup (punt-gc-cleanup gerror*)))
-          (if cleanup (cleanup))
-          (alien-null! gerror*))))))
 \f
 (define-class (<glx-viewport> (constructor () (width height)))
     ;; A <glx-widget> with camera parameters, and a default key-press
index 790d7ed5f9c32736765265bcc423a6495868778a..2715bc72ddce257a1f63b34a22c98fa65e777a1b 100644 (file)
@@ -26,6 +26,7 @@ USA.
 (global-definitions runtime/)
 (global-definitions ffi/)
 (global-definitions sos/)
+(global-definitions glib/)
 (global-definitions gtk/)
 
 (define-package (gl)
@@ -80,7 +81,11 @@ USA.
          ucode-primitive)
   (import (runtime ffi)
          %set-alien/address!)
-  (import (gtk gobject)
+  (import (glib)
+         add-glib-cleanup execute-glib-cleanup)
+  (import (gobject)
+         gobject-alien)
+  (import (gtk gdk)
          make-pixbuf)
   (import (gtk gtk-widget)
          gtk-widget-destroy-callback)
@@ -89,9 +94,8 @@ USA.
          fix-widget-geometry fix-widget-window
          set-fix-widget-map-handler! set-fix-widget-unmap-handler!)
   (import (gtk)
-         cairo-clip-extents
-         add-gc-cleanup punt-gc-cleanup error-if-null
-         gobject-alien gtk-window-new
+         error-if-null
+         gtk-window-new
          gtk-widget-destroy gtk-widget-parent
          gtk-widget-show-all
          gtk-widget-queue-draw
index 82dbae12e08e43be847cca26aa117662bda2371f..0dc93162af4b26a2f24145ebeed253fca8cef5d4 100644 (file)
@@ -240,16 +240,16 @@ USA.
 
 (define-method initialize-instance ((object <g-input-stream>))
   (call-next-method object)
-  (add-gc-cleanup object (make-g-input-stream-cleanup
-                         (gio-cleanup-info object)
-                         (g-input-stream-cleanup-info object))))
+  (add-glib-cleanup object (make-g-input-stream-cleanup
+                           (gio-cleanup-info object)
+                           (g-input-stream-cleanup-info object))))
 
 (define (make-g-input-stream-cleanup gio-info info)
   (named-lambda (g-input-stream-cleanup)
     (cleanup-g-input-stream gio-info info)))
 
 (define (cleanup-g-input-stream gio-info info)
-  ;; For gc-cleanup.  Run without-interrupts.
+  ;; For glib-cleanups.  Run without-interrupts.
   (cleanup-gio gio-info)
   (cleanup-callback-id info g-input-stream read-id)
   (cleanup-callback-id info g-input-stream skip-id))
@@ -428,16 +428,16 @@ USA.
 
 (define-method initialize-instance ((object <g-output-stream>))
   (call-next-method object)
-  (add-gc-cleanup object (make-g-output-stream-cleanup
-                         (gio-cleanup-info object)
-                         (g-output-stream-cleanup-info object))))
+  (add-glib-cleanup object (make-g-output-stream-cleanup
+                           (gio-cleanup-info object)
+                           (g-output-stream-cleanup-info object))))
 
 (define (make-g-output-stream-cleanup gio-info info)
   (named-lambda (g-output-stream-cleanup)
     (cleanup-g-output-stream gio-info info)))
 
 (define (cleanup-g-output-stream gio-info info)
-  ;; For gc-cleanup.  Run without-interrupts.
+  ;; For glib-cleanups.  Run without-interrupts.
   (cleanup-gio gio-info)
   (cleanup-callback-id info g-output-stream write-id)
   (cleanup-callback-id info g-output-stream flush-id))
@@ -713,7 +713,7 @@ USA.
 
 (define-method initialize-instance ((object <gfile-info>))
   (call-next-method object)
-  (add-gc-cleanup object (make-ginfo-cleanup (gio-cleanup-info object))))
+  (add-glib-cleanup object (make-ginfo-cleanup (gio-cleanup-info object))))
 
 (define (make-ginfo-cleanup gio-info)
   (named-lambda (ginfo-cleanup)
@@ -813,16 +813,16 @@ USA.
 
 (define-method initialize-instance ((object <gfile-enumerator>))
   (call-next-method object)
-  (add-gc-cleanup object (make-gfile-enumerator-cleanup
-                         (gio-cleanup-info object)
-                         (gfile-enumerator-ginfos object))))
+  (add-glib-cleanup object (make-gfile-enumerator-cleanup
+                           (gio-cleanup-info object)
+                           (gfile-enumerator-ginfos object))))
 
 (define (make-gfile-enumerator-cleanup gio-info ginfos)
   (named-lambda (gfile-enumerator-cleanup)
     (cleanup-gfile-enumerator gio-info ginfos)))
 
 (define (cleanup-gfile-enumerator gio-info ginfos)
-  ;; For gc-cleanup.  Run without-interrupts.
+  ;; For glib-cleanups.  Run without-interrupts.
   (cleanup-gio gio-info)
   (cleanup-ginfos ginfos))
 
@@ -974,7 +974,8 @@ USA.
 
 (define-method initialize-instance ((gmountop <g-mount-operation>))
   (call-next-method gmountop)
-  (add-gc-cleanup gmountop (make-gmountop-cleanup (gio-cleanup-info gmountop)))
+  (add-glib-cleanup gmountop
+                   (make-gmountop-cleanup (gio-cleanup-info gmountop)))
   (let ((alien (gobject-alien gmountop)))
     (set-alien/ctype! alien '|GMountOperation|)
     (C-call "g_mount_operation_new" alien)
@@ -1192,7 +1193,7 @@ USA.
   ;; SETTER is applied to an alien that must not escape.
   (let ((alien (make-alien '(* uchar)))
        (copy (make-alien '(* uchar))))
-    (add-gc-cleanup alien (make-cstringv-cleanup copy))
+    (add-glib-cleanup alien (make-cstringv-cleanup copy))
     (setter copy)
     (copy-alien-address! alien copy)
     alien))
@@ -1226,9 +1227,8 @@ USA.
 (define (free-cstringv alien)
   (without-interrupts
    (lambda ()
-     (let ((cleanup (punt-gc-cleanup alien)))
-       (if cleanup (cleanup))
-       (alien-null! alien)))))
+     (execute-glib-cleanup alien)
+     (alien-null! alien))))
 
 (define %trace? #f)
 
index cc7c14b3df30ace706d5e293b4bf30a4516d6b74..55bd2b30d94577e3590ef59148ac99a236f717bd 100644 (file)
@@ -57,7 +57,7 @@ USA.
                     (let ((gc-tick (car (gc-timestamp))))
                       (if (fix:< done-tick gc-tick)
                           (begin
-                            (run-gc-cleanups)
+                            (run-glib-cleanups)
                             (set! done-tick gc-tick)))
                       (if (fix:< next-secondary-tick gc-tick)
                           (begin
index 19d154cf979d2c4669904fa2d834b4b2e15bde32..d2b8739812a41033c8a8d3022242565274f5bafb 100644 (file)
@@ -42,7 +42,6 @@ USA.
          <gobject> gobject-alien
          gobject-live? gobject-unref!
          g-signal-connect g-signal-disconnect
-         add-gc-cleanup punt-gc-cleanup
          gobject-get-property gobject-set-properties
          gquark-from-string gquark-to-string))
 
@@ -115,8 +114,8 @@ USA.
   ;;(depends-on "main")
   (export ()
          stop-glib-thread)
-  (import (gobject)
-         run-gc-cleanups)
+  (import (glib)
+         run-glib-cleanups)
   (import (glib main)
          run-glib)
   (import (runtime primitive-io)
index f9a13c48ede5633a02d1f96fdc59605520629829..23a5838f93c4661bd4dc62846d0289b2b350ebdb 100644 (file)
@@ -105,4 +105,57 @@ USA.
   (if (color? o) (flo:vector-set! o 2 b)(error:wrong-type-argument o"a color")))
 
 (define-integrable-operator (set-color-alpha! o a)
-  (if (color? o) (flo:vector-set! o 3 a)(error:wrong-type-argument o"a color")))
\ No newline at end of file
+  (if (color? o) (flo:vector-set! o 3 a)(error:wrong-type-argument o"a color")))
+\f
+;;; GLib Cleanups
+
+(define glib-cleanups)
+
+(define (initialize-glib-cleanups!)
+  (set! glib-cleanups '()))
+
+(define (run-glib-cleanups)
+  (let loop ((alist glib-cleanups)
+            (prev #f))
+    (if (pair? alist)
+       (if (weak-pair/car? (car alist))
+           (loop (cdr alist) alist)
+           (let ((thunk (weak-cdr (car alist)))
+                 (next (cdr alist)))
+             (thunk)
+             (if prev
+                 (set-cdr! prev next)
+                 (set! glib-cleanups next))
+             (loop next prev))))))
+
+(define (reset-glib-cleanups!)
+  (set! glib-cleanups '()))
+
+(define (add-glib-cleanup object cleanup-thunk)
+  (let ((weak-pair (weak-cons object cleanup-thunk)))
+    (without-interrupts
+     (lambda ()
+       (set! glib-cleanups (cons weak-pair glib-cleanups))))
+    weak-pair))
+
+(define (execute-glib-cleanup object)
+  (let ((entry (weak-assq object glib-cleanups)))
+    (if entry
+       (begin
+         ((weak-cdr entry))
+         (set! glib-cleanups (delq! entry glib-cleanups)))))
+  unspecific)
+
+(define (weak-assq obj alist)
+  (let loop ((alist alist))
+    (if (null? alist) #f
+       (let* ((entry (car alist))
+              (key (weak-car entry)))
+         (if (eq? obj key) entry
+             (loop (cdr alist)))))))
+
+(define (initialize-package!)
+  (initialize-glib-cleanups!)
+  (add-event-receiver! event:after-restore reset-glib-cleanups!))
+
+(initialize-package!)
\ No newline at end of file
index 1b51c88c1f5e923f971e8ce3fc1515d93efb4b5b..a3732d6617d668001d135a319a49ba9132ab87b2 100644 (file)
@@ -604,12 +604,12 @@ signal handlers to them.
 
 @unnumberedsec Toolkit Resource Usage
 
-Each gobject instance is tracked by the weak alist @code{gc-cleanups},
+Each gobject instance is tracked by the weak alist @code{glib-cleanups},
 so that the toolkit object can be @code{g_object_unref}'ed when the
 instance is GCed.
 
 The initialize-instance method for subclasses of gobject should chain
-up early, adding the instance's alien to gc-cleanups @emph{before}
+up early, adding the instance's alien to glib-cleanups @emph{before}
 calling out to the toolkit.  This ensures that an allocated toolkit
 object will not be dropped; its alien address is on the list of GC
 cleanups before it is even allocated.  @emph{After} the callout, the
@@ -644,7 +644,7 @@ will not be invoked after an instance is GCed, else an error should be
 signaled.
 
 TODO: A world save hook might warn of gobject instances still on the
-gc-cleanups list.  A world restore hook could kill them.
+glib-cleanups list.  A world restore hook could kill them.
 
 @node GNU Free Documentation License, , Implementation Notes, Top
 @appendix GNU Free Documentation License
index 9d3d29c91c518d4a39743225121f511c40cc0fd1..a4b7a7e092914654270fced96c1399db12dcb8d7 100644 (file)
@@ -522,27 +522,31 @@ signal_forwarder (int signo, siginfo_t *siginfo, void *ptr)
     {
       struct handler_record * scan;
 
+      trace (";signal %d: in scheme_thread\n", signo);
       scan = old_handlers;
       while (scan != NULL)
        {
          if (scan->signo == signo)
            {
+             trace (";signal %d: invoking original handler\n", signo);
              (scan->handler)(signo, siginfo, ptr);
+             trace (";signal %d: original handler returned\n", signo);
              return;
            }
          scan = scan->next;
        }
-      complain (";signal_forwarder: no handler for signo %d\n", signo);
+      complain (";signal %d: no handler\n", signo);
     }
   else
     {
       int err;
 
+      trace (";signal %d: outside scheme_thread\n", signo);
       err = pthread_kill (scheme_thread, signo);
       if (err != 0)
        {
-         complain (";signal_forwarder: pthread_kill failed: %s\n",
-                   errno_name (err));
+         complain (";signal %d: pthread_kill failed: %s\n",
+                   signo, errno_name (err));
          sleep (1);
        }
     }
index 85dde66996ef54fb0a6829e702cb7131645855ff..30bc55e070ab6bbc5b8a308078824494a7546534 100644 (file)
@@ -40,7 +40,7 @@ USA.
   (signals define standard
           initializer (lambda () (list 'GOBJECT-SIGNALS)))
 
-  ;; This instance's weak-pair on the gc-cleanups list.  This is
+  ;; This instance's weak-pair on the glib-cleanups list.  This is
   ;; cached here mainly for g-signal-connect, which must create
   ;; callbacks that only weakly reference this instance.
   (weak-self define standard))
@@ -53,36 +53,28 @@ USA.
 (define-method initialize-instance ((object <gobject>))
   (call-next-method object)
   (set-gobject-weak-self!
-   object (add-gc-cleanup object (make-gobject-cleanup-thunk
-                                 (gobject-alien object)
-                                 (gobject-signals object)))))
+   object (add-glib-cleanup object (make-gobject-cleanup
+                                   (gobject-alien object)
+                                   (gobject-signals object)))))
 
-(define (make-gobject-cleanup-thunk alien signals)
+(define (make-gobject-cleanup alien signals)
   ;; This separate procedure ensures that the gobject is not caught in
   ;; the closure.
-  (named-lambda (gobject-cleanup-thunk)
-    (gobject-cleanup alien signals)))
+  (named-lambda (gobject-cleanup)
+    (%trace ";gobject-cleanup "alien"\n")
+    (if (not (alien-null? alien))
+       (begin
+         (for-each
+           (lambda (name.id.handle) (disconnect!? alien (cdr name.id.handle)))
+           (cdr signals))
+         (C-call "g_object_unref" alien)
+         (alien-null! alien)))
+    (%trace ";gobject-cleanup done with "alien"\n")))
 
 (define (gobject-unref! object)
   (without-interrupts
    (lambda ()
-     (gobject-cleanup (gobject-alien object) (gobject-signals object))
-     (set! gc-cleanups (delq! (gobject-weak-self object) gc-cleanups))
-     unspecific)))
-
-(define (gobject-cleanup alien signals)
-  ;; Run as a gc-daemon, or with exclusive write access to ALIEN and
-  ;; SIGNALS (or without-interrupts).
-
-  (%trace ";gobject-cleanup "alien"\n")
-  (if (not (alien-null? alien))
-      (begin
-       (for-each
-         (lambda (name.id.handle) (disconnect!? alien (cdr name.id.handle)))
-         (cdr signals))
-       (C-call "g_object_unref" alien)
-       (alien-null! alien)))
-  (%trace ";gobject-cleanup done with "alien"\n"))
+     (execute-glib-cleanup object))))
 
 (define (g-signal-connect gobject alien-function callback
                          #!optional signal-name)
@@ -152,57 +144,6 @@ USA.
        (set-car! id.handle #f)
        #t)))
 \f
-;;; GC Cleanups
-
-(define gc-cleanups)
-
-(define (initialize-gc-cleanups!)
-  (set! gc-cleanups '()))
-
-(define (run-gc-cleanups)
-  (%trace ";run-gc-cleanups\n")
-  (let loop ((alist gc-cleanups)
-            (prev #f))
-    (if (pair? alist)
-       (if (weak-pair/car? (car alist))
-           (loop (cdr alist) alist)
-           (let ((thunk (weak-cdr (car alist)))
-                 (next (cdr alist)))
-             (thunk)
-             (if prev
-                 (set-cdr! prev next)
-                 (set! gc-cleanups next))
-             (loop next prev)))))
-  (%trace ";run-gc-cleanups done\n"))
-
-(define (reset-gc-cleanups!)
-  (set! gc-cleanups '()))
-
-(define-integrable (add-gc-cleanup object cleanup-thunk)
-  (let ((weak-pair (weak-cons object cleanup-thunk)))
-    (without-interrupts
-     (lambda ()
-       (set! gc-cleanups (cons weak-pair gc-cleanups))))
-    weak-pair))
-
-(define-integrable (punt-gc-cleanup object)
-  (without-interrupts
-   (lambda ()
-     (let ((entry (weak-assq object gc-cleanups)))
-       (if entry
-          (begin
-            (set! gc-cleanups (delq! entry gc-cleanups))
-            (weak-cdr entry))
-          #f)))))
-
-(define (weak-assq obj alist)
-  (let loop ((alist alist))
-    (if (null? alist) #f
-       (let* ((entry (car alist))
-              (key (weak-car entry)))
-         (if (eq? obj key) entry
-             (loop (cdr alist)))))))
-\f
 
 ;;; Properties
 
@@ -474,9 +415,7 @@ USA.
   unspecific)
 
 (define (initialize-package!)
-  (initialize-gc-cleanups!)
   (add-event-receiver! event:after-restore reset-quark-cache!)
-  (add-event-receiver! event:after-restore reset-gc-cleanups!)
   unspecific)
 
 (define %trace? #f)
index 6e6f3d45911afec4710836de4e3b4b8d82e08a3f..1f2786fc88dcc7a878dfa56fcf18b19737ee48f3 100644 (file)
         (bindings (append (pmodel/global-exports pmodel)
                           (pmodel/package-bindings pmodel '(gtk))))
         (missing (minus (minus bindings deffns)
-                        '(add-gc-cleanup
-                          punt-gc-cleanup
-                          make-pole-zero
+                        '(make-pole-zero
                           make-fix-layout-demo
                           make-gtk-event-viewer-demo)))
         (extras (minus deffns bindings)))
index 65fac2cc433071b3bc7f588109d81394630b006e..5071c6c4a9140c49824dab4cbfd7cece0f486f40 100644 (file)
@@ -1242,8 +1242,10 @@ USA.
          (let ((fill (get-option ink 'FILL '())))
            (if (not (null? fill))
                (begin
+                 (cairo-save cr)
                  (set-fill-options! cr ink)
-                 (cairo-fill-preserve cr))))
+                 (cairo-fill-preserve cr)
+                 (cairo-restore cr))))
          (let ((outline (get-option ink 'OUTLINE '())))
            (if (not (null? outline))
                (begin
index 1026287529f5eae0c622d0d3f2923c783ec3978d..be96a3abaf7c53caa96f7ed01409d44485e76a57 100644 (file)
@@ -25,12 +25,13 @@ USA.
 ;;; package: (gdk)
 
 (define (gdk-cairo-create gdkwindow)
-  (guarantee-gdk-window gdkwindow 'gdk-window-process-updates)
+  (guarantee-gdk-window gdkwindow 'gdk-cairo-create)
   (let ((cairo (make-alien '|cairo_t|))
        (copy (make-alien '|cairo_t|)))
-    (add-gc-cleanup cairo (make-cairo-cleanup copy))
+    (add-glib-cleanup cairo (make-cairo-cleanup copy))
     (C-call "gdk_cairo_create" copy gdkwindow)
     (copy-alien-address! cairo copy)
+    (error-if-null cairo "Could not create:" cairo gdkwindow)
     (check-cairo-status cairo)
     cairo))
 
@@ -162,11 +163,10 @@ USA.
 (define (make-gerror-pointer)
   (let ((alien (make-alien '(* |GError|)))
        (copy  (make-alien '(* |GError|))))
-    (add-gc-cleanup alien (make-gerror-pointer-cleanup copy))
+    (add-glib-cleanup alien (make-gerror-pointer-cleanup copy))
     (C-call "g_try_malloc0" copy (C-sizeof "* GError"))
-    (if (alien-null? copy)
-       (error "Could not create a GError pointer."))
     (copy-alien-address! alien copy)
+    (error-if-null alien "Could not create:" alien)
     alien))
 
 (define (make-gerror-pointer-cleanup copy)
@@ -183,11 +183,8 @@ USA.
   (without-interrupts
    (lambda ()
      (if (not (alien-null? gerror*))
-        (let ((gerror (make-alien '|GError|)))
-          (C-> gerror* "* GError" gerror)
-          (if (not (alien-null? gerror))
-              (C-call "g_error_free" gerror))
-          (C-call "g_free" gerror*)
+        (begin
+          (execute-glib-cleanup gerror*)
           (alien-null! gerror*))))))
 
 (define (load-pixbuf-from-file loader filename)
index 6048872c144c977410d13a067ec49848f1d25301..c64e07c086343d6152f5f055ce348d6c9fd4b004 100644 (file)
@@ -61,7 +61,7 @@ USA.
      'gtk-demos.callbacks
      (named-lambda (gtk-demos.callbacks-test)
        (assert = 0 (car (registered-callback-count))
-              '(REGISTERED-CALLBACK-COUNT))))
+              '(CAR (REGISTERED-CALLBACK-COUNT)))))
 
     (run-test
      'gtk-demos.mallocs
index c7373500978900a2aa32706e1cc18b2d0cb549d7..8ee68607f73fdf787ea1706698cb25edbd3fcd44 100644 (file)
@@ -90,12 +90,6 @@ USA.
          (gtk-widget-show-all window)
          (make-device graphics)))))
 
-(define (gtk-graphics/make width height)
-  (guarantee-positive-fixnum width 'gtk-graphics/open)
-  (guarantee-positive-fixnum height 'gtk-graphics/open)
-  (%make-graphics-device gtk-graphics-device-type
-                        (make-gtk-graphics width height)))
-
 (define (toplevel graphics)
   (let ((widgets (fix-drawing-widgets (fix-ink-drawing graphics))))
     (if (null? (cdr widgets))
index e4ce63ed4fa24bab9dc6cc146fdc0fd9d9e23678..18cfd573b3ab7be1abe09627ccea89803df6486e 100644 (file)
@@ -103,7 +103,7 @@ USA.
 
 ;;; This is unfortunate.  We rely on the most specialized method to
 ;;; call out, creating a specific type of GtkWidget.  We want the
-;;; <gobject> method to go first, as usual, to add a gc-cleanup, but
+;;; <gobject> method to go first, as usual, to add a glib-cleanup, but
 ;;; this method to go last, AFTER the most specific (most unusual!)
 ;;; else it cannot connect its destroy-callback.  To do both would
 ;;; take... a computed effective method procedure?  For now, rely on
index ce3a358c4fdcb006ed81c02cbabee3d50e9f198e..d8b666a0a9b878db3803e352aaf3e70a0bcd1539 100644 (file)
@@ -288,8 +288,6 @@ USA.
   (import (gtk fix-layout)
          fix-ink-extent fix-rect-height fix-rect-width
          ->color set-surface-ink-surface! drawing-damage)
-  (import (runtime graphics)
-         %make-graphics-device)
   (export ()
          gtk-graphics/set-background-color
          gtk-graphics/set-foreground-color
@@ -298,8 +296,7 @@ USA.
          gtk-graphics/draw-circle
          gtk-graphics/fill-polygon-list
          gtk-graphics/clear
-         gtk-graphics/flush
-         gtk-graphics/make))
+         gtk-graphics/flush))
 
 (define-package (gtk fix-layout demo)
   (parent (gtk fix-layout))
index 1446dd9c04ae1f985d872c1e2cae2859c40664cd..081f73272bd82f3d4e5f0a689aa864b08ccfab0a 100644 (file)
@@ -233,7 +233,7 @@ pixels in size.  If @var{no-window?} is specified (not @code{#f}) the
 device will write to the surface, but not put the surface in a window.
 Instead the device's descriptor, a @bref{<surface-ink>}, can be added
 to any fix-drawing, or its Cairo surface can be passed to e.g.
-@bref{cairo-surface-write-to-png}.
+@code{cairo-surface-write-to-png}.
 
 By default (or when @var{no-window?} is @code{#f}) the device's output
 appears in a scrollable window.
@@ -241,13 +241,6 @@ appears in a scrollable window.
 You can draw on the surface with the simple graphics interface and/or
 the following procedures.
 
-@deffn Procedure gtk-graphics/make width height
-Creates a Gtk graphics device even if the output device is not
-available.  The output still goes to a new Cairo image surface with
-@var{width}x@var{height} pixels.  It just can't be displayed (only
-written to a file).
-@end deffn
-
 @deffn Procedure gtk-graphics/fill-polygon-list device points
 Draws a filled polygon.  @var{Points} is a list of flo:vectors each
 containing at least two flonums, the x and y coordinates of a point.
@@ -282,9 +275,9 @@ after resetting its clip region.
 @end deffn
 
 @deffn Procedure gtk-graphics/flush device
-Applies @bref{cairo-surface-flush} to @var{device}'s Cairo surface,
+Applies @code{cairo-surface-flush} to @var{device}'s Cairo surface,
 and updates any drawings containing @var{device}'s descriptor, a
-@bref{<surface-ink>}.  @xref{cairo-surface-flush}.  This is the method
+@bref{<surface-ink>}.  This is the method
 used by @code{graphics-flush}.
 @end deffn
 
@@ -450,11 +443,11 @@ is currently visible.
 
 A gtk-widget is a gobject that can be "destroyed".  Each instance is
 connected to the "destroy" signal of its GtkWidget.  The callback
-applies @bref{gobject-unref!} to the instance,
+applies @code{gobject-unref!} to the instance,
 allowing the toolkit to finalize and dispose of the widget.
 
 If a Gtk Widget is "dropped", never destroyed, eventually GCed, the
-usual gobject cleanup will effect a @bref{gobject-unref!} and
+usual gobject cleanup will effect a @code{gobject-unref!} and
 (potentially) release the toolkit resources.
 
 A Gtk Widget also has a ``parent'' slot --- a @bref{gtk-container} or
@@ -593,7 +586,7 @@ toplevel changes.  It will be updated to match changes to
 @var{widget}'s attributes.  @var{Widget}'s @code{style-set} and
 @code{direction-changed} signals indicate when the context has
 changed.  If you keep a PangoLayout using this default context, the
-signal callbacks should apply @bref{pango-layout-context-changed}.
+signal callbacks should apply @code{pango-layout-context-changed}.
 @end deffn
 
 @deffn Procedure gtk-widget-create-pango-layout widget #!optional text
@@ -601,7 +594,7 @@ Creates a new pango-layout with the appropriate font map, font
 description, and base direction for drawing text for @var{widget}.
 The layout will be empty unless @var{text}, a string, is provided.  If
 @var{widget}'s base direction or font changes, apply
-@bref{pango-layout-context-changed} to re-lay-out the text.
+@code{pango-layout-context-changed} to re-lay-out the text.
 @end deffn
 
 @deffn Procedure gtk-widget-get-size widget
@@ -1944,7 +1937,7 @@ displaying @var{ink}.
 @deffn Procedure set-simple-text-ink-font! text font
 Sets @var{text}'s pango layout's font to @var{font}.  @var{Font}
 should be a PangoFontDescription, or a string acceptable to
-@bref{pango-font-description-from-string} (e.g. @code{courier 12}).
+@code{pango-font-description-from-string} (e.g. @code{courier 12}).
 @end deffn
 
 @subsection Image Ink
@@ -2114,61 +2107,6 @@ In the example call to @code{gtk-label-get-text} above, a Scheme
 object represents the GtkLabel.  It is a gtk-label instance, whose
 class is a specialization of the abstract gtk-object class.
 
-@unnumberedsec Gtk Thread
-
-When the Gtk system loads, it starts a toolkit main loop with Scheme
-attached as an custom idle task.  The main loop then re-starts Scheme,
-which creates a thread to ``run'' the toolkit (actually, return to
-it).  Thus Scheme threads multitask with the toolkit.  Scheme runs as
-an idle task in the toolkit, and the toolkit runs in a Scheme thread.
-A program using the Gtk system does not call @code{gtk_init} nor
-@code{gtk_main}.  It need only create toolkit objects and attach
-signal handlers to them.
-
-@unnumberedsec Toolkit Resource Usage
-
-Each gobject instance is tracked by the weak alist @code{gc-cleanups},
-so that the toolkit object can be @code{g_object_unref}'ed when the
-instance is GCed.
-
-The initialize-instance method for subclasses of gobject should chain
-up early, adding the instance's alien to gc-cleanups @emph{before}
-calling out to the toolkit.  This ensures that an allocated toolkit
-object will not be dropped; its alien address is on the list of GC
-cleanups before it is even allocated.  @emph{After} the callout, the
-initialize method should also @code{g_object_ref_sink} any floating
-refs it receives.
-
-The following scenarios are typical of Gtk resource management.
-
-Temporary alien: The (alien) address of a PangoFontDescription
-is read from a PangoLayout member.  The layout ``owns'' the
-font description.  Scheme does not.  The address should only be used
-while without-toolkit (or without-interrupts), else the
-toolkit may "dispose" of it while Scheme is using it.
-
-Schemely: A toolkit object is created and reflected in Scheme by a
-gobject instance.  Scheme owns the toolkit object, holds a reference,
-and should eventually @code{g_object_unref} it.  The instance may be
-shared among any number of Scheme widgets or other data structures
-(e.g a file->pixbuf cache) and @emph{never} explicitly ``killed''.
-When there are no more Scheme objects sharing the instance, it
-will be GCed and its GC cleanup procedure will ``kill''
-(@code{g_object_unref}) the toolkit object.  This may release toolkit
-resources or not depending on references elsewhere in the toolkit
-data structures.  In any case the instance was GCed --- the object
-cannot be erroneously used by Scheme in the future.
-
-Signals: The @bref{g-signal-connect} procedure takes pains not to hold
-a strong reference to a gobject instance.  These instances can be GCed
-even while signal handlers are connected.  The registered callbacks
-hold only a weak reference to the instance.  It is assumed a callback
-will not be invoked after an instance is GCed, else an error should be
-signaled.
-
-TODO: A world save hook might warn of gobject instances still on the
-gc-cleanups list.  A world restore hook could kill them.
-
 @node GNU Free Documentation License, , Implementation Notes, Top
 @appendix GNU Free Documentation License
 
index 4f2ab5b6845e6ea4c0ee5f84444e7b9dac18bbdf..41824bc04d88cdd922581bd8fec7078471293e08 100644 (file)
@@ -133,19 +133,15 @@ USA.
   (guarantee-pango-layout layout 'pango-layout-get-baseline)
   (let ((iter (make-alien '|PangoLayoutIter|))
        (copy (make-alien '|PangoLayoutIter|)))
-    (add-gc-cleanup iter (make-pango-layout-iter-cleanup copy))
+    (add-glib-cleanup iter (make-pango-layout-iter-cleanup copy))
     (C-call "pango_layout_get_iter" copy (gobject-alien layout))
-    (if (alien-null? copy)
-       (begin
-         (punt-gc-cleanup iter)
-         #f)
-       (begin
-         (copy-alien-address! iter copy)
-         (let ((baseline
-                (pangos->pixels
-                 (C-call "pango_layout_iter_get_baseline" iter))))
-           (pango-layout-iter-free iter)
-           baseline)))))
+    (copy-alien-address! iter copy)
+    (error-if-null iter "Could not create:" iter layout)
+    (let ((baseline
+          (pangos->pixels
+           (C-call "pango_layout_iter_get_baseline" iter))))
+      (pango-layout-iter-free iter)
+      baseline)))
 
 (define (make-pango-layout-iter-cleanup alien)
   (named-lambda (pango-layout-iter-cleanup)
@@ -160,9 +156,8 @@ USA.
    (lambda ()
      (if (not (alien-null? iter))
         (begin
-          (C-call "pango_layout_iter_free" iter)
-          (alien-null! iter)
-          (punt-gc-cleanup iter))))))
+          (execute-glib-cleanup iter)
+          (alien-null! iter))))))
 \f
 ;;; PangoFontDescription
 
@@ -171,15 +166,11 @@ USA.
   (guarantee-string string 'pango-font-description-from-string)
   (let ((font (make-alien '|PangoFontDescription|))
        (copy (make-alien '|PangoFontDescription|)))
-    (add-gc-cleanup font (make-pango-font-description-cleanup copy))
+    (add-glib-cleanup font (make-pango-font-description-cleanup copy))
     (C-call "pango_font_description_from_string" copy string)
-    (if (alien-null? copy)
-       (begin
-         (punt-gc-cleanup font)
-         #f)
-       (begin
-         (copy-alien-address! font copy)
-         font))))
+    (copy-alien-address! font copy)
+    (error-if-null font "Could not create:" font)
+    font))
 
 (define (make-pango-font-description-cleanup alien)
   (named-lambda (pango-font-description-cleanup)
@@ -195,9 +186,8 @@ USA.
    (lambda ()
      (if (not (alien-null? font))
         (begin
-          (C-call "pango_font_description_free" font)
-          (alien-null! font)
-          (punt-gc-cleanup font))))))
+          (execute-glib-cleanup font)
+          (alien-null! font))))))
 
 (define (pango-font-description-to-string font)
   (guarantee-pango-font-description font 'pango-font-description-to-string)
@@ -214,15 +204,11 @@ USA.
 (define (pango-font-description-copy font)
   (let ((new (make-alien '|PangoFontDescription|))
        (copy (make-alien '|PangoFontDescription|)))
-    (add-gc-cleanup new (make-pango-font-description-cleanup copy))
+    (add-glib-cleanup new (make-pango-font-description-cleanup copy))
     (C-call "pango_font_description_copy" copy font)
-    (if (alien-null? copy)
-       (begin
-         (punt-gc-cleanup font)
-         #f)
-       (begin
-         (copy-alien-address! new copy)
-         new))))
+    (copy-alien-address! new copy)
+    (error-if-null new "Could not create:" new font)
+    new))
 
 (define-integrable (guarantee-pango-font-description object operator)
   (if (not (and (alien? object)
@@ -251,9 +237,10 @@ USA.
   (guarantee-pango-font-description font 'pango-context-get-metrics)
   (let ((alien (make-alien '|PangoFontMetrics|))
        (copy (make-alien '|PangoFontMetrics|)))
-    (add-gc-cleanup alien (make-pango-font-metrics-cleanup copy))
+    (add-glib-cleanup alien (make-pango-font-metrics-cleanup copy))
     (C-call "pango_context_get_metrics" copy context font 0)
     (copy-alien-address! alien copy)
+    (error-if-null alien "Could not get:" alien)
     alien))
 
 (define (pango-context-spacing context)
@@ -285,9 +272,8 @@ USA.
    (lambda ()
      (if (not (alien-null? metrics))
         (begin
-          (C-call "pango_font_metrics_unref" metrics)
-          (alien-null! metrics)
-          (punt-gc-cleanup metrics))))))
+          (execute-glib-cleanup metrics)
+          (alien-null! metrics))))))
 
 (define (pango-font-metrics-get-ascent metrics)
   (guarantee-live-pango-font-metrics metrics 'pango-font-metrics-get-ascent)
@@ -328,7 +314,7 @@ USA.
 (define-integrable (pixels->pangos pixel-units)
   (* pixel-units 1024))
 \f
-;;; Debugging hacks.  No gc-cleanups!
+;;; Debugging hacks.  No cleanups!
 
 (define (pango-context-list-families PangoContext)
   (let ((data-arg (malloc (C-sizeof "*") '(* (* |PangoFontFamily|))))
diff --git a/src/planetarium/Makefile b/src/planetarium/Makefile
new file mode 100644 (file)
index 0000000..e98198f
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright (C) 2014 Matthew Birkholz
+#
+# This file is part of an extension to MIT/GNU Scheme.
+#
+# MIT/GNU Scheme is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# MIT/GNU Scheme is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with MIT/GNU Scheme; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+MIT_SCHEME_EXE = mit-scheme
+exe = '$(MIT_SCHEME_EXE)' --batch-mode
+
+all:
+       echo '(load "mit-compile")' | $(exe)
+       @if [ -s mit-3d-unx.crf ]; then \
+           echo "mit-3d-unx.crf:0: error: non-empty"; exit 1; fi
+
+check:
+       echo '(load "mit-check")' | $(exe)
+
+.PHONY: all check
+
+maintainer-clean distclean clean:
+       rm -f *.bin *.ext *.com *.bci *.moc *.fni *.crf *.fre *.pkd
+
+tags:
+       etags *.scm
+
+.PHONY: clean distclean maintainer-clean tags
index 9a99f86fbc86b44758cc00f749505ddb830cb5df..6dd46faf155c2c26d604336a818c3cc59063288a 100644 (file)
@@ -121,7 +121,7 @@ USA.
 (define (latitude-longitude->string lat/lng)
   ;; Format a latitude/longitude in the standard form, e.g.
   ;;
-  ;;     30°26.40′N 122°44.40′W
+  ;;     30°26.400′N 122°44.400′W
 
   (let ((lat (latitude lat/lng))
        (lng (longitude lat/lng)))
@@ -136,15 +136,43 @@ USA.
          (string-append
           (number->string (inexact->exact lat-deg) '(int))
           "°"
-          (number->string lat-min '(fix 2))
+          (number->string lat-min '(fix 3))
           "′"
           (if neg-lat? "S " "N ")
           (number->string (inexact->exact lng-deg) '(int))
           "°"
-          (number->string lng-min '(fix 2))
+          (number->string lng-min '(fix 3))
           "′"
           (if neg-lng? "W" "E")))))))
 
+(define (string->latitude-longitude string)
+  (let* ((digits "\\([0-9]+\\)")
+        (regs (re-string-match
+               (string-append "^"digits"°"digits"."digits"′\\([SN]\\)"
+                              " "digits"°"digits"."digits"′\\([EW]\\)$")
+               string)))
+
+    (define-integrable (->flo n)
+      (->flonum (string->number (re-match-extract string regs n))))
+
+    (define-integrable (->neg? num)
+      (let ((string (re-match-extract string regs num)))
+       (or (string=? "W" string)
+           (string=? "S" string))))
+
+    (define-integrable (dms.->d neg? degrees minutes millimin)
+      (let ((absolute (flo:+ degrees
+                            (flo:* 60.0 (flo:+ minutes
+                                               (flo:/ millimin 1000.))))))
+       (if neg?
+           (flo:negate absolute)
+           absolute)))
+
+    (and regs
+        (make-latitude/longitude
+         (dms.->d (->neg? 4) (->flo 1) (->flo 2) (->flo 3))
+         (dms.->d (->neg? 8) (->flo 5) (->flo 6) (->flo 7))))))
+
 (define (geodesic-distance p1 p2)
   ;; "[Given] the geographic coordinates of two points on the surface
   ;; of the Earth [...] the shortest distance S between these points,
@@ -185,6 +213,16 @@ USA.
             (flo:+ pi d)
             d))))))
 
+#;(define (package-tests)
+  (run-test test-lat/lng-un/parse)
+  (run-test test-angular-separation))
+
+(define (test-lat/lng-un/parse)
+  (let ((samp "30°26.432′N 122°44.456′W"))
+    (if (not (string=? samp (latitude-longitude->string
+                            (string->latitude-longitude samp))))
+       (warn "Latitude/longitude un/parsing failed."))))
+
 (define (test-angular-separation)
 
   (define (test lat1 lng1 lat2 lng2 degrees tolerance)
index ab0d04f80ea2fe3d1642d07b8f4f638cfacd2e69..23cc946741225c5e8f5287505fd7646234b1ebb6 100644 (file)
@@ -26,6 +26,7 @@ USA.
 (global-definitions runtime/)
 (global-definitions sos/)
 (global-definitions xml/)
+(global-definitions glib/)
 (global-definitions gtk/)
 (global-definitions gl/)
 (global-definitions "./mit")
diff --git a/src/planetarium/mit-cairo.scm b/src/planetarium/mit-cairo.scm
new file mode 100644 (file)
index 0000000..d83920e
--- /dev/null
@@ -0,0 +1,59 @@
+#| -*-Scheme-*-
+
+Copyright (C) 2014  Matthew Birkholz
+
+This file is part of an extension to MIT/GNU Scheme.
+
+MIT/GNU Scheme is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+MIT/GNU Scheme is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with MIT/GNU Scheme; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
+USA.
+
+|#
+
+;;;; System specific code for MIT Scheme using a cairo-graphics device.
+
+(define (make-suitable-graphics-device)
+  (let ((device (make-graphics-device 'cairo 512 512)))
+    (graphics-set-coordinate-limits device -1.1 -1.1 1.1 1.1)
+    device))
+
+(define-integrable (x p) (flo:vector-ref p 0))
+(define-integrable (y p) (flo:vector-ref p 1))
+
+(define (draw-segment device start end color)
+  (cairo-graphics/set-foreground-color device color)
+  #;(cairo-graphics/draw-line-points device start end)
+  (cairo-graphics/draw-line device
+                           (x start) (y start)
+                           (x end) (y end)))
+
+(define (draw-circle device center radius color)
+  (cairo-graphics/set-foreground-color device color)
+  (cairo-graphics/draw-circle device (x center) (y center) radius))
+
+(define (draw-text device coords string color)
+  (cairo-graphics/set-foreground-color device color)
+  (cairo-graphics/draw-text device (x coords) (y coords) string))
+
+(define (fill-polygon-available?) #t)
+
+(define (fill-polygon device points color)
+  (cairo-graphics/set-foreground-color device color)
+  (cairo-graphics/fill-polygon-list device points))
+
+(define (clear-graphics device)
+  (cairo-graphics/clear device))
+
+(define (flush-graphics device)
+  (cairo-graphics/flush device))
\ No newline at end of file
index b4566ebc4d5340c26db4b1760611b59957ce5de2..0a1e5ba64d8f0eefada63d30df54d1bf79632db1 100644 (file)
@@ -1,6 +1,6 @@
 #| -*-Scheme-*-
 
-Copyright (C) 2013  Matthew Birkholz
+Copyright (C) 2013, 2014  Matthew Birkholz
 
 This file is part of an extension to MIT/GNU Scheme.
 
@@ -51,6 +51,7 @@ USA.
     (cf '("earth" "tellurion")
                       '("geometry" "matrices") '(planetarium))
     (cf "mit-gtk"      '() '(planetarium gtk-graphics))
+    (cf "mit-cairo"    '() '(planetarium cairo-graphics))
     (cf "mit-x"        '() '(planetarium x-graphics))
     (cf "mit-graphics" '() '(planetarium simple-graphics))
     (cf "mit-cil"      `("mit-syntax" ,@(directory-read "cil-*.txt"))
index a2709f8067e93bd7826e6a5ccc5ff4eb7ae4be4b..ca391e1f4195cbe504dda9575c89a19c2005e3da 100644 (file)
@@ -1,6 +1,6 @@
 #| -*-Scheme-*-
 
-Copyright (C) 2013  Matthew Birkholz
+Copyright (C) 2013, 2014  Matthew Birkholz
 
 This file is part of an extension to MIT/GNU Scheme.
 
@@ -24,43 +24,29 @@ USA.
 ;;;; Generate snapshots (PNG files).
 
 ;; Expect warning about DISPLAY not set.
-(load-option 'GTK)
+(load-option 'CAIRO)
 
 (with-working-directory-pathname
     (directory-pathname (current-load-pathname))
   (lambda ()
-    (load "mit-compile")
-    (let* ((package-set (package-set-pathname "mit"))
-          (file (fasload package-set)))
-      (if (not ((access package-file? (->environment '(package))) file))
-         (error "Malformed package-description file:" pkg))
-      (load-packages-from-file file '()
-                              (lambda (pathname environment)
-                                (load pathname environment 'DEFAULT #t)))
-      ((access initialize-packages-from-file (->environment '(package))) file)
-      (flush-purification-queue!))))
+    (load-package-set "mit")))
 
 (let ((planet (->environment '(planetarium)))
-      (graphics (->environment '(planetarium gtk-graphics))))
+      (graphics (->environment '(planetarium cairo-graphics))))
   (for-each (lambda (name) (environment-link-name planet graphics name))
-           '(make-suitable-graphics-device
-             draw-segment draw-circle draw-text
+           '(draw-segment draw-circle draw-text
              fill-polygon-available? fill-polygon
              clear-graphics flush-graphics)))
 
 (let ((here (the-environment))
-      (planet (->environment '(planetarium)))
-      (gtk (->environment '(gtk))))
+      (planet (->environment '(planetarium))))
   (for-each (lambda (name) (environment-link-name here planet name))
-           '(make-latitude/longitude draw-tellurion))
-  (for-each (lambda (name) (environment-link-name here gtk name))
-           '(surface-ink-surface
-             cairo-surface-write-to-png cairo-surface-destroy)))
+           '(make-latitude/longitude draw-tellurion)))
 
 (let ((time (get-universal-time))
       (latitude 33.3)
       (longitude -111.9)
-      (device (gtk-graphics/make 400 400)))
+      (device (make-graphics-device 'cairo 400 400)))
   (graphics-set-coordinate-limits device -1.1 -1.1 1.1 1.1)
 
   (call-with-append-file "tellurion.log"
@@ -77,6 +63,5 @@ USA.
          (write-string (universal-time->local-time-string time) out)
          (newline out)))))
 
-  (let ((surface (surface-ink-surface (graphics-device/descriptor device))))
-    (cairo-surface-write-to-png surface "tellurion.png")
-    (cairo-surface-destroy surface)))
\ No newline at end of file
+  (cairo-graphics/write-to-png device "tellurion.png")
+  (cairo-graphics/destroy device))
\ No newline at end of file
index ad91156b547dd1fd0e9ca531f5d54f057e805893..caef3d10eedb374e35214d14e38775aebb8740f5 100644 (file)
@@ -24,6 +24,7 @@ USA.
 ;;;; Planetarium Packaging
 
 (global-definitions runtime/)
+(global-definitions cairo/)
 (global-definitions gtk/)
 
 (define-package (r3rs essential)
@@ -113,6 +114,8 @@ USA.
          decoded-time/year decoded-time/month decoded-time/day 
          universal-time->string
 
+         re-string-match re-match-extract
+
          error warn)
   (import (planetarium syntax)
          define-integrable-operator)
@@ -126,25 +129,33 @@ USA.
   (export ()
          make-tellurion))
 
+(define-package (planetarium cairo-graphics)
+  (parent ())
+  (files "mit-cairo")
+  (export (planetarium)
+         ;; Exports must be set up manually, as in mit-link.scm, if
+         ;; this is the desired type of output device.
+         ))
+
 (define-package (planetarium gtk-graphics)
   (parent ())
   (files "mit-gtk")
   (export (planetarium)
-         ;; Exports are actually set up by make.scm per the available graphics.
+         ;; Exports are set up by mit-link.scm per the available graphics.
          ))
 
 (define-package (planetarium x-graphics)
   (parent ())
   (files "mit-x")
   (export (planetarium)
-         ;; Exports are actually set up by make.scm per the available graphics.
+         ;; Exports are set up by mit-link.scm per the available graphics.
          ))
 
 (define-package (planetarium simple-graphics)
   (parent ())
   (files "mit-graphics")
   (export (planetarium)
-         ;; Exports are actually set up by make.scm per the available graphics.
+         ;; Exports are set up by mit-link.scm per the available graphics.
          ))
 
 (define-package (planetarium earth-cil)
index 3ec6233d3117ef8507f4c1fb7db4ffeaed13aed3..450aa4b7845eece10adb467aa46c2fa577226201 100644 (file)
@@ -56,11 +56,11 @@ USA.
 (define (run-tellurion queue)
   (let ((device (make-suitable-graphics-device))
        ;; Latitude and longitude per GPS -- positive degrees long. to the east.
-       (lat/long (make-latitude/longitude 23.271 0.))
+       (lat/lng (make-latitude/longitude 23.271 0.))
        (time (get-universal-time))
        (stopped? #f))
     (define-integrable (draw)
-      (draw-tellurion device time lat/long))
+      (draw-tellurion device time lat/lng))
     (draw)
     (let loop ()
       (let ((command (if stopped?
@@ -76,8 +76,8 @@ USA.
               (set! time (get-universal-time))
               (draw))
              ((eq? (car command) 'TURN-TO)
-              (set-latitude! lat/long (cadr command))
-              (set-longitude! lat/long (caddr command))
+              (set-latitude! lat/lng (cadr command))
+              (set-longitude! lat/lng (caddr command))
               (draw))
              ((eq? (car command) 'TIME-TO)
               (if (eq? (cadr command) 'current)
@@ -105,62 +105,28 @@ USA.
       (loop))))
 
 (define draw-tellurion
-  (let ((lat/long-pos (make-2d-point -1. -1.02))
+  (let ((lat/lng-pos (make-2d-point -1. -1.02))
        (time-pos (make-2d-point -1. 1.))
        (cross-hair-left (make-2d-point -.02 0.))
        (cross-hair-right (make-2d-point .02 0.))
        (cross-hair-top (make-2d-point 0. .02))
        (cross-hair-bottom (make-2d-point 0. -.02)))
-    (named-lambda (draw-tellurion device time lat/long)
+    (named-lambda (draw-tellurion device time lat/lng)
       (clear-graphics device)
       (draw-text device time-pos (universal-time->string time) "black")
-      (draw-text device lat/long-pos (latitude/longitude-string lat/long) "black")
+      (draw-text device lat/lng-pos (latitude-longitude->string lat/lng) "black")
       (draw-earth device
-                 (orientation-matrix lat/long)
+                 (orientation-matrix lat/lng)
                  (solar-latitude/longitude
                   (universal-time->julian-day time)))
       (draw-segment device cross-hair-left cross-hair-right "black")
       (draw-segment device cross-hair-top cross-hair-bottom "black")
       (flush-graphics device))))
 
-(define (orientation-matrix lat/long)
+(define (orientation-matrix lat/lng)
   (let ((Mx (make-x-rotation-matrix (degrees->radians
-                                    (latitude lat/long))))
+                                    (latitude lat/lng))))
        (My (make-y-rotation-matrix (degrees->radians
-                                    (flo:negate (longitude lat/long))))))
+                                    (flo:negate (longitude lat/lng))))))
     (3d-multiply! Mx My Mx)
-    Mx))
-
-(define (latitude/longitude-string lat/long)
-  (let ((lat (latitude lat/long))
-       (long (longitude lat/long)))
-    (let ((lat-deg (truncate->exact (abs lat)))
-         (long-deg (truncate->exact (abs long))))
-      (let ((lat-minutes (* 60 (- (abs lat) lat-deg)))
-           (long-minutes (* 60 (- (abs long) long-deg))))
-       (let ((lat-min (truncate->exact lat-minutes))
-             (long-min (truncate->exact long-minutes)))
-         (let ((lat-frac (round->exact (* 1000 (- lat-minutes lat-min))))
-               (long-frac (round->exact (* 1000 (- long-minutes long-min)))))
-           (string-append (cond ((flo:negative? lat) "S")
-                                ((flo:positive? lat) "N")
-                                (else ""))
-                          (number->string lat-deg '(int))
-                          "°"
-                          (string-pad-left (number->string lat-min '(int))
-                                           2 #\0)
-                          "."
-                          (string-pad-left (number->string lat-frac '(int))
-                                           3 #\0)
-                          "' "
-                          (cond ((flo:negative? long) "W")
-                                ((flo:positive? long) "E")
-                                (else ""))
-                          (number->string long-deg '(int))
-                          "°"
-                          (string-pad-left (number->string long-min '(int))
-                                           2 #\0)
-                          "."
-                          (string-pad-left (number->string long-frac '(int))
-                                           3 #\0)
-                          "'")))))))
\ No newline at end of file
+    Mx))
\ No newline at end of file