3.4 Obtaining mouse information

3.4.1 Polling the mouse

The most basic way to access the mouse is polling the mouse. Polling allows you to examine the current location of the mouse and the state of the mouse buttons at any moment. The functions mouse-x, mouse-y, and mouse-buttons allow you to poll the mouse.

This function returns the current x-coordinate of the mouse in terms of the root viewport.

This function returns the current y-coordinate of the mouse in terms of the root viewport.

This function returns the current state of the mouse buttons. The value of the variable is a three-bit number (a number in the range 0 to 7). If the right mouse button is down, the low-order bit is 1. If the middle button is down, the middle bit is 1. If the left button is down, the high-order bit is 1. This information is summarized in Table 3.1.

Interpretation of mouse buttons
0000No button is depressed
1001Right button is depressed
2010Middle button is depressed
3011Middle and right buttons are depressed
4100Left button is depressed
5101Left and right buttons are depressed
6110Left and middle buttons are depressed
7111Left, middle, and right buttons are depressed

A mouse that has two buttons is considered to have a left and a right button only, so the middle bit is always 0.

The two examples that follow show how to use the mouse and polling to draw on the screen.

Begin by creating a window to contain the drawing:

(setq *window* (make-window :inside-width 100 :inside-height 100
                            :title "Poll Window"))

Define a function that draws circles in a window when the left button is down. The function will exit when the left button is released. Since the functionsmouse-x andmouse-y return bit locations that are relative to the root viewport and not to the window, the function has to adjust these values accordingly:

(defun draw-some-circles (window)
  (format t "Hold down the left button to draw circles~%")
  ;; Wait until left button down.
  (loop until (eq (mouse-buttons) 4))      
  ;; Draw while left button down.  
  (loop while (eq (mouse-buttons) 4)       
        do (draw-circle window
               (- (mouse-x) (region-origin-x
                              (window-inside-region window)))
               (- (mouse-y) (region-origin-y
                              (window-inside-region window))))
             10)))                 ; Diameter of circle is 10.

;; Invoke the function. (draw-some-circles *window*)

The next example shows how to use polling to draw connected lines on the screen. Every time you click left in the window, a line is drawn from the previous click, or from position (0,0) if there is no previous click.

(defun draw-connected-lines (window)
  (format t "Click the left button to draw a line, middle button to exit~%")
    with previous-position = (make-position 0 0)
    with current-position
    until (eq (mouse-buttons) 2)        ; Exit on middle click.
    if (eq (mouse-buttons) 4)        ; Draw line on left click.
    do (setq
           (- (mouse-x)
              (region-origin-x (window-inside-region window)))
           (- (mouse-y)
              (region-origin-y (window-inside-region window)))))
    and do (draw-line window previous-position current-position)
    and do (setq previous-position current-position)))

;; Invoke the function. (draw-connected-lines *window*)

These examples demonstrate certain limitations imposed by polling the mouse to obtain mouse data. Polling returns the location or state of the mouse only when the polling functions are invoked. You cannot determine what the mouse was doing a moment ago, nor can you wait for a specific event to occur except by checking constantly to see if the current event is the one you want. If events occur more quickly than your function invokes the polling functions, only the current state of the mouse is returned, and you might miss changes in this state. The other two methods of obtaining mouse information do not have these limitations.

The Window Tool Kit - 9 SEP 1996

Generated with Harlequin WebMaker