; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; > source.NewSWIs

SWIWimp_TextOp
        MyEntry "TextOp"

        AND     userblk,R0,#255
        TEQ     userblk,#0
        TEQNE   userblk,#1
        TEQNE   userblk,#2
        SETV    NE
        ADRVSL  R0,ErrorBlock_WimpBadReasonCode
        BVS     ExitWimp
        TEQ     userblk,#0
        BLEQ    textop_setcolours
        [ AllowMatrix
        TST     R0,#&20000000
        MOVNE   R14,R6
        MOVEQ   R14,#0
        STR     R14,validationstring
        ]
        TEQ     userblk,#1
        BLEQ    textop_gettextwidth
        TEQ     userblk,#2
        BLEQ    textop_painttext
        B       ExitWimp

textop_setcolours
        Push    lr
        [ outlinefont
        LDR     R3,systemfont
        TEQ     R3,#0
        STRNE   R1,last_fg_gcol
        STRNE   R2,last_bg_gcol
        Pull    PC,NE
        ]
        MOV     R0,R2
        MOV     R3,#128                 ; bg
        MOV     R4,#0
        SWI     XColourTrans_SetGCOL
        MOVVC   R0,R1
        MOVVC   R3,#0
        SWIVC   XColourTrans_SetGCOL

        Pull    PC

textop_painttext
        Push    "lr"

        TST     R0,#&20000000
        LDRNE   R3,redrawhandle
        Abs     R3,R3,NE
        LDRNE   R14,[R3,#w_wax0]
        ADDNE   R4,R4,R14
        LDRNE   R14,[R3,#w_way1]
        ADDNE   R5,R5,R14

        [ outlinefont
        LDR     R3,systemfont
        TEQ     R3,#0
        BEQ     systemfont_paint

        MOV     R2,R1
        MOV     R1,#is_deleted
        MOV     R9,#bignum
      [ CnP
        MOV     R7, #nullptr
      ]
        BL      pushfontstring

        LDR     R9,last_fg_gcol
        CMP     R9,#-1
        MOVNE   R9,R9, LSR #8
        ORRNE   R9,R9,#&0E000000
        Push    "R9",NE
        LDRNE   R9,last_bg_gcol
        MOVNE   R9,R9, LSR #8
        MOVNE   R9,R9, LSL #8
        ORRNE   R9,R9,#19               ; set font colours
        Push    "R9",NE
        ADDNE   R7,R7,#8
        SUBNE   R1,R1,#8
        MOVNE   R9,#-1
        STRNE   R9,last_fg_gcol

        TST     R0,#&40000000
        LDRNE   R14,systemfonty1
        SUBNE   R14,R14,#28             ; system font was 28 OS units above baseline
        SUBNE   R5,R5,R14 ,LSR #1

        TST     R0,#&10000000           ; vertically central
        LDRNE   R14,systemfonty1
        SUBNE   R5,R5,R14 ,LSR #1

;        LDRNE   R14,systemfonty0
;        SUBNE   R5,R5,R14 ,LSR #1
;        SUBNE   R5,R5,R14               ; p'=p-(y1-3y2)/2


test_rightjustified
        TST     R0,#&80000000
        BEQ     textop_paintfancy
; right justified
        Push    "R1-R5"
        MOV     R2,#0
        MOV     R3,#bignum
        MOV     R4,#bignum
        SWI     XFont_ScanString
        MOV     R1,R3
        SWI     XFont_ConverttoOS
        MOV     R0,R1
        Pull    "R1-R5"
        SUB     R4,R4,R0                ; R4 was RHS
textop_paintfancy
        MOV     R3,R4
;        LDR     R14,systemfonty0        ; get baseline same as system font
;        ADD     R14,R14,#4
;        SUB     R4,R5,R14
        MOV     R4,R5
        MOV     R2,#16                  ; use OS units

        LDR     R14,dx_1
        BIC     R3,R3,R14
        LDR     R14,dy_1
        ADD     R4,R4,R14               ; round up
        BIC     R4,R4,R14

        SWI     XFont_Paint

        ADD     sp,sp,R7                ; balance stack from pushfontstring
        Pull    "PC"

systemfont_paint

        ]

        TST     R0,#&10000000           ; vertically central
        SUBNE   R5,R5,#16               ; system font is 32 OS units high

        LDR     R14,dx_1
        BIC     R4,R4,R14
        LDR     R14,dy_1
        SUB     R5,R5,R14               ; round down as plotting from top left
        BIC     R5,R5,R14

        TST     R0,#&80000000           ; right justified ?
        BEQ     paint_systemfont
        MOV     R0,#0
        MOV     R7,R1
systemfontlength
        LDRB    R6,[R7],#1
        CMP     R6,#31
        ADDGT   R0,R0,#1
        BGT     systemfontlength
        MOV     R0,R0,LSL #4            ; 16 OS units per char
        SUB     R4,R4,R0
paint_systemfont
        Push    "R1"
        MOV     R1,R4
        ADD     R2,R5,#28               ; top left vs btm left
        MOV     R0,#4                   ; move abbsolute
        SWI     XOS_Plot
        Pull    "R0"
        SWI     XOS_Write0
        Pull    "PC"


textop_gettextwidth
        Push    "lr"

        MOV     R9,#bignum
        CMP     R2,#0
        MOVGT   R9,R2

        [ outlinefont
        LDR     R3,systemfont
        TEQ     R3,#0
        BEQ     textop_sysfontwidth

        MOV     R2,R1
        MOV     R1,#is_deleted
      [ CnP
        MOV     R7, #nullptr
      ]
        BL      pushfontstring
        [ true
        MOV     R2,#0
        MOV     R3,#bignum
        MOV     R4,#bignum
        SWI     XFont_ScanString
        ADD     sp,sp,R7
        MOV     R1,R3
        |
        SWI     XFont_StringBBox                        ; calls scanstring internally
        SUB     R1,R3,R1
        ADD     sp,sp,R7
        ]
        SWI     XFont_ConverttoOS
        MOV     R0,R1
        Pull    "PC"

textop_sysfontwidth
        ]
        MOV     R0,#0

textop_sysfontwidth_loop

        LDRB    R3,[R1],#1
        CMP     R3,#31
        ADDGT   R0,R0,#1
        CMPGT   R9,R0
        BGT     textop_sysfontwidth_loop
        MOV     R0,R0, LSL #4
        Pull    "PC"

SWIWimp_ResizeIcon
        MyEntry "ResizeIcon"

        CMP     R0,#0
        LDRLT   handle,iconbarhandle
        MOVGE   handle,R0
        BL      checkhandle
        BVS     ExitWimp
        LDR     R0,[handle,#w_nicons]
        CMP     R1,R0
        BGT     badiconhandle
        CMP     R1,#0
        BLT     badiconhandle
        LDR     R0,[handle,#w_icons]
        ADD     R0,R0,R1, LSL #i_shift
        STMIA   R0,{R2-R5}
        B       ExitWimp

        [ UseDynamicArea
wimpspritepoolarea
        DCB     "WSpr"
wimpspritepool
        DCB     "WSP",0
        ALIGN
        ]

allocatespritememory
      [ UseDynamicArea
        Push    "R1,R8,LR"

        TEQ     R0,#ModHandReason_Claim
        BNE     %FT10
        ADR     R0,wimpspritepool               ; Look up name for Wimp sprite pool.
        ADR     R2,errorbuffer                  ; Put it in a safe place for now (copied out by OS_DynamicArea).
        MOV     R3,#256
        BL      LookupToken1
        Pull    "R1,R8,PC",VS
        MOV     R8,R2
        MOV     R0,#ModHandReason_Claim         ; Restore corrupted R0.
10
        LDR     R1,wimpspritepoolarea
        BL      Dynamic_Module
        Pull    "R1,R8,PC",VC

        MyXError WimpNoSprites
        Pull    "R1,R8,PC"
      |
	Push	"LR"
	SWI	XOS_Module
	Pull	"PC"
      ]

        MakeErrorBlock WimpNoSprites

badiconhandle
        ADRL    R0,ErrorBlock_WimpBadIconHandle
        SETV
        B       ExitWimp

SWIWimp_Extend
        MyEntry "Extend"

        TEQ     R0,#1
        MOVEQ   R0,R12
        BEQ     ExitWimp
        TEQ     R0,#2
        ADREQ   R0,extendjumptable
        BEQ     ExitWimp
        TEQ     R0,#3
        LDREQ   R0,wimpswiintercept
        STREQ   R1,wimpswiintercept
        BEQ     ExitWimp
        TEQ     R0,#4
        ADREQ   R0,spritename
        ADREQ   R1,list_at
        STREQ   R1,[sp]
        BEQ     ExitWimp
        TEQ     R0,#5
        LDREQ   R0,plotsprCB
        STREQ   R1,plotsprCB
        BEQ     ExitWimp
      [ ChildWindows
        CMP     R0,#6                   ; In: R0 = 6 => get parent, 7,8 => get top/bottom child, 9,10 => get next/previous sibling
        RSBGES  R14,R0,#10              ; In: R1 = window handle, or -1 for top-level ; Out: R1 = result handle, or -1 for none
        BGE     %FT01
      ]
        TEQ     R0,#11                  ; In: R1 = pointer to block to fill with furniture dimensions
        BEQ     %FT11                   ;     [R1,#0] = window handle to use, or 0 for generic values
      [ NCErrorBox
        TEQ     R0,#12
        BEQ     %FT12
      ]
        B       ExitWimp

      [ ChildWindows

01      CMP     R1,#nullptr
        BEQ     %FT05

        MOV     handle,R1
        BL      checkhandle_iconbar
        BVS     ExitWimp

        CMP     R0,#7
        LDRLT   handle,[handle,#w_parent]
        BLT     %FT03

        LDREQ   handle,[handle,#w_children + lh_forwards]
        BEQ     %FT02

        CMP     R0,#9
        LDRLT   handle,[handle,#w_children + lh_backwards]
        BLT     %FT02

        LDR     R14,[handle,#w_flags]
        TST     R14,#ws_open                    ; sibling pointers are garbage if window is not open
        MOVEQ   handle,#nullptr
        BEQ     %FT04

        CMP     R0,#9
        LDREQ   handle,[handle,#w_active_link + ll_forwards]
        LDRGT   handle,[handle,#w_active_link + ll_backwards]

02      CMP     handle,#nullptr
        LDRNE   R14,[handle,#ll_forwards]       ; if either forward or backward pointer is null, we're at the head entry (not a window)
        CMPNE   R14,#nullptr
        LDRNE   R14,[handle,#ll_backwards]
        CMPNE   R14,#nullptr
        MOVEQ   handle,#nullptr
        SUBNE   handle,handle,#w_active_link

03      CMP     handle,#nullptr
        Rel     handle,handle,NE

04      STR     handle,[sp]
        B       ExitWimp

05      CMP     R0,#7
        LDREQ   handle,activewinds + lh_forwards
        BEQ     %BT02

        CMP     R0,#8
        LDREQ   handle,activewinds + lh_backwards
        BEQ     %BT02

        B       ExitWimp
      ]

      [ NCErrorBox
        ; Handle hiding of pointer for the duration of keyboard-driving of pointer
12      MOV     R0, #106
        MOV     R1, #0
        SWI     XOS_Byte        ; turn off pointer
        MOV     R0, #1
        ADRL    R14, ptrsuspendflag
        STR     R0, [R14]
        B       ExitWimp
      ]

extendjumptable
        B       getspriteaddr
      [ CnP
        B       extendjumptable_pushfontstring
      |
        B       pushfontstring
      ]
        B       callaswi
        B       ExitWimp
        B       ExitWimp2
        B       godrawicon
        B       exitcicon
        B       int_setcolour

      [ CnP
extendjumptable_pushfontstring
        MOV     R7, #nullptr
        B       pushfontstring
      ]
                     ^  0, userblk
furnblock_handle     #  4
furnblock_lborder    #  4
furnblock_bborder    #  4
furnblock_rborder    #  4
furnblock_tborder    #  4
furnblock_back       #  4
furnblock_close      #  4
furnblock_titlegap0  #  4
furnblock_title      #  4
furnblock_titlegap1  #  4
furnblock_iconise    #  4
furnblock_togglew    #  4
furnblock_toggleh    #  4
furnblock_vscrgap1   #  4
furnblock_up         #  4
furnblock_vscr       #  4
furnblock_down       #  4
furnblock_vscrgap0   #  4
furnblock_adjusth    #  4
furnblock_adjustw    #  4
furnblock_hscrgap1   #  4
furnblock_right      #  4
furnblock_hscr       #  4
furnblock_left       #  4
furnblock_hscrgap0   #  4

11
        CMP     userblk, #ApplicationStart
        MyXError  WimpBadPtrInR1, LT, L
        BVS     ExitWimp                ; check pointer valid in this case

        LDR     handle, furnblock_handle
        TEQ     handle, #0
        BEQ     %FT01

        BL      checkhandle_iconbar
        BVS     ExitWimp
        ADD     R0, handle, #w_ow0
        LDMIA   R0, {cx0, cy0, cx1, cy1} ; cx0-cy1 = visible area
        LDMIA   R0, {x0, y0, x1, y1}     ; x0-y1 = visible area
        BL      calc_w_x0y0x1y1          ; x0-y1 = window outline
        SUB     R0, cx0, x0
        STR     R0, furnblock_lborder
        SUB     R0, cy0, y0
        STR     R0, furnblock_bborder
        SUB     R0, x1, cx1
        STR     R0, furnblock_rborder
        SUB     R0, y1, cy1
        STR     R0, furnblock_tborder
        SUB     x1, x1, x0               ; calc total lengths of sides - top edge
        SUB     y1, y1, y0               ; - right edge
        MOV     x0, x1                   ; - bottom edge
        LDR     R14, [handle, #w_flags]  ; load flags
        LDR     R1, [handle, #w_parent]  ; get parent
        B       %FT02

01      LDR     R0, dx                   ; assume max border widths
        STR     R0, furnblock_lborder
        LDR     R0, hscroll_height1
        STR     R0, furnblock_bborder
        LDR     R0, vscroll_width1
        STR     R0, furnblock_rborder
        LDR     R0, title_height1
        STR     R0, furnblock_tborder
        MOV     x1, #&200                ; assume reasonably large
        MOV     y1, x1
        MOV     x0, x1
        MOV     R14, #wf_iconbits        ; assume all border flags set
        MOV     R1, #-1                  ; assume a top-level window

02
        TST     R14, #wf_icon1           ; back icon?
        LDRNE   R0, back_width
        MOVEQ   R0, #0
        SUB     x1, x1, R0
        STR     R0, furnblock_back

        TST     R14, #wf_icon2           ; close / iconise icons?
        LDRNE   R0, close_width
        MOVEQ   R0, #0
        SUB     x1, x1, R0
        STR     R0, furnblock_close
      [ IconiseButton
        BEQ     %FT06
        MOV     R0, #0
        CMP     R1, #-1
        BNE     %FT06 ; no iconise button on children
        LDRB    R1, iconisebutton
        TEQ     R1, #0
        BEQ     %FT06
        LDR     R0, iconise_width
06
      |
        MOV     R0, #0
      ]
        SUB     x1, x1, R0
        STR     R0, furnblock_iconise

        TST     R14, #wf_icon4           ; toggle-size icon?
        LDRNE   R0, vscroll_width
        MOVEQ   R0, #0
        SUB     x1, x1, R0
        STR     R0, furnblock_togglew
        LDRNE   R0, title_height
        SUB     y1, y1, R0
        STR     R0, furnblock_toggleh

        TST     R14, #wf_icon3           ; title bar?
        MOVEQ   x1, #0
        STR     x1, furnblock_title

        MOV     R0, #0
        STR     R0, furnblock_titlegap0  ; provided to support future expansion
        STR     R0, furnblock_titlegap1  ; eg extra buttons, or a squashable title bar

        MVN     R0, R14
        TST     R0, #wf_icon5 :OR: wf_icon7
        TSTNE   R0, #wf_icon6            ; adjust-size / blank?
        LDREQ   R0, hscroll_height
        MOVNE   R0, #0
        SUB     y1, y1, R0
        STR     R0, furnblock_adjusth
        LDREQ   R0, vscroll_width
        SUB     x0, x0, R0
        STR     R0, furnblock_adjustw

        TST     R14, #wf_icon5           ; if no vscroll, clear the vscroll words
        MOV     R0, #0
        STREQ   R0, furnblock_vscrgap1
        STREQ   R0, furnblock_up
        STREQ   R0, furnblock_vscr
        STREQ   R0, furnblock_down
        STREQ   R0, furnblock_vscrgap0
        BEQ     %FT04

        Push    "R14"
        TEQ     handle, #0
;       MOVEQ   R0, #0                   ; gap0 = 0
        MOVEQ   R14, #0                  ; gap1 = 0
        BEQ     %FT03
      [ ChildWindows
        Push    "x0,y1"                  ; determine vertical gaps
        MOV     R0, #iconposn_vscroll
        BL      calc_w_iconposn2
        SUB     R0, y0, cy0
        SUB     R14, cy1, y1
        Pull    "x0,y1"
      ]
03      STR     R0, furnblock_vscrgap0
        STR     R14, furnblock_vscrgap1
        SUB     y1, y1, R0
        SUBS    y1, y1, R14

;       CMP     y1, #0                   ; see if vertical arrows are squashed
        MOVLE   cy0, #0                  ; arrows given 0 length if scrollbar has -ve length (it can happen!)
        MOVLE   cy1, #0
        LDRGT   cy0, down_height         ; standard lengths
        LDRGT   cy1, up_height
        ADDGT   R14, cy0, cy1
        RSBGTS  R0, y1, R14
        MOVGT   cy0, y1, LSR#1           ; which may be squashed
        SUBGT   cy1, y1, cy0
        SUB     y1, y1, cy0              ; take arrows from the bar length to give the well length
        SUB     y1, y1, cy1
        STR     cy1, furnblock_up
        STR     y1, furnblock_vscr
        STR     cy0, furnblock_down
        Pull    "R14"

04
        TST     R14, #wf_icon7           ; if no hscroll, clear the hscroll words
        MOV     R0, #0
        STREQ   R0, furnblock_hscrgap1
        STREQ   R0, furnblock_right
        STREQ   R0, furnblock_hscr
        STREQ   R0, furnblock_left
        STREQ   R0, furnblock_hscrgap0
        BEQ     ExitWimp                 ; all done

        TEQ     handle, #0
;       MOVEQ   R0, #0                   ; gap0 = 0
        MOVEQ   R14, #0                  ; gap1 = 0
        BEQ     %FT05
      [ ChildWindows
        Push    "x0"                     ; determine horizontal gaps
        MOV     R0, #iconposn_hscroll
        BL      calc_w_iconposn2
        SUB     R0, x0, cx0
        SUB     R14, cx1, x1
        Pull    "x0"
      ]
05      STR     R0, furnblock_hscrgap0
        STR     R14, furnblock_hscrgap1
        SUB     x0, x0, R0
        SUBS    x0, x0, R14

;       CMP     x0, #0                   ; see if horizontal arrows are squashed
        MOVLE   cx0, #0                  ; arrows given 0 length if scrollbar has -ve length (it can happen!)
        MOVLE   cx1, #0
        LDRGT   cx0, left_width          ; standard lengths
        LDRGT   cx1, right_width
        ADDGT   R14, cx0, cx1
        RSBGTS  R0, x0, R14
        MOVGT   cx0, x0, LSR#1           ; which may be squashed
        SUBGT   cx1, x0, cx0
        SUB     x0, x0, cx0              ; take arrows from the bar length to give the well length
        SUB     x0, x0, cx1
        STR     cx1, furnblock_right
        STR     x0, furnblock_hscr
        STR     cx0, furnblock_left
        B       ExitWimp                 ; all done

        END