Initial revision
[ssr] / StraySrc / Libraries / Sapphire / s / pane
1 ;
2 ; pane.s
3 ;
4 ; Pane handling facilities (TMA)
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sapphire library.
12 ;
13 ; Sapphire is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; Sapphire is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with Sapphire. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29 GET libs:header
30 GET libs:swis
31
32 ;----- External dependencies ------------------------------------------------
33
34 GET sapphire:alloc
35 GET sapphire:event
36 GET sapphire:screen
37 GET sapphire:sapphire
38 GET sapphire:suballoc
39 GET sapphire:tspr
40
41 ;----- Main code ------------------------------------------------------------
42
43 AREA |Sapphire$$Code|,CODE,READONLY
44
45 ; --- pane_add ---
46 ;
47 ; On entry: R0 == window handle of parent window
48 ; R1 == icon handle in parent window
49 ; R2 == window handle of pane window
50 ;
51 ; On exit: May return an error
52 ;
53 ; Use: This call registers a pane to be associated with the given
54 ; window. The pane is always opened to fit exactly within
55 ; the given icon -- border widths are taken into account
56 ; if there are scroll bars etc.
57 ;
58 ; You must call pane_closed if the parent window is closed,
59 ; since there is no way for pane to trap this occurence.
60
61 EXPORT pane_add
62 pane_add ROUT
63
64 STMFD R13!,{R0-R4,R12,R14} ;Stack some registers
65 WSPACE pane__wSpace ;Locate my workspace
66
67 ; --- First, we must scan to see if the parent
68 ; window is already registered
69
70 MOV R4,R0 ;Preserve parent handle
71 BL pane__windowBlock ;Find the window block
72 CMP R0,#0 ;Is there one?
73 MOVNE R3,R0 ;Yes -- point to it
74 BNE %50pane_add ;And add in the pane
75
76 ; --- The window isn't registered ---
77
78 10 MOV R0,#wl__size ;Allocate this much memory
79 BL sub_alloc ;Get it then
80 SWIVS OS_GenerateError ;...and generate error
81 LDR R3,ws__wList ;Load first window defn
82 STR R3,[R0,#wl__next] ;Store as next pointer
83 CMP R3,#0 ;Is there any more?
84 STRNE R0,[R3,#wl__prev] ;Yes -- update prev pointer
85 MOV R3,#0 ;A NULL pointer
86 STR R3,[R0,#wl__prev] ;No previous for new block
87 STR R3,[R0,#wl__pList] ;No pane list yet
88 MOV R3,R0 ;Put pointer in R3
89 STR R4,[R3,#wl__wHandle] ;Store parent window handle
90 STR R3,ws__wList ;Store at list head
91
92 ; --- R3 points to the window list block ---
93
94 50 MOV R0,#pl__size ;Allocate this much memory
95 BL sub_alloc ;Go on then
96 SWIVS OS_GenerateError ;...and generate error
97 LDR R4,[R3,#wl__pList] ;Load first pane defn
98 STR R4,[R0,#pl__next] ;Store as next pointer
99 CMP R4,#0 ;Is there any more?
100 STRNE R0,[R4,#pl__prev] ;Yes -- update prev pointer
101 MOV R14,#0 ;A NULL pointer
102 STR R14,[R0,#pl__prev] ;No previous for new block
103 STR R1,[R0,#pl__iHandle] ;Store the icon handle
104 STR R2,[R0,#pl__wHandle] ;Store the window handle
105 STR R0,[R3,#wl__pList] ;Store at list head
106
107 ; --- Return to caller ---
108
109 LDMFD R13!,{R0-R4,R12,PC}^ ;Return
110
111 LTORG
112
113 ; --- pane_remove ---
114 ;
115 ; On entry: R0 == window handle for which pane was registered
116 ; R1 == window handle of the pane window itself
117 ;
118 ; On exit: --
119 ;
120 ; Use: Removes the pane from the given window. This call will
121 ; close the given pane, but will not actually delete it
122 ; (ie. with a Wimp_DeleteWindow).
123
124 EXPORT pane_remove
125 pane_remove ROUT
126
127 STMFD R13!,{R0-R5,R12,R14} ;Stack some registers
128 WSPACE pane__wSpace ;Locate my workspace
129
130 BL pane__windowBlock ;Find the window block
131 CMP R0,#0 ;Is there one?
132 BEQ %90pane_remove ;No -- remove
133 MOV R3,R0 ;Put pointer in R3
134
135 ; --- Remove the pane from the window list ---
136
137 50 LDR R4,[R3,#wl__pList] ;Get the first entry
138 55 CMP R4,#0 ;Is there a pane definition?
139 BEQ %90pane_remove ;No -- return
140 LDR R5,[R4,#pl__wHandle] ;Get the pane handle
141 CMP R5,R1 ;Is this the one we want
142 LDRNE R4,[R4,#wl__next] ;No -- get next in list
143 BNE %55pane_remove ;...and keep looking
144
145 ; --- We have now found the pane block ---
146
147 ADD R1,R4,#pl__wHandle ;Point to the window handle
148 SWI XWimp_CloseWindow ;Close the window
149 LDR R1,[R4,#pl__prev] ;Get the previous pointer
150 LDR R2,[R4,#pl__next] ;And the next pointer
151 CMP R2,#0 ;Is there a next field?
152 STRNE R1,[R2,#pl__prev] ;Yes -- update previous
153 CMP R1,#0 ;Is there a previous field
154 STRNE R2,[R1,#pl__next] ;Yes -- update next field
155 STREQ R2,[R3,#wl__pList] ;No -- store next as head
156
157 MOV R0,R4 ;Point to the block
158 MOV R1,#pl__size ;It's this big
159 BL sub_free ;Free the block
160 LDR R1,[R3,#wl__pList] ;Get the pane list
161 CMP R1,#0 ;Is there one?
162 MOVEQ R0,R3 ;No -- point to window block
163 BLEQ pane__removeWindow ;...remove the definition
164
165 ; --- Return to caller ---
166
167 90 LDMFD R13!,{R0-R5,R12,PC}^ ;Return
168
169 LTORG
170
171 ; --- pane__removeWindow ---
172 ;
173 ; On entry: R0 == pointer to window block
174 ;
175 ; On exit: --
176 ;
177 ; Use: Removes the give window block from the list. All associated
178 ; panes are removed too.
179
180 pane__removeWindow ROUT
181
182 STMFD R13!,{R0-R3,R14} ;Stack some registers
183
184 MOV R3,R0 ;Keep a pointer to this block
185 LDR R2,[R3,#wl__pList] ;Get the first pane block
186 CMP R2,#0 ;Is there one?
187 BEQ %10pane__removeWindow ;No -- free window block
188 00 ADD R1,R2,#pl__wHandle ;Point to the window handle
189 MOV R14,R2 ;Get block pointer in R14
190 LDR R2,[R2,#pl__next] ;Get next pointer
191 SWI XWimp_CloseWindow ;Close the window
192 MOV R0,R14 ;Block pointer in R0
193 MOV R1,#pl__size ;It's this big
194 BL sub_free ;Free the block
195 CMP R2,#0 ;Are there more blocks?
196 BNE %00pane__removeWindow ;Yes -- remove next pane too
197
198 ; --- Remove the window block ---
199
200 10 LDR R1,[R3,#wl__prev] ;Get the previous pointer
201 LDR R2,[R3,#wl__next] ;And the next pointer
202 CMP R2,#0 ;Is there a next field?
203 STRNE R1,[R2,#wl__prev] ;Yes -- update previous
204 CMP R1,#0 ;Is there a previous field
205 STRNE R2,[R1,#wl__next] ;Yes -- update next field
206 STREQ R2,ws__wList ;No -- store next as head
207 MOV R0,R3 ;Point to the block
208 MOV R1,#wl__size ;It's this big
209 BL sub_free ;And free it
210
211 LDMFD R13!,{R0-R3,PC}^ ;Return to caller
212
213 LTORG
214
215 ; --- pane_closed ---
216 ;
217 ; On entry: R0 == window handle of parent
218 ;
219 ; On exit: --
220 ;
221 ; Use: Informs pane that a parent window has closed.
222 ; All associated panes are then closed.
223
224 EXPORT pane_closed
225 pane_closed ROUT
226
227 STMFD R13!,{R0-R2,R12,R14} ;Stacks some registers
228 WSPACE pane__wSpace ;Locate workspace
229
230 BL pane__windowBlock ;Find the block
231 CMP R0,#0 ;Is there one?
232 BEQ %90pane_closed ;No -- return
233
234 LDR R2,[R0,#wl__pList] ;Get the first pane pointer
235 00pane_closed ADD R1,R2,#pl__wHandle ;Point to the window handle
236 SWI XWimp_CloseWindow ;Close the window
237 LDR R2,[R2,#pl__next] ;Get the next pane
238 CMP R2,#0 ;Is there one?
239 BNE %00pane_closed ;Yes -- close it then
240
241 90pane_closed LDMFD R13!,{R0-R2,R12,PC}^ ;Return to caller
242
243 LTORG
244
245 ; --- pane_deleted ---
246 ;
247 ; On entry: R0 == window handle of parent
248 ;
249 ; On exit: --
250 ;
251 ; Use: Informs pane that a parent window has been deleted.
252 ; All associated panes are then closed, and there
253 ; registration with the pane library module is
254 ; terminated.
255
256 EXPORT pane_deleted
257 pane_deleted ROUT
258
259 STMFD R13!,{R0-R3,R12,R14} ;Stacks some registers
260 WSPACE pane__wSpace ;Locate workspace
261
262 BL pane__windowBlock ;Find the block
263 CMP R0,#0 ;Is there one?
264 BLNE pane__removeWindow ;Yes -- remove definitions
265
266 LDMFD R13!,{R0-R3,R12,PC}^ ;Return to caller
267
268 LTORG
269
270 ; --- pane__windowBlock ---
271 ;
272 ; On entry: R0 == window handle
273 ;
274 ; On exit: R0 == pointer to window block
275 ;
276 ; Use: Find the window block associated with the given
277 ; window handle. If it is not found, 0 is returned.
278
279 pane__windowBlock ROUT
280
281 STMFD R13!,{R1,R2,R14} ;Stack some registers
282
283 MOV R1,R0 ;Keep the window handle
284 LDR R0,ws__wList ;Load first window defn
285 00 CMP R0,#0 ;Is there one?
286 BEQ %90pane__windowBlock ;No -- return
287 LDR R2,[R0,#wl__wHandle] ;Get the window handle
288 CMP R2,R1 ;Is this the one we want?
289 BEQ %90pane__windowBlock ;Yes -- return
290 LDR R0,[R0,#wl__next] ;Get the next in list
291 B %00pane__windowBlock ;And keep looking
292
293 90 LDMFD R13!,{R1,R2,PC}^ ;Return to caller
294
295 LTORG
296
297 ; --- pane_swap ---
298 ;
299 ; On entry: R0 == window handle of parent window
300 ; R1 == icon handle within parent window
301 ; R2 == window handle of new pane
302 ;
303 ; On exit: --
304 ;
305 ; Use: This call will replace the pane in associated with icon R1
306 ; in window R0, with the pane in R2.
307 ;
308 ; The exisiting pane is closed, and the new pane is
309 ; opened in it's place. No error is generated if the existing
310 ; pane does not exist; this allows the caller to delete the
311 ; window before doing the swap.
312
313 EXPORT pane_swap
314 pane_swap ROUT
315
316 STMFD R13!,{R0-R3,R12,R14} ;Stack some registers
317 WSPACE pane__wSpace ;Locate my workspace
318
319 BL pane__windowBlock ;Find the window block
320 CMP R0,#0 ;Is there one?
321 BEQ %90pane_swap ;No -- return
322
323 ; --- Find the pane in the pane window list ---
324
325 LDR R3,[R0,#wl__pList] ;Get the first entry
326 00 CMP R3,#0 ;Is there a pane definition?
327 BEQ %90pane_swap ;No -- return
328 LDR R14,[R3,#pl__iHandle] ;Get the icon handle
329 CMP R14,R1 ;Is this the one we want
330 LDRNE R3,[R3,#wl__next] ;No -- get next in list
331 BNE %00pane_swap ;...and keep looking
332
333 ; --- Do the swap ---
334
335 MOV R14,R0 ;Preserve R0
336 ADD R1,R3,#pl__wHandle ;Point to the window handle
337 SWI XWimp_CloseWindow ;Close it
338 STR R2,[R3,#pl__wHandle] ;Store the new window handle
339 SUB R13,R13,#36 ;Get a block
340 LDR R0,[R14,#wl__wHandle] ;Get parent handle
341 STR R0,[R13,#0] ;Store it in the block
342 MOV R1,R13 ;Point to the block
343 SWI Wimp_GetWindowState ;Get the window state
344 MOV R2,R1 ;Put state in R2
345 MOV R0,R14 ;The window block
346 MOV R1,R3 ;Point to the pane block
347 MOV R3,R2 ;Now put state in R3
348 BL pane__open ;Open the new pane
349 ADD R13,R13,#36 ;Reclaim my stack
350
351 90pane_swap LDMFD R13!,{R0-R3,R12,PC}^ ;Return to caller
352
353 LTORG
354
355 ; --- pane_open ---
356 ;
357 ; On entry: R0 == window handle
358 ;
359 ; On exit: --
360 ;
361 ; Use: Opens all the panes associated with the given window.
362
363 EXPORT pane_open
364 pane_open ROUT
365
366 STMFD R13!,{R0-R3,R12,R14} ;Stack some registers
367 WSPACE pane__wSpace ;Load my workspace pointer
368
369 BL pane__windowBlock ;Find the window block
370 CMP R0,#0 ;Is there one?
371 BEQ %90pane_open ;No -- return
372
373 ; --- Find the pane in the pane window list ---
374
375 SUB R13,R13,#36 ;Get a block
376 LDR R14,[R0,#wl__wHandle] ;Get the window handle
377 STR R14,[R13,#0] ;Store in the block
378 MOV R1,R13 ;Point to the block
379 MOV R2,R0 ;Preserve R0
380 SWI Wimp_GetWindowState ;Get the window state
381 MOV R0,R2 ;Get R0 back
382 MOV R3,R1 ;Put state in R3
383
384 LDR R1,[R0,#wl__pList] ;Get the first entry
385 00pane_open BL pane__open ;Open the pane
386 LDR R1,[R1,#pl__next] ;Get next pane
387 CMP R1,#0 ;Is there one?
388 BNE %00pane_open ;Yes -- keep looping
389 ADD R13,R13,#36 ;Get stack back
390
391 90pane_open LDMFD R13!,{R0-R3,R12,PC}^ ;Return to caller
392
393 LTORG
394
395 ; --- pane__open ---
396 ;
397 ; On entry: R0 == pointer to window block
398 ; R1 == pointer to pane block
399 ; R3 == pointer to parent window state
400 ;
401 ; On exit: --
402 ;
403 ; Use: Opens the pane in the right place.
404
405 pane__open ROUT
406
407 STMFD R13!,{R0-R9,R14} ;Stack some more registers
408
409 MOV R4,R0 ;Preserve window block
410 MOV R6,R1 ;Preserve R1
411 BL screen_justChangedMode ;Due to a mode change?
412 MOVCS R1,R3 ;Point to open window block
413 BLCS tspr_adjustBox ;Adjust the box
414
415 LDR R5,[R3,#28] ;Get the back value
416 CMP R5,#-2 ;Opening at the back?
417 MOVEQ R1,R3 ;Yes -- point to the block
418 SWIEQ Wimp_OpenWindow ;Open the window
419 SWIEQ Wimp_GetWindowState ;Get the window state
420
421 MOV R2,R6 ;Get R1 back again
422 SUB R13,R13,#36 ;Get me a block
423 LDR R14,[R2,#pl__wHandle] ;Get pane window handle
424 STR R14,[R13,#0] ;Store in the block
425 MOV R1,R13 ;Point to the block
426 SWI Wimp_GetWindowState ;Get the window state
427 LDR R9,[R13,#32] ;Load the window's flags
428 SUB R13,R13,#40 ;Get another block
429 LDR R14,[R4,#wl__wHandle] ;Get parent handle
430 STR R14,[R13,#0] ;Store the handle
431 LDR R14,[R2,#pl__iHandle] ;Get the icon handle
432 STR R14,[R13,#4] ;Store that too
433 MOV R1,R13 ;Point to the block
434 SWI Wimp_GetIconState ;Get the icon state
435 ADD R1,R13,#8 ;Point to coordinates
436 LDMIA R1,{R5-R8} ;Get the icon coordinates
437 ADD R13,R13,#40 ;Point at window state
438 LDR R0,[R3,#4] ;Visible area x0 coord
439 LDR R1,[R3,#16] ;Visible area y1 coord
440 ADD R5,R0,R5 ;Make icon coords screen rel.
441 ADD R6,R1,R6
442 ADD R7,R0,R7
443 ADD R8,R1,R8
444
445 STMFD R13!,{R2-R4} ;Preserve registers
446 BL screen_getInfo ;Get screen information
447 ADD R0,R0,#screen_dx ;Point to the pixel sizes
448 LDMIA R0,{R3,R4} ;Load the pixel sizes
449 BL tspr_borderWidths ;Get the border widths
450 TST R9,#&0f000000 ;Is there a title bar?
451 SUBNE R8,R8,R0 ;Yes -- correct y1 coord
452 SUBEQ R8,R8,R4 ;No -- subtract pixel size
453 TST R9,#&10000000 ;Is there a vertical bar?
454 SUBNE R7,R7,R1 ;Yes -- correct x1 coord
455 SUBEQ R7,R7,R3 ;No -- subtract pixel size
456 TST R9,#&40000000 ;Is there a horizontal bar?
457 ADDNE R6,R6,R2 ;Yes -- correct y0 coord
458 ADDEQ R6,R6,R4 ;No -- add pixel size
459 ADD R5,R5,R3 ;Add pixel size to x0
460 LDMFD R13!,{R2-R4} ;Get registers back again
461
462 10pane__open STMIB R13,{R5-R8} ;Store new coorinates
463 LDR R5,[R3,#28] ;Get behind value to use
464 LDR R6,[R13,#0] ;And the pane handle
465 CMP R6,R5 ;Are they the same?
466 STRNE R5,[R13,#28] ;No -- Store it in the block
467 STR R6,[R3,#28] ;New behind for parent window
468 MOV R1,R13 ;Point to the block
469 SWI Wimp_OpenWindow ;Open the pane window
470
471 ADD R13,R13,#36 ;Reclaim stack
472 LDMFD R13!,{R0-R9,PC}^ ;Return to caller
473
474 LTORG
475
476 ; --- pane__fakeHandler ---
477 ;
478 ; On entry: R0 == event type
479 ; R1 == event block
480 ;
481 ; On exit: CC
482 ;
483 ; Use: Although this is called as a fake handler, it does not
484 ; generate fake event. Instead, it is used to trap
485 ; open window event before any handler can claim them. This
486 ; allows the panes to be moved automatically.
487
488 pane__fakeHandler ROUT
489
490 TEQ R0,#2 ;Open window request?
491 MOVNES PC,R14 ;No -- return PDQ
492
493 STMFD R13!,{R0,R14} ;Stack some registers
494 LDR R0,[R1,#0] ;Get the window handle
495 BL pane__windowBlock ;Find out if it's registered
496 CMP R0,#0 ;Is there a block
497 LDMEQFD R13!,{R0,PC}^ ;No -- return
498
499 ; --- We are moving a window with panes in it ---
500
501 STMFD R13!,{R1,R3} ;Stack some more registers
502 MOV R3,R1 ;Put window state in R3
503 LDR R1,[R0,#wl__pList] ;Get the first pane
504 00 BL pane__open ;Open the given pane
505
506 ; --- Keep looking for more panes ---
507
508 LDR R1,[R1,#pl__next] ;Get the next pane
509 CMP R1,#0 ;Is there one?
510 BNE %00pane__fakeHandler ;Yes -- move it then
511
512 LDMFD R13!,{R1,R3} ;Get back first lot
513 LDMFD R13!,{R0,PC}^ ;And return
514
515 LTORG
516
517 ; --- pane_init ---
518 ;
519 ; On entry: --
520 ;
521 ; On exit: --
522 ;
523 ; Use: Initialises the pane unit.
524
525 EXPORT pane_init
526 pane_init ROUT
527
528 STMFD R13!,{R0,R1,R12,R14} ;Stack some registers
529 WSPACE pane__wSpace ;Locate my workspace
530
531 ; --- Set up a fake handler ---
532
533 BL event_init ;Initialise event
534 ADR R0,pane__fakeHandler ;Call this routine
535 MOV R1,R12 ;With this R12 value
536 BL event_fakeHandler ;Add in the handler
537
538 ; --- Initalise some workspace ---
539
540 MOV R0,#0 ;A nice NULL word
541 STR R0,ws__wList ;No window list yet
542
543 LDMFD R13!,{R0,R1,R12,PC}^ ;Return to caller
544
545 LTORG
546
547 pane__wSpace DCD 0
548
549 ;----- Workspace layout -----------------------------------------------------
550
551 ; --- Window list ---
552
553 ^ 0
554
555 wl__next # 4 ;The next window in list
556 wl__prev # 4 ;The previous window in list
557 wl__wHandle # 4 ;The window handle
558 wl__pList # 4 ;List of panes
559 wl__size # 0 ;The size of this structure
560
561 ; --- Pane list ---
562
563 ^ 0
564
565 pl__next # 4 ;The next pane in the list
566 pl__prev # 4 ;The previous pane in list
567 pl__wHandle # 4 ;The window handle of pane
568 pl__iHandle # 4 ;Icon handle in window
569 pl__size # 0 ;The size of this structure
570
571 ; --- The workspace ---
572
573 ^ 0,R12
574
575 ws__start # 0 ;Workspace start
576
577 ws__wList # 4 ;The window list
578
579 ws__size EQU {VAR}-ws__start ;Workspace size
580
581 AREA |Sapphire$$LibData|,CODE,READONLY
582
583 DCD ws__size ;Workspace size
584 DCD pane__wSpace ;Workspace pointer
585 DCD 0 ;Scratchpad size
586 DCD pane_init ;Initialisation code
587
588 ;----- That's all, folks ----------------------------------------------------
589
590 END