chiark / gitweb /
Initial revision
[ssr] / StraySrc / SapphToys / !DrawX / s / drawX
1
2 ; drawX.s
3 ;
4 ; An example of various Sapphire features (MDW)
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; DrawX is free software; you can redistribute it and/or modify
12 ; it under the terms of the GNU General Public License as published by
13 ; the Free Software Foundation; either version 2, or (at your option)
14 ; any later version.
15 ;
16 ; DrawX is distributed in the hope that it will be useful,
17 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ; GNU General Public License for more details.
20 ;
21 ; You should have received a copy of the GNU General Public License
22 ; along with DrawX.  If not, write to the Free Software Foundation,
23 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25 ;----- Notes ----------------------------------------------------------------
26 ;
27 ; This application is a DrawFile viewer -- not even slightly useful in
28 ; itself (although it uses the same amount of memory as Draw needs
29 ; workspace!), but it does provide quite a neat demonstration of the
30 ; following Sapphire features, and provides examples of how to use them:
31 ;
32 ; * dialogue boxes and custom dialogue box controls (arrow and numWrite)
33 ; * error handling
34 ; * memory management
35 ; * drawfile rendering
36 ; * data transfer
37 ; * menu handling
38 ; * command line processing
39 ; * loading preferences
40 ;
41 ; It demonstrates dragging objects inside windows -- the code is fairly
42 ; similar in structure to Glass's drag code, except that in the interests
43 ; of keeping code size down I've not done rotating dash boxes.
44 ;
45 ; The other interesting feature exhibited is that the image for this
46 ; application is just over half the size of the Acorn equivalent `DrawEx',
47 ; which (a) doesn't support multiple drawfiles unless you hack it, (b)
48 ; doesn't do zooming or dragging, and (c) doesn't support Help.
49 ;
50 ;                                                       Mark Wooding
51
52 ;----- Standard header ------------------------------------------------------
53
54                 GET     libs:header
55                 GET     libs:swis
56
57                 GET     libs:stream
58
59 ;----- External dependencies ------------------------------------------------
60
61                 ; --- Sapphire ---
62
63                 GET     sapphire:sapphire
64
65                 GET     sapphire:akbd
66                 GET     sapphire:alloc
67                 GET     sapphire:banner
68                 GET     sapphire:buttons
69                 GET     sapphire:cmdLine
70                 GET     sapphire:dbox
71                 GET     sapphire:defHandler
72                 GET     sapphire:divide
73                 GET     sapphire:drag
74                 GET     sapphire:draw
75                 GET     sapphire:errorBox
76                 GET     sapphire:event
77                 GET     sapphire:fastMove
78                 GET     sapphire:flex
79                 GET     sapphire:heap
80                 GET     sapphire:help
81                 GET     sapphire:hour
82                 GET     sapphire:ibicon
83                 GET     sapphire:idle
84                 GET     sapphire:intKeys
85                 GET     sapphire:libOpts
86                 GET     sapphire:mbox
87                 GET     sapphire:menu
88                 GET     sapphire:menuDefs
89                 GET     sapphire:msgs
90                 GET     sapphire:progInfo
91                 GET     sapphire:ptr
92                 GET     sapphire:report
93                 GET     sapphire:res
94                 GET     sapphire:resources
95                 GET     sapphire:screen
96                 GET     sapphire:string
97                 GET     sapphire:warning
98                 GET     sapphire:wimp
99                 GET     sapphire:win
100                 GET     sapphire:winUtils
101
102                 GET     sapphire:choices.choices
103                 GET     sapphire:choices.options
104                 GET     sapphire:choices.prefs
105
106                 GET     sapphire:dbx.dbx
107                 GET     sapphire:dbx.arrow
108                 GET     sapphire:dbx.numWrite
109
110                 GET     sapphire:xfer.load
111                 GET     sapphire:xfer.save
112                 GET     sapphire:xfer.saveAs
113
114                 ; --- Other external symbols ---
115
116                 IMPORT  version
117                 IMPORT  cright
118
119 ;----- Constants ------------------------------------------------------------
120
121                 ; --- Icon numbers ---
122
123 bnr__version    EQU     4                       ;The version display area
124 bnr__slider     EQU     6                       ;The progress slider bar
125
126 scale__write    EQU     0                       ;The scale writable icon
127 scale__up       EQU     1                       ;The scale up arrow button
128 scale__down     EQU     2                       ;The scale down arrow button
129 scale__toScreen EQU     4                       ;The Scale to screen action
130 scale__toWindow EQU     5                       ;The Scale to window action
131 scale__buttons  EQU     6                       ;The 8 set scale buttons
132 scale__ok       EQU     14                      ;And the OK button
133
134 info__name      EQU     1                       ;The DrawFile name area
135 info__size      EQU     3                       ;The file size area
136
137                 ; --- Menu items ---
138
139 im__info        EQU     0                       ;The program info option
140 im__quit        EQU     1                       ;The quit application option
141
142 mm__info        EQU     0                       ;The file info option
143 mm__save        EQU     1                       ;The save drawfile option
144 mm__scale       EQU     2                       ;The scale option
145
146                 ; --- Other constants ---
147
148 drawX__topY     EQU     940                     ;Maximum height for diagrams
149 drawX__bottomY  EQU     700                     ;Minimum height for diagrams
150 drawX__startY   EQU     844                     ;Initial height for diagrams
151
152 drawX__filetype EQU     &AFF                    ;The filetype of a DrawFile
153
154 ;----- Data structures ------------------------------------------------------
155
156                 ; --- Window blocks ---
157
158                 ^       0
159 dWin__window    #       4                       ;The window handle
160 dWin__flags     #       4                       ;Various flags
161 dWin__diagram   #       4                       ;Flex anchor for diagram
162 dWin__diagSize  #       4                       ;Size of the diagram
163 dWin__scale     #       4                       ;Scale of diagram (as 16.16)
164 dWin__extent    #       16                      ;The window's extent size
165 dWin__filename  #       256                     ;The diagram's filename
166 dWin__titleBar  #       256                     ;The diagram's title buffer
167 dWin__size      #       0
168
169 dwFlag__loaded  EQU     (1<<0)                  ;File has a good filename
170 dwFlag__hasDiag EQU     (1<<1)                  ;There is an actual diagram
171 dwFlag__saving  EQU     (1<<2)                  ;This diagram is being saved
172 dwFlag__tent    EQU     (1<<3)                  ;Diagram block is tentative
173
174                 ; --- Preferences data ---
175
176                 ^       0
177 dPref__defScale #       4                       ;Default document scale
178 dPref__size     #       0
179
180 ;----- Workspace ------------------------------------------------------------
181
182                 ^       0,R12
183 drawX__wStart   #       4
184
185 drawX__prefs    #       dPref__size             ;User's preferences
186 drawX__winY     #       4                       ;y position for next window
187 drawX__flags    #       4                       ;Various interesting flags
188 drawX__pollBlk  #       256                     ;The main polling block
189
190 dxFlag__drag    EQU     (1<<0)                  ;In midst of drag operation
191 dxFlag__ownPtr  EQU     (1<<1)                  ;We own the mouse pointer
192
193 drawX__wSize    EQU     {VAR}-drawX__wStart
194
195 ;----- Initialisation -------------------------------------------------------
196
197                 AREA    |Client$$Code|,CODE,READONLY
198                 ENTRY
199
200 drawX__main     ROUT
201
202                 ; --- Start up the library ---
203
204                 ADR     R0,drawX__appName       ;Point to application name
205                 MOV     R1,#drawX__wSize        ;Get my workspace size
206                 MOV     R2,#0                   ;Default stack size
207                 BL      sapphire_init           ;Initialise the library
208                 BL      resources_init          ;Use shared resource DLL
209                 BL      hour_init               ;Initialise hourglass system
210                 BL      hour_on                 ;Turn on hourglass as needed
211
212                 MOV     R0,#0                   ;This is the first pass
213                 BL      drawX__cmdLine          ;Read the command line
214                 SWICS   OS_Exit                 ;If helped, return to caller
215
216                 ; --- Do various bits of initialisation ---
217
218                 ADR     R0,drawX__banner        ;Point to banner block
219                 MOV     R1,R12                  ;Pass setup code my R12 value
220                 BL      banner                  ;Initialise the library
221                 BL      drawX__init             ;Initialise workspace
222                 BL      drawX__iconbar          ;Put the icon on the iconbar
223                 BL      drawX__getPrefs         ;Load the preferences
224                 BL      heap_useHeap            ;Allocate things from heap
225                 BL      ptr_blinkOn             ;Enable caret blinking
226                 MOV     R0,#1                   ;This is the second pass
227                 BL      drawX__cmdLine          ;Parse the command line
228
229                 ; --- Enter the main loop ---
230
231                 BL      drawX__errors           ;Set up the error return pt
232 00drawX__main   MOV     R0,#1                   ;Don't use idles pointlessly
233                 ADR     R1,drawX__pollBlk       ;Point to my poll block
234                 BL      event_poll              ;Get an event and handle it
235                 BLCC    drawX__unknowns         ;Handle any unknown events
236                 BLCC    defHandler              ;Supply a default action
237                 B       %00drawX__main          ;And go round for another one
238
239 drawX__appName  DCB     "DrawX",0
240
241 drawX__banner   BANNER
242                 BNSLIDE bnr__slider
243                 BNSETUP drawX__bnrSetup
244                 BNEND
245
246 ; --- drawX__errors ---
247 ;
248 ; On entry:     --
249 ;
250 ; On exit:      --
251 ;
252 ; Use:          Sets up the error handler to return to this routine's return
253 ;               address
254
255 drawX__errors   ROUT
256
257                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
258                 BIC     R0,R14,#&FC000003       ;Set up the resume address
259                 MOV     R1,R12                  ;Set up workspace on return
260                 ADD     R2,R13,#16              ;And set up return stack ptr
261                 BL      report_register         ;Set up the return point
262                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
263
264                 LTORG
265
266 ; --- drawX__init ---
267 ;
268 ; On entry:     --
269 ;
270 ; On exit:      --
271 ;
272 ; Use:          Initialises DrawX's workspace.
273
274 drawX__init     ROUT
275
276                 STMFD   R13!,{R14}              ;Save the link register
277                 MOV     R14,#drawX__startY      ;Default diagram height
278                 STR     R14,drawX__winY         ;Save the y coordinate
279                 MOV     R14,#0                  ;Clear the flags word
280                 STR     R14,drawX__flags        ;Store that away
281                 LDMFD   R13!,{PC}^              ;Return to caller
282
283                 LTORG
284
285 ; --- drawX__bnrSetup ---
286 ;
287 ; On entry:     R0 == banner dialogue handle
288 ;
289 ; On exit:      --
290 ;
291 ; Use:          Fills in fields of the opening banner dialogue box.
292
293 drawX__bnrSetup ROUT
294
295                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
296                 MOV     R1,#bnr__version        ;Get the version icon
297                 LDR     R2,=version             ;Find the version string
298                 BL      dbox_setField           ;Fill in the icon nicely
299                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
300
301                 LTORG
302
303 ; --- drawX__getPrefs ---
304 ;
305 ; On entry:     --
306 ;
307 ; On exit:      --
308 ;
309 ; Use:          Loads the application's preferences file.
310
311 drawX__getPrefs ROUT
312
313                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
314
315                 ; --- Initialise the preferences area ---
316
317                 ADR     R0,drawX__prefs         ;Point to prefs buffer
318                 ADR     R1,drawX__defaults      ;Point to default values
319                 MOV     R2,#dPref__size         ;Size of the data
320                 BL      fastMove                ;Initialise the buffer
321
322                 ; --- Now read in the preferences ---
323
324                 BL      prefs_find              ;Find the prefs chunk file
325                 ADR     R1,drawX__appName       ;Use my name as the chunk
326                 ADR     R2,drawX__optDefs       ;Point to options definition
327                 ADR     R3,drawX__prefs         ;Point to preferences buffer
328                 MOV     R4,#-1                  ;It's not in a flex block
329                 BL      options_read            ;Read the preferences
330
331                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
332
333 drawX__defaults DCD     100                     ;Initialise default scale
334
335 drawX__optDefs  OPTINT  dPref__defScale,"DefaultScale"
336                 OPTEND
337
338                 LTORG
339
340 ; --- drawX__cmdLine ---
341 ;
342 ; On entry:     R0 == 0 for first pass, 1 for second pass
343 ;
344 ; On exit:      CS if help given, CC otherwise
345 ;
346 ; Use:          Parses the DrawX command line, loading documents as required.
347
348 drawX__cmdLine  ROUT
349
350                 STMFD   R13!,{R0-R4,R10,R14}    ;Save a load of registers
351                 MOV     R4,R0                   ;Look after pass flag
352                 SWI     OS_GetEnv               ;Find the command line
353                 MOV     R1,R11                  ;Build in the scratchpad
354                 BL      cl_next                 ;Skip the application name
355                 BCC     %90drawX__cmdLine       ;If nothing there, skip
356                 MOV     R3,R0                   ;Look after the cmdline ptr
357
358                 ; --- The main parsing loop ---
359
360 00              MOV     R0,R3                   ;Point to command line
361                 ADR     R1,drawX__pollBlk       ;Build in the poll block
362                 BL      cl_next                 ;Get next word from cmdline
363                 BCC     %90drawX__cmdLine       ;If nothing there, skip
364
365                 MOV     R3,R0                   ;Keep place in string
366                 ADR     R0,drawX__cmdTable      ;Point to keyword table
367                 BL      str_match               ;Find which name matches
368                 ADDCS   PC,PC,R0,LSL #2         ;If match, use branch table
369                 B       %05drawX__cmdLine       ;If no match, load file
370
371                 B       %10drawX__cmdLine       ;Give help to the user
372                 B       %15drawX__cmdLine       ;Enable Choices support
373                 B       %20drawX__cmdLine       ;Use a Dynamic Area
374
375                 ; --- Load a file ---
376
377 05              TST     R4,#1                   ;Which pass is this?
378                 BEQ     %00drawX__cmdLine       ;First -- don't load then
379
380                 MOV     R0,R1                   ;Point to filename again
381                 MOV     R10,#0                  ;No diagram handle yet
382                 BL      drawX__loadFile         ;Try loading the file
383                 BLVC    drawX__loaded           ;If loaded, make it nice
384                 MOVVS   R1,#1                   ;Otherwise set up error
385                 BLVS    drawX__loadFail         ;And tidy up after it
386                 B       %00drawX__cmdLine       ;And parse more command line
387
388                 ; --- Give command line help ---
389
390 10              ADR     R0,drawX__cmdHelp       ;Point to command line help
391                 MOV     R1,#0                   ;Use internal dictionary
392                 LDR     R2,=version             ;Find my version string
393                 SWI     OS_PrettyPrint          ;Print the string
394                 ORR     R4,R4,#2                ;Remember we gave some help
395                 B       %00drawX__cmdLine       ;And parse more command line
396
397                 ; --- Enable the Choices application ---
398
399 15              TST     R4,#1                   ;Is this the first pass?
400                 MOVEQ   R0,#1                   ;Set Choices support on
401                 BLEQ    choices_useChoices      ;Turn the support on
402                 B       %00drawX__cmdLine       ;And parse more command line
403
404                 ; --- Enable use of Dynamic Areas ---
405
406 20              TST     R4,#1                   ;Is this the first pass?
407                 ADREQ   R0,drawX__opts          ;Yes -- point to options
408                 BLEQ    libOpts_register        ;And register them
409                 B       %00drawX__cmdLine       ;And parse more command line
410
411                 ; --- Return to caller nicely ---
412
413 90              TST     R4,#2                   ;Did we give any help?
414                 LDMFD   R13!,{R0-R4,R10,R14}    ;Restore registers
415                 ORRNES  PC,R14,#C_flag          ;If so, set C flag on exit
416                 BICEQS  PC,R14,#C_flag          ;Otherwise clear it
417
418 drawX__cmdTable DCB     "-help",0
419                 DCB     "-choices",0
420                 DCB     "-dynArea",0
421                 DCB     0
422
423 drawX__cmdHelp  DCB     "DrawX v. ",27,0,13
424                 DCB     13
425                 DCB     "Usage: *DrawX [<options>] [<filename>]...",13
426                 DCB     13
427                 DCB     "Options allowed are:",13
428                 DCB     13
429                 DCB     "-choices",9,"Store options in Acorn's `Choices' "
430                 DCB     "directory",13
431                 DCB     "-dynArea",9,"Use a Dynamic Area for memory "
432                 DCB     "management",13
433                 DCB     0
434
435 drawX__opts     LIBOPT  "FLEX"                  ;Tell flex to use a dynamic
436                 DCD     1                       ;area if it can
437                 LOEND
438
439                 LTORG
440
441 ;----- The icon bar ---------------------------------------------------------
442
443 ; --- drawX__iconbar ---
444 ;
445 ; On entry:     --
446 ;
447 ; On exit:      --
448 ;
449 ; Use:          Installs the DrawX icon on the icon bar
450
451 drawX__iconbar  ROUT
452
453                 STMFD   R13!,{R0-R6,R14}        ;Save some registers
454                 ADR     R0,drawX__sprName       ;Point to the sprite name
455                 MOV     R1,#0                   ;No text required
456                 MOV     R2,#-1                  ;Left hand side of iconbar
457                 MOV     R3,#0                   ;Standard priority please
458                 ADR     R4,drawX__ibHandler     ;Point to my event handler
459                 MOV     R5,#0                   ;No value in R10
460                 MOV     R6,R12                  ;Pass workspace in R12
461                 BL      ibicon_create           ;Create the icon
462                 SWIVS   OS_GenerateError        ;If it failed, kill the app
463                 LDMFD   R13!,{R0-R6,PC}^        ;Return to caller
464
465 drawX__sprName  DCB     "!drawx",0
466
467                 LTORG
468
469 ; --- drawX__ibHandler ---
470 ;
471 ; On entry:     R0 == icon bar event type
472 ;               R1-R9 == dependent on event type
473 ;
474 ; On exit:      --
475 ;
476 ; Use:          Handles events directed at the icon bar.
477
478 drawX__ibHandler ROUT
479
480                 CMP     R0,#ibEvent_help        ;Is it an event I recognise?
481                 ADDLS   PC,PC,R0,LSL #2         ;Yes -- dispatch to handler
482                 MOVS    PC,R14                  ;Otherwise return to caller
483
484                 B       drawX__ibSelect         ;Handle a mouse click
485                 B       drawX__ibMenu           ;Handle a Menu click
486                 MOVS    PC,R14                  ;Ignore Adjust clicks
487                 B       drawX__ibData           ;Handle a data save
488                 B       drawX__ibData           ;Handle a data load
489                 B       drawX__ibHelp           ;Handle help requests
490
491                 ; --- Handle Select clicks on the icon ---
492
493 drawX__ibSelect STMFD   R13!,{R0,R1,R10,R14}    ;Save the link register
494                 MOV     R0,#0                   ;No filename for the diagram
495                 BL      drawX__newDiag          ;Create a new diagram
496                 BLVC    drawX__setTitle         ;Set the window's title
497                 BLVC    drawX__open             ;Open the window nicely
498                 BLVC    drawX__cascade          ;If it worked, do cascading
499                 MOVVS   R1,#1                   ;Otherwise report the error
500                 BLVS    errorBox                ;With just an OK button
501                 LDMFD   R13!,{R0,R1,R10,PC}^    ;Return to caller
502
503                 ; --- Handle data transfer to the icon ---
504
505 drawX__ibData   STMFD   R13!,{R0,R1,R10,R14}    ;Save some registers
506                 BL      event_last              ;Find the last event code
507                 LDR     R0,[R1,#40]             ;Load the data filetype
508                 MOV     R10,#0                  ;No diagram created currently
509                 BL      drawX__load             ;Load the file
510                 LDMFD   R13!,{R0,R1,R10,PC}^    ;Return to caller
511
512                 ; --- Handle menu clicks on the icon ---
513
514 drawX__ibMenu   STMFD   R13!,{R0-R3,R14}        ;Save some registers
515                 ADR     R0,drawX__imDef         ;Point to the icon bar menu
516                 ADR     R1,drawX__imHnd         ;Point to the handler code
517                 MOV     R2,R10                  ;Pass my R10 value along
518                 MOV     R3,R12                  ;And my workspace pointer
519                 BL      menu_create             ;And create the menu
520                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
521
522                 ; --- Define the icon bar menu ---
523
524 drawX__imDef    MENU    "DrawX"
525                 ITEM    "drxIMINFO"
526                 SUBWARN
527                 ITEM    "drxIMQUIT"
528                 MENUEND
529
530                 ; --- Handle help requests ---
531
532 drawX__ibHelp   STMFD   R13!,{R0,R14}           ;Save some registers
533                 ADR     R0,drawX__ibHlpMsg      ;Point to the message tag
534                 BL      msgs_lookup             ;Translate the message
535                 BL      help_add                ;Add it to the help message
536                 LDMFD   R13!,{R0,PC}^           ;Return to caller
537
538 drawX__ibHlpMsg DCB     "drxhIB",0
539
540                 LTORG
541
542 ; --- drawX__imHnd ---
543 ;
544 ; On entry:     R0 == menu event code
545 ;               R1 == item number in menu
546 ;
547 ; On exit:      --
548 ;
549 ; Use:          Handles events for the icon bar menu.
550
551 drawX__imHnd    ROUT
552
553                 CMP     R0,#mEvent_help         ;Is it a help request?
554                 BEQ     %50drawX__imHnd         ;Yes -- handle it nicely
555                 CMP     R0,#mEvent_select       ;Is it a normal selection?
556                 CMPNE   R0,#mEvent_subMenu      ;Or opening a submenu
557                 MOVNES  PC,R14                  ;No -- ignore it then
558
559                 ; --- Handle a menu selection event ---
560
561                 CMP     R1,#im__quit            ;Is it the `Quit' option?
562                 SWIEQ   OS_Exit                 ;Yes -- quit the program
563                 CMP     R1,#im__info            ;Or is it the `Info' option?
564                 MOVNES  PC,R14                  ;No -- ignore the event
565
566                 ; --- Display info about DrawX ---
567
568                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
569                 ADR     R0,drawX__purpose       ;Point to the purpose string
570                 BL      msgs_lookup             ;Translate the message tag
571                 LDR     R1,=cright              ;Point to copyright string
572                 LDR     R2,=version             ;Find the version/date string
573                 BL      progInfo                ;Display the dialogue box
574                 MOVVS   R1,#1                   ;If it failed, report error
575                 BLVS    errorBox                ;With just an OK button
576                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
577
578 drawX__purpose  DCB     "drxPUR",0
579
580                 ; --- Handle help requests for the menu ---
581
582 50drawX__imHnd  STMFD   R13!,{R0,R1,R14}        ;Save some registers
583                 ADR     R0,drawX__imHlpMsg      ;Point to the help string
584                 BL      menu_help               ;Add message to help string
585                 LDMFD   R13!,{R0,R1,PC}^        ;Return to caller
586
587 drawX__imHlpMsg DCB     "drxhIM",0
588
589                 LTORG
590
591 ;----- Scale dialogue box ---------------------------------------------------
592
593 ; --- drawX__scale ---
594 ;
595 ; On entry:     R10 == diagram handle
596 ;
597 ; On exit:      --
598 ;
599 ; Use:          Displays a dialogue box allowing the user to scale the
600 ;               a draw file.
601
602 drawX__scale    ROUT
603
604                 STMFD   R13!,{R0-R3,R9,R14}     ;Save some registers
605
606                 ; --- Create the dialogue box ---
607
608                 ADR     R0,drawX__scaledb       ;Point to the dialogue name
609                 BL      dbox_create             ;Try to create the dialogue
610                 MOVVS   R1,#1                   ;If it failed, report the
611                 BLVS    errorBox                ;error and quit
612                 BVS     %90drawX__scale
613                 MOV     R9,R0                   ;Look after the dbox handle
614
615                 ; --- Set up the handler ---
616
617                 ADR     R1,drawX__scHnd         ;Point to the handler
618                 MOV     R2,R10                  ;Pass the diagram in R10
619                 MOV     R3,R12                  ;Pass workspace in R12
620                 BL      dbox_eventHandler       ;Set up the event handler
621
622                 ADR     R1,drawX__scaleDbx      ;Point to the dbx def
623                 BL      dbx_declare             ;Register the control types
624
625                 ; --- Fill in the dialogue box ---
626
627                 BL      drawX__fillScale        ;Fill in the scale
628
629                 ; --- Display it on the screen ---
630
631                 MOV     R1,#dbOpen_pointer+dbOpen_trans
632                 BL      dbox_open               ;Display the dialogue box
633
634 90drawX__scale  LDMFD   R13!,{R0-R3,R9,PC}^     ;Return to caller
635
636 drawX__scaledb  DCB     "scale",0
637
638 drawX__scaleDbx NUMWRT  scale__write,1,800
639                 ARROW   scale__up,1
640                 ARROW   scale__down,-1
641                 DBXEND
642
643 ; --- drawX__fillScale ---
644 ;
645 ; On entry:     R9 == dialogue box handle
646 ;               R10 == diagram handle
647 ;
648 ; On exit:      --
649 ;
650 ; Use:          Resets the scale dialogue box.
651
652 drawX__fillScale ROUT
653
654                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
655                 LDR     R2,[R10,#dWin__scale]   ;Load the current scale
656                 ADD     R2,R2,R2,LSL #2         ;Multiply it by 5 (x5)
657                 ADD     R2,R2,R2,LSL #2         ;Multiply it by 5 (x25)
658                 MOV     R2,R2,LSR #14           ;Divide it by 2^14
659                 MOV     R1,#scale__write        ;Find the writable icon
660                 MOV     R0,R9                   ;Get the dialogue handle
661                 BL      numWrite_set            ;Set the field up nicely
662                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
663
664                 LTORG
665
666 ; --- drawX__scHnd ---
667 ;
668 ; On entry:     R0 == dialogue box event code
669 ;               R1-R7 == depend on the event
670 ;               R9 == dialogue box handle
671 ;               R10 == diagram handle
672 ;
673 ; On exit:      --
674 ;
675 ; Use:          Handles events for the scale dialogue box.
676
677 drawX__scHnd    ROUT
678
679                 ; --- Dispatch interesting events ---
680
681                 CMP     R0,#arrow_event         ;Is it an arrow click?
682                 BEQ     %10drawX__scHnd         ;Yes -- handle it then
683                 CMP     R0,#dbEvent_OK          ;Is it an OK click?
684                 CMPNE   R0,#scale__ok
685                 BEQ     %30drawX__scHnd         ;Yes -- handle it then
686                 CMP     R0,#scale__toScreen     ;Is it the to screen button?
687                 BEQ     %50drawX__scHnd         ;Yes -- handle it then
688                 CMP     R0,#scale__toWindow     ;Is it the to window button?
689                 BEQ     %60drawX__scHnd         ;Yes -- handle it then
690                 CMP     R0,#dbEvent_close       ;Is it a close event?
691                 BEQ     %90drawX__scHnd         ;Yes -- kill the dbox
692                 CMP     R0,#dbEvent_help        ;Is it a help event?
693                 BEQ     %95drawX__scHnd         ;Yes -- give the user help
694
695                 ; --- It must be one of the standard scale buttons ---
696
697                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
698                 SUBS    R1,R0,#scale__buttons   ;Get the first one's handle
699                 CMP     R1,#8                   ;Is it in range?
700                 LDMCSFD R13!,{R0-R2,PC}^        ;No -- return then
701
702                 ADR     R2,drawX__stdScale      ;Point to the table
703                 LDR     R2,[R2,R1,LSL #2]       ;Load the correct one
704                 MOV     R1,R0                   ;Get the actual icon handle
705                 MOV     R0,R9                   ;Get the dialogue box
706                 BL      dbox_slab               ;Slab the button in nicely
707                 MOV     R1,#scale__write        ;Find the writable icon
708                 BL      numWrite_set            ;And fill it in nicely
709                 BL      dbox_unslab             ;Unslab the button now
710                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
711
712 drawX__stdScale DCD     33,50,66,80,100,120,200,400
713
714                 ; --- Handle an arrow click ---
715
716 10drawX__scHnd  STMFD   R13!,{R0-R2,R14}        ;Save some registers
717                 MOV     R1,#scale__write        ;Find the writable icon
718                 MOV     R0,R9                   ;Get the dialogue box
719                 BL      numWrite_bump           ;Bump the writable icon
720                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
721
722                 ; --- Handle an OK click ---
723
724 30drawX__scHnd  STMFD   R13!,{R0-R2,R14}        ;Save some registers
725                 MOV     R0,R9                   ;Get the dialogue box
726                 MOV     R1,#scale__ok           ;Find the OK button
727                 BL      dbox_slab               ;Slab the button nicely
728
729                 MOV     R1,#scale__write        ;Find the writable icon
730                 BL      numWrite_read           ;Read the icon value
731                 CMP     R2,#1                   ;Is the value too small?
732                 MOVLT   R2,#1                   ;Yes -- force it bigger
733                 MOV     R0,R2,LSL #16           ;Scale the value up
734                 ADD     R0,R0,#50               ;Make it round to nearest
735                 BL      div10                   ;Divide by 10 quickly
736                 BL      div10                   ;Divide by 10 again (/100)
737                 STR     R0,[R10,#dWin__scale]   ;This is the new scale
738                 BL      drawX__doScale          ;Set the scale nicely
739
740                 LDR     R14,[R13,#4]            ;Load the button status
741                 CMP     R14,#1                  ;Is this an Adjust click?
742                 MOVNE   R0,R9                   ;Not Adjust -- get dbox
743                 BLNE    dbox_close              ;Close the window
744                 BL      dbox_unslab             ;Unslab the icon
745                 BLNE    dbox_destroy            ;And destroy the dbox
746                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
747
748                 ; --- Scale the diagram to the screen ---
749
750 50drawX__scHnd  STMFD   R13!,{R0-R5,R14}        ;Save some registers
751                 MOV     R1,R0                   ;Get the icon handle
752                 MOV     R0,R9                   ;Get the dialogue box
753                 BL      dbox_slab               ;Slab the button
754
755                 BL      screen_getInfo          ;Get the screen information
756                 ADD     R14,R0,#screen_width    ;Find the screen sizes
757                 LDMIA   R14,{R0,R1}             ;Load them out
758                 SUB     R0,R0,#44               ;Lose the scroll bar width
759                 SUB     R1,R1,#88               ;And the titlebar height
760                 B       %70drawX__scHnd         ;Do the scaling stuff
761
762                 ; --- Scale the diagram to the window ---
763
764 60drawX__scHnd  STMFD   R13!,{R0-R5,R14}        ;Save some registers
765                 MOV     R1,R0                   ;Get the icon handle
766                 MOV     R0,R9                   ;Get the dialogue box
767                 BL      dbox_slab               ;Slab the button
768
769                 LDR     R14,[R10,#dWin__window] ;Load the window handle
770                 STR     R14,[R11,#0]            ;Save it in the scratchpad
771                 MOV     R1,R11                  ;Point at it there
772                 SWI     Wimp_GetWindowState     ;Find the window's info
773                 LDMIB   R11,{R0-R3}             ;Load all the coordinates
774                 SUB     R0,R2,R0                ;Get the window width
775                 SUB     R1,R3,R1                ;Get the window height
776
777                 ; --- Scale the diagram to fit in R0,R1 ---
778
779 70drawX__scHnd  LDR     R14,[R10,#dWin__diagram] ;Find the diagram
780                 ADD     R14,R14,#24             ;Find the bounding box
781                 LDMIA   R14,{R2-R5}             ;Load the coordinates out
782                 SUB     R4,R4,R2                ;Get the diagram width
783                 SUB     R5,R5,R3                ;And the height
784                 SUB     R0,R0,#32               ;Compensate for the clearance
785                 SUB     R1,R1,#32               ;On all four edges
786                 MOV     R0,R0,LSL #16           ;Scale the target sizes up
787                 MOV     R3,R1,LSL #16
788
789                 MOV     R1,R4                   ;Get the original width
790                 BL      div_round               ;Get the x scale factor
791                 MOV     R2,R0,LSL #8            ;Look after this value
792
793                 MOV     R0,R3                   ;Get the y target size
794                 MOV     R1,R5                   ;And the original height
795                 BL      div_round               ;Get the y scale factor
796
797                 CMP     R2,R0,LSL #8            ;Which one's smaller?
798                 MOVGT   R2,R0,LSL #8            ;Take that one
799                 STR     R2,[R10,#dWin__scale]   ;This is the new scale
800                 BL      drawX__doScale          ;Do everything nicely
801
802                 LDR     R14,[R13,#4]            ;Load the button status
803                 CMP     R14,#1                  ;Is this an Adjust click?
804                 BLEQ    drawX__fillScale        ;Yes -- reset writable area
805                 MOVNE   R0,R9                   ;Not Adjust -- get dbox
806                 BLNE    dbox_close              ;Close the window
807                 BL      dbox_unslab             ;Unslab the icon
808                 BLNE    dbox_destroy            ;And destroy the dbox
809                 LDMFD   R13!,{R0-R5,PC}^        ;Return to caller
810
811                 ; --- Close the dialogue box ---
812
813 90drawX__scHnd  STMFD   R13!,{R0,R14}           ;Save some registers
814                 MOV     R0,R9                   ;Get the dialogue handle
815                 BL      dbox_destroy            ;Destroy the dialogue box
816                 LDMFD   R13!,{R0,PC}^           ;Return to caller
817
818                 ; --- Get some help on the dialogue ---
819
820 95drawX__scHnd  STMFD   R13!,{R0-R2,R14}        ;Save some registers
821                 ADR     R0,drawX__scHlpMsg      ;Point to the help message
822                 BL      msgs_lookup             ;Translate it nicely
823                 BL      help_add                ;Add it into the message
824                 SUB     R14,R1,#scale__buttons  ;Subtract the buttons base
825                 CMP     R14,#8                  ;Is it in range?
826                 BCS     %96drawX__scHnd         ;No -- skip to the end
827                 MOV     R0,R9                   ;Get the dialogue handle
828                 BL      dbox_getField           ;Read the icon text
829                 ADR     R0,drawX__scButMsg      ;Point to the help text
830                 BL      msgs_lookup             ;Translate the message
831                 MOV     R1,R11                  ;Build it in the scratchpad
832                 BL      str_subst               ;Build the string up
833                 BL      help_add                ;Add this to the help message
834 96drawX__scHnd  BL      dbox_help               ;Get icon-specific stuff
835                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
836
837 drawX__scHlpMsg DCB     "drxhSCALE",0
838 drawX__scButMsg DCB     "drxhSCBUT",0
839
840                 LTORG
841
842 ; --- drawX__doScale ---
843 ;
844 ; On entry:     R10 == diagram handle
845 ;
846 ; On exit:      --
847 ;
848 ; Use:          Sets the diagram scale.  The tricky bit is ensuring that
849 ;               the bit the user was looking at is still vaguely visible.
850 ;               We assume that he's looking at the centre of the window and
851 ;               do our best to keep that in the centre of the scaled view.
852
853 drawX__doScale  ROUT
854
855                 STMFD   R13!,{R0-R7,R14}        ;Save some registers
856
857                 ; --- Work out where the user's looking ---
858
859                 LDR     R14,[R10,#dWin__window] ;Load the diagram window
860                 SUB     R13,R13,#36             ;Make space for a window blk
861                 STR     R14,[R13,#0]            ;Save it in the block
862                 MOV     R1,R13                  ;Point to it there
863                 SWI     Wimp_GetWindowState     ;Read its current position
864                 LDMIB   R13,{R0-R5}             ;Load all that lot out
865                 SUB     R6,R2,R0                ;Get the window width
866                 ADD     R4,R4,R6,ASR #1         ;Find the horizontal centre
867                 SUB     R7,R3,R1                ;Get the window height
868                 SUB     R5,R5,R7,ASR #1         ;Find the vertical centre
869
870                 ; --- Find where that is, relatively ---
871
872                 ADD     R14,R10,#dWin__extent   ;Find the window extent
873                 LDMIA   R14,{R0-R3}             ;Load that lot out
874                 ADD     R0,R0,#16               ;Compensate for the border
875                 ADD     R1,R1,#16
876                 SUB     R2,R2,#16
877                 SUB     R3,R3,#16
878                 SUB     R4,R4,R0                ;Get pos rel. to wind left
879                 SUB     R5,R5,R1                ;Get pos rel. to wind bottom
880                 SUB     R2,R2,R0                ;Get window extent width
881                 SUB     R3,R3,R1                ;Get window extent height
882
883                 MOV     R0,R4,LSL #16           ;Scale up horizontal pos
884                 MOV     R1,R2                   ;Get extent width
885                 BL      div_round               ;Find the proportion nicely
886                 MOV     R4,R0                   ;Look after it
887
888                 MOV     R0,R5,LSL #16           ;Scale up vertical pos
889                 MOV     R1,R3                   ;Get extent height
890                 BL      div_round               ;Find the proportion nicely
891                 MOV     R5,R0                   ;Look after that too
892
893                 ; --- Reset the extent and redo the scroll stuff ---
894
895                 BL      drawX__setExtent        ;Set the new extent
896                 ADD     R14,R10,#dWin__extent   ;Find the new window extent
897                 LDMIA   R14,{R0-R3}             ;Load that lot out
898                 ADD     R0,R0,#16               ;Compensate for the border
899                 ADD     R1,R1,#16
900                 SUB     R2,R2,#16
901                 SUB     R3,R3,#16
902                 SUB     R2,R2,R0                ;Get the new extent width
903                 SUB     R3,R3,R1                ;Get the new extent height
904                 MUL     R2,R4,R2                ;Work out the new relative
905                 MUL     R3,R5,R3                ;scroll positions
906                 ADD     R4,R0,R2,ASR #16        ;And convert them to
907                 ADD     R5,R1,R3,ASR #16        ;absolute ones
908                 SUB     R4,R4,R6,ASR #1         ;And uncentre them
909                 ADD     R5,R5,R7,ASR #1         ;
910
911                 ; --- Scroll the window nicely ---
912
913                 ADD     R14,R13,#20             ;Point to the scroll offsets
914                 STMIA   R14,{R4,R5}             ;Save them in there
915                 MOV     R1,R13                  ;Point to the block
916                 SWI     Wimp_OpenWindow         ;Open the window
917                 ADD     R13,R13,#36             ;Reclaim the stack space
918
919                 ; --- Redraw the window ---
920
921                 LDR     R0,[R10,#dWin__window]  ;Load the window handle
922                 ADD     R14,R10,#dWin__extent   ;Find the window extent
923                 LDMIA   R14,{R1-R4}             ;Load the coordinates out
924                 SWI     Wimp_ForceRedraw        ;Redraw the whole view
925                 LDMFD   R13!,{R0-R7,PC}^        ;Return to caller
926
927                 LTORG
928
929 ; --- drawX__setExtent ---
930 ;
931 ; On entry:     R10 == a diagram handle
932 ;
933 ; On exit:      --
934 ;
935 ; Use:          Resets the diagram window's extent so that the diagram
936 ;               fits inside it at its current scale.
937
938 drawX__setExtent ROUT
939
940                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
941                 LDR     R14,[R10,#dWin__diagram] ;Find the diagram address
942                 ADD     R14,R14,#24             ;Point to the bounding box
943                 LDMIA   R14,{R1-R4}             ;Load them out nicely
944                 LDR     R0,[R10,#dWin__scale]   ;Load the scale factor
945                 MOV     R0,R0,LSR #8            ;Scale that down a bit
946                 MUL     R1,R0,R1                ;Scale up all the positions
947                 MUL     R2,R0,R2
948                 MUL     R3,R0,R3
949                 MUL     R4,R0,R4
950                 MOV     R14,#16                 ;Add a gap round the edge
951                 RSB     R1,R14,R1,ASR #16       ;And scale them back down
952                 RSB     R2,R14,R2,ASR #16
953                 ADD     R3,R14,R3,ASR #16
954                 ADD     R4,R14,R4,ASR #16
955                 ADD     R14,R10,#dWin__extent   ;Point to the extent block
956                 STMIA   R14,{R1-R4}             ;Save them away there
957                 LDR     R0,[R10,#dWin__window]  ;Load the window handle
958                 ADD     R1,R10,#dWin__extent    ;Point to the coordinates
959                 SWI     Wimp_SetExtent          ;Set the new extent
960                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
961
962                 LTORG
963
964 ; --- drawX__refresh ---
965 ;
966 ; On entry:     R10 == diagram handle
967 ;
968 ; On exit:      --
969 ;
970 ; Use:          Refreshes a diagram after changing its extent
971
972 drawX__refresh  ROUT
973
974                 STMFD   R13!,{R0-R4,R14}
975                 LDR     R0,[R10,#dWin__window]  ;Load the window handle
976                 STR     R0,[R11,#0]             ;Save it in the scratchpad
977                 MOV     R1,R11                  ;Point to it there
978                 SWI     Wimp_GetWindowState     ;Get the window's position
979                 SWI     Wimp_OpenWindow         ;Open the window there
980                 LDR     R0,[R10,#dWin__window]  ;Load the window handle
981                 ADD     R14,R10,#dWin__extent   ;Find the window's extent
982                 LDMIA   R14,{R1-R4}             ;Load the coordinates
983                 SWI     Wimp_ForceRedraw        ;And clear the window
984                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
985
986                 LTORG
987
988 ;----- The main window handler ----------------------------------------------
989
990 ; --- drawX__newDiag ---
991 ;
992 ; On entry:     R0 == pointer to filename, or 0 for none
993 ;
994 ; On exit:      VC and R10 == pointer to a pristine new diagram structure, or
995 ;               VS and R0 == pointer to error, and R10 corrupted
996 ;
997 ; Use:          Creates a new diagram block and window, and opens it on
998 ;               the screen.
999
1000 drawX__newDiag  ROUT
1001
1002                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
1003
1004                 ; --- Allocate a block of memory for the diagram ---
1005
1006                 MOV     R0,#dWin__size          ;Get the size of the block
1007                 BL      alloc                   ;Try to get the memory
1008                 BLCS    alloc_error             ;If no memory, get error
1009                 BCS     %99drawX__newDiag       ;And tidy everything up
1010                 MOV     R10,R0                  ;Look after the block handle
1011
1012                 ; --- Fill in the block and set things up ---
1013
1014                 MOV     R14,#0                  ;No diagram currently
1015                 STR     R14,[R10,#dWin__diagram] ;So clear the diagram
1016                 LDR     R0,drawX__prefs+dPref__defScale
1017                 MOV     R0,R0,LSL #16           ;Scale it up
1018                 ADD     R0,R0,#50               ;Round to nearest
1019                 BL      div10                   ;And divide by 10
1020                 BL      div10                   ;And again -- now in 16.16
1021                 STR     R0,[R10,#dWin__scale]   ;And save that too
1022                 MOV     R0,#0                   ;Left hand side
1023                 MOV     R1,#0                   ;Bottom edge
1024                 MOV     R2,#640                 ;Right hand side
1025                 MOV     R3,#512                 ;Top edge
1026                 ADD     R14,R10,#dWin__extent   ;Point to the extent block
1027                 STMIA   R14,{R0-R3}             ;Save the initial extent
1028                 MOV     R3,#0                   ;No flags currently
1029
1030                 ; --- Work out the file's name ---
1031
1032                 LDR     R0,[R13,#0]             ;Load the filename pointer
1033                 CMP     R0,#0                   ;Is it defined properly?
1034                 ORRNE   R3,R3,#dwFlag__loaded   ;Yes -- say the file's loaded
1035                 ADREQ   R0,drawX__untitled      ;No -- point to default
1036                 BLEQ    msgs_lookup             ;And translate the message
1037                 MOV     R1,R0                   ;This is the source string
1038                 ADD     R0,R10,#dWin__filename  ;Point to filename buffer
1039                 BL      str_cpy                 ;Copy it in there nicely
1040
1041                 STR     R3,[R10,#dWin__flags]   ;Save the flags word away
1042
1043                 ; --- Now create a new window ---
1044
1045                 MOV     R0,R11                  ;Point at the scratchpad
1046                 ADR     R1,drawX__winDef        ;Point at the window def
1047                 MOV     R2,#drawX__winSize      ;Get the size of the window
1048                 BL      fastMove                ;Copy it to the scratchpad
1049
1050                 LDMIB   R11,{R0-R2}             ;Load top and bottom y
1051                 SUB     R0,R2,R0                ;Get height in R0
1052                 LDR     R2,drawX__winY          ;Get current cascade coord
1053                 SUB     R0,R2,R0                ;Work out correct bottom
1054                 STMIB   R11,{R0-R2}             ;Store back in the scratchpad
1055
1056                 ADD     R14,R10,#dWin__titleBar ;Point to the title buffer
1057                 STR     R14,[R11,#72]           ;Save this as buffer pointer
1058
1059                 MOV     R1,R11                  ;Point to the scratchpad
1060                 SWI     XWimp_CreateWindow      ;Try to create the window
1061                 BVS     %98drawX__newDiag       ;If it failed, tidy up
1062                 STR     R0,[R10,#dWin__window]  ;Save the window handle
1063
1064                 ; --- Register the window's event handler ---
1065
1066                 ADR     R1,drawX__winHnd        ;Point to the handler
1067                 MOV     R2,R10                  ;Pass diagram block in R10
1068                 MOV     R3,R12                  ;And workspace in R12
1069                 BL      win_eventHandler        ;Register the event handler
1070                 BVS     %97drawX__newDiag       ;If it failed, tidy up
1071
1072                 LDMFD   R13!,{R0-R3,R14}        ;Restore all the registers
1073                 BICS    PC,R14,#V_flag          ;And return with V clear
1074
1075                 ; --- Various things went wrong ---
1076
1077 97              MOV     R3,R0                   ;Look after error pointer
1078                 ADD     R1,R10,#dWin__window    ;Point at the window handle
1079                 SWI     Wimp_DeleteWindow       ;Don't want it any more
1080                 MOV     R0,R3                   ;Restore the error pointer
1081
1082 98              MOV     R3,R0                   ;Look after error pointer
1083                 MOV     R0,R10                  ;Point at my diagram block
1084                 BL      free                    ;Don't want that any more
1085                 MOV     R0,R3                   ;Restore the error pointer
1086
1087 99              ADD     R2,R0,#4                ;Point at the error text
1088                 ADR     R0,drawX__newErr        ;Point to error message
1089                 BL      msgs_error              ;Do clever things with it
1090                 ADD     R13,R13,#4              ;Don't restore R0 on exit
1091                 LDMFD   R13!,{R1-R3,R14}        ;Unstack all the registers
1092                 ORRS    PC,R14,#V_flag          ;And return with V set
1093
1094 drawX__newErr   DCD     1
1095                 DCB     "drxNEWERR",0
1096
1097 drawX__untitled DCB     "drxUNT",0
1098
1099 drawX__winDef   DCD     320,0,960,512,0,0,-1    ;Initial window position
1100                 DCD     &ff000002               ;All gadgets, moveable
1101                 DCB     7,2,7,0,3,1,12,0        ;Normal window colours
1102                 DCD     0,0,640,512             ;Initial work area size
1103                 DCD     &00000139               ;Indirect the title text
1104                 DCD     (7<<12)                 ;Respond to click and drag
1105                 DCD     1                       ;Use Wimp sprite area FWIW
1106                 DCW     1,0                     ;Allow title bar hiding
1107                 DCD     0,-1,256                ;Title bar indirection stuff
1108                 DCD     0                       ;No icons defined
1109
1110 drawX__winSize  EQU     {PC}-drawX__winDef      ;Size of the window block
1111
1112                 LTORG
1113
1114 ; --- drawX__winHnd ---
1115 ;
1116 ; On entry:     R0 == event code
1117 ;               R1 == pointer to event data
1118 ;               R10 == diagram handle
1119 ;
1120 ; On exit:      CS if I handled the event, CC otherwise
1121 ;
1122 ; Use:          Handles events directed at a diagram window.
1123
1124 drawX__winHnd   ROUT
1125
1126                 CMP     R0,#19                  ;Do I recognise the event?
1127                 ADDCC   PC,PC,R0,LSL #2         ;Yes -- dispatch it then
1128                 MOVS    PC,R14                  ;Otherwise ignore it
1129
1130                 MOVS    PC,R14                  ;NullReasonCode
1131                 B       drawX__redraw           ;RedrawWindowRequest
1132                 MOVS    PC,R14                  ;OpenWindowRequest
1133                 B       drawX__killDiag         ;CloseWindowRequest
1134                 B       drawX__ptrLeave         ;PointerLeavingWindow
1135                 B       drawX__ptrEnter         ;PointerEnteringWindow
1136                 B       drawX__click            ;MouseClicked
1137                 MOVS    PC,R14                  ;UserDragBox
1138                 MOVS    PC,R14                  ;KeyPressed
1139                 MOVS    PC,R14                  ;MenuSelection
1140                 MOVS    PC,R14                  ;ScrollRequest
1141                 MOVS    PC,R14                  ;LoseCaret
1142                 MOVS    PC,R14                  ;GainCaret
1143                 MOVS    PC,R14                  ;PollWordNonZero
1144                 MOVS    PC,R14                  ;UndefinedEvent_14
1145                 MOVS    PC,R14                  ;UndefinedEvent_15
1146                 MOVS    PC,R14                  ;UndefinedEvent_16
1147                 B       drawX__message          ;UserMessage
1148                 B       drawX__message          ;UserMessageRecorded
1149
1150                 LTORG
1151
1152 ; --- drawX__killDiag ---
1153 ;
1154 ; On entry:     R10 == diagram handle
1155 ;
1156 ; On exit:      CS
1157 ;
1158 ; Use:          Destroys a diagram.
1159
1160 drawX__killDiag ROUT
1161
1162                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
1163
1164                 ; --- Kill the diagram itself, if it exists ---
1165
1166                 LDR     R0,[R10,#dWin__diagram] ;Load the diagram anchor
1167                 CMP     R0,#0                   ;Is it a sensible value?
1168                 ADDNE   R0,R10,#dWin__diagram   ;Yes -- point to it then
1169                 BLNE    flex_free               ;And free the memory it used
1170
1171                 ; --- Destroy the diagram's window ---
1172
1173                 LDR     R0,[R10,#dWin__window]  ;Get the window handle
1174                 ADR     R1,drawX__winHnd        ;Point to the handler
1175                 MOV     R2,R10                  ;Pass diagram block in R10
1176                 MOV     R3,R12                  ;And workspace in R12
1177                 BL      win_removeEventHandler  ;Remove my event handler
1178
1179                 ADD     R1,R10,#dWin__window    ;Point to the window handle
1180                 SWI     Wimp_DeleteWindow       ;Destroy the window
1181
1182                 ; --- Destroy the diagram anchor block ---
1183
1184                 MOV     R0,R10                  ;Point at the diagram block
1185                 BL      free                    ;Destroy it
1186                 LDMFD   R13!,{R0-R3,R14}        ;Return to caller
1187                 ORRS    PC,R14,#C_flag
1188
1189                 LTORG
1190
1191 ; --- drawX__ptrEnter ---
1192 ;
1193 ; On entry:     R10 == diagram handle
1194 ;
1195 ; On exit:      --
1196 ;
1197 ; Use:          Makes the mouse pointer turn into a magnifying glass over
1198 ;               a diagram window.
1199
1200 drawX__ptrEnter ROUT
1201
1202                 STMFD   R13!,{R0-R2,R14}        ;Save some regisers
1203                 LDR     R14,drawX__flags        ;Load the flags word
1204                 ORR     R14,R14,#dxFlag__ownPtr ;We own the pointer now
1205                 STR     R14,drawX__flags        ;Store the flags back
1206
1207                 LDR     R14,[R10,#dWin__diagram] ;Load the diagram pointer
1208                 CMP     R14,#0                  ;Is it defined?
1209                 ADRNE   R0,drawX__ptrName       ;Yes -- point to the name
1210                 MOVNE   R1,#12                  ;Get the hot x position
1211                 MOVNE   R2,#6                   ;And the hot y position
1212                 BLNE    ptr_setShape            ;And set the pointer position
1213                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
1214
1215 drawX__ptrName  DCB     "ptr_zoom",0
1216
1217                 LTORG
1218
1219 ; --- drawX__ptrLeave ---
1220 ;
1221 ; On entry:     --
1222 ;
1223 ; On exit:      --
1224 ;
1225 ; Use:          Makes the pointer look normal again when it leaves a
1226 ;               diagram window.
1227
1228 drawX__ptrLeave ROUT
1229
1230                 STMFD   R13!,{R14}              ;Save link register
1231                 LDR     R14,drawX__flags        ;Load the flags word
1232                 BIC     R14,R14,#dxFlag__ownPtr ;Don't own pointer any more
1233                 STR     R14,drawX__flags        ;Save the flags back
1234                 TST     R14,#dxFlag__drag       ;Are we dragging?
1235                 BLEQ    ptr_resetShape          ;No -- remove the pointer
1236                 LDMFD   R13!,{PC}^              ;And return to caller
1237
1238                 LTORG
1239
1240 ; --- drawX__redraw ---
1241 ;
1242 ; On entry:     R1 == pointer to a redraw block
1243 ;               R10 == diagram handle
1244 ;
1245 ; On exit:      --
1246 ;
1247 ; Use:          Redraws a diagram window.
1248
1249 drawX__redraw   ROUT
1250
1251                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
1252                 SWI     Wimp_RedrawWindow       ;Start the redraw operation
1253                 CMP     R0,#0                   ;Is there anything to do?
1254                 BEQ     %90drawX__redraw        ;No -- skip to the end
1255
1256                 ; --- Do a redraw of a diagram ---
1257
1258 10drawX__redraw LDR     R0,[R10,#dWin__scale]   ;Load the current scale
1259                 ADD     R14,R10,#dWin__diagram  ;Point to the diagram
1260                 LDMIA   R14,{R2,R3}             ;Load the address and size
1261                 CMP     R2,#0                   ;Is there a diagram at all?
1262                 BLNE    draw_render             ;Yes -- then render it
1263                 BL      drag_redraw             ;And redraw the drag box
1264                 SWI     Wimp_GetRectangle       ;Get another rectangle
1265                 CMP     R0,#0                   ;Is there more to do?
1266                 BNE     %10drawX__redraw        ;Yes -- do another rectangle
1267
1268                 ; --- The redraw's over ---
1269
1270 90drawX__redraw LDMFD   R13!,{R0-R3,R14}        ;Restore registers
1271                 ORRS    PC,R14,#C_flag          ;Claim the event
1272
1273 ; --- drawX__message ---
1274 ;
1275 ; On entry:     R1 == pointer to a message block
1276 ;               R10 == diagram handle
1277 ;
1278 ; On exit:      CC or CS, depending on whether I handled it
1279 ;
1280 ; Use:          Handles a message sent to a diagram window.
1281
1282 drawX__message  ROUT
1283
1284                 STMFD   R13!,{R0,R14}           ;Save some registers
1285                 LDR     R14,[R1,#16]            ;Load the message type
1286                 LDR     R0,=&502                ;Get the help message code
1287                 CMP     R0,R14                  ;Does it match?
1288                 BEQ     %10drawX__message       ;Yes -- deal with it then
1289                 CMP     R14,#1                  ;Is it a Message_DataSave?
1290                 CMPNE   R14,#3                  ;Or a Message_DataLoad?
1291                 LDMNEFD R13!,{R0,PC}^           ;No -- return to caller
1292                 LDR     R0,[R1,#40]             ;Load the filetype word
1293                 BL      drawX__load             ;Load the file
1294                 LDMFD   R13!,{R0,PC}^           ;And return to caller
1295
1296 10              ADR     R0,drawX__viewHelp      ;Point to the message
1297                 BL      msgs_lookup             ;Translate it nicely
1298                 BL      help_add                ;Add it to the help message
1299                 LDMFD   R13!,{R0,PC}^           ;Return to caller
1300
1301 drawX__viewHelp DCB     "drxhDIAG",0
1302
1303                 LTORG
1304
1305 ; --- drawX__open ---
1306 ;
1307 ; On entry:     R10 == diagram handle
1308 ;
1309 ; On exit:      --
1310 ;
1311 ; Use:          Opens a diagram window on the screen.
1312
1313 drawX__open     ROUT
1314
1315                 STMFD   R13!,{R0,R1,R14}        ;Save some registers
1316                 LDR     R14,[R10,#dWin__window] ;Get the window handle
1317                 STR     R14,[R11,#0]            ;Save it in the scratchpad
1318                 MOV     R1,R11                  ;Point at it nicely
1319                 SWI     Wimp_GetWindowState     ;Find its current position
1320                 MOV     R14,#-1                 ;Bring it to the top
1321                 STR     R14,[R11,#28]           ;Save it in `behind' word
1322                 SWI     Wimp_OpenWindow         ;And open the new window
1323                 LDMFD   R13!,{R0,R1,PC}^        ;Return to caller
1324
1325                 LTORG
1326
1327 ; --- drawX__click ---
1328 ;
1329 ; On entry:     R1 == pointer to mouse click block
1330 ;               R10 == diagram handle
1331 ;
1332 ; On exit:      --
1333 ;
1334 ; Use:          Handles mouse clicks on a diagram.
1335
1336 drawX__click    ROUT
1337
1338                 STMFD   R13!,{R0-R5,R14}        ;Save some registers
1339                 LDR     R14,[R1,#8]             ;Load the button type
1340                 TST     R14,#&02                ;Is it a menu click?
1341                 BNE     %70drawX__click         ;Yes -- handle it then
1342                 LDR     R3,[R10,#dWin__diagram] ;Load the diagram pointer
1343                 CMP     R3,#0                   ;Is it valid?
1344                 TSTNE   R14,#&50                ;Yes -- some kind of drag?
1345                 BEQ     %90drawX__click         ;No -- ignore it then
1346
1347                 ; --- Start a drag operation ---
1348
1349                 LDR     R0,[R10,#dWin__window]  ;Load the window handle
1350                 MOV     R1,#0                   ;Give me update events
1351                 ADR     R2,drawX__dragHandler   ;Point to handler routine
1352                 MOV     R3,#0                   ;No magic number
1353                 MOV     R4,R10                  ;Pass diagram handle in R10
1354                 MOV     R5,R12                  ;Pass workspace in R12
1355                 BL      drag_start              ;Start the drag operation
1356
1357                 LDR     R14,drawX__flags        ;Load the flags word
1358                 ORR     R14,R14,#dxFlag__drag   ;We're now dragging something
1359                 STR     R14,drawX__flags        ;Save the flags back
1360                 B       %90drawX__click         ;And return to caller
1361
1362                 ; --- Handle a Menu click on the window ---
1363
1364 70drawX__click  ADR     R0,drawX__mainMenu      ;Point to the menu definition
1365                 ADR     R1,drawX__mmHnd         ;Point to the handler
1366                 MOV     R2,R10                  ;Pass diagram handle in R10
1367                 MOV     R3,R12                  ;Pass workspace in R12
1368                 BL      menu_create             ;Create the menu nicely
1369
1370 90drawX__click  LDMFD   R13!,{R0-R5,PC}^        ;Return to caller
1371
1372 drawX__mainMenu MENU    "DrawX"
1373                 ITEM    "drxMMINFO"
1374                 ISHADE  dWin__flags,dwFlag__hasDiag
1375                 SUBWARN
1376                 NOWARN
1377                 ITEM    "drxMMSAVE"
1378                 ISHADE  dWin__flags,dwFlag__hasDiag
1379                 SUBWARN
1380                 NOWARN
1381                 ITEM    "drxMMSCALE"
1382                 ISHADE  dWin__flags,dwFlag__hasDiag
1383                 SUBWARN
1384                 NOWARN
1385                 MENUEND
1386
1387                 LTORG
1388
1389 ; --- drawX__dragHandler ---
1390 ;
1391 ; On entry:     R0 == event code
1392 ;               R10 == diagram handle
1393 ;
1394 ; On exit:      --
1395 ;
1396 ; Use:          Handles a drag box.
1397
1398 drawX__dragHandler ROUT
1399
1400                 CMP     R0,#7                   ;Is it in range?
1401                 ADDCC   PC,PC,R0,LSL #2         ;Yes -- dispatch
1402                 MOVS    PC,R14                  ;Otherwise ignore it
1403
1404                 B       drawX__redrawDragBox
1405                 B       drawX__redrawDragBox
1406                 B       drawX__redrawDragBox
1407                 MOVS    PC,R14
1408                 B       drawX__dragScroll
1409                 B       drawX__dragDone
1410                 B       drawX__dragCancel
1411
1412                 LTORG
1413
1414 ; --- drawX__dragScroll ---
1415 ;
1416 ; On entry:     R1 == pointer to window state
1417 ;
1418 ; On exit:      --
1419 ;
1420 ; Use:          Scrolls the window during the drag.
1421
1422 drawX__dragScroll ROUT
1423
1424                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
1425                 BL      drag_scroll             ;Read the scroll position
1426                 STMIA   R14,{R2,R3}             ;Save the new scroll position
1427                 SWI     Wimp_OpenWindow         ;Do the open operation
1428                 LDMFD   R13!,{R0-R3,PC}^        ;And return to caller
1429
1430                 LTORG
1431
1432 ; --- drawX__unknowns ---
1433 ;
1434 ; On entry:     R0 == event code
1435 ;               R1 == pointer to event data
1436 ;
1437 ; On exit:      CS if I handled it, CC if I didn't
1438 ;
1439 ; Use:          Handles unrecognised events.
1440
1441 drawX__unknowns ROUT
1442
1443                 CMP     R0,#17                  ;Is it a UserMessage?
1444                 CMPNE   R0,#18                  ;Or a UserMessageRecorded?
1445                 MOVNES  PC,R14                  ;No -- ignore it then
1446
1447                 ; --- Handle messages ---
1448
1449                 STMFD   R13!,{R14}              ;Save a register
1450                 LDR     R14,[R1,#16]            ;Load the message action
1451                 CMP     R14,#5                  ;Is it Message_DataOpen?
1452                 LDMNEFD R13!,{PC}^              ;No -- ignore it then
1453
1454                 STMFD   R13!,{R1,R10}           ;Save another register
1455                 LDR     R0,[R1,#40]             ;Load the filetype
1456                 MOV     R10,#0                  ;I don't have a diagram yet
1457                 BL      drawX__load             ;Load a new diagram
1458                 LDMFD   R13!,{R1,R10,R14}       ;Unstack the resulting regs
1459                 ORRCSS  PC,R14,#C_flag          ;If it loaded, set C flag
1460                 BICCCS  PC,R14,#C_flag          ;Otherwise clear it
1461
1462                 LTORG
1463
1464 ; --- drawX__dragCancel ---
1465 ;
1466 ; On entry:     --
1467 ;
1468 ; On exit:      --
1469 ;
1470 ; Use:          Cancels the drag.
1471
1472 drawX__dragCancel ROUT
1473
1474                 STMFD   R13!,{R14}              ;Save a register
1475                 LDR     R14,drawX__flags        ;Load the current flags
1476                 BIC     R14,R14,#dxFlag__drag   ;Clear the dragging flag
1477                 STR     R14,drawX__flags        ;Save the flags back again
1478                 TST     R14,#dxFlag__ownPtr     ;Do we own the pointer?
1479                 BLEQ    ptr_resetShape          ;No -- clear the shape then
1480                 LDMFD   R13!,{PC}^              ;Return to caller
1481
1482                 LTORG
1483
1484 ; --- drawX__dragDone ---
1485 ;
1486 ; On entry:     R1 == pointer to window state
1487 ;               R2,R3 == drag start position
1488 ;               R4,R5 == drag end position
1489 ;
1490 ; On exit:      --
1491 ;
1492 ; Use:          Handles the end of a drag operation.
1493
1494
1495 drawX__dragDone ROUT
1496
1497                 STMFD   R13!,{R0-R7,R14}        ;Save some registers
1498                 BL      drawX__dragCancel       ;Cancel the drag
1499
1500                 ; --- Now read the drag values ---
1501
1502                 ADD     R14,R13,#8              ;Point to arguments on stack
1503                 LDMIA   R14,{R4-R7}             ;Move them to different regs
1504
1505                 CMP     R4,R6                   ;Make sure they're the right
1506                 EORGT   R4,R4,R6                ;... way round
1507                 EORGT   R6,R4,R6
1508                 EORGT   R4,R4,R6
1509                 CMP     R5,R7
1510                 EORGT   R5,R5,R7
1511                 EORGT   R7,R5,R7
1512                 EORGT   R5,R5,R7
1513
1514                 ; --- Get the window sizes ---
1515
1516                 LDMIB   R1,{R0-R3}              ;Load the coordinates
1517                 SUB     R2,R2,R0                ;Get the window width
1518                 SUB     R3,R3,R1                ;And the window height
1519
1520                 ; --- Work out the new scale factor ---
1521
1522                 SUBS    R1,R6,R4                ;Get the drag box width
1523                 BEQ     %90drawX__dragDone      ;If it's bad, return now
1524                 ADD     R4,R4,R1,LSR #1         ;Find the box's centre
1525                 MOV     R0,R2,LSL #16           ;And the window width
1526                 MOV     R6,R2,LSR #1            ;Look after the width
1527                 BL      div_round               ;Do the division
1528                 MOV     R2,R0                   ;Look after the quotient
1529
1530                 SUBS    R1,R7,R5                ;Get the drag box height
1531                 BEQ     %90drawX__dragDone      ;If it's bad, return now
1532                 ADD     R5,R5,R1,LSR #1         ;Find the box's centre
1533                 MOV     R0,R3,LSL #16           ;And the window height
1534                 BL      div_round               ;Do the division
1535                 MOV     R3,R3,LSR #1            ;Halve the height
1536
1537                 CMP     R2,R0                   ;Which one's smaller?
1538                 MOVGT   R2,R0                   ;Use that one then
1539                 LDR     R7,[R10,#dWin__scale]   ;Load the current scale
1540                 MOV     R1,R7,LSR #8            ;Divide it down a bit
1541                 MOV     R2,R2,LSR #8            ;And divide the new one
1542                 MUL     R0,R2,R1                ;Multiply them up
1543                 CMP     R0,#&300                ;Is it smaller than 1%?
1544                 MOVLT   R0,#&300                ;Yes -- force it to 1%
1545                 CMP     R0,#&80000              ;Is it bigger than 800%?
1546                 MOVGT   R0,#&80000              ;Yes - force it to 800%
1547                 STR     R0,[R10,#dWin__scale]   ;Save the new scale factor
1548                 BL      drawX__setExtent        ;Set the new window extent
1549                 MOV     R0,R0,LSL #8            ;Scale up the new factor
1550                 MOV     R1,R7                   ;Get the old scale factor
1551                 BL      div_round               ;Get the scale difference
1552
1553                 ; --- Set the new scroll positions ---
1554
1555                 LDR     R1,[R13,#4]             ;Find the window state
1556                 MUL     R4,R0,R4                ;Multiply left drag box side
1557                 MUL     R5,R0,R5                ;And the top edge
1558                 RSB     R4,R6,R4,ASR #8         ;Scale them down a bit
1559                 ADD     R5,R3,R5,ASR #8         ;Scale them down a bit
1560                 ADD     R14,R1,#20              ;Point to the scroll pos
1561                 STMIA   R14,{R4,R5}             ;Save the new ones in there
1562                 SWI     Wimp_OpenWindow         ;Open the window nicely
1563
1564                 ; --- Now redraw the window ---
1565
1566                 LDR     R0,[R10,#dWin__window]  ;Load the window handle
1567                 ADD     R14,R10,#dWin__extent   ;Find the new extents
1568                 LDMIA   R14,{R1-R4}             ;Load them out nicely
1569                 SWI     Wimp_ForceRedraw        ;Redraw that lot nicely
1570
1571 90              LDMFD   R13!,{R0-R7,PC}^        ;Return to caller
1572
1573                 LTORG
1574
1575 ; --- drawX__mmHnd ---
1576 ;
1577 ; On entry:     R0 == menu event code
1578 ;               R1 == item number
1579 ;               R10 == diagram handle
1580 ;
1581 ; On exit:      --
1582 ;
1583 ; Use:          Handles events for the main diagram menu.
1584
1585 drawX__mmHnd    ROUT
1586
1587                 CMP     R0,#mEvent_help         ;Does the user want help?
1588                 BEQ     %70drawX__mmHnd         ;Yes -- give him some
1589                 CMP     R0,#mEvent_subMenu      ;Is it a submenu event?
1590                 CMPNE   R0,#mEvent_select       ;Or a selection event?
1591                 MOVNES  PC,R14                  ;No -- then quit
1592
1593                 ; --- Handle a menu selection ---
1594
1595                 CMP     R1,#mm__scale           ;Is it one I recognise?
1596                 ADDLS   PC,PC,R1,LSL #2         ;Yes -- then deal with it
1597                 MOVS    PC,R14                  ;Otherwise ignore it
1598
1599                 B       %10drawX__mmHnd         ;Display the info box
1600                 B       drawX__save             ;Start a save operation
1601                 B       drawX__scale            ;Display the scale dialogue
1602
1603                 ; --- Display and handle the File info box ---
1604
1605 10drawX__mmHnd  STMFD   R13!,{R0-R3,R14}        ;Save some registers
1606                 ADR     R0,drawX__fInfodb       ;Point to the dialogue name
1607                 BL      dbox_create             ;Try to create the dialogue
1608                 BVS     %30drawX__mmHnd         ;Handle an error if if failed
1609
1610                 MOV     R3,R0                   ;Look after the dbox handle
1611                 ADD     R2,R10,#dWin__filename  ;Point to the file's name
1612                 MOV     R1,#info__name+(1<<31)  ;Get the right icon number
1613                 BL      dbox_setField           ;Set the field up nicely
1614
1615                 LDR     R0,[R10,#dWin__diagSize] ;Load the diagram's size
1616                 MOV     R1,R11                  ;Point to the scratchpad
1617                 MOV     R2,#256                 ;Assume it's nice and big
1618                 SWI     OS_ConvertFileSize      ;Make it a nice size string
1619                 MOV     R2,R11                  ;Point at the string
1620                 MOV     R0,R3                   ;Get the dialogue handle
1621                 MOV     R1,#info__size          ;And find the size icon
1622                 BL      dbox_setField           ;Set the field up
1623
1624                 ADR     R1,drawX__fInfoHlp      ;Point to the help text
1625                 BL      dbox_setClickDrag       ;Make dialogue box draggable
1626                 BL      mbox                    ;Display the dialogue box
1627                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
1628
1629                 ; --- Couldn't create the dialogue ---
1630
1631 30drawX__mmHnd  MOV     R1,#1                   ;Just an OK button please
1632                 BL      errorBox                ;Display the error message
1633                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
1634
1635 drawX__fInfodb  DCB     "drawInfo",0
1636 drawX__fInfoHlp DCB     "drxhFINFO",0
1637
1638                 ; --- Handle help requests for the menu ---
1639
1640 70drawX__mmHnd  STMFD   R13!,{R0,R1,R14}        ;Save some registers
1641                 ADR     R0,drawX__mmHlpMsg      ;Point to the help string
1642                 BL      menu_help               ;Add message to help string
1643                 LDMFD   R13!,{R0,R1,PC}^        ;Return to caller
1644
1645 drawX__mmHlpMsg DCB     "drxhMM",0
1646
1647                 LTORG
1648
1649 ; --- drawX__redrawDragBox ---
1650 ;
1651 ; On entry:     R1 == pointer to redraw block
1652 ;               R2,R3 == start positions
1653 ;               R4,R5 == end positions
1654 ;               R6,R7 == window origin
1655 ;               R10 == diagram handle
1656 ;
1657 ; On exit:      --
1658 ;
1659 ; Use:          Draws the drag box.
1660
1661 drawX__redrawDragBox ROUT
1662
1663                 STMFD   R13!,{R0-R6,R14}        ;Save some registers
1664
1665                 ; --- Set the coordinates up ---
1666
1667                 MOV     R14,R6
1668                 ADD     R6,R5,R7
1669                 ADD     R5,R4,R14
1670                 ADD     R4,R3,R7
1671                 ADD     R3,R2,R14               ;Convert to screen coords
1672
1673                 ; --- Set the correct colour ---
1674
1675                 MOV     R0,#0                   ;Background colour is white
1676                 MOV     R1,#2                   ;Drag box is grey
1677                 BL      drag_eorColour          ;Set the EOR colour nicely
1678
1679                 ; --- Plot the actual rectangle ---
1680
1681                 MOV     R0,#4                   ;Move cursor absolute
1682                 MOV     R1,R3                   ;Get left hand side
1683                 MOV     R2,R4                   ;And bottom corner
1684                 SWI     OS_Plot                 ;And plot the first point
1685                 MOV     R0,#21                  ;Draw line absolute
1686                 MOV     R1,R5                   ;Get right hand side
1687                 MOV     R2,R4                   ;And bottom corner
1688                 SWI     OS_Plot                 ;And plot the bottom edge
1689                 MOV     R0,#53                  ;Draw line absolute
1690                 MOV     R1,R5                   ;Get right hand side
1691                 MOV     R2,R6                   ;And top corner
1692                 SWI     OS_Plot                 ;And plot the right hand edge
1693                 MOV     R0,#53                  ;Draw line absolute
1694                 MOV     R1,R3                   ;Get left hand side
1695                 MOV     R2,R6                   ;And top corner
1696                 SWI     OS_Plot                 ;And plot the top edge
1697                 MOV     R0,#61                  ;Draw line absolute
1698                 MOV     R1,R3                   ;Get left hand side
1699                 MOV     R2,R4                   ;And bottom corner
1700                 SWI     OS_Plot                 ;And plot the right edge
1701
1702 90              LDMFD   R13!,{R0-R6,PC}^        ;Return to caller
1703
1704                 LTORG
1705
1706 ; --- drawX__setTitle ---
1707 ;
1708 ; On entry:     R10 == diagram handle
1709 ;
1710 ; On exit:      --
1711 ;
1712 ; Use:          Updates a diagram window's title from its current state.
1713
1714 drawX__setTitle ROUT
1715
1716                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
1717                 ADD     R0,R10,#dWin__filename  ;Point to the filename
1718                 ADD     R1,R10,#dWin__titleBar  ;Point to the title buffer
1719                 LDR     R2,[R10,#dWin__window]  ;Load the window handle
1720                 BL      winUtils_setTitle       ;Set the window's title
1721                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
1722
1723                 LTORG
1724
1725 ; --- drawX__cascade ---
1726 ;
1727 ; On entry:     --
1728 ;
1729 ; On exit:      --
1730 ;
1731 ; Use:          Updates the y position for the next diagram window so that
1732 ;               it produces a pleasing `cascading' effect.
1733
1734 drawX__cascade  ROUT
1735
1736                 STMFD   R13!,{R14}              ;Save a register
1737                 LDR     R14,drawX__winY         ;Load the current y position
1738                 SUB     R14,R14,#48             ;Decrement the counter
1739                 CMP     R14,#drawX__bottomY     ;Is it within range?
1740                 MOVLT   R14,#drawX__topY        ;No -- move it to the top
1741                 STR     R14,drawX__winY         ;Save the cascaded position
1742                 LDMFD   R13!,{PC}^              ;And return to caller
1743
1744                 LTORG
1745
1746 ;----- Data transfer --------------------------------------------------------
1747
1748 ; --- drawX__save ---
1749 ;
1750 ; On entry:     R10 == diagram handle to save
1751 ;
1752 ; On exit:      --
1753 ;
1754 ; Use:          Saves a diagram.
1755
1756 drawX__save     ROUT
1757
1758                 STMFD   R13!,{R0-R5,R14}        ;Save lots of registers
1759                 LDR     R14,[R10,#dWin__flags]  ;Get the diagram's flags
1760                 TST     R14,#dwFlag__loaded     ;Does it have a nice name?
1761                 ADREQ   R0,drawX__defName       ;No -- find one then
1762                 BLEQ    msgs_lookup             ;Translate it nicely
1763                 ADDNE   R0,R10,#dWin__filename  ;Otherwise use the name
1764                 MOV     R2,R0                   ;Put the name in R2
1765                 LDR     R0,[R10,#dWin__diagSize] ;Load the diagram's size
1766                 LDR     R1,=drawX__filetype     ;Get the filetype nicely
1767                 ADR     R3,drawX__saveTbl       ;Point to the entry table
1768                 MOV     R4,R10                  ;Pass diagram handle in R10
1769                 MOV     R5,R12                  ;Pass workspace in R12
1770                 BL      saveAs                  ;Display the dialogue box
1771                 BVS     %90drawX__save          ;If it failed, deal with it
1772
1773                 LDR     R14,[R10,#dWin__flags]  ;Load the flags word
1774                 ORR     R14,R14,#dwFlag__saving ;This window is saving
1775                 STR     R14,[R10,#dWin__flags]  ;Save the flags back
1776                 LDMFD   R13!,{R0-R5,PC}^        ;Return to caller
1777
1778 90drawX__save   MOV     R1,#1                   ;If it failed, report the
1779                 BL      errorBox                ;error with just an OK button
1780                 LDMFD   R13!,{R0-R5,PC}^        ;Return to caller
1781
1782 drawX__defName  DCB     "drxDEFN",0
1783
1784 drawX__saveTbl  DCB     "drxSVTB",0
1785                 B       drawX__saveOver
1786                 B       drawX__saveFile
1787                 B       drawX__send
1788                 MOVS    PC,R14
1789                 B       drawX__saveFail
1790
1791 ; --- drawX__saveOver ---
1792 ;
1793 ; On entry:     R10 == diagram handle
1794 ;
1795 ; On exit:      --
1796 ;
1797 ; Use:          Clears the diagram's `saving' flag.
1798
1799 drawX__saveOver ROUT
1800
1801                 STMFD   R13!,{R14}              ;Save a register
1802                 LDR     R14,[R10,#dWin__flags]  ;Load the flags word
1803                 BIC     R14,R14,#dwFlag__saving ;Window not saving any more
1804                 STR     R14,[R10,#dWin__flags]  ;Save the flags back
1805                 LDMFD   R13!,{PC}^              ;Return to caller
1806
1807                 LTORG
1808
1809 ; --- drawX__saveFile ---
1810 ;
1811 ; On entry:     R0 == pointer to filename
1812 ;               R1 == 0 if file is unsafe
1813 ;               R10 == diagram handle
1814 ;
1815 ; On exit:      May return error
1816 ;
1817 ; Use:          Saves a diagram to a given file.
1818
1819 drawX__saveFile ROUT
1820
1821                 STMFD   R13!,{R0-R5,R14}        ;Save some registers
1822                 MOV     R2,R0                   ;Keep pointer to name
1823                 CMP     R1,#0                   ;Is the file safe?
1824                 ADDNE   R1,R10,#dWin__filename  ;Find the file's current name
1825                 BLNE    str_icmp                ;Do they match?
1826                 BEQ     %10drawX__saveFile      ;Either -- don't confirm
1827                 BL      res_exists              ;Does the file exist?
1828                 BCC     %10drawX__saveFile      ;No -- skip onwards then
1829
1830                 ; --- Make sure user wants to overwrite file ---
1831
1832                 ADR     R0,drawX__oWrite        ;Point to skeleton
1833                 BL      msgs_lookup             ;Translate the message
1834                 MOV     R1,R11                  ;Build in scratchpad
1835                 BL      str_subst               ;Build the warning message
1836                 ADR     R1,drawX__owWarn        ;Point to warning block
1837                 BL      warning                 ;Get a response
1838                 MOVCC   R0,#0                   ;If no then abort saving
1839                 BCC     %99drawX__saveFile      ;By making a null error
1840
1841 10              MOV     R1,R2                   ;Get the filename in R1
1842                 MOV     R0,#10                  ;We're saving whole files
1843                 LDR     R2,=drawX__filetype     ;Get the filetype number
1844                 ADD     R14,R10,#dWin__diagram  ;Find the diagram address
1845                 LDMIA   R14,{R4,R5}             ;Load the address and size
1846                 ADD     R5,R4,R5                ;Convert size to limit ptr
1847                 SWI     XOS_File                ;Try to save the file
1848                 BVS     %99drawX__saveFile      ;If it failed, skip on
1849
1850                 LDR     R14,[R13,#4]            ;Get the `safe' flag
1851                 CMP     R14,#0                  ;Is the file safe?
1852                 BEQ     %90drawX__saveFile      ;No -- skip to the end
1853
1854                 ADD     R0,R10,#dWin__filename  ;Point to the filename
1855                 BL      str_cpy                 ;Copy the new one over
1856                 LDR     R14,[R10,#dWin__flags]  ;Load the flags word
1857                 ORR     R14,R14,#dwFlag__loaded ;File has a good name now
1858                 STR     R14,[R10,#dWin__flags]  ;Save the flags back
1859                 BL      drawX__setTitle         ;Set the window's title
1860
1861 90              LDMFD   R13!,{R0-R5,PC}^        ;Return to caller
1862
1863 99              ADD     R13,R13,#4              ;Don't restore R0 on exit
1864                 LDMFD   R13!,{R1-R5,R14}        ;Restore registers
1865                 ORRS    PC,R14,#V_flag          ;Return the error
1866
1867 drawX__oWrite   DCB     "drxCWRT",0
1868
1869 drawX__owWarn   BUTTON  "drxRPL"
1870                 BCANCEL
1871                 BUTEND
1872
1873                 LTORG
1874
1875 ; --- drawX__send ---
1876 ;
1877 ; On entry:     R10 == diagram handle
1878 ;
1879 ; On exit:      R0 == pointer to diagram
1880 ;               R1 == size of diagram
1881 ;               CS
1882 ;
1883 ; Use:          Returns the diagram block so it can be sent to another
1884 ;               application.
1885
1886 drawX__send     ROUT
1887
1888                 ADD     R0,R10,#dWin__diagram   ;Point to the diagram info
1889                 LDMIA   R0,{R0,R1}              ;Load the address and size
1890                 ORRS    PC,R14,#C_flag          ;No more data to send
1891
1892                 LTORG
1893
1894 ; --- drawX__saveFail ---
1895 ;
1896 ; On entry:     R0 == pointer to an error, or 0
1897 ;               R1 == 1
1898 ;
1899 ; On exit:      --
1900 ;
1901 ; Use:          Reports an error during a save attempt.
1902
1903 drawX__saveFail ROUT
1904
1905                 CMP     R0,#0                   ;Is there an error
1906                 MOVEQS  PC,R14                  ;No -- return now then
1907                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
1908                 ADD     R2,R0,#4                ;Point to error text
1909                 ADR     R0,drawX__badSave       ;Point to the message
1910                 BL      msgs_error              ;Translate it nicely
1911                 MOV     R1,#1                   ;Set up the button count
1912                 BL      errorBox                ;Report the error
1913                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
1914
1915 drawX__badSave  DCD     1
1916                 DCB     "drxESF",0
1917
1918                 LTORG
1919
1920 ; --- drawX__load ---
1921 ;
1922 ; On entry:     R0 == filetype of data to send
1923 ;               R10 == diagram handle, or 0 to create a new one
1924 ;
1925 ; On exit:      CS if it was handled, CC otherwise
1926 ;
1927 ; Use:          Loads a drawfile into a specified diagram, or into a newly
1928 ;               created one.
1929
1930 drawX__load     ROUT
1931
1932                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
1933                 LDR     R14,=drawX__filetype    ;Get the drawfile filetype
1934                 CMP     R0,R14                  ;Do they match properly?
1935                 BNE     %90drawX__load          ;No -- return then
1936
1937                 ; --- Disallow save from a window to itself ---
1938
1939                 CMP     R10,#0                  ;Is there a diagram?
1940                 LDRNE   R14,[R10,#dWin__flags]  ;Load the diagram's flags
1941                 TSTNE   R14,#dwFlag__saving     ;Is it currently saving?
1942                 BNE     %80drawX__load          ;Yes -- disallow this then
1943
1944                 ; --- Start a load operation ---
1945
1946                 ADR     R0,drawX__loadTbl       ;Point to the entry table
1947                 MOV     R1,R10                  ;Pass on the diagram handle
1948                 MOV     R2,R12                  ;And my workspace pointer
1949                 BL      load                    ;Start the load operation
1950                 LDMFD   R13!,{R0-R2,R14}        ;Unstack registers
1951                 ORRS    PC,R14,#C_flag          ;And say we handled it
1952
1953                 ; --- Report an error about saving ---
1954
1955 80drawX__load   ADR     R0,drawX__badLoad       ;Point to the error block
1956                 BL      msgs_error              ;Translate the message
1957                 MOV     R1,#1                   ;Only have an OK button
1958                 BL      errorBox                ;Report the error
1959
1960 90drawX__load   LDMFD   R13!,{R0-R2,R14}        ;Unstack registers
1961                 BICS    PC,R14,#C_flag          ;And don't claim the event
1962
1963 drawX__loadTbl  B       drawX__newBuf
1964                 B       load_killBuf
1965                 B       load_extendBuf
1966                 B       drawX__doneBuf
1967                 B       drawX__loadFile
1968                 B       drawX__loaded
1969                 B       drawX__loadFail
1970
1971 drawX__badLoad  DCD     1
1972                 DCB     "drxCSII",0
1973
1974                 LTORG
1975
1976 ; --- drawX__loadNew ---
1977 ;
1978 ; On entry:     R0 == pointer to name to create new diagram with
1979 ;
1980 ; On exit:      VC and R10 == pointer to diagram, or VS and R0 == pointer
1981 ;               to error
1982 ;
1983 ; Use:          Creates a new diagram for a drawfile to be loaded into.
1984
1985 drawX__loadNew  ROUT
1986
1987                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
1988                 BL      drawX__newDiag          ;Create a new diagram
1989                 BVS     %99drawX__loadNew       ;Handle an error from that
1990                 LDR     R14,[R10,#dWin__flags]  ;Load the current flags
1991                 ORR     R14,R14,#dwFlag__tent   ;Remember it's tentative
1992                 STR     R14,[R10,#dWin__flags]  ;Save the flags back again
1993                 LDMFD   R13!,{R0-R3,R14}        ;Restore registers
1994                 BICS    PC,R14,#V_flag          ;And return with V clear
1995
1996 99              ADD     R13,R13,#4              ;Don't restore R0 on exit
1997                 LDMFD   R13!,{R1-R3,R14}        ;Restore registers
1998                 ORRS    PC,R14,#V_flag          ;And return with V set
1999
2000                 LTORG
2001
2002 ; --- drawX__killOld ---
2003 ;
2004 ; On entry:     R10 == diagram handle
2005 ;
2006 ; On exit:      --
2007 ;
2008 ; Use:          Removes the current drawfile being showin in the diagram.
2009
2010 drawX__killOld  ROUT
2011
2012                 STMFD   R13!,{R0,R14}           ;Save some registers
2013                 LDR     R0,[R10,#dWin__diagram] ;Load the diagram anchor
2014                 CMP     R0,#0                   ;Does it actually exist?
2015                 ADDNE   R0,R10,#dWin__diagram   ;Yes -- point at the anchor
2016                 BLNE    flex_free               ;And free the block
2017                 MOVNE   R14,#0                  ;Zero it out nicely
2018                 STRNE   R14,[R10,#dWin__diagram] ;Save the new anchor ptr
2019                 LDMFD   R13!,{R0,PC}^           ;Return to caller
2020
2021                 LTORG
2022
2023 ; --- drawX__newBuf ---
2024 ;
2025 ; On entry:     R0 == pointer to leafname of file
2026 ;               R1 == estimated size of file
2027 ;               R10 == diagram handle, or 0 to create a new one
2028 ;
2029 ; On exit:      If all went well, VC and
2030 ;                 R0 == pointer to load buffer
2031 ;                 R1 == size of load buffer
2032 ;                 R2 == pointer to flex anchor
2033 ;                 R10 == diagram handle
2034 ;               Otherwise, VS, R0 == pointer to error, and R1, R2 corrupted
2035 ;
2036 ; Use:          Creates a load buffer for loading a new diagram.
2037
2038 drawX__newBuf   ROUT
2039
2040                 STMFD   R13!,{R14}              ;Save the link register
2041                 CMP     R10,#0                  ;Is there a diagram?
2042                 BLEQ    drawX__loadNew          ;No -- get one then
2043                 BLNE    drawX__killOld          ;Yes -- destroy the old one
2044                 ADDVC   R2,R10,#dWin__diagram   ;If OK, point to anchor
2045                 BLVC    load_initBuf            ;And find a new buffer
2046                 LDMFD   R13!,{PC}               ;Return to caller
2047
2048                 LTORG
2049
2050 ; --- drawX__doneBuf ---
2051 ;
2052 ; On entry:     R0 == pointer to diagram name
2053 ;               R1 == actual size of diagram
2054 ;               R2 == pointer to diagram flex anchor
2055 ;               R10 == diagram handle
2056 ;
2057 ; On exit:      --
2058 ;
2059 ; Use:          Wraps up a successful RAM receive of a draw file.
2060
2061 drawX__doneBuf  ROUT
2062
2063                 STR     R1,[R10,#dWin__diagSize] ;Save the diagram size
2064                 B       load_doneBuf            ;And set the flex block up
2065
2066                 LTORG
2067
2068 ; --- drawX__loadFile ---
2069 ;
2070 ; On entry:     R0 == pointer to leafname of file to load
2071 ;               R1 == pointer to filename to read
2072 ;               R10 == diagram handle, or 0 to create a new one
2073 ;
2074 ; On exit:      If all went well, VC and R10 == diagram handle
2075 ;               Otherwise, VS, R0 == pointer to error
2076 ;
2077 ; Use:          Loads a diagram from a file.
2078
2079 drawX__loadFile STMFD   R13!,{R0-R2,R14}        ;Save some registers
2080                 CMP     R10,#0                  ;Is there a diagram?
2081                 BLEQ    drawX__loadNew          ;No -- get one then
2082                 BLNE    drawX__killOld          ;Yes -- destroy the old one
2083                 MOVVS   R10,#0                  ;If no diagram, clear R10
2084                 ADDVC   R2,R10,#dWin__diagram   ;If OK, point to anchor
2085                 BLVC    load_file               ;And load the diagram
2086                 STRVC   R0,[R10,#dWin__diagSize] ;Save the diagram size
2087                 STRVS   R0,[R13,#0]             ;Otherwise return error
2088                 LDMFD   R13!,{R0-R2,PC}         ;Return to caller
2089
2090                 LTORG
2091
2092 ; --- drawX__loaded ---
2093 ;
2094 ; On entry:     R10 == diagram handle
2095 ;
2096 ; On exit:      --
2097 ;
2098 ; Use:          Completes loading of a diagram.
2099
2100 drawX__loaded   ROUT
2101
2102                 STMFD   R13!,{R0,R1,R14}        ;Save lots of registers
2103                 LDR     R0,[R10,#dWin__diagram] ;Find the diagram address
2104                 BL      draw_checkValid         ;Make sure it's kosher
2105                 MOVVS   R1,#1                   ;If not, set R1 == 1
2106                 BLVS    drawX__loadFail         ;And kill off the diagram
2107                 BVS     %90drawX__loaded        ;And return
2108
2109                 ; --- Set everything up for the new diagram ---
2110
2111                 BL      drawX__setExtent        ;Set the extents
2112                 BL      drawX__refresh          ;Refresh the window contents
2113                 BL      drawX__setTitle         ;Set the title string
2114                 LDR     R14,[R10,#dWin__flags]  ;Load the diagram flags
2115                 TST     R14,#dwFlag__tent       ;Was it tentative?
2116                 BICNE   R14,R14,#dwFlag__tent   ;Diagram not tentative now
2117                 ORR     R14,R14,#dwFlag__hasDiag ;Diagram now has a drawfile
2118                 STR     R14,[R10,#dWin__flags]  ;Save the flags back again
2119                 BLNE    drawX__open             ;Yes -- open it on screen
2120                 BLNE    drawX__cascade          ;And cascade the thing too
2121
2122 90drawX__loaded LDMFD   R13!,{R0,R1,PC}^        ;Return to caller
2123
2124                 LTORG
2125
2126 ; --- drawX__loadFail ---
2127 ;
2128 ; On entry:     R0 == pointer to error, or 0 if none
2129 ;               R1 == 1
2130 ;               R10 == diagram handle, or 0 if none
2131 ;
2132 ; On exit:      --
2133 ;
2134 ; Use:          Handles an error during loading a diagram.
2135
2136 drawX__loadFail ROUT
2137
2138                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
2139                 CMP     R10,#0                  ;Is there a diagram?
2140                 BEQ     %50drawX__loadFail      ;No -- just report error
2141
2142                 ; --- Work out what to do ---
2143                 ;
2144                 ; If the window is new, delete it.  Otherwise just leave it
2145                 ; blank.
2146
2147                 LDR     R14,[R10,#dWin__flags]  ;Load the flags word
2148                 TST     R14,#dwFlag__tent       ;Is it tentative?
2149                 BLNE    drawX__killDiag         ;Yes -- kill the diagram
2150                 BNE     %50drawX__loadFail      ;And skip ahead
2151
2152                 ; --- Blank out a diagram ---
2153
2154                 BIC     R14,R14,#dwFlag__loaded+dwFlag__hasDiag
2155                 STR     R14,[R10,#dWin__flags]  ;Save the flags back again
2156                 ADRL    R0,drawX__untitled      ;Point to the blank name
2157                 BL      msgs_lookup             ;Translate the message
2158                 MOV     R1,R0                   ;This is the source string
2159                 ADD     R0,R10,#dWin__filename  ;Point to filename buffer
2160                 BL      str_cpy                 ;Copy it over
2161                 BL      drawX__setTitle         ;Set the window's title
2162                 MOV     R1,#0                   ;Left hand side is 0
2163                 MOV     R2,#0                   ;Bottom edge is 0 too
2164                 MOV     R3,#640                 ;Window is 640 units wide
2165                 MOV     R4,#512                 ;And 512 units high
2166                 ADD     R14,R10,#dWin__extent   ;Point to the extent block
2167                 STMIA   R14,{R1-R4}             ;Save them all away
2168                 LDR     R0,[R10,#dWin__window]  ;Load the window handle
2169                 ADD     R1,R10,#dWin__extent    ;Point to the coordinates
2170                 SWI     Wimp_SetExtent          ;Set the new extent
2171                 BL      drawX__refresh          ;Refresh the window contents
2172
2173                 ; --- Report the error ---
2174
2175 50              LDR     R2,[R13,#0]             ;Load the error pointer
2176                 CMP     R2,#0                   ;Is it interesting?
2177                 ADDNE   R2,R2,#4                ;Yes -- point to error text
2178                 ADRNE   R0,drawX__loadErr       ;Point to the message
2179                 BLNE    msgs_error              ;Translate the error
2180                 MOVNE   R1,#1                   ;Only one button please
2181                 BLNE    errorBox                ;And report the error
2182
2183                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
2184
2185 drawX__loadErr  DCD     1
2186                 DCB     "drxELF",0
2187
2188                 LTORG
2189
2190 ;----- That's all, folks ----------------------------------------------------
2191
2192                 END