[JPEG image]

PCA-2 Draft changes

Introduction

First and foremost: Backward compatability has been maintained. For those programs which know about it however, there are numerous improvements...

Terminology
The following new term is used:
Applet This is a program which provides a function, or set of functions to work on a particular object type. In version one of the protocol this was termed a 'Remote' task. The only real distinction between an 'Applet' and a 'Remote task' is that an applet registers itself with version 2 of the PCA support module, and can therefore be auto-loaded by the module when required.

Change summary

New *Commands


Extensions to the PCA support module (Version 0.32).

*PCA_Register <Applet id> <type,type...> <flags> <spritenames> <run command>
This command registers an application with the PCA support module. It should be included in an applets !Boot and !Run files. This *Command also causes Message_AppletsChanged to be broadcast.
Example:

*PCA_Register Composition.115.Clares.1998 ff9,aff 111011 pcacompo,!compo <Compo$Dir>.!Run

The parameter details:

Appletname.version*100.Publisher.year_released
This is called the applet id. It is used by SWI PCA_AppletStarted to recognise the applet and add one to its counter of running copies.
Case sensitive.
Appletname should be <31 chars with no spaces.

Comma seperated list of object types we are interested in.
Limited to a maximum of 8 filetypes (no checks yet!)
NB. The applet can still fail to use an object when started up. For example, if the applet only works with sprites of a particular bit-depth. In this case it will report why it cannot work with the object to the user and send Message_UnHook back to the Local task to terminate the PCA link.

Flags for Message_ImHere
NB. An unresolved (minor) problem here where an applet can have configurable flags for things like inplace editing but as these options are best left with the Local task no action has been taken.

pcaspritename,!spritename
The PCA and RISC OS application spritenames to use. NB. a 'pressed' version of the PCA sprite should also exist. Applets which want to can also use a 'd' version of their icon for the *PCA_Register command so that applets which are on disc are displayed in the PCA dialogue 'dimmed' (see the
screenshot below).
The pca sprite should be 32x32 pixels, 256 colour (or greater) and should match the style of the existing applets as shown in the dialogue screenshot.
Currently the RISC OS application spritename is not used by any of the dialogue types supported by this version of the PCA module.

Rest of line
The string to be passed to Wimp_StartTask which will start the applet. If the applet wants to know if it has been started by the PCA module then it can append a flag to this string (eg. '-autobootpca') and parse its run tail for this string.

In addition, the beta module has two other new *Commands which are unlikely to make it into the release version, as they have been superseded by SWI PCA_AppletStarted and code within the support modules module task.

New SWIs


SWI PCA_BuildDialogueAddr
SWI PCA_DialogueInfo
SWI PCA_ActionDialogueAddr
SWI PCA_AppletStarted
SWI PCA_DialogueState
SWI PCA_DialogueToolNameFromIcon
SWI PCA_ColourTableAddr
SWI PCA_ResetColourTable
SWI PCA_WriteColour
SWI PCA_ReadColour
SWI PCA_RedrawColourWindow
SWI PCA_AppletTimeOut

SWI PCA_BuildDialogueAddr TO code_address%

You should then call the code address with R0 pointing to a block:
Block contains:
+0  filetype of object
+4  pointer to object tag
+8  WhosAbout_flags
     b0 reserved
     b1 reserved
     b2 Local supports undo extension protocol
     b3 Local is using NC user interface
     b4 Local supports help extension protocol
        all other bits clear and reserved
+12 search scope
    0 all PCA apps known (those running and those registered but not running)
    1 PCA apps running
    2 PCA apps registered but not running
    3 PCA apps registered (running or not)

+16 b0-7 return info format 
    0 return a RISC OS menu handle
    1 NCOS menu (same as above but no titlebar)
    2 window definition - RISC OS (buttonbox from below + a titlebar 'Applets')
    3 window definition - NCOS 'buttonbox' (buttonbox with no titlebar)
    4-254 reserved for expansion
    255 raw data (see format given below)

    b8-15 sorting method
    subdivided:

    b8-9
   %00 no sorting
   %01 Alphabetic sort
   %10 reserved
   %11 reserved

    b10-15
##     All values reserved (0).

    b16-23
    If return info format is =2 or =3 then this is the
    desired width of the dialogue box in items. Valid value range 1-255
    Suggest you stick to 1,2,3 or 5 or allow user control.
    Otherwise reserved and zero.

    b24-31 More flags:
           b30 (for button dialogues) set don't make icons depress (no R5)
           b31 set add an 'unhook' tool (+28 has valididity)

+20 Clear word
+24 EOR word

+28 (if +16 bit 31 set)
    a series of null terminated strings or zero for module defaults
    if strings, then the format is as follows:
    .default_menu
    EQUS "Unhook"+CHR$0:REM textual tool name
    EQUS "pcaunhook"+CHR$0:REM tool sprite name
    EQUS "spcaunhook,ppcaunhook;R5"+CHR$0:REM icon button definition


On exit, if R0=0 then no PCA applets are available otherwise R0 is a pointer to a menu definition, window definition or raw data depending on the return info format in block+16 on entry.

Called by the object owning (Local) task when the user asks to initiate a PCA session or when a currently open pca dialogue needs updating. This is the same as broadcasting Message_WhosAbout, collecting ImHere replies and building a dialogue box but this call also adds the applets which have registered but are not running (depending on the scope given in block+12 of course).

It can also be used by a task which wants to present the PCA system to the user in a different manner to gain information about the available applets. For example, NCPaint.

Notes:
If no sorting is specified, there are disc and memory based applets selected, and a menu style dialogue is requested then a dashed line will be inserted into the menu between the memory based and disc based applets.

The EOR and Clear words at +20 and +24 are used in a similar way to SWI Wimp_SetIconState to filter the flags word in the ImHere messages collected by this call. The Local task can use these words to disable inplace editing for example. To do this, you would set bits 4 and 5 in the Clear word, and have a null EOR word (b4 is the inplace flag, and b5 is PCA-inplace v2). The clear word indicates which bits to alter and the EOR word holds the new value(s). You should not clear or set bits willy-nilly, only with a definite purpose for flags which are well defined in the standard (don't clear reserved bits for example).

To avoid all sorts of nasty problems the windows created by the above calls include *no* user graphics. The wimp can redraw them by itself.

[JPEG image] If the requested return type is a window dialogue you will need to call Wimp_CreateWindow and use the window handle. You should include code to delete any PCA dialogue window created previously to avoid filling up the wimps workspace with old windows. If using popup PCA you should then open the dialogue as a menu with Wimp_CreateMenu or Wimp_CreateSubMenu so that clicks off it will close it. If you want to impliment Dynamic PCA then call your toolpane redraw code to display the newly created pca toolbar at a suitable position next to the document window.
The PCA Support module maintains dialogue data for each calling task (the memory used is freed automatically by the module when the task quits). Currently, only one dialogue per calling application is supported by the module - for dynamic PCA we suggest you move the dialogue with the input focus (and rebuild if the selected object changes).

If a dialogue type of 'Window' is asked for then the window definition returned by R0 on exit may be copied to the tasks workspace and icons added if desired before the window is created. If you do this then you must ensure that any icons you add are handled by your task and are not passed to SWI PCA_ActionDialogue.

[JPEG image] If a menu is asked for, and you thread this into your menu tree you should move the wimp block pointer to that of the sub-menu before calling SWI PCA_ActionDialogueAddr as the module cannot know the menu depth at which you have included the PCA menu. ie. The value passed in block+8 to PCA_ActionDialogue should be windowblock+sub_menu_depth*4 where zero is the first level of the menu tree.

Raw data format
This is a null terminated list of pointers to Message_ImHere blocks. You should make no assumptions about the position of these memory blocks in memory. Always access them via the list.

(The PCA module will shuffle the items in this list according to the input sort criteria - this saves it having to move the ImHere blocks around).

The Message_ImHere Wimp message blocks with two exceptions (noted below) are standard, see this messages definition in the original protocol for details.

The first difference to note is that, for applets still on disc this is a 'fake' message block - the task handle in block +4 will be zero and block +12 is a pointer to the run command string. The position of the run command in memory will be safe - raw data format users can remember it and use it later to start an applet with SWI Wimp_StartTask.

The second difference is that directly after the spritename at block +60 is an indirection definition for the dialogue type icons. ie.

+60   "spritename"+CHR$0
+60+n "sspritename,pspritename;r5"+CHR$0
This is added automatically by the PCA module and the size of the message block at block+0 updated, for both disc based and memory based applets.

SWI PCA_DialogueInfo TO infoblock%
On exit, if r0=0 then no dialogue has been built for this application otherwise, r0= a pointer to a useful block of information:

r0+0   Applets       Total applets returned by the last build dialogue
r0+4   Mem_applets   Total number of memory based applets returned
r0+8   Disc_applets  Total number of disc based applets returned
r0+12  copied from block+0 of BuildDialogue (filetype)
r0+16  copied from block+4 of BuildDialogue (tag)
r0+20  copied from block+8 of BuildDialogue (flgs)
r0+24  copied from block12 of BuildDialogue (search scope)
r0+28  copied from block16 of BuildDialogue (return format, sorting, flags)
r0+32  Pointer_raw    Pointer to the start of the raw data structure
                      [list of message pointers]
r0+36  Pointer_dlog   Pointer to the start of the dialogue definition
                      or zero if raw data was asked for.
r0+40  Safe_flag
       =1 no PCA apps registered, started  or quit since the build *began*
       =0 PCA apps have registered, started or quit since the build *began*

r0+44  TaskHandle - your task handle.
SWI PCA_ActionDialogueAddr TO action_address%
This SWI is called by the Local (object owning) task when the user selects an item in a PCA menu or dialogue box. After calling this SWI you should then call the action code address returned with R0 pointing to a block:
+0  Object tag
+4  Pointer to a string, which is the objects textual name.
    This could be a leaf-name or a full filepath as appropriate.
    A null name (NB. A pointer to a null string NOT a null pointer!)
    is allowed in which case the recieving applet should choose
    something suitable.
+8  Input data [see block+28 bits 8-15]
+12 Object type (eg. &ff9 for sprites)
+16 Local tasks flags for Message_DoYourStuff/WhosAbout:
        b0 reserved
        b1 reserved
        b2 Local supports undo extension protocol
        b3 Local is using NC user interface
        b4 Local supports help extension protocol
        b5 Local task is a colour history provider
        b6 Local task would like to inplace redraw if possible
        b7-12 reserved - set to zero.

bits 13-15 Local task request action flags:
        b13 Initiate clipboard paste please
        b14
        b15

bits 16-31 reserved - set to zero.

        all other bits clear and reserved

+20 reserved (0)
+24 handle of the Local tasks window (the one the object is in)
+28 swi flags
    b0-7  return info format
           0=Task handle
           1=ImHere block
             other values reserved
    b8-15 Input format - affects interpretation of block+8
           0=R0+8 is a pointer to a wimp poll block mouse click or menu sel.
           1=R0+8 contains the task handle of the tool to select
           2=R0+8 contains a pointer to a null terminated tool name to select
             other values reserved

On exit, R0 is either the RISC OS task handle of the applet chosen, a pointer to a Message_ImHere block , -1 or zero. If greater than zero then a pca editing session has started and the selected applet has been sent Message_DoYourStuff on your behalf, you should record the task handle (in the case of a return type of ImHere block the task handle will be at block+4) and recognise other PCA messages from this task as documented in the official PCA specification and given in summary form below.

If -1 is returned then the special 'unhook' tool has been chosen and message_deselect has been broadcast on your behalf. You should unset any variables associated with active tools, delete any trap icons and (if using Dynamic PCA) clear the 'selected' state of any tool icons that were in use by calling SWI PCA_DialogueState. This SWI is usually called by the local task whenever the user chooses a menu entry or icon in the dialogue produced with PCA_BuildDialogue. It activates the appropriate applet and passes a task handle or message block back to the local task which it must then use to talk to and recognise messages from the applet. Similar to calling Message_DoYourStuff but it automatically starts the applet first. The rest of the PCA protocol continues as normal - if the applet selected wants to do inplace editing it will send the local task Message_HookMe the reply to which should be Message_ObjectPosition. All other messages used in the standard should be recognised and delt with correctly by the local application.

The SWI can also be used to select a tool by task handle or by tool name which allows (for example) tools to be automatically selected by the local task. Because PCA is an open system you should always be prepared for this swi to return zero (no tool selected) if the tool asked for is not available. If the applet chosen wants to 'own' the object (b3 of ImHere flags word) a Message_Deselect is broadcast before the DoYourStuff is sent.

You should not terminate any previous inplace editing session until you actually get a Message_HookMe from the newly selected applet even if its flags word indicates that it can do inplace editing.

It is important that the Local task be able to handle more than one (non-inplace) applet working on the object at the same time. Ideally, it should function correctly with several non-inplace applets and one inplace applet, be able to add and remove non-inplace applets and change the inplace applet without disturbing any of the others working on the object.

(Thou shalt not send Message_UnHook or broadcast Message_Deselect unless necessary)

A typical PCA session now looks like this:
User asks the local app. to build a PCA menu for the selected object (double click on object, click on Utils button, asking to open a menu structure which contains a PCA sub-menu...whatever.)

Local app. creates a tag for the selected object if it has not already done so.

Calls PCA_BuildDialogue

Creates window/menu and does the necessary to display it

When the user chooses an item in the menu or an icon in the dialogue box the local task calls SWI PCA_ActionDialogue and remembers any task handle returned.

THEN:

[On reciept of Message_HookMe unhook any previous inplace editing task, setup for inplace and send ObjectPosition]
[On reciept of Message_UpdateArea redraw the area of the object cited]
[On reciept of Message_Changed re-read object details, resize object displayed if necessary, and redraw the object - this would also cause a ObjectPosition to be sent if inplace editing]
[On reciept of Message_ResizeRequest resize if possible and send ResizeAck]
[On reciept of Message_Done redraw the entire object]
[On reciept of Message_UnHook delete trap icon if inplace editing and forget the applet]
When the window holding the object moves, the size of the object changes, the view scale changes etc. send ObjectPosition if doing inplace editing.

When the object changes in any major way (such as a sprites bit-depth, physical dimensions changing etc.) broadcast Message_Changed.

If an area of the object is modified by the local app it should *broadcast* Message_UpdateArea.

If the object is deleted or the Local app quits then the local app should *broadcast* Message_Deselect.

SWI PCA_DialogueState

on entry:

r0 bits 0-7   format of task list

              = 0 Single task handle in R2
              = 1 List of task handles in R2 [R3 holds length of buffer]
                other values reserved

   bit 8      clear = deselect task(s)
              set   = select task(s)

              all other bits reserved and clear

r1 Window or menu handle of dialogue

r2 depending on bits 0-7 of R0 is either a task handle,
   a pointer to a word aligned list of task handles or zero.
   If zero, then all of the tools in the dialogue or menu are
   set or cleared according to the state of r0 bit 8.

r3 = length of list pointed to by r2 if r0 b0=1 in bytes (multiple of four)
This swi is used by the local task to set or clear the 'selected' state of those tools in use. It should be used to keep the dialogue state up to date with the tools which are editing objects. For example:

To select the tool when it is chosen (after ActionDialogue returns >0)
To deselect the tool when it sends an unhook message to the local task
When the object tool(s) are editing is deleted (Msg_Deselect is broadcast)

You should also call this swi to select tools with a complete list of the tools which are editing the object immediately after a successful BuildDialogue as this resets the icon/menu states (the order and number of tools may be different anyway). Use this SWI in preference to any other method as it allows for the different dialogue types available.

SWI PCA_DialogueToolNameFromIcon
on entry -
r0 =item/icon number (as returned from Wimp_PointerInfo etc)

on exit
r0 = 0 or,
r0 = pointer to a null terminated tool name
This swi is used in the creation of a suitable line of help text for the PCA dialogue box. eg. 'Click here to select the Painting tool.'

SWI PCA_AppletStarted
on entry -
           r0 = pointer to null terminated Applet id (as *PCA_Register)
           r1 = task handle of applet
           r2 = 0 (!expansion!)

This SWI must be called immediately after an applet successfully Wimp_Initialises so that the PCA module knows it is running.

SWI PCA_ColourTableAddress,table TO address
This SWI returns the address of the colour table in R0. On entry, specify zero for the main palette of 256 colours, -1 for the temporary palette of 16 colours. The colour table format is currently very simple, a 16 byte header with the number of colours-1 in the table at header+4 and the maximum number of colours-1 in header+8. The colour data starts at +16 and is in the form of bbggrr00 colour words.
Generally, you won't need to access the colour table directly and should use the SWIs provided. Exceptions are loading and saving the colour table as SWIs are not provided for this function yet.

SWI PCA_ResetColourTable
This resets the global and temporary colour tables to a set of hardwired defaults. Generally, you won't want to use this SWI. :-)

SWI PCA_WriteColour
on entry:
r0 = bbggrr00 colour to write
r1 = index into colour table to write to:
(0-255) write to location specified
-1 rotate palette right (fifo) and write to first location
-2 check that colour isn't alreay there, and if not, fifo and write to first location
r2 = colour table to write to: 0,-1 or ptr to user

SWI PCA_ReadColour
on entry:
r0 = index to read from (0-255)
r1 = colour table to read from: 0,-1 or ptr to user

on exit:
r0 is the colour at this index bbggrr00.

SWI PCA_RedrawColourWindow
on entry:
r0 = palette to use: 0,-1 or ptr to user
r1 = WimpBlock
r2 = x%
r3 = y%
r4 = blocks_per_line
r5 = size of each block
This SWI can be used within the GetRectangle redraw loop of a window to display a colour table. You can either pass zero or -1 to use the global colour tables or pass your own. The format of your own colour tables should be the same as that given above, 16 byte header with the number of colours -1 in header+4.
The wimpblock in R1 is that returned from Wimp_GetRectangle and is used in a (very primitive!) redraw optimisation test.
The x and y position are given in OS units (in screen coordinates, not window coords!) and point to the top left of the palette block.
blocks_per_line in R4 is the number of colour blocks which will be plotted before a new line is started (and the y plotting coordinate decreased).
R5 holds the size of the block to be plotted in OS units. This is inclusive, so to paint the global palette in 16x16 OS unit colour blocks in a 64 wide by 4 high arrangement you would do something like:
SYS "PCA_RedrawColourWindow",0,WimpBlock,xpos%,ypos%,64,14

SWI PCA_AppletTimeOut

on entry:
r0 = new timeout or 0 to read (-1 to disable)

on exit:
r0 = previous timeout setting

Implimentation

Extension to PCASupport module

*PCA_Register
Record variables passed in a structure (use tags for pointers to strings?) Also store and init. copies_running and timeout flags for new tool. Broadcast AppletsChanged for the information of dynamic PCA applications (it'll cause them to send BuildDialogue and regenerate their toolbars to add the applet to the list of those available.

Done, however some of the parameters aren't checked fully yet.

SWI PCA_BuildDialogueAddr
The method used to call this SWI is odd because the OS cannot easily be persuaded to call Wimp_Poll from within a SWI routine. Threading out to user mode and then calling the routine directly works. The R0 pointing to a block method of passing data to the swi was chosen because C APCS compatible code is needed and, potentially a large number of parameters could be required. (Avoids stacking them)

Broadcast WhosAbout for calling task. Collect replies via a dummy Wimp_Poll loop.

When finished, scan structure from PCA_Register and add appropriate entries to the list.

If sorting requested sort the list of available applets.

If return info type=255 then just return a pointer to a list of pointers to ImHere messages.

If another return info type requested use the list of raw data to generate a menu structure or window dialogue definition and return pointing to that.

Done. Currently a hardwired limit of 512 applets.

SWI PCA_ActionDialogueAddr
The method used to call this SWI is odd because the OS can not easily be persuaded to call Wimp_Poll from within a SWI routine. Threading out to user mode and then calling the routine directly works. The R0 pointing to a block method was chosen because C APCS compatible code is needed, and a potentially large number of parameters could be required. (Avoids stacking them)

If applet chosen is not running then start it up.

If the selected applet has bit 3 set in its flags word then broadcast Deselect before hooking as the applet wants sole ownership of the object (Only Compo working as a remote does this ATM).

Send the task Message_DoYourStuff

Return with tasks handle or a pointer to the ImHere block in R0 depending on the content of block +28

Issues to point out:

The local task must include all of the PCA messages and Wimp message Task_Initialise (&400C2) in its list of 'messages I am interested in' which is passed to Wimp_Initialise. Failure to do this will result in odd things happening...

Dynamic PCA

The protocol can now be used to generate large 'component-ware' applications built from PCA applets and a simple core to tie everything together. Implimentation of this is now very simple, as the support module maintains dialogue information for each calling task. Basically, create a dialogue box of available tools and open this as a pane attatched to your document window (move this from one document to another with the input focus in a manner similar to Artworks). You should keep watch for Message PCA_AppletsChanged. On reciept, set a flag and enable null-polls. On reciept of a null-poll check if the flag is set and, if so, rebuild the PCA dialogue box.
SWI PCA_DialogueState can be used to indicate which tools are currently selected.

It is easiest to just the data returned from the SWI to build a suitable window or menu, however it is possible to ask for Raw data and 'do it yourself' to seemlessly merge PCA tools into a toolbar of your own 'local' tools. Here for example, is the iconbar from an early version of NCPaint:

[JPEG image]
The icons towards the centre represent PCA applets, the selected applet is pressed.

The simple demo application !PCADemo is a good example of the basics of Dynamic PCA.

More information on dynamic pca will be included here at a later date. In the meantime, anyone interested in pca who has a query is welcome to email me. I will endevour to help in any way I can.

Message protocol extensions

New Messages

PCA_AppletsChanged  &83493
Currently no other information is passed with this message. It informs dynamic pca applications that either:
* A new applet has registered
* An applet has started
* An applet has quit
In all cases, the Local task should regenerate its toolbar of PCA applets. (If the number of applets does not change as a result of this you can use Wimp_UpdateWindow to redraw the pca applet icons without flicker).
NB. This message is low priority, it is not gauranteed to be sent for *every* event. For example, if an obey file were to register three applets at once the message would only be sent once.

PCA_ColourSetChanged  &83494
This message is broadcast by a colour history provider task when the PCA palette has changed (see colour history protocol below).

PCA_AppletQuitIfIdle  &83495
This message is broadcast by the PCA support module task every two minutes (by default - see
SWI PCA_AppletTimeOut) to assist in the implimentation of a simple applet timeout scheme. Any running pca applets that are not editing objects or 'working' as normal RISC OS tasks should quit on receipt.

New flags word
The previously reserved word in R1+28 of Message_WhosAbout and Message_DoYourStuff has been turned into a flags word thus:

R1+28   PCA version word:
        all bits clear - PCAv1.00

bits 0-12 Local task flags:
        b0 reserved. Write as zero and assume zero.
        b1 reserved for object change protocol. Write as zero and assume zero.
        b2 set - Local task supports undo extension protocol.
        b3 set - Local task is using NC user interface.
        b4 set - Local task supports Help extension protocol.
        b5 set - Local task is a colour history provider
        b6 set - Local task would like to inplace redraw if possible
        b7-12 reserved - set to zero.

bits 13-15 Local task request action flags:
        b13 Clipboard paste please
        b14
        b15

bits 16-31 reserved - set to zero.

b2 If the Local task can undo the operations made on the object by a remote then it should set this bit, and handle Message_MiscOp calls 83482 and 83484 as defined below. If this bit is clear then a remote app. which might want to make use of undo can take its own action.

b3 This bit has two uses. When set in a Message_WhosAbout the tool should pass the new style 32x32 pixel 'pca' sprite in Message_ImHere instead of its RISC OS !appsprite. There should be two forms of the pca sprite, 'sprite' and 'psprite' (see example icons).
If this bit is set by the Local task in a Message_DoYourStuff then the applet knows that it is using a NC style user interface. If the applet has the ability to look like a NC app. then it should take the following actions:

On reciept of _DoYourStuff the applet could, if it wanted to, change the shape and layout of its toolbars and dialogue boxes to suit the NC look and feel if this bit is set.

b5 If this bit is set then the Local task supports the PCA palette SWIs and messages (see miscop messages below). Immediately after sending DoYourStuff it will send MiscOp SubReason_PaletteWindow

b6 If this bit is set then the Local task would like to redraw the object when doing inplace editing (the local task can redraw it in a special way). This bit may be ignored by the applet if it needs to redraw its own 'widgets' over the object. It can also be ignored if the applet has a 'fast' redraw mode (see PCA inplace v2 details below).

b13 This bit is set by a NC style Local task when it selects an applet as a result of a 'Paste from clipboard' action by the user. It indicates to the applet that it would like the applet to paste from clipboard. This would typically cause the applet to find out what is on the clipboard and if appropriate data exists, to get a copy of it using the standard clipboard protocol before allowing the user to paste it into the object.

In Place v2

Remote applications which want to draw user graphics over the object (such as a caret, bezier curve control handles, or simply a selection box) can now do inplace editing. Whats more, they can do it to a Local application which only knows about inplace v1 (which requires the local task to send mouse clicks over the object to the applet). First, and purely for the information of the local task the applet should set b5 of R1+20 along with b4 in Message_ImHere to indicate that you will do inplace v2.
(Some Local apps may not like the idea of doing the old style of inplace editing with what it entails - they can use these bits to accept remotes that do the new style inplace while forcing those that only know the old style back to non-inplace). In general though, the Local task should just support the origional version of inplace editing and leave it up to the applet chosen to use this new system as there are advantages to both methods.

The inplace editing protocol proceeds as normal, with the Remote sending Message_HookMe right after getting DoYourStuff. The whole trick of the new system is what happens when the applet recieves Message_ObjectPosition.

Previously this message was used to return information on the scale and position of the object on screen and allow the applet to open a toolbar beside the object. It is now also used to create and move a window _owned_ by the applet over the object in question. This window can be identical to the one the applet would open if it wasn't doing inplace editing apart from the lack of title and scroll bars and a transparent window title foreground colour. In fact, I find the easiest way is to have two copies of your normal work window, one for inplace pca and one for normal operations. Simply rename the variable used to access your active window to one or the other as appropriate and all the normal redraw/editing code can remain the same.

If you have access to the Nested Window manager the enhancements this provides can be used when opening the transparent PCA window to make it scroll and resize along with the parent window owned by the Local task. If you do not have the new Wimp inplace v2 will still work but will look odd if the object in the local window is scrolled outside the Local tasks windows visible area. (yuck, a nasty sentence)

The only other thing to watch is to disable your own rescale code and rely on the scale factors sent with Message_ObjectPosition to determine the scale at which you display the object.

Undo protocol

This uses Message_MiscOp.

R1+20 SubReason_UndoUpdate (&83482)
R1+24 Address of objects tag,
The Remote task sends this message when it wants the local task to keep a snapshot of the objects current state. How it does this is up to it. Uncompressed in a Dynamic area, compressed, on disc - whatever.

R1+20 SubReason_UndoPlease (&83483)
R1+24 Address of object tag
The Remote task sends this message to the Local when it wants it to undo the changes made since the last UndoUpdate or undo grab made by the local task. The local task will generate Message_Changed by way of a response which the Remote task should use to redraw the 'undone' object.

Help protocol A method whereby an applet can pass help text to the Local task for inclusion in its help bar. This uses Message_MiscOp.

R1+20 SubReason_ToolHelp   (&83484)
R1+24 Null terminated string
Egs.
"The Freehand line tool"
(The pointer is over a tool in the toolbar)

"Hold the left button and move the pointer to draw a line"
(The pointer is over the work window)

The Remote task should send this message to the local when the users pointer moves over a tool it wants to give information on. It should also be sent when the pointer moves over its trap window during inplace editing. For efficiency, it should not send this message unless the string has changed since it was last sent or the pointer has been outside its window(s).

Colour history protocol

This uses Message_MiscOp.

R1+20 SubReason_RememberColour (&83485)
R1+24 Colour to remember &BBGGRR00
R1+28 Slot to insert colour into or -1 to use a FIFO buffer

The Remote task sends this message when it wants the local task to remember the colour specified. If R1+28 contains -1 then the local task should roll a temporary buffer of colours right and insert the supplied colour in the first entry. If a value other than -1 is supplied then the colour should be inserted in the specified slot in another palette of more permanent colours for later use. Valid values are 0-255 though values outside this range should not cause the local task to crash.

R1+20 SubReason_UseThisColour (&83486)
R1+24 Colour to use &BBGGRR00
R1+28 Destination window handle or -1
R1+32 Destination icon handle or -1
R1+36 Destination x coordinate or -1
R1+40 Destination y coordinate or -1
R1+44 Colour importance (described below)
R1+48 Null or Null terminated colour name

The local task will send this message when the user drags a colour from one of its palettes to the remote task. The remote task is determined by the window and icon handle when the drag event ends, in this respect the message is similar to Message_DataSave. However, the destination window handle, icon handle and coordinates may be given as -1. This allows the local task to send this message if the drag is made to an icon within its own workspace which is used to represent the remote task.
On reciept, the remote task should decide how to use the colour data given to it and update windows etc. as necessary. It should not use SubReason_RememberColour as the colour given it will already appear on the local tasks colour palettes.

R1+20 SubReason_PaletteWindow (&83487)
R1+24 object tag
R1+28 handle of local tasks palette window
R1+32 xoffset within this window (from left)
R1+36 yoffset within this window (from top = windowblock!16)
R1+40 preferred width of colour patch subwindow
R1+44 preferred height of colour patch subwindow
R1+48 basic width of palette window
R1+52 basic height of palette window

Local tasks which have bit 5 set in their PCA flags word in Message_DoYourStuff will send this message to the remote task immediately after it has been given the object. The local task will also generate this message if its palette window changes. A remote task which supports palette management should use the information passed in this message to open a small 'colour patch' window nested within the local tasks window. This is to give the appearance that the colour information handled by the remote task is actually owned by the local task.
If the window handle at R1+28 is -1 then the remote task should resume control of its own colour settings. The suggested way to do this is to attatch the colour patch window to its toolbar.
The basic width and basic height in R1+48 and R1+52 is the size required by the palette window to accomodate its own icons etc (which will include your colour patch at the offsets given). If you require more space, for example to add another nested tool status window you should call SubReason_ResizePaletteWindow which is described below. The remote task should not check that the task which sent it this message is its local task. It is sufficient to check the tag passed in R1+24 is one it has been given to edit. This provison allows for the creation of a central 'palette manager' task which is not necessarily the same as the Local task.

R1+20 SubReason_ResizePaletteWindow (&83488)
R1+24 object tag
R1+28 handle of remote tasks status window
R1+32 desired change in palette window x0
R1+36 desired change in palette window y0
R1+40 desired change in palette window x1
R1+44 desired change in palette window y1

This message is sent by the Remote task to the task which sent it SubReason_PaletteWindow if it wants to change the size of the palette window in order to incorporate a status bar or other information. Values in R1+32 and R1+36 are OS-unit offsets which will be added to the palette window x0,y0,x1 and y1 extents. The palette window will be reopened extended to the new size and SubReason_PaletteWindow returned. Applets should set a flag when calling SubReason_ResizePaletteWindow and not attempt to send the message again if the returned size is different to that requested. They should take other action instead.

R1+20 SubReason_PaletteWindowMoving (&83489)
R1+24 object tag
R1+28 handle of palette window
R1+32 palette window x0
R1+36 palette window y0
R1+40 palette window x1
R1+44 palette window y1
R1+48 Reserved (0)

This message is broadcast by the owner of the palette window whenever it is moved. The applet can use it to attatch a status/tool pane.

R1+20 SubReason_UndoInfo (&8348A)
R1+24 object tag
R1+28 Local task undo state
       0 = can undo
      -1 = Has undone, can redo
       2 = cannot undo (lack of memory?)

Example code

Some of this is intended to demonstrate how to write programs to use the protocol. Other things are vaguely useful from a users point of view.


Rob Davison
29th of November 1998 Back Home 1