> 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

Documentaton updates since RISC OS 2.00 release (Wimp 2.00)

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.

Changes applying to Wimp 2.00

The following changes apply to any task, even those passing 200 to Wimp_Initialise The new Wimp actually returns the code for the NON-highlighted box, ie. R1=2 if OK was highlighted, and R1=1 if CANCEL was highlighted.

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.

Bit 15 of the window flags performs the same function for the lower extent of the window.
      +  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)
In fact the windows are still restricted in the following circumstances:
  1. If window flags bit 13 is set
  2. If the window is being opened, and was closed
  3. If a toggle-to-full-size occurs
  4. While you are dragging the size box
  5. Immediately after a mode change
  6. On the next call to Wimp_OpenWindow after Wimp_SetExtent is called for a window which is fully on-screen at the time. In cases (3) to (6), the Wimp sets bit 21 of the window flags, which causes the window to be restricted to the screen area for one call to Wimp_OpenWindow only (this causes the bit to be cleared). Case (2) means that when a window is first opened it will be forced onto the screen, but can subsequently be dragged off by the user.

    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.

    { The following should not be documented in the PRM !!!!!!!!!!! } {--------------------------------------------------------------------}
            [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
    
    If the configured Wimp mode is a hi-res mono mode (ie. bit 4 of the modeflags is set), then it will use the suffix "23"; otherwise the suffix is "<OS units per pixel (x)><OS units per pixel (y)>".
        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.

    Message_Iconize:
          +20  Window handle.
          +24  Task handle for task which owns the window.
          +28  20 Bytes of title string. (last part of first word)
          +48
    
    Message_WindowClosed
          +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
    
    Wimp_RegisterFilter
              Registers a filter to be called on call to or before return from Wimp_Poll
    
    Entry:
           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.

    Changes applying to Wimp 2.18 or later

    Typically such a message will contain the window handle of the menu window, which will not be recognised by the menu owner. However, it cn make use of the following call to find out which part of the menu tree it corresponds to:
            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.

    Changes applying to Wimp 2.23

            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.

    Documentation that relates to Wimp 2.00 as well

    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.