> net#arf:$.a500.RiscOS+.doc.Wimp
Author: Neil Raine
Status: changes to Wimp documentation for PRM
History:
13-Sep-89 NRaine History section added.
14-Sep-89 NRaine Changes for Wimp 2.34 added.
21-Sep-89 NRaine Changes up to Wimp 2.38 added.
2-Oct-89 NRaine Added 'hints and tips' section
18-Oct-89 NRaine Changes up to Wimp 2.45 added.
20-Oct-89 NRaine Stuff for TaskManager 0.32 added.
24-Oct-89 NRaine Stuff about icon flags bit 7 added.
25-Oct-89 NRaine Changes up to Wimp 2.50 added.
25-Oct-89 NRaine Extra documentation added to last section
26-Oct-89 NRaine Fixed bug in Message_PreQuit section
27-Oct-89 NRaine Changes up to Wimp 2.52 added.
16-Nov-89 NRaine Changes up to Wimp 2.61 added.
9-Dec-89 NRaine Added Wimp_SlotSize bug, reworded mode change stuff
26-Feb-90 NRaine Added *WimpWriteDir, Wimp_ReadSysInfo (4), backward menus
26-Feb-90 NRaine Added Wimp_CreateIcon stuff with handle -5 to -8
10-Apr-91 RMokady Updated to reflect Wimp 3.00 for Risc OS 2.5
As the Wimp is developed, it is often necessary to make alterations or additions to the application interface. Sometimes this can be done in such a way that the new behaviour is 'back-compatible' with the old (ie. it will not confuse applications which do not know about the extension), for example where a reserved field can be set non-zero to enable the new feature.
However, it is occasionally necessary to make changes that could potentially confuse an application which was not aware of them. In order to cope with this, the Wimp allows an application to inform it of how much it knows, by supplying the version number of the latest release of the Wimp which the programmers have taken into account:
SWI Wimp_Initialise R0 = latest known version of Wimp * 100 R1 = "TASK" R2 -> task name string
Applications written for RISC OS 2.00 should all have R0 set to 200 when calling Wimp_Initialise.
This allows the Wimp to provide 'incompatible' new facilities only to those applications which it knows are aware of them, thereby avoiding compatibility problems with the others.
In many cases a 'compatible' extension can be made, where it is clear to the Wimp whether or not the application is trying to use the new facility, so not all extensions require the application to 'know' about the later version of the Wimp.
The following extensions are grouped according to which version of the Wimp the application must know about: note that extensions for a given version of the Wimp also apply to any subsequent versions, so if R0 is set to 300, then all features up to and including those in Wimp 3.00 are enabled.
Under Risc OS 2.5 an application can only pass 200 or 300 to Wimp_Initialise. The wimp will give an error if any other value is passed in.
Pressing any other key selects the highlighted box, and returns 1 or 2 as appropriate.
In either case, if the box that would have been selected is not present, the other box is selected.
+ Wimp_DragBox is called (eg. in response to a drag button event). + The pointer moves by more than the configured number of OS units. + The mouse is not clicked again inside the configured amount of time.
(*Configure WimpDragMove, WimpDragDelay)
If you are dragging the size box of a window, and you move the pointer off the bottom-right of the screen, the Wimp will try to make the window bigger. If it succeeds, the window will be forced onto the screen, so it will appear to grow upwards and left. The speed of growing can be controlled by how far the pointer is off-screen.
Window flags bit 21 is also set automatically by the Wimp when a menu or a dialogue window is opened as a result of the pointer moving over the relevant submenu icon, or as a result of a call to Wimp_CreateMenu or Wimp_CreateSubMenu. This forces the menus onto the screen normally, but allows them to be dragged off-screen if desired.
Bit 13 of a window's flags can be set to indicate that it should be kept permanently on-screen.
[R1,#0] = -3 => create icon on iconbar to left of icon handle R0 -4 => create icon on iconbar to right of icon handle R0 R0 = handle of icon to open next to, if [R1,#0] = -3 or -4 R0 = -1 => create icon at extreme left (-3) or right (-4)
This allows icons to be recreated and deleted (in order to change their width, for example) such that they stay in the same relative position on the iconbar. It also allows applications to keep groups of iconbar icons together.
{ -------------------------------------------------------------------- } The following is what should be in the PRM, it should say that -3 and -4 are reserved.
Wimp 2.73 also supports prioritising of iconbar icons, so that for example, the RAM disc icon can be positioned immediately to the right of the Apps icon.
[R1,#0] = -5 => create icon on left side, scanning from the left -6 => create icon on left side, scanning from the right -7 => create icon on right side, scanning from the left -8 => create icon on right side, scanning from the right R0 = signed 32-bit priority (higher priority => towards outside)
The Wimp positions the icons so that they are sorted, with those of higher priority nearer the extreme ends of the iconbar. Where icons are of equal priority, the position of the new icon is determined by the scan direction.
The priorities assumed for the other possible window handle values are:
handle = -1 priority = 0 handle = -2 priority = 0 handle = -3, R0 = icon handle priority = same as matched icon handle = -3, R0 = -1 priority = &78000000 handle = -4, R0 = icon handle priority = same as matched icon handle = -4, R0 = -1 priority = &78000000
The various Desktop modules create icons with the following priorities:
Task Manager &60000000 !Help &40000000 Palette Utility &20000000 Applications 0
ADFS hard discs &70000000 ADFS floppy discs &60000000 "Apps" icon &50000000 RAM disc &40000000 Ethernet &30000000 Econet &20000000 Other filing systems &10000000 Printer drivers &0F000000 TinyDirs -&40000000
eg: Configured Wimp mode Suffix
23 "23" 20 "22" 12 "24"
This allows applications to easily provide an alternative set of icons for hi-res mono modes (when using the new Wimp). For example, an application could provide a set of colour sprites in a file called "!Sprites", and an alternative monochrome set in a file called "!Sprites23", and then load one set or the other automatically by using "*Iconsprites <Obey$Dir>.Sprites".
In: R0=1 gives R0 = current Wimp mode on exit R0=2 gives R0 -> iconsprites filename suffix for the configured mode. When loading sprite files containing icons, the suffix should be tried - if the file does not exist, try the original filename. R0=3 gives R0 = 0 => we are in text output mode (ie. outside the desktop, or in the ShellCLI, or in a command window). R0 = 1 => we are in the desktop other values reserved (test for non-zero when looking to see whether we're in command mode or not). R0=4 gives R0 = 0 => left to right text entry R0 = 1 => right to left text entry this returns the state last set by *WimpWriteDir.
"commands" Wimp_ReadSysInfo (3) returns 0 "desktop" Wimp_ReadSysInfo (3) returns 1 other values should be treated as 'not "commands"'.
The 'backwindow' bit of the iconbar's window flags is toggled.
If the 'back' bit of the iconbar is now set, it is sent to the back, otherwise it is brought to the front.
When the iconbar is brought to the front, bit 11 of its window flags ('backwindow') is cleared, and when it is sent to the back, this bit is set. This ensures that the iconbar only has the 'backwindow' bit set when it is at the back.
Wimp_GetWindowInfo R1 bits 2..31 -> buffer to receive data R1 bit 0 set => just return window header (without icons) R1 bit 1 reserved (must be 0)
Wimp_LoadTemplate In R1 <= 0 => return R1 = size of buffer required R2 = size of indirected data Out [R5..] = actual name only if [R5..] on entry was wildcarded
No error is generated for objects of type <> 1: the object is simply loaded into the buffer, and no indirected data processing occurs. This is different from Wimp 2.00, which reported an error in these circumstances.
Message_TaskStarted (&400C8)
This is sent by the Filer after it has started up all its children so that the TaskManager can 'renumber' it. This is so that during the deskboot saving sequence, the Filer_Boot and Filer_OpenDir commands are inserted after the logons returned by the NetFiler.
R1!0 = 24 (size) R1!16 = Message_PreQuit (8) R1!20 = flag word: bit 0 set => just quit this task, else desktop being quit bits 1..31 reserved (ie. ignore them)
This allows applications to tell whether they should restart the desktop closedown sequence after prompting the user to save any unsaved data. If bit 0 of the flag word is set, then the task should not send a ctrl-shift-f12 key_pressed event to the task which sent it the PreQuit message, to restart the closedown sequence, but should instead just terminate itself.
Note that if the flag word is not present (ie. the block is too small), the task should treat the flag word as having been zero.
If a task has a menu tree open, and another task calls Wimp_CreateMenu, thereby deleting the first tree.
If a task has a menu tree open, and it calls Wimp_CreateMenu with a different menu pointer than the one last used.
If a task has a menu tree open, and the user clicks somewhere outside the menu tree, thereby closing it. The Wimp now sends mouse clicks as messages if the message queue is not empty, which ensures that the click event arrives after the Message_MenusDeleted.
Note in particular that no message is returned if a menu selection event is returned, or if a menu tree is replaced by another with the same menu pointer.
Ticks appear on the right, arrows on the left Submenus are opened to the left (including Message_MenuWarning ones) Left-justified menu items are right-justified, and vice-versa
If the command is issued from within a running Wimp task, then *Wimptask <command> causes SWI Wimp_StartTask, R0 -> "<command>".
If the command is issued from outside the desktop, or from a task that has not called Wimp_Initialise, then *WimpTask <command> causes the Window Manager module to be entered as an application with <command> as its parameter string. The Wimp's application entry point calls Wimp_Initialise, then issues SWI Wimp_StartTask with R0 -> "<command>", and then calls OS_Exit.
The reason for all this messing about is that it is not possible to call Wimp_StartTask from within a "dead" task, since the Wimp would not know how to return to the dead task after starting the required task. In order to start a task, it is necessary to be a "proper" application, and to be running in USR mode - this is why the Wimp is entered.
The important thing to know about *WimpTask is that it will exit via OS_Exit if you call it from outside a Wimp task.
*WimpSlot -next <n>K
The -min keyword in *WimpSlot is now optional.
+20 Window handle. +24 Task handle for task which owns the window. +28 20 Bytes of title string. (last part of first word) +48
+20 Window handle. +24
B<Type>,<Slab in colour> To set the icon's border type (This will override the Wimp's default border for the icon).
Where type is:
0: 3d raised border. 1: Group border. 2: Default action border. 3: Writable icon border. 4: Pressed 3d border. 5: Normal 2d border. 6: Pressed type 2 border.
Border type 0 changes to 4 and 2 changes to 6 when a mouse event is about to be reported to the application, and changes back when you release the mouse button, or when you move the pointer away from the icon. It will not change if the icon's button type means that the click is not reported to the application.
The Slab in colour is used to set the icon's background colour just before a mouse click is reported to the task.
P<spritename>,active_x,active_y To change the pointer shape while over the icon.
Default sprites provided in the wimp sprite area are:
Name Active point ptr_write 4,4 ptr_menu 6,5 ptr_direct 13,7 ptr_hand 12,8 ptr_cross 13,7
Registers a filter to be called on call to or before return from Wimp_PollEntry:
r0 - reason code: 0 - Register / Deregister Pre-Filter 1 - Register / Deregister Post-Filter
r1 - Address of filter, or 0 to de-register. r2 - Value to be passed in R12 on entry to filter.Exit:
Registers preserved.
A pre filter is called whenever a task calls Wimp_poll:
On Entry:
R0 = Event mask as passed to Wimp_Poll R1 -> User block as passed to Wimp_Poll. R2 = Task handle. R12 = Value of R2 when registered.On Exit:
R0 May be modified by the filter. All other register and processor mode must be preserved
A post filter is called when the Wimp is about to return an event to a
task.
On Entry:
R0 - Event code for event that is about to be returned. R1 -> Event block for event to be returned. (Owner task paged in) R2 = Task handle of task that is about to receive the event.On Exit:
The filter may modify R0 and the contents of the buffer pointed to by R1, to return a different event.
R1,R2 must be preserved.
If R0=-1 on exit, the event will not be passed to the task.
This SWI is provided for the use of the FilterManager, and should not be used unless you want to replace the whole filter system. Use the FilterManager to register filters for specific tasks.
Wimp_GetMenuState R0 = 0 => report current state of tree, ignoring R2,R3 R0 = 1 => report tree which leads up to R2,R3 R1 -> buffer to contain result R2 = window handle R3 = icon handle
The tree is put into the buffer in R1 in the same format as that returned by Wimp_Poll reason code 9 (Menu_Select), ie. a list of selection indices terminated by -1.
The tree returned will be null if R0=1 and the window/icon in R2/R3 is not in the tree, or if R0=0 or 1 and the menu tree is owned by a different application, or is closed altogether.
If the window is a dialogue box, the tree returned will go up to (but not include) the dialogue box.
If R0 bit 13 is clear, then:
R0 bit 22 set => scan 'poll word' pointed to by R3 R0 bit 23 set => scan the poll word at high priority R3 -> poll word (NOT in application space)
The Wimp will normally scan the word after delivering any outstanding messages and issuing any Redraw_Window_Requests that are required, so that the application can then update its windows etc. as required.
If R0 bit 23 was set, the poll word will be scanned before the messages or the Redraw_Window_Requests are delivered. Note that this means that the screen may not yet be up-to-date, and certain messages may not have been delivered (in particular Message_ModeChange).
If the Wimp discovers that the word has become non-zero, it will return the following event from Wimp_Poll:
R0 = 13 (PollWord_NonZero) [R1,#0] = address of poll word [R1,#4] = contents of poll word
This facility is used to transfer control to a task's foreground process, where control is currently in an interrupt routine, service call handler or the like.
For example, the NetFiler module intercepts a special service call which is issued by NetFS whenever a *Logon, *Bye or *SDisc is executed. This tells NetFiler that it should re-scan its list of fileservers and update the iconbar as appropriate, but it cannot do this directly because it needs to get control in the foreground in order to call the Wimp.
It therefore sets a flag in its workspace, which tells it that it should rescan the list the next time the Wimp returns to it from Wimp_Poll. Using the new facility, it can use a 'fast poll' to get the Wimp to tell it BEFORE the screen is up-to-date, which means that if the user issues a *Logon from within ShellCLI, the NetFiler can update the iconbar before the screen is redrawn when ShellCLI returns, and so the iconbar does not have to be redrawn twice.
A more normal application for this would be for a background process to buffer incoming data in the RMA, and to signal to its foreground process when there was enough data to use. It would normally use the 'slow' form of polling, so that it could update its window with the new data.
Note that there is still no guarantee about how long it will take before the application regains control, since other applications can take control away from the Wimp for arbitrarily long periods of time (eg. ShellCLI).
R0 bit 24 set => save / restore FP registers R1 -> poll block R2 = earliest return time (for Wimp_PollIdle) R3 -> poll word (if R0 bit 22 set - see above)
The floating point registers should only be saved if one or more of the following is true:
This is because in general other C programs running under the Wimp that use floating point will not save their FP registers, but will assume that the status register is still correct for the C run-time environment.
To enable this to work, the Wimp resets the FP status register to the correct value for the C run-time environment immediately after saving the FP registers for a task that requests it.
There is one complication with this: when the Wimp comes to save the floating point registers for a task, it is possible (when using the actual FP hardware, as opposed to the emulator) for an asynchronous exception to be generated (eg. after a divide by 0, the next FP instruction is the one that actually generates the error).
In this case OS_GenerateError is called by the FP support code, once it has determined the cause of the exception. The important point here is that the error is passed to the task whose FP registers were being saved. When OS_GenerateError is called, the supervisor stack is cleared out, so it is as though the Wimp_Poll call never happened. Note that the error number here has the top bit set, which indicates to the error handler that execution cannot be resumed after the PC address where the error occurred.
Changes applying to Wimp 2.86 and above
Tasks knowing about Wimp 2.86 or later have to provide an extra argument to Wimp_Initialise.
Wimp_Initialise now becomes: R0 = latest known version of Wimp * 100 (300) R1 = "TASK" R2 -> task name string R3 -> A list of message numbers terminated by a 0 word.
The task will only receive messages which are included in the list.the list should not (and cannot) include Message_Quit (0) as this message will always be delivered to all tasks.
Update of writeable icons:
If an application wishes to update the contents of a writeable icon directly, while the caret is inside the icon, then it cannot in general simply write to the icon's indirected buffer and make sure it gets redrawn.
The general routine goes as follows:
REM In: window% = window handle of icon to be updated REM icon% = icon handle of icon to be updated REM buffer% = address of indirected icon text buffer REM string$ = new string to put into icon
DEF PROCwrite_icon(window%,icon%,buffer%,string$) LOCAL cw%,ci%,cx%,cy%,ch%,ci% $buffer% = string$ SYS "Wimp_GetCaretPosition" TO cw%,ci%,cx%,cy%,ch%,ci% IF cw%=window% AND ci%=icon% THEN IF ci% > LEN($buffer%) THEN ci% = LEN($buffer%) SYS "Wimp_SetCaretPosition",cw%,ci%,cx%,cy%,-1,ci% ENDIF PROCseticonstate(window%,icon%,0,0) :REM redraw the icon ENDPROC
Basically if the length of the string changes, it is possible for the caret to be positioned off the end of the string, in which case nasty effects can occur (especially if you delete the string terminator!).
Deleting and creating icons:
Using Wimp_CreateIcon and Wimp_DeleteIcon to create and delete icons has certain disadvantages: the window is not redrawn, and the icon handles can change.
An alternative is to use Wimp_SetIconState to set and clear the icon's 'deleted' bit (bit 23).
However, it should be noted that when calling Wimp_SetIconState to set bit 23 of the icon flags (ie. to delete it), the icon will not be 'undrawn' unless bit 7 of the icon flags ('needs help to be redrawn') is also set. This is because icons without this bit set are simply redrawn on top of their old selves without filling in the background, to avoid flicker.
Thus to delete an icon, use:
block%!0 = window_handle% block%!4 = icon_handle% block%!8 = &00800080 :REM set block%!12= &00800080 :REM bits 7 and 23 SYS "Wimp_SetIconState",,block%
and to re-create it, use:
block%!0 = window_handle% block%!4 = icon_handle% block%!8 = &00000000 :REM clear block%!12= &00800080 :REM bits 7 and 23 SYS "Wimp_SetIconState",,block%
Note that when re-creating the icon, bit 7 should normally be cleared, to avoid flicker when updating the icon.