a2d/MGTK.md

954 lines
19 KiB
Markdown
Raw Normal View History

2018-03-01 03:03:07 +00:00
# MouseGraphics ToolKit
2017-09-22 16:00:30 +00:00
2018-02-19 19:33:13 +00:00
This is a complex API library written by Apple circa 1985. It consists of:
2017-09-22 16:00:30 +00:00
2018-03-01 03:01:34 +00:00
* [Graphics Primitives](#graphics-primitives) - screen management, lines, rects, polys, text, patterns, pens
* [Concepts](#concepts)
* [Commands](#commands)
* [Mouse Graphics](#mouse-graphics) - windows, menus, events, cursors
* [Concepts](#concepts-1)
* [Commands](#commands-1)
* [More](#more)
2017-09-22 16:00:30 +00:00
2018-03-01 04:54:18 +00:00
For the purposes of DeskTop, the entry point is fixed at $4000 AUX, called MLI-style:
```
JSR $4000
.byte call
.addr params
```
Result will be in A, with Z bit set, 0 indicating success (so `BNE error` works).
2017-09-22 16:00:30 +00:00
2018-03-01 03:02:17 +00:00
ca65 syntax is used for primitives: `.byte`, `.word` (interpreted as 16-bit signed integer), `.addr` (16-bit address), `.res N` (N byte buffer)
2018-02-19 21:29:57 +00:00
---
2017-09-22 16:00:30 +00:00
2018-02-19 21:29:57 +00:00
# Graphics Primitives
2017-09-22 16:00:30 +00:00
2018-02-19 21:29:57 +00:00
## Concepts
2017-09-22 16:00:30 +00:00
2018-02-19 21:29:57 +00:00
### Point
2017-09-22 16:00:30 +00:00
```
2018-02-19 21:29:57 +00:00
.word xcoord
.word ycoord
2017-09-22 16:00:30 +00:00
```
2018-02-19 21:29:57 +00:00
### Rect
```
.word x1
.word y1
.word x2
2018-03-01 03:03:37 +00:00
.word y2
2018-02-19 21:29:57 +00:00
```
2017-09-22 16:00:30 +00:00
2018-02-19 21:29:57 +00:00
### Pattern
2018-03-01 04:44:25 +00:00
A simple repeating 8x8 pattern is defined by 8 bytes. All bits of each byte are used.
```
.byte row0
.byte row1
.byte row2
.byte row3
.byte row4
.byte row5
.byte row6
.byte row7
```
2017-09-22 16:00:30 +00:00
2018-02-19 21:29:57 +00:00
### MapInfo
Used with GrafPorts to define offsets/clipping, and bitmaps for source data.
```
Point viewloc
.addr mapbits $2000 for the screen, or bitmap bits
.byte mapwidth $80, or stride for bitmap
.byte reserved
Rect maprect a.k.a. cliprect
```
### GrafPort
There is always a current GrafPort (or "port" for short) that defines
the destination and pen state of drawing operations.
```
MapInfo portmap
2018-03-01 02:39:58 +00:00
Pattern penpattern
2018-02-19 21:29:57 +00:00
.byte colormask_and
.byte colormask_or
Point penloc
.byte penwidth horizontal pen thickness
.byte penheight vertical pen thickness
.byte penmode
.byte textback text background
.addr textfont
```
### PolyList
```
.byte count number of vertices in this polygon
.byte last high bit set if there are more polygons
Point vertex0
... repeats for each vertex
... repeats for each polygon
```
### Font
```
.byte fonttype 0=regular, $80=double-width
.byte lastchar char code of last character (usually $7F)
.byte height pixels (1-16)
.res N charwidth pixels, for each char
.res N row0 bits
.res N row0right bits (double-width only)
... repeats for each row
```
## Commands
2018-03-01 02:39:58 +00:00
#### NoOp ($00)
No-op
No parameters.
### Initialization
#### InitGraf ($01)
No parameters.
#### SetSwitches ($02)
Configure display switches
Parameters:
```
.byte flags bit 0=hires, 1=page2, 2=mixed, 3=text
```
### GrafPort - assign, update, query ports
#### InitPort ($03)
Initialize GrafPort to standard values
Parameters:
```
(input is address of GrafPort record)
```
#### SetPort ($04)
Set current port as specified
Parameters:
```
(input is address of GrafPort record)
```
#### GetPort ($05)
Get pointer to current port
Parameters:
```
.addr port (out)
```
#### SetPortBits ($06)
2018-03-01 03:13:11 +00:00
Set just the mapinfo (viewloc, mapbits) of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
(input is address of MapInfo record)
```
#### SetPenMode ($07)
2018-03-01 03:13:11 +00:00
Set the pen mode of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
.byte mode pen*/notpen*
```
#### SetPattern ($08)
2018-03-01 03:13:11 +00:00
Set the pattern of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
.res 8 pattern 8x8 pixel pattern for PaintRect calls
```
#### SetColorMasks ($09)
2018-03-01 03:13:11 +00:00
Set the color masks of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
.byte and_mask
.byte or_mask
```
#### SetPenSize ($0A)
2018-03-01 03:13:11 +00:00
Set the pen size of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
.byte penwidth horizontal pen thickness
.byte penheight vertical pen thickness
```
#### SetFont ($0B)
2018-03-01 03:13:11 +00:00
Set the font of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
.addr textfont font definition
```
#### SetTextBG ($0C)
2018-03-01 03:13:11 +00:00
Set the text background of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
.byte backcolor 0=black, $7F=white
```
### Drawing - draw lines; frame, fill, and test rects and polys
#### Move ($0D)
2018-03-01 03:13:11 +00:00
Set pen location (relative) of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
.word xdelta
.word ydelta
```
#### MoveTo ($0E)
2018-03-01 03:13:11 +00:00
Set pen location (absolute) of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
Point pos
```
#### Line ($0F)
2018-03-01 03:13:11 +00:00
Draw line from pen location (relative) of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
.word xdelta
.word ydelta
```
#### LineTo ($10)
2018-03-01 03:13:11 +00:00
Draw line from pen location (absolute) of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
Point pos
```
#### PaintRect ($11)
2018-03-01 03:13:11 +00:00
Fill rectangle with pattern of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
Rect rect
```
#### FrameRect ($12)
2018-03-01 03:13:11 +00:00
Draw rectangle with pen mode/size of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
Rect rect
```
#### InRect ($13)
Is current position in bounds? A=$80 true, 0 false
Parameters:
```
Rect rect
```
#### PaintBits ($14)
2018-03-01 03:13:11 +00:00
Draw bitmap.
2018-03-01 02:39:58 +00:00
Parameters:
```
(input is address of MapInfo record)
```
#### PaintPoly ($15)
2018-03-01 03:13:11 +00:00
Fill multiple closed polygons with the pattern of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
(input is address of PolyList record)
```
#### FramePoly ($16)
2018-03-01 03:13:11 +00:00
Draw multiple closed polygons with the pen mode/size of the current grafport.
2018-03-01 02:39:58 +00:00
Parameters:
```
(input is address of PolyList record)
```
#### InPoly ($17)
2018-03-01 03:13:11 +00:00
Is pen location of the current grafport within the polygon? A=$80 true, 0 false
2018-03-01 02:39:58 +00:00
Parameters:
```
(input is address of PolyList record)
```
### Text - draw and measure text
#### TextWidth ($18)
Measure the width of a string in pixels
Parameters:
```
.addr data
.byte length
.word width (out) result in pixels
```
#### DrawText ($19)
2018-03-01 03:13:11 +00:00
Draw string at the pen location of the current graphport (as left, baseline)
2018-03-01 02:39:58 +00:00
Parameters:
```
.addr data
.byte length
```
### Utility - configuration and version
#### SetZP1 ($1A)
Configure lower half of ZP usage by API (speed vs. convenience)
Parameters:
```
.byte preserve 0=stash/no auto restore; 1=restore now and onward
```
#### SetZP2 ($1B)
Configure upper half ZP usage by API (speed vs. convenience)
Parameters:
```
.byte preserve 0=stash/no auto restore; 1=restore now and onward
```
2018-02-19 21:29:57 +00:00
---
# Mouse Graphics
## Concepts
### Cursor
```
.res 24 bitmap 2x12 byte bitmap (XOR'd after mask)
.res 24 mask 2x12 byte mask (OR'd with screen)
.byte hotx hotspot coords (pixels)
.byte hoty
```
### Event
```
.byte kind event_kind_*
.res 4
```
if `kind` is `event_kind_key_down`:
```
.byte kind event_kind_*
.byte key (ASCII code; high bit clear)
.byte modifiers (0=none, 1=open-apple, 2=solid-apple, 3=both)
.res 2 reserved
```
if `kind` is `event_kind_update:`
```
.byte kind event_kind_*
.byte window_id
.res 3 reserved
```
otherwise:
```
.byte kind event_kind_*
.word mousex
.word mousey
```
2018-02-20 03:21:10 +00:00
```
event_kind_no_event := 0 ; No mouse or keypress
event_kind_button_down := 1 ; Mouse button was depressed
event_kind_button_up := 2 ; Mouse button was released
event_kind_key_down := 3 ; Key was pressed
event_kind_drag := 4 ; Mouse button still down
event_kind_apple_key := 5 ; Mouse button was depressed, modifier key down
event_kind_update := 6 ; Window update needed
event_modifier_open_apple := 1 << 0
event_modifier_solid_apple := 1 << 1
```
2018-02-19 21:29:57 +00:00
### Menu
Menu Bar record:
```
.word count Number of menu bar items
.byte menu_id Menu identifier
.byte disabled Flag
.addr title Address of length-prefixed string
.addr menu Address of Menu record
.res 6 reserved Reserved
... repeats for each menu
```
Menu record:
```
.word count Number of items in menu
.res 5 reserved Reserved
.byte options bit 0=OA, 1=SA, 2=mark, 5=check, 6=filler, 7=disabled
.byte mark_char Custom mark character if mark option set
.byte char1 ASCII code of shortcut #1 (e.g. uppercase B); or 0
.byte char2 ASCII code of shortcut #2 (e.g. lowercase b, or same); or 0
.addr name Address of length-prefixed string
... repeats for each menu item
```
### Window "winfo"
```
.byte id
.byte options option_*
.addr title
.byte hscroll scroll_option_*
.byte vscroll scroll_option_*
.byte hthumbmax
.byte hthumbpos
.byte vthumbmax
.byte vthumbpos
.byte status
.byte reserved
.word mincontwidth minimum content size (horizontal)
.word maxcontwidth maximum content size (horizontal)
.word mincontlength minimum content size (vertical)
.word maxcontlength maximum content size (vertical)
GrafPort windowport GrafPort record
.addr nextwinfo address of next lower window in stack
```
2017-09-22 16:00:30 +00:00
2018-02-19 19:33:13 +00:00
Windows have a _content area_ which has the requested dimensions. Above this is an optional
_title bar_ which in turn has an optional _close box_. Within the content area are an
2017-09-22 16:00:30 +00:00
optional _resize box_ and optional _scroll bars_.
2018-02-20 03:21:10 +00:00
```
option_dialog_box := 1 << 0
option_go_away_box := 1 << 1
option_grow_box := 1 << 2
scroll_option_none := 0
scroll_option_present := 1 << 7
scroll_option_thumb := 1 << 6
scroll_option_active := 1 << 0
scroll_option_normal := scroll_option_present | scroll_option_thumb | scroll_option_active
```
2018-02-19 21:29:57 +00:00
## Commands
2018-03-01 02:39:58 +00:00
### Initialization
#### Version ($1C)
Get toolkit version
Parameters:
```
.byte (out) major
.byte (out) minor
.byte (out) patch
.byte (out) status
.word (out) number
```
#### StartDeskTop ($1D)
Inits state, registers interrupt handler, draws desktop
Parameters:
```
.byte machine ROM FBB3 ($06 = IIe or later)
.byte subid ROM FBC0 ($EA = IIe, $E0 = IIe enh/IIgs, $00 = IIc/IIc+)
.byte op_sys 0=ProDOS, 1=Pascal
.byte slot_num: Mouse slot, 0 = search (will be filled in)
.byte use_interrupts 0=passive, 1=interrupt
.addr sysfontptr
.addr savearea buffer for saving screen data (e.g. behind menus)
.word savesize bytes
```
#### StopDeskTop ($1E)
Deallocates interrupt, hides cursor
No parameters.
#### SetUserHook ($1F)
Parameters:
```
.byte hook_id 0=before, 1=after event checking
.addr routine_ptr 0=remove hook_id
```
#### AttachDriver ($20)
Install pointer driver; A=0 on success, $95 if mouse disabled
Parameters:
```
.addr hook Mouse hook routine to install
.addr mouse_state (out) Address of mouse state (.word x, y; .byte status)
```
#### ScaleMouse ($21)
Set mouse/screen scaling
Parameters:
```
.byte x_exponent x-scale factor for mouse, 0...3
.byte y_exponent y-scale factor for mouse, 0...3
```
#### KeyboardMouse ($22)
Next operation will be performed by keyboard
No parameters.
#### GetIntHandler ($23)
Get address of interrupt handler
Parameters:
```
.addr handler (out) Address of interrupt handler (after cld)
```
### Cursor Manager - set, show, hide
#### SetCursor ($24)
Set cursor definition
Parameters:
```
(input is address of Cursor record)
```
#### ShowCursor ($25)
Return cursor to visibility
No parameters.
#### HideCursor ($26)
Cursor hidden until ShowCursor call
No parameters.
#### ObscureCursor ($27)
Cursor hidden until moved
No parameters.
#### GetCursorAddr ($28)
Get cursor definition
Parameters:
```
.addr definition (out) Address of cursor record
```
### Event Manager - get, peek, post
#### CheckEvents ($29)
Process mouse/kbd if GetEvent will be delayed.
No parameters.
#### GetEvent ($2A)
Parameters:
```
(parameter is address of Event record)
```
#### FlushEvents ($2B)
No parameters.
#### PeekEvent ($2C)
Parameters:
```
(parameter is address of Event record)
```
#### PostEvent ($2D)
Post event to queue
Parameters:
```
(parameter is address of Event record)
```
#### SetKeyEvent ($2E)
If set, keypresses are ignored by Tool Kit
Parameters:
```
.byte handle_keys high bit set = ignore keyboard, otherwise check
```
### Menu Manager - configure, enable, disable, select
#### InitMenu ($2F)
Parameters:
```
.byte solid_char char code to use for solid apple glyph
.byte open_char char code to use for open apple glyph
.byte check_char char code to use for checkmark glyph
.byte control_char char code to use for control key glyph
```
#### SetMenu ($30)
Configure (and draw) menu
Parameters:
```
(input is address of Menu Bar record)
```
#### MenuSelect ($31)
Enter modal loop for handling mouse-down on menu bar
Parameters:
```
.byte menu_id (out) Top level menu identifier, or 0 if none
.byte menu_item (out) Index (1-based) of item in menu, or 0 if none
```
#### MenuKey ($32)
Find menu item corresponding to keypress
Parameters:
```
.byte menu_id (out)
.byte menu_item (out)
.byte which_key
.byte key_mods bit 0=OA, bit 1=SA
```
#### HiliteMenu ($33)
Toggle highlight state of menu
Parameters:
```
.byte menu_id
```
#### DisableMenu ($34)
2018-03-01 03:13:11 +00:00
Disable/enable a menu. Effectively disables all items, but individual disable/enable states are restored when re-enabled.
2018-03-01 02:39:58 +00:00
Parameters:
```
.byte menu_id
.byte disable 0=enable, 1=disable
```
#### DisableItem ($35)
2018-03-01 03:13:11 +00:00
Disable/enable a specific item in a menu.
2018-03-01 02:39:58 +00:00
Parameters:
```
.byte menu_id
.byte menu_item
.byte disable 0=enable, 1=disable
```
#### CheckItem ($36)
2018-03-01 03:13:11 +00:00
Sets a specific menu item as checked.
2018-03-01 02:39:58 +00:00
Parameters:
```
.byte menu_id
.byte menu_item
.byte check 0=unchecked, 1=checked
```
#### SetMark ($37)
2018-03-01 03:13:11 +00:00
Sets a specific menu item as using a distinct mark character when checked.
2018-03-01 02:39:58 +00:00
Parameters:
```
.byte menu_id
.byte menu_item
.byte set_char 0=use checkmark, 1=use mark_char
.byte mark_char char code to use for mark
```
### Window Manager - open, close, drag, grow, update
#### OpenWindow ($38)
Parameters:
```
(input is address of WInfo record)
```
#### CloseWindow ($39)
Parameters:
```
.byte window_id
```
#### CloseAll ($3A)
No parameters.
#### GetWinPtr ($3B)
Get pointer to window params by id; A=0 on success
Parameters:
```
.byte window_id
.addr window_ptr (out) winfo address
```
#### GetWinPort ($3C)
Get drawing state of window
Parameters:
```
.byte window_id
.addr port (out) grafport address
```
#### SetWinPort ($3D)
Update port of window
Parameters:
```
.byte window_id
.addr port GrafPort to copy from
```
#### BeginUpdate ($3E)
Respond to update event for window
Parameters:
```
.byte window_id
```
#### EndUpdate ($3F)
No parameters.
#### FindWindow ($40)
Parameters:
```
.word mousex screen coordinates
.word mousey
.byte which_area (out) area_*
.byte window_id (out) of window
```
#### FrontWindow ($41)
Get id of top window
Parameters:
```
.byte window_id (out) window, or 0 if none
```
#### SelectWindow ($42)
Make window topmost
Parameters:
```
.byte window_id
```
#### TrackGoAway ($43)
Parameters:
```
.byte clicked (out) 0 = cancelled, 1 = close
.byte ?? (out)
.byte ?? (out)
```
#### DragWindow ($44)
Parameters:
```
.byte window_id
.word dragx mouse coords
.word dragy
.byte moved high bit set if moved, clear if not
```
#### GrowWindow ($45)
Parameters:
```
.byte window_id
.word mousex
.word mousey
.byte itgrew (out) 0 = no change, 1 = moved
```
#### ScreenToWindow ($46)
Map screen coords to content coords
Parameters:
```
.byte window_id
.word screenx
.word screeny
.word windowx (out)
.word windowy (out)
```
#### WindowToScreen ($47)
Map content coords to screen coords
Parameters:
```
.byte window_id
.word windowx
.word windowy
.word screenx (out)
.word screeny (out)
```
### Control Manager - scrollbars
#### FindControl ($48)
Parameters:
```
.word mousex
.word mousey
.byte which_ctl ctl_*
.byte which_part part_*
```
#### SetCtlMax ($49)
Parameters:
```
.byte which_ctl ctl_*_scroll_bar
.byte ctlmax maximum value
```
#### TrackThumb ($4A)
Parameters:
```
.byte which_ctl ctl_*_scroll_bar
.word mousex
.word mousey
.byte thumbpos (out) 0...255
.byte thumbmobed (out) 0 = no change, 1 = moved
```
#### UpdateThumb ($4B)
Parameters:
```
.byte which_ctl ctl_*_scroll_bar
.byte thumbpos new position 0...250
```
#### ActivateCtl ($4C)
Activate/deactivate scroll bar
Parameters:
```
.byte which_ctl ctl_*_scroll_bar
.byte activate 0=deactivate, 1=activate
```
2018-02-19 21:29:57 +00:00
## More
2017-09-22 16:33:49 +00:00
> NOTE: Movable windows must maintain an _offscreen_flag_. If a window is moved so that the
2018-02-19 19:33:13 +00:00
> content area is entirely offscreen then various operations should be skipped because
2017-09-22 16:33:49 +00:00
> the window's box coordinates will not be set correctly.
2018-02-20 03:21:10 +00:00
### Use by DAs
2017-09-24 23:20:32 +00:00
#### Input Loop
2017-09-22 16:33:49 +00:00
2018-02-20 03:21:10 +00:00
* Call `GetEvent`.
2018-02-05 05:05:31 +00:00
* If a key, then check modifiers (Open/Solid Apple) and key code, ignore or take action.
2018-01-29 05:18:00 +00:00
* If a click, call FindWindow.
2017-09-24 23:26:15 +00:00
* If target id not the window id, ignore.
2018-01-29 05:18:00 +00:00
* If target element is desktop or menu then ignore.
* If target element is close box then initiate [window close](#window-close).
* If target element is title bar then initiate [window drag](#window-drag).
* If target element is resize box then initiate [window resize](#window-resize).
2018-02-20 03:21:10 +00:00
* Otherwise, it is content area; call `FindControl`.
2018-02-19 19:33:13 +00:00
* If content part is a scrollbar then initiate a [scroll](#window-scroll).
* Otherwise, handle a content click using custom logic (e.g. hit testing buttons, etc)
2017-09-24 23:26:15 +00:00
#### Window Close
2018-02-20 03:21:10 +00:00
* Call `TrackGoAway`, which enters a modal loop to handle the mouse moving out/in the box.
* Result indicates clicked or canceled. If canceled, return to input loop.
* Call `CloseWindow`
2017-09-24 23:16:36 +00:00
2017-09-24 23:20:32 +00:00
#### Window Drag
2017-09-22 16:33:49 +00:00
2018-02-20 03:21:10 +00:00
* Call `DragWindow`, which enters a modal loop to handle the mouse moving out/in the box.
* Result indicates moved or canceled. If canceled, return to input loop.
* Call `JUMP_TABLE_REDRAW_ALL`.
* If _offscreen flag_ was not set, redraw desktop icons (`DESKTOP_REDRAW_ICONS`).
2017-09-22 16:33:49 +00:00
* Set _offscreen flag_ if window's `top` is greater than or equal to the screen bottom (191), clear otherwise.
* If _offscreen flag_ is not set, redraw window.
2017-09-24 23:20:32 +00:00
#### Window Resize
2017-09-22 16:33:49 +00:00
2018-02-20 03:21:10 +00:00
* Call `GrowWindow`, which enters a modal loop to handle resizing.
* Result indicates changed or canceled. If canceled, return to input loop.
* Call `JUMP_TABLE_REDRAW_ALL`.
* Call `DESKTOP_REDRAW_ICONS`.
* Call `UpdateThumb` if needed to adjust scroll bar settings.
2017-09-22 16:33:49 +00:00
* Redraw window.
2017-09-24 23:20:32 +00:00
#### Window Scroll
2018-02-20 03:21:10 +00:00
* Call `TrackThumb`, which enters a modal loop to handle dragging.
* Redraw window.