OMERO(2)                                                 OMERO(2)

     NAME
          createpanel, createsubpanel, panelpath, openpanel,
          openpanelctl, closepanel, closepanelctl, seekpanel,
          readpanel, dirstatpanel, readallpanel, writepanel,
          readpanelctl, writepanelctl, omeroterm, omeroeventchan,
          clearoev, removepanel, panelctl, plumbexec, plumblook,
          evhistory, createport, createportproc - Omero graphical user
          interface library

     SYNOPSIS
          #include <u.h>
          #include <libc.h>
          #include <thread.h>
          #include <omero.h>

          struct Repl{
                     Repl*      next;      // in replica list
                     char*      path;      // e.g., "/n/.../row:2/slider:volume"
                     int        fd[2];     // data and ctl fds
          };
          struct Panel{
                     QLock;                // name is WORM, so mostly for repl.
                     char*      name;      // e.g., "slider:volume"
                     Repl*      repl;      // known replicas
                     int        nrepl;
                     Channel*evc;          // events here or through oeventchan(nil)
                     ...
          };

          Panel*                createpanel(char* name, char* type, char* omero);
          Panel*                createsubpanel(Panel* g, char* name);
          char*                 panelpath(Panel*);
          int                   openpanel(Panel* g, int omode);
          int                   openpanelctl(Panel* g);
          void                  closepanel(Panel* g);
          void                  closepanelctl(Panel* g);
          vlong                 seekpanel(Panel*g, vlong pos, int type);
          long                  readpanel(Panel* g, void* buf, long len);
          Dir*                  dirstatpanel(Panel* g);
          void*                 readallpanel(Panel* g, long* l);
          long                  writepanel(Panel* g, void* buf, long len);
          long                  readpanelctl(Panel* g, void* buf, long len);
          long                  writepanelctl(Panel* g, void* buf, long len);
          void                  omeroterm(void);
          Channel*              omeroeventchan(Panel* g);
          void                  clearoev(Oev* e);
          void                  removepanel(Panel* g);
          int                   panelctl(Panel* g, char* fmt, ...);

          int                   plumbexec(char* dir, char* arg);

     OMERO(2)                                                 OMERO(2)

          int                   plumblook(char* dir, char* arg);
          void                  evhistory(char* prg, char* ev, char* arg);
          Channel*              createportproc(char* port);
          int                   createport(char* name);

          extern char*appluiaddress;
          extern int omerodebug;

     DESCRIPTION
          These functions provide a convenient application interface
          for using omero(4) to build user interfaces for Plan B
          applications.  The application must be programmed using
          thread(2) if this library is used.

          Each omero panel is represented by a Panel data structure,
          where Name is the file name (not the full path) for the
          panel in the omero file system.  Repl is the list of of
          copies known for the panel. Each once is called a replica.
          For each replica, path is the absolute path for its file in
          omero, when it is mounted at the standard mount point
          /devs/$sysnameui.

          The library creates processes to service events from omero
          and handles replication of omero panels by itself. Different
          copies of the same panel are kept synchronized by the
          library. When the application updates a panel, the library
          updates all known replicas. When a panel reports a data
          change through event delivery, the library pulls the data,
          updates other replicas, and delivers the event to the appli-
          cation. The library handles in the same way the creation,
          deletion, and control operations for graphs within repli-
          cated interfaces.

          If the omero file tree for a given replica is not mounted,
          the library attempts to mount it at its standard mount point
          when it is first seen.  Regarding failure, an error at a
          replica causes it to be removed from the replica list and a
          failed operation at all the known replicas is considered to
          be failed.  A panel is considered to be gone if all its
          replicas are gone.

          The library assumes that the file name (not the path) for a
          given panel is unique. Events sent by omero carry the path
          for the panel and are used to determine which panels are
          affected. The name determines the graph, and the full path
          determines the replica. When omero reports that a panel
          moved, was created, or was deleted, the library updates the
          set of replicas.

          Createpanel initializes the library, if not yet initialized,
          mounts omero if necessary, and starts an event listener. The
          function creates a top-level panel for the application  with

     OMERO(2)                                                 OMERO(2)

          the name specified as an argument. The name is randomized by
          the function. The parameter type argument is usually the
          string col and determines the type of panel created.  The
          panel is kept in hold mode and its control file is open and
          programed with the application address before returning to
          the user.  See omero(4) for an exhaustive list of panel
          types and more details about their behaviour.

          Createsubpanel behaves in a similar way, but creates the
          named panel within the one passed as a parameter. Unlike
          createpanel this function does not set the panel in hold
          mode and does not open its control file.

          Panelpath returns the path for the directory representing
          the first replica found for the panel.

          Openpanel opends the data file(s) for the panel (there is
          one file per replica).  Openpanelctl does the same for the
          control file(s).  Closepanel and closepanelctl are the
          respective close operations.

          While open, seekpanel, readpanel, and writepanel can be used
          to seek, read, and write the panel data file.  Readpanelctl,
          and writepanelctl do the same for the control file. Also,
          panelctl permits formatted output to the control file.

          Dirstatpanel returns a stat(2) structure (unpacked) for the
          data file of the first replica of the panel.

          As a convenience, readallpanel returns all the contents of
          the data file for the panel.

          Removepanel deletes a panel (i.e. all its replicas).

          Omeroterm terminates any user interface created by the
          library and kills any process started by the library (to
          receive and process events).

          Omeroeventchan returns a channel where events from omero are
          sent. When its parameter is nil, a global channel is
          returned. When the parameter is a panel, the routine ini-
          tializes the panel's evc field with a channel where events
          for that panel are sent.

          Events are represented by Oev structures that contain the
          event name, ev, and event arguments, arg. The panel and path
          to the replica generating the event are initialized before
          delivering the event to the user.
          struct Oev {
                     Panel*     panel;
                     char*      path;      // to repl
                     char*      ev;

     OMERO(2)                                                 OMERO(2)

                     char*      arg;
          };
          Once used, event resources are to be deallocated by calling
          clearoev. This is important because it may lead to (already
          removed) panels to be destroyed.

          When the last replica for the application's interface is
          known to be gone, the user routine omerogone is called. This
          routine must be provided by all applications using this
          library.  It usually terminates the application. If the
          application wants to stay running and stay listening to fur-
          ther omero connections, it should return zero.

          Plumbexec and plumblook are helper routines to make the user
          interface respond to execution and looking up requests in a
          similar way to ox (1) and other omero applications. They
          send arg to portfs(4) as either exec or look requests.

          Portfs ports can be created using createport and supplying
          the name for the port file (basename only). Instead of cre-
          ating the port and servicing it by hand, createportproc
          returns a channel where Plumbmsg* elements are forwarded as
          they are obtained by a process that creates and serves the
          port. This is more convenient, but requires using the thread
          library and does not permit a fine control over the ports.

          Evhistory updates the omero event history for the user. It
          receives the program name, the event name and its argument.

     EXAMPLES
          See oclock(1) for a simple example that does not require
          user interaction, and ox(1) for a more elaborate example
          that includes user input.

     SOURCE
          /sys/src/libomero

     SEE ALSO
          omero(4) and ox(1),

     DIAGNOSTICS
          These functions set errstr.

     BUGS
          This service is still evolving. Expect changes.