> net#arf:$.a500.RiscOS+.doc.SaveDesk
Author: Neil Raine
Status: Draft proposal, not agreed yet
History:
20-Sep-89 0.01 First draft.
20-Sep-89 0.02 TinyDirs section added.
20-Sep-89 0.03 Desktop_PreSavingDesktop stuff deleted.
*SetMemorySize -next <n>k added
Comment about *Desktop_SetPalette added.
Comment about printer drivers saving choices added.
20-Sep-89 0.04 /<Edit$Dir>.!Edit changed to /<Edit$Dir>
Comment about junking Filer=>Display=>Save added.
20-Sep-89 0.05 Section about "shared resources" replaces "!System"
21-Sep-89 0.06 Simplified according to WStoye's comments
26-Sep-89 0.07 Added stuff about !Alarm
Added 'Outline' section
Added 'Work done in Desktop module' section
29-Sep-89 0.08 Correct section about dbox
Enlarged section on Filer
4-Oct-89 0.09 Message_SavingDesktop changed to Message_SaveDesktop
Example code segment for C application added
6-Oct-89 0.10 Stuff about not acknowledging Message_SaveDesktop
19-Oct-89 0.11 Stuff about desktop auto-saving removed
Aside about save dbox not being a menu removed
"Work done in the Desktop module" section removed
GStark 27-Oct-89 0.12 Added Service_WimpSaveDesktop (in resident modules
section) 27-Oct-89 0.13 Corrected Service_WimpSaveDesktop 31-Oct-89 0.14 Put auto-save icon into description of dboxGStark 03-Jan-89 0.15 Changed Ram Disc and other slot size stuff to the new spec.
This document describes the Task Manager facility that allows a user to save and restore the current state of his desktop, thus obviating the need for a separate !SetDeskWorld utility.
The Task Manager menu provides an option to save the current state of the desktop world into a Desktop file, which can be used to restart the desktop in its original state.
There will also be facilities to save the Desktop file as a !Boot file (on ADFS) or !ArmBoot file (on NetFS), whereby the necessary configuration commands to get the system to reboot via this file are automatically carried out by the Task Manager.
In general the boot file will not return the desktop to precisely the state it was in, because:
(a) Applications which have not been specially written to deal with
desktop saving will not be restarted.
(b) Apart from Filer directory viewers, applications will not re-open
all the windows that were open when the desktop was saved. In particular, this means that editors will not re-open the files that were being edited.
Task Manager will have the following options:
Save state to a given file, without exitting Exit to supervisor Shutdown machine
The menu therefore contains:
New task => (writeable buffer) Task display *Commands (f12) Desktop boot => (boot dbox) Exit Shutdown
Note that the menu option says "Desktop boot" rather than "Save desktop" in order not to raise the user's expectations too high, since it will not in general be possible to return to precisely the same state as the desktop was in.
The boot file save dbox would look like this:
<file icon>
[ !Boot ] [OK]
[ ] Auto boot [ ] Auto save
If auto boot is enabled, then the effect of SHIFT being pressed on reset is
reversed: ie. if it is not pressed, the boot file will be executed, and if
it is pressed, the boot file will not be executed. The icon is initially
set up to reflect the current state of the auto-boot CMOS RAM bit.
The auto save icon is always turned off by default - if it is enabled when the file is saved, the file will be marked as an auto-save file, so that when the user selects Exit or Shutdown from the iconbar menu, the desktop state will be automatically saved in that file.
The filename is initialised to "!Boot" or "!ArmBoot" when the Task Manager starts up, depending on whether adfs or net is the configured filing system. The user can change this if he wishes, and then click on OK or drag the file into a directory viewer.
net: If directory name is net#<fsname>:& *opt 4,2 executed on the appropriate fileserver *configure filesystem net *configure fs <fsname> *configure boot/noboot
other: If directory name is <fs>::<discname>.$ *opt 4,2 executed on the appropriate disc *configure filesystem <fs> *configure boot/noboot If <fs> is adfs *configure drive <drive containing appropriate disc>
Filing systems other than the network are assumed to behave like adfs, ie. the boot filename is "!Boot" and it must be created in "$".
Aside: It was felt that it would be too much of a shock for the user if
an error message was returned if the file was not saved in the root directory, so instead it just doesn't do the filesystem configuration etc.
Once the file to be saved is known, the save protocol can start:
If there is not enough memory free to be allocated for a particular slot then, instead of giving errors, the largest amount of memory which is free will be allocated to the slot.
*Set SaveDesk$File <Desktop$File>
What this does is to ensure that when the file is used to restart the desktop, the environment variable SaveDesk$File is set up to remember the name of the file. This works because the Desktop module has also been extended to set up Desktop$File to the name of the file passed to it.
When the user selects 'Exit' or 'Shutdown' from the task manager's menu, it looks to see if the variable SaveDesk$File is set up - if it is, it automatically saves the desktop state in this file before exitting.
+16 Message_SaveDesktop (10) +20 (word) file handle of desktop file being written +24 flag word: bits 0..31 reserved (ignore them)
Note that this is a RISC OS rather than a C file handle, so fprintf() cannot be used. The RISC OS SWIs OS_BPut or OS_GBPB should be used instead.
A typical example for a C application follows:
#include <os.h> #include <swis.h>
os_error *save_desktop(int handle) { char *ptr;
for (ptr=getenv ("Edit$Dir"); *ptr; ptr++) { os_error *error = os_swi2(OS_BPut, *ptr, handle); if (error) return error; }
return os_swi2(OS_BPut, 10, handle); /* line terminator */ }
(a) Tasks which don't understand desktop saving will not be saved in the desktop file, and the documentation should make it clear that this will happen with old applications.
(b) If an application gets an error while writing to the file, it should acknowledge the message and report the error. The Task Manager will detect that the message has been acknowledged, and will abort the save operation and remove the file.
Normal applications:
The typical restart command for an application is a GSTrans-ed form of something like:
/<Edit$Dir>
Note that since several copies of !Edit can be loaded at once, this GSTrans-ing operation should be done as soon as the application is loaded (and the result stored in a buffer), in case the value of Edit$Dir changes subsequently.
Resident modules:
Resident module tasks do not require a restart command of that form, since they are automatically started when the desktop is entered (by means of the Service_StartWimp protocol). However, if the modules are not stored in the ROM, they will probably be loaded by means of some form of *RMEnsure command in a !foo application, so the !foo application should be re-run instead.
There is a service call provided, though, for modules which need to save some state to the file, e.g. ColourTrans saves its calibration. This is as below:
Service_WimpSaveDesktop (&5C)
In R0 = flag word (as in Message_SaveDesktop)
R1 = &5C (reason code) R2 = file handle of file to write *commands toOut R0 -> Error, if necessary, else preserved
R1 = 0 for error (i.e. claim), else preserved all other registers preserved
When a module receives this service code it should write out any * commands, to the specified file handle, which should be performed by a Desktop Boot file on entry to the Desktop.
If an error occurs (Disc full, Can't extend, or even a module specific error like 'Can't save desktop now because...' then the service should be claimed, and R0 should point to the error block.
This service call is performed before the task manager issues the Wimp broadcast message Message_SaveDesktop.
NetFiler:
Network logons must be regenerated, so that Filer windows referring to network directories can be re-opened. The NetFiler module must keep track of which username is in use on each fileserver, so that it knows the required username to put in the *command. These commands would not include the password - if the user id required a password, the Wimp's command window would appear with the *Logon command in the title and the prompt 'Password:' in the window. The current NetFiler would have to be changed so that the window title displayed the fileserver and username, so that the user knew which password to enter!
Filer:
As long as the appropriate logons are executed, the current state of the filer display can be saved by using the Filer's ability to generate *Filer_OpenDir commands for the directories currently open (already used in the Filer's Display => Save option).
The Filer must remember the full pathnames of any applications it sees (eliminating duplicates), and issue a "Filer_Boot" command for each application that contained a !Boot file (since these can set up aliases and load in icons for data filetypes).
The Filer must issue a Message_FileStarted broadcast after it has started all its children, which allows the TaskManager to 'renumber' the Filer in its list, so that its desktop saving will be done AFTER that of the individual filing systems. This is important so that the NetFiler can issue its logon commands before any net directories are opened.
Shared resources:
Environment variables pointing to shared resources are set up when the !Boot file of the relevant shared resource directory is run. This is therefore dealt with by the Filer.
PaletteUtil:
The Palette Utility is capable of saving the current palette in a file, but this would not be suitable for saving its current state into the saved desktop file. It would have to accept a new *command of the form:
*Desktop_SetPalette RRGGBB RRGGBB RRGGBB etc. (times 20)
where 'RRGGBB' is a sequence of 6 hex digits defining colour (0..15, then the border colour and then the 3 mouse colours).
(The maximum length of a line in a Desktop file is 256 characters, and at 158 characters, this line is OK).
Printer drivers:
Similarly the printer drivers can set their current state from the 'PrData' file stored within themselves, but strictly speaking ought to save their state as a set of textual parameters on the command line, which could be re-asserted when the command was executed. The problem with simply saving the current state into the PrData file is that two different desktop save files with different printer setups would produce the same result if there was only one printer application, since both would cause the same PrData file to be loaded. However, it may be impractical to duplicate all the functionality of the modifiable parts of the PrData file as *commands.
If the state must be saved in the PrData file, then at least the printer drivers should behave like !Edit in that if you try to exit while you have unsaved choices, a dialogue box is presented.
!Alarm:
Applications such as !Alarm that live in DeskFS: cannot easily save data into their application directory (unless the user copies the directory onto a disc and runs it from there).
With the advent of desktop saving, it is probably better for applications like !Alarm to save small bits of configuration status in an environment variable, and then to output an appropriate *Set command when the desktop save occurs.
The ROM version of !Alarm will detect which filing system it was run from, and grey out the "Alarm=>Set" option if it detects that it has been run from DeskFS. It can do this as follows:
handle% = OPENIN"Alarm:!Alarm" :REM open alarm file SYS "OS_FSControl",21,handle% TO ,,fsword% :REM read FS info word CLOSE #handle% IF (fsword% AND &FF)=21 THEN <grey out "set alarm">
!Alarm should use an environment variable to store the user format time string, eg.
*Set Alarm$DateFormat %w3 %zdy %m3 %z12:%mi %pm
Another environment variable is also required:
*Set Alarm$DateType Analogue *Set Alarm$DateType HoursMins *Set Alarm$DateType HoursMinsSecs
since Alarm$DateFormat is still used for the user date string even if (eg) analogue is initially selected.
In this way all the data concerning the display options is held in the desktop save file, rather than the application itself. CMOS RAM is not used, since (a) there is not enough to store the user format string, and (b) if the user format string is in a variable, then so should the display type be.
However, the alarms are stored in the application directory, but are not available if !Alarm is run from DeskFS.
ADFSFiler:
It is not necessary to 'log on' to discs - the user will automatically be prompted to insert the appropriate discs as required.
TinyDirs:
The TinyDirs module must return a *AddTinyDir command for each directory currently held on the iconbar, in left-to-right order. When re-executed, these commands would cause each new directory to be placed to the right of the previous one.