chiark / gitweb /
JPEG support and other fixes from Nick Clark
[ssr] / StraySrc / Libraries / Sapphire / s / help
1 ;
2 ; help.s
3 ;
4 ; Sending and handling help messages (MDW)
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:event
35                 GET     sapphire:idle
36                 GET     sapphire:msgs
37                 GET     sapphire:sapphire
38                 GET     sapphire:string
39
40 ;----- Main code ------------------------------------------------------------
41
42                 AREA    |Sapphire$$Code|,CODE,READONLY
43
44 ; --- help_init ---
45 ;
46 ; On entry:     --
47 ;
48 ; On exit:      --
49 ;
50 ; Use:          Initialises the help system for use.
51
52                 EXPORT  help_init
53 help_init       ROUT
54
55                 STMFD   R13!,{R0,R1,R12,R14}    ;Save some registers
56
57                 ; --- Make sure we're not going already ---
58
59                 WSPACE  help__wSpace            ;Locate my workspace pointer
60                 LDR     R14,help__flags         ;Get my flags word
61                 TST     R14,#hFlag__inited      ;Am I initialised already?
62                 LDMNEFD R13!,{R0,R1,R12,PC}^    ;Yes - return to caller
63                 ORR     R14,R14,#hFlag__inited  ;I will be initialised soon
64                 STR     R14,help__flags         ;Store the flags word back
65
66                 ; --- Set up the workspace ---
67
68                 MOV     R14,#20                 ;Start message size as 20
69                 STR     R14,help__message+0     ;Store this in the block
70                 MOV     R14,#0                  ;No message to reply to
71                 STR     R14,help__msgTask       ;Store in the your_ref field
72
73                 ; --- Set up my prefilter ---
74
75                 BL      event_init              ;Make sure event is awake
76                 ADR     R0,help__preFilter      ;Point to the prefilter
77                 MOV     R1,R12                  ;Pass along my workspace
78                 BL      event_preFilter         ;Register it with event
79                 ADR     R0,help__postFilter     ;Point to the postfilter
80                 BL      event_postFilter        ;Register that with event too
81                 LDMFD   R13!,{R0,R1,R12,PC}^    ;Return to caller
82
83                 LTORG
84
85 help__wSpace    DCD     0
86
87 ; --- help__preFilter ---
88 ;
89 ; On entry:     --
90 ;
91 ; On exit:      --
92 ;
93 ; Use:          Dispatches the currently waiting help reply, if there is
94 ;               one.  Also fakes hint requests and dispatches finished hints
95 ;               to windows.
96
97 help__preFilter ROUT
98
99                 STMFD   R13!,{R14}              ;Save a register
100
101                 ; --- Check for hints first ---
102
103                 LDR     R14,help__flags         ;Get my flags word
104                 TST     R14,#hFlag__hinted      ;Do we have a waiting hint?
105                 BNE     %50help__preFilter      ;Yes -- dispatch it to window
106                 TST     R14,#hFlag__hinting     ;Do we need to make a hint?
107                 BNE     %60help__preFilter      ;Yes -- build the block then
108
109                 ; --- Otherwise, check for finished help messages ---
110
111                 LDR     R14,help__msgTask       ;Get the your_ref for this
112                 CMP     R14,#0                  ;Is this sensible?
113                 LDMEQFD R13!,{PC}^              ;No -- return
114
115                 STMFD   R13!,{R0-R3}            ;Save some more registers
116                 LDR     R14,help__message+0     ;Load the message length
117                 ADD     R14,R14,#4              ;Word align the size as reqd.
118                 BIC     R14,R14,#3              ;Yep, indeedy
119                 STR     R14,help__message+0     ;Store length back again
120
121                 ADR     R1,help__message        ;Point to the message block
122                 LDR     R2,help__msgTask        ;Load the task handle out
123                 MOV     R0,#0                   ;No more messages waiting
124                 STR     R0,help__msgTask        ;So zero the task handle
125                 MOV     R0,#17                  ;Don't care if it bounces
126                 SWI     Wimp_SendMessage        ;Send the message out
127                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
128
129                 ; --- Send a finished hint to the hint window ---
130
131 50              STMFD   R13!,{R1}               ;Save some registers away
132                 BIC     R14,R14,#hFlag__hinted :OR: hFlag__hinting
133                 STR     R14,help__flags         ;Clear all the hint flags
134                 LDR     R14,help__window        ;Get the hint destination
135                 STR     R14,[R1,#0]             ;Store in the poll block
136                 ADD     R0,R1,#4                ;Point to next spare field
137                 ADR     R1,help__message+20     ;Point to hint string
138                 BL      str_cpy                 ;Copy it over
139                 MOV     R0,#-1                  ;The magic hint reason code
140                 LDMFD   R13!,{R1,R14}           ;Restore registers
141                 ORRS    PC,R14,#C_flag          ;Return to caller
142
143                 ; --- Try to get a new hint from the window ---
144
145 60              STMFD   R13!,{R1-R5}            ;Save a load of registers
146                 ORR     R14,R14,#hFlag__hinted  ;Dispatch hint next time
147                 STR     R14,help__flags         ;Save new flags word
148
149                 ; --- Build a skeleton hint in case of no reply ---
150
151                 MOV     R0,#0                   ;A null string
152                 STR     R0,help__message+20     ;Store over the string start
153
154                 ; --- Build a help request in the poll block ---
155
156                 MOV     R0,#44                  ;Size of help request message
157                 MOV     R2,#-1                  ;A very bogus task handle
158                 MOV     R3,#-1                  ;A similarly bogus my_ref
159                 MOV     R4,#0                   ;This is not a reply
160                 MOV     R5,#&500                ;Help request message code
161                 ORR     R5,R5,#&002             ;Finish off message code
162                 STMIA   R1!,{R0,R2-R5}          ;Build message header
163                 STR     R4,help__msgTask        ;Zero destination task handle
164                 SWI     Wimp_GetPointerInfo     ;Get the current pointer pos
165                 MOV     R0,#18                  ;Make it look real!
166                 LDMFD   R13!,{R1-R5,R14}        ;Restore registers
167                 ORRS    PC,R14,#C_flag          ;Return to caller
168
169                 LTORG
170
171 ; --- help__postFilter ---
172 ;
173 ; On entry:     R0 == event reason code
174 ;               R1 == pointer to event block
175 ;
176 ; On exit:      --
177 ;
178 ; Use:          Catches pointer-entering and pointer-leaving events and
179 ;               sets up the idle claimer appropriately.
180
181 help__postFilter ROUT
182
183                 ; --- Ensure that we want this event ---
184
185                 CMP     R0,#4                   ;Pointer leaving?
186                 MOVNES  PC,R14                  ;No -- return now
187
188                 ; --- Pointer is leaving one of tasks windows ---
189
190                 STMFD   R13!,{R0-R3,R14}        ;Stack some registers
191                 LDR     R14,help__flags         ;Get my flags word
192                 TST     R14,#hFlag__hintable    ;Is window hintable?
193                 LDMEQFD R13!,{R0-R3,PC}^        ;No -- ignore this then
194                 MOV     R0,#5                   ;Call it this frequently
195                 ADR     R1,help__idles          ;Call this on idle events
196                 MOV     R2,#0                   ;Our user handle
197                 MOV     R3,R12                  ;Put our workspace in R12
198                 BL      idle_removeHandler      ;Remove handler
199
200                 ; --- Pointer has just left the window ---
201                 ;
202                 ; It looks really silly if the window we left still has a
203                 ; hint in it, so we send it a dummy hint with a null string.
204
205                 MOV     R0,#0                   ;A zero byte for the string
206                 STR     R0,help__message+20     ;Store over the string start
207                 LDR     R14,help__flags         ;Get my flags word
208                 ORR     R14,R14,#hFlag__hinted  ;There's a hint waiting
209                 BIC     R14,R14,#hFlag__hintable;Disable the hints system
210                 STR     R14,help__flags         ;Store flags back again
211                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
212
213                 LTORG
214
215 ; --- help_sendHints ---
216 ;
217 ; On entry:     --
218 ;
219 ; On exit:      --
220 ;
221 ; Use:          Should be called on a pointer-entering-window event.  It
222 ;               enables hint requests for the window beneath the pointer.
223
224                 EXPORT  help_sendHints
225 help_sendHints  ROUT
226
227                 STMFD   R13!,{R0-R3,R12,R14}    ;Save some registers
228                 WSPACE  help__wSpace            ;Load my workspace address
229                 LDR     R14,help__flags         ;Load my flags word
230                 TST     R14,#hFlag__hintable    ;Are hints enabled?
231                 LDMNEFD R13!,{R0-R3,R12,PC}^    ;Yes -- then return now
232                 ORR     R14,R14,#hFlag__hintable;Set the hints enabled flag
233                 STR     R14,help__flags         ;And save the flags back
234
235                 MOV     R0,#5                   ;Call it this frequently
236                 ADR     R1,help__idles          ;Call this on idle events
237                 MOV     R2,#0                   ;Our user handle
238                 MOV     R3,R12                  ;Put our workspace in R12
239                 BL      idle_handler            ;Add idle handler
240                 MOV     R0,#-3                  ;Set up previous icon hnd
241                 STR     R0,help__icon           ;...to a really weird value
242                 LDMFD   R13!,{R0-R3,R12,PC}^    ;And return to caller
243
244                 LTORG
245
246 ; --- help__idles ---
247 ;
248 ; On entry:     --
249 ;
250 ; On exit:      --
251 ;
252 ; Use:          Catches pointer movement between icons, and sets the hint
253 ;               flags accordingly.
254
255 help__idles     ROUT
256
257                 STMFD   R13!,{R0-R2,R14}        ;Save some registers away
258                 SUB     R13,R13,#24             ;Make space for a pointer blk
259                 MOV     R1,R13                  ;Point to it
260                 SWI     Wimp_GetPointerInfo     ;Get the current ptr posn
261                 ADD     R14,R13,#12             ;Point to window/icon hnds
262                 LDMIA   R14,{R0,R2}             ;Load them out of the block
263                 ADD     R13,R13,#24             ;Reclaim the stack I used
264
265                 ; --- Find out if we need to get a new hint ---
266
267                 LDR     R1,help__icon           ;Get the old icon I was on
268                 CMP     R1,R2                   ;Do they match?
269                 BEQ     %90help__idles          ;Yes -- nothing more to do
270
271                 CMP     R2,#0                   ;Is ptr over the background?
272                 MOVLT   R2,#-3                  ;Yes -- give it a silly value
273                 STR     R2,help__icon           ;No -- store as new old icon
274                 STR     R0,help__window         ;Save the hint window handle
275                 LDR     R14,help__flags         ;Get my flags word
276                 ORR     R14,R14,#hFlag__hinting ;Get ready to send a hint rq
277                 STR     R14,help__flags         ;Store the flags away again
278
279 90help__idles   LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
280
281                 LTORG
282
283 ; --- help_add ---
284 ;
285 ; On entry:     R0 == pointer to message string to add
286 ;
287 ; On exit:      --
288 ;
289 ; Use:          Adds a line to the help message being built currently.  Note
290 ;               that overflows are trapped, and errors are generated if one
291 ;               would occur.
292
293                 EXPORT  help_add
294 help_add        ROUT
295
296                 STMFD   R13!,{R0-R4,R12,R14}    ;Save some registers
297                 WSPACE  help__wSpace            ;Find my workspace area
298                 LDR     R14,help__msgTask       ;Get the destination task
299                 CMP     R14,#0                  ;Is there one set up?
300                 BNE     %10help_add             ;Yes -- add a subsequent line
301
302                 ; --- We're starting a new help reply ---
303
304                 BL      event_last              ;Get the last event out
305                 MOV     R2,#&500                ;The message code to match
306                 ORR     R2,R2,#&002             ;Can't load in one op
307                 CMP     R0,#17                  ;Make sure it's a message
308                 CMPNE   R0,#18                  ;Either one will do
309                 LDREQ   R14,[R1,#16]            ;Get the message code
310                 CMPEQ   R14,R2                  ;Does this match up?
311                 LDMNEFD R13!,{R0-R4,R12,PC}^    ;If not, return right now
312
313                 ; --- Set up the message block ---
314
315                 ADD     R4,R2,#1                ;The reply code is one larger
316                 MOV     R0,#20                  ;Size of the message block
317                 LDR     R3,[R1,#8]              ;Load his my_ref value
318                 MOV     R14,#0                  ;Null terminate the string
319                 STMIB   R12,{R0-R4,R14}         ;Build the message block
320                 LDR     R14,[R1,#4]             ;Get the task handle out
321                 STR     R14,help__msgTask       ;Store the handle away
322
323                 ; --- Set up for main copy loop ---
324
325                 LDR     R0,[R13,#0]             ;Get the string pointer back
326                 MOV     R1,R11                  ;Find a spare buffer
327                 BL      msgs_build              ;Build the message nicely
328                 ADR     R1,help__message+20     ;Current pointer for string
329                 MOV     R2,#20                  ;Current length
330                 B       %20help_add             ;Now skip to main code
331
332                 ; --- Add in a line separator ---
333
334 10help_add      MOV     R1,R11                  ;Find a spare buffer
335                 BL      msgs_build              ;Build the message nicely
336
337                 LDR     R2,help__message+0      ;Get the current message size
338                 ADR     R1,help__message        ;Point to the message start
339                 ADD     R1,R1,R2                ;Get current pointer
340                 CMP     R2,#253                 ;Make sure it will fit
341                 BGT     %90                     ;If it doesn't, make error
342
343                 LDR     R14,help__flags         ;Load my flags word
344                 TST     R14,#hFlag__hinted      ;Am I building a hint?
345                 MOVEQ   R14,#'|'                ;No -- strings get GSTransed
346                 MOVNE   R14,#' '                ;Yes -- spaces not newlines
347                 STRB    R14,[R1],#1             ;Store the character
348                 MOVEQ   R14,#'M'                ;`|M' is a return character
349                 STRB    R14,[R1],#1             ;Store the character
350                 ADD     R2,R2,#2                ;We've added two characters
351
352                 ; --- Now copy the string over, trapping overflows ---
353
354 20help_add      CMP     R2,#256                 ;Do we have room for another?
355                 BGE     %90                     ;No -- moan bitterly
356                 LDRB    R14,[R0],#1             ;Get an input character
357                 CMP     R14,#' '                ;Is this a control character?
358                 MOVLT   R14,#0                  ;Yes -- store a zero nicely
359                 STRB    R14,[R1],#1             ;Store it in my message
360                 ADD     R2,R2,#1                ;Bump the character count
361                 BGE     %20help_add             ;Loop round for more
362
363                 ; --- Set things up for next time ---
364
365                 SUB     R2,R2,#1                ;Overwrite the last null byte
366                 STR     R2,help__message+0      ;Store the message length
367                 LDMFD   R13!,{R0-R4,R12,PC}^    ;Return to caller
368
369                 ; --- We overflowed -- complain ---
370
371 90help_add      MOV     R0,#0                   ;Zero the task handle...
372                 STR     R0,help__msgTask        ;...to stop it being sent
373                 ADR     R0,help__overflow       ;Point to the message
374                 BL      msgs_error              ;Translate it as normal
375                 SWI     OS_GenerateError        ;And generate the error
376
377 help__overflow  DCD     1
378                 DCB     "helpOFLOW",0
379
380                 LTORG
381
382 ; --- help_reset ---
383 ;
384 ; On entry:     --
385 ;
386 ; On exit:      --
387 ;
388 ; Use:          Resets the help system so that a hint request is sent to an
389 ;               icon that the pointer is already over. The proposed use
390 ;               is that the caller can change a help message for a given
391 ;               icon as soon as it is clicked on.
392
393                 EXPORT  help_reset
394 help_reset      ROUT
395
396                 STMFD   R13!,{R12,R14}          ;Stack some registers
397                 WSPACE  help__wSpace            ;Load my workspace address
398                 MOV     R14,#-3                 ;Set up previous icon hnd
399                 STR     R14,help__icon          ;...to a really weird value
400                 LDMFD   R13!,{R12,PC}^          ;Return to caller
401
402                 LTORG
403
404 ;----- Workspace ------------------------------------------------------------
405
406                 ^       0,R12
407 help__wStart    #       0
408
409 help__flags     #       4                       ;Various flags
410 help__message   #       256                     ;The actual message to send
411 help__msgTask   #       4                       ;Task to send message to
412 help__msgNext   #       4                       ;Pointer to message tail
413 help__window    #       4                       ;The window the ptr is over
414 help__icon      #       4                       ;The icon the ptr is over
415
416 help__wSize     EQU     {VAR}-help__wStart
417
418 hFlag__inited   EQU     (1<<0)                  ;Am I initialised?
419 hFlag__hintable EQU     (1<<1)                  ;Current window wants hints
420 hFlag__hinting  EQU     (1<<2)                  ;We're gathering up a hint
421 hFlag__hinted   EQU     (1<<3)                  ;Is a hint waiting?
422
423                 AREA    |Sapphire$$LibData|,CODE,READONLY
424
425                 DCD     help__wSize
426                 DCD     help__wSpace
427                 DCD     0
428                 DCD     help_init
429
430 ;----- That's all, folks ----------------------------------------------------
431
432                 END