What does PCA do for me as a user ?
The PCA standard works at two levels. In each case a document in a common memory area can be 'shared' between two or more applications. This is not like the versions of OLE implemented on the Acorn platform. There is a major difference in that OLE copies the document for the second application to work on, thus your data takes up twice as much RAM. With PCA all applications work on the same document thus incurring no RAM overheads.
The controlling application is called the Local application and the slave application is called the Remote application.
When a document is edited in a Remote application the object in the Local application is automatically updated.
What we have up to now is a more efficient way of doing OLE. However, PCA does not stop there. Take an application like Composition which provides a page make up environment for bit image and vector images - all of which can be moved and edited - a bit like Draw for bit images but with a LOT of extras. Composition does not provide 'painting' tools but ProArtisan 24 does. If both applications are PCA compliant then a Utilities menu in Compo will show ProArt 24 as a 'tool'. Clicking on this menu entry opens a PA24 window showing the selected Compo object. PA24 can paint into this object or indeed perform any of its functions on the object. All changes are reflected immediately in Compo.
This means that an application can have other applications as 'tools'. Small 'applets' can be written to provide specific functions to a PCA application and they will be usable by any other PCA compliant application.
Imagine a simple application that does nothing else except display a sprite and conform to the PCA standard. Another application could provide paint tools, yet another could provide filters, another might provide warping tools - you get the picture I'm sure. From this range of applets you can construct the tool that you require to get the job done.
What's more, more than one remote applet can work on the same object at the same time and changes made in any one of these will be immediately reflected in all of them.
This is an awful lot better than OLE but there's still more.
Instead of each applet opening its own window we can use 'In-place' editing. This means that only the Local application displays the document. When you click on a 'tool' entry in the Utilities menu the new tool's Toolbar opens over the Local application's window. All tools then work on the image in the Local's window.
Now you are really able to construct an application from a range of applets. All you will see is one window displaying the document.
Take this a little further and imagine a DTP package supporting the PCA standard. It could have a frame containing a graphic image and you could link this to PA24, Compo or any other PCA application, which could manipulate the image. The changes would be reflected immediately in the DTP window. However, if In-place editing is used, the Toolbars would appear in the DTP window and allow you to edit the graphic directly in the DTP window.
What we now have is a system whereby an application can have an infinite number of additional tools and all applications conforming to PCA can be used with and by all other PCA applications.
An example of this could be an image in a DTP frame linked to Compo which used this image as a 'canvas' for a composite picture. From Compo one of the images in the composite picture could also be linked to ProArt24 and any changes would immediately be reflected in Compo and the DTP package.
If you jump to the bottom of this page you can download some example applications and documentation that may make things clearer. The main document to read is 'ToTest'.
A Local application creates and maintains an area of shared memory (on the RiscPC this is most likely to be a dynamic area, older hardware must use RMA or something like the Dynamite memory manager). Objects in this area may be edited by any PCA 'remote' application which is running, provided that it knows about the type of object concerned. It is the local application's responsibility to create and maintain pointers to objects and to take the correct action when an object moves or changes size.
A Remote application modifies an object in some way when requested to do so by a Local application. Remote applications can be small 'applets' or major programs in their own right. The PCA specification sets no limits on the changes which may be made to an object.
In practice, the two sides blur considerably. For example, it is possible for more than one 'Remote' task to work on the same object at the same time in which case the 'Remote' tasks must respond to some messages in a similar way to the 'Local' task.
In addition, an optional extension to the standard provides support for 'In-place' editing of objects directly in another application's window.
Limitations, assumptions and philosophy
The PCA standard requires the following:
If you are writing or have written a program which produces data objects that may be desirable for other programs to render, you should consider providing a rendering module (or some code) which other applications can use to display your object types. You should also consider placing the details (if not the rendering code itself) in the public domain.
No well written RISC OS application is an island. By supporting the PCA standard programs can take advantage of each other's good features and minimise their weaknesses while providing the user with a far richer and more productive working environment.
Memory management issues
For backwards compatability programs that wish to use PCA on pre RiscPC hardware can fall back to using the RMA or something like the Dynamite memory manager. We do not however believe that Dynamite is the best solution for a PCA task on the RiscPC. This is because Dynamite uses one dynamic area to store all of its data rather than one dynamic area for each task. This practice means that, in the event of a PCA remote task going wrong and writing beyond the end of the object being edited, *all* tasks using Dynamite could crash rather than just the one local task in question. Also, Dynamite will not work with Virtualise which provides a PCA compatible virtual memory system.
Message Index
Notes:
Filetype is divided into two fields with this format:
b 0-12 RISC OS filetype b13-31 reserved - zero.
On reading, please mask bits 13-31 out before checking the filetype.
Strings are null terminated but supporting applications should accept Ctrl. terminated (ASCII 0-31).
'Address of base' is the beginning of the data structure which contains the object.
'Offset to object' is the offset from the Address of base to the object-of-interest
For example, the 'Offset to object' of a sprite is the offset to the sprite itself (base!8 for the first sprite in a sprite area). The 'Address of base' is the address of the sprite area in which the sprite resides. For objects where the offset has no meaning the offset to the object must be zero.
The PCA references objects using 'tags'. Each tag is usually 16 bytes in length and its format is defined thus:
tag+0 = Address of base. (anchor) tag+4 = Offset to object from base. tag+8 = Length of object. (if applicable - see note below) tag+12 = Extension size and flags b0-15 These bits are to provide for expansion of the size of a tag by up to 65532 bytes. Typically, this is for app. or object specific data. This document specifies two extensions to show you how it's done. Details below. b16-31 (reserved, set to zero)The first two values in a tag are most important as they are pointers to the address of the object and the base of the data structure containing it. Remote tasks must *always* reference an object by reading these values. Generally speaking, Remote tasks can usually trust the address and offset until the next Wimp_Poll but if in doubt, re-read it from the tag. The Local task has the responsibility of creating the object's tag when the object joins the PCA system, updating the relevant fields in the tag if the object is moved or resized and discarding the tag when it is sure it is no longer needed. Tags must themselves be in a common memory area and they must not move during the lifetime of the object in the PCA system. Clares provide a small module called 'PCASupport' which may be freely distributed by registered PCA developers to facilitate the creation of PCA tags for applications which do not want to create tags themselves.
Notes:
Many objects store their length within the object data structure itself and in that case you must use the value stored within the object's data instead of relying on the length field in the tag. It is intended for object types which include no record of their size (text for example).
Tag extensions must adhere to the following standard:
tag+12.b0-15 = (bytes required+4). Multiples of 4 bytes only. tag+16 extension id. Types 0-&fff are reserved for Clares PCA. Other values are allocated in line with SWI/Message chunk numbers for application developers. (extended data dependant on tag id)To give an example of a tag extension we define two tag extensions which may be used with PCA text objects.
Simple text object ------------------ tag+12 8 tag+16 &FFF tag+20 length of buffer allocated to object (ie the remote task can extend the size of the text (as given at tag+8) until its size reaches tag+20 bytes before calling Message_Resize. Edited text object ------------------ tag+12 16 tag+16 &FFE tag+20 length of buffer for first chunk tag+24 offset to rest of text from object base tag+28 length of rest of textEdited text objects are split into two separate parts, the pointer to base at the beginning of the tag, points to the start of the first chunk of text, the offset to object points to the end of this chunk of text (= the caret position) while the values at tag+24 and tag+28 point to the rest of the text. Suitable manipulation of these values should allow a text editor to work with PCA. Note: this has not been tested with any code - any comments please contact the author of PCA.
The tag extension system is potentially very powerful but please do not abuse it. If everyone who ever writes a PCA program creates a tag extension for their own object format then chaos will reign and the PCA system will become useless. (Anyone questioning this is invited to use the specification document for the TIFF file format as bedside reading - a perfect example of a tagged file format gone wrong). In general, the basic tag structure or the 'pca text' extension defined above will do for most data types. If you really feel you have to create your own extension then please double check with Clares that a suitable extension does not already exist. The extension should then be defined in the format given above and the information sent to Clares for distribution to the PCA community.
On receipt of a PCA message you should decide if the message refers to one of your objects (either a local one you created yourself or a remote object which you are editing). You do this by comparing the object's tag address, passed in the message, with a local array of tags that you know about. Get into the habit of doing it this way (rather than comparing the tag's address fields with your own data structures) as one message, Message_Deselect may pass a tag address which no longer actually contains valid data (the object itself having been deleted). See its entry for details.
In the following documentation 'Local' is the 'owning task' being the task to which the object is 'local'. This task created the object and its PCA tag. It knows how to resize and how to delete the object.
'Remote' is the 'utility' task - the one which modifies an object for the 'local' or owning task.
Please note which messages are to be broadcast and which are sent task-to-task. The correct functioning of the system depends on the correct usage.
1. Local task broadcasts Message_WhosAbout for a selected object.
2. Remote tasks examine message data and respond with Message_ImHere.
3. Local task, in response to users choice of Remote sends Message_DoYourStuff.
4. (if doing inplace editing) Remote task, on receipt of DoYourStuff sends Message_HookMe.
5. (repeated) Remote and Local tasks broadcast Message_UpdateArea if the user changes the object.
6. Remote task sends Message_Unhook when user closes window/toolbar onto object.
7. Local task broadcasts Message_Deselect if user deletes object/quits program.
The variable names used in the example BASIC program are included after the
message number.
Message_WhosAbout (&83484) (Msg_Whos%)
Broadcast by Local task when opening Utility sub-menu/popup (see the section on user interface).
The block pointed to by R1 contains:
R1+20 filetype of object R1+24 address of object tag R1+28 reserved - 0
Receiving remote tasks should respond with Message_ImHere as defined below if the filetype is 'interesting'. You can examine the data in the tag at R1+24 if the filetype alone does not suffice (for example, a program which can only edit 32bpp sprites should examine the sprite type word at !(R1+24)+(R1+24)!4) +40 (ie tag address field+offset to object field)+40 before sending Message_ImHere).
Message_ImHere (&83485) (Msg_Im%)
Sent by Remote task to Local task. Local records the data passed for later use in creating a dialogue box or menu.
The block pointed to by R1 contains:
R1+20 bits 0-7 flags: b0 Spritename supplied b1 Info available b2 Generate 'Ping' messages. b3 Tool wants to 'own' the object b4 Tool wants In place editing b5-7 Reserved - 0 b8-31 Reserved - 0 R1+24 Tool id. R1+28 String. Menu entry/Function name (eg. Contrast...). Length limited to 31chars+terminator. R1+60 String. Name of sprite in wimp sprite pool (if b0 of R1+20 is set)The tool id is intended for remote tasks which provide more than one utility. It is returned to the task with Message_DoYourStuff.
Flags:
b0 indicates to the recipient that there is a sprite name at R1+60 - the sprite is stored in the Wimp sprite pool and should be used when rendering the popup dialogue box.b1 indicates that the tool can provide a response to Message_Info. b2 indicates that the tool would like to 'move' with the selected object (ie it gets sent Message_DoYourStuff again when the 'selected object' changes. Note: If preferred, the local application can offer this as an option as it is part of the standard that remote applications must accept Message_DoYourStuff messages for objects they cannot edit without producing an error. b3 indicates that the tool wants to 'own' the object. Local task should send Msg_Deselect for the object before sending Message_DoYourStuff if this bit is set. Do not set this bit unless you have to as it will prevent other remote tasks from sharing the object at the same time. It should only be set when the remote task wants to 'take over' the object completely. - such as Composition taking over a 32bpp sprite for use as a canvas. b4 This bit is designed to allow for real 'in place editing' operations. Because of the amount of code necessary at the local end to handle this it has been defined as an optional part of the standard.
Local applications which do not support in place editing should clear bit 4 of the flags word and send that with DoYourStuff. On receipt, the remote application should check if bit 4 is still set and if not open a remote window onto the object.
Notes: In early versions of this standard bits 28-31 of the flags word had another use. This data has been moved to Message_HookMe. Please see below.
Message_DoYourStuff (&83486) (Msg_Do%)
The block pointed to by R1 contains:
R1+20 Filetype of object R1+24 Address of object tag R1+28 reserved - 0 R1+32 Tool id R1+36 Tool flags word R1+40 String. Name of object or null (&0)
Sent by Local task to remote task depending on entry selected in Utilities sub-menu/dialogue. Remote task should record the tag address and open its window (or just its toolbar if bit 4 of the flags word is set).
Notes:
If the Remote task set bit 4 of the flags word in Message_ImHere when replying to Message_WhosAbout it should check that this bit is still set now. If it has been cleared then the Local task cannot handle remote messaging and the Remote task must open a separate window onto the object.
If bit 4 is still set it means that the local task is willing to participate in an in-place editing session. In this case the Remote task should simply open its toolbar and send Message_HookMe to the Local task to ask it to intercept mouse button and other Wimp events. Receipt of this message will also cause the Local task to send Message_ObjectPosition to move the remote tasks toolbar to the correct position.
Nothing about the standard prevents the object changing type (eg from sprite to Drawfile) between Message_WhosAbout and this message. On receipt of this message the Remote task must therefore check the filetype field and as much of the object's data structure as necessary to ensure that it can edit the object and delink/ignore the message quietly if the type is not to its liking. This allows the Local task to 'move' a remote task to different objects cleanly.
Before sending Message_DoYourStuff with bit 4 set the local task should broadcast Message_UnhookMe to prevent more than one remote task attempting to do in-place editing at once.
Before sending Message_DoYourStuff with bit 3 set the local task should broadcast Message_Deselect as the remote task in question wants to 'own' the object.
Message_Deselect (&83487) (Msg_Desel%)
Broadcast by Local task when the object has been deleted.
The block pointed to by R1 contains:
R1+20 Filetype of object. R1+24 Address of object tag
All Tasks interested in the object should close their window/abandon their operations as the object in question has been removed from the PCA system (usually because it has been deleted). Local tasks must generate this message when deleting an object, quitting etc. or remote tasks using the object will crash. If the Local task is using PCASupport for tag generation it should call SWI PCA_DeleteAndKill which will delete the tag and send this message in one operation but only when the object really is being deleted.
Note: This implies that the remote task, on receipt of this message cannot rely on more than the tag address as a key to the object. It _cannot_ access the object data via the tag passed as SWI PCA_DeleteTag has already been called (the address fields within the tag will contain -1 and the object data itself may well have been discarded). This is unavoidable without a two message (Message/Ack) deselection system which would be more difficuilt for tasks to handle. Especially (as is often the case) if the local task is about to quit.
Message_DoneMyStuff (&83488) (Msg_Done%)
Broadcast by a task when it has modified the object. All tasks accessing the object other than the originator of the message should recognise this message and redraw the object.
The block pointed to by R1 contains:
R1+20 0 R1+24 Address of object tag
Use this message for 'whole object changed' operations which do not involve changes to the object's basic structure (Eg. image filter of sprite).
Note: Recepit of this message by the Local task should not be taken as an indication that the remote task is no longer interested in it. That is what Message_UnhookMe is for.
Message_Changed (&8348A) (Msg_Changed%)
Broadcast by Local or Remote task when the object has changed (either in size or its details). Task should act as if it had got a new DoYourStuff message.
Broadcast by Remote task after it has changed the object's size. Local and other interested Remote tasks will re-read the object's details and redraw the object.
The block pointed to by R1 contains:
R1+20 Filetype of object R1+24 Address of object tag R1+28 reserved - 0 R1+32 String. New name of object or zero for no change.
Note: Nothing about the standard prevents the object changing type (eg from sprite to Drawfile). On receipt of this message please check the filetype field as well as all necessary aspects of the object's data structure. If the object is not to a Remote task's liking it should send Message_UnHook and delink quietly.
Message_ResizeRequest (&8348B) (Msg_Resize%)
Sent by Remote task to Local (task handle in R1+4 of DoYourStuff message). If the Local task fails to deal successfully it will claim the message.
The block pointed to by R1 contains:
R1+20 0 R1+24 Address of object tag R1+28 reserved - 0 R1+32 New size. Total size of object structure (including header, offset to base etc.) if flags b1 clear otherwise new size of object itself. R1+36 Flags b0 set 'Resize associated objects as well' b1 set 'New Size is for object alone - does not include header.'
If the Local task succeeds then it will send Message_ResizeAck (basically, copy R1+8 to R1+12, put Message ResizeAck into R1+16, update R1+32 and return to sender). On receipt of ResizeAck message the sender of ResizeRequest should modify the object appropriately (for example, adding rows/columns to a sprite).
Notes:
You must be prepared for the resize request to fail in which case it is the responsibility of the Local task to report to the user and the Remote task to continue safely.
If the ResizeAck message returns to a Remote task you must check that the field in R1+12 is equal to the MyRef generated by the Resize message you sent to ensure that the ResizeAck is for the object you have requested be resized. If it is, ensure that the object is in a renderable state before the next Wimp_Poll by updating the relevant parts of the object's internal data structure.
The local task's only modification to the data after a Resize is to write new size fields where appropriate and to update the object's tag address fields if the object moves. For sprites the new total area size should be written into 'Base of data'+0 - it does not know what the Remote task is going to do with the sprite and therefore cannot make any other modifications to the data.
For data types which do not store size within their data structure then the length field of the tag should also be modified (along with the address fields if the object has to be moved).
After modifying the object the Remote task must broadcast Message_Changed.
Composition will read bit zero of the flags word. If this bit is set, it will resize masks associated with the sprite in question as well. The amount by which masks will be resized is calculated from the resize-request for the sprite itself. Other applications can ignore or act on this bit as they wish. The task which requested the resize must be able to handle either action.
Bit one of the flags word is intended to facilitate the resizing of paths in Drawfiles and similar data structures under the PCA though no code has been written to do this yet.
This is what you do to change the size of an object you are editing:
From a Remote task's point of view:
Send Message_ResizeRequest and keep myref generated >from the message. On receipt of ResizeAck check myref, modify object data and broadcast Message_Changed.
From the Local task's point of view:
On receipt of Message_ResizeRequest resize object if possible, update the objects tag anchors and send ResizeAck otherwise claim the message and report an error to user.
Both Remote and Local tasks:
On receipt of Message_Changed re-read the object header as if it was newly created and redraw the entire object. (You may need to regenerate an area of your window the size of the old object - remember the new object may occupy less screen area).
Resize speed issues
When the object being resized is very large, VM (Virtual Memory)is being used, or the resize requests are frequent, there may be a performance issue. In such situations the Local task should consider moving the object to the top of its data storage area to prevent repeated memory moving operations. In applications where many small resize requests are likely then consider employing a tag extension system similar to the one defined above for text files to reduce the frequency of the resize requests.
Message_UpdateArea (&8348C) (Msg_Uparea%)
Broadcast by task when it has modified part of an object. Apps interested in the object should redraw the appropriate area of the object as quickly as possible if they have a window onto the object open.
The block pointed to by R1 contains:
R1+20 Format of subsequent data (0) R1+24 Address of object tag R1+28 Xlow (OS units at 1:1 scale) R1+32 Ylow (OS units at 1:1 scale) R1+36 Xhi (OS units at 1:1 scale) R1+40 Yhi (OS units at 1:1 scale)
where coordinates are relative to the bottom left of the object.
Currently this is the only format supported by code (working with bitmap sprites).
Other proposed formats are as follows:
R1+20 Format of subsequent data (1) R1+24 Address of object tag R1+28 Xlow (Draw units = OS units <<8) R1+32 Ylow (Draw units = OS units <<8) R1+36 Xhi (Draw units = OS units <<8) R1+40 Yhi (Draw units = OS units <<8)
where coordinates are relative to the bottom left of the object.
R1+20 Format of subsequent data (2) R1+24 Address of object tag R1+28 Xlow (Draw units = OS units <<8) R1+32 Ylow (Draw units = OS units <<8) R1+36 Xhi (Draw units = OS units <<8) R1+40 Yhi (Draw units = OS units <<8)
where coordinates are relative to the top left of the object.
If you have anyother suggestions please contact Clares or the author.
Message_ResizeAck (&8348D) (Msg_ResizeAck%)
Sent by Local task when a resize request has succeeded. On receipt by a Remote task, check that R1+12 is the myref generated from Message_ResizeRequest before modifying the object data structure and broadcasting Message_Changed.
The block pointed to by R1 contains:
R1+20 reserved - 0 R1+24 Address of object tag R1+28 reserved - 0 R1+32 New size allocated to object R1+36 Flags
Message_MiscOp (&8348E) (Msg_Misc%)
This message is designed to provide a private interface option for PCA programs without them having to request other message allocations from Acorn.
The block pointed to by R1 contains:
R1+20 Sub-reason code
- other data dependant on sub-reason code.
The sub-reason codes available to application developers are allocated in line with SWI and Message blocks - if you have one of these then those values may be used by your programs. Where appropriate, please make details of your messages available to the PCA community by sending them to Clares for distribution.
Currently, only two sub-reasons are defined for use with Composition. The current format of these is given below but is subject to change. Please contact Clares before releasing programs which rely on it:
SubReason_GiveAssociatedData (&83480)
Broadcast by remote plug-in when it would like to know more about the object.
The block pointed to by R1 contains:
R1+24 Address of object tagSubReason_AssociatedDataCompo (&83481)
Sent by Compo to Remote which broadcast GiveAssociatedData containing a tag pointing to a Compo object.
The block pointed to by R1 contains:
R1+24 Address of object tag R1+28 reserved - 0 R1+32 two eight bit and one sixteen bit fields bits 0-7 Masks in use by object bits 8-15 Format of subsequent data (zero) bits 16-31 Reserved R1+36 Reserved (0) R1+40 Blend mask address or zero = no Blend mask R1+44 Tint mask address or zero = no Tint mask R1+48 Curve mask address or zero = no Curve mask R1+52 Displace mask address or zero = no Displace mask R1+56 Shadow mask address or zero = no Shadow mask R1+60 Reserved R1+64 Reserved R1+68 Opacity of object (65536=solid 0=transparent) R1+72 Math type in use for object
Notes: The 'mask address' passed is the address of the base of a sprite area containing one eight bit greyscale sprite (at address+address!8). The size of a mask should not be assumed to be the same as that of the object - read it from the mask sprite data or use OS_SpriteOp to extract it.
The data returned by this message is fragile - re-read whenever you want to make use of it.
Message_Info (&8348F) (Msg_Info%)
Sent by Local to Remote application when the info button in the pop-up is clicked.
The block pointed to by R1 contains:
R1+20 0
Remote application should write a suitable info string into +20, change the message size and return the message to the sender.
Example info strings:
"Image Filter. No image linked at the moment."
"Image Filter. Image 'Face' linked at the moment."
Message_ObjectPosition (&83490) (Msg_ObjPos%)
This message is generated by the Local application after receipt of Message_HookMe, object repositioning operations and window open operations, if the Local application supports 'in-place editing'.
The block pointed to by R1 contains:
R1+20 0 R1+24 Address of object tag R1+28 Y scale of object in Local window (65536=1:1 or 100%) R1+32 Xlow of object on screen in 'Local' window. (limited to visible area) R1+36 Ylow of object on screen in 'Local' window. (limited to visible area) R1+40 Handle of 'Local' window. R1+44 Handle of Local windows toolbar window (or -1 if no toolbar) R1+48 X scale factor of object in Local window (16.16 format eg 65536=1:1 or 100%) R1+52 Xlow of object on screen in Local window. (unlimited) R1+56 Ylow of object on screen in Local window. (unlimited)
On receipt, the Remote task should open its toolbar/infobar relative to the positions in R1+32 and R1+36 behind the window handle at R1+44. The coordinates passed in R1+32 and R1+36 should be limited to the windows visible area (by the Local task) while those at +52 and +56 should not.
The information at R1+28 and R1+48 onwards is for use by the Remote task during mouse click operations on the object. To convert mouse coordinates read directly it should subtract the values at R1+52,R1+56 from the raw mousex and mousey coordinates, and then scale them by the factors in R1+28 and R1+48.
The X and Y scale factors are in 16.16 format. To convert a scale factor into this format, multiply by 1 << 16. For example, 100% = a scale factor of one and is therefore (1 << 16) * 1 which is 65536 or &10000. 150% = a scale factor of 1.5 and is therefore (1 << 16) * 1.5 which is 98304 or &18000.
See the remote painting code (DEFPROCremote_win) in !Spaint for a practical example of what you should do.
Message_HookMe (&83491) (Msg_Hook%)
This message is sent by the Remote task to the Local task. It indicates to the Local task that it should begin intercepting mouse button and other Wimp events to the object and send them to the Remote task. On receipt, the Local task should create a trap icon over the object (using the button type in r1+28) and send Message_ObjectPosition.
The block pointed to by R1 contains:
R1+20 0 R1+24 Address of object tag R1+28 bits 0-27 Flags - reserved and set to zero. bits 28-31 Window 'work area' button type to use for trap icon. R1+32 Window handle R1+36 String. indirection string for icon or Null (&0)
To make life easier for the remote task the Local task should also take note of the window handle at R1+32 and insert that value into the window handle field when passing on Wimp messages. This allows the remote task to use much of the same code to deal with remotely generated messages and messages to their own window.
The optional indirection string at R1+36 is intended to allow for adding a mouse pointer change when entering in-place edited objects. Take care with this string as certain settings can disrupt the Local task's message trapping. This extension is optional. Some local tasks may not support it so do not rely on it.
If the remote task is already editing an object in-place (and it is going to replace it) then it should send Message_Unhook to the local task previously being worked with so that it deletes its trap icon.
Please see the section below on In-place editing for details of the best method of trapping messages and the alterations which should be made before forwarding them.
Message_UnhookMe (&83492) (Msg_Unhook%)
This message is sent by a remote task to the Local task (or local to remote) when it wants to 'unhook' from the object.
The block pointed to by R1 contains:
R1+20 0 R1+24 Address of object tag R1+28 reserved - 0 R1+32 Window handle R1+36 Unhook 'type'
This message should be used by a Remote task to indicate its lack of interest in an object. After sending this message the Remote task should forget any references to the object and close its toolbar and/or window.
Little action need be taken at the Local end on receipt of this message unless 'Inplace editing' is going on between the tasks in which case it should remove the traps on Button click messages etc for the object. If the Local task wishes to be efficient in its generation of PCA messages then it should keep a counter for each object in the PCA system, increase the counter on each call to Message_DoYourStuff and decrease it on each receipt of Message_UnHook. Then PCA messages need only be generated in response to changes made by the Local task if the objects counter is greater than zero. When the counter reaches zero the Local task should broadcast Message_Deselect as a saftey measure to ensure that all Remote tasks stop using the object.
The 'unhook type' at R1+36 currently has two defined values:
R1+36 0 'Unhook' is temporary (used by Compo to support the 'Track selected' preference option) R1+36 1 'Unhook' is permanent - forget about this PCA.
All values other than zero should currently be treated as 'permanent'.
Date : 15/08/96
Status : Release 1
The aim of this section is to define the work necessary for applications to support 'in-place' editing (applications working on an object within another application's window) within the framework supplied by the PCA itself.
This feature is an optional part of the PCA specification. All remote tasks must be able to operate according to the normal PCA specification (open their own window onto the object) if the Local task in question does not support in-place editing. Even if the Local task does support this, it is wise for the remote task to give the user the option of switching to external editing as in-place editing has its disadvantages as well as advantages. (The principal disadvantage being that only one in-place editing session per object can be undertaken at a time, for obvious reasons).
Local task
The greatest amount of work is down to the 'Local' or object-owning application.
After invoking a remote task with the PCA message DoYourStuff when bit 4 of the flags word is set, it must expect receipt of Message_HookMe from the remote task. When it gets this message it should create a transparent icon in its window which completely covers the object and send Message_ObjectPosition.
The button type of this icon should be taken from bits 28-31 of the flags word as sent by Message_HookMe and the indirection string (if supported) from R1+36
Then, on receipt of the following standard Wimp messages the Local task must check to see if the message refers to an icon covering the object, and if it is, modify the message block and pass the message to the remote task using Wimp_SendMessage.
Doing this effectively cuts a 'hole' in the window where the object is. Messages into that region get shunted to the Remote task and are ignored by the Local task.
6. Button_Click
xposition and yposition should be made relative to the object's bottom left. Window handle must be set to the one supplied in Message_HookMe. Icon handle must be set to the special value -&414350 (-"PCA")
??? Other messages ???
??? Which to support and how to modify them ???
??? Advise us if you have any suggestions ???
On receipt of Message_OpenWindow for the window in which the object resides the Local task must send Message_ObjectPosition to the remote task so that it can open its toolbar at an appropriate place.
Also, any actions which cause the position or size of the remotely linked object to change must resize and reposition the icon created above and send Message_ObjectPosition again.
On receipt of Message_UnhookMe it must delete the icon covering the object and carry out any other work necessary to restore normal access to the object. The same action should obviously also be undertaken if the object is deleted.
Remote Task
On receipt of Message_ObjectPosition the remote task must open its toolbar at an appropriate position calculated from the data contained in the message.
This toolbar must contain at least one icon which, when clicked on, sends Message_UnhookMe to the local task, removes any references it has to the object and closes the toolbar. Model the appearance of this icon on the window close icon and position the icon at the far left horizontal toolbars or at the top left of vertical toolbars.
On receipt of Message_Do/Message_Changed the remote task must check to see if In-place editing is on (b4 of flags in Message_Do) and, if so, send Message_HookMe rather than opening its own window onto the object.
On receipt of ButtonClick messages (apparently) to its main window the remote task should check the icon handle and if it is equal to -&414350 treat the coordinates passed in the ButtonClick block as 'corrected' for the position of its window, scrollbars etc as the coordinates are already relative to the objects bottom left. Modify the object data as appropriate and generate Message_UpdateArea as with standard PCA practice.
You should be able to use the same code for remote and local actions just do not convert pointer coordinates to be relative to your main window and do not redraw your main window (it should be closed anyway).
Note: For 'painting' or 'dragging' type actions it is sometimes wise to set the remote button type (in Message_HookMe) to Click and to do a tight repeating 'loop' around your redraw/paint code, reading the mouse pointer information directly until the button click stops. In this situation the Remote task should make use of the information in the last Message_ObjectPosition it receieved to work out the visible size and position of the object in the Local task's window (see the !Spaint example).
This documents the suggested user-interface and general message handling requirements for applications on both sides of the PCA protocol. You should note that it is possible for applications to implement either or both sides of the protocol.
To invoke the popup Ctrl-Shift-Double Click is recommended. If that shortcut is not free another combination is acceptable, preferably related in some way to the Ctrl-Double click Acorn OLE-1 standard.
In addition, add the PCA to your menu structure. The sub-menu item "Utilities >" is appropriate.
Another alternative is to add a button to your toolbar to invoke the protocol.
The width of this dialogue should be set to the width of the longest tool name returned in the Message_ImHere messages (which may be found on the RiscPC using SWI Wimp_TextOp). Add 220 OS-units to the width of all items to allow for the Tool icon and Info buttons. The height of each item is fixed at 96 OS-units.
The tool icon is present in the Wimp sprite pool and is usually the PCA applications icon. Applications which provide multiple 'tools' can register more than once, passing a unique 'toolnumber' with Message_ImHere.
The popup should be opened such that the pointer is centred over the top tool name and as a menu so it automatically closes on any mouse access outside it. If there are more than five PCAs available the popup dialogue should be given a vertical scrollbar and the initial size limited to five items. For a more detailed example, see the PCA version of Composition or the dialogue creation and redraw code in !Spaint.
Other options
Several other options may be offered to the user by a Local task. Which are practical depends on the application in question but the following may be appropriate for a task which supports both sides of the protocol:
The display radio buttons allow the user to choose the form of popup which will be presented to the user. Menus are simpler and take up less desktop space. Dialogue boxes look better and provide more information.
The In-place editing option should be provided by a Remote task. If no objects are being edited then toggling this option simply prevents or allows bit 4 of the flags word to be set in subsequent Message_ImHere messages generated. If an object is being edited in-place when this option is toggled the Remote task should switch between in-place and remote operation on that object as the option is toggled.
The 'Follow selected' option is provided by a Local task and, when on, the last task sent a Message_DoYourStuff is automatically sent a new Message_DoYourStuff every time the 'selected object' changes. Obviously this option only has validity when there is a concept of the 'selected object'.
Version : 0.07 (12 August 1996)
Chunk : &4D6C0
The PCA support module is designed to facilitate the creation of PCA style 'tags' in an area of shared memory. At a future date other useful PCA related SWIs (eg. colaescing update area rectangles) may be added. In the meantime the following SWIs are provided.
SWI PCA_CreateTag on entry - r1 = address of base r2 = Offset to object r3 = size of object (optional) r4 = flags/extension data (not in this version.) on exit - r0 = address of tag (r1-r4 are written into the tag as initial values.) All other registers preserved. Errors returnable: "This version of the PCA support module cannot create extended tags." Produced if bits set in R4 (b0-15). "This version does not resize the tag block on old hardware. (too many tags)." Produced on pre-RPC hardware if more than 2048 tags are in use.
NOTE: PCASupport relies on the first value of a valid tag not being &FFFFFFFF (-1). NEVER write this value into the base field of the tag as the next call to PCA_CreateTag will probably map your tag to another object - causing chaos.
SWI PCA_DeleteTag on entry - R0 = ptr to tag on exit all registers preserved. Errors returnable: "Bad tag passed to PCASupport." SWI PCA_DeleteAndKill on entry - R0 = ptr to tag R1 = filetype of object on exit all registers preserved.As well as the functionality of the above SWI this also broadcasts Message_Deselect for you.
You are invited to add the PCA standard to your programs and to create PCA 'applets'. However, before publishing or distributing (in any form) a program which makes use of the PCA standard you must first obtain a licence to do so >from Clares Micro Supplies.
The licence is currently free of charge and early adopters will be guaranteed
that the license will remain free for a minimum of five years. We do not
have any plans to charge for a license but we do not want to preclude the
possibility at a later date - well would you ?
PD Authors : We gurantee that your license will *always* be free.
Licensing the PCA standard allows us to keep track of who is using it, inform them of changes to the standard and provide support in the case of a problem.
PCA Logo
The PCA logo may be used by licensed PCA developers to indicate PCA compliancy. Licensed developers must not use the logo to suggest any Clares approval or branding for their products.
DJackson@clares.demon.co.uk - Licensing details and project coordination.
rdavison@xtra.co.nz
- Author of the standard.
This standard is supplied 'as is'; neither Clares nor the author of the standard make any warranty, whether express or implied, as to the merchantability of the software or standard or its fitness for any purpose.
In no circumstances will Clares or the author of the standard be liable for any damage, loss of profits, goodwill or for any indirect or consequential loss arising from the use of this standard or software.
Implementation of the standard is deemed acceptance of these terms.
We have prepared several examples of PCA applications in both C and BASIC. They show different interfaces that can be used as well as an example of 'In-Place' editing.
Don't forget to let us know what applications you are writing to comply with the standard. Clares may be interested in publishing any PCA applications that you write so please send us a copy if this appeals to you.
Click below to download the example applications and a copy of this document. The files are compressed with Spark. Use either SparkFS or the PD SparkPlug to decompress the files.