X-Git-Url: https://git.distorted.org.uk/~mdw/clg/blobdiff_plain/3a64da99b33794112a373a89060d6a0018e46901..e99a089d8043b561235529dbc613fac386bd9bf4:/gdk/gdk.lisp diff --git a/gdk/gdk.lisp b/gdk/gdk.lisp index cf5ea87..18ef429 100644 --- a/gdk/gdk.lisp +++ b/gdk/gdk.lisp @@ -20,7 +20,7 @@ ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -;; $Id: gdk.lisp,v 1.31 2006-07-06 13:05:59 espen Exp $ +;; $Id: gdk.lisp,v 1.39 2007-06-18 12:23:05 espen Exp $ (in-package "GDK") @@ -36,11 +36,21 @@ ;;; Display +#-debug-ref-counting +(defmethod print-object ((display display) stream) + (if (and (proxy-valid-p display) (slot-boundp display 'name)) + (print-unreadable-object (display stream :type t :identity nil) + (format stream "~S at 0x~X" + (display-name display) (pointer-address (foreign-location display)))) + (call-next-method))) + (defbinding %display-open () display (display-name (or null string))) (defun display-open (&optional display-name) - (let ((display (%display-open display-name))) + (let ((display (or + (%display-open display-name) + (error "Opening display failed: ~A" display-name)))) (unless (display-get-default) (display-set-default display)) display)) @@ -73,6 +83,8 @@ (defbinding display-close (&optional (display (display-get-default))) nil (display display)) +(defbinding flush () nil) + (defbinding display-get-event (&optional (display (display-get-default))) event (display display)) @@ -90,19 +102,39 @@ (&optional (display (display-get-default))) int (display display)) +(defun find-display (name) + (if (not name) + (display-get-default) + (find name (list-displays) :key #'display-name :test #'string=))) + +(defun ensure-display (display) + (etypecase display + (null (display-get-default)) + (display display) + (string (or (find-display display) (display-open display))))) ;;; Display manager (defbinding display-get-default () display) -(defbinding (display-manager "gdk_display_manager_get") () display-manager) - (defbinding (display-set-default "gdk_display_manager_set_default_display") (display) nil ((display-manager) display-manager) (display display)) +(defbinding (list-displays "gdk_display_manager_list_displays") () + (gslist (static display)) + ((display-manager) display-manager)) + +;; The only purpose of exporting this is to make it possible for +;; applications to connect to the display-opened signal +(defbinding (display-manager "gdk_display_manager_get") () display-manager) + +(defbinding display-get-core-pointer + (&optional (display (display-get-default))) device + (display display)) + ;;; Primitive graphics structures (points, rectangles and regions) @@ -147,7 +179,6 @@ (location pointer)) (defmethod allocate-foreign ((region region) &key rectangle polygon fill-rule) - (declare (ignore initargs)) (cond ((and rectangle polygon) (error "Only one of the keyword arguments :RECTANGLE and :POLYGON can be specified")) @@ -159,7 +190,9 @@ (etypecase region (region region) ((or rectangle vector) - (make-instance 'region :rectangle (ensure-rectangle region))))) + (make-instance 'region :rectangle (ensure-rectangle region))) + (list + (make-instance 'region :polygon region)))) (defbinding region-get-clipbox (region &optional (rectangle (make-instance 'rectangle))) nil (region region) @@ -174,7 +207,7 @@ "Obtains the area covered by the region as a list of rectangles." (multiple-value-bind (location length) (%region-get-rectangles region) (prog1 - (map-c-vector 'list #'identity location 'point length :get) + (map-c-vector 'list #'identity location '(inlined rectangle) length :get) (deallocate-memory location)))) (defbinding region-empty-p () boolean @@ -204,19 +237,19 @@ (dy int)) (defbinding region-intersect (source1 source2) nil - (source1 region) + ((ensure-region source1) region :in/return) ((ensure-region source2) region)) (defbinding region-union (source1 source2) nil - (source1 region) + ((ensure-region source1) region :in/return) ((ensure-region source2) region)) (defbinding region-subtract (source1 source2) nil - (source1 region) + ((ensure-region source1) region :in/return) ((ensure-region source2) region)) (defbinding region-xor (source1 source2) nil - (source1 region) + ((ensure-region source1) region :in/return) ((ensure-region source2) region)) @@ -244,11 +277,18 @@ ;;; Miscellaneous functions -(defbinding screen-width () int) -(defbinding screen-height () int) +(defbinding screen-width () int + (screen screen)) + +(defbinding screen-height () int + (screen screen)) + +(defbinding screen-width-mm () int + (screen screen)) + +(defbinding screen-height-mm () int + (screen screen)) -(defbinding screen-width-mm () int) -(defbinding screen-height-mm () int) (defbinding pointer-grab (window &key owner-events events confine-to cursor time) grab-status @@ -405,6 +445,13 @@ (dx int) (dy int)) +#?(pkg-exists-p "gtk+-2.0" :atleast-version "2.8.0") +(defbinding window-move-region (window region dx dy) nil + (window window) + ((ensure-region region) region) + (dx int) + (dy int)) + (defbinding window-reparent () nil (window window) (new-parent window) @@ -539,9 +586,9 @@ (defun window-shape-combine (window shape offset-x offset-y) (etypecase shape - (nil (%window-shape-combine-region window nil 0 0) + (null (%window-shape-combine-region window nil 0 0)) (region (%window-shape-combine-region window shape offset-x offset-y)) - (bitmask (window-shape-combine-mask window shape offset-x offset-y))))) + (bitmap (window-shape-combine-mask window shape offset-x offset-y)))) (defbinding window-set-child-shapes () nil (window window)) @@ -565,9 +612,9 @@ (defun window-input-shape-combine (window shape x y) (etypecase shape - (nil (%window-input-shape-combine-region window nil 0 0) - (region (%window-input-shape-combine-region window shape x y)) - (bitmask (%window-input-shape-combine-mask window shape x y))))) + (null (%window-input-shape-combine-region window nil 0 0)) + (region (%window-input-shape-combine-region window shape x y)) + (bitmap (%window-input-shape-combine-mask window shape x y)))) (defbinding window-set-child-input-shapes () nil (window window)) @@ -606,7 +653,7 @@ ;(defbinding window-set-geometry-hints () nil -(defbinding window-icon-list () nil +(defbinding window-set-icon-list () nil (window window) (icons (glist pixbufs))) @@ -1010,28 +1057,35 @@ ;; (defbinding cairo-region () nil ;; (cr cairo:context) ;; (region region)) + + (defbinding (cairo-surface-get-window "clg_gdk_cairo_surface_get_window") () window + (surface cairo:surface)) ) ;;; Multi-threading support -#+sbcl +#+sb-thread (progn (defvar *global-lock* (sb-thread:make-mutex :name "global GDK lock")) - (let ((recursive-level 0)) - (defun threads-enter () - (if (eq (sb-thread:mutex-value *global-lock*) sb-thread:*current-thread*) - (incf recursive-level) - (sb-thread:get-mutex *global-lock*))) - - (defun threads-leave (&optional flush-p) - (cond - ((zerop recursive-level) - (when flush-p - (display-flush)) - (sb-thread:release-mutex *global-lock*)) - (t (decf recursive-level))))) + + (defun %global-lock-p () + (eq (car (sb-thread:mutex-value *global-lock*)) sb-thread:*current-thread*)) + + (defun threads-enter () + (if (%global-lock-p) + (incf (cdr (sb-thread:mutex-value *global-lock*))) + (sb-thread:get-mutex *global-lock* (cons sb-thread:*current-thread* 0)))) + + (defun threads-leave (&optional flush-p) + (assert (%global-lock-p)) + (cond + ((zerop (cdr (sb-thread:mutex-value *global-lock*))) + (when flush-p + (flush)) + (sb-thread:release-mutex *global-lock*)) + (t (decf (cdr (sb-thread:mutex-value *global-lock*)))))) (define-callback %enter-fn nil () (threads-enter)) @@ -1047,5 +1101,31 @@ `(progn (threads-enter) (unwind-protect - ,@body - (threads-leave t))))) + (progn ,@body) + (threads-leave t)))) + + (defun timeout-add-with-lock (interval function &optional (priority +priority-default+)) + (timeout-add interval + #'(lambda () + (with-global-lock (funcall function))) + priority)) + + (defun idle-add-with-lock (funcation &optional (priority +priority-default-idle+)) + (idle-add + #'(lambda () + (with-global-lock (funcall function))) + priority))) + + +#-sb-thread +(progn + (defmacro with-global-lock (&body body) + `(progn ,@body)) + + (defun timeout-add-with-lock (interval function &optional (priority +priority-default+)) + (timeout-add interval function priority)) + + (defun idle-add-with-lock (funcation &optional (priority +priority-default-idle+)) + (idle-add function priority))) + +