# Mouse subsystem

The mouse subsystem periodically polls a mouse driver for movement and clicks
and maintains its position in a two dimensional environment.

To be able to properly follow updates from the device, this subsystem has to
be called upon regularly, which you'll probably want to do in the Loop
[lib/idle].

The mouse subsystem defines a "mouse" structure as well as a global "mouse"
value [lib/bm] holding the active mouse.  During initialization, what you'll
want to do is create a mouse struct from the driver and set the "mouse" value to
it.

## Driver implementation

To implement the mouse, we need an underlying driver to extend it and implement
its methods, namely:

mouse@ ( mouse -- dx dy btnflags )
  Return the number of "units" (device dependant) by which the mouse moved since
  we last called this method. "dx" is negative when going left. "dy" is negative
  when going up. "btnflags" is a bitmask of the buttons that are currently
  pushed. b0=left b1=right b2=middle.

mouseabs@  ( mouse -- 0 ) or ( mouse -- x xbounds y ybounds )
  Most implementations can just return 0. In case the mouse is an absolute
  pointer device (touch screen or tablet), the implementation can return the
  current absolute position and the bounds of the absolute device. For example,
  when x = xbound / 2 and y = ybound / 2, the cursor will be moved to the middle
  of the screen.

## API

### Structures

struct Mouse
  fields rawx rawy xmax ymax divisor buttons
  method update ( mouse -- )

rawx    Current X pos before divisor is applied
rawy    Current Y pos before divisor is applied
xmax    Max rawx value
ymax    Max rawy value
divisor A divisor to apply to movement to make it go slower
buttons Bitmask of buttons that are currently pressed

update ( mouse -- )
  Poll the mouse and update the structure accordingly.

### Constants

BTN_LEFT   $01
BTN_RIGHT  $02
BTN_MIDDLE $04

### Values

mouse
  Points to the main mouse of the system. By default, points to a dummy mouse
  with a noop update.

## Words

x ( mouse -- n )
  X with divisor applied

y ( mouse -- n )
  Y with divisor applied

moveto ( rawx rawy mouse -- )
  Set rawx and rawy to mouse fields of the same name, ensuring that the field
  doesn't go negative or exceeds its maximum value.

moveby ( rawx rawy mouse -- )
  Add rawx and rawy to mouse fields of the same name, ensuring that the field
  doesn't go negative or exceeds its maximum value.

configuremouse ( screenwidth screenheight divisor mouse -- )
  Configure mouse with specified parameters. Screen width and height end up,
  with 1 subtracted, in xmax and ymax.
