Hipe : HTML Interface Pipe
How Hipe Works  |  Installation  |  Running hiped  |  Hipe API

The Hipe API
Including libhipe
libhipe functions
C++ extensions
Multithreading considerations
Hipe instructions
Interprocess communication
Tags, attributes and styles
Locations
HIPE_OP_ADD_FONT
HIPE_OP_ADD_STYLE_RULE
HIPE_OP_ADD_STYLE_RULE_SRC
HIPE_OP_APPEND_TAG
HIPE_OP_APPEND_TEXT
HIPE_OP_ATTRIBUTE_RETURN
HIPE_OP_AUDIOVIDEO_STATE
HIPE_OP_CANVAS_ACTION
HIPE_OP_CANVAS_QUERY
HIPE_OP_CANVAS_QUERY_RETURN
HIPE_OP_CANVAS_SET_PROPERTY
HIPE_OP_CARAT_POSITION
HIPE_OP_CLEAR
HIPE_OP_CONTAINER_GRANT
HIPE_OP_CONTENT_RETURN
HIPE_OP_DELETE
HIPE_OP_DIALOG
HIPE_OP_DIALOG_INPUT
HIPE_OP_DIALOG_RETURN
HIPE_OP_EDIT_ACTION
HIPE_OP_EDIT_CONTEXT_REQUEST
HIPE_OP_EDIT_STATUS
HIPE_OP_EVENT
HIPE_OP_EVENT_CANCEL
HIPE_OP_EVENT_REQUEST
HIPE_OP_FIFO_ADD_ABILITY
HIPE_OP_FIFO_CLOSE
HIPE_OP_FIFO_DROP_PEER
HIPE_OP_FIFO_GET_PEER
HIPE_OP_FIFO_INFO
HIPE_OP_FIFO_OPEN
HIPE_OP_FIFO_REMOVE_ABILITY
HIPE_OP_FIFO_RESPONSE
HIPE_OP_FILE_RETURN
HIPE_OP_FIND_RESULT
HIPE_OP_FIND_TEXT
HIPE_OP_FRAME_CLOSE
HIPE_OP_FRAME_EVENT
HIPE_OP_FREE_LOCATION
HIPE_OP_GEOMETRY_RETURN
HIPE_OP_GET_ATTRIBUTE
HIPE_OP_GET_AUDIOVIDEO_STATE
HIPE_OP_GET_BY_ID
HIPE_OP_GET_CARAT_POSITION
HIPE_OP_GET_CONTENT
HIPE_OP_GET_FIRST_CHILD
HIPE_OP_GET_FRAME_KEY
HIPE_OP_GET_GEOMETRY
HIPE_OP_GET_LAST_CHILD
HIPE_OP_GET_NEXT_SIBLING
HIPE_OP_GET_PREV_SIBLING
HIPE_OP_GET_RANGE_GEOMETRY
HIPE_OP_GET_SCROLL_GEOMETRY
HIPE_OP_GET_SELECTION
HIPE_OP_GET_STYLE
HIPE_OP_INSERT_TAG
HIPE_OP_GET_X11_XID
HIPE_OP_INSERT_TAG
HIPE_OP_KEY_RETURN
HIPE_OP_LOCATION_RETURN
HIPE_OP_MEASURE_TEXT
HIPE_OP_MESSAGE
HIPE_OP_OPEN_LINK
HIPE_OP_RANGE_GEOMETRY
HIPE_OP_REMOVE_ATTRIBUTE
HIPE_OP_REQUEST_CONTAINER
HIPE_OP_SCROLL_BY
HIPE_OP_SCROLL_TO
HIPE_OP_SERVER_DENIED
HIPE_OP_SERVER_NOTICE
HIPE_OP_SET_ATTRIBUTE
HIPE_OP_SET_CURSOR
HIPE_OP_SET_FOCUS
HIPE_OP_SET_ICON
HIPE_OP_SET_SRC
HIPE_OP_SET_STYLE
HIPE_OP_SET_STYLE_SRC
HIPE_OP_SET_TEXT
HIPE_OP_SET_TITLE
HIPE_OP_SRC_RETURN
HIPE_OP_STYLE_RETURN
HIPE_OP_TAKE_SNAPSHOT
HIPE_OP_TEXT_METRICS
HIPE_OP_TOGGLE_CLASS
HIPE_OP_USE_CANVAS
HIPE_OP_X11_XID_RETURN

Instruction set reference

HIPE_OP_FIFO_OPEN

In a client-host relationship between two applications, the client sends this instruction to the framing manager to coordinate opening a FIFO resource which has previously been granted to it through a HIPE_OP_FIFO_RESPONSE instruction. A framing manager that supports FIFO-based communication among applications is then required to relay the instruction to and from the host application.

When the host receives this instruction, it is required to open the FIFO resource at its end in the complementary direction of transfer, and relay the same HIPE_OP_FIFO_OPEN instruction back to the client to acknowledge that the resource is now likely to be open at both ends and ready to be used. The FIFO resource ID string (FIFO path) is used to uniquely identify the FIFO resource on the system, and the framing manager should use this to identify where to relay the acknowledgement back to when the host retransmits it.

This does not mean establishing a shared resource (done through HIPE_OP_FIFO_GET_PEER), but beginning a transfer in a particular direction. The same resource may be opened or closed multiple times in the lifetime of a FIFO resource.

Synchronising opening a FIFO resource at both ends of transfer

A FIFO is a special file in a UNIX-style environment that does not buffer any data on the disk. One end is written to (in one application) while the other end is read from (in another application). In the Linux programming environment, the C open() and close() function are normally used to tell the operating system to open a FIFO resource. Often a Hipe application would open a FIFO in 'nonblocking' mode which means an application will not freeze up if the other end of the transfer is too slow to process data or open the resource. However this means that the application that is going to read from the FIFO must open its end of the FIFO first before the other end begins writing. If the reader has not opened the FIFO yet, any data written into the FIFO will have nowhere to go and will be discarded by the operating system. So to avoid data loss, both applications must cooperate to ensure the reading end is opened first.

  1. The FIFO resource should initially be in a closed state at both ends. (If in an open state, the HIPE_OP_FIFO_CLOSE instruction is used to coordinate closing both ends.
  2. The client opens its end of the FIFO resource for either reading or writing depending on the mode being used, but does not actually begin reading or writing yet.
  3. The client should then send a HIPE_OP_FIFO_OPEN instruction to location 0 (which then goes to the parent frame/framing manager to be relayed to the host application that it shares the FIFO resource with)
  4. The host application receives the HIPE_OP_FIFO_OPEN instruction and opens the FIFO at its end in the opposite direction to the mode requested by the client (e.g. if the client is reading, the host opens the FIFO for writing).
  5. At this point the host updates its internal status and may begin reading/writing operations on the FIFO.
  6. The host application sends the HIPE_OP_FIFO_OPEN instruction back in the other direction (by sending it to location 0). The arguments should be the same as those it received except that the file position should be updated as necessary to reflect the actual position in the file represented by the host (e.g. if the file is opened in append mode, the host should send back the position of the existing end of the file). The designated host application is always required to relay this instruction back regardless of the access mode. The framing manager relays it back to the client.
  7. The client receives the HIPE_OP_FIFO_OPEN instruction, and begins reading/writing at its end.
  8. At this point the client updates its internal status and may begin reading/writing operations on the FIFO.

If the host cannot open the resource as asked (for example the file no longer exists, or it has no permission), it does not relay the HIPE_OP_FIFO_OPEN back. It sends a HIPE_OP_FIFO_CLOSE for the resource with the reason in arg[1]. So a client waiting for the HIPE_OP_FIFO_OPEN to come back must also accept a HIPE_OP_FIFO_CLOSE (or a HIPE_OP_FIFO_DROP_PEER) for that resource: either means no transfer was opened, and the client should close its end. See HIPE_OP_FIFO_CLOSE for how the end of a transfer, and its success or failure, is reported.

Access mode

The access mode should be a single specifier from those that were granted to the client when the HIPE_OP_FIFO_RESPONSE instruction was relayed to the client. For example, if "w" access (write mode) was not granted, then "w" should not be specified. The access mode tells the host what it should now do.

FIFO access modes

The following specifiers can be used to control how data is read or written to the FIFO stream. The direction of transfer is specified from the client's point of view.

Typically, a host should not be expected to implement all of these access modes. For example, it might not be appropriate to save a document to a scanner or to load a file from a printer, but reading a scanned page from a scanner and sending it to a printer is more reasonable. Likewise, for some sources of data, it is only sensible (or technically feasible) to transfer the data sequentially from beginning to end, while a database system might allow random access from any position within a file.

SpecifierDescription
rRead sequentially from the beginning of the data. Data to be read should already exist at the host.
RRead data from a specified position, rather than from the start of the file. Data to be read should already exist at the host.
wWrite new data sequentially from the beginning, discarding all existing data held by the host.
WWrite data from a specified position, overwriting a section of existing data held by the host.
aWrite data by appending it to the end of the existing data held by the host. Existing data is preserved. If there is no pre-existing data in the resource, data will be written from the beginning.
nMake a new, empty directory inside a directory resource. No data is transferred.
mMove or rename an entry inside a directory resource. Fails if something already has the new name. No data is transferred.
MAs m, but if a file already has the new name, it is replaced. No data is transferred.
dDelete an entry inside a directory resource: a file, or an empty directory. No data is transferred.
sSwap roles: the host becomes the client for the rest of the relationship, and the client the host. Used once, before any transfer. No data is transferred.

Notes on access modes

Starting position/transfer length

For modes r,w,a, the starting position is implied and the total length is never specified when opening the transfer. arg[2] is not used in these modes. If the client is reading, the host writes the whole contents down the FIFO pipe until the end of the file or close of transfer. If the client is writing (or appending), it writes as much as it needs to and then closes the transfer.

For modes R and W, the client is able to specify a starting position within the file for the host to seek to. If it is reading, it is also useful to specify a maximum number of characters required so that the host does not write everything to the end of the file if the client only requires a fixed number of characters (e.g. a customer record in a database).

For these modes arg[2] is specified as a starting position, optionally followed by a comma and a length in bytes, without spaces. A negative starting position means a distance from the end of the file, such that -1 in W mode is equivalent to a. A specified length of 0 is equivalent to omitting the length.

Directories

If the filename of the shared resource has a trailing slash /, this means the resource is treated as a directory, and filenames within the directory can be specified in arg[3] regardless of the access mode used. If no filename is specified here, the client can access the directory itself, which shall be formatted as follows:

[iso date] [iso date] [size] [accessmodes] [filename]\n

Note that for filenames within a directory, the filename extension should be included if present (e.g. a_photograph.jpg) since for clients that are capable of dealing with directories, Hipe does not filter client abilities by file type within a directory, only the type of the main directory itself.

Representing files within subdirectories

Many real-world directories also contain files within subdirectories. These should also be included in the same flat list (Hipe's FIFO interface treats all files within the base directory on the same footing regardless of how deep they are in a subdirectory hierarchy) however the subdirectory structure is preserved within the filename of each entry as follows.

Subject to what is sensible for each implementation, subdirectories are normally represented as separate items in the list regardless of whether they are empty or contain files. The presence of a trailing slash at the end of the filename indicates that the entry is a subdirectory. The size value given to a subdirectory is undefined and is not used, since there is no data to be read or transmitted through the FIFO from the subdirectory itself.

Changing the contents of a directory

Four access modes change what a directory resource contains, without transferring any data: n makes a new directory, m and M move or rename an entry, and d deletes one. A client may use only those the host granted it.

These work differently from a transfer. Neither application opens the FIFO. The client sends HIPE_OP_FIFO_OPEN and the host carries out the operation at once. The host does not relay the HIPE_OP_FIFO_OPEN back: it answers with a HIPE_OP_FIFO_CLOSE for the resource, whose arg[1] is empty if the operation was done, or says why it was not (see HIPE_OP_FIFO_CLOSE). The client sends no HIPE_OP_FIFO_CLOSE of its own. As with a transfer, the client must wait for the answer before opening the resource again.

Modearg[3]arg[2]What the host doesIt fails if
nThe directory to make, e.g. img/thumbs/Not usedMakes one new, empty directory.The directory it would be made in doesn't exist, or something already has that name.
mAn existing entry, e.g. notes.txtIts new name, e.g. old/notes-2019.txtGives the entry the new name, which may place it in a different directory of the resource. A directory keeps its contents.The entry doesn't exist, the directory the new name is in doesn't exist, or something already has the new name.
MAs for mAs for mAs m, except that a file which already has the new name is replaced, in a single step: the new name refers to the old file's contents until it refers to the moved entry's, and is never missing.As for m, except that a file with the new name is not a failure. It still fails if a directory has the new name, or if the entry being moved is a directory and a file has the new name.
dThe entry to deleteNot usedDeletes a file, or a directory that has nothing in it.The entry doesn't exist, or it is a directory that still has entries in it.

Names are written as they appear in the directory's list: relative to the directory resource, and with a trailing slash for a directory (for m and M, in both the old and the new name).

m is the mode for renaming at the user's request: because it never replaces anything, a client can ask the user before anything is lost. M lets a client save a file safely, by writing the new contents under a temporary name and then moving that over the original.

A host may include m, M and d in an entry's access modes in the directory's list to show that the entry may be moved or deleted, and n in a directory's access modes to show that directories may be made in it. The client should be prepared for the host to refuse all the same.

The directory's list is not updated for the client. After a change, the client reads the list again if it needs the new contents.

What deleting means is up to the host. For example, a file manager might move the entry to a wastebasket of its own. In all cases the entry is no longer in the directory resource afterwards. A host should also refuse names that would reach outside the directory it is sharing.

Swapping roles

Only the client can start a transfer. When the application that asked for the resource should instead serve it (for example, a file manager that hands a file to an editor, which then saves its changes back), the two applications can swap roles once:

  1. The client lists s in the full set of access modes in its HIPE_OP_FIFO_GET_PEER, e.g. "w ws".
  2. A host that can act as the client grants s in its HIPE_OP_FIFO_RESPONSE. A host that doesn't grant it stays the host.
  3. The client sends HIPE_OP_FIFO_OPEN with mode s before any transfer. arg[2] holds the access modes the new client may use, from its own point of view, as they would be granted in a HIPE_OP_FIFO_RESPONSE: for example "rw", "r" for a file that may only be read, or "rwnmd" for a directory. arg[3] is not used.
  4. Neither application opens the FIFO. The host does not relay the HIPE_OP_FIFO_OPEN back: it answers with a HIPE_OP_FIFO_CLOSE, with arg[1] empty if it accepts the swap, otherwise the reason. The client sends no HIPE_OP_FIFO_CLOSE of its own.
AnswerAfterwards
AcceptedThe former host is the client: only it sends HIPE_OP_FIFO_OPEN to start a transfer, using the modes it was given in arg[2]. The former client serves each one exactly as a host does, relaying it back or refusing it with a HIPE_OP_FIFO_CLOSE.
RefusedThe roles stay as they were. The client may still use the modes it was granted, for example to write the data with w.

A host that the user carries on working in, such as an editor or a viewer, should grant s whenever the client offers it, even if it will only read the data once: the framing manager then leaves it in front (see HIPE_OP_FIFO_RESPONSE). A viewer, for example, swaps, reads the resource with r, and drops the relationship when the user closes the document.

Notes

Hipe is just the messenger here. It does not open anything, but merely relays the request to the client. The access mode and arguments tell the FIFO-host what to do with the shared resource. Both host and client should then open and access the resource using regular file read/write operations.

This instruction works in the same way as HIPE_OP_MESSAGE in that the instruction contents are passed to a child or parent frame without interpretation of the contents by the Hipe display server. This means that applications are required to supply and/or read the specified arguments in order to understand one another, but the Hipe display server is not itself involved in interpreting them.