* Demo01.a      Version 1.00   July 20, 2000   by Ken Shillito


*
*  This program demonstrates minimal programming of ucode.library
*  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*  It...  (1) opens a window
*         (2) puts a Unicode glyph on the window
*         (3) waits for the user to click the close window gadget
*         (4) shuts down
*
*  (Caution: If the program fails, it does not report why, but just exits)


 IFND what
 INCLUDE 'exec/types.i'
 INCLUDE 'UCODE:Includes/ucode.i'
 INCLUDE 'UCODE:Includes/ucodeasms.i'
 ENDC

 INCLUDE 'dos/dosextens.i'
 INCLUDE 'intuition/intuition.i'


 XREF _AbsExecBase
 XREF _LVOCloseLibrary
 XREF _LVOCloseWindow
 XREF _LVOFindTask
 XREF _LVOForbid
 XREF _LVOGetMsg
 XREF _LVOOpenLibrary
 XREF _LVOOpenWindowTagList
 XREF _LVOReplyMsg
 XREF _LVOWaitPort


***************************************************************************
*
*                 First, do setting up
*                 ~~~~~~~~~~~~~~~~~~~~
***************************************************************************


***********  Setting up Step 1: Process Startup  **************

Start:                     ;cold startup...
 clr.l bench               ;(bench will 0 if started from CLI)
 move.l _AbsExecBase,a6
 sub.l a1,a1               ;for current task..
 jsr _LVOFindTask(a6)      ;.. find own Process structure
 move.l d0,a2              ;(A2) = our own Process structure
 tst.l pr_CLI(a2)          ;pr_CLI<>0 if from CLI
 bne.s Both                ;go if from CLI

 lea pr_MsgPort(a2),a0     ;wait for workbench startup message to arrive
 jsr _LVOWaitPort(a6)
 lea pr_MsgPort(a2),a0     ;get workbench startup message now it's here
 jsr _LVOGetMsg(a6)
 move.l d0,bench           ;remember the message, for replying &c (bench<>0)


*******   Setting up Step 2: open ucode.library *************

Both:

 IFND what
 lea uname,a1
 moveq #xxp_uver,d0
 jsr _LVOOpenLibrary(a6)
 move.l d0,ubase
 beq Quit0
 ENDC

 IFD  what
 IFEQ what-3
 lea uname,a1
 moveq #xxp_uver,d0
 jsr _LVOOpenLibrary(a6)
 move.l d0,ubase
 beq Quit0
 ENDC
 IFEQ what-4
 move.l #Endcode+24,ubase  ;(only assemble if debugging)
 ENDC
 ENDC

******** Setting up Step 3: make ucode_path structure   *********

 move.l ubase,a6           ;a6 = base of ucode.library
 moveq #0,d0               ;d0 = 0 = same bitplanes as default public screen
 moveq #48,d1              ;d1 = 48 = value for single glyphs
 moveq #70,d2              ;d2 = 70 = max glyph height
 jsr _LVOTLUstart(a6)      ;create ucode_path
 tst.l d0
 beq Quit1                 ;quit if can't
 move.l d0,upath           ;address of ucode_path to upath


*************  Setting up Step 4: open window ***************

 move.l upath,a0           ;get intuition.library base from ucode_path
 move.l xxp_intp(a0),a6

 sub.w #128,a7             ;room for 15 tags
 move.l a7,a0
 move.l #WA_Left,(a0)+      ;xpos = 20
 move.l #20,(a0)+
 move.l #WA_Top,(a0)+       ;ypos = 20
 move.l #20,(a0)+
 move.l #WA_Width,(a0)+     ;init width = 400
 move.l #400,(a0)+
 move.l #WA_Height,(a0)+    ;init height = 150
 move.l #150,(a0)+
 move.l #WA_MinWidth,(a0)+  ;min width = 80
 move.l #80,(a0)+
 move.l #WA_MinHeight,(a0)+ ;min height = 20
 move.l #20,(a0)+
 move.l #WA_MaxWidth,(a0)+  ;max width = unlimited
 move.l #0,(a0)+
 move.l #WA_MaxHeight,(a0)+ ;max height = unlimited
 move.l #0,(a0)+
 move.l #WA_CloseGadget,(a0)+ ;+ close gadget
 move.l #-1,(a0)+
 move.l #WA_SizeGadget,(a0)+  ;+ size gadget
 move.l #-1,(a0)+
 move.l #WA_DragBar,(a0)+     ;+ drag bar
 move.l #-1,(a0)+
 move.l #WA_Activate,(a0)+ ;open active
 move.l #-1,(a0)+
 move.l #WA_NoCareRefresh,(a0)+  ;no refresh
 move.l #-1,(a0)+
 move.l #WA_IDCMP,(a0)+
 move.l #IDCMP_CLOSEWINDOW,(a0)+ ;+ close window
 move.l #WA_Title,(a0)+
 move.l #wnam,(a0)+        ;title = *wnam
 clr.l (a0)                ;delimit tags
 sub.l a0,a0               ;a0 = 0 = no NewWindow structure
 move.l a7,a1              ;a1 = tags
 jsr _LVOOpenWindowTagList(a6)   ;open the window
 add.w #128,a7             ;discard tags
 move.l d0,wndw            ;wndw = address of window
 beq Quit2                 ;quit if can't open window


***************************************************************************
*
*            Setting up is complete - now do something
*            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
***************************************************************************


******************  Step 1: set ucode_path attributes  ********************

; The glyph to be displayed below will be grabbed from a data file named
; "Ucode/Uni/U0B/NMSS100".  The "0B" in the "U0B" sub-directory
; means the glyphs are of nominal height 11 ($0B=11). Files of nominal
; height 11 have "actual" height of 14 (for details, see ucode.guide). The
; "NM" means width = NorMal, which means the width code (which can be
; 0-8) is 4. The "SS" means "Sans Serif" style. The "1" means the weight
; code (which can be 1 to 9) is 1. The "00" means that the 1024 glyphs in
; the file have first 2 digits $00.., that is they are $0000 to $03FF.

 move.l ubase,a6           ;a6 = base of ucode.library
 moveq #11,d0              ;d0 = nominal height = 11
 moveq #4,d1               ;d1 = width = 4 = NM = normal
 move.w #'SS',d2           ;d2 = style = SS = sans serif
 moveq #1,d3               ;d3 = weight = 1
 moveq #0,d4               ;d4 = flags = 0 = no flags set
 move.l upath,a0           ;a0 = ucode_path
 jsr _LVOTLUset(a6)        ;set the ucode_path attributes


******************  Step 2: show a glyph *****************************

; I arbitrarily decided to show the glyph for Unicode $0158,
; at position 20,10 on the window interior, with pens 1,0.


 subq.l #8,a7              ;make 8 bytes in stack for wint

 move.l wndw,a2            ;a2 = window to draw to
 moveq #0,d0
 move.b wd_BorderLeft(a2),d0  ;wint+0 = xpos of top of interior
 move.w d0,(a7)
 add.b wd_BorderRight(a2),d0
 move.w wd_Width(a2),d1
 sub.w d0,d1
 move.w d1,4(a7)              ;wint+4 = width of window interior
 move.b wd_BorderTop(a2),d0   ;wndt+2 - ypos of top of window interior
 move.w d0,2(a7)
 add.b wd_BorderBottom(a2),d0
 move.w wd_Height(a2),d1
 sub.w d0,d1
 move.w d1,6(a7)              ;wint+6 = height of window interior

 move.l ubase,a6           ;a6 = base of ucode.library
 moveq #20,d0              ;d0 = xpos of lhs of glyph = 20
 moveq #10,d1              ;d1 = ypos of top of glyph's max ascender = 10
 moveq #0,d2               ;d2 = 0 = use default wbox (i.e. 0,0,10000,10000)
 move.l a7,d3              ;d3 = wint
 move.w #$0158,d4          ;d4 = Unicode = $0158
 moveq #1,d5               ;d5 = fgpen = 1
 moveq #0,d6               ;d6 = bgpen = 0
 move.l upath,a0           ;a0 = ucode_path
 move.l wd_RPort(a2),a1    ;a1 = window's rastport
 jsr _LVOTLUgrabrport(a6)  ;grab the glyph to the window

 addq.l #8,a7              ;discard wint

 tst.l d0
 beq Quit3                 ;quit if TLUgrabrport failed


*********  Step 3: Wait until user clicks the CloseWindow gadget **********

Step3:
 move.l _AbsExecBase,a6
 move.l wndw,a2
 move.l wd_UserPort(a2),a0 ;(i.e. get IDCMP_CloseWindow & reply to it)
 jsr _LVOWaitPort(a6)
 move.l wd_UserPort(a2),a0
 jsr _LVOGetMsg(a6)
 tst.l d0
 beq.s Quit3
 move.l d0,a1
 jsr _LVOReplyMsg(a6)


***************************************************************************
*
*                  Finally, close everything down
*                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
***************************************************************************


*****   Close window  *****

Quit3:
 move.l upath,a0
 move.l xxp_intp(a0),a6
 move.l wndw,a0
 jsr _LVOCloseWindow(a6)


*****   Release ucode.library structures  *****

Quit2:
 move.l ubase,a6           ;call TLUfinish
 move.l upath,a0
 jsr _LVOTLUfinish(a6)


*****   Close ucode.library  *******

Quit1:                     ;close ucode.library

 IFND what
 move.l _AbsExecBase,a6
 move.l ubase,a1
 jsr _LVOCloseLibrary(a6)
 ENDC

 IFD what
 IFEQ what-3
 move.l _AbsExecBase,a6
 move.l ubase,a1
 jsr _LVOCloseLibrary(a6)
 ENDC
 ENDC


******  Exit from Program  *******

Quit0:                     ;reply to workbench startup message if any
 move.l _AbsExecBase,a6
 move.l bench,d2
 beq.s Quit
 jsr _LVOForbid(a6)
 move.l d2,a1
 jsr _LVOReplyMsg(a6)
Quit:
 rts


***************************************************************************
*
*                           Data Section
*                           ~~~~~~~~~~~~
***************************************************************************


* system data
bench: ds.l 1             ;bench = 0 if CLI, else = workbench message
ubase: ds.l 1             ;ucode.library base
uname: dc.b 'UCODE:ucode.library',0
 ds.w 0


* window data
wnam: dc.b 'Ucode Test Asm Window',0
 ds.w 0
wndw: ds.l 1              ;window


* ucode.library structure
upath: ds.l 1             ;pointer ucode_path structure
