; 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.
;
; s.Mouse
;
; Handle mouse clicks


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; mouse_click
;
; Handle mouse click events
;
; In: r1 -> wimp_event structure
;
; Out: Registers may be corrupted - returning to Wimp_Poll

mouse_click     ROUT

        Push    "LR"

        LDMIA   r1!,{r10,r11}    ; x,y
        LDMIA   r1,{r0-r2}
        ADR     r14, drag_start  ; store x and y in case of drag start
        STMIA   r14, {r10,r11}
        STR     r1, drag_window
        STR     r2, drag_icon

        ; At this point:
        ;   r0 = Buttons
        ;   r1 = Window
        ;   r2 = Icon.

        Debug   pi,"Mouse click ",r0,r1,r2
        LDR     r14,saveas_handle
        CMP     r1,r14
        BEQ     save_click
        Debug   pi,"Not saveas"
        CMP     r1,#-2
        LDRNE   r14,backdrop_handle
        CMPNE   r1,r14
        Pull    "PC",NE

        Debug   pi,"Backdrop click ",r0

        TST     r0,#2                   ; Is it a menu request?
        BNE     create_menu

        CMP     r1,#-2
        LDREQ   r14,TinyDirs_Handle
        TEQ     r2,r14
        Pull    "PC",EQ

        CMP     r0,#&400
        BEQ     Select_Click
        CMP     r0,#&100
        BEQ     Adjust_Click
        CMP     r0,#&40
        BEQ     Select_Drag
        CMP     r0,#&10
        BEQ     Adjust_Drag
        CMP     r0,#&4
        BEQ     SelectDoubleClick
        CMP     r0,#&1
        BEQ     AdjustDoubleClick

        Pull    "PC"


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Select_Click

Select_Click    ROUT

        Debug   pi,"Select click",r1,r2

        CMP     r2,#-1
        BNE     %FT01

        MOV     r0,r1
        BL      DeselectAllIcons
        Pull    "PC"
01
        Push    "r1,r2"
        BL      FindIcon
        ;Pull    "r1,r2,pc",NE
        Pull    "r1, r2", NE
        BNE     Iconized_SelectClick

        LDMIA   sp,{r1,r2}

        MOV     r0,r1
        MOV     r3,r0

        ADR     r1,dataarea
        STR     r0,[r1]
        STR     r2,[r1,#4]
        SWI     XWimp_GetIconState
        Pull    "r1,r2,PC",VS

        Debug   pi,"Got icon state"

        ADR     r1,dataarea
        LDR     r14,[r1,#24]            ; Get icon flags
        TST     r14,#selected
        Pull    "r1,r2,PC",NE           ; Ignore if already selected.

        Debug   pi,"Not already selected"

        MOV     r0,r3
        BL      DeselectAllIcons

        Debug   pi,"Icons deselected ",r3

        ADR     r1,dataarea
        STR     r3,[r1]
        STR     r2,[r1,#4]
        MOV     r0,#is_selected
        STR     r0,[r1,#8]
        STR     r0,[r1,#12]
        SWI     XWimp_SetIconState
        Pull    "r1,r2,PC",VS

        MOV     r1,#1
        CMP     r3,#0
        STRGE   r1,Pinboard_Selected
        STRLT   r1,TinyDirs_Selected
        Debug   pi,"selected icons = ",r1

        Pull    "r1,r2,PC"


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Iconized_SelectClick
;
; Handle a select click on an iconized window icon.
;
; In: r1 = Window handle
;     r2 = Icon handle
;
; Out:

Iconized_SelectClick

        LDR     r0, backdrop_handle
        CMP     r0, r1                  ; check if click was on backdrop
        Pull    "pc", NE                ; exit if not

        MOV     r6, r2                  ; r6 = icon
        BL      find_iconized           ; find the structure relating to the icon in r6
        CMP     r7, #0                  ; found one?
        Pull    "pc", EQ                ; no, then exit

        ADR     r1, dataarea
        LDR     r0, [r7, #w_icon_id]
        STR     r0, [r1]
        LDR     r0, [r7, #w_icon_handle]
        STR     r0, [r1, #4]
        SWI     XWimp_GetIconState      ; Find current state of icon
        Pull    "pc", VS

        LDR     r0, [r1, #24]
        TST     r0, #selected           ; Is icon currently selected?
        Pull    "pc", NE                ; Yes? Then ignore click

        LDR     r0, backdrop_handle
        BL      DeselectAllIcons        ; Deselect all currently selected icons

        LDR     r0, [r7, #w_icon_id]
        STR     r0, [r1]
        LDR     r0, [r7, #w_icon_handle]
        STR     r0, [r1, #4]
        MOV     r0, #is_selected
        STR     r0, [r1, #8]
        MOV     r0, #0
        STR     r0, [r1, #12]
        SWI     XWimp_SetIconState      ; Change the state
        Pull    "pc", VS

        MOV     r0, #1
        STR     r0, Windows_Selected    ; Update number of selected window icons
        Pull    "pc"


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Adjust_Click

Adjust_Click    ROUT

        CMP     r2,#-1
        Pull    "PC",EQ

        Push    "r1,r2"
        BL      FindIcon
        Pull    "r1,r2"
        BNE     Iconized_AdjustClick
        ;Pull    "PC",NE                 ; An iconized icon.

        MOV     r3,r1
        ADR     r1,dataarea
        STR     r3,[r1]
        STR     r2,[r1,#4]
        SWI     XWimp_GetIconState
        Pull    "PC",VS

        LDR     r14,[r1,#24]            ; Get icon flags
        TST     r14,#selected
        MOVEQ   r2,#1
        MOVNE   r2,#-1

        CMP     r3,#0
        LDRGE   r0,Pinboard_Selected
        LDRLT   r0,TinyDirs_Selected
        ADD     r0,r0,r2
        STRGE   r0,Pinboard_Selected
        STRLT   r0,TinyDirs_Selected
        Debug   pi,"selected icons = ",r0

        MOVGE   r0,#is_selected         ; Toggle icon's state.
        MOVLT   r0,#selected
        STR     r0,[r1,#8]
        MOV     r0,#0
        STR     r0,[r1,#12]
        SWI     XWimp_SetIconState

        Pull    "PC"

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Iconized_AdjustClick
;
; Handle an adjust click on an iconized window icon.
;
; In: r1 = Window handle
;     r2 = Icon handle
;
; Out:

Iconized_AdjustClick

        LDR     r5, Windows_Selected
        LDR     r0, backdrop_handle
        CMP     r0, r1                  ; check if click was on backdrop
        Pull    "pc", NE                ; exit if not

        MOV     r6, r2                  ; r6 = icon
        BL      find_iconized           ; find the structure relating to the icon in r6
        CMP     r7, #0                  ; found one?
        Pull    "pc", EQ                ; no, then exit

        ADR     r1, dataarea
        LDR     r0, [r7, #w_icon_id]
        STR     r0, [r1]
        LDR     r0, [r7, #w_icon_handle]
        STR     r0, [r1, #4]
        SWI     XWimp_GetIconState      ; Find current state of icon
        Pull    "pc", VS

        LDR     r0, [r1, #24]
        TST     r0, #selected           ; Is icon currently selected?
        SUBNE   r5, r5, #1              ; Yes, then it will be deselected
        ADDEQ   r5, r5, #1              ; No, then it will be selected

        LDR     r0, [r7, #w_icon_id]
        STR     r0, [r1]
        LDR     r0, [r7, #w_icon_handle]
        STR     r0, [r1, #4]
        MOV     r0, #is_selected
        STR     r0, [r1, #8]
        MOV     r0, #0
        STR     r0, [r1, #12]
        SWI     XWimp_SetIconState      ; Change the state
        Pull    "pc", VS

        STR     r5, Windows_Selected    ; Update number of selected window icons
        Pull    "pc"


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Adjust_DoubleClick

AdjustDoubleClick       ROUT

        CMP     r2,#-1
        Pull    "PC",EQ

        Push    "r1,r2"

        BL      FindIcon                ; r2 -> icon block
        Pull    "r1,r2,PC",NE           ; Not found (Iconized window).

        MOV     r0,#BufferReason_Remove
        ADD     r2,r2,#ic_path
        BL      strlen
        DebugS  pi,"Path = ",r2
        Debug   pi,"Action = ",r0
        Debug   pi,"Window = ",r1
        Debug   pi,"length = ",r3
        BL      BufferIcon
        SUB     r2,r2,#ic_path
        B       %FT01


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SelectDoubleClick

SelectDoubleClick

        CMP     r2,#-1
        Pull    "PC",EQ

        Push    "r1,r2"

        BL      FindIcon                ; r2 -> icon block
        Pull    "r1,r2",NE              ; Not found (Iconized window).
        BNE     IconizedReopen

01
        ADRL    r0,FilerRunCom
        ADR     r1,dataarea
        BL      Copy_r0r1
        ADD     r0,r2,#ic_path
        BL      Copy_r0r1
        ADR     r0,dataarea
        DebugS  pi,"Command: ",r0
        SWI     XOS_CLI
        Pull    "r2,r3"
        Pull    "PC",VS

        ADR     r1,dataarea
        STR     r2,[r1]
        STR     r3,[r1,#4]
        MOV     r0,#0
        STR     r0,[r1,#8]
        CMP     r2,#0
        MOVLT   r0,#selected
        MOVGT   r0,#is_selected
        STR     r0,[r1,#12]
        SWI     XWimp_SetIconState
        Pull    "PC",VS

        CMP     r2,#0
        LDRGE   r0,Pinboard_Selected
        LDRLT   r0,TinyDirs_Selected
        SUB     r0,r0,#1
        STRGE   r0,Pinboard_Selected
        STRLT   r0,TinyDirs_Selected
        Debug   pi,"selected icons = ",r0

        Pull    "PC"

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Claim input focus (make a note of who had it before us).
; Fail silently.
Claim_Focus
        Push    "R0-R5, LR"
        ADR     R1, CaretPos
        SWI     XWimp_GetCaretPosition
        LDR     R0, backdrop_handle
        MOV     R1, #-1         ; icon handle
        MOV     R2, #0          ; x co-ord
        MOV     R3, #0          ; y co-ord
        MOV     R4, #-1         ; height + flags
        MOV     R5, #-1         ; string index
        SWI     XWimp_SetCaretPosition
        CLRV
        Pull    "R0-R5, PC"


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Put the input focus back to where ever it was when we claimed
; it. Note: if that window has been closed, we fail silently.
Restore_Focus
        Push    "R0-R5, LR"
        ADR     LR, CaretPos
        LDMIA   LR, {R0-R5}
        TEQ     R0, #0
        SWINE   XWimp_SetCaretPosition
        MOV     R0, #0
        STR     R0, CaretPos
        CLRV
        Pull    "R0-R5, PC"


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Adjust_Drag

Adjust_Drag     ROUT
        BL      Claim_Focus

        CMP     r2,#-1
        BNE     Select_DragIcon

        MOV     r0,#DragType_AdjustDrag
        STR     r0,DragType

        B       %FT01


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Select_Drag

Select_Drag
        BL      Claim_Focus

        CMP     r2,#-1
        BNE     Select_DragIcon

        MOV     r0,#DragType_SelectDrag
        STR     r0,DragType

01
      [ {TRUE}
        MOV     r0,#1
        LDR     r2,XEig
        LDR     r3,YEig
        MOV     r2,r0,LSL r2            ; pixel width
        MOV     r3,r0,LSL r3            ; pixel height
        ADR     r1,dataarea
        LDMIA   r1!,{r0,r14}
        STMIA   r1!,{r0,r14}
        ADD     r0,r0,r2                ; make exclusive!
        ADD     r14,r14,r3
        STMIA   r1!,{r0,r14}
        SUB     r1,r1,#8*3
      |
        ADR     r1,dataarea
        LDR     r14,[r1]
        STR     r14,[r1,#8]             ; Initial x0
        STR     r14,[r1,#16]            ; Initial x1
        LDR     r14,[r1,#4]
        STR     r14,[r1,#12]            ; Initial y0
        STR     r14,[r1,#20]            ; Initial y1
      ]
        LDR     r14,icon_bar_height     ; Parent y0
        STR     r14,[r1,#28]
        MOV     r14,#6                  ; Drag type
02
        STR     r14,[r1,#4]
        MOV     r14,#0
        STR     r14,[r1,#24]            ; Parent x0
        LDR     r14,Screen_x1           ; Parent x1
      [ {TRUE}
        ADD     r14,r14,r2              ; make exclusive!
      ]
        STR     r14,[r1,#32]
        LDR     r14,Screen_y1           ; Parent y1
      [ {TRUE}
        ADD     r14,r14,r3              ; make exclusive!
      ]
        STR     r14,[r1,#36]

 [ ursulawimp
        LDR     r2, backdrop_handle
        STR     r2, [r1]
        LDR     r2, taskword
        MOV     r3, #3
 ]

        SWI     XWimp_DragBox

        Pull    "PC"

 [ ursulawimp
taskword DCB "TASK"
 ]

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Adjust_DragIcon

Adjust_DragIcon
        Push    "r0-r2"
        BL      FindIcon
        STREQ    r2,[sp,#8]

        Pull    "r0-r2"
        Pull    "PC",NE                 ; Iconized window !


        MOV     r0,#DragType_AdjustDragIcon
        STR     r0,DragType

        MOV     r3,r1
        ADR     r1,dataarea
        STR     r3,[r1]
        STR     r2,[r1,#4]
        SWI     XWimp_GetIconState
        Pull    "PC",VS

        LDR     r14,[r1,#24]            ; Get icon flags
        TST     r14,#selected
        MOVNE   r1,r3
        BNE     %FT10                   ; Ignore if already selected.

        STR     r3,[r1]
        STR     r2,[r1,#4]
        MOV     r0,#is_selected
        STR     r0,[r1,#8]
        STR     r0,[r1,#12]
        SWI     XWimp_SetIconState
        Pull    "PC",VS

        CMP     r3,#0
        LDRGE   r1,Pinboard_Selected
        LDRLT   r1,TinyDirs_Selected
        ADD     r1,r1,#1
        STRGE   r1,Pinboard_Selected
        STRLT   r1,TinyDirs_Selected
        Debug   pi,"selected icons = ",r1
        MOV     r1,r3
        B       %FT10


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Select_DragIcon
;
; Deals with drags of icons

Select_DragIcon

        LDR     r14,saveas_handle
        TEQ     r1,r14
        BEQ     save_drag
        Push    "r0-r2"
        BL      FindIconBoth                ; r2 -> icon block if found
        STREQ   r2,[sp,#8]
        Pull    "r0-r2"
        Pull    "pc", NE
        ;BNE     Iconized_Drag
        MOV     r0,#DragType_SelectDragIcon
        STR     r0,DragType

10
        MOV     r0,r1
        STR     r0,DragWindow

        ; Check for DragASprite
        Push    "r0-r2"
        MOV     r0,#OsByte_ReadCMOS
        MOV     r1,#FileSwitchCMOS
        SWI     XOS_Byte
        MOVVS   r3,#0
        ANDVC   r3,r2,#DragASpriteCMOSBit
        Pull    "r0-r2"

        ; If using DragASprite then FindBBOX will set up the drag for us.
        Debug   tmp,"r2 (icon blk ptr) = ",r2
        Debug   tmp,"r3 (DAS) = ",r3
        BL      FindBBOX

        CMP     r0,#0
        ADDLT   r7,r7,#24
        ADDLT   r9,r9,#24
        Debug   tmp,"BBOX is ",r6,r7,r8,r9

        ; Ensure bounding box is at least grid_x_spacing by grid_y_spacing
        SUB     r0,r8,r6
        CMP     r0,#grid_x_spacing
        RSBLT   r0,r0,#grid_x_spacing
        SUBLT   r6,r6,r0,LSR #1
        ADDLT   r8,r8,r0,LSR #1
        SUB     r0,r9,r7
        CMP     r0,#grid_y_spacing
        RSBLT   r0,r0,#grid_y_spacing
        SUBLT   r7,r7,r0,LSR #1
        ADDLT   r9,r9,r0,LSR #1

        Debug   tmp,"adjusted BBOX is ",r6,r7,r8,r9

        ADR     r14,DragBBOX
        STMIA   r14,{r6,r7,r8,r9}

        CMP     r3,#0
        Pull    "pc",NE         ; Don't do Wimp_DragBox if using DragASprite

        ADRL    r1,dataarea+8
        STMIA   r1,{r6,r7,r8,r9}
        SUB     r1,r1,#8

        ; Why on earth is the parent box defined like this:
        SUB     r6,r6,r10
        STR     r6,[r1,#24]             ; Parent x0

        SUB     r7,r7,r11
        STR     r7,[r1,#28]             ; Parent y0

        LDR     r14,Screen_x1
        SUB     r8,r8,r10
        ADD     r14,r14,r8
        STR     r14,[r1,#32]            ; Parent x1

        LDR     r14,Screen_y1
        SUB     r9,r9,r11
        ADD     r14,r14,r9
        STR     r14,[r1,#36]

        MOV     r14,#5
        STR     r14,[r1,#4]

        SWI     XWimp_DragBox

        Pull    "PC"

        LNK     Drag.s