Hipe manual

How Hipe Works

How Hipe Works

There are two sides to a Hipe session. On the server side is the Hipe display server (hiped), a single process that serves every Hipe application in the session.

On the client side are applications such as file managers, text editors, media players and calculators. They are called clients because they use the services of the display server. hiped gives each client its own frame, and a client can display content only within its own frame. Any number of clients can share one display server.

A framing manager is a client whose job is to arrange other clients' frames on the screen, much as a window manager does in other systems. It is an ordinary Hipe application, so it can look and behave however its author likes. Framing managers can be nested: a suite of related applications can be given its own environment, or untrusted applications can be kept together in a sandbox of their own.

Clients communicate with hiped by exchanging instructions over a local socket. For example, a client sends an instruction to change the contents of a tag, and receives an event instruction when the user clicks it.

Where Hipe fits

Connecting to hiped

To connect, a client needs two things: the location of hiped's socket, which by default is in the user's runtime directory, and a host key, a string that proves the client is allowed a frame at a particular place.

A framing manager obtains a key for each frame it creates and hands it to the application it hosts there, typically through the HIPE_HOSTKEY environment variable when it launches it. For top-level frames, hiped keeps a key-file, which it rewrites with a fresh key every time one is used. The client library looks in both places by default.

Keys can't be reused, and access to the key-file can be restricted. A system can therefore place the key-file where only its own framing manager can read it, so that the framing manager holds the only top-level frame and every other application runs inside it.

Implementation stack

The Hipe display server is a Qt application built on hipecore, a display engine derived from WebKit. Hipe applications only ever talk to hiped; they don't use X11, Wayland or any other display system themselves. hiped draws through Qt, so it runs wherever Qt does: in an X11 or Wayland session, or directly on the graphics hardware through EGLFS (a build option of hipecore).

You can think of Hipe as a 'high level' display server. It does rendering, layout and frame management, and leaves hardware, input devices and drivers to the platform beneath it.

There are two ways to run Hipe:

See Running hiped for the options.

Installation

Installing Hipe

Hipe is built from source, in this order:

  1. Install the dependencies.
  2. Build and install hipecore, the display engine.
  3. Build and install hiped, the display server.
  4. Configure hiped to start automatically.
  5. Build and install the client library, libhipe, and the sample applications. Running Hipe applications doesn't need the library; building them does.

The instructions assume you have the Hipe source in a directory named hipe (see Download), and start each step from that directory. A $ prompt means a command run as a normal user, and # one run as root (for example with sudo). Don't type the prompt itself.


Install the dependencies

You need the development files for Qt 5.15. Earlier Qt 5 releases are not supported, and Qt 6 is not supported yet. To use Hipe within a desktop, you also need an X11 or Wayland session.

You don't need your distribution's QtWebKit packages (such as libqt5webkit5-dev): hipecore, built in the next step, takes their place.

Build and install hipecore

hipecore is Hipe's display engine: a leaner, modified WebKit engine purpose-built for Hipe. The display server requires it.

$ cd hipecore
$ mkdir build && cd build
$ cmake -G Ninja -DPORT=Qt -DCMAKE_BUILD_TYPE=Release ..
$ ninja
# ninja install

hipecore has its own build dependencies: CMake, Ninja, a C++17 compiler, the Qt 5 development packages and a handful of image, XML and multimedia libraries. hipecore/README.md lists them for Debian-based systems; elsewhere, if the cmake step fails, its output says which package is missing.

This installs the libraries libHipeCore and libHipeCoreWidgets, and their headers in /usr/include/HipeCore.

This is a large build. On a machine with little memory, limit the number of parallel jobs, e.g. ninja -j2.

Build and install hiped

The display server needs the Qt 5.15 development files, including the Qt SVG module. On a Debian-based system:

# apt install qtbase5-dev libqt5svg5-dev

Then build it:

$ cd server
$ qmake -makefile ./src/hiped.pro
$ make

If a Qt module is missing, qmake stops with a message such as Unknown module(s) in QT: svg. On a system that also has another version of Qt installed, qmake may belong to that version (check with qmake --version); use qmake -qt=5 or qmake-qt5 in its place.

This produces the hiped executable in server/. It can be run from there, but it is usually installed for all users:

# cp hiped /usr/local/bin/

Configure hiped

Within an existing desktop environment

Start hiped when the user logs in to their desktop, for example by adding this line to the session's startup script (such as .xprofile) or to the desktop's autostart settings:

$ hiped &

hiped uses very little CPU or memory until an application connects.

As the entire desktop

Where Hipe is the whole desktop, on a workstation or an embedded device, start a bare X11 session (with no window manager or desktop environment) and run hiped with --fill, which makes top-level applications fill the screen. hiped can also run directly on the graphics hardware through EGLFS, if hipecore is built for it.

$ hiped --fill &

The server/start_hipe_standalone_x11 script, run from a text console, shows one way to do this. The first top-level application is normally a framing manager that hosts the others; the hipe-quadrant sample is a very simple one.

See Running hiped for the other options, including choosing Qt's graphics platform and giving applications keys to frames inside your framing manager, or run hiped --help.


Build and install the client library and samples

$ cd api
$ make
# make install
$ make testing

make builds libhipe, and make install installs it, with its headers, in /usr/local/lib/ and /usr/local/include/; edit the paths in the Makefile to install it elsewhere. make testing then builds the sample applications in api/test/ against the installed library.

Try it

Start the display server if it isn't already running. From your desktop environment, run it in the background:

$ hiped &

Nothing appears yet: hiped shows nothing until an application connects. Now run one of the test applications from the same terminal:

$ api/test/hipe-clock

A window with a digital clock should open. The application found the display server by itself, through the socket and key files that hiped creates (see Running hiped). Other test applications worth trying are hipe-calc (a calculator), hipe-slider (range sliders) and hipe-canvas (a small paint program). Their source code, in api/test/, is the quickest way to see how a Hipe application is written, and may be copied freely into your own.

Running hiped

Running hiped

hiped is the Hipe display server. Hipe applications need it to be running, and need to be able to find the files it creates.

Where to run it

hiped is a Qt application, and runs on any of Qt's display platforms that hipecore is built for.

Choosing the platform

Qt picks a platform automatically. To choose one, set QT_QPA_PLATFORM when starting hiped:

CommandRuns on
QT_QPA_PLATFORM=xcb hipedX11. On a Wayland desktop this runs through XWayland, which applications need in order to embed X11 windows (HIPE_OP_GET_X11_XID).
QT_QPA_PLATFORM=wayland hipedWayland.
QT_QPA_PLATFORM=eglfs hiped --fillEGLFS, with no display server.

hiped doesn't accept Qt's -platform command line option; use the environment variable.

Socket file and host key

hiped creates two files when it starts:

By default both files go in the first of these directories that applies:

  1. /run/, if hiped is run by the root user.
  2. $XDG_RUNTIME_DIR, if set. This is usually a directory under /run/user/ belonging to the current user.
  3. /tmp/.

Applications look in the same place, so on most systems they find hiped with no configuration. To put either file elsewhere, for example so that only trusted applications can read the host key, start hiped with:

hiped [--socket ⟨file path⟩] [--keyfile ⟨file path⟩]

and set HIPE_SOCKET and HIPE_KEYFILE to the same paths in the applications' environment.

Applications don't have to be started from the same terminal as hiped: any application that can find these files can be given a frame.

Giving keys to applications in your own desktop

When your own framing manager runs the desktop, ordinary applications shouldn't create top-level frames. Put the top-level key-file where only the framing manager can read it, and give applications keys to frames inside it instead, in one of two ways:

  1. Through a key-file of its own. The framing manager keeps its own key-file, writing a new key each time one is claimed, and HIPE_KEYFILE points applications at it.
  2. When it launches them. The framing manager starts applications itself and sets HIPE_HOSTKEY to a fresh key for each one. No key-file is needed, and it can treat particular applications differently, but applications can then only be started by the framing manager.

The sample framing manager, hipe-quadrant, does neither: it shows each new key on screen and in its terminal, to be given to applications by hand.

Command line options

OptionEffect
--fillTop-level frames fill the entire screen. Use it when there's no window manager.
--css ⟨paths⟩Default stylesheets for all applications (see below).
--socket ⟨file path⟩Create the socket at this path.
--keyfile ⟨file path⟩Create the top-level key-file at this path.
--cursorDraw a mouse cursor, on systems where no regular cursor is available.
--openglForce OpenGL rendering.
--random ⟨file path⟩Generate keys from this random device, e.g. /dev/random.
--silentPrint only critical errors.
--helpList the options.

Stylesheets and themes

--css takes one or more CSS files, separated by colons, which are read when hiped starts and applied to every application as default style rules. Use full paths rather than ~, which the shell might not expand when several files are listed.

Applications use the first stylesheet (index 1) by default. Setting HIPE_THEME in an application's environment selects another one by its index, counting from 1, or 0 for no default stylesheet.

Hipe API

The Hipe API

The Hipe API

Hipe applications use libhipe, a small C library that connects to the display server and exchanges instructions with it. It is statically linked, so an application built with it needs nothing at run time except a running hiped. C++ programs can also use an object-style interface to sessions and locations.

The instruction set is deliberately low-level: each instruction does one thing to one element, such as creating a tag, setting its text or style, or asking for its events. It is Hipe's assembly language. An application using it directly has complete control of its interface, and higher-level toolkits can be built on top of it.

libhipe isn't the only way in. Instructions travel over a local socket in a simple binary format, so any language that can write to a socket can talk to hiped.

libhipe is under the MIT licence, so it can be used in any application, open source or proprietary, and the sample applications are under 0BSD, so you can copy from them freely. See Licenses.

In this section

Including libhipe Building an application against the library.
libhipe functions Opening a session, and sending and receiving instructions.
C++ extensions The C++ interface.
Multithreading considerationsUsing a session from more than one thread.
Hipe instructions What an instruction contains, and its format on the socket.
Interprocess communicationExchanging messages and data with other applications.
Tags, attributes and stylesWhat HTML and CSS can be used.
Locations How applications refer to elements.

Each instruction (HIPE_OP_...) has its own page, listed alphabetically after these.

Including libhipe

Including libhipe

How to include the Hipe API in your C/C++ program

Assuming the Hipe API is correctly installed on your system, inclusion is simple. Use this compiler directive in your code:

#include <hipe.h>

When building your application, pass the -lhipe argument to your compiler/linker, so that the static library is linked into your program.

libhipe functions

libhipe functions

Functions for creating and destroying a Hipe frame

Each application is granted a single frame when it connects to Hipe. A frame is a rectangular window on the screen through which that application is able to interact with the user. Applications are not normally allowed to create multiple frames, although they can create their own sub-frames for embedding other applications inside.

hipe_open_session()

This function connects to the Hipe display server and requests a frame.

hipe_session hipe_open_session(const char* host_key, const char* socket_path,
                               const char* key_path, const char* client_name)

Returns a value of type hipe_session on success. The return value is a session handle which is required by other hipe functions. On failure, the function returns 0, and an error message is printed to stderr.

hipe_close_session()

This function disconnects from the Hipe server and closes the session. The application's frame is destroyed and server resources associated with it are freed.

short hipe_close_session(hipe_session session)

Returns 0 on success.

Functions for dealing with Hipe instruction structures

libhipe uses data structures of type hipe_instruction for sending and receiving instructions from the display server. The functions for managing these variables all start with the prefix hipe_instruction_.

hipe_instruction_init()

Initialises a hipe_instruction instance by making its internal pointers null, making it safe for use in Hipe API functions.

void hipe_instruction_init(hipe_instruction* obj)

Must be called on any new hipe_instruction instance (excluding shallow copies of an existing instance).

Must also be called on a hipe_instruction object whose values have been populated manually by the user (e.g. by assigning as arguments string pointers that are not owned by the hipe_instruction object itself) and is now going to be re-used by a Hipe API function.

hipe_instruction_clear()

Frees memory allocated within the instruction, and leaves the hipe_instruction structure in a clean state ready for reuse.

void hipe_instruction_clear(hipe_instruction* obj)

Do not use this function to clear a hipe_instruction for which you have allocated values yourself. Instead, de-allocate the argument strings in a way consistent with how you allocated them, then call hipe_instruction_init() to re-initialise the values into a clean state.

hipe_instruction_copy()

Deeply copies values from one hipe_instruction instance to another, allocating memory for storage of values in the destination instance.

void hipe_instruction_copy(hipe_instruction* dest, hipe_instruction* src);

When done with the instruction values in dest, you should free the memory associated with its internal variables using hipe_instruction_clear().

hipe_instruction_alloc()

Allocates memory for each argument of an instruction, according to the lengths already set in its arg_length[] values. Use it when building an instruction by hand whose arguments you will then fill in.

void hipe_instruction_alloc(hipe_instruction* obj)

Arguments allocated in this way should later be freed with hipe_instruction_clear().

hipe_instruction_move()

Moves the contents of one hipe_instruction instance into another without copying the arguments: the memory belonging to src is handed over to dest, and src is left re-initialised.

void hipe_instruction_move(hipe_instruction* dest, hipe_instruction* src);

As with hipe_instruction_copy(), dest should be in a clean state beforehand. The memory now in dest should later be freed in the way that suits how src was filled: with hipe_instruction_clear() if libhipe allocated it.

Functions for sending and receiving Hipe instructions

All interaction with the Hipe display server is done by sending and receiving Hipe instructions.

hipe_next_instruction()

Gets the next instruction from the display server, with an optional blocking wait.

short hipe_next_instruction(hipe_session session, hipe_instruction* instruction_ret,
                            short blocking)

Returns 1 if an instruction has been received, 0 if no instruction is available at the present moment and blocking was not requested, or -1 if disconnection from the server has occurred.

Always check for a return value of -1 (or an instruction_ret->opcode of HIPE_OP_SERVER_DENIED) in your event loop, and exit (or otherwise stop calling hipe_next_instruction()) when it occurs. Once a session is disconnected, a blocking call can no longer block on anything, so an application that keeps calling hipe_next_instruction() in a tight loop without checking for disconnection will spin continuously instead of exiting cleanly when the display server goes away.

hipe_await_instruction()

A variation of the hipe_next_instruction function that waits for a specific type of instruction. There is a blocking wait until an instruction with the specified opcode arrives. When this happens, that instruction will jump the queue and be returned first.

short hipe_await_instruction(hipe_session session, hipe_instruction* instruction_ret,
                             short opcode)

Returns 1 if an instruction of type opcode has been received or -1 if disconnection from the server has occurred.

Instructions that have already been received and are waiting in the queue are checked first, oldest first, so a reply that arrived while you were awaiting something else is still found. Any other instructions that arrive during the wait are added to the queue, to be retrieved later with hipe_next_instruction().

This function should only be used when you have sent the server a request that is guaranteed a response. Otherwise your application will hang waiting for an instruction that never arrives. That includes the case where the response has already been taken out of the queue by a call to hipe_next_instruction(): once retrieved, it is no longer there to be found.

hipe_session_fd()

Returns the file descriptor of the session's connection to the display server, so that an application can wait for Hipe instructions and its own file descriptors (pipes, FIFOs, sockets) at the same time, using poll(), select() or epoll, instead of checking each one on a timer.

int hipe_session_fd(hipe_session session)

Returns the file descriptor, or -1 if there is no connection to the display server.

Only wait on this file descriptor for readability. Never read from or write to it directly: use hipe_next_instruction() and the send functions.

Important: libhipe keeps a queue of instructions it has already received. A single read can take in several instructions, and hipe_await_instruction() queues every instruction that isn't the one it's waiting for. Queued instructions are no longer waiting in the connection, so they won't wake poll(). Always empty the queue with non-blocking calls to hipe_next_instruction() before waiting:

for(;;) {
    while(hipe_next_instruction(session, &instruction, 0) > 0)
        handle(&instruction);
    poll(fds, nfds, -1);  /* fds includes hipe_session_fd(session) */
    /* ...handle your own file descriptors... */
}

A readable file descriptor doesn't guarantee that a complete instruction has arrived, so hipe_next_instruction() may still return 0. In that case, just wait again.

hipe_queued_instructions()

Returns the number of instructions that libhipe has received and queued, but that haven't yet been retrieved with hipe_next_instruction().

int hipe_queued_instructions(hipe_session session)

This function doesn't read from the connection, so it doesn't count data the server has sent that hasn't been read yet. It's mainly useful for checking that the queue is empty before waiting on hipe_session_fd(). Like hipe_next_instruction(), it first sends any instructions waiting in the send buffer (see hipe_set_buffered()).

hipe_set_buffered()

Turns send buffering on or off for a session. Buffering is off by default, and each instruction is transmitted as soon as it is sent. With buffering on, sent instructions are collected and transmitted together, which is much more efficient for an application that sends many instructions at once (for example, building a large document or table). The order of instructions is always preserved.

void hipe_set_buffered(hipe_session session, int buffered)

Buffered instructions are transmitted when the buffer fills up (at 64 KiB), when the application waits or checks for instructions from the display server (with hipe_next_instruction(), hipe_await_instruction() or hipe_queued_instructions()), when hipe_flush() is called, when buffering is turned off, and when the session is closed. So a request is always transmitted before the application waits for its reply, and an application that drains hipe_next_instruction() before waiting on hipe_session_fd() (as described above) never needs to flush.

An application that sends instructions and then waits for something else without calling any of those functions (a timer, or one of its own file descriptors) must call hipe_flush() first. Otherwise its last instructions stay in the buffer, and the screen isn't updated, until it next does.

hipe_flush()

Transmits any instructions waiting in the session's send buffer.

int hipe_flush(hipe_session session)

Returns 0 on success, or -1 if there is no connection to the display server (or the connection has failed). It does nothing if buffering is off or nothing is waiting.

hipe_send_instruction()

Transmits an instruction to the display server.

int hipe_send_instruction(hipe_session session, hipe_instruction instruction)

Returns 0 on success or -1 if there is no connection to the display server (or the connection has failed). With send buffering on (see hipe_set_buffered()), the instruction may be held in the buffer and transmitted later.

hipe_send()

A convenience function for transmitting a simple instruction to the display server without having to create a hipe_instruction instance first.

int hipe_send(hipe_session session, char opcode, uint64_t requestor, hipe_loc location,
              int n_args[, const char* arg, ...])

This function calls hipe_send_instruction internally and returns the return value from that call.

hipe_newest_location()

Retrieves the location value of the most recently created tag.

hipe_loc hipe_newest_location()

Returns the location that was given to the tag created by this thread's most recent HIPE_OP_APPEND_TAG or HIPE_OP_INSERT_TAG, in whichever session. Read it straight after sending. Reserving locations doesn't change it. See "Locations".

hipe_reserve_location(), hipe_reserve_locations()

Reserve location numbers for elements you will create with markup (hipe-loc="N", text mode 3). Nothing is sent to the display server.

hipe_loc hipe_reserve_location(hipe_session session)
hipe_loc hipe_reserve_locations(hipe_session session, size_t count)

hipe_reserve_locations() reserves count consecutive numbers and returns the first. A reserved number you don't use must be freed with HIPE_OP_FREE_LOCATION, like any other.

hipe_send_markup()

Sends markup (text mode 3) together with the list of locations it uses.

int hipe_send_markup(hipe_session session, hipe_loc where, const char* markup, int append,
                     const hipe_loc* reserved, size_t count)

Replaces the contents of where (append == 0, HIPE_OP_SET_TEXT) or appends to them (HIPE_OP_APPEND_TEXT). reserved lists the count numbers used in the markup's hipe-loc attributes; consecutive numbers are sent as ranges. Returns as hipe_send().

hipe_last_error()

const char* hipe_last_error(hipe_session session)

The display server's reason for disconnecting session (for example "location 57 already in use"), or "". With session == 0: the reason the last hipe_open_session() was refused, or "". Lets an application tell its user why it lost its frame.

C++ extensions

C++ extensions for Hipe

While Hipe is primarily intended as a library for C, Hipe comes with an additional C++ header intended for C++ developers who prefer to deal with Hipe sessions and locations as C++ objects.

You still need to include and use the normal Hipe API for many tasks, but the C++ header adds a convenient alternative interface for dealing with locations. Instead of dealing with hipe_loc variables, Hipe provides the hipe::loc C++ class.

Including it in your program

For C++ developers, the name of the header file to include is slightly different. Use the following include statement at the top of each relevant code file:

#include <hipe>

and compile using the -lhipe linker argument as usual.

You now don't need to include the header as it is included automatically within . Therefore the ordinary C-based API function calls remain available, but you now also get access to the hipe:: namespace containing C++ alternative classes.

Classes for C++

Hipe provides two classes. hipe::session creates and manages a connection to the Hipe server, and hipe::loc represents the location of an on-screen document element within your program's user interface, such as a frame or button.

The hipe::session class inherits functionality from hipe::loc and represents the <body> element in your application's user interface.

The hipe::session class

To use the Hipe API in an object-oriented way, create a session object from the C++ hipe::session class, rather than the C hipe_session variable type.

hipe::session::open()

After instantiating a session object, call open() on it to open a connection to hiped.
bool open(const char* host_key, const char* socket_path, const char* key_path,
          const char* client_name);

(with arguments as per the hipe_open_session() C function)

Returns true on success. The session object now represents the open session.

hipe::session::close()

Call this on your session object to disconnect your application from hiped. Your application's user interface, and associated resources, are removed from the display server.

The hipe::loc class

A hipe::loc object represents a reference to a document element managed by your application. Unlike C-based hipe_loc variables, you never need to send Hipe a HIPE_OP_FREE_LOCATION instruction, since hipe::loc objects manage their own reference counts. The C++ API will automatically send an instruction to free the server resource once all hipe::loc objects referring to a particular location are discarded.

You can derive hipe::loc location references from other existing hipe::loc objects. This includes your session object, which inherits all of hipe::loc's public functions, and represents the top-level body element.

You can also create hipe::loc objects from C-style hipe_loc variables (or cast them back again), but hipe::loc instances created in this way are not resource-managed and must not be used for anything except comparison with other hipe::loc objects.

hipe::loc::loc()

The loc class has multiple constructors to choose from, depending on how you need to create your location object.

Default constructor. This constructs a 'null' instance of a loc object with no pre-assigned meaning. It must be defined by assigning it to a location before it is used.

loc()

Copy constructor. This creates a loc object by copying the location reference from another existing loc object. Note that a loc object represents a reference to an element location, not the element itself, so it's perfectly safe to have multiple loc objects referring to the same user interface element.

loc(const loc& orig)

Construct from hipe_loc variable. This constructor defines a hipe::loc object from a C-style hipe_loc variable. Since hipe_loc variables don't have managed reference counts or Hipe session information, the resulting hipe::loc object may only be used as a comparison object (for comparison with another hipe::loc object; to check if it matches a particular document element).

loc(const hipe_loc& location)   //object can be used for comparisons only.

hipe::loc::operator=

Assignment operator. You can assign either from another hipe::loc object, or from a C-style hipe_loc variable type value. If you assign from a hipe_loc variable, the same rule applies as with the constructor described above: the newly defined loc object can only be used for comparison purposes.

loc& operator= (const loc& orig)
loc& operator= (const hipe_loc& location)   //object can be used for comparisons only.

hipe::loc::~loc()

Destructor. Always ensure hipe::loc objects are discarded correctly when you're done with them, but don't discard all hipe::loc objects that point to a location you wish to reference again. When the last hipe::loc object pointing to a particular location (excepting comparison objects as described above) is destroyed, the location handle is automatically freed by the display server (the element itself still exists but can no longer be referenced and instructions such as HIPE_OP_GET_LAST_CHILD will no longer produce a valid location value for that object). Therefore, do not destroy all the hipe::loc objects that refer to a particular location whilst you still have hipe_loc variables (and/or hipe::loc comparison objects) referring to that location in memory, and/or wish to reference that location in future.

hipe::loc::firstChild()

Returns a new hipe::loc object corresponding to the first child tag inside this one.

hipe::loc::lastChild()

Returns a new hipe::loc object corresponding to the last child tag inside this one.

hipe::loc::nextSibling()

Returns a new hipe::loc object corresponding to the tag that follows this one at the same level.

hipe::loc::prevSibling()

Returns a new hipe::loc object corresponding to the tag that precedes this one at the same level.

hipe::loc::send()

Sends a hipe instruction as a method of the location the instruction relates to. This is the O-O equivalent of the hipe_send() function.

int send(char opcode, uint64_t requestor, const std::vector& args)

hipe::loc::appendAndGetTag()

Appends a new tag inside this one, and returns a hipe::loc object corresponding to the new tag.

hipe::loc appendAndGetTag(std::string type, std::string id="")

hipe::loc::insertAndGetTag()

Inserts a new tag before this one, at the same level, and returns a hipe::loc object corresponding to the new tag.

hipe::loc insertAndGetTag(std::string type, std::string id="")

Comparing and converting locations

Two hipe::loc objects can be compared with == and !=, and a hipe::loc can be compared with a C-style hipe_loc value using == (for example, the location of a received instruction). < is provided so that hipe::loc objects can be used as keys in ordered containers such as std::map.

A hipe::loc converts to hipe_loc, so it can be passed to the C functions, and to bool: it is false for a null location (a default-constructed object that hasn't been assigned to) and true otherwise.

Note that firstChild(), lastChild(), nextSibling() and prevSibling() return location 0 when there is no such tag, and location 0 is also the <body> element. The object returned is therefore not null: it converts to true and compares equal to your session object. To find out whether a tag was found, compare the result with the session object, or test whether its hipe_loc value is 0.

More hipe::session functions

A hipe::session converts to the C hipe_session handle, so it can be passed to the C functions (for example hipe_next_instruction(), to receive instructions). It also has these functions, each equivalent to the C function named:

FunctionEquivalent C function
int fd() consthipe_session_fd()
int queuedInstructions() consthipe_queued_instructions()
void setBuffered(bool buffered)hipe_set_buffered()
int flush()hipe_flush()

Multithreading considerations

Multithreading with the Hipe API

How should you use the Hipe API if your application contains multiple threads?

The safest possible approach is to limit interactions with the Hipe API to a single thread, regardless of how many threads you have. Nonetheless a degree of thread safety exists within Hipe.

As of version 1.03, sending a completed instruction to the Hipe display server is an atomic, thread-safe operation. This means that if multiple threads send instructions to the hiped server at the same time, the Hipe API will ensure that the instructions are serialised.

Allocating and reserving locations is thread-safe too, and each session has its own pool of location numbers. hipe_newest_location() returns the location given by the calling thread's own last HIPE_OP_APPEND_TAG or HIPE_OP_INSERT_TAG.

Receiving (and waiting on) instructions is not thread-safe. Only one thread should receive instructions at a time. Otherwise incoming instructions may be decoded in a garbled way. Hipe also has no Earthly way of knowing which instructions are wanted by which thread—the display server sends all instructions to the process via a single linear queue.

Example

One sensible compromise is to use one thread for handling the bulk of graphical interactions with the user, while using another thread to display information that does not require user interaction; sending only instructions that do not generate (or require) a reply from the display server. As long as the second thread doesn't compete with the main thread for being the first to append an element to a particular location, for instance, the desired result is guaranteed each time the program runs.

Hipe instructions

Hipe instructions

Anatomy of an instruction

The hipe_instruction data type produces a C struct with the following member variables:

char     opcode,       /* 8 bits  */
uint64_t requestor,    /* 64 bits */
hipe_loc location,     /* 64 bits */
uint64_t arg_length[4],/* 64 bits per length value */
char*    arg[4]        /* size of each element as specified in arg_length[] */

opcode identifies the nature of the instruction request. You should fill this field using only the predefined macro constants provided by the Hipe API, which are all prefixed by HIPE_OP_ (the prefix was HIPE_OPCODE_ in older versions).

requestor is a 64-bit unsigned integer which you can use to identify an instruction request in a meaningful way. When the Hipe server receives an instruction from an application that requires a response, it passes back the same requestor value in the response. The value of requestor is not interpreted by Hipe in any way. You can use requestor in any number of ways. For example, when requesting events from a calculator utility, you might request that when the user clicks numerical buttons, the events are identified with a requestor value equal to the numerical value of the button clicked. In a more general case, for example when developing a complete GUI toolkit, you might pass as requestor a pointer to an object that will handle a particular event, or deal with a particular subset of incoming instructions.

location is a 64-bit unsigned integer which serves as a numerical handle corresponding to a particular element in the Document Object Model (i.e. a particular HTML tag). Location 0 refers to the <body> element which encloses all other elements within the application frame.

arg[] elements are character strings carrying a different meaning depending on the opcode of the instruction being passed.

arg_length[] specifies the corresponding length of each arg[] element, excluding any null-termination character at the end of the argument string. (Hipe does not expect arguments to be null-terminated.)

If an argument is unused (or not required in a particular instruction), its corresponding arg_length[] element should be assigned a value of 0, and the arg[] element itself may be assigned a NULL pointer.

Transmission of an instruction

The first 49 bytes of a transmitted Hipe instruction form the 'instruction preamble.' The preamble specifies the opcode, requestor and location (the subject of the instruction), as well as the remaining instruction length. Any arguments are then concatenated to the preamble. The arguments may be of any length (or no length at all, depending on the instruction). The recipient therefore reads the preamble first in order to know how much memory to allocate to storing the rest of the instruction. An instruction must be entirely received at the other end before it can be used.

Interprocess communication

Interprocess communication through Hipe

Like many display servers, Hipe provides some capabilities for sending data from one application to another via the display server itself. While the operating system provides its own capabilities for this, transmitting data through the display server is sometimes useful in its own right: for example, where the user must be involved in selecting target application for data to be exported to (e.g. by selecting the target application from a menu in the desktop environment itself), or where the on-screen relationship between two applications is significant.

Basic message passing

The HIPE_OP_MESSAGE instruction is used to send an arbitrary message to a direct child or parent frame within Hipe.Both applications must have a mutual understanding of what these messages mean, so this technique is most useful in cases where the parent application manages child frames that are directly related to it. For example, a suite of utilities that are all written by the same author and are designed to exchange messages with one another.

FIFOs

A FIFO (or named pipe) is a capability of the operating system where a virtual 'file' is written to by one applicaiton and read from by a different application. The resource looks and behaves like a file on the disk, but no data is actually written to the disk. In certain cases, an actual file on the disk may be used.

Examples include sending a file from a word processor application to a printer application, saving a file to a cloud application by writing to a FIFO that is then read by the cloud access utility, and even simply loading a file by requesting the file's contents from a file manager utility.

Hipe does not create or maintain FIFO resources itself but does provide a set of instructions for allowing applications in Hipe to negotiate setting them up and exchange of data.

A typical interaction might go like this:

  1. An application (the 'host') uses HIPE_OP_FIFO_ADD_ABILITY to tell the framing manager about an ability it offers (such as open, save, print, scan, edit, etc.)
  2. In another application (the 'client'), the user selects an option to import or export data from/to another application, and the application sends a HIPE_OP_FIFO_GET_PEER request to the framing manager with details of the read/write access it requires.
  3. The framing manager prompts the user to select a host application and switches focus to the host to allow the user to select options. The framing manager relays the HIPE_OP_FIFO_GET_PEER instruction to the chosen host application and also inserts the name of the ability the user has selected.
  4. The host sends a HIPE_OP_FIFO_RESPONSE response to inform the client of the resource path, and access permissions that are available.
  5. The client and host exchange HIPE_OP_FIFO_OPEN instructions to coordinate opening the FIFO resource at both ends in the required direction of transfer.
  6. The client sends a HIPE_OP_FIFO_CLOSE instruction when it has finished reading or writing the data required. The host repeats this message back to the client to acknowledge that the resource is now closed at both ends.
  7. The client may re-open the FIFO any number of times (e.g. to save the latest changes to a file while the user is working on it). The host is informed each time, so that the service can be provided at the other end.
  8. When the client is done with the peer connection, it issues a HIPE_OP_FIFO_DROP_PEER instruction to tell the host to discard the FIFO resource.
  9. Before the host terminates, it issues a HIPE_OP_FIFO_REMOVE_ABILITY instruction to indicate that it is no longer offering the FIFO service.

If the host should be the one that starts transfers (for example, a file manager hands a file to an editor, and the editor saves its changes back), the two applications can agree to swap roles once, before the first transfer: the client asks for the s access mode, the host grants it, and the client then sends HIPE_OP_FIFO_OPEN with mode s. From then on the editor is the client and the file manager serves it. The FIFO itself is still created and removed by the application that answered the HIPE_OP_FIFO_GET_PEER. See "Swapping roles" under HIPE_OP_FIFO_OPEN.

Tags, attributes and styles

Tags, attributes and styles

A Hipe application builds its interface from HTML tags, attributes and CSS styles. This page lists what the display server accepts.

Anything that isn't accepted is ignored, without an error. If a tag doesn't appear, or a style has no effect, check it against this page first.

Tags

Any tag can be created.

A tag that is not created still uses up the location that was allocated for it. Instructions sent to that location do nothing, and the location can be freed as usual.

Some tags do nothing useful in a Hipe frame:

TagIn a Hipe frame
scriptNever runs.
styleIts rules apply, but text set with HIPE_OP_SET_TEXT has its quotes escaped. Use HIPE_OP_ADD_STYLE_RULE.
meta link base titleNo effect. The window title is set with HIPE_OP_SET_TITLE.
iframe frameShow only an application given the frame's key (HIPE_OP_GET_FRAME_KEY).

Attributes

Any attribute can be set with HIPE_OP_SET_ATTRIBUTE, removed with HIPE_OP_REMOVE_ATTRIBUTE and read with HIPE_OP_GET_ATTRIBUTE. Some attributes have an instruction of their own that suits them better: see HIPE_OP_SET_ATTRIBUTE.

The attribute hipe-loc is reserved: in markup it gives an element a location, and it never stays in the document. See "Locations".

Styles

Any CSS property and value can be used with HIPE_OP_SET_STYLE, and any selector and properties with HIPE_OP_ADD_STYLE_RULE. HIPE_OP_ADD_STYLE_RULE, HIPE_OP_ADD_STYLE_RULE_SRC and HIPE_OP_ADD_FONT are ignored if their text contains </.

A url() in a style loads only data: URLs; any other address loads nothing. To use an image or a font without encoding it yourself, send its data with HIPE_OP_SET_STYLE_SRC, HIPE_OP_ADD_STYLE_RULE_SRC or HIPE_OP_ADD_FONT.

Standard names

These use their standard CSS names. For the properties, the old -webkit- name still works and sets the same property; the keywords, selectors and functions are recognised by their standard names only.

Standard nameOld name
Propertiesappearance backface-visibility box-decoration-break font-kerning hyphens hyphenate-character initial-letter line-break print-color-adjust ruby-position shape-outside shape-margin shape-image-threshold text-decoration-line text-decoration-style text-decoration-color text-emphasis (and -color, -position, -style) text-orientation text-underline-position user-selectThe same with -webkit- in front
Propertiesmargin-, padding- and border- inline-start, inline-end, block-start, block-end (and the border- ones' -color, -style, -width) -webkit-margin-start, -end, -before, -after and so on
Propertiesinline-size block-size min-inline-size max-inline-size min-block-size max-block-size-webkit-logical-width, -webkit-logical-height, -webkit-min-logical-width and so on
Keywordsmin-content max-content fit-content sticky grab grabbing xxx-large plaintext match-parent isolate-overrideThe same with -webkit- in front (no longer recognised)
Selectors:is() :autofill:matches(), :-webkit-autofill (no longer recognised)
Functionsimage-set() cross-fade()The same with -webkit- in front (no longer recognised)

Other -webkit- names, such as -webkit-text-stroke and the ::-webkit-scrollbar selectors, have no standard equivalent and keep their names.

Text

Text given to the tag instructions, and to HIPE_OP_SET_TEXT and HIPE_OP_APPEND_TEXT in modes 0, 1 and 2, is never treated as HTML. In mode 3 it is HTML, and the tags and attributes in it are created as described on this page. See HIPE_OP_SET_TEXT.

Paragraph breaks

The character U+2029 PARAGRAPH SEPARATOR (UTF-8 E2 80 A9) in text starts a new paragraph. It works in every element, whatever its white-space, and in every text mode. It isn't shown, it stays in the text, and HIPE_OP_GET_CONTENT returns it as sent. Caret offsets count it as one character.

TextShows as
aU+2029ba, a gap, then b on a new line
aU+2029U+2029ba, a gap, an empty line, a gap, then b
U+2029bAn empty first line, a gap, then b
aU+2029 at the enda; nothing is added after the last line
a\nbUnchanged: a line break without a gap in pre, pre-wrap and pre-line, a space otherwise

Two CSS properties set how a paragraph break looks. Both are inherited, so a theme can set them once, on body.

PropertyValuesDefaultEffect
-hipe-paragraph-spacingA number (a multiple of the line height) or a length; not negative0.5The gap below each line that ends with U+2029
-hipe-paragraph-indentA length, or a percentage of the containing block's width; may be negative0The indent of the first line after each U+2029

To indent paragraphs instead of spacing them, set -hipe-paragraph-spacing: 0; -hipe-paragraph-indent: 2em. The first line of an element is indented only by text-indent. Pressing Return in editable text doesn't insert U+2029; insert it with HIPE_OP_EDIT_ACTION "t".

Locations

Locations

A location is a number that names one element of your frame. Instructions act on the element named by their location field. Location 0 is the body element.

Who gives an element its location

Your application does, through libhipe, without asking the display server. Each session has its own pool of numbers. An element gets a location only when you give it one:

How the element is createdHow it gets its location
HIPE_OP_APPEND_TAG, HIPE_OP_INSERT_TAGAutomatically. Read it with hipe_newest_location() straight after sending.
Markup (HIPE_OP_SET_TEXT / HIPE_OP_APPEND_TEXT mode 3)Reserve numbers with hipe_reserve_location() or hipe_reserve_locations(), write hipe-loc="N" on the elements, and list the numbers in arg[2], e.g. with hipe_send_markup().
Anything else: markup elements without hipe-loc, elements the HTML parser adds, elements created by the user's editing or pastingNone. They can't be named in instructions.

Lookups (HIPE_OP_GET_BY_ID, HIPE_OP_GET_FIRST_CHILD, HIPE_OP_GET_LAST_CHILD, HIPE_OP_GET_NEXT_SIBLING, HIPE_OP_GET_PREV_SIBLING) return an element's location, or 0 if it has none. They never give an element a location.

Each element has at most one location and each location names at most one element, so two locations are equal exactly when they name the same element.

Numbering markup

hipe_loc rows = hipe_reserve_locations(session, 3);
hipe_loc list[3] = {rows, rows+1, rows+2};
/* markup: <div hipe-loc="(rows)">...</div><div hipe-loc="(rows+1)">...</div>... */
hipe_send_markup(session, fileList, markup, 0, list, 3);
hipe_send(session, HIPE_OP_EVENT_REQUEST, 0, rows, 1, "click"); /* usable straight away */
CaseResult
A listed number is on an elementThe element gets that location. The hipe-loc attribute is removed.
A listed number is on no element (the HTML parser dropped the element, or the number wasn't used)The location names no element: instructions sent to it do nothing. Free it as usual. The server reports it (see "Errors and notices").
A listed number is on two elementsThe first gets it. Reported.
A hipe-loc number that isn't listedIgnored, and the attribute is removed.
A listed number is already in use, or the list is malformedFatal: your application is disconnected (see "Errors and notices").

hipe-loc never stays in the document. It is removed as markup is inserted, and HIPE_OP_SET_ATTRIBUTE refuses it. So HTML you pass through, such as text a user pasted, can't take over your locations.

A list in arg[2] (and in HIPE_OP_FREE_LOCATION) is comma-separated numbers and ranges, with no spaces: "57", "57,58,93", "1000-1499", "57,1000-1499". Each number may appear once.

Freeing locations

Free a location with HIPE_OP_FREE_LOCATION when you no longer need it. Many at once: arg[0] = "1000-1499". All of a session's locations are freed when it closes.

Locations in removed content stay in use until you free them. Only your application knows which copies of a number it still holds, so a number never becomes free by itself. When HIPE_OP_SET_TEXT replaces an element's contents, or an element is deleted, locations inside it still name the removed elements while anything keeps them (for example the undo history, which may bring them back); instructions sent to them have no visible effect. Once nothing keeps them, they name no element. To re-render a region, free its old locations in one instruction and reserve new ones.

Freeing a location also takes it off its element. If the element comes back into the document later (for example, the user undoes the deletion of a paragraph), it comes back with no location, so it can never be confused with an element you have since given that number.

Locations and events

Limits

LimitValue
Locations in use in one frame4,194,304. Going over is fatal.
Location numbers1 and up, below 263 (the top bit is reserved). libhipe always gives valid numbers.

Errors and notices

KindWhat happens
Fatal: a number already in use, a malformed list, too many locationsThe server sends HIPE_OP_SERVER_DENIED with the reason and disconnects. libhipe prints the reason to stderr, and hipe_last_error() returns it.
Not fatal: a listed number found on no element, or used twiceThe server sends HIPE_OP_SERVER_NOTICE. libhipe prints it to stderr.

HIPE_OP_ADD_FONT

Instruction set reference

HIPE_OP_ADD_FONT

Adds a font to the document for use in subsequent styling, by sending font data to the display server.

Notes

For security reasons, the font data added using HIPE_OP_ADD_FONT is local to the client application. It is inaccessible to other applications running within the Hipe session.

HIPE_OP_ADD_STYLE_RULE

Instruction set reference

HIPE_OP_ADD_STYLE_RULE

Sent by a client application to the display server to specify a CSS style rule.

Notes

The instruction is ignored if the selector or the properties contain </. See "Tags, attributes and styles".

For styling individual elements after you have created them, use the HIPE_OP_SET_STYLE instruction instead.

Some combinations of CSS rules can produce undefined behaviour involving race conditions where application layouts may either render correctly or incorrectly each time the application runs. To avoid this, ensure that multiple layout elements are not defined purely relative to one another, particularly when using tables.

HIPE_OP_ADD_STYLE_RULE_SRC

Instruction set reference

HIPE_OP_ADD_STYLE_RULE_SRC

Sets background image data for a particular CSS style rule specifier.

HIPE_OP_APPEND_TAG

Instruction set reference

HIPE_OP_APPEND_TAG

Appends a new HTML tag element as the last child within the specified tag element.

Notes

The element is created directly, exactly where you ask: nothing is added around it and nothing is left out, so the location always names the element you asked for. Inside an svg or math element it is an SVG or MathML element, as in markup; SVG names may be given in any letter case (lineargradient). A tag whose name isn't a valid element name is not created, and its location is still used up. See "Tags, attributes and styles".

When building a table, append a tbody tag to the table first, and append the tr rows to that. A tr appended straight to a table goes in without a tbody: it displays the same, but style rules such as table > tbody > tr won't match it.

When building up a table (or similar layout-intensive element) by appending td elements to it, keep the table hidden (use the display style property for this purpose) until it is complete. It will display faster overall, since Hipe will not have to keep recalculating and re-rendering the layout as you add your table cells.

Setting the class and text in the same instruction (arg[2] and arg[3]) is much faster than following up with HIPE_OP_TOGGLE_CLASS and HIPE_OP_SET_TEXT, which matters when building many small elements, such as the coloured spans of syntax-highlighted text.

Prior to version 2, Hipe accepted an extra argument in arg[2] where passing "1" would cause the server to reply with a HIPE_OP_LOCATION_RETURN instruction describing the newly appended tag. This was removed in version 2, and arg[2] is now the class list. A more efficient way to obtain the new location is by calling the hipe_newest_location() function (C) or the hipe::loc::appendAndGetTag() method (C++) in the hipe API.

HIPE_OP_APPEND_TEXT

Instruction set reference

HIPE_OP_APPEND_TEXT

Appends a text element as the last child element within the specified tag element.

Text modes

In modes 0, 1 and 2, the characters <, >, " and ' are shown as typed. Text that looks like an HTML tag, such as <b>, is never treated as markup, so there is no need to remove such things from arg[0]. These modes differ in what happens to & and to newlines, carriage returns and tabs. In mode 3, arg[0] is HTML.

Mode&Newlines, carriage returns and tabsText read back with HIPE_OP_GET_CONTENT
"0"Shown as typed.Not converted.The same as arg[0].
"1"Shown as typed.Converted: a newline becomes a line break, a carriage return an empty paragraph, a tab a wide space.Differs from arg[0]: the newlines and carriage returns are now elements, not characters, and each tab is a wide space character.
"2"Starts a character entity: &times; shows as ×, &amp; as &.Not converted.arg[0] with its entities replaced by the characters they stand for.
"3"Starts a character entity, as in mode 2.Not converted.The text of the elements arg[0] created. HIPE_OP_GET_CONTENT mode 1 returns them as HTML.

Mode 3: markup

Where newlines and tabs are not converted (modes 0 and 2), how they look depends on the element. Most elements show any run of spaces, tabs and newlines as a single space, as HTML normally does. An element that keeps whitespace, such as a pre tag or one styled with white-space: pre, shows them as line breaks and tab stops.

Also in modes 0 and 2, a carriage return is stored as a newline, and a carriage return followed by a newline is stored as one newline.

In every mode, the character U+2029 starts a new paragraph, with a gap or an indent set by CSS, in any element. See "Paragraph breaks" on the "Tags, attributes and styles" page.

Which mode to use

HIPE_OP_ATTRIBUTE_RETURN

Instruction set reference

HIPE_OP_ATTRIBUTE_RETURN

This instruction is received by the client (sent by the display server) in response to a HIPE_OP_GET_ATTRIBUTE request. It is the server's way of returning the requested data.

HIPE_OP_AUDIOVIDEO_STATE

Instruction set reference

HIPE_OP_AUDIOVIDEO_STATE

When sent from the client to the server, modifies the playback state of an <audio> or <video> element. When received from the server, this is sent in response to a HIPE_OP_GET_AUDIOVIDEO_STATE request and reflects the current state of the media element.

Notes

When sending this instruction to set the playback state, any argument that isn't being changed may be left empty — only the arguments you provide will be applied.

HIPE_OP_CANVAS_ACTION

Instruction set reference

HIPE_OP_CANVAS_ACTION

Calls a drawing method on the canvas that was selected with HIPE_OP_USE_CANVAS. The methods are those of the HTML Canvas 2D Context.

An unknown method name, the wrong number of parameters, or a parameter that can't be used (such as text where a number is expected) causes the instruction to be ignored. No error is reported.

The methods are those listed below. Most are methods of the HTML Canvas 2D Context; those dealing with ids, and setSrcRegion, are Hipe's own.

Writing the parameters

Methods

MethodArguments
save—
restore—
scalesx, sy
rotateangle (radians)
translatetx, ty
transformm11, m12, m21, m22, dx, dy
setTransformm11, m12, m21, m22, dx, dy
beginPath—
closePath—
moveTox, y
lineTox, y
quadraticCurveTocpx, cpy, x, y
bezierCurveTocp1x, cp1y, cp2x, cp2y, x, y
arcTox0, y0, x1, y1, radius
arcx, y, radius, startAngle, endAngle, anticlockwise ("true"/"false")
ellipsex, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise ("true"/"false")
rectx, y, width, height
fill0 args (implicit path, default winding); 1 arg (implicit path, winding rule "nonzero"/"evenodd"); or 2 args (path id, winding rule)
stroke0 args (implicit path) or 1 arg (path id)
clipsame shape as fill above
clearRectx, y, width, height
fillRectx, y, width, height
strokeRectx, y, width, height
fillTexttext, x, y, optional maxWidth
strokeTexttext, x, y, optional maxWidth
setLineDasha single bracketed list of numbers, e.g. [4,2] ([] clears the dash pattern)
drawImagesource element id, then either (dx, dy), (dx, dy, dw, dh), or (sx, sy, sw, sh, dx, dy, dw, dh) (see Notes)
setSrcRegiondx, dy, width, height (see Notes)
createLinearGradientid, x0, y0, x1, y1
createRadialGradientid, x0, y0, r0, x1, y1, r1
addColorStopgradientId, offset, color
createPatternid, sourceElementId, repetition ("repeat"/"repeat-x"/"repeat-y"/"no-repeat")
deleteGradientgradientId
deletePatternpatternId
createPath2Did
deletePath2Did
selectPath2Did (empty string reselects this canvas's own implicit path)

Gradients, patterns and paths

In HTML a gradient, pattern or path is an object that a script keeps hold of. Here each one is given an id by the client when it is created, and is referred to by that id afterwards. Ids belong to the canvas they were created on: the same id on another canvas is a different object.

Notes

beginPath always starts the canvas's own path afresh, whichever path is selected. To start a new named path, create one under a new id.

drawImage's first parameter is the id attribute of an img, canvas or video element in the document. The rest are numbers, in one of three forms: the destination position (dx, dy); the destination rectangle (dx, dy, dw, dh); or a source rectangle followed by the destination rectangle (sx, sy, sw, sh, dx, dy, dw, dh).

setSrcRegion is not a method of the HTML canvas. It sets the area of the canvas that raw pixels sent with HIPE_OP_SET_SRC will be written to: the top-left position (dx, dy) and the width and height of the pixel data. The area is in canvas pixels and is not affected by scale, translate or the other transformations. It stays in effect until it is set again. If it is never set, raw pixels fill the whole canvas. See HIPE_OP_SET_SRC.

Only the 2D context is available. To read a canvas back as an image, use HIPE_OP_GET_SRC.

HIPE_OP_CANVAS_QUERY

Instruction set reference

HIPE_OP_CANVAS_QUERY

Asks a question of the canvas that was selected with HIPE_OP_USE_CANVAS. It covers the methods of the HTML Canvas 2D Context that return a value. The display server replies with HIPE_OP_CANVAS_QUERY_RETURN.

QueryParametersReply
isPointInPathpathId, x, y, and optionally the winding rule: "nonzero" (the default) or "evenodd"true or false
isPointInStrokepathId, x, ytrue or false
measureTextthe textIts width in pixels, in the canvas's current font

Notes

pathId is always given. It is the id of a path made with createPath2D (see HIPE_OP_CANVAS_ACTION), or empty to test the canvas's own current path, as in ",10,20".

measureText measures in the font set on the canvas with HIPE_OP_CANVAS_SET_PROPERTY. To measure text in the font of an element of the document, use HIPE_OP_MEASURE_TEXT.

HIPE_OP_CANVAS_QUERY_RETURN

Instruction set reference

HIPE_OP_CANVAS_QUERY_RETURN

Sent by the server in response to a HIPE_OP_CANVAS_QUERY request.

HIPE_OP_CANVAS_SET_PROPERTY

Instruction set reference

HIPE_OP_CANVAS_SET_PROPERTY

Sets a property on the canvas context currently selected with HIPE_OP_USE_CANVAS (for example, fillStyle or lineWidth).

Only the property names listed below are recognised. An unrecognised property name, or a value that fails to parse for that property's type, is silently ignored — the server does not report an error back to the client.

Properties

PropertyValue
fillStylea CSS colour string (e.g. red, #ff0000, rgba(0,0,0,0.5)), or url(#id) referencing a gradient/pattern id created via HIPE_OP_CANVAS_ACTION's createLinearGradient/createRadialGradient/createPattern — see that instruction's "Named objects" section
strokeStylesame as fillStyle above
lineWidtha number
lineCapbutt, round, or square
lineJoinround, bevel, or miter
miterLimita number
lineDashOffseta number
shadowOffsetXa number
shadowOffsetYa number
shadowBlura number
shadowColora CSS colour string
globalAlphaa number from 0 to 1
globalCompositeOperationa composite operation name from the HTML Canvas 2D Context specification, e.g. source-over, multiply
fonta CSS font shorthand string, e.g. 16px sans-serif
textAlignstart, end, left, right, or center
textBaselinea baseline name from the HTML Canvas 2D Context specification, e.g. alphabetic, middle
imageSmoothingEnabled"true" or "false"

Note that setLineDash is a method in the Canvas 2D specification, not a property — set it via HIPE_OP_CANVAS_ACTION instead, described on that instruction's reference page.

HIPE_OP_CARAT_POSITION

Instruction set reference

HIPE_OP_CARAT_POSITION

This instruction relates to the current position of the text entry carat (cursor position, or range of selected text) in an input element such as a textarea tag, or in an element with the contenteditable attribute.

The instruction may be sent to the server in order to move the text cursor position or select a range of text. It can also be received from the server in response to a HIPE_OP_GET_CARAT_POSITION instruction, to get the current text entry and/or selection position.

Offsets

Offsets count characters, starting from 0 before the first character. A character is a Unicode code point, which may be several bytes long in UTF-8: an offset is never a byte count.

For input and textarea elements, offsets index the element's value. For other elements, they index the element's text as it is laid out: the same text that HIPE_OP_GET_CONTENT returns in mode 2. In this text, line-break tags such as <br> and the boundaries between block elements (such as consecutive div tags) each count as one line-break character, and runs of spaces that are displayed as a single space count once. Elements styled display:none don't count.

Negative offsets count from the end of the text: -1 is the position after the last character, -2 the position before the last character, and so on. This is useful for placing the cursor at (or near) the end of the text without first having to query its length. For example, arg[0] = "0" and arg[1] = "-1" selects all the text. Offsets beyond the text are clamped to it.

Notes

If arg[0] is empty, the instruction is ignored. HIPE_OP_GET_CARAT_POSITION replies with empty arguments when the element contains neither the cursor nor selected text, so sending back what it returned never moves the selection. Arguments that aren't whole numbers are also ignored.

Setting the carat in an element with the contenteditable attribute also gives that element keyboard focus.

Some positions can't hold a cursor, and the display engine moves the cursor to the nearest one that can. For example, in a contenteditable element whose text ends with a line break, the position after that final line break has no line to appear on, so the cursor is placed before it. Similarly, a character that the user sees as one symbol may be made of several code points (such as some flags, or a letter with a separately encoded accent), and the cursor can't be placed between them.

HIPE_OP_CLEAR

Instruction set reference

HIPE_OP_CLEAR

Clears the contents of the tag at the given location, removing all child elements.

Notes

While the tag content of location is cleared, the tag at location itself, and its attributes, remain.

Clearing location 0 (the body element) clears the frame's contents.

If you need to delete a tag entirely, clear its parent tag, or use HIPE_OP_DELETE.

HIPE_OP_CONTAINER_GRANT

Instruction set reference

HIPE_OP_CONTAINER_GRANT

You never need to deal with this instruction directly. It is sent by the server to the client application to indicate the validity of a new client session. It is received and processed automatically by hipe_open_session() before that function returns.

HIPE_OP_CONTENT_RETURN

Instruction set reference

HIPE_OP_CONTENT_RETURN

Sent back from the server in response to a HIPE_OP_GET_CONTENT request.

Replies to mode 4 requests

A HIPE_OP_GET_CONTENT request in mode 4 asks for the changes to the element's text since the client's previous mode 4 request for that element, rather than the whole text. The reply describes one replacement, to be applied to the text as returned by the previous mode 4 reply:

For example, if the text was hello world and the user typed X after hello, the reply is X, 5, 0, delta: replace 0 characters at position 5 with X. If nothing has changed, the reply is an empty string, 0, 0, delta, which changes nothing when applied.

Characters are Unicode code points, as in HIPE_OP_CARAT_POSITION: count UTF-8 characters, not bytes. The reported change is the smallest one that turns the previous text into the new one. It always produces the right text, but it isn't necessarily where the user typed: in hello, typing another l after the first l may be reported as an insertion after the second one, since both give the same result.

Only mode 4 fills in arg[1] to arg[3], and a mode 4 reply always has delta or full in arg[3]. A reply with an empty arg[3] is therefore never a list of changes.

HIPE_OP_DELETE

Instruction set reference

HIPE_OP_DELETE

Deletes the specified element itself, rather than clearing its contents.

Notes

Use HIPE_OP_CLEAR to clear the contents of an element rather than the element itself.

HIPE_OP_DIALOG

Instruction set reference

HIPE_OP_DIALOG

This instruction is used to request a dialog box prompt to be displayed for collecting user input. If the frame that sends the instruction is a child of another frame (such as a framing manager), the parent frame receives the instruction to act upon. If the frame that requests the dialog is a top-level frame, Hipe itself produces the dialog box.

The dialog box should be implemented modally, which means the user should not be able to continue interacting with the application until the dialog has either been answered or dismissed (cancelled).

Notes

Framing managers without dialog support: As there is no mechanism in Hipe that may be used to determine whether a framing manager implements dialogs or not, a framing manager that does not implement dialog functionality must respond to a HIPE_OP_DIALOG or HIPE_OP_DIALOG_INPUT instruction with a HIPE_OP_DIALOG_RETURN instruction and arguments {"","0"} to indicate that the dialog has been cancelled. Otherwise, client applications that request dialogs may be left in an undefined or suspended state.

The framing manager should send a HIPE_OP_DIALOG_RETURN instruction back to the client once the dialog has been answered by the user.

Modality: The framing manager should display the dialog in a modal way, preventing interaction with the client frame until the dialog is answered. There are at least two ways to implement this: (a) prevent the user interacting with the client until the dialog is dismissed, or (b) that the dialog is dismissed automatically if the user removes focus from the dialog, and a 'cancel' is inferred.

HIPE_OP_DIALOG_INPUT

Instruction set reference

HIPE_OP_DIALOG_INPUT

This instruction provides an alternative form of HIPE_OP_DIALOG that allows freeform text input by the user, rather than a set of fixed choices. Otherwise, this dialog functions similarly to HIPE_OP_DIALOG and the user's response is received back via a HIPE_OP_DIALOG_RETURN instruction.

Notes

Framing managers without dialog support: As there is no mechanism in Hipe that may be used to determine whether a framing manager implements dialogs or not, a framing manager that does not implement dialog functionality must respond to a HIPE_OP_DIALOG or HIPE_OP_DIALOG_INPUT instruction with a HIPE_OP_DIALOG_RETURN instruction and arguments {"","0"} to indicate that the dialog has been cancelled. Otherwise, client applications that request dialogs may be left in an undefined or suspended state.

For providing suggested inputs to the user in arg[2], a possible use case might be to provide the user with the 5 most recently used commands, based on the user's previous inputs.

HIPE_OP_DIALOG_RETURN

Instruction set reference

HIPE_OP_DIALOG_RETURN

This instruction is sent to a client application that has requested a dialog (either using a HIPE_OP_DIALOG or HIPE_OP_DIALOG_INPUT instruction), to allow the client application to receive the user's response to the dialog.

If the client application is running as a top-level frame, Hipe itself handles display of the dialog and sending the user's response back to the client. If the client application is running as a child frame of another application (such as a framing manager), the parent application is expected to handle display of an appropriate dialog box, and to send a HIPE_OP_DIALOG_RETURN instruction back to the client application (by specifying the location of the client frame) in order to communicate the user's response back to the appropriate client.

Notes

Framing managers without dialog support: As there is no mechanism in Hipe that may be used to determine whether a framing manager implements dialogs or not, a framing manager that does not implement dialog functionality must respond to a HIPE_OP_DIALOG or HIPE_OP_DIALOG_INPUT instruction with a HIPE_OP_DIALOG_RETURN instruction and arguments {"","0"} to indicate that the dialog has been cancelled. Otherwise, client applications that request dialogs may be left in an undefined or suspended state.

HIPE_OP_EDIT_ACTION

Instruction set reference

HIPE_OP_EDIT_ACTION

Performs a cut/copy/paste or other edit action on the text the user has selected, or at the text cursor, in the element that has keyboard focus.

Every application inside a top-level window is a frame of the same document hierarchy, so an edit action always applies to the frame that currently has keyboard focus. To stop one application acting on another's content, the rules depend on who sends the instruction:

Action codes

CharacterEditing operation
zUndo
ZRedo
aSelect all
xCut selected text to clipboard
cCopy selected text to clipboard
vPaste selected text from clipboard, matching destination formatting
VPaste selected text from clipboard, preserving source formatting if applicable
bToggles bold if applicable
iToggles italic if applicable
uToggles underline if applicable
kToggles strikethrough if applicable
lAlign left if applicable
CAlign center if applicable
rAlign right if applicable
jAlign justified if applicable
dSet text direction default
>Set text direction left to right
<Set text direction right to left
tInsert the text given in arg[1], or delete the selected text if arg[1] is empty

Notes

This operation will succeed or fail silently. There is no response from the server. Use HIPE_OP_EDIT_STATUS to find out which actions are currently available.

Paste from a non-top-level client. Pasting gives the clipboard's contents to the client that receives them, so a client that isn't top-level may only paste in response to the user: within a few seconds after the user clicked or pressed a key in its frame, or after the framing manager relayed the user's answer to a dialog (HIPE_OP_DIALOG_RETURN) to it or to a frame containing it. In practice, send the paste instruction as soon as you receive the click, key press or dialog answer that asked for it. At other times it is ignored. The user can always paste with the keyboard shortcut, which doesn't use this instruction.

Insert text (t) puts the text in arg[1] at the text cursor, replacing any selected text, as if the user had typed it. Nothing happens unless the text cursor is in editable content (a text input, a <textarea>, or an element with the contenteditable attribute). The text is never treated as HTML: characters such as < and & are shown as typed. Each newline in the text becomes a line break, as when the user presses Enter in plain text (a single-line text input can't hold line breaks, so each newline becomes a space there), and the text cursor is left after the inserted text. The whole insertion is undone by a single undo; as with ordinary typing, that undo also removes anything the user typed immediately before it. A typical use is inserting a tab or indentation when the user presses Tab, after cancelling the key's default action (see HIPE_OP_EVENT_REQUEST).

If arg[1] is empty, t deletes the selected text instead, as the Delete key would, and leaves the text cursor where the selection was. This is one step for undo. If no text is selected (there is only a text cursor), nothing is deleted. To remove a particular range, select it first with HIPE_OP_CARAT_POSITION.

Undo and redo act on the undo history of the focused frame's document. Each frame has its own undo history, so undoing in one application never reverts an edit made in another.

HIPE_OP_EDIT_CONTEXT_REQUEST

Instruction set reference

HIPE_OP_EDIT_CONTEXT_REQUEST

Receiving this instruction on a top-level frame indicates that there has been an unhandled context menu request either in that frame or in a child (or descendent) of that frame.

This normally means the user has right-clicked on a section of text somewhere in the frame hierarchy and expects to see a default menu of clipboard commands such as cut/copy/paste. Further information is not available. However, a framing manager can respond by using a HIPE_OP_EDIT_STATUS instruction to query what commands are suitable for whatever the user has selected, and globally implement a default context menu that way.

This instruction is not generated if a context click event has already been handled by the application (e.g. to produce a more relevant menu at the application level).

HIPE_OP_EDIT_STATUS

Instruction set reference

HIPE_OP_EDIT_STATUS

Used to determine which edit actions are available, i.e. applicable to the currently selected content or focused element. This is useful for creating an 'Edit' menu with unavailable options removed.

The answer describes the frame an edit action would apply to, under the same rules as HIPE_OP_EDIT_ACTION: a top-level client may query any child frame (and if the keyboard focus isn't inside that frame, focus is moved to it, as for an edit action), while any other client gets an answer only while the keyboard focus is inside its own frame or the child frame it names. Otherwise every action is reported as unavailable.

Action codes

CharacterEditing operation
zUndo
ZRedo
aSelect all
xCut selected text to clipboard
cCopy selected text to clipboard
vPaste selected text from clipboard, matching destination formatting
VPaste selected text from clipboard, preserving source formatting if applicable
bToggles bold if applicable
iToggles italic if applicable
uToggles underline if applicable
kToggles strikethrough if applicable
lAlign left if applicable
CAlign center if applicable
rAlign right if applicable
jAlign justified if applicable
dSet text direction default
>Set text direction left to right
<Set text direction right to left
tInsert text, or delete the selected text (available when the text cursor or selection is in editable content)

Notes

The server responds with a HIPE_OP_EDIT_STATUS instruction. Its arg[0] repeats the action codes that were asked about, and its arg[1] holds one status character for each of them, in the same order:

For example, asking about "zxcv" might return "0ee0": undo and paste are available, but cut and copy aren't because no text is selected.

Paste is reported as available whenever there is something to paste into, even for a client that isn't top-level; whether such a client may actually paste also depends on recent user input (see HIPE_OP_EDIT_ACTION).

HIPE_OP_EVENT

Instruction set reference

HIPE_OP_EVENT

Generated by the server and sent to the client when a requested GUI event occurs.

Event details

The detail in arg[1] is a comma-separated list of numbers:

Eventarg[1]
keydown, keyupkeyCode,modifiers
keypresscharCode (the character typed; no modifiers)
clickbutton,modifiers
mousedown, mouseup, mousemove, mouseenter, mouseleave, mouseover, mouseout button,pageX,pageY,offsetX,offsetY,modifiers
dblclick, contextmenu button,pageX,pageY,offsetX,offsetY,modifiers
wheel deltaX,deltaY,deltaMode,modifiers (deltaMode: 0 = pixels, 1 = lines, 2 = pages)
Other events0

button is 1 for the left mouse button, 2 for the middle and 3 for the right.

modifiers is always present, and is 0 when no modifier keys are held. Otherwise it's the sum of: 1 = Shift, 2 = Alt, 4 = Ctrl, 8 = Meta. For example, Ctrl+S gives a keydown detail of 83,4, and Shift+Tab gives 9,1. On the keyup of a modifier key itself, that modifier is already released, so it isn't included.

Notes

Events that can arrive in fast bursts are combined before they are sent, so that a client isn't flooded with them. Each request gets its own combined stream. Such events are sent a few tens of milliseconds after they occur, at most:

The event detail provided in arg[1] may be inadequate for what you require. In this case, it may be necessary to use HIPE_OP_GET_ATTRIBUTE in order to obtain further information about how the tag has changed following the user's interaction.

HIPE_OP_EVENT_CANCEL

Instruction set reference

HIPE_OP_EVENT_CANCEL

Send this instruction to the server to stop receiving events of a certain type on the specified element

Notes

Cancelling removes every active request for that event type on the element, whatever requestor values they were made with. See HIPE_OP_EVENT_REQUEST.

HIPE_OP_EVENT_REQUEST

Instruction set reference

HIPE_OP_EVENT_REQUEST

Send this instruction to the server to request notifications of a particular event on a particular element.

Notes

For specifying the type of event, names of events are the same as their HTML/Javascript equivalents, except without the "on" prefix.

For example, to get reports of click events, you would pass "click" in arg[0] (not "onclick"), or for a key pressed down event you would pass "keydown" (not "onkeydown" as in HTML/Javascript).

Each event is reported with HIPE_OP_EVENT, which lists the detail reported for each event type, including which modifier keys (Shift, Alt, Ctrl, Meta) were held.

keyup and keydown events can be requested on a child iframe: they report keys pressed while the keyboard focus is inside the client occupying that frame (or inside any frame nested within it). The events carry the requestor value of your most recent request for that event on that iframe, and each key is reported once: requesting keydown or keyup again on the same iframe replaces the requestor rather than adding another report. The detail includes the modifier mask as for any other keydown or keyup event. The same keys also reach your body element, so if you have requested keydown or keyup on the body as well, you receive both reports. keypress events remain within the iframe and don't propagate out to the parent client.

mousedown and mouseup events can also be requested on a child iframe: they report every press and release of a mouse button anywhere in that frame, including inside frames nested within it. They tell you where the pointer was, not what it was over. The detail is in your own coordinates, as if the event had happened on the iframe element itself:

DetailValue
buttonAs for any mouse event (1 = left).
pageX, pageYThe pointer's position on your page.
offsetX, offsetYThe same, relative to the iframe element.
modifiersThe modifier mask, as for any mouse event.

As with keys, the events carry the requestor of your most recent request for that event on that iframe, and the child client still receives its own mouse events as usual. A frame that has no content yet reports nothing.

Several requests can be active for the same event on the same element. Each request adds a new listener, and all of them stay active, so each event is reported once per request. This happens even if the requests use the same requestor value. For example, if you request the click event on the same button twice, each click on that button is reported twice.

To replace a request, cancel it with HIPE_OP_EVENT_CANCEL before requesting the event again.

Cancelling default actions

arg[1] can cancel an event's default action: what would happen without your app (a key typing text or moving the focus, the wheel scrolling, a right-click opening the edit menu, and so on). The event is cancelled as it happens, before the default action, so the decision is made from rules given in advance. You still receive the event as usual, and can then do something else instead (e.g. indent a line when Tab is pressed).

arg[1] is a list of rules separated by ;. An event is cancelled if it matches any of them. Each rule is code,modifiers, written like the event's detail in HIPE_OP_EVENT:

* matches anything, and ,modifiers can be left out to match any modifiers. So * alone cancels every event. A rule with a specific code or modifier mask never matches an event that doesn't have one: e.g. wheel events have no code (only * matches), and events such as input or scroll have neither. Rules that can't be read are ignored.

Eventarg[1]Cancels
keydown9,0;9,1Tab and Shift+Tab (the focus doesn't move)
keydown83,4Ctrl+S
keydown9Tab with any modifier keys
wheel*,4Ctrl+wheel (plain wheel still scrolls)
mousedown1left-button presses (no focus change or text selection)
contextmenu-nothing: the edit menu still opens

Notes:

Events and locations

An event request belongs to the element, not its location number: each event is reported with the location the element has when it happens. After HIPE_OP_FREE_LOCATION the element's events are no longer reported. See "Locations".

HIPE_OP_FIFO_ADD_ABILITY

Instruction set reference

HIPE_OP_FIFO_ADD_ABILITY

This instruction is usually sent by a client to its parent frame (the framing manager for the desktop environment) to indicate that the client may be called on to carry out a particular action. This means the client can act as a FIFO host when the user selects the listed ability.

Name of ability

The name of the ability serves two purposes: (1) it is shown to the user to help the user decide which host function to select when exchanging data with another application. (2) it is used to identify the particular ability within Hipe (together with the client ID).

If a client application offers multiple host abilities, each must have a unique name.

The name of the ability is case sensitive.

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

Order of access modes

The order of access mode specifiers is significant: where appropriate, the expected initial access mode should be specified first. For example, "rw" means that data will initially be read, and may be written back to later, while "wr" means that fresh data will be written from the start. An initial access mode of r or R means that the host acts (initially at least) as a source of data rather than a destination.

An example of "read then write" ordering would be a file which is opened for editing. First the editor must read the file to load its contents. Later the user may save changes back into the file.

Metadata about ability

The metadata argument is used to specify what sort of data the host can work with. This information spans multiple lines, separated by a newline character (in C, \n is used to represent a newline character).

LineDescriptionExample
1 Description of ability Get image from scanner
2 Preferred file format pattern pdf:Portable document format
3 Alternative file format pattern (optional) jpg;jpeg;gif:Graphical image
... Additional lines for other file formats as necessary. txt:scan to text

Where multiple file formats are supported, the filename extension normally associated with that format is used. For example, gif means a GIF image format. To prevent ambiguity (in cases where two very different file formats might share a common filename extension), a description is added. The description is not used to identify the file, but is displayed to the user so the user can exclude inappropriate files where prompted to select a file from disk. The client application will probably use a different description for the same file format. Since descriptions are intended for user information only and are subject to be altered in transit, descriptions alone cannot be used to differentiate between different file formats with the same extension. (Therefore each extension should only be listed once in the entire metadata argument).

We use Windows-style file extensions to filter file formats as they are well-understood in practice. Why are MIME types not used? Whilst MIME types were envisaged as a way to remove ambiguity from file format types, they tend to produce less clarity than confusion in reality.

The file type (extension) should be in lowercase, and should not include the *. prefix often used in Windows where the file type follows a dot at the end of each filename. It is worth noting that the host may not organise files with filename extensions, but may use a different scheme.

Some FIFO-hosts can handle any file format. In this case, a single * is specified to indicate a single file of any type. (Note, the * character does not work for matching filename patterns, and should be used by itself only.)

Directory resources

In some cases, the resource is not a single file-style resource, but a directory resource (the client can access multiple files in the directory, which are indexed by filenames). This is useful in cases where a client works on an entire project rather than a single file. To specify that any directory is allowed, use a single forward slash / for the type. To require a directory to have a certain filename extension (e.g. to denote an application, python project, etc.) place the slash after the type, e.g. pro/ would match a directory named myproject.pro/. Note that 'directories' here are an abstract resource. It may not be a physical directory on disk, but something with a directory-like structure, like a set of database tables.

Notes

Abilities are added by FIFO 'hosts' (applications that provide access to a FIFO resource) and the framing manager is expected to maintain a list of these. The list is not given to FIFO-client applications, which never see the name of the ability they access. The framing manager mediates the connection by displaying the ability for the user to select, after which the FIFO-client receives the filename of the FIFO resource.

HIPE_OP_FIFO_CLOSE

Instruction set reference

HIPE_OP_FIFO_CLOSE

Sent by either end of a FIFO relationship (and relayed to the other end by the framing manager) to say that the sender has finished with the current transfer, and whether the transfer succeeded at its end. The resource still exists and may be opened again later.

Each end sends this instruction once per transfer. The end that finishes first sends it, and the other end closes the FIFO at its own end and answers with its own HIPE_OP_FIFO_CLOSE. The transfer is over when both have been sent, and the resource is then ready to be opened again, in a different mode if required.

Who sends it, and what the outcome means

SituationWhat is sentWhat the receiver should do
The client has finished writing.The client sends HIPE_OP_FIFO_CLOSE with arg[1] empty, after writing all its data and closing its end.The host reads the remaining data, stores it, and answers as in the next two rows.
The host has stored what the client wrote.The host answers with arg[1] empty.The client can report the data as saved.
The host could not store what the client wrote (disk full, no permission...).The host answers with the reason in arg[1].The client reports that saving failed, and can show the reason.
The client gives up part-way through writing.The client sends HIPE_OP_FIFO_CLOSE with a reason in arg[1].The host discards what it received, leaving the stored data as it was, and answers.
The host has finished writing what the client asked to read.The host sends HIPE_OP_FIFO_CLOSE with arg[1] empty, after writing all the data.The client reads the remaining data and answers.
The host fails part-way through writing (the file became unreadable...).The host sends HIPE_OP_FIFO_CLOSE with the reason in arg[1].The client discards what it received, reports the failure, and answers.
The client needs no more of what it is reading.The client sends HIPE_OP_FIFO_CLOSE with arg[1] empty.The host stops writing and answers.
The host cannot do what a HIPE_OP_FIFO_OPEN asked (no such file, no permission...).The host sends HIPE_OP_FIFO_CLOSE with the reason in arg[1], in place of relaying the HIPE_OP_FIFO_OPEN back.The client closes its end and reports the failure. No transfer was opened, so it sends no answer.

Notes

A client that writes data should treat it as saved only once the host's answer arrives with arg[1] empty. Until then the host may still fail to store it.

A program should act only on whether arg[1] is empty. The text itself comes from the other application and is meant for the user; its wording is not defined.

A HIPE_OP_FIFO_DROP_PEER for the resource that arrives while a transfer is open also ends the transfer, as a failure: the other application has gone or has ended the relationship. An application should also give up on a transfer whose other end stays silent for too long.

Applications written before arg[1] was defined send it empty and ignore it when receiving, so they report every transfer as successful.

Like the other FIFO instructions, this one is passed between frames without the Hipe display server interpreting its contents.

HIPE_OP_FIFO_DROP_PEER

Instruction set reference

HIPE_OP_FIFO_DROP_PEER

In a client-host relationship, this instruction is used when a client wishes to tell a host that access to the FIFO resource will no longer be required (for example, the user has closed a certain document that was being accessed through the resource).

In the normal use case, the client would send this instruction to location 0 (to be picked up by the parent frame), and the parent frame on receiving the instruction should pass it on to the corresponding host frame.

Notes

Either end of the peer relationship can initiate terminating the FIFO relationship, however the host is the end responsible for actually deleting the shared FIFO resource on disk. If the roles have been swapped (see "Swapping roles" under HIPE_OP_FIFO_OPEN), the new client normally sends this instruction when it is done, but the FIFO is still deleted by the application that sent the HIPE_OP_FIFO_RESPONSE, which was the host when the relationship began. In this page, "host" means that application. Whichever end initiates dropping the peer should send this instruction via the framing manager to the opposite end of the relationship.

After receiving this message, the FIFO-host should discard and clean up the shared FIFO resource. (Or if the host is the initator of the drop peer request, it should delete the FIFO resource at the same time as it sends the message to the client.

After this instruction is sent, it should be assumed that the peer relationship no longer exists and no further instructions referencing that that particular FIFO resource should be sent through hipe.

HIPE_OP_FIFO_GET_PEER

Instruction set reference

HIPE_OP_FIFO_GET_PEER

Requests (or handles a request) for a program to begin communications with a FIFO peer that has the required ability. This leads to the creation of a FIFO resource between the two applications.

There is a one-to-many relationship between a supported ability and the number of peers that may be making use of that ability.

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

Order of access modes

The order of access mode specifiers is significant: where appropriate, the expected initial access mode should be specified first. For example, "rw" means that data will initially be read, and may be written back to later, while "wr" means that fresh data will be written from the start. An initial access mode of r or R means that the host acts (initially at least) as a source of data rather than a destination.

An example of "read then write" ordering would be a file which is opened for editing. First the editor must read the file to load its contents. Later the user may save changes back into the file.

Minimal vs desired access modes

An application might be able to deal with a multitude of access modes (such as file seeking, reading and writing) but may also be able to make do with a minimal set of access modes. For example, a text editor might be capable of opening a file for reading and writing. However, in the worst case, loading a file read-only may be supported too. In this case, arg[1] might be specified as: "r rw"

A client that can also serve the resource itself adds s to the full set, e.g. "w ws", so that the host may offer to swap roles (see "Swapping roles" under HIPE_OP_FIFO_OPEN). s is never the minimal access mode.

Notes

In certain cases a peer relationship needs to be set up to transfer a group of files that are not physically located in a particular named directory. For this case, request a peer using a blank filename in arg[0] and the directory type (/) specified via arg[2]. The treatment of a group of files is the same as a directory of files except that the lack of a filename tells the peer that they should not be copied into a new directory but should be placed within a given location.

HIPE_OP_FIFO_INFO

Instruction set reference

HIPE_OP_FIFO_INFO

Carries properties of a FIFO relationship: for example, which application has the resource and what the user chose it for, so that an application can tell the user why their file is in use ("notes.txt is open in Appscape"). Properties stated by the framing manager are kept apart from what the application at the other end says about itself.

Properties

Properties are lines of the form key=value, separated by newline characters. The key is everything before the first =; the value is everything after it, as UTF-8 text with no newline characters.

KeyInValue
abilityarg[1]The name of the ability the user chose for this relationship, as the host gave it in HIPE_OP_FIFO_ADD_ABILITY, e.g. Edit in Appscape.
peer-titlearg[1]The title of the application at the other end, as the framing manager shows it to the user.

Who sends it

SenderWhenArguments
The framing managerTo both ends, after relaying a HIPE_OP_FIFO_RESPONSE that gave a resource, and whenever its properties change (e.g. the other end's title changes).arg[1] = its properties, arg[2] empty.
An application at either endWhen something it states about itself becomes known or changes. arg[2] = its properties, arg[1] empty. The framing manager relays it to the other end with arg[2] unchanged and only its own properties (or nothing) in arg[1].
An application at either endTo ask for the framing manager's properties. arg[1] and arg[2] both empty. The framing manager answers that application only, with arg[1], and does not relay the request.

Notes

An application receives this instruction from its parent (location 0), so arg[1] always comes from the framing manager. A framing manager must never copy anything an application sent into arg[1]. arg[2] is only what the other application claims.

Properties describe the other end of the relationship, not "the host" or "the client", so they keep their meaning after the roles are swapped (see "Swapping roles" under HIPE_OP_FIFO_OPEN).

The instruction is optional. A framing manager that doesn't support it sends nothing, and applications that don't support it ignore it, so an application must work without it. An application in a top-level window has no framing manager, and gets no answer.

Like the other FIFO instructions, this one is passed between frames without the Hipe display server interpreting its contents.

HIPE_OP_FIFO_OPEN

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.

HIPE_OP_FIFO_REMOVE_ABILITY

Instruction set reference

HIPE_OP_FIFO_REMOVE_ABILITY

Where an application is capable of acting as a host in a FIFO relationship, this instruction provides a way for the application to notify the framing manager that it should no longer be called on to perform a particular action.

Notes

An application can only remove an ability that it previously added.

There's no guarantee that an application will remove all its abilities before it terminates. So a supporting framing manager should clean up outstanding abilities for applications that terminate.

HIPE_OP_FIFO_RESPONSE

Instruction set reference

HIPE_OP_FIFO_RESPONSE

In a client/host relationship between applications, this instruction is used to relay a message from the host to the client (via the framing manager), whereby the host either rejects the peer relationship, or informs the client of the path to the shared FIFO resource.

The framing manager will receive this message from a FIFO-host and is responsible for relaying it back to the corresponding FIFO-client (which made the initial HIPE_OP_FIFO_GET_PEER request).

The FIFO-host will have been brought to the foreground by the framing manager as part of the user-selection process. When the framing manager relays this message, it should then give the focus back to the FIFO-client, unless:

Notes

A blank value for arg[0] always indicates rejection of the peer request, e.g. cancellation by the user. In this case the remaining arguments are superfluous.

A host grants s only if the client asked for it and the host can also act as the client. The roles are swapped only once the client then sends HIPE_OP_FIFO_OPEN with mode s and the host accepts (see "Swapping roles" under HIPE_OP_FIFO_OPEN). Until then, and if the client never sends it, the host serves the client as usual.

HIPE_OP_FILE_RETURN

Instruction set reference

HIPE_OP_FILE_RETURN

Sent to the client after the client requests a file (e.g. a snapshot of the frame contents).

Notes

requestor carries the value of the instruction that requested the file.

HIPE_OP_FIND_RESULT

Instruction set reference

HIPE_OP_FIND_RESULT

Sent to the client in reply to HIPE_OP_FIND_TEXT.

Notes

requestor carries the value of the HIPE_OP_FIND_TEXT instruction.

A search tool can show these values as e.g. "3 of 12", or "3 of 1000+" when arg[3] is "+".

HIPE_OP_FIND_TEXT

Instruction set reference

HIPE_OP_FIND_TEXT

Finds text in the style of a web browser's 'find on page' feature. All matches are highlighted, and the next one is selected and scrolled into view. The server replies with HIPE_OP_FIND_RESULT.

Notes

The match selected is the first one after the current selection or text cursor within the searched content (or the last one before it, with b). If there's none, the search wraps round to the first (or last) match. If there's no selection there, the first (or last) match is selected. Sending the same instruction again therefore steps through the matches one by one. Any selection left in another frame within the searched content is removed, so the search always carries on from the latest match.

Keyboard focus doesn't move. A user can go on typing in a search box while the matches are being selected.

Each search replaces the highlighting within the searched content. Highlighting elsewhere (e.g. from a search of a different element) stays.

A client can only search its own content, including the frames of child clients it owns. It can't search the frame of its parent or of any other client.

At most 1000 matches are found. Beyond that, the reply's arg[3] is "+", and later matches aren't highlighted or reachable.

Text that can't be selected, because it has the style user-select: none, isn't searched, since a match there couldn't be selected. Use this to leave out e.g. line numbers, or a layer that repeats text shown elsewhere. The style is inherited, and user-select: text on a descendant makes its text searchable again.

Text is matched as it is laid out (as HIPE_OP_GET_CONTENT mode 2 reads it), including text in form fields, but a match can't span two frames.

Appearance

The highlighting is styled with the CSS ::search-text pseudo-element (from CSS Pseudo-Elements Level 4). It supports two properties:

The selected match is shown as the selection, so it's styled with ::selection instead.

The standard Hipe themes set ::search-text to suit their colours (e.g. black text on yellow). Without a rule, matches get a translucent yellow background and keep their own text colour, so they stay readable on light and dark backgrounds alike. For example, a theme or client can use:

::search-text { background-color: yellow; color: black; }

A client can override the theme for its own elements with a rule of its own (e.g. with HIPE_OP_ADD_STYLE_RULE). Each property is decided separately, so a client rule that sets only background-color still gets the theme's color: set both if the text colour matters.

A rule applies to the text directly inside the elements it selects, not to text inside their child elements: #editor::search-text doesn't style a match inside a <span> in the editor. To cover everything inside an element, include its descendants too:

#editor::search-text, #editor *::search-text { background-color: lime; color: black; }

A rule without an element selector, like the theme example above, applies everywhere.

color is also used where the text itself is invisible. For example, a code editor might have an editable layer with color: transparent above a syntax-highlighted copy of its text. There, color: black would draw matches in black over the copy, while a translucent background with color: transparent lets the copy's own colours show through:

#editor::search-text { background-color: rgba(255, 200, 60, 0.3); color: transparent; }

HIPE_OP_FRAME_CLOSE

Instruction set reference

HIPE_OP_FRAME_CLOSE

Sent to a client frame (by the display server, or by a framing manager) to indicate that the user has requested a client be closed/terminated.

Notes

You are required and expected to check for this instruction in your application, and respond in a reasonable way. It may not be appropriate for your application to terminate immediately - an acceptable response might be to ask the user for confirmation before discarding unsaved changes to a document.

Unless the close operation is forced, receiving this instruction will not actually close your application. You are required to handle the received instruction, to close the hipe client session and then terminate your application.

A forced close operation makes no guarantee that the client process will terminate; only that it will be removed from the display server. A poorly written application might continue to run in the background after it no longer has access to the display, although most ought to terminate.

HIPE_OP_FRAME_EVENT

Instruction set reference

HIPE_OP_FRAME_EVENT

Sent by the server to a client that manages one or more sub-frames to indicate an event affecting a direct sub-frame of this one. Frame events usually relate to a change in some information about the client in the subframe, rather than user interaction events happening within the subframe itself.

Notes

Frame events are sent automatically once HIPE_OP_GET_FRAME_KEY has been requested for that frame.

Frame events are different to regular events in Hipe, and usually refer to a change in information about the client frame. The framing client doesn't get to specify which events should be listened for. All of the following events will be received if they occur

Event types are defined by macros in hipe_instruction.h, and have the prefix: HIPE_FRAME_EVENT_. These are represented by the raw char value of the first character in arg[0], and can be checked by evaluating the value of (received instruction).arg[0][0]

Client event types

arg[0]arg[1]arg[2]
HIPE_FRAME_EVENT_CLIENT_CONNECTEDClient titleClient process ID (or 0)
HIPE_FRAME_EVENT_CLIENT_DISCONNECTED - -
HIPE_FRAME_EVENT_TITLE_CHANGEDClient title string -
HIPE_FRAME_EVENT_ICON_CHANGEDbinary PNG image data -
HIPE_FRAME_EVENT_COLOR_CHANGEDnew foreground color -
HIPE_FRAME_EVENT_BACKGROUND_CHANGEDnew background color -

HIPE_OP_FREE_LOCATION

Instruction set reference

HIPE_OP_FREE_LOCATION

Send this instruction to the display server to free server resources associated with a hipe_loc location handle the client application no longer needs.
Usually a location that has been deleted. After this operation, the tag may still exist on the screen but no longer has a location value connected to it.

Notes

Freeing a location takes it off its element. The element's events are no longer reported, and if the element returns to the document later (for example by undo), it has no location. Locations inside content replaced by HIPE_OP_SET_TEXT stay in use until freed. See "Locations".

Location handle resources held by the display server are freed automatically when your application terminates. However, it is still polite to free unneeded location handles from time to time, especially if your application uses a lot of them.

Discard any local copies of hipe_loc values whenever you free them, since they are no longer valid for use in Hipe instructions.

HIPE_OP_GEOMETRY_RETURN

Instruction set reference

HIPE_OP_GEOMETRY_RETURN

The display server sends this instruction out to a client application in reply to a request for geometry information. For example, a HIPE_OP_GET_GEOMETRY or HIPE_OP_GET_SCROLL_GEOMETRY request.

Notes

When the requested information is scroll geometry on a scrollable element, the left and top co-ordinates relate to the visible edges of the scrollable content relative to the edge of the scrollable element, while the width and height relate to the total dimensions of the scrollable content inside the scrollable element.

HIPE_OP_GET_ATTRIBUTE

Instruction set reference

HIPE_OP_GET_ATTRIBUTE

Requests the current value of an HTML attribute for a particular element.

Notes

After sending this instruction to the display server, the Hipe server process will send a HIPE_OP_ATTRIBUTE_RETURN instruction back to the client in reply.

Some values are better read with an instruction of their own:

To readUseBecause
A styleHIPE_OP_GET_STYLEIt returns the value in effect, including style rules. style holds only the element's inline styles.
An image or a drawingHIPE_OP_GET_SRCIt returns an img's data as sent with HIPE_OP_SET_SRC, or a canvas's drawing.

HIPE_OP_GET_AUDIOVIDEO_STATE

Instruction set reference

HIPE_OP_GET_AUDIOVIDEO_STATE

Requests the current playback state of an <audio> or <video> element. The server responds with a HIPE_OP_AUDIOVIDEO_STATE instruction containing the element's current position, playback speed, playing/paused status and volume.

Notes

If the location isn't an <audio> or <video> element, the reply's four arguments are all empty.

HIPE_OP_GET_BY_ID

Instruction set reference

HIPE_OP_GET_BY_ID

Looks up an element using its id attribute. The server then sends a HIPE_OP_LOCATION_RETURN instruction back to the client containing the location of the requested element.

HIPE_OP_GET_CARAT_POSITION

Instruction set reference

HIPE_OP_GET_CARAT_POSITION

Gets the current position of the text entry cursor in an element, or the range of text selected in it.

The display server responds with a HIPE_OP_CARAT_POSITION instruction. Its arg[0] is the character offset of the selection's anchor (where the selection starts) and its arg[1] is the offset of the selection's focus (where it ends, which is where the cursor is). They are equal when no text is selected, and arg[1] is less than arg[0] when the text was selected backwards. Offsets are counted as described on the HIPE_OP_CARAT_POSITION page.

Notes

A cursor with no text selected is still a position: it is reported with both arguments equal, e.g. "3" and "3".

If the element contains neither the cursor nor selected text, arg[0] and arg[1] of the reply are both empty strings. A document has only one cursor or selection at a time, so this is the case when it is somewhere else: for example, the user has clicked into another editable element or on ordinary text elsewhere in the document, or nothing has been clicked or focused yet. It is also the case when a selection extends beyond the element, starting inside it and ending outside (this can't happen within a contenteditable element, whose editing selection stays inside it). input and textarea elements keep their own cursor position even when they don't have focus, so they always report one.

An empty string is distinct from "0", which is a cursor before the first character, so check the argument's length before converting it to a number (for example, atoi would return 0 for an empty string).

This works for the cursor in editable content and also for text the user has selected in non-editable content inside the element. To get the selected text itself, use HIPE_OP_GET_SELECTION.

HIPE_OP_GET_CONTENT

Instruction set reference

HIPE_OP_GET_CONTENT

Requests the inner content of an element. The server responds with a HIPE_OP_CONTENT_RETURN instruction containing the requested content.

Notes

Mode 4 is for editors and other clients that keep their own copy of a large text. Reading only the changes saves transferring, decoding and comparing the whole text after every edit. Apply each reply to your copy (replace arg[2] characters at arg[1] with arg[0], or replace everything when arg[3] is full), and the copy stays exactly equal to the element's text. The display server keeps the last text it returned in mode 4 for each element (freed with the location, e.g. by HIPE_OP_FREE_LOCATION).

Modes 0 and 2 both return text whether or not it is currently visible on screen, including text in an element or frame that is hidden or has never been shown. They differ in what they include: mode 0 returns every piece of text inside the element, including text inside elements styled display:none, while mode 2 leaves those out. Text styled visibility:hidden is included by both.

Mode 0 is the most faithful way to read back text that must not be lost, such as the contents of an editor. For an editable element using contenteditable="plaintext-only", line breaks are stored as real newline characters, so mode 0 returns them.

HIPE_OP_GET_FIRST_CHILD

Instruction set reference

HIPE_OP_GET_FIRST_CHILD

Send to the server to request the location of the first child element inside the specified element.

Notes

The server responds to this instruction by sending a HIPE_OP_LOCATION_RETURN instruction back to the client.

HIPE_OP_GET_FRAME_KEY

Instruction set reference

HIPE_OP_GET_FRAME_KEY

Send this instruction to requests a host key for a child frame (iframe element) at the specified location. Hipe will respond by sending a HIPE_OP_KEY_RETURN instruction back to the client. This key can then be passed to another application to allow that application to be hosted within that frame.

HIPE_OP_GET_GEOMETRY

Instruction set reference

HIPE_OP_GET_GEOMETRY

Send this instruction to the display server to request the position and size of a particular element as it is laid out.

Notes

The Hipe display server sends back a HIPE_OP_GEOMETRY_RETURN instruction, containing the left and top position coordinates, as well as the width and height of the specified element.

With location 0 it reports the body. This works even as the client's first instruction, before it has added any content.

The left and top coordinates are in pixels, measured from the nearest containing element that is positioned (one whose position style is relative, absolute or fixed) or is a table or table cell, or from the top-left of the frame's content if there is none. They are not screen coordinates, and they do not change when the element, or anything containing it, is scrolled.

HIPE_OP_GET_LAST_CHILD

Instruction set reference

HIPE_OP_GET_LAST_CHILD

Send to the server to request the location of the last child element inside the specified element.

Notes

The server responds to this instruction by sending a HIPE_OP_LOCATION_RETURN instruction back to the client.

HIPE_OP_GET_NEXT_SIBLING

Instruction set reference

HIPE_OP_GET_NEXT_SIBLING

Send to the server to request the location of the element that follows after the current element on the same level.

Notes

The server responds to this instruction by sending a HIPE_OP_LOCATION_RETURN instruction back to the client.

HIPE_OP_GET_PREV_SIBLING

Instruction set reference

HIPE_OP_GET_PREV_SIBLING

Send to the server to request the location of the element that follows immediately before the current element on the same level.

Notes

The server responds to this instruction by sending a HIPE_OP_LOCATION_RETURN instruction back to the client.

HIPE_OP_GET_RANGE_GEOMETRY

Instruction set reference

HIPE_OP_GET_RANGE_GEOMETRY

Requests where a range of text in an element appears on screen, as one rectangle per line, or where a text cursor appears. This is useful for placing something next to the cursor or a piece of text (such as a completion list or a tooltip), or for highlighting text.

The display server responds with a HIPE_OP_RANGE_GEOMETRY instruction.

Notes

Offsets are counted exactly as for HIPE_OP_CARAT_POSITION: in characters, in the element's value for input and textarea elements and otherwise in its text as laid out (the text HIPE_OP_GET_CONTENT returns in mode 2). Negative offsets count from the end: -1 is the position after the last character. For example, "0" and "-1" request the whole text. The order of the two offsets doesn't matter.

To find where the cursor would be drawn at a given offset without moving it, give just arg[0].

HIPE_OP_GET_SCROLL_GEOMETRY

Instruction set reference

HIPE_OP_GET_SCROLL_GEOMETRY

Send this instruction to the display server to request the scroll position geometry of content within a particular scrollable element as rendered on screen.

Notes

The Hipe display server sends back a HIPE_OP_GEOMETRY_RETURN instruction, containing the scroll position of the content inside the scrollable element at its left and top edge, as well as the total width and height of the scrollable content inside the element.

With location 0 it reports the body. This works even as the client's first instruction, before it has added any content.

HIPE_OP_GET_SELECTION

Instruction set reference

HIPE_OP_GET_SELECTION

Gets the current user-selected text in the document (if the user has selected any content) and requests the server to send back a HIPE_OP_CONTENT_RETURN instruction. The server sends back an instruction even if there is no selection: in this case a blank string is sent in the reply instruction.

Notes

If a client that does not occupy a top-level frame attempts to ask for the global selection, a blank selection "" is always returned. This is a security feature to prevent clients from snooping on other client frames.

HIPE_OP_GET_SRC

Instruction set reference

HIPE_OP_GET_SRC

Reads back the data of an img element, or the contents of a canvas, as a file. The display server replies with HIPE_OP_SRC_RETURN.

ElementWhat is returned
imgThe bytes most recently given to it with HIPE_OP_SET_SRC, unchanged, with their mime type.
canvasA picture of what is currently drawn on it. As "png", an image of the canvas's size in pixels. As "pdf", a one-page document with no margins whose page is the size of the canvas at 96 pixels to the inch, which is convenient for printing.
audio, video and other elementsNothing: the reply is an error. A client that needs a media file again should keep its own copy.

Notes

The "pdf" of a canvas contains the same pixels as the "png": a canvas holds a picture, not the shapes that were drawn. To capture a whole frame, use HIPE_OP_TAKE_SNAPSHOT.

HIPE_OP_GET_STYLE

Instruction set reference

HIPE_OP_GET_STYLE

Requests the resolved value of a CSS style property on a particular element - i.e. the actual value in effect once the display server applies cascading and inheritance, not just whatever (if anything) happens to be set directly on the element itself. Use this instead of HIPE_OP_GET_ATTRIBUTE with an attribute name of "style" when the property you want might only be in effect via an inherited or cascaded rule - for example, a background colour coming from a loaded theme stylesheet rather than a literal style="..." written onto the element.

Notes

After sending this instruction to the display server, the Hipe server process will send a HIPE_OP_STYLE_RETURN instruction back to the client in reply.

This instruction does not retry or block waiting for a layout pass to complete. If the element hasn't actually been rendered yet, or the property name given isn't a CSS property the display server recognises, the value returned may be an empty string - if that matters for your use case, retry the request again after a short delay.

HIPE_OP_GET_X11_XID

Instruction set reference

HIPE_OP_GET_X11_XID

Turns an object element into a place where the window of an X11 application can be embedded. The display server creates an X11 window at the element's position and keeps it at the element's position and size from then on. It replies with HIPE_OP_X11_XID_RETURN, which carries the window's XID.

Notes

The client does the embedding itself: once it has the XID, it reparents the other application's window into it over its own connection to the X server (for example with XReparentWindow).

The embedded window is a real X11 window and is drawn above everything in the Hipe frame, so nothing in the document can be placed over it. To hide it for a while (for example, to show a menu or a dialog where it is), give the object element the style visibility: hidden. The window reappears when the element is made visible again.

Don't hide it with display: none. That destroys the X11 window, and the application's window embedded in it is destroyed too. Making the element visible again creates a new, empty window with a new XID.

The reply's XID is 0, and nothing is created, if:

HIPE_OP_INSERT_TAG

Instruction set reference

HIPE_OP_INSERT_TAG

Inserts a new HTML tag element before the specified tag element.

Notes

The element is created directly, exactly where you ask: nothing is added around it and nothing is left out. A tag whose name isn't a valid element name is not created, and its location is still used up. See HIPE_OP_APPEND_TAG and "Tags, attributes and styles".

Setting the class and text in the same instruction (arg[2] and arg[3]) is much faster than following up with HIPE_OP_TOGGLE_CLASS and HIPE_OP_SET_TEXT, which matters when building many small elements, such as the coloured spans of syntax-highlighted text.

Prior to version 2, Hipe accepted an extra argument in arg[2] where passing "1" would cause the server to reply with a HIPE_OP_LOCATION_RETURN instruction describing the newly appended tag. This was removed in version 2, and arg[2] is now the class list. A more efficient way to obtain the new location is by calling the hipe_newest_location() function (C) or the hipe::loc::appendAndGetTag() method (C++) in the hipe API.

HIPE_OP_KEY_RETURN

Instruction set reference

HIPE_OP_KEY_RETURN

This instruction is sent back to the client from the server in response to a HIPE_OP_GET_FRAME_KEY request.

HIPE_OP_LOCATION_RETURN

Instruction set reference

HIPE_OP_LOCATION_RETURN

Sent to the client by the display server in reply to a request for a location handle to a particular element.

Notes

Location handles should be freed using HIPE_OP_FREE_LOCATION when no longer required. They are also freed automatically when the client application terminates.

The location value 0 is returned if the element does not exist or the element exists but its location handle has been freed/de-allocated from use. (With the C++ library, this can happen if all hipe::loc objects corresponding to an element have been discarded.)

HIPE_OP_MEASURE_TEXT

Instruction set reference

HIPE_OP_MEASURE_TEXT

Measures how much space some text would take up if it were the content of an element, without adding anything to the document. This is useful for fitting text to a space (for example choosing a font size or where to break a label), finding the width of a character in a monospace font, or placing things alongside text.

The display server responds with a HIPE_OP_TEXT_METRICS instruction.

Notes

The text is measured as if it were placed directly inside the element as its only content: in the element's font (family, size, weight and style, including inherited values), with its letter and word spacing, tab size, text-transform and white-space rules applied. For example, in an element that collapses white space, a run of spaces counts as one space, and spaces at the start and end of a line don't count.

The text is not wrapped: its width is the width of the widest line, however narrow the element is. If the element preserves newlines (e.g. a pre element, or white-space:pre-wrap), each newline in arg[0] starts a new line; otherwise newlines count as spaces. To fit text into a given width, measure different line breaks and font sizes and choose the one that fits.

The element doesn't have to be displayed: an element styled display:none can still be used to measure text.

HIPE_OP_MESSAGE

Instruction set reference

HIPE_OP_MESSAGE

Sends a user-defined message to another client, which must be a direct child of the sending client, or the direct parent of the sending client.

Notes

Unlike most Hipe instructions, this instruction may be either sent or received by the client. It passes more or less straight through the server from one client to another.

Instruction set reference

HIPE_OP_OPEN_LINK

This instruction sends a link resource (such as a hyperlink URL) to the parent frame or desktop environment to be opened for the user. When used within another desktop environment, this action might launch a web browser or similar to make use of the link resource. On an embedded system, this action might display a QR code for the user to scan on a mobile device. The exact behaviour and implementation depends on the framing manager and user environment.

HIPE_OP_RANGE_GEOMETRY

Instruction set reference

HIPE_OP_RANGE_GEOMETRY

Sent by the display server in response to a HIPE_OP_GET_RANGE_GEOMETRY instruction.

Notes

Coordinates are in CSS pixels, relative to the top-left corner of the element (its border edge) as it is currently displayed. If the element, or anything containing it, is scrolled, the rectangles move with the text: they describe where the text appears, not where it would be if nothing were scrolled.

Text on the same line forms a single rectangle, even when it spans several elements or font sizes. Each rectangle covers the text itself, not the full height of the line. Lines within the range that contain no text, such as empty lines, have no rectangle.

For a cursor position, there is a single rectangle with a width of 0, as tall as the line the cursor is on.

arg[0] is empty if there is nothing to report: the element isn't displayed, the range covers no text, or the request was for the element's cursor and the cursor isn't in the element.

HIPE_OP_REMOVE_ATTRIBUTE

Instruction set reference

HIPE_OP_REMOVE_ATTRIBUTE

Removes (unsets) an HTML attribute from a particular HTML tag element.

Notes

Removing class removes all of the element's classes, and removing style all of its inline styles. To remove one class, use HIPE_OP_TOGGLE_CLASS. See HIPE_OP_SET_ATTRIBUTE for other attributes that have an instruction of their own.

HIPE_OP_REQUEST_CONTAINER

Instruction set reference

HIPE_OP_REQUEST_CONTAINER

This instruction is produced by a client application and sent to the display server in order to initiate a client session and request a frame for the application.

You never need to deal with this instruction directly. It is sent to the display server automatically when you call hipe_open_session().

Notes

The client process identifier sent to the Hipe display server should not be retrieved or relied upon without some form of additional verification. As with X11, the display server's record of the client's PID is dependent on the honesty of the client application.

The theme index value is used for cases where multiple stylesheet themes are loaded into hiped, and different clients require a different theme; usually specified via an environment variable. If blank the default CSS theme will be used. A value of 0 means that only minimal default styling should be used, which then gives the client absolute control over GUI styling.

HIPE_OP_SCROLL_BY

Instruction set reference

HIPE_OP_SCROLL_BY

Scrolls the contents of a scrollable element by a relative amount compared to the current scroll position.

Notes

Leave arg[0] or arg[1] blank if scrolling in a certain direction is not required.

HIPE_OP_SCROLL_TO

Instruction set reference

HIPE_OP_SCROLL_TO

Scrolls the contents of a scrollable element to a new scroll position.

Notes

Leave arg[0] or arg[1] blank if scrolling in a certain direction is not required.

HIPE_OP_SERVER_DENIED

Instruction set reference

HIPE_OP_SERVER_DENIED

Sent by the server when a request is received but cannot be acted on due to some critical violation. Usually this means that the client has not followed protocol, e.g. is trying to send instructions even though a container request was previously denied. Or, the session has been terminated at the server end.

This is also the opcode reported (via instruction_ret->opcode) when hipe_next_instruction() returns -1 because the connection to the display server has been lost. Client applications must check for it and stop calling hipe_next_instruction() when it occurs – see the warning under hipe_next_instruction().

Notes

The server sends this, with a reason, just before disconnecting an application that broke the protocol (see "Locations"), and when it refuses a client built against an older libhipe. libhipe prints the reason to stderr and hipe_last_error() returns it.

HIPE_OP_SERVER_NOTICE

Instruction set reference

HIPE_OP_SERVER_NOTICE

Sent by the display server to report a mistake in your application that isn't fatal, for example a location listed for markup but found on no element in it (see "Locations").

Notes

libhipe prints the message to stderr and doesn't pass the instruction to your application.

HIPE_OP_SET_ATTRIBUTE

Instruction set reference

HIPE_OP_SET_ATTRIBUTE

Sets an HTML attribute for a particular tag element.

Notes

Any attribute can be set, except hipe-loc, which only has a meaning in markup (see "Locations"). An invalid attribute name is ignored.

These attributes have an instruction of their own that suits them better:

AttributeInstead useBecause
classHIPE_OP_TOGGLE_CLASS, or arg[2] of HIPE_OP_APPEND_TAG and HIPE_OP_INSERT_TAGIt adds or removes one class. Setting class replaces all of the element's classes.
styleHIPE_OP_SET_STYLEIt sets one property. Setting style replaces all of the element's inline styles.
srcHIPE_OP_SET_SRCIt sends the file's data, in parts if it is large. src loads only a data: URL.
hrefHIPE_OP_OPEN_LINKNothing in a Hipe frame navigates. HIPE_OP_OPEN_LINK hands a link to the user's environment.
onclick, onkeydown and other event attributesHIPE_OP_EVENT_REQUESTNo scripts run.

HIPE_OP_SET_CURSOR

Instruction set reference

HIPE_OP_SET_CURSOR

Send this instruction to the display server to apply a custom mouse cursor to the specified location. The mouse cursor is generated from a character symbol and can be any unicode character for which the necessary font is available on the system.

arg[1]The symbol is drawnThe hotspot is
omittedfrom the left edge of the squarenear the symbol's top-left corner (suits arrows such as "⇖")
"0.5,0.5"centred in the squarethe middle of the symbol (suits "↔", "✖", "✛")
"0,0" to "1,1"centred in the squarethat point of the square

Values outside 0 to 1 are treated as 0 or 1. If arg[1] isn't two numbers separated by a comma, it is ignored. A centred symbol's middle can be a pixel or two away from the square's centre, depending on the symbol's shape in its font.

Notes

As with all text data in Hipe, the character symbol is assumed to be UTF8 encoded.

Only the cursor of the body element (no location) is regenerated when the body's colours change. A cursor set on another element keeps the colours it was created with; set it again to recolour it.

HIPE_OP_SET_FOCUS

Instruction set reference

HIPE_OP_SET_FOCUS

Gives keyboard focus to the specified element.

Notes

ElementCaret or selection after SET_FOCUS
Text input, textarea, editable element focused beforeAs it was when the element last lost focus.
Text input, first focusCaret at the end of its value, or as HIPE_OP_CARAT_POSITION set it.
Textarea or editable element, first focusCaret at the start, or as HIPE_OP_CARAT_POSITION set it.
<iframe>Focus goes to the element focused last inside the frame.

Framed clients

When a framed client sends SET_FOCUSResult
The focus is inside its own frameThe element is focused at once.
The focus is elsewhere (the framing manager or another client)Nothing changes yet: the element is remembered, and gets the focus when the framing manager next focuses the client's <iframe> (the latest request wins).
Its <iframe> is hidden (e.g. an inactive tab)The same: remembered until the frame is shown and focused.

HIPE_OP_SET_ICON

Instruction set reference

HIPE_OP_SET_ICON

Sets or updates the icon image for the application. This instruction is sent by a client node; it is never received by an application. If the client is running inside a framing manager, the framing manager receives a HIPE_OP_FRAME_EVENT instruction containing the icon data to decorate the client with.

HIPE_OP_SET_SRC

Instruction set reference

HIPE_OP_SET_SRC

Sends the data of an image, audio or video file to an img, audio or video element, or a block of raw pixels to a canvas. In Hipe an element's source is always the data itself, never an address.

Sending a file in chunks

A large file can be sent over several HIPE_OP_SET_SRC instructions to the same location, so that the client doesn't have to hold it all in memory or send it as one huge instruction. Set arg[2] to "1" on every chunk except the last.

Images

A chunked image is drawn progressively as its chunks arrive. The exception is an element that is already showing a complete image: it keeps showing that until the new one has fully arrived, then swaps, so that the user doesn't see a half-loaded replacement.

Audio and video

Sent as a single instruction, a file plays as soon as playback is started. Playback, speed and volume are controlled with HIPE_OP_AUDIOVIDEO_STATE.

Sent in chunks, when playback can start depends on arg[3]:

arg[3] on the first chunkWhat happens
The size of the whole file in bytesPlayback can start once the start of the file has arrived (typically its first tenth), and the element's own controls show how much has arrived. If playback catches up with the data, it pauses by itself and resumes when more has arrived.
EmptyNothing plays until the last chunk has arrived, although the duration may be reported earlier. Use this when the total size isn't known in advance.

Once the whole file has arrived, a chunked file behaves exactly like one sent in a single instruction, including seeking and looping.

To play something else in the same element, send the new file to it: the old one stops and is replaced.

Canvas

Sending arg[1] = "image/x-raw-rgba" to a canvas writes pixels straight into it (the equivalent of putImageData() in HTML).

Notes

To read an image's data or a canvas's contents back, use HIPE_OP_GET_SRC.

HIPE_OP_SET_STYLE

Instruction set reference

HIPE_OP_SET_STYLE

Send to the display server to apply a CSS style property to the specified location element.

Notes

To set a background image from its binary data, use HIPE_OP_SET_STYLE_SRC.

HIPE_OP_SET_STYLE_SRC

Instruction set reference

HIPE_OP_SET_STYLE_SRC

Send this instruction to the display server to specify background image data, or other binary data for the specified style property on the specified tag element.

Notes

arg[3] may be used to facilitate working with CSS properties that take additional parameters that follow after the source image. For example, for the background property in CSS, you might wish to specify not only the background image itself, but also "repeat-x repeat-y" or similar CSS values that modify the behaviour of the CSS property. These would be placed in arg[3] and are treated as a suffix to the style property setting. Values that must be specified before the source data cannot be specified in this way.

HIPE_OP_SET_TEXT

Instruction set reference

HIPE_OP_SET_TEXT

Send this instruction to the display server to populate a tag element with the specified text string. Any existing child elements are discarded.

  • location: The tag element to be populated with text.
  •     arg[0]: Text to be placed in the tag element.
  •     arg[1]: Text mode: "0" (the default, also used if the argument is empty), "1", "2" or "3". See the table below.
  •     arg[2]: Mode 3 only: the locations used in the markup's hipe-loc attributes, e.g. "57,1000-1499". See "Locations".

Text modes

In modes 0, 1 and 2, the characters <, >, " and ' are shown as typed. Text that looks like an HTML tag, such as <b>, is never treated as markup, so there is no need to remove such things from arg[0]. These modes differ in what happens to & and to newlines, carriage returns and tabs. In mode 3, arg[0] is HTML.

Mode&Newlines, carriage returns and tabsText read back with HIPE_OP_GET_CONTENT
"0"Shown as typed.Not converted.The same as arg[0].
"1"Shown as typed.Converted: a newline becomes a line break, a carriage return an empty paragraph, a tab a wide space.Differs from arg[0]: the newlines and carriage returns are now elements, not characters, and each tab is a wide space character.
"2"Starts a character entity: &times; shows as ×, &amp; as &.Not converted.arg[0] with its entities replaced by the characters they stand for.
"3"Starts a character entity, as in mode 2.Not converted.The text of the elements arg[0] created. HIPE_OP_GET_CONTENT mode 1 returns them as HTML.

Mode 3: markup

  • arg[0] is HTML, and the tags and attributes in it are created as written, including class. Write a literal < or & in its text as &lt; or &amp;.
  • The markup stays inside the element: unclosed tags are closed at the end of arg[0], and a closing tag can't end the element itself.
  • To use an element later (request its events, set its attributes or source, get a frame key for an iframe, draw on a canvas), give it a location: write hipe-loc="N" on it with a number reserved by hipe_reserve_location(), and list the number in arg[2]. hipe_send_markup() does the listing for you. Other elements created this way have no location. See "Locations".
  • Tags that do nothing in a Hipe frame, such as script, do nothing here either. See "Tags, attributes and styles".

Where newlines and tabs are not converted (modes 0 and 2), how they look depends on the element. Most elements show any run of spaces, tabs and newlines as a single space, as HTML normally does. An element that keeps whitespace, such as a pre tag or one styled with white-space: pre, shows them as line breaks and tab stops.

Also in modes 0 and 2, a carriage return is stored as a newline, and a carriage return followed by a newline is stored as one newline.

In every mode, the character U+2029 starts a new paragraph, with a gap or an indent set by CSS, in any element. See "Paragraph breaks" on the "Tags, attributes and styles" page.

Which mode to use

  • Mode 0 for most text, and for any text that will be read back or edited and must come back the same, such as a source file shown in a pre tag. To show a symbol, put the character itself in the text: arguments are UTF-8. Also for the CSS of a style tag: modes 1 and 2 would change it.
  • Mode 1 for showing text you don't control, such as an error message or a command's output, in an ordinary element with its line breaks and tabs visible and no styling of your own.
  • Mode 2 for text you write yourself, where you want symbols by name, such as a calculator button labelled &times;. Don't use it for text that may contain & for any other reason: some older entity names are recognised without their closing semicolon, so &param shows as ¶m and &times, as ×,.
  • Mode 3 for formatted text sent in one instruction, such as syntax-highlighted code as span tags with classes, or HTML you already have.

Notes

Some tags like the input tag don't accept text directly. The input tag requires text to be supplied through a special value attribute. Use HIPE_OP_SET_ATTRIBUTE instead for such tags.

HIPE_OP_SET_TITLE

Instruction set reference

HIPE_OP_SET_TITLE

Sets the application title. The framing manager will usually display this to help the user identify the frame.
  • location: 0. Not used.
  •   arg[0]: Title string.

HIPE_OP_SRC_RETURN

Instruction set reference

HIPE_OP_SRC_RETURN

This instruction is sent back to the client from the server in response to a HIPE_OP_GET_SRC request.

  • location: the element the request was made on (echoed back).
  • arg[0]: on success, the binary source data. Absent/empty on failure.
  • arg[1]: on success, the data's MIME type (e.g. "image/png", "image/jpeg", "application/pdf"). Absent/empty on failure.
  • arg[2]: on failure, a human-readable error message (e.g. the element wasn't an img/canvas, or an img had no image data loaded yet). Absent/empty on success.
  • requestor: value passed back to client from the HIPE_OP_GET_SRC request.

HIPE_OP_STYLE_RETURN

Instruction set reference

HIPE_OP_STYLE_RETURN

This instruction is sent back to the client from the server in response to a HIPE_OP_GET_STYLE request.

  • location: the location of the element for which style data is being returned.
  • arg[0]: the name of the CSS property for which data was requested.
  • arg[1]: the resolved value of the property, as a string (e.g. "rgb(0, 0, 0)"). An empty string if the value could not be resolved.
  • requestor: value passed back to client from HIPE_OP_GET_STYLE request.

HIPE_OP_TAKE_SNAPSHOT

Instruction set reference

HIPE_OP_TAKE_SNAPSHOT

This instruction is used to generate either a vector (PDF or SVG) or raster (PNG) screenshot of the frame managed by the calling client. For example, a framing manager might include an event binding which responds to the Print Screen key by calling this instruction.

The snapshot captures the frame exactly as it appears on screen — at its full content size, as a single page, in screen media (so, for instance, drop shadows and screen-only stylesheet rules are preserved). In the PDF output, graphical elements can be zoomed without loss of clarity and text is embedded as selectable text rather than outlines.

The resulting screenshot data is not written to a file on disk. Instead, the image file data is streamed back to the calling client process, which can then write this to a file on disk as needed.

For security reasons, a client process cannot obtain screenshot data outside the frame it manages. Therefore, to obtain a screenshot of the entire screen, the framing manager that manages the entire screen would need to make the call.

  • location: not used. The whole frame is captured.
  • arg[0]: The required image format: "pdf" or "svg" for a vector screenshot, or "png" for a raster screenshot. Any other value is ignored.

Notes

The "svg" format has one known limitation: an element that has both a CSS gradient background and a plain border (one without rounded corners) loses its gradient in the output, and is drawn with no background. A gradient with no border, or with rounded corners and no border, is not affected, and nor are the "pdf" and "png" formats.

The image data will be sent back to your client application as a HIPE_OP_FILE_RETURN instruction.

HIPE_OP_TEXT_METRICS

Instruction set reference

HIPE_OP_TEXT_METRICS

Sent by the display server in response to a HIPE_OP_MEASURE_TEXT instruction. All values are in CSS pixels and may have up to two decimal places.

  • location: The element the text was measured in.
  • arg[0]: The width of the text (the widest line, if there are several).
  • arg[1]: The height of the text: the number of lines multiplied by the element's line height. For a single line, this is the line height itself, which is a convenient way to find out how tall each line of an element is.
  • arg[2]: The ascent of the font: the height above the baseline.
  • arg[3]: The descent of the font: the depth below the baseline.

Notes

If the text couldn't be measured (for example, the location doesn't refer to an element), all four arguments are empty.

HIPE_OP_TOGGLE_CLASS

Instruction set reference

HIPE_OP_TOGGLE_CLASS

Makes an element a member of the specified CSS class, or removes it if it is already a member.

  • location: the element to apply a CSS class to, or remove the CSS class from.
  •   arg[0]: The name of a CSS class corresponding to a CSS style rule you've created.

Notes

This instruction can be used in conjunction with predefined CSS style rules to modify the appearance and behaviour of an element quickly.

When assigning classes to location 0 (the body element), note that the body element is not initialised until the first piece of content is added to it. Applying a CSS class to the body before the document is initialised will produce undefined behaviour.

HIPE_OP_USE_CANVAS

Instruction set reference

HIPE_OP_USE_CANVAS

Sets the current active canvas to be used for drawing.

Note: Only the "2d" context type is supported (WebGL is not available). Requesting any other context type leaves this element with no active context, so subsequent HIPE_OP_CANVAS_ACTION/HIPE_OP_CANVAS_SET_PROPERTY instructions are silently ignored until a valid HIPE_OP_USE_CANVAS call is made. See HIPE_OP_CANVAS_ACTION and HIPE_OP_CANVAS_SET_PROPERTY for the drawing methods and properties available.

  • location: The canvas element to use as the current active drawing element.
  •     arg[0]: the canvas drawing context to be used (e.g. "2d"), as defined in HTML/CSS specifications.

HIPE_OP_X11_XID_RETURN

Instruction set reference

HIPE_OP_X11_XID_RETURN

This instruction is sent back to the client from the server in response to a HIPE_OP_GET_X11_XID request.

  • location: The <object> element for which the XID was requested.
  • arg[0]: The XID of the native X11 window the display server created for the element, as a decimal string. 0 if the element was not a suitable <object> element, or the server has no X11 embed-target support.
  • requestor: Returns back any user value that was passed in the client's original request.

Notes

Once you hold the XID, the embed target's lifetime is tied to the <object> element's renderer. To hide the embedded window temporarily, use visibility: hidden rather than display: none - the latter destroys the embed target and, with it, any foreign window reparented in. See HIPE_OP_GET_X11_XID for details.