
Current method of starting a task:

    *   TaskIcon sends a NewTask message to Edit, where data = name of
        command to execute (ie. "ShellCLI_Task").

    *   Edit creates a text buffer to contain the output, appends its task
        number and the text buffer handle as two 8-digit hex numbers to the
        original command, and issues it using SWI Wimp_StartTask.

    *   TaskWindow picks up the *ShellCLI_Task command, and enters itself
        with the same parameters.

    *   The TaskWindow module start entry picks up the parameters, decodes
        them and sets up its task block based on that.

    *   It invokes a command prompt in the new task domain.

    *   To kill the task, a Message_Quit is sent to it (either by Edit or
        the TaskManager).

New requirements:

    *   A simple *command with various options that allows a task window to
        be started from any other task (not just edit).

    *   An option to specify the task's slot size.

    *   An optional *command to be executed in the window initially.

    *   An option for the task to be 'invisible' until it requests some
        input from the keyboard, or output to the screen.

    *   An option for the window to be automatically removed when the
        initial command terminates.

New specification:

   *TaskWindow [-wimpslot <n>k]                ; set slot size
               [-display]                      ; display window immediately
               [-noignore]                     ; don't ignore ctrl chars
               [-quit]                         ; close window when finished
               [-name <string>]                ; name of task/window
               [[-command] <string>]           ; command to execute

Note that the command following -command may be in " ", to allow for OS
redirection to be put into it (without the quotes, the OS redirection would
be applied to the *TaskWindow command, not to the command to be executed in
the window).

The command following -command is executed in the task window, (after the
Wimp slot is set to that specified by the -wimpslot option) but the command
itself is not displayed in the window.  When the command returns, the task
window either disappears (if -quit is specified), or the command prompt is
displayed.

If there is no command present, -display is ON by default and -quit is OFF,
otherwise they are the other way round.  Thus if the command is null, the
window must be displayed initially and kept open until explicitly closed.

The string following "-name" is used for:

    *   Error reporting if Wimp_ReportError is used (ie. if an error occurs
        in the task while it has no edit buffer open).

    *   The task's name as seen by the TaskManager.

    *   The title bar in the !Edit window.

The default value for -name is "Task Window".


How it works
------------

The TaskWindow module supports the *TaskWindow command.

If called from within a task window, the command must be prefaced with
"*WimpTask ", to ensure that it is invoked in another task domain.  Note
that an alias could be used to do this, eg:

        *Set Alias$Task WimpTask TaskWindow %*0

The TaskWindow module must cope correctly with Wimp_StartTask being called
from within itself.  It should do this by associating a task domain (stored
by the Wimp at location &FF8) with each task block, so that vectors are only
intercepted if the current task domain matches that in the block.

The TaskWindow command checks whether it is running inside a task window
(ie. is it in the same task domain as a task window), and returns an error
if so.

Otherwise it sets the wimp slot to that specified, and sets up a new task
block, with the ParentTask and ParentTxt fields both null.

If the -display option is specified, it invokes the "connect task to window"
procedure; otherwise this is only done if a keyboard input or screen output
operation is performed (ie. RdchV, WrchV or ByteV (inkey) are called).

If the -command option is specified, the block's Quit flag is set TRUE, else
FALSE.  If the -quit command is specified, this overrides the other setting.

If the -command option is specified, the command is executed, otherwise a
command prompt is displayed.

The task window's exit handler checks the QUIT flag.  If set, the edit
window is closed and the task killed - otherwise the command prompt is
displayed in the edit window.

The task window's error handler checks whether the task is connected to an
edit buffer, and the QUIT flag:

        Edit    Quit    Action
        ----    ----    ------
        YES     YES     Error reported textually, "Press SPACE", window killed.
        YES     NO      Error reported textually, command prompt displayed.
        NO      YES     Wimp_ReportError called, task killed.
        NO      NO      Error reported textually, command prompt displayed.

New method:

    *   *TaskWindow <etc> causes a task block to be set up in the current
        domain, with no ParentTask or ParentTxt.  It does this by entering
        the TaskWindow module.

    *   If interactive I/O is required in a task that has no parent task,
        the TaskWindow module sends a NewTask broadcast, hopefully to be
        picked up by !Edit, and sets a flag saying that it wants to be given
        a text buffer.  The task then calls Wimp_Poll, and blocks while it
        still has no text buffer.  If the NewTask message bounces, an error
        is returned, and the task enters a 'moribund' state.  Note that it
        is important that it does not attempt to reopen the text buffer once
        this has happened. [ Actually it does just that, and can get stuck
        as a result].

    *   On receipt of a NewTask message, or when the user chooses
        'Create=>New Task' on the iconbar menu, Edit creates a text buffer
        to contain the output, appends its task number and the text buffer
        handle as two 8-digit hex numbers to the original command, and
        issues it using SWI Wimp_StartTask.

    *   The TaskWindow module start entry checks for XXXXXXXX XXXXXXXX being
        on the command line.  If it is, it treats the command as an
        old-style ShellCLI_Task one; otherwise it is a new-fangled
        *TaskWindow command.

        If the command is an old-style one, it then looks to see if there is
        a task window waiting to pick up a text buffer:

           - If so, the handles are given to the task that is waiting, and
             we call OS_Exit.  The waiting task, which was looping calling
             Wimp_Poll, spots that its parent task handle has become
             non-zero and wakes up, sending an Ego message to its parent.

           - If not, the handles are given to the current task, and we
             proceed to claim a task block etc.

    *   To kill the task, a Message_Quit is sent to it (either by Edit or
        the TaskManager).

    *   Exit and Error handling are improved in the way described above.

Bugs:

    *   If you *Obey a file from within a task window, and that file
        contains more than one line of the form "WimpTask TaskWindow ...",
        then:

          - Under RISC OS 2.00, you get "File 'Can't' not found"
                If you create a file called "Can't" in the current
                directory, as an obey file that says "Error 1 Can't %*0",
                then you get the error "Can't start task from here".

          - Under RISC OS 2.05, you get "Address exception at ...".
                This turns out to be because R0 on entry to Wimp_ReportError
                contains a task handle.

        It appears that there is some horrible interaction between obey
        files, task windows and the wimp, to do with overwriting buffers
        perhaps?

    *   If you select the -ctrl option when creating a task window, this
        setting is not mirrored in !Edit.  Similarly, if you create a task
        window using !Edit, the "Ignore ctrl" status is not reflected in the
        task itself (which is a shame as the task is much better at it than
        !Edit is).

    *   There is also a bug in !Edit, in that control sequences are still
        not ignored in full anyway - only one character at a time.

    *   The TaskWindow must perform the 'ignore ctrl' option itself, as the
        current Wimp causes the following control sequences to be sent to a
        task that starts another:

                VDU     28,13,38,68,25
                VDU     4
                VDU     23,1,0,0,0,0,0,0,0,0
                VDU     23,16,&01,&FE,0,0,0,0,0,0

        Even if the 'ignore ctl' option is on in !Edit, this will still
        cause the task window to be opened if the task had not yet printed
        anything.

    *   If you Quit a task because the -quit option is set, the task window
        edit buffer is not closed.  This needs a new message between the
        TaskWindow and !Edit.

    *   The task name is not put into the task window title bar.  This needs
        a new message between the TaskWindow and !Edit.

    *   It would also be useful to have a *command that changed the title of
        a task dynamically (ie. after it had started running).

    *   It is possible for a task to become stuck, such that you can't kill
        it using the task manager display.  For example, if !Edit is not
        loaded when you start a task, it will remain stuck until you next
        create a task window using !Edit, whereupon it will run in that window.

    *   Currently exit and error handling is rather simpler than in the
        scheme described above.  Errors are reported in a window if there is
        no text buffer, and as text otherwise.  Since task windows do not
        yet close automatically, there is no need to check whether the -quit
        option is set when reporting an error textually.

    *   Because the spool file used in a taskwindow is maintained by the
        MOS, and only swapped in and out at Wimp_Poll time, and because the
        action of starting a new task is invisible to the TaskWindow module
        until it next comes to grab something on the vectors (it checks its
        Domain ID against that maintained by the Wimp at location &FF8), it
        is not possible to automatically turn off the spool file if a task
        is started from within a task window.  All it knows is that next
        time OS_WriteC is called, the OS's spool handle is non-0 and the
        domain ID has changed.  This means it doesn't know if the spool file
        was started in the original task window or was invoked in the new
        task, prior to writing any characters.

