- (:alien-name "GObject")))
-
-(defmethod initialize-instance ((object gobject) &rest initargs)
- ;; Extract initargs which we should pass directly to the GObeject
- ;; constructor
- (let* ((slotds (class-slots (class-of object)))
- (args (when initargs
- (loop
- as (key value . rest) = initargs then rest
- as slotd = (find-if
- #'(lambda (slotd)
- (member key (slot-definition-initargs slotd)))
- slotds)
- when (and (typep slotd 'effective-property-slot-definition)
- (slot-value slotd 'construct))
- collect (progn
- (remf initargs key)
- (list
- (slot-definition-pname slotd)
- (slot-definition-type slotd)
- value))
- while rest))))
- (if args
- (let* ((string-size (size-of 'string))
- (string-writer (writer-function 'string))
- (string-destroy (destroy-function 'string))
- (params (allocate-memory
- (* (length args) (+ string-size +gvalue-size+)))))
- (loop
- for (pname type value) in args
- as tmp = params then (sap+ tmp (+ string-size +gvalue-size+))
- do (funcall string-writer pname tmp)
- (gvalue-init (sap+ tmp string-size) type value))
+ (:gtype "GObject")))
+
+#+debug-ref-counting
+(defmethod print-object ((instance gobject) stream)
+ (print-unreadable-object (instance stream :type t :identity nil)
+ (if (proxy-valid-p instance)
+ (format stream "at 0x~X (~D)" (pointer-address (foreign-location instance)) (ref-count instance))
+ (write-string "at \"unbound\"" stream))))
+
+
+(define-type-method reader-function ((type gobject) &key (ref :read) inlined)
+ (assert-not-inlined type inlined)
+ (ecase ref
+ ((:read :peek) (call-next-method type :ref :read))
+ (:get
+ #'(lambda (location &optional (offset 0))
+ (let ((instance (ref-pointer location offset)))
+ (unless (null-pointer-p instance)
+ (multiple-value-bind (gobject new-p)
+ (ensure-proxy-instance 'gobject instance :reference nil)
+ (unless new-p
+ (%object-unref instance))
+ (setf (ref-pointer location offset) (make-pointer 0))
+ gobject)))))))
+
+(define-type-method callback-wrapper ((type gobject) var arg form)
+ (let ((class (type-expand type)))
+ `(let ((,var (ensure-proxy-instance ',class ,arg)))
+ ,form)))
+
+(defun initial-add (object function initargs key pkey)
+ (loop
+ as (initarg value . rest) = initargs then rest
+ do (cond
+ ((eq initarg key) (funcall function object value))
+ ((eq initarg pkey) (mapc #'(lambda (value)
+ (funcall function object value))
+ value)))
+ while rest))
+
+(defun initial-apply-add (object function initargs key pkey)
+ (initial-add object #'(lambda (object value)
+ (apply function object (mklist value)))
+ initargs key pkey))
+
+
+(defmethod make-proxy-instance ((class gobject-class) location &rest initargs)
+ (declare (ignore location initargs))
+ (if (slot-value class 'instance-slots-p)
+ (error "Objects of class ~A has instance slots and should only be created with MAKE-INSTANCE" class)
+ (call-next-method)))
+
+
+(defmethod allocate-foreign ((object gobject) &rest initargs)
+ (let ((init-slots ()))
+ (flet ((value-from-initargs (slotd)
+ (loop
+ with slot-initargs = (slot-definition-initargs slotd)
+ for (initarg value) on initargs by #'cddr
+ when (find initarg slot-initargs)
+ do (return (values value t)))))
+
+ (loop
+ for slotd in (class-slots (class-of object))
+ when (and
+ (eq (slot-definition-allocation slotd) :property)
+ (construct-only-property-p slotd))
+ do (multiple-value-bind (value initarg-p) (value-from-initargs slotd)
+ (cond
+ (initarg-p (push (cons slotd value) init-slots))
+ ((slot-definition-initfunction slotd)
+ (push
+ (cons slotd (funcall (slot-definition-initfunction slotd)))
+ init-slots))))))
+
+ (cond
+ (init-slots
+ (let* ((pointer-size (size-of 'pointer))
+ (element-size (+ +gvalue-size+ pointer-size))
+ (num-slots (length init-slots)))
+ (with-memory (params (* num-slots element-size))
+ (loop
+ with string-writer = (writer-function 'string)
+ for (slotd . value) in init-slots
+ as param = params then (pointer+ param element-size)
+ as type = (slot-definition-type slotd)
+ as pname = (slot-definition-pname slotd)
+ do (funcall string-writer pname param)
+ (gvalue-init (pointer+ param pointer-size) type value))
+