diff -ruN /tmp/cl-opengl/glut/callbacks.lisp glut/callbacks.lisp
--- /tmp/cl-opengl/glut/callbacks.lisp	2009-07-08 22:19:09.000000000 +0100
+++ glut/callbacks.lisp	2009-07-06 21:28:49.000000000 +0100
@@ -137,21 +137,29 @@
   (poll-interval :int))
 
 ;; freeglut ext
+#-darwin
 (defcfun ("glutMouseWheelFunc" mouse-wheel-func) :void
   ;; void (*func)(int button, int pressed, int x, int y)
   (callback-pointer :pointer))
 
 ;; freeglut ext
+#-darwin
 (defcfun ("glutCloseFunc" close-func) :void
   ;; void (*func)(void)
   (callback-pointer :pointer))
 
+#+darwin
+(defcfun ("glutWMCloseFunc" close-func) :void
+  ;; void (*func)(void)
+  (callback-pointer :pointer))
+
 ;; freeglut ext
 (defcfun ("glutWMCloseFunc" wm-close-func) :void
   ;; void (*func)(void)
   (callback-pointer :pointer))
 
 ;; freeglut ext
+#-darwin
 (defcfun ("glutMenuDestroyFunc" menu-destroy-func) :void
   ;; void (*func)(void)
   (callback-pointer :pointer))
diff -ruN /tmp/cl-opengl/glut/fonts.lisp glut/fonts.lisp
--- /tmp/cl-opengl/glut/fonts.lisp	2009-07-08 22:19:09.000000000 +0100
+++ glut/fonts.lisp	2009-07-06 21:28:49.000000000 +0100
@@ -107,19 +107,23 @@
   (string :string))
 
 ;; freeglut ext
+#-darwin
 (defcfun ("glutBitmapHeight" bitmap-height) :int
   (font :pointer))
 
 ;; freeglut ext
+#-darwin
 (defcfun ("glutStrokeHeight" stroke-height) %gl:float
   (font :pointer))
 
 ;; freeglut ext
+#-darwin
 (defcfun ("glutBitmapString" bitmap-string) :void
   (font :pointer)
   (string :string))
 
 ;; freeglut ext
+#-darwin
 (defcfun ("glutStrokeString" stroke-string) :void
   (font :pointer)
   (string :string))
\ No newline at end of file
diff -ruN /tmp/cl-opengl/glut/geometry.lisp glut/geometry.lisp
--- /tmp/cl-opengl/glut/geometry.lisp	2009-07-08 22:19:08.000000000 +0100
+++ glut/geometry.lisp	2009-07-06 21:28:49.000000000 +0100
@@ -92,33 +92,39 @@
 
 ;;; The following are freeglut extensions:
 
-(defcfun ("glutWireRhombicDodecahedron" wire-rhombic-dodecahedron) :void)
-(defcfun ("glutSolidRhombicDodecahedron" solid-rhombic-dodecahedron) :void)
+#-darwin (defcfun ("glutWireRhombicDodecahedron" wire-rhombic-dodecahedron) :void)
+#-darwin (defcfun ("glutSolidRhombicDodecahedron" solid-rhombic-dodecahedron) :void)
 
+#-darwin
 (defcfun ("glutWireSierpinskiSponge" %glutWireSierpinskiSponge) :void
   (num-levels :int)
   (offset-seq :pointer) ; GLdouble offset[3]
   (scale %gl:double))
 
+#-darwin
 (defun wire-sierpinski-sponge (num-levels offset-seq scale)
   (gl::with-opengl-sequence (offset '%gl:double offset-seq)
     (%glutWireSierpinskiSponge num-levels offset scale)))
 
+#-darwin
 (defcfun ("glutSolidSierpinskiSponge" %glutSolidSierpinskiSponge) :void
   (num-levels :int)
   (offset-seq :pointer) ; GLdouble offset[3]
   (scale %gl:double))
 
+#-darwin
 (defun solid-sierpinski-sponge (num-levels offset-seq scale)
   (gl::with-opengl-sequence (offset '%gl:double offset-seq)
     (%glutSolidSierpinskiSponge num-levels offset scale)))
 
+#-darwin
 (defcfun ("glutWireCylinder" wire-cylinder) :void
   (radius %gl:double)
   (height %gl:double)
   (slices %gl:int)
   (stacks %gl:int))
 
+#-darwin
 (defcfun ("glutSolidCylinder" solid-cylinder) :void
   (radius %gl:double)
   (height %gl:double)
diff -ruN /tmp/cl-opengl/glut/init.lisp glut/init.lisp
--- /tmp/cl-opengl/glut/init.lisp	2009-07-08 22:19:09.000000000 +0100
+++ glut/init.lisp	2009-07-08 22:11:07.000000000 +0100
@@ -43,22 +43,65 @@
   #-(and sbcl (or x86 x86-64))
   `(progn ,@body))
 
+
+(defparameter *glut-initialized-p* nil)
+
+#+(and darwin (or
+               openmcl-native-threads
+               sb-thread))
+(defparameter *glut-thread* nil)
+
+
 (defun init (&optional (program-name (lisp-implementation-type)))
   (without-fp-traps
     ;; freeglut will exit() if we try to call initGlut() when
     ;; things are already initialized.
-    (unless (getp :init-state)
-      (with-foreign-objects ((argcp :int) (argv :pointer))
-        (setf (mem-ref argcp :int) 1)
-        (with-foreign-string (str program-name)
-          (setf (mem-ref argv :pointer) str)
-          (%glutInit argcp argv)))
-      ;; By default, we choose the saner option to return from the event
-      ;; loop on window close instead of exit()ing.
-      (set-action-on-window-close :action-continue-execution)
-      ;; this probably doesn't play well with other toolkits
-      (setq %gl:*gl-get-proc-address* 'get-proc-address)))
+    (unless
+        #-darwin (getp :init-state)
+        #+darwin *glut-initialized-p*
+        #+(and darwin openmcl-native-threads)
+        (setf *glut-thread*
+              (ccl:process-run-function
+               "GLUT thread"
+               (lambda ()
+                 (progn
+                   (ccl::external-call "_CFRunLoopGetCurrent" :address)
+                   (ccl::external-call
+                    "__CFRunLoopSetCurrent"
+                    :address (ccl::external-call "_CFRunLoopGetMain" :address)))
+                 (init-2 program-name)
+                 (loop (sleep 1)))))
+        #+(and darwin sb-thread)
+        (setf *glut-thread*
+              (sb-thread:make-thread
+               (lambda ()
+                 (progn
+                   (cffi:foreign-funcall "CFRunLoopGetCurrent" :pointer)
+                   (cffi:foreign-funcall "_CFRunLoopSetCurrent" :pointer
+                                         (cffi:foreign-funcall "CFRunLoopGetMain" :pointer)))
+                 (init-2 program-name)
+                 (loop (sleep 1))) :name "GLUT thread"))
+        #-(and darwin (or sb-thread openmcl-native-threads))
+        (init-2 program-name)
+        ))
   (values))
+             
+                            
+
+(defun init-2 (&optional (program-name (lisp-implementation-type)))
+  (with-foreign-objects ((argcp :int) (argv :pointer))
+    (setf (mem-ref argcp :int) 1)
+    (with-foreign-string (str program-name)
+      (setf (mem-ref argv :pointer) str)
+      (%glutInit argcp argv)
+      (setf *glut-initialized-p* t)))
+  ;; By default, we choose the saner option to return from the event
+  ;; loop on window close instead of exit()ing.
+  (set-action-on-window-close :action-continue-execution)
+  ;; this probably doesn't play well with other toolkits
+  (setq %gl:*gl-get-proc-address* 'get-proc-address)
+  (values))
+
 
 ;; We call init at load-time in order to ensure a usable glut as often
 ;; as possible. Also, we call init when the main event loop returns in
diff -ruN /tmp/cl-opengl/glut/interface.lisp glut/interface.lisp
--- /tmp/cl-opengl/glut/interface.lisp	2009-07-08 22:19:09.000000000 +0100
+++ glut/interface.lisp	2009-07-08 22:38:43.000000000 +0100
@@ -112,6 +112,7 @@
 (defgeneric enable-event (window event-name))
 (defgeneric disable-event (window event-name))
 
+
 (defmacro when-current-window-exists (&body body)
   "Evals BODY when GLUT's current window exists in *ID->WINDOW*.
 Lexically binds CURRENT-WINDOW to the respective object."
@@ -123,6 +124,7 @@
              ;;(format t "glut callback: ~A -> ~A~%" ,id current-window)
              ,@body))))))
 
+    
 (define-foreign-type ascii-to-char ()
   ()
   (:actual-type :unsigned-char)
@@ -159,6 +161,7 @@
                 (when-current-window-exists
                  (,name current-window ,@(mapcar #'car (cdr args))))))))
 
+
 (define-glut-events
   ;; (idle             (window))
   (keyboard         (window (key ascii-to-char) (x :int) (y :int)))
@@ -188,10 +191,10 @@
   ;;                           (z :int)))
   (mouse-wheel      (window (button mouse-button) (pressed mouse-button-state)
                             (x :int) (y :int)))
-  (close            (window))
-  ;; (wm-close         (window)) ; synonym for CLOSE
+  (close            (window)) 
   (menu-destroy     (window)))
 
+
 ;;; These two functions should not be called directly and are called
 ;;; by ENABLE-EVENT and DISABLE-EVENT. See below.
 
@@ -220,6 +223,7 @@
 (defclass base-window ()
   ((name :reader name :initarg :name :initform (gensym "GLUT-WINDOW"))
    (id   :reader id)
+   (destroyed :accessor destroyed :initform nil)
    (pos-x  :accessor pos-x  :initarg :pos-x)
    (pos-y  :accessor pos-y  :initarg :pos-y)
    (height :accessor height :initarg :height)
@@ -249,6 +253,7 @@
         when (and (not (null window)) (eq (name window) name))
         do (return window)))
 
+
 (defmacro with-window (window &body body)
   (let ((current-id (gensym)))
     `(let ((,current-id (get-window)))
@@ -258,12 +263,14 @@
               ,@body)
          (set-window ,current-id)))))
 
+
 ;;; We do some extra stuff to provide an IDLE event per-window since
 ;;; GLUT's IDLE event is global.
 (define-glut-event idle (window)
   (loop for win in *windows-with-idle-event*
-        do (with-window win
-             (idle win))))
+     do (with-window win
+          (idle win))))
+
 
 (defun find-applicable-events (window)
   (loop for event in *events*
@@ -303,42 +310,81 @@
 (defmethod display-window ((win base-window))
   (values))
 
+;; Bugfix: Check if event is already enabled
 (defmethod enable-event ((window base-window) event-name)
   (let ((event (find-event-or-lose event-name)))
-    (with-window window
-      (register-callback event))
-    (pushnew event (events window))
-    (when (eq event-name :idle)
-      (push window *windows-with-idle-event*))))
+    (when (not (find event (events window)))
+      (with-window window
+        (register-callback event))
+      (pushnew event (events window))
+      (when (eq event-name :idle)
+        (push window *windows-with-idle-event*)))))
+  
 
 (defmethod disable-event ((window base-window) event-name)
   (if (eq event-name :display)
       (warn "GLUT would be upset if we set the DISPLAY callback to NULL. ~
              So we won't do that.")
       (let ((event (find-event-or-lose event-name)))
-        ;; We don't actually disable the CLOSE event since we need it
-        ;; for bookkeeping. See the CLOSE methods below.
-        (unless (or (eq event-name :idle) (eq event-name :close))
-          (with-window window
-            (unregister-callback event)))
-        (setf (events window) (delete event (events window)))
-        (when (eq event-name :idle)
-          (setq *windows-with-idle-event*
-                (delete window *windows-with-idle-event*))))))
+        (when (find event (events window))
+          ;; We don't actually disable the CLOSE event since we need it
+          ;; for bookkeeping. See the CLOSE methods below.
+          (unless (or (eq event-name :idle)
+                      (eq event-name :close))
+            (with-window window
+              (unregister-callback event)))
+          (setf (events window) (delete event (events window)))
+          (when (eq event-name :idle)
+            (setq *windows-with-idle-event*
+                  (delete window *windows-with-idle-event*)))
+          ;; We need to disable the idle callback here too in addition to close
+          (when (null *windows-with-idle-event*)
+            (unregister-callback (find-event-or-lose :idle)))))))
+          
 
 (defun destroy-current-window ()
   (when-current-window-exists
     (if (game-mode current-window)
         (leave-game-mode)
-        (destroy-window (id current-window)))))
+        #-darwin
+        (destroy-window (id current-window))
+        #+darwin
+        (progn
+          (destroy-window (id current-window))
+          (setf (destroyed current-window) t)
+          (close current-window))
+        )))
 
 (defmethod close :around ((w base-window))
   (when (member :close (events w) :key #'event-name)
     (call-next-method))
   (setf (aref *id->window* (id w)) nil)
   (setq *windows-with-idle-event* (delete w *windows-with-idle-event*))
+  #+darwin
+  (when (not (destroyed w))
+    (setf (destroyed w) t)
+    (destroy-window (id w)))
   (when (null *windows-with-idle-event*)
-    (unregister-callback (find-event-or-lose :idle))))
+    (unregister-callback (find-event-or-lose :idle)))
+  #+darwin
+  (progn
+    (when (= 0 (length (remove-if #'null *id->window*)))
+      ;; We want to leave the glut event loop if all glut windows are closed,
+      ;; even when :action-continue-execution is set
+      (leave-main-loop))
+    (ecase *window-close-action*
+      ;; :action-exit is probably unnecessary, as it should never be used
+      (:action-exit                       
+       #+sbcl (sb-ext:quit)
+       #+ccl (ccl:quit)
+       #-(or sbcl ccl) nil
+       )
+      (:action-glutmainloop-returns
+       (leave-main-loop))
+      (:action-continue-execution
+       nil)))
+  )
+
 
 (defmethod close ((w base-window))
   (values))
@@ -417,10 +463,17 @@
 ;;; loops in the initial thread on multithreaded Lisps, or in this case,
 ;;; OpenMCL."
 
+
 ;; #-openmcl
 ;; (defun run-event-loop ()
 ;;   (glut:main-loop))
 
+;;; The following does not seem to work in current CCL (1.3) as the initial
+;;; thread does various housekeeping tasks and can not be simply hijacked
+;;; in the manner demonstrated below. Someone familiar with CCL might look
+;;; into how CCL does this with its own event loop that hooks into cocoa
+;;; and duplicate the functionality.
+
 ;; #+openmcl
 ;; (defun run-event-loop ()
 ;;   (flet ((start ()
diff -ruN /tmp/cl-opengl/glut/library.lisp glut/library.lisp
--- /tmp/cl-opengl/glut/library.lisp	2009-07-08 22:19:08.000000000 +0100
+++ glut/library.lisp	2009-07-06 23:14:08.000000000 +0100
@@ -32,9 +32,15 @@
 
 (in-package :cl-glut)
 
+#+(and sb-thread darwin)
+(define-foreign-library core-foundation
+  (:darwin (:framework "CoreFoundation")))
+  
 (define-foreign-library glut
-  (:darwin (:or "libglut.dylib" "libglut.3.dylib"))
+  (:darwin (:framework "GLUT"))
   (:windows "freeglut.dll")
   (:unix (:or "libglut.so" "libglut.so.3")))
 
-(use-foreign-library glut)
\ No newline at end of file
+(use-foreign-library glut)
+#+(and sb-thread darwin)
+(use-foreign-library core-foundation)
\ No newline at end of file
diff -ruN /tmp/cl-opengl/glut/main.lisp glut/main.lisp
--- /tmp/cl-opengl/glut/main.lisp	2009-07-08 22:19:09.000000000 +0100
+++ glut/main.lisp	2009-07-08 22:13:29.000000000 +0100
@@ -33,12 +33,48 @@
 (in-package #:cl-glut)
 
 (defcfun ("glutMainLoop" %glutMainLoop) :void)
+#+darwin (defcfun ("glutCheckLoop" check-loop) :void)
 
+#-darwin
 (defun main-loop ()
   (without-fp-traps
     (%glutMainLoop))
   (init))
 
-(defcfun ("glutMainLoopEvent" main-loop-event) :void)
+#+darwin
+(let ((darwin-run-main-loop-p t))
+  (defun main-loop ()
+      (warn "GLUT main loop entered~%")
+      #+openmcl-native-threads
+      (ccl:process-interrupt
+       *glut-thread*
+       (lambda ()         
+         (without-fp-traps
+           (loop :while darwin-run-main-loop-p :do (check-loop)))
+         (init)
+         (warn "GLUT main loop exit~%")
+         (setf darwin-run-main-loop-p t)))
+      #+sb-thread
+      (sb-thread:interrupt-thread
+       *glut-thread*
+       (lambda ()
+         (without-fp-traps
+           (loop :while darwin-run-main-loop-p :do (check-loop)))
+         (init)
+         (warn "GLUT main loop exit~%")
+         (setf darwin-run-main-loop-p t)))
+      #-(or openmcl-native-threads sb-thread)
+      (progn
+        (without-fp-traps
+          (loop :while darwin-run-main-loop-p :do (check-loop)))
+        (init)
+        (warn "GLUT main loop exit~%")
+        (setf darwin-run-main-loop-p t))
+      )
+  
+  (defun leave-main-loop ()
+    (setf darwin-run-main-loop-p nil)))
+  
 
-(defcfun ("glutLeaveMainLoop" leave-main-loop) :void)
\ No newline at end of file
+#-darwin (defcfun ("glutMainLoopEvent" main-loop-event) :void)
+#-darwin (defcfun ("glutLeaveMainLoop" leave-main-loop) :void)
\ No newline at end of file
diff -ruN /tmp/cl-opengl/glut/misc.lisp glut/misc.lisp
--- /tmp/cl-opengl/glut/misc.lisp	2009-07-08 22:19:09.000000000 +0100
+++ glut/misc.lisp	2009-07-06 21:28:49.000000000 +0100
@@ -73,7 +73,8 @@
 (defcfun ("glutGameModeString" game-mode-string) :void
   (string :string))
 
-(defcfun ("glutEnterGameMode" enter-game-mode) :int)
+#-darwin (defcfun ("glutEnterGameMode" enter-game-mode) :int)
+#+darwin (defcfun ("glutEnterGameMode" enter-game-mode) :void)
 (defcfun ("glutLeaveGameMode" leave-game-mode) :void)
 
 (defcenum (game-mode-param %gl:enum)
diff -ruN /tmp/cl-opengl/glut/state.lisp glut/state.lisp
--- /tmp/cl-opengl/glut/state.lisp	2009-07-08 22:19:08.000000000 +0100
+++ glut/state.lisp	2009-07-06 21:28:49.000000000 +0100
@@ -41,6 +41,11 @@
 
 ;;; Setting Options
 
+
+(defparameter *window-close-action*
+  nil)
+
+
 ;; freeglut ext
 (defcenum (options %gl:enum)
   (:init-window-x #x01F4)
@@ -54,10 +59,15 @@
   (:window-cursor #x007A))
 
 ;;; freeglut ext
+#-darwin
 (defcfun ("glutSetOption" set-option) :void
   (option options)
   (value :int))
 
+#+darwin
+(defun set-option (val1 val2)
+  (declare (ignore val1 val2)))
+
 ;;; Also provide some utility functions around glutSetOption().
 
 ;; freeglut ext
@@ -100,9 +110,13 @@
   (set-option :init-display-mode
               (foreign-bitfield-value 'display-mode options)))
 
+
 (defun set-action-on-window-close (action)
   (set-option :action-on-window-close
-              (foreign-enum-value 'window-close-behaviour action)))
+              (foreign-enum-value 'window-close-behaviour action))
+  (setf *window-close-action*
+        action))
+
 
 (defun set-rendering-context (option)
   (set-option :rendering-context
@@ -155,8 +169,8 @@
   (:action-on-window-close #x01F9)      ; freeglut ext
   :window-border-width                  ; freeglut ext
   :window-header-height                 ; freeglut ext
-  :version                              ; freeglut ext
-  :rendering-context                    ; freeglut ext
+  :version                              ; freeglut ext  
+#-darwin  :rendering-context                    ; freeglut ext
   :direct-rendering)
 
 (defcfun ("glutGet" get) :int
