Wimp05 182 KB
Newer Older
Neil Turton's avatar
Neil Turton committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
; 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.Wimp05

;;----------------------------------------------------------------------------
;; Code for dealing with writable icons
;;----------------------------------------------------------------------------

SWIWimp_SetCaretPosition
        MyEntry "SetCaretPosition"

; next bit turned off as they've changed their mind AGAIN!!!

        [ false
; in 16/32 bit modes ReadPalette EOR trick doesn't work, so make sure
; that wimp colour 11 is used.

        LDR     R14,log2bpp
        CMP     R14,#3

        [ false
        BICGT   R4,R4,#(1 :SHL: 26)
        |
; alternatively, assume colour is a wimp colour number
        BICGT   R4,R4,#(1:SHL:27)
        ]
        ]

        BL      int_set_caret_position
        B       ExitWimp

; Entry:  R0,R1 = window/icon handles
;         R2,R3 = x,y coords (relative to window)
;         R4 = caret height/flags
;         R5 = index of caret (if in a writable icon)
;         [caretdata .. caretdata+20] = old caret data
;         [caretscrollx] = scroll offset within current icon
; Exit:   old caret removed from screen
;         new caret replotted
;         if old/new text icon had to scroll, it will be redrawn

; Actions on new caret data:
;         R0<=0 ==> just turn caret off
;         R1<0 ==> R4>=0, R5 ignored
;         R4>=0 and R5>=0 ==> recompute R2 from R5 (R3,R4 preserved)
;         R5<0 ==> recompute R4,R5 from R0,R1,R2,R3
;         R4<0 ==> recompute R2,R3,R4 from R0,R1,R5

        MACRO
$label  TraceCaretData
$label  TraceK  sc, "w "
        TraceX  sc, R0
        TraceK  sc, ", i "
        TraceD  sc, R1
        TraceK  sc, ", (x, y) ("
        TraceD  sc, R2
        TraceK  sc, ", "
        TraceD  sc, R3
        TraceK  sc, "), height "
        TraceD  sc, R4
        TraceK  sc, ", index "
        TraceD  sc, R5
        TraceNL sc
        MEND

int_set_caret_position TraceL sc
        Push    "R6-R7,LR"              ; R6,R7 are used as temporaries
        LDR     R6,taskhandle           ; preserve calling task
        Push    "R0-R6"                 ; save caret data + taskhandle

        TraceK  sc, "int_set_caret_position: "
        TraceCaretData

Neil Turton's avatar
Neil Turton committed
86 87
        CheckAllWindows "int_set_caret_position (before)"

Neil Turton's avatar
Neil Turton committed
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
        LDR     R14,caretdata
        STR     R14,oldcaretwindow
        TEQ     R0,R14                  ; are we going to the same window?
        BLNE    send_losecaret          ; [caretdata] contains data

        MOV     R14,#-bignum
        STR     R14,leftborder          ; in case any redrawing needs doing

        ADR     R14,caretdata
        LDMIA   R14,{R0-R6}             ; R6 = previous caretscrollx
        TraceK  sc, "Old caret data: "
        TraceCaretData

        MOV     R14,#0
        STR     R14,caretdata+24
Robert Sprowson's avatar
Robert Sprowson committed
103
        AcceptLoosePointer_NegOrZero R0,nullptr
Neil Turton's avatar
Neil Turton committed
104
        CMP     R0,#nullptr             ; any window selected?
Ben Avison's avatar
Ben Avison committed
105
        BEQ     notwindow1              ; if not, caretscrollx must = 0
Neil Turton's avatar
Neil Turton committed
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
        CMP     R1,#0
        BLT     noticon1                ; this isn't an icon
        STR     R6,caretdata+24         ; that value was indeed valid

; if icon scrolls because the caret leaves, it must be redrawn
; [caretdata+24] updated to reflect state of icon to receive the caret

        LDR     R14,[sp,#0]
        TEQ     R14,R0
        LDREQ   R14,[sp,#4]
        TEQEQ   R14,R1

        TEQNE   R6,#0                   ; NE ==> we must redraw the icon
        BEQ     noticon1

        MOV     R14,#0
        STR     R14,caretdata+24        ; 'old caretscrollx' = 0 for sure now
Jeffrey Lee's avatar
Jeffrey Lee committed
123
        MOV     R14,#nullptr
Neil Turton's avatar
Neil Turton committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
        STR     R14,caretdata+0         ; CARET IS DEFINITELY NOT NOW HERE
        BL      pageinicontask          ; Swap to task if icon indirected

        Trace   sc, "int_set_caret_position: psr ", X, PC

        BLVC    redrawtexticon          ; R1 = icon handle
        B       notwindow1
noticon1 TraceL sc
        BL      upcaret
notwindow1 TraceL sc
        MOVVS   R14,#nullptr            ; no caret if error
        STRVS   R14,caretdata+0

        STRVS   R0,[sp]
        Pull    "R0-R5"                 ; report errors when removing caret
        BVS     exitsetcaret

; now do the new caret:

        TraceK  sc, "New caret data: "
        TraceCaretData

        MOV     R14,#0                  ; will be 0 unless find/setcaret called
        STR     R14,caretscrollx

        MOV     handle,R0
        BL      checkhandle
        MOVVS   R0,#nullptr             ; treat as null window if deleted

; decide whether we're going into an icon, or if this is a 'user caret'

Robert Sprowson's avatar
Robert Sprowson committed
155
        AcceptLoosePointer_NegOrZero R0,nullptr
Ben Avison's avatar
Ben Avison committed
156 157
        CMP     R0,#nullptr     ; CLR V ; no caret at all
        BEQ     notwindow2
Neil Turton's avatar
Neil Turton committed
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
        CMP     R1,#0
        BLT     noticon2

; now, if R4 and R5 valid, compute R2 from R5, to cope with scrolling
; NB: R5<0 overrides R4<0 (ie. findcaret is preferred to setcaretcoords)

        LDR     R14,[handle,#w_taskhandle]
        Task    R14,,"SetCaret"         ; this will be reset on exit from Wimp!

        Push    "R3,R4"                 ; these are valid, so save them
        CMP     R4,#0
        CMPPL   R5,#0
        BLPL    setcaretcoords          ; must recompute [caretscrollx]
        Pull    "R3,R4"

        CMP     R5,#0                   ; if R5<0 then R4,R5 <-- R0,R1,R2,R3
        BLMI    findcaret
        CMP     R4,#0                   ; if R4<0 then R2,R3,R4 <-- R0,R1,R5
        BLMI    setcaretcoords

        TraceK  sc, "Modified caret data: "
        TraceCaretData

        ADR     R14,caretdata
        STMIA   R14,{R0-R5}             ; processed values

        LDR     R6,caretdata+24         ; R6 = old value
        LDR     R14,caretscrollx
        STR     R14,caretdata+24        ; new value = R14 = caretscrollx

        Debug   sc,"Old/New caretscrollx =",R6,R14

        TEQ     R14,R6                  ; is this different from last time?
        BEQ     noticon2

        BL      redrawtexticon          ; handle,R1 = window,icon handles
        B       notwindow2              ; caret was drawn as well
noticon2 TraceL sc
        BL      upcaret
notwindow2 TraceL sc
        BVS     gained_caret

        TraceK  sc, "Storing new caret data: "
        TraceCaretData

        ADR     R14,caretdata           ; relevant only if R0<=0 or R1<0
        STMIA   R14,{R0-R5}

; update window borders

        LDR     R0,oldcaretwindow
        LDR     R14,caretdata
        TEQ     R0,R14
        BLNE    focusoff                ; preserves flags
        BVS     gained_caret
        BLNE    send_gaincaret          ; [caretdata] contains data
        LDRNE   R0,caretdata
        BLNE    focuson
gained_caret TraceL sc
        MOVVS   R14,#nullptr            ; no caret if error
        STRVS   R14,caretdata+0

exitsetcaret TraceL sc
Neil Turton's avatar
Neil Turton committed
221 222 223

        CheckAllWindows "int_set_caret_position (after)"

Neil Turton's avatar
Neil Turton committed
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
        Pull    "R14"                   ; taskhandle is remembered
        Task    R14,,"Restoring after SetCaret"
        Pull    "R6-R7,PC"


; Entry:  R0,R1 = handle,icon
;         R2,R3 = caret coords (rel. to window origin)
;         R4,R5 = caret height/index


upcaret TraceL sc
        TST     R4,#crf_invisible
        MOVNE   PC,LR

        Push    "R0-R5,LR"

Neil Turton's avatar
Neil Turton committed
240 241
        Debug   child,"upcaret called"

Neil Turton's avatar
Neil Turton committed
242 243 244 245
        MOV     handle,R0
        BL      checkhandle
        BVS     %FT99

Kevin Bracey's avatar
Kevin Bracey committed
246 247 248
	MOV	R4,R4,LSL #16		; remove flags
	MOV	R4,R4,LSR #16

Neil Turton's avatar
Neil Turton committed
249 250 251 252 253 254
        LDR     R14,dx
        SUB     x0,R2,R14
        SUB     x0,x0,R14,LSL #1        ; x0 <- R2 - 3*dx
        ADD     x1,R2,R14,LSL #2        ; x1 <- R2 + 4*dx
        MOV     y0,R3
        ADD     y1,R3,R4                ; just above top of caret
Kevin Bracey's avatar
Kevin Bracey committed
255
	ADD	y1,y1,R14		; +dx for luck
Neil Turton's avatar
Neil Turton committed
256 257 258 259 260 261 262 263 264 265

        Push    "R1-R5"
        MOV     R0,#getrect_firstrect:OR:getrect_updating:OR:getrect_noicons
        BL      int_update_window2
        ADD     R14,handle,#w_wax0
        LDMIA   R14,{R1-R6}
        SUB     x1,R1,R5                        ; get x origin
        SUB     y1,R4,R6                        ; get y origin
        Pull    "R1-R5"

Kevin Bracey's avatar
Kevin Bracey committed
266
	LDR	R1,[sp,#4*4]			; caret height (OS coords) + flags
Neil Turton's avatar
Neil Turton committed
267 268 269 270 271 272 273 274 275 276 277 278
        ADD     R4,y1,R3                        ; y coord of caret
        ADD     R3,x1,R2                        ; x coord of caret
        MOV     R2,#&10                         ; use OS coords
upcarlp
        Push    "R1-R4"
        BL      int_get_rectangle
        Pull    "R1-R4"
        TEQ     R0,#0                   ; doesn't affect V flag
        BEQ     %FT99
        BLVC    plotcaret
        BVC     upcarlp
99
Neil Turton's avatar
Neil Turton committed
279 280
        Debug   child,"upcaret exitting"

Neil Turton's avatar
Neil Turton committed
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
        STRVS   R0,[sp]
        Pull    "R0-R5,PC"


; Plot caret
; Entry:  R1 = height of caret (plus funny bits)
;              crf_vdu5caret  ==> don't use font manager
;              crf_invisible  ==> don't actually draw caret
;              crf_usercolour ==> bits 16-23 are colour to use
;              crf_realcolour ==> don't use colour lookup table
;         R3,R4 = caret position
;         handle --> window definition


plotcaret ROUT
        TST     R1,#crf_invisible
        MOVNE   PC,LR

        Push    "R0-R3,R5,LR"

        TST     R1,#crf_usercolour
302
        MOVEQ   R0,#sc_red                      ; default caret colour
Neil Turton's avatar
Neil Turton committed
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
        MOVNE   R0,R1,LSR #crb_colourshift
        ANDNE   R0,R0,#&FF

        TSTNE   R1,#crf_realcolour              ; was it a Wimp colour?
        BNE     %FT10                           ; no, it was a real colour so ignore this lookup

        BL      getpalpointer                   ; R14 -> physical colour table (fifteen entries)
        AND     R0,R0,#&F                       ; range from 0..15
        LDR     R0,[R14,R0,LSL #2]
        LDR     R5,[R14,#0]                     ; get caret physical and background physical

        SWI     XColourTrans_ReturnGCOL         ; = caret colour to use
        Push    "R0"
        MOVVC   R0,R5                           ; = background colour to apply
        SWIVC   XColourTrans_ReturnGCOL
        Pull    "R5"                            ; translate the colours
        BVS     upfancyfont_leave
; R0 = logical background colour
; R5 = logical foreground colour

        EOR     R0,R5,R0                        ; R0 = ((colour 11) EOR (colour 0))

10      TST     R1,#crf_vdu5caret
        MOV     R1,R1,LSL #32-crb_colourshift   ; bottom 16 bits are height
        MOV     R1,R1,ASR #32-crb_colourshift
        BEQ     upfancyfont

        Push    "R3-R4"
        MOV     R3,#&00                         ; logic mode 3, EOR
        MOV     R4,#&03
        SWI     XColourTrans_SetColour
        Pull    "R3-R4"                         ; must preserve R2..R4
        BVS     upfancyfont_leave

        SUB     R1,R1,#1                ; make inclusive (not nec. aligned!)

Kevin Bracey's avatar
Kevin Bracey committed
339
	MOV	R5,R1
Neil Turton's avatar
Neil Turton committed
340
        Plot    &04,R3,R4               ; draw vertical bar
Kevin Bracey's avatar
Kevin Bracey committed
341
        Plot    &01,#0,R5
Neil Turton's avatar
Neil Turton committed
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356

caret_stroke    *       2
caret_cross     *       3*caret_stroke  ; width of cross-pieces (OS units)

        Plot    &00,#(caret_stroke-caret_cross)/2,#0   ; draw upper cross-piece
        Plot    &01,#caret_cross-2,#0
        SUB     R1,R3,#(caret_cross-caret_stroke)/2
        Plot    &04,R1,R4               ; draw lower cross-piece
        Plot    &01,#caret_cross-2,#0

        Pull    "R0-R3,R5,PC"

upfancyfont
        LDR     R14,log2bpp
        TEQ     R14,#3
357 358
        LDREQ   R14,modeflags
        TSTEQ   R14,#ModeFlag_FullPalette
Neil Turton's avatar
Neil Turton committed
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
        SWIEQ   XColourTrans_GCOLToColourNumber

        MOV     R2,#&14                 ; use OS units

        TraceK  sc, "upfancyfont: colour "
        TraceD  sc, R0
        TraceK  sc, ", height "
        TraceD  sc, R1
        TraceK  sc, ", flags "
        TraceX  sc, R2
        TraceK  sc, ", (x, y) ("
        TraceD  sc, R3
        TraceK  sc, ", "
        TraceD  sc, R4
        TraceK  sc, ")"
        TraceNL sc
        SWI     XFont_Caret

upfancyfont_leave
        STRVS   R0,[sp]
        Pull    "R0-R3,R5,PC"


; if updating and drawing icons, we must remove/replace the caret!


forcecaret
        Push    "R1,cx0,cy0,cx1,cy1,LR"

        Rel     R0,handle
        LDR     R14,caretdata                   ; window handle
        CMP     R0,R14                          ; same one?
        Pull    "R1,cx0,cy0,cx1,cy1,PC",NE

; draw caret (having already drawn the icons)

        ADD     R14,handle,#w_wax0
        LDMIA   R14,{R0,R1,cx0,cy0,cx1,cy1}
        SUB     cx1,R0,cx1                      ; cx1 <- x0-scx
        SUB     cy1,cy0,cy1                     ; cy1 <- y1-scy

        ASSERT  (cx1=R4)
Robert Sprowson's avatar
Robert Sprowson committed
401
        ADRL    R14,caretdata+8
Neil Turton's avatar
Neil Turton committed
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
        LDMIA   R14,{R0,R1,R2}                  ; x,y coords and height
        ADD     R3,cx1,R0                       ; x coord of caret
        ADD     R4,cy1,R1                       ; y coord of caret
        MOV     R1,R2                           ; caret height (OS coords)
        BL      plotcaret

        Pull    "R1,cx0,cy0,cx1,cy1,PC"


;-----------------------------------------------------------------------------
; Set up appropriate input focus (highlight window)
; Entry:  R0 = (relative) window handle
;         R1 = state of ws_hasfocus bit to set
;-----------------------------------------------------------------------------

focusoff TraceL sc
        MOV     R1,#0
        B       setfocus

focuson TraceL sc
        MOV     R1,#ws_hasfocus

setfocus TraceL sc
Kevin Bracey's avatar
Kevin Bracey committed
425
        EntryS  "R0,R2,R3"
Neil Turton's avatar
Neil Turton committed
426 427 428 429 430 431

        CMP     R0,#nullptr
        BEQ     exitsetfocus

; Find window with handle R0 in active stack

Neil Turton's avatar
Neil Turton committed
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
      [ ChildWindows
        MOV     handle,R0
        BL      checkhandle_iconbar             ; allow caret in iconbar now
        BVS     errbadstack

        ADD     R2,handle,#w_active_link

01      LDR     R14,[handle,#w_flags]
        TST     R14,#ws_open
        BEQ     errbadstack                     ; window (and all its parents) must be open
        LDR     handle,[handle,#w_parent]
        CMP     handle,#nullptr
        BNE     %BT01

        SUB     handle,R2,#w_active_link        ; go back to original window

setfocus_loop
      |
Neil Turton's avatar
Neil Turton committed
450 451 452 453 454 455 456 457 458 459
        LDR     R2,activewinds+lh_forwards
getfoclp1
        LDR     R3,[R2,#ll_forwards]
        CMP     R3,#nullptr
        BEQ     errbadstack
        SUB     R14,R2,#w_active_link
        Rel     R14,R14
        TEQ     R14,R0
        MOVNE   R2,R3
        BNE     getfoclp1
Neil Turton's avatar
Neil Turton committed
460
      ]
Neil Turton's avatar
Neil Turton committed
461 462 463

; Drop through any panes

Neil Turton's avatar
Neil Turton committed
464
getfoclp2
Neil Turton's avatar
Neil Turton committed
465 466
        LDR     R3,[R2,#ll_forwards]
        CMP     R3,#nullptr
Neil Turton's avatar
Neil Turton committed
467
        BEQ     errbadstack                     ; NB: windows with pane bit must still find a sibling to pass it on to
Neil Turton's avatar
Neil Turton committed
468 469 470 471 472 473 474 475 476 477
        LDR     R14,[R2,#w_flags-w_active_link]
        TST     R14,#wf_isapane
        MOVNE   R2,R3
        BNE     getfoclp2

; Convert to an Abs handle

        SUB     handle,R2,#w_active_link
        B       gotfoc

Neil Turton's avatar
Neil Turton committed
478 479
; urg - no suitable input focus window found

Neil Turton's avatar
Neil Turton committed
480 481 482
errbadstack
        MyXError  WimpFocus
errexitf
Kevin Bracey's avatar
Kevin Bracey committed
483 484
        STRVS   R0,[R13, #Proc_RegOffset]
        EXIT
Neil Turton's avatar
Neil Turton committed
485 486
        MakeErrorBlock WimpFocus

Neil Turton's avatar
Neil Turton committed
487 488 489 490
; handle -> window to receive the focus
; R14 = current window flags of this window
; R1 = ws_hasfocus bit setting

Neil Turton's avatar
Neil Turton committed
491
gotfoc
Neil Turton's avatar
Neil Turton committed
492 493 494 495 496
    [ ChildWindows
        AND     R0,R14,#ws_hasfocus
        TEQ     R0,R1
        BEQ     %FT10

Neil Turton's avatar
Neil Turton committed
497 498 499 500
        BIC     R14,R14,#ws_hasfocus
        ORR     R14,R14,R1
        STR     R14,[handle,#w_flags]

Neil Turton's avatar
Neil Turton committed
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
        Debug   child,"ws_setfocus on/off for window",handle
        BL      int_mark_window_opening         ; open window stuff will deal with redrawing the window borders

        MOV     R0,#3
        Push    "R1"
        BL      int_force_redraw_border         ; redraw title bar, in case caller is trying to force a redraw
        Pull    "R1"

10      LDR     handle,[handle,#w_parent]
        CMP     handle,#nullptr
        ADDNE   R2,handle,#w_active_link
        BNE     setfocus_loop                   ; mark all parents of this window as well
    |
        BIC     R14,R14,#ws_hasfocus
        ORR     R14,R14,R1
        STR     R14,[handle,#w_flags]

      [ Twitter
        BL      visibleoutertwitter
        BL      checktwitter
      |
Neil Turton's avatar
Neil Turton committed
522
        BL      visibleouterportion
Neil Turton's avatar
Neil Turton committed
523
      ]
Neil Turton's avatar
Neil Turton committed
524 525
        ADD     R14,handle,#w_wax0
        LDMIA   R14,{cx0,cy0,cx1,cy1}
Neil Turton's avatar
Neil Turton committed
526 527 528 529
      [ Twitter
        SUBNE   cy0, cy0, #2
        ADDNE   cy1, cy1, #2
      ]
Neil Turton's avatar
Neil Turton committed
530 531 532 533 534
        MOV     R0,#windowrects
        MOV     R1,R0
        BL      subrect
        BL      markinvalidrects
        BL      losewindowrects
Neil Turton's avatar
Neil Turton committed
535
    ]
Neil Turton's avatar
Neil Turton committed
536 537

exitsetfocus
Kevin Bracey's avatar
Kevin Bracey committed
538
        EXITS
Neil Turton's avatar
Neil Turton committed
539 540 541 542 543

;..............................................................................

SWIWimp_GetCaretPosition
        MyEntry "GetCaretPosition"
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558
      [ CnP
        LDR     R14, taskidentifier4
        TEQ     R2, R14                 ; = "TASK" ?
        MOVEQ   R14, #0
        STREQ   R14, [sp, #1*4]         ; R2 on exit = 0
        MOVNE   R0, #0                  ; always return caret data if not special

        TEQ     R0, #1
        BEQ     int_get_ghost_caret_position
        TEQ     R0, #2
        BEQ     int_get_selection_position
        TEQ     R0, #0
        BNE     ExitWimp
int_get_caret_poition
      ]
Neil Turton's avatar
Neil Turton committed
559 560 561 562 563
        ADR     R14,caretdata
        LDMIA   R14,{R0-R5}
        STMIA   userblk,{R0-R5}
        B       ExitWimp

564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
      [ CnP
int_get_ghost_caret_position
        ADRL    R14, ghostcaretdata
        LDMIA   R14, {R0-R5}
        STMIA   userblk, {R0-R5}
        B       ExitWimp

int_get_selection_position
        CMP     R3, #nullptr
        MOVNE   handle, R3
        LDREQ   handle, selectionwindow

        CMP     handle, #nullptr        ; no unshaded selection?
        STREQ   handle, [userblk]
        BEQ     ExitWimp

        BL      checkhandle_iconbar
        BVS     ExitWimp

        MOV     R0, R3
        ADD     handle, handle, #w_seldata
        LDMIA   handle, {R1-R7}
        CMP     R1, #nullptr            ; no selected icon in this window?
        MOVEQ   R0, R1
        STMIA   userblk, {R0-R7}
        B       ExitWimp

taskidentifier4 DCB     "TASK"
      ]
Neil Turton's avatar
Neil Turton committed
593 594 595 596 597 598

;-----------------------------------------------------------------------------
; Send a message to the relevant task whenever the caret window changes
;-----------------------------------------------------------------------------

send_losecaret
Kevin Bracey's avatar
Kevin Bracey committed
599
        EntryS  "R0-R2,handle"
Neil Turton's avatar
Neil Turton committed
600 601 602 603
        MOV     R0,#Lose_Caret
        B       %FT01

send_gaincaret
Kevin Bracey's avatar
Kevin Bracey committed
604
        ALTENTRY
Neil Turton's avatar
Neil Turton committed
605 606 607 608 609 610 611 612 613 614 615
        MOV     R0,#Gain_Caret
01
        ADR     R1,caretdata
        LDR     handle,caretdata
        BL      checkhandle                     ; error if handle -1
        BVS     %FT99

        LDR     R2,[handle,#w_taskhandle]
        CMP     R2,#0                           ; menus are owned by Wimp
        BLGT    int_sendmessage_fromwimp
99
Kevin Bracey's avatar
Kevin Bracey committed
616
        EXITS                                   ; ignore errors
Neil Turton's avatar
Neil Turton committed
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650


;-----------------------------------------------------------------------------
; Deal with a mouse click on a writable icon
; Entry:  R0,R1 = mouse coords
;         R2 = mouse button state
;         R6 = button flags for this icon
;         handle,R3,R4 = window/icon handles
;         R14 = link address
;-----------------------------------------------------------------------------

clickonwriteable
        Push    "R0-R6,LR"

        MOV     R0,R3                           ; window handle
        MOV     R1,R4                           ; icon handle
        LDR     R2,mousexrel                    ; x,y coords
        LDR     R3,mouseyrel
        MOV     R5,#-1                          ; calculate R4,R5 from R2,R3
        BLVC    int_set_caret_position

        Pull    "R0-R6,PC",VC

        Pull    "R1-R7,LR"
        B       ExitWimp


;-----------------------------------------------------------------------------
; Find caret position given coords
; Entry:  R0,R1,R2,R3 = window/icon handles and x,y coords (relative)
; Exit :  R4,R5 set up as well (unless icon null)
;-----------------------------------------------------------------------------

findcaret TraceL sc
Ben Avison's avatar
Ben Avison committed
651 652 653
        CMP     R0,#nullptr
        MOVEQ   PC,LR
        CMP     R1,#0
Neil Turton's avatar
Neil Turton committed
654 655 656 657 658 659 660 661 662 663 664 665 666 667
        MOVLT   PC,LR                           ; can't do anything with this

        Push    "R0-R3,LR"                      ; save window/icon handles etc.

        LDR     R14,caretdata+0
        EORS    R14,R14,R0
        LDREQ   R14,caretdata+4
        EOREQS  R14,R14,R1
        STR     R14,hascaret            ; 0 ==> this icon had the caret already
;                                       ; [caretdata+20] = caret index
        MOV     handle,R0
        BL      checkhandle
        Pull    "R0-R3,LR",VS
        MOVVS   R0,#nullptr             ; if window does not exist, forget it
Kevin Bracey's avatar
Kevin Bracey committed
668
        MOVVS   PC,LR
Neil Turton's avatar
Neil Turton committed
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703

; find origin of text given OLD status of icon (with or without caret)

        LDR     R2,[handle,#w_icons]
        ;;ADD   R2,R2,#i_bbx0 ???
        ADD     R2,R2,R1,ASL #i_shift
        LDMIA   R2!,{x0,y0,x1,y1}       ; set up x0,y0,x1,y1 (relative)

        Push    "R0-R3"
        LDR     R1,[R2]                 ; get the icon flags
        LDR     R3,[R2,#8]              ; get the pointer to the validation string

; if text+indirected then R3 is validation string, else store zero
        TST     R1,#if_text
        TSTNE   R1,#if_indirected
        MOVEQ   R3,#0
        STR     R3,validationstring     ;320nk

        BL      getborder
        BL      adjustforborder         ; attempt to adjust for border specified
        Pull    "R0-R3"

        LDR     R1,[R2]                 ; set up R1,R2 (was 4)
        ADD     R2, R2, #4              ; R2 -> icon data (was absent)
        TST     R1,#if_indirected
        LDRNE   R2,[R2]                 ; pointer is indirected

        ASSERT  :INDEX:tempworkspace = 0
        STMIA   wsptr,{R1,R2,x0,y0,x1,y1}       ; icon flags/data, bbox

; NB [caretx] = offset of caret from previous time

        BL      findtextorigin                  ; cx1,cy1 = x,y coords

        LDR     R14,writeabledir
704
        Push    "x0"
Neil Turton's avatar
Neil Turton committed
705 706 707
        LDR     x0,[wsptr]
        TST     x0,#if_numeric
        MOVNE   R14,#0
708
        Pull    "x0"
Neil Turton's avatar
Neil Turton committed
709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
        TEQ     R14,#0
        SUBNE   R14,cx1,x0
        SUBNE   cx1,x1,R14

        MOV     x0,cx1
        MOV     y0,cy1                          ; x0,y0 = old text origin


        Pull    "R3,R4,x1,y1"                   ; x1,y1 click coordinates
        Pull    "PC",VS

        BL      findcaretx0y0                  ; R2,R3 = offset, R4,R5 set up
        STR     R2,caretx                       ; needed for next call

        Push    "R0-R5"
        MOV     R14,#0                          ; compute new positions
        STR     R14,hascaret                    ; Icon has caret
        LDMIA   wsptr,{R1,R2,x0,y0,x1,y1}       ; icon flags/text ptr, box
        BL      findtextorigin                  ; do it again ==> NEW coords
        Pull    "R0-R3"

        Push    "r0"
        LDR     R14,writeabledir
        LDR     r0,[wsptr]
        TST     r0,#if_numeric
        MOVNE   R14,#0
        TEQ     R14,#0
        Pull    "r0"
        SUBNE   R14,cx1,x0
        SUBNE   cx1,x1,R14


        ASSERT  cx1=R4
        ADDEQ   R2,cx1,R2                       ; add to origin
        SUBNE   R2,cx1,R2
        ADD     R3,cy1,R3
        Pull    "R4-R5,LR"                      ; drop through to shrinkcaret


; Entry:  R0,R1 = window/icon handles of caret
;         R2,R3 = coordinates of bottom of caret
;         R4,R5 = caret height/index
;         handle --> window definition
; Exit:   R3,R4 = adjusted so that the caret is within the icon


shrinkcaret
Ben Avison's avatar
Ben Avison committed
756 757 758 759
        CMP     R0,#nullptr             ; forget it if not inside an icon
        MOVEQ   PC,LR
        CMP     R1,#0
        MOVLT   PC,LR
Neil Turton's avatar
Neil Turton committed
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902

        Push    "y0,y1,LR"

        LDR     R14,[handle,#w_icons]           ; R14 --> icon list
        ADD     R14,R14,R1,LSL #i_shift         ; R14 --> icon R1
        LDR     y0,[R14,#i_flags]
        TST     y0,#if_border
        LDR     y0,[R14,#i_bby0]                ; y0,y1 = bottom/top of icon
        LDR     y1,[R14,#i_bby1]

      [ false
        LDRNE   R14,dy
        ADDNE   y0,y0,R14              ; allow for border (1 pixel)
        SUBNE   y1,y1,R14
      |
        Push    "r0-r3"
        LDR     r1,[R14,#i_flags]
        LDR     r3,[R14,#i_data+4]     ; validation string pointer

        TST     R1,#if_text
        TSTNE   R1,#if_indirected
        MOVEQ   R3,#0
        STR     R3,validationstring

        BL      getborder
        BL      adjustforborder
        Pull    "r0-r3"
      ]

        CMP     R3,y0                   ; move base of caret up if nec.
        MOVLT   R3,y0
        MOV     R14,R4,LSL #32-crb_colourshift
        ADD     R14,R3,R14,ASR #32-crb_colourshift ; R14 = coords of top
        SUBS    R14,y1,R14
        ADDLT   R4,R4,R14               ; reduce caret height if nec.

        Pull    "y0,y1,PC"

; Find offset to nearest character position
; Entry:  R1,R2 = icon flags/text
;         R3,R4 = window/icon handles
;         x0,y0 = text origin
;         x1,y1 = coords of mouse click
; Exit:   R0,R1 = window/icon handles (R3,R4 on entry)
;         R2,R3 = offset from x0,y0
;         R4,R5 = caret height/index

findcaretx0y0 TraceL sc
        Push    "R3,R4,LR"                      ; R3,R4 go into R0,R1 on exit

        TraceK  sc, "findcaretx0y0: icon flags "
        TraceX  sc, R1
        TraceK  sc, ", w "
        TraceX  sc, R3
        TraceK  sc, ", i "
        TraceD  sc, R4
        TraceNL sc

        [       outlinefont
        LDR     LR, systemfont
        TEQ     LR, #0
        TSTEQ   R1, #if_fancyfont
        |
        TST     R1, #if_fancyfont
        ]
        BNE     findcaretx0y0_fancy

        ;System font case
        MOV     R3,#-32
        MOV     R4,#40
        ORR     R4,R4,#crf_vdu5caret            ; don't call the Font manager!

        LDR     R14,writeabledir
        TST     R1,#if_numeric
        MOVNE   R14,#0
        TEQ     R14,#0
        ADDEQ   R14,x1,#8                       ; round to nearest
        SUBEQ   R14,R14,x0
        SUBNE   R14,x1,#8
        SUBNE   R14,x0,R14
        MOV     R14,R14,ASR #4                  ; divide by 16 (down to chars)
        MOV     R5,#0
srchlp  CMP     R5,R14
        BGE     srchdone
        LDRB    R0,[R2,R5]
        CMP     R0,#32
        ADDCS   R5,R5,#1
        BCS     srchlp
srchdone
        MOV     R2,R5,LSL #4
        Pull    "R0,R1,PC"                      ; R0,R1 = window/icon handles

        ;Outline font case
findcaretx0y0_fancy TraceL sc

; R1 = icon flags
; R2 -> icon text
; (R6, R7) = text origin
; (R8, R9) = click coords

        Push    R6-R9

        TraceK  sc, "findcaretx0y0_fancy: text origin ("
        TraceD  sc, R6
        TraceK  sc, ", "
        TraceD  sc, R7
        TraceK  sc, ") OSU"
        TraceNL sc

        TraceK  sc, "findcaretx0y0_fancy: click coords ("
        TraceD  sc, R8
        TraceK  sc, ", "
        TraceD  sc, R9
        TraceK  sc, ") OSU"
        TraceNL sc

        SUB     R8, R8, R6
        CMP     R8, #&100000
        MOVGT   R8, #&100000
        SUB     R9, R9, R7
        CMP     R9, #&100000
        MOVGT   R9, #&100000
; (R8, R9) = offset to caret (OSU)

        TraceK  sc, "findcaretx0y0_fancy: click coords ("
        TraceD  sc, R8
        TraceK  sc, ", "
        TraceD  sc, R9
        TraceK  sc, ") OSU"
        TraceNL sc

        ;First get the index and x offset of the caret
        [       outlinefont
        TST     R1, #if_fancyfont
        LDREQ   R3, systemfont
        MOVNE   R3, R1, LSR #ib_fontno  ;get the correct font handle
        |
        MOV     R3, R1, LSR #ib_fontno  ;get the correct font handle
        ]
; R1 = icon flags
; R2 -> icon text
; R3 = handle for icon font

903 904
      [ UTF8
        Push    "R2"
905 906 907
      ]
      [ CnP
        MOV     R7, #nullptr
908
      ]
Neil Turton's avatar
Neil Turton committed
909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953
        BL      pushfontstring
; R1 -> font string
; R7 = stack change (word aligned)

        MOV     R0, R3
        MOV     R6, R1
; R0 = icon font handle
; R6 -> font string

        MOV     R1, R8
        MOV     R2, R9
; (R1, R2) = offset in OSU
        SWI     XFont_Converttopoints
; (R1, R2) = offset in mpt

        MOV     R3, R2
        MOV     R2, R1
        MOV     R1, R6
        TraceK  sc, "Font_FindCaret ("
        TraceS  sc, R1
        TraceK  sc, ", ("
        TraceD  sc, R2
        TraceK  sc, ", "
        TraceD  sc, R3
        TraceK  sc, ")mpt)"
        TraceNL sc
        SWI     XFont_FindCaret
        TraceError
        ADD     SP, SP, R7                      ; align the stack as required

        TraceK  sc, "Font_FindCaret -> terminator '"
        TracePC sc, R1
        TraceK  sc, "', (x, y) ("
        TraceD  sc, R2
        TraceK  sc, ", "
        TraceD  sc, R3
        TraceK  sc, "), printable count "
        TraceD  sc, R4
        TraceK  sc, ", index "
        TraceD  sc, R5
        TraceNL sc
; (R2, R3) = offset to caret (mpt)
; R4 = number of printable characters
; R5 = index into string

954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976
      [ UTF8
; R4 = number of *characters*, we want *byte* index into *original* string to put in R5

        Pull    "R7"        ; get pointer to original icon text pushed above
        Push    "R2"        ; we will be corrupting R2

        BL      read_current_alphabet
        MOVNE   R5, R4
        BNE     %FT01       ; in non-UTF-8 alphabets, 1 character = 1 byte

        MOV     R6, #bignum ; we're not expecting to reach the end anyway
        MOV     R2, R7

03      CMP     R4, #0
        BLE     %FT02
        BL      skipcharR
        SUB     R4, R4, #1
        B       %BT03

02      SUB     R5, R2, R7
01
        Pull    "R2"
      |
Neil Turton's avatar
Neil Turton committed
977 978
        MOV     R5, R4
; R5 = index into original string (which consisted of printable characters only)
979
      ]
Neil Turton's avatar
Neil Turton committed
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995

        MOV     R1, R2
        MOV     R2, R3
; (R1, R2) = offset in mpt
        SWI     XFont_ConverttoOS
        MOV     R8, R1
        MOV     R9, R2
; (R8, R9) = offset to caret (OSU)

        SWI     XFont_ReadInfo
; ((R1, R2), (R3, R4)) = bounding box (OSU)

        SUB     R4, R4, R2
; R4 = caret height

        ADD     R3, R9 ,R2              ; 320nk
Kevin Bracey's avatar
Kevin Bracey committed
996
	ADD	R2, R8, #2		; KJB bodgery
Neil Turton's avatar
Neil Turton committed
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029

; (R2, R3) = caret coords

        TraceK  sc, "findcaretx0y0_fancy: caret offset ("
        TraceD  sc, R2
        TraceK  sc, ", "
        TraceD  sc, R3
        TraceK  sc, ") OSU"
        TraceNL sc

        ;Restore handles etc and return (parameters are right for SetCaret
        ;       except that (R2, R3) are relative)
        Pull    R6-R9
        Pull    "R0-R1, PC"

;-----------------------------------------------------------------------------
; Find caret coords given position
;-----------------------------------------------------------------------------

setcaretcoords TraceL sc

; R0 = window handle
; R1 = icon handle
; R5 = position in string

        TraceK  sc, "setcaretcoords: w "
        TraceX  sc, R0
        TraceK  sc, ", i "
        TraceD  sc, R1
        TraceK  sc, ", index "
        TraceD  sc, R5
        TraceNL sc

Robert Sprowson's avatar
Robert Sprowson committed
1030
        AcceptLoosePointer_NegOrZero R0,nullptr
Ben Avison's avatar
Ben Avison committed
1031 1032 1033
        CMP     R0,#nullptr             ; can't do it if no icon
        MOVEQ   PC,LR
        CMP     R1,#0
Neil Turton's avatar
Neil Turton committed
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
        MOVLT   PC,LR

        Push    "LR"

        MOV     R14,#0                  ; we want coords given caret IS here
        STR     R14,hascaret            ; 0 ==> icon has the caret

        MOV     handle,R0
        BL      checkhandle
        Pull    "PC",VS

        Trace   sc, "setcaretcoords: index ", D, R5

        Push    "R0,R1,R5"
        LDR     R2,[handle,#w_icons]
        ;;ADD     R2,R2,#i_bbx0 NOP!
        ADD     R2,R2,R1,ASL #i_shift
; R2 -> bbox of icon

        LDMIA   R2!,{x0,y0,x1,y1}

; (R6, R7, R8, R9) = relative coords of icon
; R2 -> icon flags

        Push    "R0-R3"
        LDR     R1,[R2]
        LDR     R3,[R2,#8]
        TST     R1,#if_text
        TSTNE   R1,#if_indirected
        MOVEQ   R3,#0
        STR     R3,validationstring            ;320nk
; R1 = icon flags
; R3 -> validation string

        BL      getborder
        BL      adjustforborder
        Pull    "R0-R3"                 ; restore important registers

Kevin Bracey's avatar
Kevin Bracey committed
1072
        LDR     R1,[R2],#4
Neil Turton's avatar
Neil Turton committed
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
; R1 = icon flags
; R2 -> icon data

        TST     R1,#if_indirected
        LDRNE   R2,[R2]
; R2 -> text

        TraceK  sc, "setcaretcoords: flags "
        TraceX  sc, R1
        TraceK  sc, ", text "
        TraceS  sc, R2
        TraceK  sc, ", index "
        TraceD  sc, R5
        TraceNL sc

        STMIA   wsptr,{R1,R2}                   ; used later
        [       outlinefont
        TST     R1, #if_fancyfont
        MOVNE   R3, R1, LSR #ib_fontno  ; get the correct font handle
        LDREQ   R3, systemfont
        TEQEQ   R3, #0
        BNE     setcaretcoords_fancy
        |
        TST     R1, #if_fancyfont
        MOVNE   R3, R1, LSR #ib_fontno  ; get the correct font handle
        BNE     setcaretcoords_fancy
        ]

; work out R2,R3 = offset of caret from text origin

setcaretcoords_system TraceL sc

        Pull    "R0-R1,R5"

        Trace   sc, "setcaretcoords: index ", D, R5

        MOV     R2,R5,LSL #4
        MOV     R3,#-32
        MOV     R4,#40
        ORR     R4,R4,#crf_vdu5caret            ; normal caret
        B       addinorigin

setcaretcoords_fancy TraceL sc

; R1 = icon flags
; R2 -> string
; R3 = font handle to use for text

        Trace   sc, "setcaretcoords: index ", D, R5

        Push    "R3,R7"
1124 1125 1126
      [ CnP
        MOV     R7, #nullptr
      ]
Neil Turton's avatar
Neil Turton committed
1127 1128 1129 1130 1131 1132 1133 1134 1135
        BL      pushfontstring

; R1 -> string
; R7 = difference in stack (word aligned)

        ;;;LDR     R5,[sp,#3*4]            ; R5 = offset (grab it off the stack!)
        ;I think this is STILL in R5

        [       outlinefont
1136
        ;Convert the value in R5 (a count of PRINTABLE bytes) to a
Neil Turton's avatar
Neil Turton committed
1137 1138
        ;       string index

1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152
      [ UTF8
        ; R5 = bytes into original string
        ; We need R5 = bytes into pushed string
        ; In addition to skipping font-setting commands, we now also have to contend with cases
        ; where the same characters are different sizes in the two strings (ie when passworded)
        Push    "R2-R4,R6"
        ADD     R4, R2, R5              ; -> caret position in original string
        MOV     R3, #-1                 ; character count
        MOV     R6, #6                  ; not bothered about buffer space
        ; Count characters in original string
01      CMP     R2, R4
        BGT     %FT02                   ; past the caret point? don't count the partial character (matches font mgr)
        ADD     R3, R3, #1
        BEQ     %FT02                   ; at the caret point?
1153 1154 1155
        LDRB    R14, [R2]               ; reached terminator before byte count?
        CMP     R14, #' '               ;   yes, don't increment R3 any more (avoids infinite loop here in UTF8 case
        BLO     %FT02                   ;   and running off the top of the SVC stack below in non-UTF8 case)
1156 1157 1158 1159 1160 1161 1162 1163 1164 1165
        BL      skipcharR
        B       %BT01
02      ; Now have R3 = printable character count, find that byte index into pushed string
        LDRB    R2, alphabet
        MOV     R5, #0                  ; start at index 0
01      CMP     R3, #0
        BLE     %FT02                   ; break if we've got to the right position
        TEQ     R2, #ISOAlphabet_UTF8
        MOVNE   R4, #1                  ; \ non UTF-8 read
        LDRNEB  R6, [R1, R5]            ; /
Jeffrey Lee's avatar
Jeffrey Lee committed
1166
        MOVEQ   R4, #6                  ; \.
1167 1168 1169 1170
        ADDEQ   R6, R1, R5              ;  > UTF-8 read
        BLEQ    convert_UTF8_to_UCS4    ; /
        CMP     R6, #26                 ; font change command?
        ADDEQ   R5, R5, #2              ; skip 2 bytes of pushed string if so
1171 1172 1173 1174 1175 1176
      [ CnP
        CMP     R6, #19                 ; colour change command?
        ADDEQ   R5, R5, #8              ; skip 8 bytes of pushed string if so
;        CMP     R6, #19
        CMPNE   R6, #26
      ]
1177 1178 1179 1180 1181 1182 1183
        ADDNE   R5, R5, R4              ; else skip character in pushed string, and decrement character count
        SUBNE   R3, R3, #1
        B       %BT01
02      ; R5 now correctly set
        Pull    "R2-R4,R6"

      |
Neil Turton's avatar
Neil Turton committed
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211
        Push    "R2-R4"
; R5 = number of printable character required

        MOV     R3, #0
        MOV     R4, #0
; R3 = count of printable characters
; R4 = index into string

        B       setcaretcoords_reinit
setcaretcoords_loop

; R2 = character under consideration

        CMP     R3, R5
        BGE     setcaretcoords_exit
        TEQ     R2, #26
        ADDNE   R3, R3, #1 ;increment printable count
        ADDEQ   R4, R4, #2 ; } go to next relevant character
        ADDNE   R4, R4, #1 ; }
setcaretcoords_reinit
        LDRB    R2, [R1, R4]
        TEQ     R2, #0
        BNE     setcaretcoords_loop
setcaretcoords_exit
        MOV     R5, R4
; R5 = index of printable character in string

        Pull    "R2-R4"
1212
      ]
Neil Turton's avatar
Neil Turton committed
1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239

        Trace   sc, "setcaretcoords: an index now: ", D, R5
        ]
        MOV     R2,#bignum
        MOV     R3,#bignum
        MOV     R4,#-1
        BL      myFont_StringWidth
;        Trace   nk, "setcaret, width of string: ",D,R2
        ADD     SP, SP, R7              ; very important!
        Pull    "R3,R7"
; R3 = icon font handle

        MOVVC   R1,R2                   ; x offset
        SWIVC   XFont_ConverttoOS       ; (OS coords)

        Push    "R1"                    ; x offset
        ;;LDRVCB  R0,[wsptr,#3]     ??  ; R0 = top byte of flags
        MOVVC   R0, R3                  ; get the right font for this icon
        SWIVC   XFont_ReadInfo          ; get bounding box
        TraceError sc

        MOVVC   R3,R2                   ; R3 = y coord (at bottom)
        SUBVC   R4,R4,R2                ; R4 = height (OS coords)
        Pull    "R2"                    ; R2 = x offset
        ;;STRVS   R0,[sp] ?? don't corrupt stacked window handle
        Pull    "R0-R1,R5"              ; window/icon handles & offset

Kevin Bracey's avatar
Kevin Bracey committed
1240 1241
	ADD	R2,R2,#2

Neil Turton's avatar
Neil Turton committed
1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283
addinorigin TraceL sc

        Trace   sc, "setcaretcoords: index ", D, R5

        Push    "R0-R5"                 ; R2,R3 are relative coords
        STR     R2,caretx
        MOV     R14,#0
        STR     R14,hascaret            ; caret is definitely here

        LDMIA   wsptr,{R1,R2}           ; icon flags/text ptr
        BL      findtextorigin
        Pull    "R0-R3"

        Push    "r0"
        LDR     r0,writeabledir
        LDR     r14,[wsptr]
        TST     r14,#if_numeric
        MOVNE   r0,#0
        CMP     r0,#0
        Pull    "r0"

        ADDEQ   R2,cx1,R2               ; add in origin
        SUBNE   r14,cx1,x0
        SUBNE   r14,x1,r14
        SUBNE   r2,r14,r2

        ADD     R3,cy1,R3

        Pull    "R4-R5,LR"
        B       shrinkcaret             ; ensure caret is within icon


;;----------------------------------------------------------------------------
;; myFont_StringWidth
;; Entry and Exit as Font_StringWidth SWI
;;----------------------------------------------------------------------------

myFont_StringWidth
        Push    "R6,R7,lr"
        MOV     R7,R5
        MOV     R4,R3
        MOV     R3,R2
1284 1285 1286 1287 1288 1289
        [ true
        LDR     R2,writeabledir ;
        TEQ     R2,#0           ; This bit isn't ideal, but this stuff will all have to
        MOV     R2,#128         ; be rewritten anyway to cope with kerning
        ORRNE   R2,R2,#1<<10    ;
        |
Neil Turton's avatar
Neil Turton committed
1290
        MOV     R2,#128
1291
        ]
Neil Turton's avatar
Neil Turton committed
1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321
        SWI     XFont_ScanString
        MOV     R2,R3
        MOV     R3,R4
        Pull    "R6,R7,PC"


;;----------------------------------------------------------------------------
;; Wimp_ProcessKey
;; Entry:  R0 = character to process
;;         [caretdata] indicates position of caret
;;         [hotkeyptr] indicates how far down the chain we have gone
;; Exit:   R0 = action (as returned from Wimp_Poll)
;;         if R0 <> 0, the key was not accepted

;; The key is passed first to the input focus owner,
;;                   then to any windows with wf_grabkeys set
;; If not claimed by anybody, and caret is inside a writable icon,
;;                   then soft key expansion is performed

;;----------------------------------------------------------------------------

SWIWimp_ProcessKey
        MyEntry "ProcessKey"
        MOV     R6,R0                   ; R6 = key code on entry
        BL      int_processkey
        B       ExitWimp

int_processkey
        Push    "R1-R6,handle,LR"

1322 1323 1324
        Debug   key,"ProcessKey:",R6

      [ :LNOT: UTF8
Neil Turton's avatar
Neil Turton committed
1325 1326
        ADR     R14,caretdata
        LDMIA   R14,{R0-R5}
1327
      ]  ; not needed, because we won't be calling WriteableKey directly any more
Neil Turton's avatar
Neil Turton committed
1328 1329

        LDR     R14,singletaskhandle    ; don't muck about if single task
Ben Avison's avatar
Ben Avison committed
1330 1331
        CMP     R14,#nullptr
        BNE     defaultkey
Neil Turton's avatar
Neil Turton committed
1332 1333 1334 1335 1336

        LDR     R14,hotkeyptr
        Debug   key,"HotKeyPtr",R14

        CMP     R14,#0
1337
        BGT     sendhotkey              ; try hot keys if hotkeyptr is already set up
Neil Turton's avatar
Neil Turton committed
1338

1339 1340 1341 1342 1343
      [ true ; BJGA bugfix: don't crash if lowest iconised window calls Wimp_ProcessKey
        CMP     R14, #nullptr
        BEQ     defaultkey
      ]

1344 1345 1346 1347 1348 1349
      [ UTF8
        ; No Key_Pressed/ProcessKey sequence currently active => task is initiating keypress
        ; We now need to cache these, and let the trykeys code validate them during Wimp_Poll
        ; This also provides the advantage that Wimp_ProcessKey 13 can activate writable menu items at last!
        CMP     R6, #0
        CMPNE   R6, #&100
Ben Avison's avatar
Ben Avison committed
1350 1351 1352 1353
        MOVLO   R0, #1
        MOVHS   R0, #2
        ANDHS   R5, R6, #&FF
        MOVHS   R6, #0
1354 1355 1356 1357 1358 1359
        ; R0 = number of bytes to insert into keyprocess_buffer
        ; R6 = first byte
        ; R5 = second byte (if applicable)
        LDRB    R3, keyprocess_buflen
        RSB     R4, R3, #?keyprocess_buffer  ; R4 = space in buffer
        CMP     R4, R0
Ben Avison's avatar
Ben Avison committed
1360
        Pull    "R1-R6,handle,PC", LO   ; bail out if it won't fit
1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372

        ADR     R4, keyprocess_buffer
        ADD     R4, R4, R3              ; -> position to insert byte(s) at
        TEQ     R0, #2
        STRB    R6, [R4], #1            ; insert byte(s)
        STREQB  R5, [R4], #1
        ADD     R3, R3, R0
        STRB    R3, keyprocess_buflen   ; update byte count
        Pull    "R1-R6,handle,PC"

      |

Ben Avison's avatar
Ben Avison committed
1373 1374
        MOV     handle,R0
        CMP     handle,#nullptr
Neil Turton's avatar
Neil Turton committed
1375 1376
        BL      topmost_window
        STR     R0,hotkeyptr
Ben Avison's avatar
Ben Avison committed
1377
        BEQ     sendhotkey              ; if no input focus, just try hot keys
Neil Turton's avatar
Neil Turton committed
1378

Ben Avison's avatar
Ben Avison committed
1379 1380
        CMP     R1,#0
        BLT     sendkey                 ; not in a writable icon
Neil Turton's avatar
Neil Turton committed
1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394

        MOV     R0,handle
        BL      WriteableKey            ; R0-R5 set up on entry
        TEQ     R0,#No_Reason
        Pull    "R1-R6,handle,PC",EQ    ; done

        Debug   key,"Writable icon returned reason",R0

        TEQ     R0,#Key_Pressed
        TEQNE   R0,#Key_PressedOldData
        LDREQ   handle,caretdata        ; handle = (rel) input focus window
        BEQ     sendkey
                                        ; NB: menu icon CR comes here
                                        ; this is wrong, but hard to fix
1395
      ]
Neil Turton's avatar
Neil Turton committed
1396 1397 1398 1399 1400 1401 1402
sendhotkey

; Check the window's still around and open

        LDR     handle,hotkeyptr
        BL      checkhandle
        BVS     %FT01
1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415
      [ ChildWindows
        ; check that the window *and* all the window's ancestors are still open
        MOV     R0, handle
00
        LDR     R14, [R0, #w_flags]
        TST     R14, #ws_open
        BEQ     %FT01

        LDR     R0, [R0, #w_parent]
        CMP     R0, #nullptr
        BEQ     %FT02
        B       %BT00
      |
Neil Turton's avatar
Neil Turton committed
1416 1417 1418
        LDR     R14,[handle,#w_flags]
        TST     R14,#ws_open
        BNE     %FT02
1419
      ]
Neil Turton's avatar
Neil Turton committed
1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435
01

; 'Next' hotkey window disappeared or is closed so start from the top again

        BL      topmost_window
        STR     R0,hotkeyptr

; Just in case there're no windows (arrrrggghhh!)

        TEQ     R0,#0
        BEQ     defaultkey
        Abs     handle,R0
02

; Drop through the list of windows, checking for grabkey windows.

1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455
      [ ChildWindows

        MOV     R1, handle
03
        LDR     R14, [R1, #w_flags]
        TST     R14, #wf_grabkeys
        BNE     %FT04 ; found the next grabkey window!
        BL      hotkey_nextwindow
        BNE     %BT03
        BEQ     defaultkey ; done all windows!
04
        Rel     handle, R1
; Now find hotkeyptr for next time
        BL      hotkey_nextwindow
        MOVEQ   R2, #nullptr
        Rel     R2, R1, NE
        STR     R2, hotkeyptr

      |

Neil Turton's avatar
Neil Turton committed
1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471
        ADD     R3,handle,#w_active_link
03
        LDR     R2,[R3,#ll_forwards]
        CMP     R2,#nullptr
        BEQ     defaultkey              ; We've run out of windows
        LDR     R14,[R3,#w_flags-w_active_link]
        TST     R14,#wf_grabkeys
        MOVEQ   R3,R2
        BEQ     %BT03
        SUB     handle,R3,#w_active_link
        Rel     handle,handle

; Set hotkeyptr to next window to try

        LDR     R14,[R2,#ll_forwards]
        CMP     R14,#nullptr
1472 1473 1474
      [ true ; BJGA bugfix: don't crash if lowest iconised window calls Wimp_ProcessKey
        MOVEQ   R2,#nullptr
      |
Neil Turton's avatar
Neil Turton committed
1475
        MOVEQ   R2,#0                   ; Run out of windows
1476
      ]
Neil Turton's avatar
Neil Turton committed
1477 1478 1479 1480
        SUBNE   R2,R2,#w_active_link
        Rel     R2,R2,NE
        STR     R2,hotkeyptr

1481 1482
      ]

1483 1484 1485
      [ UTF8
        ADRL    R14, savedcaretdata
      |
Neil Turton's avatar
Neil Turton committed
1486 1487 1488 1489
sendkey
        TEQ     R0,#Key_PressedOldData
        ADREQL  R14,savedcaretdata
        ADRNE   R14,caretdata
1490
      ]
Neil Turton's avatar
Neil Turton committed
1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504

        LDMIA   R14,{R0-R5}             ; R6 already set up
        Push    "R0-R6"
        MOV     R1,sp
        MOV     R2,handle               ; send to input focus/grab window
        MOV     R0,#Key_Pressed

        Debug   key,"SendKey: handle",R2

        BL      int_sendmessage_fromwimp
        ADD     sp,sp,#7*4

        Pull    "R1-R6,handle,PC"

1505 1506 1507 1508
      [ ChildWindows
hotkey_nextwindow
; Entry: R1 = absolute window handle
; Exit:  NE => R1 = next window to consider (down/across/up the window tree)
1509 1510
;        EQ => no more windows (R1 corrupted)
;        R2 always corrupted
1511
        Entry
1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531
        ; First look for a child of the last window
        LDR     R2, [R1, #w_children + lh_forwards]
        LDR     R14, [R2, #ll_forwards]
        CMP     R14, #nullptr
        SUBNE   R1, R2, #w_active_link
        EXIT    NE
        ; Then try a sibling
01      LDR     R2, [R1, #w_active_link + ll_forwards]
        LDR     R14, [R2, #ll_forwards]
        CMP     R14, #nullptr
        SUBNE   R1, R2, #w_active_link
        EXIT    NE
        ; Then try aunts, great-aunts and so on
        LDR     R1, [R1, #w_parent]
        CMP     R1, #nullptr
        BNE     %BT01
        ; Run out of ancestors - exit with Z set
        EXIT
      ]

Neil Turton's avatar
Neil Turton committed
1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542
;..............................................................................

; not recognised by caret owner, or any hot-key handlers
; In    R6 = key code

defaultkey
        Debug   key,"DefaultKey: code",R6

        MOV     R14,#0
        STR     R14,hotkeyptr           ; reached the end of the road!

Neil Turton's avatar
Neil Turton committed
1543 1544
 [ :LNOT: DisableShiftF12

Neil Turton's avatar
Neil Turton committed
1545 1546 1547 1548 1549 1550 1551 1552
; shift+f12 => toggle iconbar between front and back
; when at front, wf_backwindow is unset; when at back, it is set

        LDR    R14,=&1DC                ; shift+f12
        TEQ     R6,R14
        BNE     %FT01

        LDR     handle,iconbarhandle
Ben Avison's avatar
Ben Avison committed
1553 1554
        CMP     handle,#nullptr
        BEQ     %FT01
Neil Turton's avatar
Neil Turton committed
1555 1556

        BL      checkhandle             ; handle -> window block
1557
      [ PoppingIconBar :LAND: :LNOT: OldStyleIconBar
1558 1559 1560 1561 1562 1563 1564 1565
        LDRVC   R14, iconbar_pop_state
        TEQ     R14, #pop_Back
        TEQNE   R14, #pop_Delaying
        MOVEQ   R14, #pop_Front2
        MOVNE   R14, #pop_Back
        STRVC   R14, iconbar_pop_state
        LDRVC   R14, [handle, #w_flags]
      |
Neil Turton's avatar
Neil Turton committed
1566 1567 1568
        BLVC    calc_w_status           ; set up flag word
        LDRVC   R14,[handle,#w_flags]
        TSTVC   R14,#ws_top             ; is the window covered?
1569
      ]
Neil Turton's avatar
Neil Turton committed
1570 1571 1572 1573 1574 1575
        BICEQ   R14,R14,#wf_backwindow  ; not backwindow if coming to front
        ORRNE   R14,R14,#wf_backwindow  ; backwindow if going to back
        STRVC   R14,[handle,#w_flags]
        ADDVC   R14,handle,#w_wax0
        LDMVCIA R14,{R0-R3,R4,R5}
        MOVEQ   R6,#-1                  ; EQ => bring window to front
1576 1577 1578
 [ HideIconBar
        MOVNE   R6,#-3                  ; NE => send to back
 |
Neil Turton's avatar
Neil Turton committed
1579
        MOVNE   R6,#-2                  ; NE => send to back
1580
 ]
Neil Turton's avatar
Neil Turton committed
1581 1582 1583 1584 1585 1586 1587 1588 1589 1590
        Push    "R0-R6,R7-R11"
        LDRVC   R14,iconbarhandle       ; relative window handle
        Push    "R14"
        MOVVC   userblk,sp
        BLVC    int_open_window         ; this corrupts all registers!
        ADD     sp,sp,#8*4
        Pull    "R7-R11"

        Pull    "R1-R6,handle,PC"
01
Neil Turton's avatar
Neil Turton committed
1591
 ]
Neil Turton's avatar
Neil Turton committed
1592 1593 1594 1595

; if caret is in a writable icon, expand soft key

        LDR     R14,caretdata+0         ; all we can do now is fn key expansion
Ben Avison's avatar
Ben Avison committed
1596 1597 1598 1599 1600 1601 1602 1603
        CMP     R14,#nullptr            ; (if the caret is in a writable icon)
        BEQ     %FT01
        LDR     R14,caretdata+4
        CMP     R14,#0
        BGE     %FT02
01
        Pull    "R1-R6,handle,PC"
02
Neil Turton's avatar
Neil Turton committed
1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636
fnkeynamelen    *       8               ; must be a multiple of 4
fnkeyexplen     *       256             ; must be a multiple of 4

        SUBS    R14,R6,#&180
        BCC     notfnkey
        CMP     R14,#10                 ; f0-f9
        BCC     %FT01
        SUBS    R14,R14,#&1CA-&180
        BCC     notfnkey
        CMP     R14,#3                   ; f10-f12
        BCS     notfnkey
        ADD     R14,R14,#10
01
; R14 = function key code (0..12)

        SUB     sp,sp,#fnkeynamelen
        MOV     R0,R14
        MOV     R1,sp
        LDR     R14,keyd                ; R14 = "Key$"
        STR     R14,[R1],#4
        MOV     R2,#fnkeynamelen-4
        SWI     XOS_ConvertCardinal1

        MOVVC   R0,sp
        SUB     sp,sp,#fnkeyexplen
        MOV     R1,sp
        MOV     R2,#fnkeyexplen
        MOV     R3,#0
        MOV     R4,#3
        SWIVC   XOS_ReadVarVal
        BVS     %FT99                   ; no function key string

        MOV     R1,sp
1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661
      [ UTF8
        ; Again, this now needs to be fed through the cacheing and validating routines in trykeys
        ; This is done by copying into keystring_buffer, but substituting each null byte with two null bytes
        TEQ     R2, #0
        BEQ     %FT99
        ADD     R2, R1, R2              ; end of source
        ADR     R3, keystring_buffer    ; start of dest buffer
        ADD     R4, R3, #?keystring_buffer ; end of dest buffer
01      LDRB    R0, [R1], #1
        TEQ     R0, #0
        MOVEQ   R0, #&100               ; STRBs the same as 0, but flagged as first of two
02      STRB    R0, [R3], #1
        CMP     R3, R4
        BGE     %FT03                   ; break if we reach the end of dest buffer
        TEQ     R0, #&100
        MOVEQ   R0, #0
        BEQ     %BT02                   ; if first of two, jump back into middle of loop for next byte
        CMP     R1, R2
        BLT     %BT01                   ; loop if there's still stuff left

03      ADR     R14, keystring_buffer
        SUB     R3, R3, R14             ; number of bytes put into keystring_buffer
        STRB    R3, keystring_buflen

      |
Neil Turton's avatar
Neil Turton committed
1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695
01
        TEQ     R2,#0
        BEQ     %FT99
        LDRB    R6,[R1],#1
        Debug   val,"r0,r1,r2",r0,r1,r2
        Push    "R0,R1,R2"

        Debug   val,"R13 (1)",R13
        Debug   val,"Next key is ",r6

        BL      go_writeablekey
        Debug   val,"R0 on exit is ",r0
        TEQ     R0,#Key_Pressed         ; should this be passed back?
        ADREQ   R14,caretdata
        ADRNEL  R14,savedcaretdata
        TEQNE   R0,#Key_PressedOldData
      [ debugval
        BNE    %FT89
        Debug  val,"EQ !!!"
89
      ]
        LDMEQIA R14,{R0-R5}             ; R6 already set up

        Push    "R0-R6"
        MOVEQ   R1,sp
        MOVEQ   R2,R0                   ; send to input focus window
        MOVEQ   R0,#Key_Pressed
        BLEQ    int_sendmessage_fromwimp
        ADD     sp,sp,#7*4

        Debug   val,"R13 (2)",R13
        Pull    "R0,R1,R2"
        SUB     R2,R2,#1
        B       %BT01
1696 1697

      ]
Neil Turton's avatar
Neil Turton committed
1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710
99
        SUBS    R0,R0,R0                ; R0=0, V clear (ignore errors)
        ADD     sp,sp,#fnkeyexplen + fnkeynamelen
notfnkey
        Pull    "R1-R6,handle,PC"

keyd    DCB     "Key$"


;-----------------------------------------------------------------------------
; Wimp_Poll entry to process key-press (caret is inside a writable icon)
; Entry:  R0,R1 = window/icon handle
;         R5 = index into string
1711
;         R6 = key pressed (internal Wimp keycode)
Neil Turton's avatar
Neil Turton committed
1712 1713 1714 1715 1716 1717 1718 1719
;-----------------------------------------------------------------------------