[cells-cvs] CVS cells-gtk3/cells-gtk

phildebrandt phildebrandt at common-lisp.net
Mon Apr 14 16:43:47 UTC 2008


Update of /project/cells/cvsroot/cells-gtk3/cells-gtk
In directory clnet:/tmp/cvs-serv13587/cells-gtk

Modified Files:
	buttons.lisp cairo-drawing-area.lisp cells-gtk.asd 
	drawing-area.lisp gl-drawing-area.lisp gtk-app.lisp 
	packages.lisp widgets.lisp 
Log Message:
Added OpenGL drawing area


--- /project/cells/cvsroot/cells-gtk3/cells-gtk/buttons.lisp	2008/04/13 10:59:16	1.1
+++ /project/cells/cvsroot/cells-gtk3/cells-gtk/buttons.lisp	2008/04/14 16:43:41	1.2
@@ -81,7 +81,7 @@
 
 (def-widget radio-button (check-button)
   () () ()
-  :new-tail (c? (and (upper self box)
+  :new-tail (c_1 (and (upper self box)
 		     (not (eql (first (kids (fm-parent self))) self))
 		     '-from-widget))
 			 
--- /project/cells/cvsroot/cells-gtk3/cells-gtk/cairo-drawing-area.lisp	2008/04/13 10:59:16	1.1
+++ /project/cells/cvsroot/cells-gtk3/cells-gtk/cairo-drawing-area.lisp	2008/04/14 16:43:41	1.2
@@ -216,19 +216,6 @@
   (deb "done."))
 
 
-;;;; -----------------------------------------------------------
-;;;;        redraw method (called to trigger a refresh) 
-;;;; -----------------------------------------------------------
-
-;;; a handler if redraw called on nil
-(defmethod redraw (self))
-
-(defmethod redraw ((self cairo-drawing-area))
-  "Queues a redraw with GTK.  This is called whenever a primitve is modified"
-  (trc nil "queue redraw" self)
-  (gtk-ffi:gtk-widget-queue-draw (widget-id self)))
-
-
 (defobserver prims ((self cairo-drawing-area))
   (redraw self))
 
--- /project/cells/cvsroot/cells-gtk3/cells-gtk/cells-gtk.asd	2008/04/13 10:59:16	1.1
+++ /project/cells/cvsroot/cells-gtk3/cells-gtk/cells-gtk.asd	2008/04/14 16:43:42	1.2
@@ -17,7 +17,7 @@
 (pushnew :cells-gtk-cairo *features*)
 
 ;;; drawing-area widget using OpenGL (requires libgtkglext1)
-;(pushnew :cells-gtk-opengl *features*)
+(pushnew :cells-gtk-opengl *features*)
 
 (asdf:defsystem :cells-gtk
   :name "cells-gtk"
@@ -27,7 +27,10 @@
 	       :gtk-ffi
 	       :ph-maths
 	       #+cells-gtk-cairo :cl-cairo2
-	       #+cells-gtk-threads :bordeaux-threads)
+	       #+cells-gtk-threads :bordeaux-threads
+	       #+cells-gtk-opengl :cl-opengl
+	       #+cells-gtk-opengl :cl-glu
+	       #+cells-gtk-opengl :cl-glut)
   :serial t
   :components
   ((:file "packages")   
--- /project/cells/cvsroot/cells-gtk3/cells-gtk/drawing-area.lisp	2008/04/13 10:59:17	1.1
+++ /project/cells/cvsroot/cells-gtk3/cells-gtk/drawing-area.lisp	2008/04/14 16:43:42	1.2
@@ -123,10 +123,26 @@
   (declare (ignore rest))
   (let ((widget (id self)))
     (trc "registering handlers for" widget)
-   (gtk-widget-add-events widget 772) ; 512 + 256 + 4 button_press, release, motion
-   (gtk-signal-connect-swap widget "button-press-event" (cffi:get-callback 'drawing-button-handler) :data widget)
-   (gtk-signal-connect-swap widget "button-release-event" (cffi:get-callback 'drawing-button-handler) :data widget)
-   (gtk-signal-connect-swap widget "motion-notify-event" (cffi:get-callback 'drawing-pointer-motion-handler) :data widget)
-   (gtk-signal-connect-swap widget "expose-event" (cffi:get-callback 'drawing-expose-handler) :data widget)))
+    (gtk-widget-add-events widget 772) ; 512 + 256 + 4 button_press, release, motion
+    (gtk-signal-connect-swap widget "button-press-event" (cffi:get-callback 'drawing-button-handler) :data widget)
+    (gtk-signal-connect-swap widget "button-release-event" (cffi:get-callback 'drawing-button-handler) :data widget)
+    (gtk-signal-connect-swap widget "motion-notify-event" (cffi:get-callback 'drawing-pointer-motion-handler) :data widget)
+    (gtk-signal-connect-swap widget "expose-event" (cffi:get-callback 'drawing-expose-handler) :data widget)))
+
+
+;;;
+;;; redraw method (called to trigger a refresh) 
+;;;
+
+;;; a handler if redraw called on nil
+(export! redraw)
+
+(defmethod redraw (self))
+
+(defmethod redraw ((self drawing-area))
+  "Queues a redraw with GTK."
+  (trc nil "queue redraw" self)
+  (gtk-widget-queue-draw (id self)))
+
 
 
--- /project/cells/cvsroot/cells-gtk3/cells-gtk/gl-drawing-area.lisp	2008/04/13 10:59:17	1.1
+++ /project/cells/cvsroot/cells-gtk3/cells-gtk/gl-drawing-area.lisp	2008/04/14 16:43:42	1.2
@@ -2,9 +2,112 @@
 
 (in-package :cgtk)
 
+(defvar *gl-config* nil)
+
 ;;;
 ;;; gl drawing area
 ;;; 
 
+;;;
+;;; OpenGL interaction
+;;;
+
+(defun get-gl-config ()
+  (let ((cfg (gdk-gl-config-new-by-mode '(:gdk-gl-mode-rgba :gdk-gl-mode-depth :gdk-gl-mode-double))))
+    (if (cffi-sys:null-pointer-p cfg)
+	(let ((cfg (gdk-gl-config-new-by-mode '(:gdk-gl-mode-rgba :gdk-gl-mode-depth :gdk-gl-mode-double))))
+	  (warn "No double buffered visual found.  Trying single-buffered.")
+	  (if (cffi-sys:null-pointer-p cfg)
+	      (error "No OpenGL capable visual found.")
+	      cfg))
+	cfg)))
+
+(defun gl-init ()
+  (gtk-gl-init +c-null+ +c-null+)
+  (setf *gl-config* (get-gl-config)))
+
+
+(defmacro with-gl-context ((widget &key (swap-buffers-p t)) &rest body)
+  (with-gensyms (drawable context swap-p w wid)
+    `(let ((,swap-p ,swap-buffers-p)
+	   (,w ,widget))
+       (let ((,wid (id ,w)))
+	 (let ((,context (gtk-widget-get-gl-context ,wid))
+	       (,drawable (gtk-widget-get-gl-window ,wid)))
+	   (if (gdk-gl-drawable-gl-begin ,drawable ,context)
+	       (progn
+		 , at body
+		 (when ,swap-p
+		   (when (gdk-gl-drawable-is-double-buffered ,drawable)
+		     (trc "swapping buffers")
+		     (gdk-gl-drawable-swap-buffers ,drawable)))
+		 (gdk-gl-drawable-gl-end ,drawable))
+	       (trc "gl-begin failed" ,w ,drawable ,context)))))))
+
+;;;
+;;; Event handling
+;;;
+
+(defun %gl-draw (self)
+  (bwhen (draw-fn (draw self))
+   (with-gl-context (self)
+     (funcall draw-fn self))))
+
+(cffi:defcallback realize-handler :void ((widget :pointer) (data :pointer))
+  (declare (ignore data))
+  (let ((self (gtk-object-find widget)))
+    (trc "gl realize" self widget (id self))
+    (bwhen (init-fn (init self))
+      (with-gl-context (self)
+	(funcall init-fn self)))
+    (trc "done gl realize" self)))
+
+
+(defun %resize (self)
+  (let ((width (allocated-width self))
+	(height (allocated-height self)))
+   (when (and (plusp width) (plusp height))
+     (trc "%resize to" width height)
+     (with-gl-context (self)
+       (gl:viewport 0 0 width height)
+       (bwhen (resize-fn (resize self))
+	 (funcall resize-fn self))))))
+
+;;;
+;;; Widget
+;;;
+
 (defmodel gl-drawing-area (drawing-area)
-  ())
\ No newline at end of file
+  ((draw :accessor draw :initarg :draw :cell nil :initform nil)
+   (init :accessor init :initarg :init :cell nil :initform nil)
+   (resize :accessor resize :initarg :resize :cell nil :initform nil))
+  (:default-initargs
+      :on-draw #'%gl-draw))
+
+(defmethod initialize-instance :after ((self gl-drawing-area) &rest initargs)
+  (declare (ignore initargs))
+  (trc "registering handlers for" self)
+  (gtk-signal-connect-swap (id self) "realize" (cffi:get-callback 'realize-handler) :data (id self))
+  (trc "set gl capability" self)
+  (gtk-widget-set-gl-capability (id self) *gl-config* +c-null+ t :gdk-gl-rgba-type))
+
+(defobserver allocated-width ((self gl-drawing-area))
+  (%resize self))
+
+(defobserver allocated-height ((self gl-drawing-area))
+  (%resize self))
+
+
+;;;
+;;; supporting macros
+;;;
+
+(export! with-matrix-mode)
+
+(defmacro with-matrix-mode ((mode) &body body)
+  `(progn
+     (gl:matrix-mode ,mode)
+     (gl:load-identity)
+     , at body
+     (gl:matrix-mode :modelview)
+     (gl:load-identity)))
--- /project/cells/cvsroot/cells-gtk3/cells-gtk/gtk-app.lisp	2008/04/13 11:34:24	1.2
+++ /project/cells/cvsroot/cells-gtk3/cells-gtk/gtk-app.lisp	2008/04/14 16:43:42	1.3
@@ -127,28 +127,6 @@
   (with-trc (gtk-quit-remove (slot-value self 'cb-quit-id))))
 
 ;;;
-;;; callback table
-;;; 
-
-(defvar *gtk-global-callbacks* nil)
-
-(defun gtk-reset ()
-  (cells-reset)
-  (gtk-objects-init)
-  (setf *gtk-global-callbacks*
-	(make-array 128 :adjustable t :fill-pointer 0)))
-
-(defun gtk-global-callback-register (callback)
-  (vector-push-extend callback *gtk-global-callbacks* 16))
-
-(defun gtk-global-callback-funcall (n)
-  (trc nil "gtk-global-callback-funcall >" n
-    *gtk-global-callbacks*
-    (when n (aref *gtk-global-callbacks* n)))
-  (funcall (aref *gtk-global-callbacks* n)))
-
-
-;;;
 ;;; Helper functions convering the life cycle of an application
 ;;; 
 
@@ -184,6 +162,7 @@
 	    (gdk-threads-init)
 	    (assert (gtk-init-check +c-null+ +c-null+))
 	    (gtk-init +c-null+ +c-null+)
+	    #+cells-gtk-opengl (gl-init)
 	    (gtk-reset)
 	    #-libcellsgtk (setf threading-initialized t)))))
 
@@ -349,6 +328,5 @@
      ('no (error "Cannot mix start-win and start-app in one lisp session.  Use start-app or restart lisp"))
      (t (setf *using-thread* 'yes)))
    (start-gtk-main)
-   (apply #'show-win app-class initargs)
-   0))
+   (apply #'show-win app-class initargs)))
 
--- /project/cells/cvsroot/cells-gtk3/cells-gtk/packages.lisp	2008/04/13 10:59:17	1.1
+++ /project/cells/cvsroot/cells-gtk3/cells-gtk/packages.lisp	2008/04/14 16:43:42	1.2
@@ -44,11 +44,15 @@
 	     #:cells-tree-node
 	     #:cells-tree-store
 	     #:cells-gtk-init
+
 	     #:title
 	     #:icon
 	     #:tooltips
 	     #:tooltips-enable
 	     #:tooltips-delay
+	     #:allocated-width
+	     #:allocated-height
+	     
 	     #:start-app
 	     #:start-win
 	     #:stop-gtk-main
@@ -142,4 +146,9 @@
 	     #:on-dragged ; (on-dragged [widget] [button] [primitive] [start-pos] [end-pos])
 	     #:hover	  ; the primitive the mouse is currently over
 	     #:dragging	  ; the primitive currently being dragged
+
+	     #:gl-drawing-area
+	     #:with-gl-context
+	     #:init
+	     #:draw
 	     ))
--- /project/cells/cvsroot/cells-gtk3/cells-gtk/widgets.lisp	2008/04/13 10:59:17	1.1
+++ /project/cells/cvsroot/cells-gtk3/cells-gtk/widgets.lisp	2008/04/14 16:43:44	1.2
@@ -24,9 +24,9 @@
    (def-gtk-class-name :accessor def-gtk-class-name :initarg :def-gtk-class-name :initform nil)
    (new-function-name :accessor new-function-name :initarg :new-function-name 
 		      :initform (c_1 (intern (format nil "GTK-~a-NEW~a"
-						    (def-gtk-class-name self)
-						    (or (new-tail self) ""))
-					    :gtk-ffi)))
+						     (def-gtk-class-name self)
+						     (or (new-tail self) ""))
+					     :gtk-ffi)))
    (new-args :accessor new-args :initarg :new-args :initform nil)
    (new-tail :accessor new-tail :initarg :new-tail :initform nil)
    (id :initarg :id :accessor id 
@@ -36,6 +36,7 @@
 		       (let ((id (apply (symbol-function (new-function-name self))
 					(new-args self))))
 			 (gtk-object-store id self)
+			 (gtk-signal-connect-swap id "configure-event" (cffi:get-callback 'reshape-widget-handler) :data id)
 			 id))))
    
    (callbacks :cell nil :accessor callbacks
@@ -47,14 +48,19 @@
 
 ;; --------- provide id-to-clos lookup ------
 
-(defvar *gtk-objects* nil)
+;;;
+;;; gtk object registry
+;;; 
 
+(defvar *gtk-objects* nil)
 (defvar *widgets* nil)
 
 (defun gtk-objects-init ()
   (setf *gtk-objects* (make-hash-table :size 100 :rehash-size 100)
 	*widgets* (make-hash-table :test #'equal)))
 
+;;; id lookup
+
 (defun gtk-object-store (gtk-id gtk-object &aux (hash-id (cffi:pointer-address gtk-id)))
   (unless *gtk-objects*
     (gtk-objects-init))
@@ -88,10 +94,11 @@
         (gtk-report-error gtk-object-id-error "gtk.object.find ID not found ~a" hash-id))         
       clos-widget)))
 
+;;; name lookup
+
 (defun find-widget (name &optional default)
   (gethash name *widgets* default))
 
-
 (defmacro with-widget ((widget name &optional alternative) &body body)
   `(bif (,widget (find-widget ,name))
 	(progn , at body)
@@ -104,12 +111,13 @@
 	   (progn , at body)
 	   ,alternative))))
 
-(defun widget-value (name default &key (accessor 'value))
+(defun widget-value (name &optional default (accessor 'value))
   (with-widget-value (val name :accessor accessor :alternative default)
     val))
 
-
-
+;;;
+;;; callbacks
+;;;
 
 ;; ----- fake callbackable closures ------------
 
@@ -121,8 +129,6 @@
 (defun callback-recover (self callback-key)
   (cdr (assoc callback-key (callbacks self))))
 
-; ------------------------------------------
-
 ;;;
 ;;; callback table
 ;;; 
@@ -145,7 +151,6 @@
   (funcall (aref *gtk-global-callbacks* n)))
 
 
-
 (defmethod configure ((self gtk-object) gtk-function value)
   (apply gtk-function
     (id self)
@@ -321,15 +326,36 @@
    (x-pad :accessor x-pad :initarg :x-pad :initform (c? (padding? self)))
    (y-pad :accessor y-pad :initarg :y-pad :initform (c? (padding? self)))
    (width :accessor width :initarg :width :initform nil)
-   (height :accessor height :initarg :height :initform nil))
+   (height :accessor height :initarg :height :initform nil)
+   (allocated-width :accessor allocated-width :initform (c-in 0))
+   (allocated-height :accessor allocated-height :initform (c-in 0))
+   )
   ()
   (focus show hide delete-event destroy-event)
   ;; this is called unless the user overwrites this routine
   :on-delete-event (c-in #'(lambda (self widget event data)
 			     (declare (ignore widget event data))
+			     (trc "on-delete")
 			     (gtk-object-forget (id self) self)
 			     0)))
 
+#+libcellsgtk
+(cffi:defcallback reshape-widget-handler :int ((widget :pointer) (event :pointer) (data :pointer))
+  (declare (ignore data event))
+  (bwhen (self (gtk-object-find widget))
+    (let ((new-width (gtk-adds-widget-width widget))
+	  (new-height (gtk-adds-widget-height widget)))
+      (trc "reshape widget to new size" self widget new-width new-height)
+      (with-integrity (:change :adjust-widget-size)
+	(setf (allocated-width self) new-width
+	      (allocated-height self) new-height))))
+  0)
+
+(defmethod initialize-instance :after ((self widget) &rest initargs)
+  (declare (ignore initargs))
+  #+libcellsgtk-
+  )
+
 (defmethod focus ((self widget))
   (gtk-widget-grab-focus (id self)))
 




More information about the Cells-cvs mailing list