;; License along with this library; if not, write to the Free Software
;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-;; $Id: gboxed.lisp,v 1.2 2001-04-30 11:25:25 espen Exp $
+;; $Id: gboxed.lisp,v 1.13 2004-11-09 10:10:59 espen Exp $
(in-package "GLIB")
(eval-when (:compile-toplevel :load-toplevel :execute)
- (defclass boxed (proxy)
- ()
- (:metaclass proxy-class)))
-
-(defmethod initialize-proxy ((boxed boxed) &rest initargs
- &key location weak-ref)
- (declare (ignore initargs))
- (setf
- (slot-value boxed 'location)
- (if weak-ref
- (%boxed-copy (find-type-number (class-of boxed)) location)
- location))
- (call-next-method))
-
-(defmethod instance-finalizer ((boxed boxed))
- (let ((location (proxy-location boxed))
- (type-number (find-type-number (class-of boxed))))
- (declare (type system-area-pointer location))
+ (init-types-in-library #.(concatenate 'string
+ (pkg-config:pkg-variable "glib-2.0" "libdir")
+ "/libgobject-2.0.so")))
+
+(defclass boxed (struct)
+ ()
+ (:metaclass struct-class))
+
+(defmethod instance-finalizer ((instance boxed))
+ (let ((location (proxy-location instance))
+ (type-number (type-number-of instance)))
#'(lambda ()
- (%boxed-free type-number location)
- (remove-cached-instance location))))
+ (remove-cached-instance location)
+ (%boxed-free type-number location))))
-(deftype-method translate-to-alien boxed (type-spec boxed &optional weak-ref)
- (if weak-ref
- `(proxy-location ,boxed)
- `(let ((boxed ,boxed))
- (%boxed-copy
- (find-type-number type-spec)
- (proxy-location boxed)))))
+;;;; Metaclass for boxed classes
-(deftype-method unreference-alien boxed (type-spec c-struct)
- `(%boxed-free ,(find-type-number type-spec) ,c-struct))
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (defclass boxed-class (struct-class)
+ ())
+
+ (defmethod validate-superclass ((class boxed-class) (super standard-class))
+ (subtypep (class-name super) 'boxed)))
+
+
+(defmethod shared-initialize ((class boxed-class) names
+ &rest initargs &key name alien-name)
+ (declare (ignore initargs names))
+ (call-next-method)
+
+ (let* ((class-name (or name (class-name class)))
+ (type-number
+ (find-type-number
+ (or (first alien-name) (default-alien-type-name class-name)))))
+ (register-type class-name type-number)))
(defbinding %boxed-copy () pointer
- (type type-number)
+ (type-number type-number)
(location pointer))
(defbinding %boxed-free () nil
- (type type-number)
+ (type-number type-number)
(location pointer))
+(defmethod reference-foreign ((class boxed-class) location)
+ (%boxed-copy (find-type-number class) location))
-;;;; Metaclass for boxed classes
+(defmethod unreference-foreign ((class boxed-class) location)
+ (%boxed-free (find-type-number class) location))
-(eval-when (:compile-toplevel :load-toplevel :execute)
- (defclass boxed-class (proxy-class)))
+;;;;
-(defmethod shared-initialize ((class boxed-class) names
- &rest initargs
- &key name alien-name type-init)
- (declare (ignore initargs names))
- (call-next-method)
+(defun expand-boxed-type (type-number &optional slots)
+ `(defclass ,(type-from-number type-number) (boxed)
+ ,slots
+ (:metaclass boxed-class)
+ (:alien-name ,(find-type-name type-number))))
+
+(register-derivable-type 'boxed "GBoxed" 'expand-boxed-type)
+
+;;;; Special boxed types
+
+;; (defclass gstring (boxed)
+;; ()
+;; (:metaclass boxed-class)
+;; (:alien-name "GString"))
+
+;; (deftype-method translate-from-alien
+;; gstring (type-spec location &optional weak-ref)
+;; `(let ((location ,location))
+;; (unless (null-pointer-p location)
+;; (prog1
+;; (c-call::%naturalize-c-string location)
+;; ,(unless weak-ref
+;; (unreference-alien type-spec location))))))
+
+;; (deftype-method translate-to-alien
+;; gstring (type-spec string &optional weak-ref)
+;; (declare (ignore weak-ref))
+;; `(let ((string ,string))
+;; ;; Always copy strings to prevent seg fault due to GC
+;; (funcall
+;; ',(proxy-class-copy (find-class type-spec))
+;; ',type-spec
+;; (make-pointer (1+ (kernel:get-lisp-obj-address string))))))
+
+;; (deftype-method cleanup-alien gstring (type-spec c-string &optional weak-ref)
+;; (when weak-ref
+;; (unreference-alien type-spec c-string)))
- (let* ((class-name (or name (class-name class)))
- (type-number
- (cond
- ((and alien-name type-init)
- (error
- "Specify either :type-init or :alien-name for class ~A"
- class-name))
- (alien-name (type-number-from-alien-name (first alien-name)))
- (type-init (funcall (mkbinding (first type-init) 'type-number)))
- (t
- (or
- (type-number-from-alien-name
- (default-alien-type-name class-name) nil)
- (funcall
- (mkbinding
- (default-alien-fname (format nil "~A_get_type" class-name))
- 'type-number)))))))
- (setf (find-type-number class) type-number)))
-
-
-(defmethod validate-superclass
- ((class boxed-class) (super pcl::standard-class))
- (subtypep (class-name super) 'boxed))
-
-
-;;;; Initializing type numbers
-
-(setf (alien-type-name 'boxed) "GBoxed")