; 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. ; ;;---------------------------------------------------------------------------- ;; Create/Delete icon on icon bar ;; userblk --> user's original block ;; handle = -1 ==> right side from left edge with priority 0 ;; -2 ==> left side from right edge with priority 0 ;; -3 ==> to left of existing icon in R0 Wimp 2.21 onwards ;; - or extreme left if R0 < 0 ;; -4 ==> to right of existing icon in R0 Wimp 2.21 onwards ;; - or extreme right if R0 < 0 ;; -5 ==> left side from left edge with R0 = priority 2.73 onwards ;; -6 ==> left side from right edge with R0 = priority 2.73 onwards ;; -7 ==> right side from left edge with R0 = priority 2.73 onwards ;; -8 ==> right side from right edge with R0 = priority 2.73 onwards ;; R0 = handle of icon to open next to (if used) ;; if icon not found, move to extreme left/right of iconbar ;;---------------------------------------------------------------------------- icbf_rightside * 1 :SHL: 0 ; 1 => start from right, else left icbf_r0handle * 1 :SHL: 1 ; 1 => R0 = icon handle icbf_r0priority * 1 :SHL: 2 ; 1 => R0 = priority level icbf_fromedge * 1 :SHL: 7 ; 1 => scan from edge, else middle ; MUST be highest-order bit iconbartab DCB icbf_rightside ; right, from left , priority 0 DCB 0 ; left , from right, priority 0 DCB icbf_fromedge :OR: icbf_r0handle ; left , from left , r0 handle DCB icbf_rightside :OR: icbf_fromedge :OR: icbf_r0handle ; right, from right, r0 handle DCB icbf_fromedge :OR: icbf_r0priority ; left , from left , r0 priority DCB icbf_r0priority ; left , from right, r0 priority DCB icbf_rightside :OR: icbf_r0priority ; right, from left, r0 priority DCB icbf_rightside :OR: icbf_fromedge :OR: icbf_r0priority ; right, from right, r0 priority iconbartabsize * .-iconbartab ALIGN addtoiconbar ; work out whereabouts in the list to put the new icon CMN handle, #iconbartabsize MyXError WimpBadHandle, MI, L BVS ExitWimp ADRL R14,iconbartab-1 LDRB R14,[R14,-handle] ; R14 = flag byte TST R14,#icbf_rightside ADREQ R7,iconbarleft ADRNE R7,iconbarright TST R14,#icbf_r0handle BNE gofindit TST R14,#icbf_r0priority MOVEQ R0,#0 ; default is priority 0 addwithpriority ; R0 = priority of icon to add ADD R1,R7,#icd_list-icb_link 01 LDR R4,[R1,#icb_link] ; R4 -> next icon block CMP R4,#nullptr BEQ %FT02 LDR R3,[R4,#icb_priority] Debug icb,"Iconblk, priority, newpriority:",R4,R3,R0 CMP R0,R3 CMPEQ R14,#icbf_fromedge ; icbf_fromedge is highest order bit MOVLT R1,R4 BLT %BT01 02 ; now r1 -> block before one to insert B addtoR1 MakeErrorBlock WimpBadIconHandle gofindit MOVS R4,R0 ; R4 = icon handle to open next to MOVMI R0,#WimpPriority_Maximum BMI addwithpriority MOV R3,R7 ; R3 -> default end to add to BL findicon ; R1 -> previous, R2 -> current, R7 -> left/right head pointer MyXError WimpBadIconHandle,NE BVS ExitWimp LDR R0,[R2,#icb_priority] ; inherit matched icon's priority TEQ R7,R3 ; if not same as default end, LDRNE R1,[R1,#icb_link] ; move in to next icon ; now drop through to addtoR1 ; in R0 = priority to give to the new icon ; R1 -> block prior to where the new one is going ; R7 -> iconbar left/right chain head addtoR1 Push "R0" ; save priority level ; create iconbar window if necessary LDR handle,iconbarhandle BL checkhandle ; V set ==> not created yet BVC %FT01 ; skip this if already present ; Push "R2,R3,R7,userblk" ; iconbar ptr, original R1 from user ; ADR R0,wn_iconbar MOV R2,#0 ; no indirected icons allowed! MOV R3,#0 BL createsystemp ; R0,handle = window rel/abs handles STRVC R0,iconbarhandle LDRVC R14,[handle,#w_way1] LDRVC R2,[handle,#w_way0] SUBVC R14,R14,R2 STRVC R14,iconbarheight ; used later [ HideIconBar MOVVC R2, #-3 | LDRVC R2,iconbarhandle ; open at same height ] BLVC openiconbar ; Pull "R2,R3,R7,userblk" BVS %FT99 01 ; create icon and associated block (R0 is still stacked!) Push "R1,cx0,cy0,cx1,cy1,x0,y0,x1,y1" ; LDMIA userblk,{R0,cx0,cy0,cx1,cy1,x0,y0,x1,y1} Push "R0,cx0,cy0,cx1,cy1,x0,y0,x1,y1" MOV userblk,sp ; copy icon onto the stack ; 322nk store default width SUB R14,cx1,cx0 STR R14,tempworkspace+16 ; ; 320nk, adjust size of icon if text too big in current font TST x0,#if_text ; x0 is flags BEQ %FT10 Push "R0-R2" ADD R1,sp,#36 ; 12 (Push) +4 (icon block) +20 (icon data) TST x0,#if_indirected BEQ %FT05 ; if indirected can be turned off with validation X Push R3 LDR R3,[R1,#4] MOV R2,#WimpValidation_NoAuto BL findcommand Pull R3 BEQ %FT9 ; found X LDR R1,[R1] 05 MOV R0,#1 MOV R2,#0 ; don't stop! SWI XWimp_TextOp ; R0 now has width LDR R14,dx ADD R0,R0,R14, LSL #1 ; add on 2 dx for luck SUB R1,cx1,cx0 SUBS R0,R0,R1 Pull "R0-R2",MI BMI %FT10 ADD cx1,cx1, R0 STR cx1,[sp,#24] 09 Pull "R0-R2" 10 BL int_create_icon ; on exit R0 = icon handle ADD sp,sp,#4+i_size ; correct stack Pull "R1,cx0,cy0,cx1,cy1,x0,y0,x1,y1" ; Pull "R4" ; R4 = priority to set ; Push "R0" ; used later MOVVC R3,#icb_size BLVC claimblock BVS %FT99 ; couldn't create block ; link new block into chain, and initialise various fields ; in [sp] = icon handle ; R1 -> block after which R2 is to be linked ; R2 -> new icon block ; R4 = priority to set ; R7 -> head of appropriate chain (left or right) STR R4,[R2,#icb_priority] ; LDR R14,[R1,#icb_link] ; don't assume link is null STR R14,[R2,#icb_link] STR R2,[R1,#icb_link] ; LDR R14,[sp,#0*4] ; R14 = icon handle STR R14,[R2,#icb_iconhandle] ; LDR R14,tempworkspace+16 STR R14,[R2,#icb_defwidth] LDR R14,taskhandle ; R14 = task handle STR R14,[R2,#icb_taskhandle] ; NB no version bits internally ; BL recalcposns 99 STRVS R0,[sp,#0*4] LDR R14,taskhandle Debug swp,"iconbar task handle is ",R14 LDR R14,[wsptr,R14] LDR R0,[R14,#task_priority] ORR R0,R0,#priority_iconbar STR R0,[R14,#task_priority] Debug swp,"Priority (ICONBAR ICON) ",R0 Pull "R0" B ExitWimp wn_iconbar DCB "iconbar",0 ; must be word-aligned ALIGN ; ; Entry: R0 --> window identifier ; R2,R3 --> indirected icon data start/end ; Exit: R0,handle = handle of window (read from WindowManager:Templates) ; createsystemp Push "R1-R6,userblk,LR" ; LDMIA R0,{R4-R6} Push "R4-R6" ; Save window ident on stack ; ADR R1,wimptempfname BL int_open_template BVS %FT99 ; LDR R2,[sp,#12+1*4] ; 12 byte name, then R1-R6 LDR R3,[sp,#12+2*4] MOV R4,#0 ; no fancy fonts! MOV R5,sp ; R5 --> identifier MOV R6,#0 ; 1st entry MOV userblk,#-1 ; Check space reqd BL int_load_template ; Read template Debug systmpl,"Template buffer size, data size, count",R1,R2,R6 TEQ R6,#0 ; Any entries? MyXError WimpNoTemplate,EQ ; No then error MOVVC R3,R1 ; Size of scratch buffer reqd BLVC claimblock ; Claim from RMA MOVVS userblk,#0 ; No memory claimed if error MOVVC userblk,R2 ; Get-> claimed block LDRVC R2,[sp,#12+1*4] ; 12 byte name, then R1-R6 LDRVC R3,[sp,#12+2*4] MOVVC R4,#0 ; no fancy fonts! MOVVC R6,#0 ; search whole of index Debug systmpl,"Loading template to",userblk BLVC int_load_template MOVVC R14, #0 ; created window will be 'owned' by Wimp STRVC R14, createwindowtaskhandle BLVC int_create_window ; R0,handle = window handles (if V clr) MOV R14, #1 ; subsequent windows are 'owned' by their creators STR R14, createwindowtaskhandle MOVVC R14,#1 STRVC R14,[handle,#w_areaCBptr] ; use common sprite pool 98 SavePSR R14 Push "R0,R14" ; Save flags TEQ userblk,#0 MOVNE R2,userblk ; userblk --> window block MOVNE R0,#ModHandReason_Free Debug systmpl,"Freeing block",userblk BLNE XROS_Module BL int_close_template Pull "R0,R14" RestPSR R14,,f ; Restore V flag 99 ADD sp,sp,#12 ; lose copy of name Pull "R1-R6,userblk,PC" MakeErrorBlock WimpNoTemplate [ NewErrorSystem wimptempfname DCB "WindowManager:Templates",0 ; AMcC 18-Oct-94 was Template3D | wimptempfname DCB "WindowManager:Templates",0 ] ALIGN ; (Re)open iconbar in appropriate position for the current mode ; In R2 = handle of window to open iconbar behind ; Out handle -> window data of iconbar (ie. absolute handle) ASSERT handle = R10 ; we want to return this openiconbar Entry "R1-R9,R11" LDR R0,iconbarhandle CMP R0,#nullptr EXIT EQ MOV handle,R0 BL checkhandle EXIT VS ; try to keep things the same as before ; however, we must ensure that the extent is big enough for the OpenWindow ADR R14,scrx0 LDMIA R14,{cx0,cy0,cx1,cy1} ; always open iconbar at bottom LDR R14,iconbarheight ADD cy1,cy0,R14 [ ThreeDPatch LDR R14,ThreeDFlags TST R14,#ThreeDFlags_NoIconBarBorder MOVNE R14,#255 ; no border special value MOVEQ R14,#sc_black STRB R14,[handle,#w_tfcol] ; transfer border visual flag to window definition MOVNE R14,#0 ; no left/right border allowance MOVNE R11,#0 LDREQ R14,dx LDREQ R11,dy | LDR R14,dx LDR R11,dy ] ADD cx0,cx0,R14 SUB cx1,cx1,R14 ADD cy0,cy0,R11 ; cx0,cy0,cx1,cy1 = screen posn LDR x0,[handle,#w_wex0] ; try to keep extent the same SUB x1,cx1,cx0 ADD x1,x0,x1 ; x0,x1 = extent LDR R14,[handle,#w_wex1] CMP x1,R14 ; we need extent >= screen width MOVLT x1,R14 ; so the OpenWindow works ; ensure that the other variables are consistent with this new size STR x0,iconbarleft+icd_extent ; window version is the same STR x1,iconbarright+icd_extent STR x1,[handle,#w_wex1] ; NB: pixel aligned SUB R14,cx1,cx0 STR R14,iconbarleft+icd_widthoffset ; +width from left to right RSB R14,R14,#0 STR R14,iconbarright+icd_widthoffset ; -width from right to left LDR R14,iconbarleft+icd_width ADD R14,x0,R14 ; relative to extent STR R14,iconbarleft+icd_middle LDR R14,iconbarright+icd_width ; widths initialised before SUB R14,x1,R14 ; relative to extent STR R14,iconbarright+icd_middle LDR x0,[handle,#w_scx] ; keep same scroll offsets LDR y0,[handle,#w_scy] [ debugicb Push "cy0,cy1" LDR cy0,[handle,#w_wex0] LDR cy1,[handle,#w_wex1] Debug icb,"openic: iconbar =",cx0,cx1,x0, cy0,cy1 Pull "cy0,cy1" ] LDR R14,[sp, #1*4] ; R2 on entry = bhandle Push "R0,cx0,cy0,cx1,cy1,x0,y0,R14" MOV userblk,sp BL int_open_window ADD sp,sp,#u_ow1 EXIT ; ; Entry: R2 = icon handle ; it tries the filing system and utilities sections in turn ; removefromiconbar BL int_removefromiconbar B ExitWimp int_removefromiconbar Push "R1-R7,LR" ; Debug ic,"Remove from icon bar: R2 =",R2 ; ORR R0,R2,#msh_iconbar ; R0 = icon handle (+marker bit) BL byemessages ; delete relevant messages ; LDR handle,iconbarhandle BL checkhandle BLVC int_deleteicon ; no error if not found ; MOV R4,R2 ; R4 = icon handle BL findicon ; exit: R2 --> block (if found) ; LDREQ R14,[R2,#icb_link] ; remove from chain STREQ R14,[R1,#icb_link] MOVEQ R0,#ModHandReason_Free BLEQ XROS_Module ; BL recalcposns ; ignore errors from ROS_Module here ; LDR R5,iconbarleft+icd_list LDR R6,iconbarright+icd_list TST R5,R6 ; both negative? Pull "R1-R7,PC",PL ; LDR R0,iconbarhandle CMP R0,#nullptr MOVNE R14,#nullptr ; kill off iconbar if empty STRNE R14,iconbarhandle BLNE int_delete_window ; Pull "R1-R7,PC" ; ; Entry: R4 = icon handle ; Exit: found: Z set ; R1-->previous link ; R2-->icon block ; R7-->iconbarleft/right ; not found: Z unset ; findicon Push "LR" ; ADR R7,iconbarleft BL tryfindicon ADRNE R7,iconbarright BLNE tryfindicon ; Pull "PC" tryfindicon Push "LR" ADD R1,R7,#icd_list-icb_link 01 LDR R2,[R1,#icb_link] CMP R2,#nullptr BEQ %FT02 LDR R14,[R2,#icb_iconhandle] TEQ R14,R4 MOVNE R1,R2 BNE %BT01 ; Pull "PC" ; found (Z set) 02 TEQ R2,#0 Pull "PC" ; not found (Z unset) ; ; Recompute positions of icons (called from CreateIcon and DeleteIcon) ; In R7 -> icon data for appropriate side of icon bar ; handle -> window defn of iconbar (ie. absolute handle) ; recalcposns Push "R1-R9,userblk,LR" ; ADR R8,iconbarleft ; R8 --> other section TEQ R8,R7 ADREQ R8,iconbarright ; Push handle LDR handle,[handle,#w_icons] ; MOV x0,#0 LDR R1,[R7,#icd_list] 01 CMP R1,#nullptr LDRNE R2,[R1,#icb_iconhandle] ADDNE R14,handle,R2,LSL #i_shift LDRNE cx0,[R14,#i_bbx0] LDRNE cx1,[R14,#i_bbx1] SUBNE cx1,cx1,cx0 ADDNE x0,x0,#iconbargap ; allow for gap between icons ADDNE x0,x0,cx1 ; plus width of icon itself LDRNE R1,[R1,#icb_link] BNE %BT01 ; STR x0,[R7,#icd_width] ; Debug ic,"This/other side, width =",R7,R8,x0 ; ; decide if this will fit inside one screen-width ; LDR R0,iconbarleft + icd_width LDR R1,iconbarright+ icd_width ADD R1,R0,R1 ; total width of icons LDR cx1,iconbarleft + icd_widthoffset SUB cx1,cx1,#iconbarsepgap ; gap between left and right ; ; if it fits: start at the outside and go in ; otherwise: start at the inside and go out ; LDR R0,[R8,#icd_widthoffset] ; +- screenwidth CMP R1,cx1 BGT startinmiddle ; LDR R9,[R8,#icd_extent] ; other end ADD R9,R9,R0 ; must still be pixel-aligned STR R9,[R7,#icd_extent] CMP R0,#0 ; was that plus or minus? SUBPL R14,R9,x0 ADDMI R14,R9,x0 STR R14,[R7,#icd_middle] ; work back to middle Debug ic,"Unlimited: extent,middle =",R9,R14 B allocateicons startinmiddle CMP R0,#0 LDR R14,[R8,#icd_middle] ADDPL R14,R14,#iconbarsepgap SUBMI R14,R14,#iconbarsepgap STR R14,[R7,#icd_middle] ADDPL R9,R14,x0 SUBMI R9,R14,x0 STR R9,[R7,#icd_extent] Debug ic,"Limited: extent,middle =",R9,R14 ; ; R0 (bit 31) ==> direction to move in ; R7 --> data for this set of icons ; R8 --> data for the other set of icons ; R9 = start x-coord for icons ; allocateicons LDR R2,[R7,#icd_list] 01 CMP R2,#nullptr BEQ doneicons ; LDR R3,[R2,#icb_iconhandle] ADD R14,handle,R3,LSL #i_shift LDMIA R14,{R3,R4,R5,R6} SUB R5,R5,R3 ; width of icon ; CMP R0,#0 ; direction ADDMI R3,R9,#iconbargap ADDMI R5,R3,R5 MOVMI R9,R5 SUBPL R9,R9,#iconbargap SUBPL R3,R9,R5 MOVPL R5,R9 MOVPL R9,R3 STMIA R14,{R3,R4,R5,R6} ; LDR R2,[R2,#icb_link] B %BT01 ; ; reset window extent, and check whether we must scroll ; doneicons Pull handle ; LDR R14,iconbarleft + icd_extent LDR R0,dx_1 ; must be pixel-aligned BIC R14,R14,R0 STR R14,[handle,#w_wex0] ; poke direct! LDR R0,[handle,#w_scx] CMP R0,R14 MOVLT R0,R14 ; LDR R14,iconbarright+ icd_extent LDR R1,dx_1 ; must be pixel-aligned BIC R14,R14,R1 STR R14,[handle,#w_wex1] ; poke direct! LDR R1,iconbarright + icd_widthoffset ADD R14,R14,R1 CMP R0,R14 MOVGT R0,R14 ; ; Poke these directly to stop the Wimp attempting to do a block copy ; STR R0,[handle,#w_scx] ; poke direct! (pixel aligned) [ ChildWindows STR R0,[handle,#w_old_scx] ; also old position ] ; [ debugicb ADD R14,handle,#w_wax0 LDMIA R14,{cx0,cy0,cx1,cy1,x0,y0} LDR cy0,[handle,#w_wex0] LDR cy1,[handle,#w_wex1] Debug icb,"recalc: iconbar =",cx0,cx1,x0, cy0,cy1 ] ; MOV x0,#-bignum MOV y0,#-bignum MOV x1,#bignum MOV y1,#bignum BL int_force_redraw ; mark invalid ; Pull "R1-R9,userblk,PC" [ true resizeiconbaricons ; make sure widths of iconbar icons are ok in new font Push "R0-R5,R7,handle,userblk,lr" MOV R0,#0 STRB R0,iconbar_needs_rs LDR handle,iconbarhandle CMP handle,#nullptr Pull "R0-R5,R7,handle,userblk,PC",EQ Abs handle,handle LDR R5,[handle,#w_icons] LDR R3,[handle,#w_nicons] TEQ R3,#0 Pull "R0-R5,R7,handle,userblk,PC",EQ ; return if no icons LDR R4,taskhandle Push "R4" MOV R4,#0 resizeicons_loop BL findicon BNE resizeicons_next ; R2 -> icon block LDR R14,[R5,#i_flags] TST R14,#if_text BEQ resizeicons_next TST R14,#if_indirected ADD R1,R5,#i_data BEQ %FT05 LDR R1,[R1] LDR R0,[R2,#icb_taskhandle] CMP R0,#0 BMI %FT05 LDR R14,orig_applicationspacesize CMP R14,R1 BLHI mapslotinout ; so that indirected data is ok. Now R1-> text Push "R2,R3" MOV R2,#WimpValidation_NoAuto LDR R3,[R5,#i_data+4] ; validation string BL findcommand Pull "R2,R3" BEQ resizeicons_next 05 MOV R0,#1 Push "R2" MOV R2,#0 SWI XWimp_TextOp LDR R14,dx ADD R0,R0,R14, LSL #1 ; add on 2 dx for luck Pull "R2" LDR R1,[R2,#icb_defwidth] CMP R0,R1 MOVHI R1,R0 LDR R0,[R5,#i_bbx0] ADD R1,R0,R1 STR R1,[R5,#i_bbx1] ; update width if needed resizeicons_next SUBS R3,R3,#1 ADDNE R5,R5,#i_size ADDNE R4,R4,#1 BNE resizeicons_loop ADR R7,iconbarleft BL recalcposns ADR R7,iconbarright BL recalcposns ADR R7,iconbarleft BL recalcposns Pull "R0" CMP R0,#0 BLPL mapslotinout Pull "R0-R5,R7,handle,userblk,PC" mapslotinout Push "R0-R2,R14" LDR R1,taskhandle TEQ R0,R1 Pull "R0-R2,PC",EQ LDR R0,[R12,R1] ; task block TST R0,#&80000000 BNE %FT01 LDR R0,[R0,#task_slotptr] CMP R0,#nullptr BLNE mapout 01 Pull "R0" LDR R14,=&ffff AND R0,R0,R14 ; make sure internal t/h STR R0,taskhandle LDR R0,[R12,R0] TST R0,#&80000000 Pull "R1-R2,PC",NE LDR R0,[R0,#task_slotptr] CMP R0,#nullptr BLNE mapin Pull "R1-R2,PC" ] END