chiark / gitweb /
JPEG support and other fixes from Nick Clark
[ssr] / StraySrc / Libraries / Sapphire / s / viewer
1 ;
2 ; viewer.s
3 ;
4 ; Filer-like windows with re-arranging icons (MDW)
5 ;
6 ; © 1995-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sapphire library.
12 ;
13 ; Sapphire is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; Sapphire is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with Sapphire.  If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29                 GET     libs:header
30                 GET     libs:swis
31
32                 GET     libs:stream
33
34 ;----- External dependencies ------------------------------------------------
35
36                 GET     sapphire:akbd
37                 GET     sapphire:alloc
38                 GET     sapphire:divide
39                 GET     sapphire:drag
40                 GET     sapphire:fastMove
41                 GET     sapphire:msgs
42                 GET     sapphire:sapphire
43                 GET     sapphire:screen
44                 GET     sapphire:wimp
45                 GET     sapphire:win
46                 GET     sapphire:winUtils
47
48 ;----- Macros ---------------------------------------------------------------
49
50                 MACRO
51 $label          MSGB    $msg,$branch
52 $label          DCD     $msg
53                 B       $branch
54                 MEND
55
56 ;----- Main code ------------------------------------------------------------
57
58                 AREA    |Sapphire$$Code|,CODE,READONLY
59
60 ;----- Creating and deleting viewers ----------------------------------------
61
62 ; --- viewer_create ---
63 ;
64 ; On entry:     R0 == pointer to a viewer definition block
65 ;               R1 == pointer to a list
66 ;               R2 == sprite area for window
67 ;
68 ; On exit:      R0 == viewer handle
69 ;               May return an error
70 ;
71 ; Use:          Creates a viewer window.  The viewer definition block
72 ;               contains various interesting bits of information about the
73 ;               viewer which are likely to be known at assembly time:
74 ;
75 ;               (word)   address of a list manager definition block
76 ;               (word)   address of a shape handler function (or 0)
77 ;               (word)   standard width of icons
78 ;               (word)   standard height of icons
79 ;               (string) banner text message tag, or empty
80 ;
81 ;               The shape function is used to allow viewer icons to have a
82 ;               non-rectangular shape.  The function is called with a reason
83 ;               code in R0; entry and exit conditions depend on this:
84 ;
85 ;                                                       vwShape_size
86 ;               On entry
87 ;                 R1 == pointer to list item
88 ;                 R2 == standard width of icon
89 ;                 R3 == standard height of icon
90 ;
91 ;               On exit
92 ;                 R2 == width of this icon
93 ;                 R3 == height of this icon
94 ;
95 ;               Use
96 ;                 This routine is used to find the actual size of an icon.
97 ;                 The icons are aligned on a grid according to the largest
98 ;                 one: this routine is used to find out which one that is.
99 ;
100 ;                                                       vwShape_intersects
101 ;               On entry
102 ;                 R1 == pointer to list item
103 ;                 R2 == address of bounding box of this icon
104 ;                 R3 == address of bounding box to compare
105 ;
106 ;               On exit
107 ;                 CS if boxes intersect, else CC
108 ;
109 ;               Use
110 ;                 For detecting mouse clicks etc. on an icon.  viewer has
111 ;                 already ensured that the box in R3 intersects with the
112 ;                 bounding box, so for rectangular icons, you can just return
113 ;                 with C set always.  This entry is provided so that you
114 ;                 can check against the sprite and text of a text+sprite
115 ;                 icon separately.
116 ;
117 ;               More reason codes may be added later; it will always be
118 ;               sensible to return immediately preserving all registers and
119 ;               flags.
120
121                 EXPORT  viewer_create
122 viewer_create   ROUT
123
124                 STMFD   R13!,{R1-R5,R10,R14}    ;Save some registers
125
126                 ; --- Move arguments into other registers ---
127
128                 MOV     R5,R0                   ;Look after block def
129                 MOV     R4,R2                   ;And the sprite area
130
131                 ; --- Allocate a viewer block ---
132
133                 MOV     R0,#vw__size            ;Get the block size
134                 BL      alloc                   ;Allocate the memory
135                 BLCS    alloc_error             ;If it failed, get error
136                 BCS     %99viewer_create        ;And return to caller
137                 MOV     R10,R0                  ;Look after the pointer
138
139                 ; --- Fill in bits of the block ---
140
141                 STR     R1,[R10,#vw__list]      ;Store the list address
142                 LDMIA   R5!,{R0-R3}             ;Load regs from def block
143                 STR     R0,[R10,#vw__listDef]   ;Store list definition addr
144                 CMP     R1,#0                   ;Is the shape function 0?
145                 ADREQ   R1,vw__dummyShape       ;Yes -- use default one
146                 STR     R1,[R10,#vw__shape]     ;Store that away nicely
147                 ADD     R14,R10,#vw__stdDimens  ;Point to standard icon sz
148                 STMIA   R14,{R2,R3}             ;Store them away nicely
149                 LDRB    R0,[R5,#0]              ;Load first byte of banner
150                 CMP     R0,#0                   ;Is it actually defined?
151                 MOVNE   R0,R5                   ;Yes -- point to it then
152                 BLNE    msgs_lookup             ;And translate the tag
153                 STR     R0,[R10,#vw__banner]    ;Store that away nicely
154
155                 ; --- Now create a window ---
156
157                 MOV     R0,R11                  ;Copy definition to scratch
158                 ADR     R1,vw__windDef          ;Point to my definition
159                 MOV     R2,#88                  ;Size of window definition
160                 BL      fastMove                ;Copy the data over
161
162                 STR     R4,[R11,#64]            ;Store caller's sprite area
163                 ADD     R14,R10,#vw__title      ;Point to title buffer
164                 STR     R14,[R11,#72]           ;Save this in window block
165                 MOV     R1,R11                  ;Point to window definition
166                 SWI     XWimp_CreateWindow      ;Try to do that then
167                 BVS     %98viewer_create        ;If it failed, tidy up
168                 STR     R0,[R10,#vw__window]    ;Save the window handle
169
170                 ; --- Set up the event handler ---
171
172                 ADR     R1,vw__events           ;Point to event handler
173                 MOV     R2,R10                  ;Use viewer handle as R10
174                 MOV     R3,R12                  ;Pass workspace in R12 (*)
175                 BL      win_eventHandler        ;Set up the event handler
176                 BVS     %97viewer_create        ;If it failed, tidy up
177
178                 ; --- Fix up rest of viewer block ---
179
180                 MOV     R14,#0                  ;No handler defined yet
181                 STR     R14,[R10,#vw__handler]  ;Save that in my block
182                 STR     R14,[R10,#vw__flags]    ;Clear the flags too
183                 STR     R14,[R10,#vw__tempSel]  ;No temporary selection
184
185                 ; --- Now return to caller ---
186
187                 MOV     R0,R10                  ;Get the viewer handle
188                 LDMFD   R13!,{R1-R5,R10,R14}    ;Restore registers
189                 BICS    PC,R14,#V_flag          ;And return to caller
190
191                 ; --- Handle minor mishaps ---
192
193 97viewer_create MOV     R5,R0                   ;Look after error pointer
194                 ADD     R1,R10,#vw__window      ;Point to window handle
195                 SWI     Wimp_DeleteWindow       ;Destroy the window
196                 MOV     R0,R5                   ;And get the error back
197
198 98viewer_create MOV     R5,R0                   ;Look after error pointer
199                 MOV     R0,R10                  ;Point to viewer block
200                 BL      free                    ;Free the block up
201                 MOV     R0,R5                   ;And get the error back
202
203 99viewer_create ADD     R2,R0,#4                ;Point to error text
204                 ADR     R0,vw__createErr        ;Point to error skeleton
205                 BL      msgs_error              ;Translate and substitute
206                 LDMFD   R13!,{R1-R5,R10,R14}    ;Restore registers
207                 ORRS    PC,R14,#V_flag          ;And return the error
208
209 vw__dummyShape  ORRS    PC,R14,#C_flag          ;Dummy shape function
210
211 vw__createErr   DCD     1
212                 DCB     "vwCRTE",0
213
214 vw__windDef     DCD     0,0,0,0
215                 DCD     0,0
216                 DCD     0
217                 DCD     &BF000002
218                 DCB     7,2,7,1,3,1,12,0
219                 DCD     0,0,0,0
220                 DCD     &1700013D
221                 DCD     &0000A000
222                 DCD     1
223                 DCW     1,0
224                 DCD     0,-1,256
225                 DCD     0
226
227                 LTORG
228
229 ; --- viewer_destroy ---
230 ;
231 ; On entry:     R0 == viewer handle
232 ;
233 ; On exit:      --
234 ;
235 ; Use:          Destroys a viewer, removing it from the screen etc.
236
237                 EXPORT  viewer_destroy
238 viewer_destroy  ROUT
239
240                 STMFD   R13!,{R0,R1,R10,R14}    ;Save some registers
241                 MOV     R10,R0                  ;Look after the handle
242                 LDR     R0,[R10,#vw__window]    ;Load the window handle
243                 BL      win_windowDeleted       ;Say it's been deleted
244                 ADD     R1,R10,#vw__window      ;Find the window handle
245                 SWI     Wimp_DeleteWindow       ;Destroy the window
246                 MOV     R0,R10                  ;Point to the viewer block
247                 BL      free                    ;Release the memory
248                 LDMFD   R13!,{R0,R1,R10,PC}^    ;And return to caller
249
250                 LTORG
251
252 ;----- Opening and closing --------------------------------------------------
253
254 ; --- viewer_open ---
255 ;
256 ; On entry:     R0 == viewer handle
257 ;               R1 == opening style
258 ;               R2,R3 == extra arguments
259 ;
260 ; On exit:      --
261 ;
262 ; Use:          Opens a viewer window on the screen.
263
264                 EXPORT  viewer_open
265 viewer_open     ROUT
266
267                 STMFD   R13!,{R0,R1,R4,R10,R14} ;Save some registers
268                 MOV     R10,R0                  ;Get the viewer handle
269                 MOV     R4,R1                   ;Look after opening style
270
271                 SUB     R13,R13,#36             ;Make a window state block
272                 LDR     R14,[R10,#vw__window]   ;Load the window handle
273                 STR     R14,[R13,#0]            ;Save it in the block
274                 MOV     R1,R13                  ;Point to the block
275                 SWI     Wimp_GetWindowState     ;And read the window state
276
277                 ; --- If window is open, skip on ---
278
279                 BL      vw__open                ;Is the window open?
280                 BCS     %10viewer_open          ;Yes -- skip onwards then
281
282                 ; --- Open the window onto the screen ---
283
284                 LDR     R1,[R10,#vw__listDef]   ;Find the list definition
285                 LDR     R0,[R10,#vw__list]      ;And the list base
286                 MOV     R14,PC                  ;Set up return address
287                 ADD     PC,R1,#vw__items        ;Find how many items
288                 STR     R1,[R10,#vw__icons]     ;Store this away
289
290                 MOV     R1,R13                  ;Point at window state blk
291                 BL      vw__tWidth              ;Work out title width
292                 BL      vw__rescanSize          ;Rescan the item size
293                 BL      vw__extend              ;Yes -- make it big then
294                 BL      vw__resize              ;Work out new arrangement
295                 BL      vw__setExtent           ;Set the window's extent
296
297                 ; --- Finally work out where to open it ---
298
299 10viewer_open   MOV     R0,R4                   ;Get the opening style
300                 BL      winUtils_setPosition    ;Set the window position
301                 BL      vw__openWindow          ;Open the window there
302                 ADD     R13,R13,#36             ;Reclaim the stack space
303                 LDR     R14,[R10,#vw__flags]    ;Load the flags word
304                 ORR     R14,R14,#vwFlag__opened ;We've now opened it
305                 STR     R14,[R10,#vw__flags]    ;Store the flags back
306                 LDMFD   R13!,{R0,R1,R4,R10,PC}^ ;And return to caller
307
308                 LTORG
309
310 ; --- viewer_close ---
311 ;
312 ; On entry:     R0 == viewer handle
313 ;
314 ; On exit:      --
315 ;
316 ; Use:          Closes a viewer window.
317
318                 EXPORT  viewer_close
319 viewer_close    ROUT
320
321                 STMFD   R13!,{R0,R1,R14}        ;Save some registers
322                 ADD     R1,R0,#vw__window       ;Find the window handle
323                 SWI     Wimp_CloseWindow        ;Close the window
324                 LDMFD   R13!,{R0,R1,PC}^        ;And return to caller
325
326                 LTORG
327
328 ;----- Event handling -------------------------------------------------------
329
330 ; --- viewer_eventHandler ---
331 ;
332 ; On entry:     R0 == viewer handle
333 ;               R1 == pointer to event handler
334 ;               R2 == value to pass in R10
335 ;               R3 == value to pass in R12
336 ;
337 ; On exit:      R1-R3 == old values
338 ;
339 ; Use:          Sets up the event handle for the viewer.
340
341                 EXPORT  viewer_eventHandler
342 viewer_eventHandler ROUT
343
344                 STMFD   R13!,{R4-R6,R14}        ;Save some registers
345                 ADD     R14,R0,#vw__handler     ;Point to handler block
346                 LDMIA   R14,{R4-R6}             ;Load the old handler
347                 STMIA   R14,{R1-R3}             ;Save the new one
348                 MOV     R1,R4                   ;Transfer information over
349                 MOV     R2,R5                   ;All of it, don't let it
350                 MOV     R3,R6                   ;Get away!
351                 LDMFD   R13!,{R4-R6,PC}^        ;And return to caller
352
353                 LTORG
354
355 ; --- vw__events ---
356 ;
357 ; On entry:     R0 == event code
358 ;               R1 == pointer to event block
359 ;
360 ; On exit:      CS if handled, else CC
361 ;
362 ; Use:          Handles events for a viewer window.
363
364 vw__events      ROUT
365
366                 CMP     R0,#17                  ;Is this a message?
367                 CMPNE   R0,#18                  ;Check *both* types
368                 BEQ     %10vw__events           ;Yes -- handle them
369                 CMP     R0,#9                   ;Is the event interesting?
370                 ADDCC   PC,PC,R0,LSL #2         ;Yes -- dispatch it then
371                 MOVS    PC,R14                  ;Otherwise ignore it
372
373                 ; --- Branch table ---
374
375                 MOVS    PC,R14
376                 B       vw__evRedraw
377                 B       vw__evOpen
378                 B       vw__evClose
379                 MOVS    PC,R14
380                 MOVS    PC,R14
381                 B       vw__evMouse
382                 MOVS    PC,R14
383                 B       vw__evKey
384
385                 ; --- Handle messages ---
386                 ;
387                 ; This is a little odd, in the interests of expandability.
388
389 10vw__events    STMFD   R13!,{R2-R4,R14}        ;Save some registers
390                 LDR     R2,[R1,#16]             ;Load the message code
391                 ADR     R3,vw__msgTable         ;Point to the message table
392 00              LDR     R4,[R3],#8              ;Load the message code
393                 CMP     R4,R2                   ;Do I recognise this event?
394                 SUBEQ   R3,R3,#4                ;Yes -- point to branch instr
395                 STREQ   R3,[R13,#12]            ;Store as return address
396                 CMPNE   R4,#-1                  ;Is it the end of the list?
397                 BNE     %b00                    ;No -- keep looping then
398                 LDMFD   R13!,{R2-R4,PC}^        ;Call the routine
399
400                 ; --- Message table ---
401
402 vw__msgTable    MSGB    &1,vw__mDataSave
403                 MSGB    &3,vw__mDataLoad
404                 MSGB    &502,vw__mHelpRq
405                 MSGB    &400CF,vw__mFontChnge
406                 DCD     -1,-1
407
408                 LTORG
409
410 ; --- vw__dispatch ---
411 ;
412 ; On entry:     R0 == event code
413 ;               R1-R5 set up for event
414 ;
415 ; On exit:      CS or CC according to event handler
416 ;
417 ; Use:          Dispatches an event to the user's handler.
418
419                 EXPORT  vw__dispatch
420 vw__dispatch    ROUT
421
422                 STMFD   R13!,{R8-R10,R12,R14}   ;Save some registers
423                 ADD     R14,R10,#vw__handler    ;Find the handler routine
424                 MOV     R9,R10                  ;Pass viewer handle in R9
425                 LDMIA   R14,{R8,R10,R12}        ;Load the things out
426                 ADDS    R0,R0,#0                ;Clear the carry flag
427                 TEQ     R8,#0                   ;Is there a routine?
428                 MOVNE   R14,PC                  ;Yes -- set up return addr
429                 MOVNE   PC,R8                   ;And call the routine
430                 LDMFD   R13!,{R8-R10,R12,R14}   ;Restore registers
431                 ORRCSS  PC,R14,#C_flag          ;If it set C, we do too
432                 BICCCS  PC,R14,#C_flag          ;Otherwise we clear it
433
434                 LTORG
435
436 ; --- vw_evRedraw ---
437 ;
438 ; On entry:     R1 == pointer to window handle in block
439 ;
440 ; On exit:      CS
441 ;
442 ; Use:          Redraws a viewer window.
443
444 vw__evRedraw    ROUT
445
446                 STMFD   R13!,{R0-R7,R14}        ;Save some registers
447                 SWI     Wimp_RedrawWindow       ;Start the redraw job
448                 CMP     R0,#0                   ;Is this the end yet?
449                 BEQ     %90vw__evRedraw         ;Yes -- do nothing then
450
451                 ; --- Find the window origin ---
452
453                 MOV     R7,R1                   ;Remember the block pointer
454                 LDR     R2,[R7,#4]              ;Load the left hand side
455                 ADD     R14,R7,#16              ;Point to top and scroll pos
456                 LDMIA   R14,{R3-R5}             ;Load those positions out
457                 SUB     R6,R3,R5                ;Find the top position
458                 SUB     R5,R2,R4                ;And the left side
459                 SUB     R13,R13,#32             ;Space for rectangle block
460
461                 ; --- The main redraw loop ---
462                 ;
463                 ; First of all, handle the banner.
464
465 10vw__evRedraw  LDR     R14,[R10,#vw__banner]   ;Load the banner address
466                 CMP     R14,#0                  ;Is there one defined?
467                 BEQ     %f00                    ;No -- skip ahead then
468
469                 ; --- See if we need to do this ---
470
471                 LDR     R14,[R7,#28+16]         ;Load the top coordinate
472                 CMP     R14,R6                  ;Is this above the line?
473                 BLT     %f00                    ;No -- don't bother then
474
475                 ; --- Render the banner's background ---
476
477                 MOV     R0,#3                   ;Get the banner colour
478                 SWI     Wimp_SetColour          ;Set this as the colour
479
480                 MOV     R0,#4                   ;Move the graphics cursor
481                 LDR     R1,[R7,#28+0]           ;Find left side of window
482                 MOV     R2,R6                   ;Baseline on window origin
483                 SWI     OS_Plot                 ;Do the cursor move
484                 MOV     R0,#101                 ;Rectangle fill absolute
485                 LDR     R1,[R7,#28+8]           ;Load right side of window
486                 ADD     R2,R6,#vw__banHeight    ;Get the banner height
487                 SWI     OS_Plot                 ;Do that too
488
489                 ; --- Now plot the banner text ---
490
491                 MOV     R14,R13                 ;Point at the stack block
492
493                 MOV     R0,#28                  ;We have an odd left side
494                 MOV     R1,#0                   ;Baseline is along origin
495                 LDR     R2,[R10,#vw__fixedWidth] ;Load width of the banner
496                 MOV     R3,#vw__banHeight       ;Get the banner's height
497                 STMIA   R14!,{R0-R3}            ;Save the coordinates
498
499                 LDR     R0,=&37000131           ;Get the icon flags word
500                 LDR     R1,[R10,#vw__banner]    ;Load the banner pointer
501                 MOV     R2,#-1                  ;No validation string
502                 MOV     R3,#1                   ;Bogus string length
503                 STMIA   R14!,{R0-R3}            ;Save the other bits
504
505                 MOV     R1,R13                  ;Point to the block
506                 SWI     Wimp_PlotIcon           ;Plot the text as an icon
507
508                 ; --- Now alter the graphics rectangle ---
509
510 00              ADD     R14,R7,#28              ;Find the clipping rectangle
511                 LDMIA   R14,{R0-R3}             ;Load the rectangle out
512                 SUB     R0,R0,R5                ;Convert to window coords
513                 SUB     R1,R1,R6                ;This isn't terribly hard
514                 SUB     R2,R2,R5                ;Just subtract origin posn
515                 SUB     R3,R3,R6                ;For all the coordinates
516                 STMIA   R14,{R0-R3}             ;Store those in the block
517
518                 ; --- Plot each interesting icon ---
519
520                 MOV     R0,#vwEvent_redraw      ;Say this is a redraw event
521                 MOV     R1,#0                   ;Start at the beginning
522                 MOV     R2,R13                  ;Use my stack buffer
523                 ADD     R3,R7,#28               ;Point to the clip block
524 00              BL      vw__enum                ;Get next icon ready
525                 BCC     %f00                    ;If no more, skip onwards
526                 BL      vw__intSimple           ;Do quick clipping check
527                 BLCS    vw__dispatch            ;Yes -- package off the event
528                 B       %b00                    ;Loop round for the rest
529
530                 ; --- Finish off the redraw loop ---
531
532 00              MOV     R1,R7                   ;Point at the event block
533                 BL      drag_redraw             ;Draw the drag box if reqd
534                 SWI     Wimp_GetRectangle       ;Get another rectangle
535                 CMP     R0,#0                   ;Is there more to do?
536                 BNE     %10vw__evRedraw         ;Yes -- loop back to do it
537
538                 ADD     R13,R13,#32             ;Restore the stack pointer
539
540 90vw__evRedraw  LDMFD   R13!,{R0-R7,R14}        ;Unstack the registers
541                 ORRS    PC,R14,#C_flag          ;And *claim the event*
542
543                 LTORG
544
545 ; --- vw__evOpen ---
546 ;
547 ; On entry:     R1 == pointer to an open-window block
548 ;
549 ; On exit:      CS
550 ;
551 ; Use:          Opens a viewer window.
552
553 vw__evOpen      ROUT
554
555                 STMFD   R13!,{R0,R14}           ;Save some registers
556                 MOV     R14,#0                  ;Force horizontal scroll
557                 STR     R14,[R1,#20]            ;To stop it looking odd
558                 BL      screen_justChangedMode  ;Just had a mode change?
559                 BCS     %50vw__evOpen           ;Yes -- handle that
560
561                 ; --- Just rescan the size like nice people ---
562
563                 BL      vw__resize              ;Modify the arrangement
564                 BLCS    vw__setExtent           ;Maybe modify the extent too
565                 BLCS    vw__refresh             ;If so, force a redraw
566                 BL      vw__openWindow          ;Whatever, open the window
567                 LDMFD   R13!,{R0,R14}           ;Restore the registers
568                 ORRS    PC,R14,#C_flag          ;And claim the event
569
570                 ; --- Just changed mode -- anything could have happened ---
571
572 50vw__evOpen    BL      vw__tWidth              ;Rescan the title width
573                 BL      vw__rescanSize          ;Rescan the icon sizes
574                 BL      vw__resize              ;Rearrange the icons
575                 BL      vw__setExtent           ;Rework the extent
576                 BL      vw__refresh             ;Redraw the work area
577                 BL      vw__openWindow          ;And reopen the window
578                 LDMFD   R13!,{R0,R14}           ;Restore the registers
579                 ORRS    PC,R14,#C_flag          ;And claim the event
580
581                 LTORG
582
583 ; --- vw__evClose ---
584 ;
585 ; On entry:     R1 == pointer to block
586 ;
587 ; On exit:      CC or CS
588 ;
589 ; Use:          Handles a close request for a viewer,
590
591 vw__evClose     ROUT
592
593                 STMFD   R13!,{R0,R14}           ;Save some registers
594                 MOV     R0,#vwEvent_close       ;Get the event code
595                 BL      vw__dispatch            ;Send it to the user
596                 LDMFD   R13!,{R0,PC}            ;And return this state
597
598                 LTORG
599
600 ; --- vw__evMouse ---
601 ;
602 ; On entry:     R1 == pointer to pointer info block
603 ;
604 ; On exit:      CS
605 ;
606 ; Use:          Handles a mouse click on the viewer.
607
608 vw__evMouse     ROUT
609
610                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
611                 MOV     R4,R1                   ;Look after this pointer
612                 LDMIA   R4,{R2,R3}              ;Load the coordinates out
613                 BL      vw__whichIcon           ;Which icon is that?
614
615                 LDR     R2,[R4,#8]              ;Load the button state
616                 TST     R2,#&002                ;Is this a menu click?
617                 MOVNE   R0,#vwEvent_menu        ;Yes -- pass that event
618                 TST     R2,#&005                ;Another normal click?
619                 MOVNE   R0,#vwEvent_double      ;Yes -- that's a double
620                 TST     R2,#&050                ;Is it a drag?
621                 MOVNE   R0,#vwEvent_drag        ;Yes -- use that event then
622                 TST     R2,#&500                ;Or a normal click?
623                 MOVNE   R0,#vwEvent_click       ;Yes -- that's a real one
624                 BL      vw__dispatch            ;Sent the event on
625                 LDMFD   R13!,{R0-R4,R14}        ;Save some registers
626                 ORRS    PC,R14,#C_flag          ;We dealt with it
627
628                 LTORG
629
630 ; --- vw__evKey ---
631 ;
632 ; On entry:     R1 == pointer to caret info block
633 ;
634 ; On exit:      CC if unclaimed, else CS
635 ;
636 ; Use:          Handles a keypress while the viewer has the input focus.
637
638 vw__evKey       ROUT
639
640                 STMFD   R13!,{R0,R1,R14}        ;Save some registers
641                 LDR     R0,[R1,#24]             ;Load the character code
642                 BL      akbd_translate          ;Try translating the key
643                 MOV     R1,R0                   ;Put this back in R1
644                 MOV     R0,#vwEvent_key         ;Get the event code
645                 BL      vw__dispatch            ;Dispatch the event
646                 LDMFD   R13!,{R0,R1,R14}        ;Restore registers
647                 ORRCSS  PC,R14,#C_flag          ;Claim if he claimed it
648                 BICCCS  PC,R14,#C_flag          ;Don't claim if he didn't
649
650                 LTORG
651
652 ; --- vw__mDataSave ---
653 ;
654 ; On entry:     R0 == message code
655 ;               R1 == pointer to message block
656 ;
657 ; On exit:      --
658 ;
659 ; Use:          Handles a file dropped on the viewer.
660
661 vw__mDataSave   ROUT
662
663                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
664                 MOV     R4,#vwDrop_save         ;Say it's a save event
665                 ADD     R3,R1,#44               ;Point to the filename
666                 LDR     R2,[R1,#36]             ;Load the estimated size
667                 LDR     R1,[R1,#40]             ;And the filetype
668                 MOV     R0,#vwEvent_drop        ;Get the event code
669                 BL      vw__dispatch            ;And send it to the client
670                 LDMFD   R13!,{R0-R4,PC}^        ;And return to caller
671
672                 LTORG
673
674 ; --- vw__mDataLoad ---
675 ;
676 ; On entry:     R0 == message code
677 ;               R1 == pointer to message block
678 ;
679 ; On exit:      --
680 ;
681 ; Use:          Handles a file dropped on the viewer.
682
683 vw__mDataLoad   ROUT
684
685                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
686                 MOV     R4,#vwDrop_load         ;Say it's a load event
687                 ADD     R3,R1,#44               ;Point to the filename
688                 LDR     R2,[R1,#36]             ;Load the estimated size
689                 LDR     R1,[R1,#40]             ;And the filetype
690                 MOV     R0,#vwEvent_drop        ;Get the event code
691                 BL      vw__dispatch            ;And send it to the client
692                 LDMFD   R13!,{R0-R4,PC}^        ;And return to caller
693
694                 LTORG
695
696 ; --- vw__mHelpRq ---
697 ;
698 ; On entry:     R0 == message code
699 ;               R1 == pointer to message block
700 ;
701 ; On exit:      --
702 ;
703 ; Use:          Handles a help request for the viewer.
704
705 vw__mHelpRq     ROUT
706
707                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
708                 ADD     R14,R1,#20              ;Find the mouse position
709                 LDMIA   R14,{R2,R3}             ;Load the coordinates
710                 BL      vw__whichIcon           ;Find the icon pointed at
711                 MOV     R0,#vwEvent_help        ;It's a help request
712                 BL      vw__dispatch            ;Send it to the client
713                 LDMFD   R13!,{R0-R3,PC}^        ;And return to caller
714
715                 LTORG
716
717 ; --- vw__mFontChnge ---
718 ;
719 ; On entry:     R0 == message code
720 ;               R1 == pointer to message block
721 ;
722 ; On exit:      --
723 ;
724 ; Use:          Handles font changed events for the viewer.
725
726 vw__mFontChnge  ROUT
727
728                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
729                 SUB     R13,R13,#36             ;Make a window state block
730                 LDR     R14,[R10,#vw__window]   ;Load viewer's window handle
731                 STR     R14,[R13,#0]            ;Store it in the block
732                 MOV     R1,R13                  ;Point to this block
733                 SWI     Wimp_GetWindowState     ;Read the window information
734                 BL      vw__tWidth              ;Rescan the title width
735                 BL      vw__rescanSize          ;Rescan the icon sizes
736                 BL      vw__resize              ;Rearrange the icons
737                 BL      vw__setExtent           ;Rework the extent
738                 BL      vw__refresh             ;Redraw the work area
739                 BL      vw__openWindow          ;And reopen the window
740                 ADD     R13,R13,#36             ;Restore the stack pointer
741                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
742
743                 LTORG
744
745 ;----- Icon position handling -----------------------------------------------
746
747 ; --- vw__callShape ---
748 ;
749 ; On entry:     R0 == reason code
750 ;               R1-R? == other arguments
751 ;               R10 == pointer to viewer block
752 ;
753 ; On exit:      R0-R? and C returned from shape function
754 ;
755 ; Use:          Calls a shape function and returns the result.
756
757                 EXPORT  vw__callShape
758 vw__callShape   ROUT
759
760                 STMFD   R13!,{R8-R10,R12,R14}   ;Save some registers
761                 LDR     R8,[R10,#vw__shape]     ;Load the shape function addr
762                 MOV     R9,R10                  ;Point to the viewer block
763                 ADD     R14,R10,#vw__handler+4  ;Find owner's R10 and R12
764                 LDMIA   R14,{R10,R12}           ;Load them out nicely too
765                 CMP     R0,R0                   ;Set the C flag on entry
766                 MOV     R14,PC                  ;Set up the return address
767                 MOV     PC,R8                   ;Call the shape function
768                 LDMFD   R13!,{R8-R10,R12,R14}   ;Restore registers
769                 ORRCSS  PC,R14,#C_flag          ;If it set C, return C set
770                 BICCCS  PC,R14,#C_flag          ;Otherwise return C clear
771
772                 LTORG
773
774 ; --- vw__whichIcon ---
775 ;
776 ; On entry:     R2,R3 == mouse coordinates (screen relative)
777 ;               R10 == pointer to viewer block
778 ;
779 ; On exit:      R1 == icon beneath the mouse pointer
780 ;
781 ; Use:          Works out which icon the user is pointing at, should this be
782 ;               interesting.
783
784 vw__whichIcon   ROUT
785
786                 STMFD   R13!,{R0,R2-R6,R14}     ;Save lots of registers
787
788                 ; --- Find the window's state ---
789
790                 SUB     R13,R13,#36             ;Drop the stack to make a blk
791                 LDR     R14,[R10,#vw__window]   ;Get the window handle
792                 STR     R14,[R13,#0]            ;Store that in the block
793                 MOV     R1,R13                  ;Point to the block
794                 SWI     Wimp_GetWindowState     ;Read the window state
795
796                 LDR     R0,[R13,#4]             ;Load the left hand side
797                 ADD     R14,R13,#16             ;Point to the top edge
798                 LDMIA   R14,{R4-R6}             ;Load those values out
799                 SUB     R5,R0,R5                ;Work out x origin position
800                 SUB     R6,R4,R6                ;And the y origin position
801
802                 ; --- Find the click position ---
803
804                 SUB     R2,R2,R5                ;Translate click coordinates
805                 SUB     R3,R3,R6                ;Do that nicely
806                 MOV     R14,R13                 ;Point to my nice block
807                 STMIA   R14!,{R2,R3}            ;Save coordinates away
808                 STMIA   R14!,{R2,R3}            ;And do it again
809
810                 ; --- Now do the enumeration ---
811
812                 MOV     R1,#0                   ;Start at the beginning
813                 ADD     R2,R13,#16              ;Point to spare bit of block
814                 MOV     R3,R13                  ;Point to my coordinates
815                 BL      vw__withinBox           ;Try to find a match
816                 MOVCC   R1,#0                   ;No match -- no icon
817                 ADD     R13,R13,#36             ;Recover stack space
818                 LDMFD   R13!,{R0,R2-R6,PC}^     ;And return to caller
819
820                 LTORG
821
822 ; --- vw__rescanSize ---
823 ;
824 ; On entry:     R10 == pointer to viewer block
825 ;
826 ; On exit:      --
827 ;
828 ; Use:          Recalculates the sizes of icons in the viewer.
829
830 vw__rescanSize  ROUT
831
832                 STMFD   R13!,{R0-R7,R14}        ;Save some registers
833
834                 ; --- Set up for the loop ---
835
836                 LDR     R6,[R10,#vw__listDef]   ;Find the list block
837                 MOV     R1,#0                   ;No item found yet
838                 ADD     R7,R10,#vw__stdDimens   ;Find standard dimensions
839                 LDMIA   R7,{R4,R5}              ;These are minimum sizes
840
841                 ; --- Now read all the items ---
842
843 00              LDR     R0,[R10,#vw__list]      ;Find the list head
844                 MOV     R2,#0                   ;Match any flags
845                 MOV     R3,#0                   ;Still match any flags
846                 MOV     R14,PC                  ;Set up return address
847                 ADD     PC,R6,#vw__enumerate    ;Read the next list item
848                 BCC     %10vw__rescanSize       ;If no more, skip on
849                 LDMIA   R7,{R2,R3}              ;Load standard sizes
850                 MOV     R0,#vwShape_size        ;Get the reason code
851                 BL      vw__callShape           ;And call the shape function
852                 CMP     R4,R2                   ;Now update the sizes
853                 MOVCC   R4,R2                   ;Use the biggest on both
854                 CMP     R5,R3                   ;Check the height too
855                 MOVCC   R5,R3                   ;Use the biggest again
856                 B       %b00                    ;Now loop round for more
857
858                 ; --- Finished -- store result away ---
859
860 10              ADD     R14,R10,#vw__iconWidth  ;Find current sizes
861                 STMIA   R14,{R4,R5}             ;Store these new sizes
862                 LDMFD   R13!,{R0-R7,PC}^        ;And return to caller
863
864                 LTORG
865
866 ; --- vw__intSimple ---
867 ;
868 ; On entry:     R2 == pointer to a box
869 ;               R3 == pointer to another box
870 ;
871 ; On exit:      CS if boxes intersect, else CC
872 ;
873 ; Use:          Informs you whether boxes intersect.  Saves lots of
874 ;               registers.  This is typically used before calling the
875 ;               caller's shape routine to see if it's really worth it.
876
877                 EXPORT  vw__intSimple
878 vw__intSimple   ROUT
879
880                 STMFD   R13!,{R0-R6,R14}        ;Save some registers
881                 LDMIA   R3,{R4-R6,R14}          ;Load second box out
882                 LDMIA   R2,{R0-R3}              ;Load first box out
883                 CMP     R2,R4                   ;Now do the compare
884                 CMPGE   R3,R5
885                 CMPGE   R6,R0
886                 CMPGE   R14,R1
887                 LDMFD   R13!,{R0-R6,R14}        ;Restore registers
888                 ORRGES  PC,R14,#C_flag          ;Return C set if OK
889                 BICLTS  PC,R14,#C_flag          ;Otherwise return CC
890
891                 LTORG
892
893 ; --- vw__enum ---
894 ;
895 ; On entry:     R1 == 0 for first call, or item pointer
896 ;               R2 == pointer to 16-byte coordinate buffer
897 ;               R4 == continuation value from old call
898 ;               R10 == pointer to viewer block
899 ;
900 ; On exit:      CS if more icons, and
901 ;                 R1 == item handle
902 ;                 R4 == new continuation value
903 ;               else CC and
904 ;                 R1,R4 corrupted
905 ;
906 ; Use:          Scans through icons, returning their coordinates in the
907 ;               block.
908 ;
909 ;               This routine is exported, although it isn't for user
910 ;               consumption.  People using it in application code will be
911 ;               shot.
912
913                 EXPORT  vw__enum
914 vw__enum        ROUT
915
916                 STMFD   R13!,{R0,R2,R3,R5-R8,R14} ;Save some registers
917
918                 ; --- Set up for first go round ---
919
920                 CMP     R1,#0                   ;Is this the first go?
921                 BNE     %05vw__enum             ;No -- skip onwards then
922
923                 MOV     R4,#0                   ;Yes -- start at top left
924
925                 ADD     R14,R10,#vw__iconWidth  ;Find the icon dimensions
926                 LDMIA   R14,{R7,R14}            ;Load them out of the block
927                 MOV     R5,#vw__iconGap         ;Set up the gap nicely
928                 ADD     R7,R5,R7                ;Work out right hand side
929                 MOV     R8,#-vw__iconGap        ;Work out top edge
930                 SUB     R6,R8,R14               ;And set up the bottom
931                 STMIA   R2,{R5-R8}              ;Save all of those away
932                 B       %10vw__enum             ;Now skip on to next bit
933
934                 ; --- Sort out a subsequent round ---
935
936 05vw__enum      LDMIA   R2,{R5,R6}              ;Load bottom left of icon
937                 ADD     R14,R10,#vw__iconWidth  ;Find the icon dimensions
938                 LDMIA   R14,{R7,R8}             ;Load them out of the block
939                 ADD     R4,R4,#1                ;Bump horizontal position
940                 LDR     R14,[R10,#vw__across]   ;How many icons going across?
941                 CMP     R4,R14                  ;Reached the edge yet?
942                 ADDCC   R5,R5,R7                ;No -- move along then
943                 ADDCC   R5,R5,#vw__iconGap      ;Add on our extra spacing
944                 MOVCS   R5,#vw__iconGap         ;Otherwise go back to left
945                 MOVCS   R4,#0                   ;Return left side position
946                 SUBCS   R6,R6,R8                ;Drop down one row
947                 SUBCS   R6,R6,#vw__iconGap      ;And add on the spacing
948                 ADD     R7,R5,R7                ;Work out other box position
949                 ADD     R8,R6,R8                ;To make the box right
950                 STMIA   R2,{R5-R8}              ;Store all that away
951
952                 ; --- Now advance the icon pointer ---
953
954 10vw__enum      LDR     R0,[R10,#vw__list]      ;Load the list base
955                 MOV     R2,#0                   ;Give me all the icons
956                 MOV     R3,#0                   ;I really mean that
957                 LDR     R5,[R10,#vw__listDef]   ;Find the list block
958                 MOV     R14,PC                  ;Set up return address
959                 ADD     PC,R5,#vw__enumerate    ;Get the next item
960                 LDMFD   R13!,{R0,R2,R3,R5-R8,R14} ;Unstack registers
961                 ORRCSS  PC,R14,#C_flag          ;If more to come, OK
962                 BICCCS  PC,R14,#C_flag          ;Otherwise return the end
963
964                 LTORG
965
966 ; --- vw__withinBox ---
967 ;
968 ; On entry:     R1 == 0 for first call, or pointer from previous
969 ;               R2 == pointer to 16-byte buffer
970 ;               R3 == pointer to coordinate box (window relative)
971 ;               R4 == value from previous call
972 ;               R10 == pointer to viewer block
973 ;
974 ; On exit:      CS if match found, and
975 ;                 R1 == item handle of match
976 ;                 R4 == continuation value
977 ;               else CC and
978 ;                 R1,R4 corrupted
979 ;
980 ; Use:          Enumerates icons which intersect a given rectangle.  The
981 ;               coordinates of a matching icon are left in the block; these
982 ;               must be set up correctly for the next call.
983
984 vw__withinBox   ROUT
985
986                 STMFD   R13!,{R0,R14}           ;Save some registers
987                 MOV     R0,#vwShape_intersects  ;Get shape fn reason code
988 00              BL      vw__enum                ;Get another icon
989                 BCC     %10vw__withinBox        ;If no more, return now
990                 BL      vw__intSimple           ;Check simple intersection
991                 BLCS    vw__callShape           ;And then the complex one
992                 BCC     %b00                    ;If no match, skip back
993                 LDMFD   R13!,{R0,R14}           ;Restore registers
994                 ORRS    PC,R14,#C_flag          ;And return match
995
996 10vw__withinBox LDMFD   R13!,{R0,R14}           ;Restore registers
997                 BICS    PC,R14,#C_flag          ;Return no match
998
999                 LTORG
1000
1001 ; --- vw__iconBox ---
1002 ;
1003 ; On entry:     R1 == item pointer
1004 ;               R2 == pointer to a block to fill in
1005 ;               R10 == viewer handle
1006 ;
1007 ; On exit:      --
1008 ;
1009 ; Use:          Works out the bounding box of an icon (within the window).
1010
1011 vw__iconBox     ROUT
1012
1013                 STMFD   R13!,{R0-R5,R14}        ;Save some registers
1014
1015                 ; --- First, get the icon index ---
1016
1017                 LDR     R0,[R10,#vw__list]      ;Load the list head pointer
1018                 LDR     R5,[R10,#vw__listDef]   ;Find the definition too
1019                 MOV     R14,PC                  ;Set up return address
1020                 ADD     PC,R5,#vw__itemToIndex  ;Find the item's index
1021
1022                 ; --- Now work out its across and down position ---
1023
1024                 MOV     R0,R1                   ;Get the item index
1025                 LDR     R1,[R10,#vw__across]    ;Find icons going across
1026                 BL      divide                  ;Do the division
1027
1028                 ; --- Finally find the actual position ---
1029
1030                 ADD     R14,R10,#vw__iconWidth  ;Point to icon dimens
1031                 LDMIA   R14,{R4,R5}             ;Load the width and height
1032                 ADD     R3,R4,#vw__iconGap      ;Add on the gap here
1033                 ADD     R14,R5,#vw__iconGap     ;And again, please
1034                 MUL     R14,R0,R14              ;Work out vertical placing
1035                 MUL     R0,R1,R3                ;And the horizontal placing
1036                 RSB     R14,R14,#0              ;Make vertical position -ve
1037                 ADD     R0,R0,#vw__iconGap      ;Push the icon in a little
1038                 SUB     R14,R14,#vw__iconGap    ;And push it down a little
1039                 ADD     R3,R0,R4                ;Work out the right side
1040                 SUB     R1,R14,R5               ;And the bottom edge
1041                 STMIA   R2,{R0,R1,R3,R14}       ;Save them in my block
1042                 LDMFD   R13!,{R0-R5,PC}^        ;And return to caller
1043
1044                 LTORG
1045
1046 ;----- Default selection model ----------------------------------------------
1047
1048 ; --- viewer_select ---
1049 ;
1050 ; On entry:     R0 == viewer handle
1051 ;               R1 == icon handle
1052 ;               R2 == 0 to unselect, 1 to select or 2 to toggle
1053 ;
1054 ; On exit:      --
1055 ;
1056 ; Use:          Selects an icon, or maybe unselects it.  Whatever, it doesn't
1057 ;               flicker if it doesn't need to.
1058
1059                 EXPORT  viewer_select
1060 viewer_select   ROUT
1061
1062                 CMP     R1,#0                   ;Is there an icon?
1063                 MOVEQS  PC,R14                  ;No -- do nothing then
1064
1065                 STMFD   R13!,{R0-R5,R10,R14}    ;Save some registers
1066                 MOV     R10,R0                  ;Get the viewer block pointer
1067
1068                 ; --- Read the current flags ---
1069
1070                 LDR     R4,[R10,#vw__listDef]   ;Get the list definition
1071                 MOV     R5,R2                   ;And get the argument
1072                 MOV     R3,#0                   ;Don't toggle flags
1073                 MOV     R2,#0                   ;Don't clear any flags
1074                 LDR     R0,[R10,#vw__list]      ;Load the list base address
1075                 MOV     R14,PC                  ;Set up return address
1076                 ADD     PC,R4,#vw__setFlags     ;Read the current flags
1077
1078                 ; --- Work out the new ones ---
1079
1080                 AND     R2,R2,#1                ;Leave only selected flag
1081                 CMP     R5,#1                   ;What is the operation?
1082                 MOVLT   R3,#0                   ;Clear -- clear the flag
1083                 MOVEQ   R3,#1                   ;Set -- set the flag
1084                 EORGT   R3,R2,#1                ;Toggle -- toggle the flag
1085                 CMP     R3,R2                   ;Have we made a difference?
1086                 LDMEQFD R13!,{R0-R5,R10,PC}^    ;No -- return now then
1087
1088                 ; --- Set the new flags now ---
1089
1090                 MOV     R2,#1                   ;Clear the selected bit
1091                 MOV     R14,PC                  ;Set up return address
1092                 ADD     PC,R4,#vw__setFlags     ;Set the new flags
1093                 MOV     R0,R10                  ;Get handle in R0
1094                 BL      viewer_update           ;Update the icon
1095                 LDMFD   R13!,{R0-R5,R10,PC}^    ;Return to caller
1096
1097                 LTORG
1098
1099 ; --- viewer_isSelected ---
1100 ;
1101 ; On entry:     R0 == viewer handle
1102 ;               R1 == icon handle
1103 ;
1104 ; On exit:      CS if icon is selected, else CC
1105 ;
1106 ; Use:          Informs you whether an icon is selected.
1107
1108                 EXPORT  viewer_isSelected
1109 viewer_isSelected ROUT
1110
1111                 CMP     R1,#0                   ;Is there an icon?
1112                 BICEQS  PC,R14,#C_flag          ;No -- not selected then
1113                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
1114                 MOV     R2,#0                   ;Don't clear any flags
1115                 MOV     R3,#0                   ;Don't toggle any either
1116                 LDR     R4,[R0,#vw__listDef]    ;Find the list block
1117                 LDR     R0,[R0,#vw__list]       ;Find the list base
1118                 MOV     R14,PC                  ;Set up return address
1119                 ADD     PC,R4,#vw__setFlags     ;Read the current flags
1120                 TST     R2,#1                   ;Is it selected then?
1121                 LDMFD   R13!,{R0-R4,R14}        ;Restore caller's registers
1122                 ORRNES  PC,R14,#C_flag          ;If selected, return C set
1123                 BICEQS  PC,R14,#C_flag          ;Otherwise clear C on exit
1124
1125                 LTORG
1126
1127 ; --- viewer_selectAll ---
1128 ;
1129 ; On entry:     R0 == viewer handle
1130 ;               R2 == 0 to deselect, or 1 to select
1131 ;
1132 ; On exit:      --
1133 ;
1134 ; Use:          Selects or deselects all the icons in a viewer.
1135
1136                 EXPORT  viewer_selectAll
1137 viewer_selectAll ROUT
1138
1139                 STMFD   R13!,{R0-R5,R10,R14}    ;Save some registers
1140                 MOV     R10,R0                  ;Look after the handle
1141                 MOV     R1,#0                   ;Start at the beginning
1142                 MOV     R4,R2                   ;Look after selection state
1143                 LDR     R5,[R10,#vw__listDef]   ;Find the list block
1144
1145 00              LDR     R0,[R10,#vw__list]      ;Find the list head
1146                 MOV     R2,#1                   ;Check the selected bit
1147                 EOR     R3,R4,#1                ;Find interesting icons
1148                 MOV     R14,PC                  ;Set up return address
1149                 ADD     PC,R5,#vw__enumerate    ;Find next icon
1150                 BCC     %f00                    ;If all done, skip on
1151                 MOV     R0,R10                  ;Get viewer handle
1152                 MOV     R2,R4                   ;Get selection state
1153                 BL      viewer_select           ;Do the selection
1154                 B       %b00                    ;And skip back for the rest
1155
1156 00              MOV     R14,#0                  ;Clear temporary selection
1157                 STR     R14,[R10,#vw__tempSel]  ;Store that in the block
1158                 LDMFD   R13!,{R0-R5,R10,PC}^    ;Return to caller when done
1159
1160                 LTORG
1161
1162 ; --- viewer_click ---
1163 ;
1164 ; On entry:     R0 == viewer handle
1165 ;               R1 == icon handle (or 0)
1166 ;               R2 == mouse button state
1167 ;
1168 ; On exit:      --
1169 ;
1170 ; Use:          Handles a click, drag etc. according to the standard
1171 ;               selection model.
1172
1173                 EXPORT  viewer_click
1174 viewer_click    ROUT
1175
1176                 TST     R2,#&002                ;Is this a menu click?
1177                 BNE     %20viewer_click         ;Yes -- handle it then
1178                 TST     R2,#&400                ;Is this a SELECT click?
1179                 BNE     %10viewer_click         ;Yes -- handle that
1180                 TST     R2,#&050                ;Is this a drag?
1181                 BNE     %50viewer_click         ;Yes -- start a drag box
1182                 TST     R2,#&100                ;Is this an ADJUST click?
1183                 MOVEQS  PC,R14                  ;No -- do nothing then
1184
1185                 ; --- Handle an ADJUST click ---
1186
1187                 STMFD   R13!,{R2,R14}           ;Save some registers
1188                 BL      viewer_clearTemp        ;Clear temporary selection
1189                 MOV     R2,#2                   ;Now select interesting icon
1190                 BL      viewer_select           ;Do the selection op
1191                 LDMFD   R13!,{R2,PC}^           ;And return to caller
1192
1193                 ; --- Handle a SELECT click ---
1194
1195 10viewer_click  STMFD   R13!,{R2,R14}           ;Save some registers
1196                 BL      viewer_clearTemp        ;Clear temporary selection
1197                 BL      viewer_isSelected       ;Is the icon selected?
1198                 LDMCSFD R13!,{R2,PC}^           ;Yes -- do nothing then
1199                 MOV     R2,#0                   ;Clear entire selection
1200                 BL      viewer_selectAll        ;Do that then
1201                 MOV     R2,#1                   ;Now select my icon
1202                 BL      viewer_select           ;Go do that then
1203                 LDMFD   R13!,{R2,PC}^           ;And return to caller
1204
1205                 ; --- Handle a MENU click ---
1206
1207 20viewer_click  STMFD   R13!,{R0-R5,R10,R14}    ;Save some registers
1208                 MOV     R10,R0                  ;Look after the handle
1209                 BL      viewer_clearTemp        ;Clear temporary selection
1210                 MOV     R4,R1                   ;Look after icon handle
1211                 LDR     R5,[R10,#vw__listDef]   ;Find the list definition
1212                 LDR     R0,[R10,#vw__list]      ;Find the list base
1213                 MOV     R1,#0                   ;Start at the beginning
1214                 MOV     R2,#1                   ;Check selected bit
1215                 MOV     R3,#1                   ;Any with it set?
1216                 MOV     R14,PC                  ;Set return address
1217                 ADD     PC,R5,#vw__enumerate    ;Find first selected icon
1218                 LDMCSFD R13!,{R0-R5,R10,PC}^    ;Robust selection -- quit now
1219                 MOV     R0,R10                  ;Get the handle back
1220                 MOV     R1,R4                   ;Get clicked icon
1221                 MOV     R2,#1                   ;Select the icon
1222                 BL      viewer_select           ;Go select it then
1223                 STR     R1,[R10,#vw__tempSel]   ;This is temporary selection
1224                 LDMFD   R13!,{R0-R5,R10,PC}^    ;Return to caller
1225
1226                 ; --- Handle a drag ---
1227
1228 50viewer_click  CMP     R1,#0                   ;Is there actually an icon?
1229                 BNE     %60viewer_click         ;Yes -- handle that
1230                 STMFD   R13!,{R0-R5,R14}        ;Save some registers
1231                 MOV     R4,R0                   ;Pass viewer handle in R10
1232                 MOV     R5,#0                   ;I have no workspace
1233                 LDR     R0,[R4,#vw__window]     ;Load the window handle
1234                 MOV     R1,#0                   ;No flags to set
1235                 ADR     R2,vw__dragSel          ;Point to drag handler
1236                 MOV     R3,#0                   ;No magic number in R9
1237                 BL      drag_start              ;Start the drag operation
1238                 LDMFD   R13!,{R0-R5,PC}^        ;And return to caller
1239
1240                 ; --- Handle drag on an icon -- select it ---
1241
1242 60viewer_click  STMFD   R13!,{R2,R14}           ;Save some registers
1243                 MOV     R2,#1                   ;Select the icon
1244                 BL      viewer_select           ;Do that then
1245                 LDMFD   R13!,{R2,PC}^           ;And return to caller
1246
1247                 LTORG
1248
1249 ; --- vw__dragSel ---
1250 ;
1251 ; On entry:     R0 == drag op event code
1252 ;               Other registers depend on this
1253 ;
1254 ; On exit:      --
1255 ;
1256 ; Use:          Handles events during a marquee-select drag operation.
1257
1258 vw__dragSel     ROUT
1259
1260                 CMP     R0,#7                   ;Is this a kosher event?
1261                 ADDCC   PC,PC,R0,LSL #2         ;Yes -- then dispatch it
1262                 MOVS    PC,R14                  ;Otherwise ignore it
1263
1264                 B       vw__dragRender          ;Draw the drag box
1265                 B       vw__dragRender          ;Undraw the drag box
1266                 B       vw__dragRender          ;Rotate the drag box
1267                 MOVS    PC,R14                  ;Do no coordinate conversion
1268                 B       vw__dragScroll          ;Auto-scroll the viewer
1269                 B       vw__dragDone            ;Completed the drag OK
1270                 MOVS    PC,R14                  ;Drag operation cancelled
1271
1272                 ; --- Draw the drag box ---
1273
1274 vw__dragRender  STMFD   R13!,{R0-R5,R14}        ;Save some registers
1275
1276                 ; --- Set the colour up ---
1277
1278                 MOV     R0,#1                   ;Background colour is 1
1279                 MOV     R1,#7                   ;Make lines black, please
1280                 BL      drag_eorColour          ;Set the colour up
1281
1282                 ; --- Now render the drag box ---
1283
1284                 SUB     R4,R4,R2                ;Get the box width
1285                 SUB     R5,R5,R3                ;And the box height
1286
1287                 MOV     R0,#4                   ;Move cursor absolute
1288                 ADD     R1,R6,R2                ;Find the start position
1289                 ADD     R2,R7,R3                ;Set up the y position too
1290                 SWI     OS_Plot                 ;Move the graphics cursor
1291
1292                 MOV     R0,#17                  ;Relative dotted plot
1293                 MOV     R1,R4                   ;Plot bottom line
1294                 MOV     R2,#0                   ;Keep y constant
1295                 SWI     OS_Plot
1296                 MOV     R0,#49                  ;Relative dotted plot
1297                 MOV     R1,#0                   ;Keep x constant
1298                 MOV     R2,R5                   ;Plot right hand side
1299                 SWI     OS_Plot
1300                 MOV     R0,#49                  ;Relative dotted plot
1301                 RSB     R1,R4,#0                ;Plot top line
1302                 MOV     R2,#0                   ;Keep y constant
1303                 SWI     OS_Plot
1304                 MOV     R0,#57                  ;Relative dotted plot
1305                 MOV     R1,#0                   ;Keep x constant
1306                 RSB     R2,R5,#0                ;Plot left hand side
1307                 SWI     OS_Plot                 ;Plot that too
1308
1309                 LDMFD   R13!,{R0-R5,PC}^        ;And return to caller
1310
1311                 ; --- Scroll the window during the drag ---
1312
1313 vw__dragScroll  STMFD   R13!,{R0-R3,R14}        ;Save some registers
1314                 BL      drag_scroll             ;Get the scroll position
1315                 STR     R3,[R1,#24]             ;Save vertical scroll posn
1316                 BL      vw__openWindow          ;Reopen the window
1317                 LDMFD   R13!,{R0-R3,PC}^        ;And return to caller
1318
1319                 ; --- Handle the end of the drag ---
1320
1321 vw__dragDone    STMFD   R13!,{R0-R5,R14}        ;Save some registers
1322
1323                 ; --- Fiddle the coordinates ---
1324
1325                 CMP     R2,R4                   ;Are these the right way?
1326                 EORGT   R2,R2,R4                ;No -- swap them round then
1327                 EORGT   R4,R2,R4
1328                 EORGT   R2,R2,R4
1329
1330                 CMP     R3,R5                   ;Are these the right way?
1331                 EORGT   R3,R3,R5                ;No -- swap them round then
1332                 EORGT   R5,R3,R5
1333                 EORGT   R3,R3,R5
1334
1335                 ; --- Now enumerate matching boxes ---
1336
1337                 STMFD   R13!,{R2-R5}            ;Stuff the drag box on stack
1338                 SUB     R13,R13,#16             ;And make another block
1339
1340                 MOV     R0,R10                  ;Get the viewer handle
1341                 MOV     R1,#0                   ;Start at the beginning
1342                 ADD     R3,R13,#16              ;Point at the drag box
1343
1344 00              MOV     R2,R13                  ;Point to my spare block
1345                 BL      vw__withinBox           ;Get next matching icon
1346                 MOVCS   R2,#1                   ;Select this icon please
1347                 BLCS    viewer_select           ;Please do that
1348                 BCS     %b00                    ;And loop back
1349
1350                 ; --- Finished -- return ---
1351
1352                 ADD     R13,R13,#32             ;Restore the stack block
1353                 LDMFD   R13!,{R0-R5,PC}^        ;And return to caller
1354
1355                 LTORG
1356
1357 ; --- viewer_clearTemp ---
1358 ;
1359 ; On entry:     R0 == viewer handle
1360 ;
1361 ; On exit:      --
1362 ;
1363 ; Use:          Clears the temporary selection (use when you receive a
1364 ;               menu closed event).
1365
1366 viewer_clearTemp ROUT
1367
1368                 STMFD   R13!,{R1,R2,R14}        ;Save some registers
1369                 LDR     R1,[R0,#vw__tempSel]    ;Find temporary selection
1370                 CMP     R1,#0                   ;Is that defined?
1371                 LDMEQFD R13!,{R1,R2,PC}^        ;No -- return now
1372                 MOV     R2,#0                   ;Yes -- deselect the icon
1373                 BL      viewer_select           ;Go do that then
1374                 MOV     R14,#0                  ;And also clear temp select
1375                 STR     R14,[R0,#vw__tempSel]   ;Store that in the block
1376                 LDMFD   R13!,{R1,R2,PC}^        ;Return to caller when done
1377
1378                 LTORG
1379
1380 ; --- viewer_dragSelection ---
1381 ;
1382 ; On entry:     R0 == viewer handle
1383 ;
1384 ; On exit:      --
1385 ;
1386 ; Use:          Starts a drag of the icons within the viewer.  When the drag
1387 ;               is finished, you get sent a vwEvent_dragged event.
1388
1389                 EXPORT  viewer_dragSelection
1390 viewer_dragSelection ROUT
1391
1392                 STMFD   R13!,{R0-R10,R14}       ;Save lots of registers
1393                 MOV     R10,R0                  ;Look after the viewer handle
1394                 LDR     R9,[R10,#vw__listDef]   ;Find the list definition
1395
1396                 ; --- First, see if we need DragASprite ---
1397
1398                 MOV     R0,#161                 ;Read CMOS locations
1399                 MOV     R1,#28                  ;Various strange status flags
1400                 SWI     OS_Byte                 ;Do the read op
1401                 TST     R2,#2                   ;Is the bit set?
1402                 BEQ     %50viewer_dragSelection ;No -- use normal Wimp box
1403
1404                 ; --- Work out what sprite to use ---
1405                 ;
1406                 ; We need to ask the client here.
1407
1408                 LDR     R0,[R10,#vw__list]      ;Load the list base pointer
1409                 MOV     R1,#0                   ;Start at the beginning
1410                 MOV     R2,#1                   ;Check the selected bit
1411                 MOV     R3,#1                   ;Make sure it's on
1412                 MOV     R14,PC                  ;Set up return address
1413                 ADD     PC,R9,#vw__enumerate    ;Read first matching item
1414                 BCC     %90viewer_dragSelection ;No selection -- no drag
1415                 MOVCS   R4,R1                   ;Match -- get icon handle
1416                 MOVCS   R14,PC                  ;And set up again
1417                 ADDCS   PC,R9,#vw__enumerate    ;Read next matching iten
1418                 MOVCS   R4,#-1                  ;If more than one, say `many'
1419
1420                 MOV     R1,R4                   ;Give this to the client
1421                 MOV     R0,#vwEvent_sprite      ;Pretend it's an event
1422                 BL      vw__dispatch            ;And send it off nicely
1423                 BCC     %50viewer_dragSelection ;Told to use Wimp box
1424
1425                 ; --- Now use DragASprite nicely ---
1426
1427                 MOV     R2,R1                   ;Look after the name
1428                 MOV     R3,R0                   ;And the sprite area
1429                 SUB     R13,R13,#20             ;Make a small block
1430                 MOV     R1,R13                  ;Point to the block
1431                 SWI     Wimp_GetPointerInfo     ;Read the pointer position
1432                 MOV     R14,R13                 ;Point to the block
1433                 LDMIA   R14,{R0,R1}             ;Load the coordinates out
1434                 SUB     R0,R0,#64               ;Turn into a little box
1435                 SUB     R1,R1,#64               ;Chop off a little bit
1436                 STMIA   R14!,{R0,R1}            ;Store them back
1437                 ADD     R0,R0,#128              ;Work out the other side
1438                 ADD     R1,R1,#128              ;Add on quite a lot actually
1439                 STMIA   R14!,{R0,R1}            ;Store them back
1440
1441                 MOV     R0,#&C5                 ;DragASprite flags
1442                 MOV     R1,R3                   ;Get the sprite area
1443                 MOV     R3,R13                  ;Point to my rectangle block
1444                 SWI     XDragASprite_Start      ;Start the drag operation
1445                 ADD     R13,R13,#20             ;Reclaim the stack pointer
1446                 BVC     %70viewer_dragSelection ;If it worked, set up handler
1447
1448                 ; --- Try and do a dotted outline ---
1449
1450 50              SUB     R13,R13,#40             ;Make a small block
1451                 LDR     R0,[R10,#vw__list]      ;Find the list definition
1452                 MOV     R1,#0                   ;Start at the beginning
1453                 MOV     R2,#1                   ;Check selected bits
1454                 MOV     R3,#1                   ;Make sure they're on
1455                 MOV     R14,PC                  ;Set up return address
1456                 ADD     PC,R9,#vw__enumerate    ;Do the enumeration
1457                 ADDCC   R13,R13,#40             ;Restore stack pointer
1458                 BCC     %90viewer_dragSelection ;No selection -- no drag
1459
1460                 MOV     R2,R13                  ;Point to a block
1461                 BL      vw__iconBox             ;Find the icon's bounding box
1462                 LDMIA   R2,{R4-R7}              ;Load the bounding box
1463
1464                 ; --- Now work out the bounding box of selected icons ---
1465
1466 00              MOV     R2,#1                   ;Check selected bits
1467                 MOV     R3,#1                   ;Make sure they're on
1468                 MOV     R14,PC                  ;Set up return address
1469                 ADD     PC,R9,#vw__enumerate    ;Do the enumeration
1470                 BCC     %f00                    ;No more -- skip onwards
1471                 MOV     R2,R13                  ;Point to a block
1472                 BL      vw__iconBox             ;Find the bounding box
1473                 LDMIA   R2,{R2,R3,R8,R14}       ;Load these coordinates
1474
1475                 CMP     R4,R2
1476                 MOVGT   R4,R2
1477                 CMP     R5,R3
1478                 MOVGT   R5,R3
1479                 CMP     R6,R8
1480                 MOVLT   R6,R8
1481                 CMP     R7,R14
1482                 MOVLT   R7,R14
1483
1484                 B       %b00                    ;Loop back for the rest now
1485
1486                 ; --- Translate coordinates to screen relative ---
1487
1488 00              MOV     R1,R13                  ;Point to my block
1489                 SWI     Wimp_GetPointerInfo     ;Read the pointer position
1490                 LDMIA   R13,{R8,R9}             ;Load the position out
1491
1492                 LDR     R14,[R10,#vw__window]   ;Load the window handle
1493                 STR     R14,[R13,#0]            ;Store it in the block
1494                 SWI     Wimp_GetWindowState     ;Read the window position
1495                 LDR     R0,[R13,#4]             ;Load the left hand side
1496                 ADD     R14,R13,#16             ;Point to top edge/scroll
1497                 LDMIA   R14,{R1-R3}             ;Load those out nicely
1498                 SUB     R2,R0,R2                ;Work out x origin pos
1499                 SUB     R3,R1,R3                ;And the y origin pos
1500
1501                 ADD     R4,R4,R2
1502                 ADD     R5,R5,R3
1503                 ADD     R6,R6,R2
1504                 ADD     R7,R7,R3
1505
1506                 SUB     R4,R4,#vw__iconGap /2
1507                 SUB     R5,R5,#vw__iconGap /2
1508                 ADD     R6,R6,#vw__iconGap /2
1509                 ADD     R7,R7,#vw__iconGap /2
1510
1511                 ADD     R14,R13,#8              ;Point to bit of block
1512                 STMIA   R14,{R4-R7}             ;Save the drag box position
1513
1514                 ; --- Work out the parent box position ---
1515
1516                 SUB     R4,R4,R8                ;Work out min x position
1517                 SUB     R5,R5,R9                ;And the min y position
1518                 SUB     R6,R6,R8                ;Fiddle with max x
1519                 SUB     R7,R7,R9                ;And max y
1520                 BL      screen_getInfo          ;Read the screen information
1521                 ADD     R14,R0,#screen_width    ;Find the screen dimensions
1522                 LDMIA   R14,{R8,R9}             ;Load them out nicely
1523                 ADD     R6,R6,R8                ;Work out max x position
1524                 ADD     R7,R7,R9                ;And the max y position
1525                 ADD     R14,R0,#screen_dx       ;Get the pixel sizes
1526                 LDMIA   R14,{R8,R9}             ;Load those out too
1527                 SUB     R6,R6,R8                ;Subtract a pixel off
1528                 SUB     R7,R7,R9                ;To make things nice
1529                 ADD     R14,R13,#24             ;Point to parent box area
1530                 STMIA   R14,{R4-R7}             ;Save that lot away
1531
1532                 ; --- Start the drag (phew...) ---
1533
1534                 MOV     R14,#5                  ;Drag fixed sized box
1535                 STR     R14,[R13,#4]            ;Store it in the block
1536                 MOV     R1,R13                  ;Point to the block
1537                 SWI     Wimp_DragBox            ;And start the drag op
1538                 ADD     R13,R13,#40             ;Reclaim my drag box block
1539
1540                 ; --- Set up my handler at the end of it ---
1541
1542 70              ADR     R0,vw__dragIcn          ;Point to my handler
1543                 MOV     R2,R10                  ;Pass viewer handle in R10
1544                 MOV     R3,R12                  ;And workspace (?) in R12
1545                 BL      win_unknownHandler      ;Register that routine please
1546 90              LDMFD   R13!,{R0-R10,PC}^       ;And return to caller
1547
1548                 LTORG
1549
1550 ; --- vw__dragIcn ---
1551 ;
1552 ; On entry:     R0 == event code
1553 ;               R1 == pointer to event block
1554 ;
1555 ; On exit:      --
1556 ;
1557 ; Use:          Handles events during a selection drag.
1558
1559 vw__dragIcn     ROUT
1560
1561                 CMP     R0,#7                   ;Is it a drag end event?
1562                 MOVNES  PC,R14                  ;Nope -- nothing to do
1563
1564                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
1565                 SWI     XDragASprite_Stop       ;Turn off any sprite drags
1566                 SUB     R13,R13,#20             ;Make a little block
1567                 MOV     R1,R13                  ;Point to the block
1568                 SWI     Wimp_GetPointerInfo     ;Read the pointer position
1569                 ADD     R14,R1,#12              ;Point to window handle
1570                 LDMIA   R14,{R1,R2}             ;Load window and icon
1571                 ADD     R13,R13,#20             ;Restore stack block
1572                 MOV     R0,#vwEvent_dragged     ;Get the event code
1573                 BL      vw__dispatch            ;Send it the event
1574                 LDMFD   R13!,{R0-R2,PC}^        ;And return to caller
1575
1576                 LTORG
1577
1578 ;----- Miscellaneous --------------------------------------------------------
1579
1580 ; --- viewer_window ---
1581 ;
1582 ; On entry:     R0 == viewer handle
1583 ;
1584 ; On exit:      R0 == window handle
1585 ;
1586 ; Use:          Returns the window handle of the viewer.
1587
1588                 EXPORT  viewer_window
1589 viewer_window   ROUT
1590
1591                 LDR     R0,[R0,#vw__window]     ;Load the window handle
1592                 MOVS    PC,R14                  ;And return to caller
1593
1594                 LTORG
1595
1596 ; --- viewer_update ---
1597 ;
1598 ; On entry:     R0 == viewer handle
1599 ;               R1 == icon handle
1600 ;
1601 ; On exit:      --
1602 ;
1603 ; Use:          Updates (redraws) a given icon.
1604
1605                 EXPORT  viewer_update
1606 viewer_update   ROUT
1607
1608                 STMFD   R13!,{R2,R14}           ;Save some registers
1609                 MOV     R2,#vwEvent_redraw      ;Normal is redraw event
1610                 BL      vw__doUpdate            ;Go and do the update
1611                 LDMFD   R13!,{R2,PC}^           ;And return to caller
1612
1613                 LTORG
1614
1615 ; --- vw__doUpdate ---
1616 ;
1617 ; On entry:     R0 == viewer handle
1618 ;               R1 == icon handle
1619 ;               R2 == event code to send
1620 ;
1621 ; On exit:      --
1622 ;
1623 ; Use:          Updates an item, passing a given event to the client.  This
1624 ;               is purely for the use of gallery ;-)
1625
1626                 EXPORT  vw__doUpdate
1627 vw__doUpdate    ROUT
1628
1629                 STMFD   R13!,{R0-R7,R10,R14}    ;Save some registers
1630                 MOV     R10,R0                  ;Get the viewer handle in R10
1631                 MOV     R7,R2                   ;Find the event code
1632
1633                 ; --- Start the update job ---
1634
1635                 SUB     R13,R13,#32+44          ;Make a rectangle block
1636                 MOV     R2,R13                  ;Point to space for box
1637                 BL      vw__iconBox             ;Find the icon's box
1638
1639                 LDMIA   R2,{R2-R5}              ;Load the box coordinates
1640                 ADD     R14,R13,#32+4           ;Find the update block
1641                 STMIA   R14,{R2-R5}             ;Store the rectangle there
1642                 LDR     R14,[R10,#vw__window]   ;Load the window handle
1643                 STR     R14,[R13,#32+0]         ;Store in my nice block
1644                 MOV     R4,R1                   ;Look after icon handle
1645                 ADD     R1,R13,#32              ;Point to update block
1646                 SWI     Wimp_UpdateWindow       ;Start the update job
1647                 CMP     R0,#0                   ;Anything to do?
1648                 BEQ     %90vw__doUpdate         ;No -- skip to end then
1649
1650                 ; --- Read the window origin ---
1651
1652                 LDR     R2,[R13,#32+4]          ;Load the left hand side
1653                 ADD     R14,R13,#32+16          ;Find top and scroll offsets
1654                 LDMIA   R14,{R3,R5,R6}          ;Load those out too
1655                 SUB     R6,R3,R6                ;Find the y origin position
1656                 SUB     R5,R2,R5                ;And the x origin position
1657
1658                 ; --- Now embark on the main loop ---
1659
1660 00              ADD     R14,R13,#32+28          ;Point to graphics rectangle
1661                 LDMIA   R14,{R0-R3}             ;Load that out
1662                 SUB     R0,R0,R5                ;Adjust the block by origin
1663                 SUB     R1,R1,R6                ;This is just to keep the
1664                 SUB     R2,R2,R5                ;User's event handler happy
1665                 SUB     R3,R3,R6                ;I know what needs to be done
1666                 STMIA   R14,{R0-R3}             ;Store that lot back
1667
1668                 MOV     R0,R7                   ;Get the redraw event ready
1669                 MOV     R1,R4                   ;Point to the item
1670                 MOV     R2,R13                  ;Point to his icon block
1671                 ADD     R3,R13,#32+28           ;Point to clipping block
1672                 BL      vw__dispatch            ;Send to the handler
1673
1674                 ; --- Do any other bits of drawing ---
1675
1676                 ADD     R1,R13,#32              ;Point to update block
1677                 CMP     R7,#vwEvent_draw        ;Gallery redraw event? (yuk)
1678                 BLEQ    drag_redraw             ;Yes -- update drag rectangle
1679                 SWI     Wimp_GetRectangle       ;Do that rectangle
1680                 CMP     R0,#0                   ;Any more to do?
1681                 BNE     %b00                    ;Yes -- do it then
1682
1683                 ; --- Wrap up and return ---
1684
1685 90              ADD     R13,R13,#32+44          ;Restore the stack
1686                 LDMFD   R13!,{R0-R7,R10,PC}^    ;And return to caller
1687
1688                 LTORG
1689
1690 ; --- viewer_setTitle ---
1691 ;
1692 ; On entry:     R0 == viewer handle
1693 ;               R1 == title string
1694 ;
1695 ; On exit:      --
1696 ;
1697 ; Use:          Sets the viewer window's title.
1698
1699                 EXPORT  viewer_setTitle
1700 viewer_setTitle ROUT
1701
1702                 STMFD   R13!,{R0-R2,R10,R14}    ;Save some registers
1703                 MOV     R10,R0                  ;Get the viewer handle
1704                 LDR     R2,[R10,#vw__window]    ;Load the window handle
1705                 MOV     R0,R1                   ;Get the string to set
1706                 ADD     R1,R10,#vw__title       ;Point to title bar buffer
1707                 BL      winUtils_setTitle       ;Do the title setting
1708                 BL      vw__open                ;Is the window open?
1709                 LDMCCFD R13!,{R0-R2,R10,PC}^    ;No -- do nothing then
1710
1711                 SUB     R13,R13,#36             ;Make a window state block
1712                 LDR     R14,[R10,#vw__window]   ;Load the window handle
1713                 STR     R14,[R13,#0]            ;Store it in the block
1714                 MOV     R1,R13                  ;Point to the block
1715                 SWI     Wimp_GetWindowState     ;Read the current position
1716
1717                 BL      vw__tWidth              ;Yes -- reset the width
1718                 BL      vw__setExtent           ;And reset the extent
1719                 BL      vw__openWindow          ;Open the window, in case
1720                 ADD     R13,R13,#36             ;And reset the stack pointer
1721                 LDMFD   R13!,{R0-R2,R10,PC}^    ;And return to caller
1722
1723                 LTORG
1724
1725 ; --- vw__open ---
1726 ;
1727 ; On entry:     R10 == pointer to viewer block
1728 ;
1729 ; On exit:      CS if window is open, else CC
1730 ;
1731 ; Use:          Sees if a viewer window is currently open.
1732
1733 vw__open        ROUT
1734
1735                 STMFD   R13!,{R0,R1,R14}        ;Save some registers
1736                 SUB     R13,R13,#36             ;Make some space
1737                 LDR     R14,[R10,#vw__window]   ;Load the window handle
1738                 STR     R14,[R13,#0]            ;Save it in the block
1739                 MOV     R1,R13                  ;Point to the block
1740                 SWI     Wimp_GetWindowState     ;Read the information
1741                 LDR     R14,[R13,#32]           ;Load the flags word
1742                 TST     R14,#1<<16              ;Is the window open?
1743                 ADD     R13,R13,#36             ;Reclaim the stack space
1744                 LDMFD   R13!,{R0,R1,R14}        ;Restore registers
1745                 ORRNES  PC,R14,#C_flag          ;Return with C set if so
1746                 BICEQS  PC,R14,#C_flag          ;Otherwise clear C
1747
1748                 LTORG
1749
1750 ; --- vw__openWindow ---
1751 ;
1752 ; On entry:     R1 == pointer to window state block
1753 ;               R10 == pointer to viewer block
1754 ;
1755 ; On exit:      R0 corrupted (just like Wimp_OpenWindow)
1756 ;
1757 ; Use:          Opens a viewer window, and informs the user through the
1758 ;               vwEvent_open event.
1759
1760 vw__openWindow  ROUT
1761
1762                 SWI     Wimp_OpenWindow         ;Reopen the window as ordered
1763                 MOV     R0,#vwEvent_open        ;Send the event along nicely
1764                 B       vw__dispatch            ;And report, and return
1765
1766                 LTORG
1767
1768 ; --- vw__tWidth ---
1769 ;
1770 ; On entry:     R10 == pointer to viewer block
1771 ;
1772 ; On exit:      --
1773 ;
1774 ; Use:          Updates the window's fixed width parameter.
1775
1776 vw__tWidth      ROUT
1777
1778                 STMFD   R13!,{R0,R1,R14}        ;Save some registers
1779                 ADD     R0,R10,#vw__title       ;Point to title buffer
1780                 BL      wimp_strWidth           ;Get the string width
1781                 ADD     R1,R0,#vw__titleAdd     ;Add on a fudge factor
1782                 LDR     R0,[R10,#vw__banner]    ;Load the banner address
1783                 CMP     R0,#0                   ;Is the banner there?
1784                 BLNE    wimp_strWidth           ;Yes -- get its width
1785                 ADDNE   R0,R0,#vw__banAdd       ;And add on its fudge
1786                 CMP     R1,R0                   ;Which is bigger?
1787                 MOVCC   R1,R0                   ;Use the biggest one
1788                 STR     R1,[R10,#vw__fixedWidth] ;Store the new width
1789                 LDMFD   R13!,{R0,R1,PC}^        ;And return to caller
1790
1791                 LTORG
1792
1793 ; --- viewer_rescan ---
1794 ;
1795 ; On entry:     R0 == viewer handle
1796 ;
1797 ; On exit:      --
1798 ;
1799 ; Use:          Rescans all the icons in the viewer and forces a redraw,
1800 ;               in case icons have been added or deleted (or renamed).  Note
1801 ;               that the redraw is done *anyway* -- it's your responsibility
1802 ;               to avoid calling this routine when you don't need to.
1803
1804                 EXPORT  viewer_rescan
1805 viewer_rescan   ROUT
1806
1807                 STMFD   R13!,{R0,R1,R10,R14}    ;Save some registers
1808                 MOV     R10,R0                  ;Get the viewer handle
1809                 BL      vw__open                ;Is the window open at all?
1810                 LDMCCFD R13!,{R0,R1,R10,PC}^    ;No -- handle on open then
1811
1812                 SUB     R13,R13,#36             ;Make a window state block
1813                 LDR     R14,[R10,#vw__window]   ;Load the window handle
1814                 STR     R14,[R13,#0]            ;Save it in the block
1815                 MOV     R1,R13                  ;Point to the block
1816                 SWI     Wimp_GetWindowState     ;And read the window state
1817
1818                 ; --- Open the window onto the screen ---
1819
1820                 LDR     R1,[R10,#vw__listDef]   ;Find the list definition
1821                 LDR     R0,[R10,#vw__list]      ;And the list base
1822                 MOV     R14,PC                  ;Set up return address
1823                 ADD     PC,R1,#vw__items        ;Find how many items
1824                 STR     R1,[R10,#vw__icons]     ;Store this away
1825
1826                 MOV     R1,R13                  ;Point at window state blk
1827                 BL      vw__rescanSize          ;Rescan the item size
1828                 BL      vw__extend              ;Yes -- make it big then
1829                 BL      vw__resize              ;Work out new arrangement
1830                 BL      vw__setExtent           ;Set the window's extent
1831                 BL      vw__refresh             ;Force update of display
1832                 BL      vw__openWindow          ;And open the window
1833                 ADD     R13,R13,#36             ;Reclaim my stack space
1834                 LDMFD   R13!,{R0,R1,R10,PC}^    ;And return to caller
1835
1836                 LTORG
1837
1838 ;----- Icon rearrangement routines ------------------------------------------
1839
1840 ; --- vw__resize ---
1841 ;
1842 ; On entry:     R1 == pointer to window state block
1843 ;               R10 == pointer to viewer block
1844 ;
1845 ; On exit:      CS if the size has changed, else CC
1846 ;
1847 ; Use:          Updates the icon arrangement within a window, returning
1848 ;               whether the arrangement is different now.  Note that this
1849 ;               doesn't redraw the window; it just recaches the extent.
1850 ;               If the size has changed, you'll probably need to call
1851 ;               vw__setExtent and vw__refresh to get everything looking nice.
1852
1853 vw__resize      ROUT
1854
1855                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
1856
1857                 ; --- Now work out how many icons we should have ---
1858
1859                 LDMIB   R1,{R1-R3}              ;Load the x coords from win
1860                 SUB     R0,R3,R1                ;Work out the window width
1861                 SUB     R0,R0,#vw__iconGap      ;Subtract off extra border
1862                 LDR     R2,[R10,#vw__iconWidth] ;Load the icon width out
1863                 ADD     R1,R2,#vw__iconGap      ;Add on the gap
1864                 BL      divide                  ;Divide one by the other
1865                 MOV     R3,R0                   ;Icons which fit across win
1866
1867                 BL      screen_getInfo          ;Find the screen information
1868                 LDR     R0,[R0,#screen_width]   ;Load the screen width
1869                 SUB     R0,R0,#40+vw__iconGap   ;Fudge for scroll bar
1870                 ADD     R1,R2,#vw__iconGap      ;Get icon width+gap again
1871                 BL      divide                  ;Divide one by the other
1872                 MOV     R2,R0                   ;Icons which fit across scrn
1873
1874                 ; --- Fiddle these numbers appropriately ---
1875
1876                 LDR     R0,[R10,#vw__icons]     ;Load number of icons
1877                 CMP     R3,R0                   ;Too many across window?
1878                 MOVCS   R3,R0                   ;Yes -- use number we have
1879                 CMP     R2,R0                   ;Too many across screen?
1880                 MOVCS   R2,R0                   ;Yes -- use number we have
1881                 CMP     R2,R3                   ;More than fit across screen?
1882                 MOVCS   R2,R3                   ;Use -- use that then (erk)
1883                 CMP     R2,#0                   ;No icons at all?
1884                 MOVEQ   R2,#1                   ;Then have at least one
1885
1886                 ; --- Work out how many go down ---
1887
1888                 MOV     R1,R2                   ;Get number going across
1889                 BL      divide                  ;Do the division
1890                 CMP     R1,#0                   ;Any extra ones on bottom?
1891                 ADDNE   R0,R0,#1                ;Yes -- add an extra row
1892                 MOVS    R3,R0                   ;Look after this value
1893                 MOVEQ   R3,#0                   ;If it's zero, use one
1894
1895                 ; --- Now see if anything's changed ---
1896
1897                 ADD     R14,R10,#vw__across     ;Find old across counter
1898                 LDMIA   R14,{R0,R1}             ;Load across and down values
1899                 CMP     R0,R2                   ;Compare with old ones
1900                 CMPEQ   R1,R3                   ;Are they the same?
1901                 STMNEIA R14,{R2,R3}             ;If not, store new ones
1902                 LDMFD   R13!,{R0-R3,R14}        ;Restore caller's registers
1903                 ORRNES  PC,R14,#C_flag          ;If changed, return C set
1904                 BICEQS  PC,R14,#C_flag          ;Otherwise return C clear
1905
1906                 LTORG
1907
1908 ; --- vw__setExtent ---
1909 ;
1910 ; On entry:     R10 == pointer to viewer block
1911 ;
1912 ; On exit:      --
1913 ;
1914 ; Use:          Resets the extent of a viewer window, in case the
1915 ;               arrangement of icons or banner/title text has changed.
1916 ;               If the window is currently open, you should follow this
1917 ;               call with a Wimp_OpenWindow SWI.
1918
1919 vw__setExtent   ROUT
1920
1921                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
1922
1923                 ; --- Work out correct horizontal extent ---
1924
1925                 BL      screen_getInfo          ;Find the screen information
1926                 LDR     R0,[R0,#screen_width]   ;Load the screen width
1927                 SUB     R0,R0,#40+vw__iconGap   ;Fudge for scroll bar
1928                 MOV     R2,R0                   ;Look after this value
1929                 LDR     R3,[R10,#vw__iconWidth] ;Load the icon width
1930                 ADD     R3,R3,#vw__iconGap      ;Add on the inter-icon gap
1931                 MOV     R1,R3                   ;Divide by this
1932                 BL      divide                  ;Divide one by the other
1933                 LDR     R14,[R10,#vw__icons]    ;Load the number of icons
1934                 CMP     R0,R14                  ;Is this bigger?
1935                 MOVCS   R0,R14                  ;Yes -- then use that
1936                 CMP     R0,#0                   ;Unless there's none
1937                 MOVEQ   R0,#1                   ;In which case use one
1938                 MUL     R2,R3,R0                ;Work out the correct width
1939                 ADD     R2,R2,#vw__iconGap      ;Add on extra border around
1940                 LDR     R14,[R10,#vw__fixedWidth] ;Load width of title/banner
1941                 CMP     R2,R14                  ;Do we have enough here?
1942                 MOVCC   R2,R14                  ;No -- then use more
1943
1944                 ; --- And now the vertical extent ---
1945
1946                 LDR     R1,[R10,#vw__iconHeight] ;Load the icon height
1947                 ADD     R1,R1,#vw__iconGap      ;Add on the gap
1948                 LDR     R14,[R10,#vw__down]     ;Load vertical number of icns
1949                 MUL     R1,R14,R1               ;Work out the size
1950                 ADD     R1,R1,#vw__iconGap      ;Add on extra border
1951
1952                 ; --- Work out the other two ---
1953
1954                 RSB     R1,R1,#0                ;And vertical extent -ve
1955                 LDR     R3,[R10,#vw__banner]    ;Load banner pointer
1956                 CMP     R3,#0                   ;Do we have a banner?
1957                 MOVNE   R3,#vw__banHeight       ;Yes -- then add above origin
1958                 MOV     R0,#0                   ;Start at the left side
1959
1960                 ; --- Make sure the extent is big enough ---
1961
1962                 SUBS    R14,R2,#vw__minWidth    ;Get the minimum width
1963                 SUBCC   R2,R2,R14               ;Make bigger if needs be
1964                 SUB     R14,R3,R1               ;Work out extent height
1965                 SUBS    R14,R14,#vw__minHeight  ;Get the minimum height
1966                 ADDCC   R1,R1,R14               ;Make bigger if needs be
1967
1968                 ; --- Finally set up the extent ---
1969
1970                 ADD     R14,R10,#vw__extent     ;Set the window extent
1971                 STMIA   R14,{R0-R3}             ;Save the values in there
1972                 LDR     R0,[R10,#vw__window]    ;Load the window handle
1973                 ADD     R1,R10,#vw__extent      ;Point to the extent block
1974                 SWI     Wimp_SetExtent          ;Set the window's extent
1975                 LDMFD   R13!,{R0-R3,PC}^        ;And return to caller
1976
1977                 LTORG
1978
1979 ; --- vw__refresh ---
1980 ;
1981 ; On entry:     R10 == pointer to a viewer block
1982 ;
1983 ; On exit:      --
1984 ;
1985 ; Use:          Forces a redraw of the contents of a viewer.  Use in
1986 ;               conjunction with vw__resize.
1987
1988 vw__refresh     ROUT
1989
1990                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
1991                 LDR     R0,[R10,#vw__window]    ;Load the window handle
1992                 MOV     R1,#-&FFFFFFF           ;Force a redraw of the world
1993                 MOV     R2,#-&FFFFFFF           ;This hack prevents problems
1994                 MOV     R3,#&FFFFFFF            ;with the extent being bodged
1995                 MOV     R4,#&FFFFFFF            ;by the Wimp.
1996                 SWI     Wimp_ForceRedraw        ;Redraw the whole lot
1997                 LDMFD   R13!,{R0-R4,PC}^        ;And return to caller
1998
1999                 LTORG
2000
2001 ; --- vw__extend ---
2002 ;
2003 ; On entry:     R1 == pointer to window open block
2004 ;               R10 == pointer to a viewer block
2005 ;
2006 ; On exit:      --
2007 ;
2008 ; Use:          Extends the viewer window if necessary to accomodate new
2009 ;               items.  The new coordinates to open are written back to the
2010 ;               window open block.  Correct procedure for adding items is
2011 ;               as follows:
2012 ;
2013 ;               1. Get window state
2014 ;               2. Call vw__extend
2015 ;               3. Call vw__resize
2016 ;               4. Call vw__setExtent
2017 ;               5. Call vw__refresh
2018
2019 vw__extend      ROUT
2020
2021                 STMFD   R13!,{R0-R8,R14}        ;Save some registers
2022
2023                 ; --- Load current and maximum width and height ---
2024
2025                 MOV     R8,R1                   ;Look after this address
2026                 LDMIB   R8,{R4-R7}              ;Load the window dimensions
2027                 SUB     R6,R6,R4                ;Find the window width
2028                 SUB     R7,R7,R5                ;And its height
2029
2030                 ADD     R14,R10,#vw__extent     ;Find the current extent
2031                 LDMIA   R14,{R0-R3}             ;Load the dimensions out
2032                 SUB     R4,R2,R0                ;Find the maximum width
2033                 SUB     R5,R3,R1                ;And the maximum height
2034                 LDR     R14,[R10,#vw__flags]    ;Load the flags word
2035                 TST     R14,#vwFlag__opened     ;Has viewer ever been opened?
2036                 BNE     %f00                    ;Yes -- skip onwards
2037
2038                 ; --- Set up special values for first time ---
2039
2040                 MOV     R4,#0                   ;No -- force width to max
2041                 MOV     R5,#0                   ;And height forced to max
2042                 LDR     R6,[R10,#vw__fixedWidth] ;Set a default width though
2043                 CMP     R6,#vw__minWidth        ;Get the minimum width
2044                 MOVCC   R6,#vw__minWidth        ;If too small, use this
2045                 MOV     R7,#vw__minHeight       ;Use the minimum height too
2046
2047                 ; --- Find out if we have anything to do horizontally ---
2048                 ;
2049                 ; We only try to extend if the window is currently as wide
2050                 ; as it will go.
2051
2052 00              CMP     R6,R4                   ;Does the width shape up?
2053                 BCC     %50vw__extend           ;No -- skip to vertical
2054
2055                 ; --- Extend the width ---
2056                 ;
2057                 ; We ensure that the width of the window is the smaller
2058                 ; of the maximum width we allow and the width of the number
2059                 ; of icons in the window.
2060
2061                 MOV     R0,#vw__maxWidth        ;Get the maximum width
2062                 LDR     R3,[R10,#vw__iconWidth] ;Find the icon width
2063                 ADD     R3,R3,#vw__iconGap      ;And add on the gap as usual
2064                 MOV     R1,R3                   ;Divide by this
2065                 BL      divide                  ;Divide one by the other
2066                 LDR     R1,[R10,#vw__icons]     ;Load total number of icns
2067                 CMP     R0,R1                   ;Which one is bigger?
2068                 MOVCS   R0,R1                   ;Use the smaller
2069                 CMP     R0,#0                   ;Are there no icons at all?
2070                 MOVEQ   R0,#1                   ;None -- make space for one
2071                 MUL     R0,R3,R0                ;Work out new improved width
2072                 ADD     R0,R0,#vw__iconGap      ;Add on the extra border
2073                 CMP     R6,R0                   ;Which is bigger?
2074                 MOVCC   R6,R0                   ;Use the bigger of the two
2075
2076                 ; --- Now do things vertically ---
2077                 ;
2078                 ; This is basically the same.  We only extend if the window
2079                 ; is as tall at it will go.
2080
2081 50vw__extend    CMP     R7,R5                   ;Does the height shape up?
2082                 BCC     %90vw__extend           ;No -- skip on then
2083
2084                 ; --- Extend the height ---
2085                 ;
2086                 ; This is trickier, because we have to work out how many
2087                 ; icons there will be vertically.
2088
2089                 LDR     R3,[R10,#vw__iconHeight] ;Load the icon height
2090                 ADD     R3,R3,#vw__iconGap      ;Add on the inter-icon gap
2091                 SUB     R0,R6,#vw__iconGap      ;Get the current width
2092                 LDR     R1,[R10,#vw__iconWidth] ;Find the icon width
2093                 ADD     R1,R1,#vw__iconGap      ;And add on the gap as usual
2094                 BL      divide                  ;Find how many will fit
2095
2096                 MOV     R1,R0                   ;We will divide by this
2097                 LDR     R0,[R10,#vw__icons]     ;Load the number of icons
2098                 BL      divide                  ;Work out number down
2099                 CMP     R1,#0                   ;Is there a remainder?
2100                 ADDNE   R0,R0,#1                ;Yes -- extra one then
2101                 CMP     R0,#0                   ;Are there no icons?
2102                 MOVEQ   R0,#1                   ;None -- make space for one
2103                 MOV     R2,R0                   ;Look after this value
2104
2105                 MOV     R0,#vw__maxHeight       ;Get the maximum height
2106                 MOV     R1,R3                   ;And the icon height
2107                 BL      divide                  ;Do the division again
2108                 CMP     R0,R2                   ;Which one is bigger?
2109                 MOVCS   R0,R2                   ;Use the smaller
2110                 MUL     R0,R3,R0                ;Work out new improved height
2111                 ADD     R0,R0,#vw__iconGap      ;Add on the extra border
2112                 LDR     R14,[R10,#vw__banner]   ;Do we have a banner string?
2113                 CMP     R14,#0                  ;Quick check for that...
2114                 ADDNE   R0,R0,#vw__banHeight    ;Yes -- add that on too
2115                 CMP     R7,R0                   ;Which is bigger?
2116                 MOVCC   R7,R0                   ;Use the bigger
2117
2118                 ; --- Now update the window block ---
2119
2120 90vw__extend    LDMIB   R8,{R0-R3}              ;Load the current values
2121                 ADD     R2,R0,R6                ;Work out new right side
2122                 SUBS    R1,R3,R7                ;And the new bottom
2123                 SUBLT   R3,R3,R1                ;Move the top if hit bottom
2124                 SUBLT   R1,R1,R1                ;And move the bottom too
2125                 STMIB   R8,{R0-R3}              ;Save that lot back again
2126                 LDMFD   R13!,{R0-R8,PC}^        ;And return to caller
2127
2128                 LTORG
2129
2130 ;----- Viewer block structure -----------------------------------------------
2131 ;
2132 ; This is shadowed by gallery.s -- keep them in step.
2133
2134                 ^       0
2135
2136                 ; --- Information about the window ---
2137
2138 vw__window      #       4                       ;Window handle
2139 vw__extent      #       16                      ;Current window extent
2140 vw__flags       #       4                       ;Any flags of interest
2141 vw__list        #       4                       ;Pointer to list head
2142 vw__listDef     #       4                       ;Pointer to list handler
2143 vw__handler     #       12                      ;Viewer's event handler
2144 gl__handler     #       4                       ;Gallery's event handler
2145 vw__shape       #       4                       ;Shape handler function
2146 vw__banner      #       4                       ;Pointer to banner string
2147 vw__fixedWidth  #       4                       ;Width of banner/title
2148
2149                 ; --- Icon sizing information ---
2150
2151 vw__icons       #       4                       ;Cache number of icons
2152 vw__stdDimens   #       8                       ;`Standard' width and height
2153 vw__iconWidth   #       4                       ;Width of icons currently
2154 vw__iconHeight  #       4                       ;Height of icons currently
2155 vw__across      #       4                       ;Number of icons across
2156 vw__down        #       4                       ;Number of icons down
2157
2158                 ; --- Data for default selection model ---
2159
2160 vw__tempSel     #       4                       ;Temporary selected icon
2161
2162                 ; --- Big buffers at the end ---
2163
2164 vw__title       #       256                     ;Title bar buffer
2165
2166 vw__size        #       0                       ;Size of a viewer block
2167
2168                 ; --- Flags bits ---
2169                 ;
2170                 ; Gallery `borrows' top-end flags bits here
2171
2172 vwFlag__opened  EQU     (1<<0)                  ;Has the window been opened?
2173
2174 ;----- Constants ------------------------------------------------------------
2175
2176 vw__iconGap     EQU     16                      ;Gap between icons
2177 vw__banHeight   EQU     48                      ;Height of viewer banner
2178
2179 vw__minWidth    EQU     380                     ;Minimum width for a viewer
2180 vw__minHeight   EQU     160                     ;Minimum height
2181
2182 vw__titleAdd    EQU     164                     ;Fudge factor to add to title
2183 vw__banAdd      EQU     64                      ;Fudge factor for the banner
2184
2185 vw__maxWidth    EQU     900-vw__iconGap         ;Maximum width of a viewer
2186 vw__maxHeight   EQU     700-vw__iconGap         ;Maximum height of a viewer
2187
2188 ;----- List definition format -----------------------------------------------
2189
2190                 ^       0
2191 vw__itemToIndex #       4                       ;Item to index routine
2192                                                 ;Entry: R0 == pointer to list
2193                                                 ;       R1 == pointer to item
2194                                                 ;Exit:  R1 == index, or -1
2195
2196 vw__indexToItem #       4                       ;Index to item routine
2197                                                 ;Entry: R0 == pointer to list
2198                                                 ;       R1 == index of item
2199                                                 ;Exit:  R1 == item ptr, or 0
2200
2201 vw__enumerate   #       4                       ;Enumeration function
2202                                                 ;Entry: R0 == list pointer
2203                                                 ;       R1 == item, or 0
2204                                                 ;       R2 == BIC mask
2205                                                 ;       R3 == test mask
2206                                                 ;Exit:  CS if match, and
2207                                                 ;       R1 == item ptr
2208
2209 vw__items       #       4                       ;Function to return items
2210                                                 ;Entry: R0 == list pointer
2211                                                 ;Exit:  R1 == number of items
2212
2213 vw__setFlags    #       4                       ;Function to set/read flags
2214                                                 ;Entry: R1 == pointer to item
2215                                                 ;       R2 == BIC mask
2216                                                 ;       R3 == EOR mask
2217                                                 ;Exit:  R2 == new flags
2218
2219 ;----- Shape function reason codes ------------------------------------------
2220
2221                 ^       0
2222 vwShape_size    #       1                       ;Read an icon's size
2223                                                 ;Entry: R1 == list item
2224                                                 ;       R2,R3 == std size
2225                                                 ;Exit:  R2,R3 == actual size
2226
2227 vwShape_intersects #    1                       ;Does icon intersect box?
2228                                                 ;Entry: R1 == list item
2229                                                 ;       R2 == ptr to icon box
2230                                                 ;       R3 == ptr to box
2231                                                 ;Exit:  CS if intersect
2232
2233 vwShape_slowBit #       1                       ;Does slow bit need redraw?
2234                                                 ;Entry: R1 == list item
2235                                                 ;       R2 == ptr to icon box
2236                                                 ;       R3 == ptr to box
2237                                                 ;Exit:  CS if intersect
2238
2239 ;----- Viewer event codes ---------------------------------------------------
2240
2241                 ^       0
2242 vwEvent_close   #       1                       ;User has closed the window
2243
2244 vwEvent_click   #       1                       ;User has clicked an icon
2245                                                 ;R1 == icon handle (or 0)
2246                                                 ;R2 == mouse status
2247
2248 vwEvent_double  #       1                       ;User has double-clicked
2249                                                 ;R1 == icon handle (or 0)
2250                                                 ;R2 == mouse status
2251
2252 vwEvent_drag    #       1                       ;User has dragged the mouse
2253                                                 ;R1 == icon handle (or 0)
2254                                                 ;R2 == mouse status
2255
2256 vwEvent_menu    #       1                       ;User has clicked menu
2257                                                 ;R1 == icon handle (or 0)
2258                                                 ;R2 == mouse status
2259
2260 vwEvent_redraw  #       1                       ;Redraw a viewer icon
2261                                                 ;R1 == icon handle
2262                                                 ;R2 == pointer to coords blk
2263                                                 ;R3 == pointer to clip blk
2264                                                 ;R5,R6 == window origin
2265
2266 vwEvent_drop    #       1                       ;File dropped on the viewer
2267                                                 ;R1 == filetype of data
2268                                                 ;R2 == estimated size
2269                                                 ;R3 == address of filename
2270                                                 ;R4 == drop type
2271
2272 vwEvent_help    #       1                       ;Help request for the viewer
2273                                                 ;R1 == icon handle, or 0
2274
2275 vwEvent_key     #       1                       ;Key pressed
2276                                                 ;R1 == key code (translated)
2277                                                 ;Return CS if used, else CC
2278
2279 vwEvent_dragged #       1                       ;Icons dropped on a window
2280                                                 ;R1 == destination window
2281                                                 ;R2 == destination icon
2282
2283 vwEvent_sprite  #       1                       ;Return sprite name to use
2284                                                 ;Entry: R1 == icon handle
2285                                                 ;         (-1 for many)
2286                                                 ;Exit:  CS if sprite found,
2287                                                 ;       R0 == ptr to spr area
2288                                                 ;       R1 == pointer to name
2289                                                 ;       else CC
2290
2291 vwEvent_open    #       1                       ;The viewer has been moved
2292                                                 ;R1 == ptr to open/state blk
2293
2294 vwEvent_draw    #       1                       ;Slowly redraw icon
2295                                                 ;R1 == icon handle
2296                                                 ;R2 == pointer to coords blk
2297                                                 ;R3 == pointer to clip blk
2298                                                 ;R5,R6 == window origin
2299                                                 ;(Event only used by gallery)
2300
2301 vwEvent_unDraw  #       1                       ;Undraw temporary part
2302                                                 ;R1 == icon handle
2303                                                 ;R2 == pointer to coords blk
2304                                                 ;R3 == pointer to clip blk
2305                                                 ;R5,R6 == window origin
2306                                                 ;(Event only used by gallery)
2307
2308                 ; --- Drop event subreason codes ---
2309
2310                 ^       0
2311 vwDrop_save     #       1                       ;File from another app
2312 vwDrop_load     #       1                       ;File from filing system
2313
2314 ;----- That's all, folks ----------------------------------------------------
2315
2316                 END