[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: New cursor

>Hi, MCL experts:
>How to make a new cursor that has the same properties as the cursor
>*arrow-cursor*?  I used the following way to create it, set it to
>some shape and move it on the different background:
>(a). (setf *my-cursor* (make-record :cursor))
>(b). (dotimes (i 17)
>             (%put-word *my-cursor* 0 (* i 2)))
>     (%put-word *my-cursor* 0 64)
>     (%put-word *my-cursor* 0 66)
>(c). (defmethod window-update-cursor ((toy my-window) point) 
>               (set-cursor *my-cursor*))
>However, I got some interesting situations on the different background.
>While the new cursor is on the white background, I can't see the shape
>of the cursor; while it is on the black and gray background, I can see
>some garbage points in the 16x16 square (suppose I should see a white
>square without any other points).  I am wondering whether I have missed
>something or there are other ways to create a new cursor.  Thanks.

There are a couple of problems with your code.


(make-record :cursor) macroexpands into (#_NewHandle 64)

You really want a pointer here, not a handle, so you need to say
(make-record (:cursor :storage :pointer)).


Since *my-cursor* was a handle, you're setting bits in master
pointers near that handle. I.e. you're clobberring the master
pointers for some other handles. When I did this, it caused my
MCL to crash right away. You must have gotten lucky and trashed
a handle that wasn't used right away.

Also, even had *my-cursor* been a pointer rather than a handle,
you only initialized the first 34 bytes and the last 4, leaving
the mask completely uninitialized.

This is fine except you forgot to (declare (ignore where))

The usual way to define a cursor is to use a resource editing tool,
e.g. ResEdit to create it, then use the resource manager to load the
cursor resource into MCL. If you really want to do it yourself, here's
some code:


; make-cursor.lisp

; Data & mask are 16-element sequences of
; 16 bit numbers, each defining a 16x16 bit array.
; hotspot is a point.
(defun make-cursor (data mask hotspot)
  (let ((cursor (make-record (:cursor :storage :pointer)))
        (data-start (get-field-offset :cursor.data))
        (mask-start (get-field-offset :cursor.mask))
        (offset 0))
    (dotimes (i 16)
      (setf (%get-word cursor (+ data-start offset)) (elt data i)
            (%get-word cursor (+ mask-start offset)) (elt mask i))
      (incf offset 2))
    (setf (pref cursor :cursor.hotspot) hotspot)

(defparameter *my-cursor*
  (make-cursor #(#b0100000000000000
               #@(1 0)))

(defclass my-window (window) ())

(defmethod view-cursor ((w my-window) where)
  (declare (ignore where))

(defparameter *w* (make-instance 'my-window))