.\"## .\" $Xorg: api.pg,v 1.3 2000/08/17 19:42:16 cpqbld Exp $ .\"## .\"## $XMCOPY .\"## Copyright (c) 1990, 1991 by Sun Microsystems, Inc. .\"## .\"## All Rights Reserved .\"## .\"## Permission to use, copy, modify, and distribute this software and its .\"## documentation for any purpose and without fee is hereby granted, .\"## provided that the above copyright notice appear in all copies and that .\"## both that copyright notice and this permission notice appear in .\"## supporting documentation, and that the name of Sun Microsystems, .\"## not be used in advertising or publicity .\"## pertaining to distribution of the software without specific, written .\"## prior permission. .\"## .\"## SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, .\"## INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO .\"## EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR .\"## CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF .\"## USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR .\"## OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\"## PERFORMANCE OF THIS SOFTWARE. .H C "Porting the PEX-API" .H 2 "General Porting Concerns" .BP The routine \fIsocketpair()\fR , used in \fL\s-1mit/extensions/lib/PEX/cp/cp_ccom.c\fR\s+1 is not available on all System V systems. .BP A combination of \fIsocket()\fR, \fIbind()\fR, \fIlisten()\fR, \fIconnext()\fR, and \fIaccept()\fR may be used to provide the equivalent of \fIsocketpair()\fR. .LP .H 2 "Customizing" .H 3 "Using UNIX Sockets or Shared Memory" .LP The compiler symbol \s-1PEX_API_SOCKET_IPC\s+1 controls how the client process communicates with the \s-1PM\s+1. If the symbol is defined when the \s-1API\s+1 is built, \s-1UNIX\s+1 sockets are used. If the symbol is not defined, System V shared memory is used. The symbol can be defined in the \fI.cf\fR file (for example, \fL\s-1sun.cf\s+1\fR) found in the \s-1X\s+1 source tree \fL\s-1config\fR\s+1 directory. .H 3 "Changing Implementation-Dependent Parameters" .LP .IX "PEXGetEnumeratedTypeInfo" "" "\s-1PEXGetEnumeratedTypeInfo\s+1" .IX "PEXGetImpDepConstants" "" "\s-1ImpDepConstants\s+1" Most of the implementation-dependent parameters depend on the capabilities of the server. The \s-1PEX\s+1 inquiries \s-1PEXGetEnumeratedTypeInfo\s+1 and \s-1PEXGetImpDepConstants\s+1 are used to ``get'' these capabilities. The Workstation Description Table (\s-1WDT\s+1) manual page describes how each of the implementation-dependent parameters are determined. .H 3 "Workstation Capabilities" .LP Workstation \s-1DC\s+1 limits correspond to the window size of the window used by the \s-1PHIGS\s+1 workstation. The units are drawable coordinates. When the \s-1API\s+1 responds to a window resize event, more or less of the window will be exposed; the \s-1PHIGS\s+1 output will not be scaled. .LP The application accesses the \s-1API\s0-defined \s-1WDT\s+1 information using the functions \fIphigs_ws_type_set()\fR and \fIphigs_ws_type_get()\fR. New workstation types can be created with the function \fIphigs_ws_type_create()\fR and destroyed with the function \fIphigs_ws_type_destroy()\fR. See the \fIPEX-SI Graphics Library Manual Pages\fR for a full description of these functions. .KS .H 4 "Opening Workstations" .IX "Workstations" "opening" .IX "Workstation Functions" "popen_ws" .IX "Functions" "popen_ws" .LP Workstations are opened with the following function: .ta 0.5i 1.5i 3.0i .nf (void)popen_ws(ws_id, conn_id, ws_type) Pint ws_id; /*workstation identifier */ char *conn_id; /* connection identifier */ Pint ws_type; /* workstation type */ .fi .KE .LP \fIws_id\fR is the application-chosen identifier of the workstation. \fIws_type\fR is the workstation type to open. For tool workstation types, \fIconn_id\fR is either \s-1NULL\s+1 or contains the name of the display to open the workstation on. For drawable workstation types, \fIconn_id\fR is a pointer to a structure containing the display pointer and drawable identifier of the drawable to use for the \s-1PHIGS\s+1 workstation. .LP .IX "Workstations" "generic, API" .IX "generic workstations, API" The \s-1API\s+1 provides two generic workstation types:\ \ \fIphigs_ws_type_x_tool\fR and \fIphigs_ws_type_x_drawable\fR. The \s-1PHIGS\s+1 function, \s-1OPEN WORKSTATION\s+1 will create a new \s-1X\s+1 window for the \fItool\fP type. Use of the \fIdrawable\fP type requires that the application also pass a drawable identifier as part of the connection id parameter to the \s-1PHIGS\s+1 function \s-1OPEN WORKSTATION\s+1. This drawable is used as the output drawable of the \s-1PHIGS\s+1 workstation. .LP .IX "PEXGetEnumeratedTypeInfo" "" "\s-1PEXGetEnumeratedTypeInfo\s+1" .IX "PEXGetImpDepConstants" "" "\s-1PEXGetImpDepConstants\s+1" .IX "PEXGetTableInfo" "" "\s-1PEXGetTableInfo\s+1" The \s-1API\s+1 uses the \s-1PEX\s+1 inquiries \s-1PEXGetEnumeratedTypeInfo\s+1, \s-1PEXGetImpDepConstants\s+1, \s-1PEXGetTableInfo\s+1, etc., to determine \s-1PEX\s+1 capabilities, using the root window of the display as the drawable id parameter to these requests. .H 4 "Workstation Type Creation and Modification" .IX "Workstations" "creation" .IX "Workstations" "modification" .LP New generic workstation types can be created with \fIphigs_ws_type_create()\fR and existing ones can be modified with \fIphigs_ws_type_set()\fR. .H 4 "Modifying a WDT to Correspond to a Particular Display" .LP Two \s-1WDT\s+1 attributes are defined to assist in building workstation types for specific displays:\ \ \s-1PHIGS_X_DISPLAY\s+1 and \s-1PHIGS_X_DISPLAY_NAME\s+1. These attributes can be specified in the \fIattributes\fR parameter of the functions \fIphigs_ws_type_create()\fR and \fIphigs_ws_type_set()\fR, and will cause all the fields in the augmented \s-1WDT\s+1 to be modified to correspond to the capabilities of the specified display (specified either by a display pointer or display name), assuming that display can be opened and contains a \s-1PEX\s+1 extension. The display name will be stored in the \s-1WDT\s+1. .RE .H 2 "Areas for Optimization" .LP If you are interested in optimizing \s-1PEX-API\s+1, you should consider the following areas. .H 3 "Structure Storage" .LP In \s-1PHIGS\s+1 the Central Structure Store (\s-1CSS\s+1) appears to the application as one database located somewhere within the \s-1PHIGS\s+1 implementation. The \s-1CSS\s+1 is independent of any \s-1PHIGS\s+1 workstations so it exists regardless of whether or not any \s-1PHIGS\s+1 workstations are open. When a \s-1PHIGS\s+1 structure is created there is no indication of which, if any, workstations will eventually display the structure. The application can create many structures that all appear on many different workstations, each of which may exist on a different display, or it can be selective and have each structure appear on only one workstation or just a few workstations. .LP The \s-1API\s+1 keeps one full copy of the \s-1CSS\s+1 on some server and keeps full copies on all servers with open workstations. All \s-1CSS\s+1 operations requested by the application are broadcast to all servers holding a copy of the \s-1CSS\s+1. One of those servers is designated the main \s-1CSS\s+1 server and it holds the \s-1CSS\s+1 even when there are no workstations open on that server. .LP The \s-1API\s+1 selects the main \s-1CSS\s+1 server when \s-1OPEN PHIGS\s+1 is called. The application can specify the server that will hold the \s-1CSS\s+1 for the duration of the \s-1PHIGS\s+1 session if it opens \s-1PHIGS\s+1 with the \s-1OPEN XPHIGS\s+1 function. The default is the server indicated by the \s-1DISPLAY\s+1 environment variable. The \s-1CSS\s+1 is copied to other servers when workstations are first opened on them, and each copy is destroyed when the last workstation on the server is closed. .H 3 "Dealing with Partial PEX Support" .LP \s-1PEX\s+1 defines three levels of support that a server can provide:\ \ the Immediate Rendering Only Subset, the \s-1PHIGS\s+1 Workstation Only subset and Full \s-1PEX\s+1, which provides both the subsets. Both subsets provide the needed support for a \s-1PHIGS\s+1 client. .LP The \s-1API\s+1 is capable of utilizing either of these subsets, automatically and without any direction from the user. When it connects to a server, either during \s-1OPEN PHIGS\s+1, \s-1OPEN XPHIGS\s+1 or \s-1OPEN WORKSTATION\s+1, the \s-1API\s+1 inquires what level of \s-1PEX\s+1 is supported. If Full \s-1PEX\s+1 or the Workstation Only subset is supported the \s-1API\s+1 will use \s-1PHIGS\s+1 workstation resources and server structure storage on that server. If only the Immediate Rendering subset is supported the \s-1API\s+1 will use its own implementation of \s-1PHIGS\s+1 workstations and will maintain a copy of the \s-1CSS\s+1 itself. This copy is used for all workstations on that server and any other server that supports only the Immediate Rendering subset. .LP If the main \s-1CSS\s+1 server only supports the Immediate Rendering subset, then the main copy of the \s-1CSS\s+1 will reside in the \s-1API\s+1. This main \s-1CSS\s+1 is treated similarly to a server-based main \s-1CSS\s+1, except that it does not exist in a server. \s-1CSS\s+1 copies are still made on the server when workstations are opened on servers that support \s-1PEX\s+1 structure storage, but the \s-1CSS\s+1 in the \s-1API\s+1 remains the main \s-1CSS\s+1. .LP Maintaining a main \s-1CSS\s+1 in the \s-1API\s+1 is called client-side structure storage. The \s-1API\s+1 allows applications to force client-side structure storage even though \s-1PEX\s+1 structure storage is available, but this is only a feature useful for testing that configuration. Using client-side structure storage is too slow to be preferable when server structure storage is available. .H 3 "Display Connections" .LP The \s-1API\s+1 does not always use the display connection\** .FS A ``display connection'' in this paper means the display pointer returned by \s-1XOpenDisplay\s+1. .FE specified when a workstation is opened. To avoid synchronization problems the \s-1API\s+1 maintains only one connection to any server. This ensures that \s-1PEX\s+1 \s-1CSS\s+1, \s-1PEX\s+1 workstation and Xlib requests issued by the \s-1API\s+1 are processed by the server in the right order. (Recall that the single \s-1CSS\s+1 on a server will serve all the workstations on that server.) .LP When a workstation is opened the \s-1API\s+1 first checks to see if it already has a connection to the specified server. If it does then it uses that connection even if a different connection was specified by the application in the \s-1OPEN WORKSTATION\s+1 call. If it does not, then the \s-1API\s+1 uses the specified connection to the new server for all subsequent requests to that server. This requires some cooperation on the application's part:\ \ the application cannot close that connection until the \s-1API\s+1 is done using it. The \s-1API\s+1 is done using a connection when all workstations on that server are closed, except when the server is the main \s-1CSS\s+1 server. If the application does not specify a connection, but only specifies a server name, and the \s-1API\s+1 does not already have a connection to the named server, the \s-1API\s+1 creates a new connection and uses it for all subsequent requests to that server. All server connections the \s-1API\s+1 opens are closed when no more workstations exist on that server, unless that server is the main \s-1CSS\s+1 server. .LP In all cases the server specified by the application must support some subset of the \s-1PEX\s+1 extension. The \s-1API\s+1 will not open workstations on servers that do not support \s-1PEX\s+1. .LP The application can specify the display connection for the main \s-1CSS\s+1 server when \s-1PHIGS\s+1 is opened. It does this by calling the \s-1API\s+1's alternative \s-1OPEN PHIGS\s+1 function, \s-1OPEN XPHIGS\s+1. \s-1OPEN XPHIGS\s+1 accepts a variety of X-related information that helps the \s-1API\s+1 ``do the right thing'' in the X environment. \s-1OPEN XPHIGS\s+1 also performs the same operations as \s-1OPEN PHIGS\s+1. .LP If the application wants the \s-1API\s+1 to share the application's connection for workstations that will subsequently be opened on the main \s-1CSS\s+1 server, it must specify that connection to \s-1OPEN XPHIGS\s+1. Otherwise the \s-1API\s+1 will create its own connection to the main \s-1CSS\s+1 server when \s-1PHIGS\s+1 is opened, and will use that connection for all workstations opened on that server, regardless of connections to that server specified in the \s-1OPEN WORKSTATION\s+1 call. .LP If the specified main \s-1CSS\s+1 server does not support \s-1PEX\s+1 structure storage, the \s-1API\s+1 does not maintain a connection to it after \s-1PHIGS\s+1 is opened. Structure storage is in the client in this case so there is no need for a server connection for \s-1CSS\s+1 storage. .LP .H 3 "The \fLmit/extensions/lib/PEX\fP Subdirectories\fR" There are eleven subdirectories that contain code and one that contains run-time files. .IP \fL\s-1archive\s+1\fR 14 Contains the code for reading and writing archive files. .IP \fL\s-1c_binding\s+1\fR 14 Contains the C binding code. All the public entry points are in this code. .IP \fL\s-1cp\s+1\fR 14 Contains the \s-1CP\s+1 and PHIGS state list code (see below). There are different sets of code used for client-side structure storage and server-side structure storage. Some of the code used in the client is also different from the code used in the \s-1PM\s+1. The function and file prefixes indicate the code usage: .DS .ta +.5i cpa_ Code for server-side structure storage cpb_ Code for client-side structure storage cpx_ Top level \s-1CP\s+1 code used in both the client and the \s-1PM\s+1 cpm_ \s-1CP\s+1 code used only in the \s-1PM\s+1 psl_ PHIGS state list code .DE There are also four files prefixed only with cp_: .DS .ta +1i cp_ccom.c Code used only in client for communicating with the \s-1PM\s+1 cp_rcom.c Code used only in \s-1PM\s+1 for communicating with the client cp_com.c Communication code used by both the client and the \s-1PM\s+1 cp_util.c Utility code potentially used in both the client and the \s-1PM\s+1 .DE .IP The \s-1PM\s+1 program is also in this directory in the file \fL\s-1phigsmon.c\fR\s+1. .IP \fL\s-1css\s+1\fR 14 Contains the central structure store code for client-side structure storage. .IP \s-1\fLerror\s+1\fR 14 Contains the error handling code. This code is invoked by potentially all of the modules. .IP \s-1\fLinclude\s+1\fR 14 The \s-1API\s+1's header files. .IP \fL\s-1input\s+1\fR 14 Contains the input device code. .IP \fL\s-1lib\s+1\fR 14 Contains the run-time files. .IP \fL\s-1pex\s+1\fR 14 Contains the \s-1PEX\s+1 protocol library used to build and send \s-1PEX\s+1 requests. .IP \fL\s-1util\s+1\fR 14 Contains general purpose utility functions. .IP \fL\s-1ws\s+1\fR 14 Contains the workstation code. There are different sets of code used for client-side structure storage and server-side structure storage. Some of the code used in the client is also different from the code used in the \s-1PM\s+1. The function and file prefixes indicate the code usage: .DS .ta +.5i wsa_ Code used only for server-side structure storage wsb_ Code used only for client-side structure storage wsx_ Utility code potentially used by all workstation functions .DE If a function or file also has the sequence \fIpm\fR in its name then it contains code used only in the \s-1PM\s+1. There are also two files with only a ``\fIws_\fR'' prefix:\ \ \s-1\fLws_inp.c\s+1\fR and \fL\s-1ws_pm.c\s+1\fR. \fL\s-1ws_inp.c\s+1\fR contains the workstation input device control code. It is used only in the \s-1PM\s+1. \fL\s-1ws_pm.c\s+1\fR contains code specific to the \s-1PM\s+1. .IP \fL\s-1ws_type\s+1\fR 14 Contains the code for building and modifying workstation description tables. .H 3 "The Importance of Keeping the Code Organization" .LP The code is carefully partitioned among the files in a way that prevents the client from having to link with X toolkit or Athena Widget set code. The files that reference toolkit code are kept separate and are only included by a reference from the \s-1PM\s+1 main program in \fL\s-1cp/phigsmon.c\fR\s+1. Files with \fIpm\fR in their name are only included in the \s-1PM\s+1, not the client. When adding code you must be careful not to add any references to these files from code that will run in the client. If this does happen then the linker will complain of unresolved references to \fIXt\fR or \fIXaw\fR symbols when attempting to link a PHIGS application program. .H 3 "Important Modules and Data Structures" .H 4 "The CP" .LP The \s-1CP\s+1 module is the heart of the \s-1API\s+1. It is responsible for coordinating the other modules. The binding functions call the \s-1CP\s+1, the \s-1CP\s+1 then calls other modules to execute their part of the \s-1PHIGS\s+1 function. All the \s-1CP\s+1 code is in the \fL\s-1cp\fR\s+1 subdirectory. .LP The data structure for the \s-1CP\s+1 is \fICp_struct\fR (see \fL\s-1cp.h\fR\s+1). It contains state and control info and a function vector. One \s-1CP\s+1 is maintained in the client and one in the \s-1PM\s+1. The function vector is loaded with pointers to \s-1CP\s+1 functions when \s-1PHIGS\s+1 is opened. The function vector for the \s-1CP\s+1 in the client and the \s-1CP\s+1 in the \s-1PM\s+1 are loaded differently. .LP The \s-1CP\s+1 functions call \fIcss_srvr\fR functions (see below), or in a few cases just do the work or gather the inquiry information themselves. The \s-1CP\s+1 functions are in the files in the \fL\s-1cp\fR\s+1 subdirectory with the \fIcpx\fR prefix. .H 4 "CSS Servers" .LP \s-1CSS\s+1 servers maintain a structure store for all workstations that use it. There is a \fIcss_srvr\fR for every copy of the CSS maintained. The list of \fIcss_srvr\fR structures is attached to the \s-1CP\s+1 structure. .LP The \fICpx_css_srvr\fR (see \fL\s-1cpx.h\fR\s+1) data structure contains state information and a function vector. The function vector is loaded differently for client-side structure storage and server-side structure storage. These functions are called by the \fIcpx\fR functions of the \s-1CP\s+1. .LP Some \fIcss_srvr\fR functions are carried out in the \s-1PM\s+1 if the \s-1PM\s+1 is being used. The \fIcss_srvr\fR functions for these cases send the \s-1PM\s+1 a function code and any data needed and the \s-1PM\s+1 performs the function and sends back any return data. For server side structure storage there are only a few of these functions. For client-side structure storage almost all \fIcss_srvr\fR functions are executed in the \s-1PM\s+1. (For more information see Section .XR @NumberOf(paths).) .LP \fIcss_srvr\fR structures are maintained in both the client and the \s-1PM\s+1 when the \s-1PM\s+1 is used. For client-side structure storage the \fIcss_srvr\fR in the client is loaded with functions that send the information to the \s-1PM\s+1. The functions in the \fIcss_srvr\fR in the \s-1PM\s+1 carry out the work. For server-side structure storage the \fIcss_srvr\fR in the \s-1PM\s+1 is only partially loaded with the functions that are executed in the \s-1PM\s+1. .LP If the \s-1PM\s+1 is not used, there is no client-side structure storage. .H 4 Workstations .LP The workstation structure (\fIWs\fR in \fL\s-1ws.h\s+1\fR) maintains workstations. There is a workstation structure for each open workstation. This structure contains workstation state and a function vector. The function vector is loaded differently for client-side and server-side structure storage. .LP All access to the workstation function vector is through its parent \fIcss_srvr\fR. .LP Workstation operations are executed in the \s-1PM\s+1 when the \s-1PM\s+1 and client-side structure storage are being used, otherwise workstation operations are carried out in the client. Workstation structures are maintained in both the client and the \s-1PM\s+1 in the former case, but not all the state is maintained in the client version. .H 4 "Workstation Description Table" .LP The \fIWst\fR structure (see \fL\s-1ws_type.h\s+1\fR) contains the workstation description table and some other information for each workstation type. Duplicate copies of a workstation's specific description table are kept in both the client and the \s-1PM\s+1 when the \s-1PM\s+1 is being used. .H 3 "Paths Through the Code" paths .LP \s-1PHIGS\s+1 functions can take many paths through the code. The path is determined by the structure storage used and whether the \s-1PM\s+1 is running. The major paths are listed below. In all cases the binding calls one of the client-side \s-1CP\s+1 functions. The \s-1CP\s+1 function then calls the appropriate entry in the \fIcss_srvr\fR function vector. For CSS functions the \s-1CP\s+1 calls this entry in all \fIcss_srvr\fRs. For \s-1PHIGS\s+1 workstation functions the \s-1CP\s+1 calls only the \fIcss_srvr\fR associated with the workstation. .LP The function vector of each \fIcss_srvr\fR is loaded according to the structure storage and \s-1PM\s+1 configuration in effect. Each function in the vector knows what it is to do for the given configuration. .IP "\fIServer-side structure storage, \s-1PM\s+1 is running\fR" The binding calls the client-side \s-1CP\s+1 function. The \s-1CP\s+1 function calls the appropriate \fIcss_srvr\fR function. The \fIcss_srvr\fR function sends the needed \s-1PEX\s+1 request to the server. If the \s-1PHIGS\s+1 function is related to \s-1PHIGS\s+1 input, \s-1MESSAGE\s+1 or the \s-1REDRAW REGIONS\s+1 escape the \fIcss_srvr\fR does not issue a \s-1PEX\s+1 request from the client but instead sends a command to the \s-1PM\s+1. The \s-1PM\s+1 executes the function, which may require sending a \s-1PEX\s+1 request to the server. .IP "\fIServer-side structure storage, \s-1PM\s+1 is not running\fR" Same as the non-\s-1PM\s+1 case except that a command is not sent to the \s-1PM\s+1. \s-1PHIGS\s+1 input and \s-1MESSAGE\s+1 are not available and the \s-1REDRAW REGIONS\s+1 escape is serviced in the client. .IP "\fIClient-side structure storage, \s-1PM\s+1 is running\fR" The binding calls the client-side \s-1CP\s+1 function. The \s-1CP\s+1 function calls the appropriate \fIcss_srvr\fR function. The \fIcss_srvr\fR function sends the appropriate command to the \s-1PM\s+1. The \s-1PM\s+1 executes the function, which may require sending a \s-1PEX\s+1 request to the server. .IP "\fIClient-side structure storage, \s-1PM\s+1 is not running\fR" The binding calls the client-side \s-1CP\s+1 function. The \s-1CP\s+1 function calls the appropriate \fIcss_srvr\fR function. The \fIcss_srvr\fR function performs the requested action, which may require sending a \s-1PEX\s+1 request to the server. \s-1PHIGS\s+1 input and \s-1MESSAGE\s+1 are not available and the \s-1REDRAW REGIONS\s+1 escape is serviced in the client. .IP "\fIThe path in the PM\fR" The \s-1PM\s+1 has a \s-1CP\s+1 just as the client does. The \s-1PM\s+1 communication code gets commands from the client and calls the appropriate \s-1CP\s+1 function (just like the binding in the client calls the \s-1CP\s+1 in the client). The \s-1CP\s+1 then calls the \fIcss_srvr\fRs involved. .IP "\fIWorkstation operations\fR" In the server-side structure storage case most workstation operations are performed in the \fIcss_srvr\fR functions in \fL\s-1cpa_ws.c\s+1\fR. In the other case, however, workstation operations are performed by the functions in the workstation's function vector. These functions are called by the \fIcss_srvr\fR. .IP "\fINon-css_srvr functions\fR" The \s-1PHIGS\s+1 functions \s-1AWAIT EVENT\s+1, \s-1FLUSH DEVICE\s+1, \s-1INQUIRE INPUT QUEUE OVERFLOW\s+1 and \s-1INQUIRE MORE SIMULTANEOUS EVENTS\s+1 do not go through a \fIcss_srvr\fR. They go directly to the \s-1PM\s+1 if the \s-1PM\s+1 is running. The \s-1CP\s+1 calls the communication routines that send the command and data to the \s-1PM\s+1. The \s-1CP\s+1 in the \s-1PM\s+1 then executes them directly. .H 3 "Adding Operations" .LP Adding a new operation generally requires that function vector entries and functions be added for each of the above paths through the code. The steps involved are listed here. .IP "\fIExtend the Binding\fR" Add a binding function for the user to call. This can be either a new function or it can be an escape. Escapes should be used whenever possible. Adding new functions may violate \s-1PHIGS\s+1 conformance. .IP Escapes are added by defining an escape code and the escape input and output data structures in \fL\s-1phigs.h\fR\s+1, and adding an escape function to the others in \fL\s-1c_binding/cb_esc.c\fR\s+1. .IP All data is passed from the binding to the \s-1CP\s+1 via the \fIPhg_args\fR structure. All data is passed back from the \s-1CP\s+1 to the binding via the \fIPhg_ret\fR structure. If the new operation involves data then \fIPhg_args\fR may need to be expanded to handle it. \fIPhg_args\fR is defined in \fL\s-1include/phgargs.h\fR\s+1. It contains data fields for each existing \s-1PHIGS\s+1 operation. Many of the existing operations use the generic \fIidata\fR and \fIfdata\fR fields. If the new operation returns data then \fIPhg_ret\fR may also need expansion. \fIPhg_ret\fR is defined in \fL\s-1include/phgretdata.h\fR\s+1. .IP It is important to keep these data structures small. The whole \fIPhg_args\fR data structure is copied beteween the client and the \s-1PM\s+1 when the operation is sent to the \s-1PM\s+1. A large \fIPhg_args\fR structure will slow down all operations that use the \s-1PM\s+1. The size is kept relatively small by using indirection. The client-to-\s-1PM\s+1 communication code knows how to copy indirect data to the \s-1PM\s+1 after it sends the \fIPhg_args\fR structure. .IP "\fIExtend the CP\fR" Add a new \fIop\fR code to \fL\s-1include/cp_ops.h\fR\s+1. .IP Add a new \s-1CP\s+1 function to the appropriate \fL\s-1cp/cpx_*\fR\s+1 file, either \fL\s-1cpx_css.c\s+1\fR, \fL\s-1cpx_ws.c\s+1\fR, \fL\s-1cpx_ar.c\s+1\fR or \fL\s-1cpx_misc.c\s+1\fR. This function will dispatch to the \fIcss_srvr\fR's. It will be used in both the client and the \s-1PM\s+1. If the client-side function must be different from the \s-1PM\s+1 function then put the client-side function in \fL\s-1cpx_clnt.c\s+1\fR and the \s-1PM\s+1 function in \fL\s-1cpx_pm.c\s+1\fR. Declare the added function or functions extern in \fL\s-1cpx.h\fR\s+1. .IP Load the new \s-1CP\s+1 function vector entry in the function \fIcpx_load_funcs()\fR in \fL\s-1cpx_clnt.c\s+1\fR. The function to assign the new entry is the \fIcpx_\fR function added in the previous step. There is a section at the bottom of the function for entries that must be loaded differently depending on whether or not the \s-1PM\s+1 is running. .IP Load the new \s-1CP\s+1 function vector entry in the function \fIcpm_load_funcs()\fR in \fL\s-1cpx_pm.c\s+1\fR. In most cases the function vector entry will be assigned the same function it was assigned in \fL\s-1cpx_clnt.c\s+1\fR. .IP "\fIExtend the css_srvr\fR" Add a new function vector entry to the \fICpx_css_srvr\fR structure (see \fL\s-1cpx.h\fR\s+1). .IP Add new \fIcss_srvr\fR functions to the appropriate \fL\s-1cp/cpa_\fR\s+1 and \fL\s-1cp/cpb_\fR\s+1 files, either \fL\s-1cpa_css.c\s+1\fR or \fL\s-1cpa_ws.c\s+1\fR, and \fL\s-1cpb_css.c\s+1\fR or \fL\s-1cpb_ws.c\s+1\fR. These functions will service the \s-1PHIGS\s+1 function for their respective structure storage configuration. They will be used in both the client and the \s-1PM\s+1. If a client-side function must be different from the \s-1PM\s+1 function then put the client-side function in \fL\s-1cp{a,b}_clnt.c\s+1\fR and the \s-1PM\s+1 function in \fL\s-1cp{a,b}_pm.c\s+1\fR. Declare the added functions extern in \fL\s-1cpa.h\fR\s+1 and \fL\s-1cpb.h\fR\s+1. .IP Load the new \fIcss_srvr\fR function vector entry in the \fIload_funcs()\fR functions in the files \fL\s-1cpa_clnt.c\s+1\fR, \fL\s-1cpa_pm.c\s+1\fR, \fL\s-1cpb_clnt.c\s+1\fR and \fL\s-1cpb_pm.c\s+1\fR. There is a section at the bottom of \fIcpa_load_funcs()\fR in \fL\s-1cpa_clnt.c\s+1\fR for loading the vector differently depending on whether or not the \s-1PM\s+1 is running. In \fL\s-1cpb_clnt.c\s+1\fR this is done with a separate function for each case. When the \s-1PM\s+1 is running, almost all \fIcpb css_srvr\fR functions are sent to the \s-1PM\s+1 for execution, so the function vector is loaded almost entirely with the client-to-\s-1PM\s+1 communication routines. When the \s-1PM\s+1 is not running the \fIcpb\fR function vector is loaded directly with \fIcpb\fR functions. The \fIcpa\fR function vector varies little for the \s-1PM\s+1/no-\s-1PM\s+1 cases. Most \fIcpa\fR functions are executed in the client even when the \s-1PM\s+1 is running. .IP To determine the client-to-\s-1PM\s+1 communication routine to use look at their definition in \fL\s-1cp_ccom.c\s+1\fR. There are seven of them, each for a different combination of sending and receiving data between the client and the \s-1PM\s+1. They are named \fIphg_cpc_class_{\s-1B,C,D,E,CD,CE,SPECIAL\s+1}\fR. If the operation involves variable length data or otherwise requires indirection in the \fIPhg_args\fR of \fIPhg_ret\fR structures then the data copying functions in \fL\s-1cp_ccom.c\s+1\fR and \fL\s-1cp_rcom.c\s+1\fR must be extended. The functions to extend are \fIcpc_send_pre_data()\fR (\fL\s-1cp_ccom.c\s+1\fR) and \fIcpr_get_pre_data()\fR (\fL\s-1cp_rcom.c\s+1\fR) for \fIPhg_args\fR data, and \fIcpr_send_post_data()\fR (\fL\s-1cp_rcom.c\s+1\fR) and \fIcpc_get_post_data\fR (\fL\s-1cp_ccom.c\s+1\fR) for \fIPhg_ret\fR. .IP Load the \fIcss_srvr\fR function vector entries in the \fIload_funcs()\fR functions in \fL\s-1cpa_pm.c\s+1\fR and \fL\s-1cpb_pm.c\s+1\fR. This may not be necessary for the \fIcpa\fR case, and is only required for \fIcpa\fR operations that will execute in the \s-1PM\s+1, such as input operations. It is almost always necessary for the \fIcpb\fR case, since almost all operations are executed in the \s-1PM\s+1 when client-side structure store is used. .IP "\fIExtend the Workstation\fR" If the new operation is a workstation operation then add a new function vector entry to the workstation function vector in \fL\s-1ws.h\fR\s+1. .IP Load the new workstation function vector entry in the \fIload_funcs()\fR function in \fL\s-1wsa.c\s+1\fR and \fL\s-1wsb.c\s+1\fR. Loading it in \fL\s-1wsa.c\s+1\fR is not necessary if the \fIcss_srvr\fR function in \fL\s-1cpa_ws.c\s+1\fR does all the work. Some workstation functions only work in the \s-1PM\s+1, and their entry is \s-1NULL\s+1 in the client. .H 3 "Using Different Toolkits" .LP All code that uses or references toolkits is confined to the files \fL\s-1cp/phigsmon.c\fR\s+1, \fL\s-1cp/cpm_tlkt.c\fR\s+1, \fL\s-1input/sin_cho.c\fR\s+1, \fL\s-1input/sin_val.c\fR\s+1, \fL\s-1input/sin_strg.c\fR\s+1 and \fL\s-1ws/ws_pm.c\fR\s+1 (for the \s-1MESSAGE\s+1 function). References to toolkit functions is kept in \s-1PM\s+1 code and out of client code by the use of function vectors and confining all input and event processing to the \s-1PM\s+1. Only the \s-1PHIGS\s+1 choice, valuator and string devices use a toolkit. Locator, stroke and pick devices use raw X input. .LP Changing the toolkit involves modifying the toolkit initialization code in \fL\s-1cp/cpm_tlkt.c\fR\s+1, the device realization code in \fL\s-1input/sin_{cho,val,strg}.c\fR\s+1, the event dispatching code in \fL\s-1phigsmon.c\s+1\fR, and the message window code in \fL\s-1ws/ws_pm.c\fR\s+1. No other code should have to change. The input device state is maintained in a way that is independent of the actual device realization. .H 3 "Adding Input Devices" .LP The steps to add additional input devices are: .NP Extend the input device counts and descriptions in the workstation desription table (function \fIinit_input_ws_dt()\fR in \fL\s-1ws_type/wstx_ini.c\fR\s+1). .NP Add the device realization to the \fL\s-1input\fR\s+1 directory. .NP Ensure that the event dispatching code in \fL\s-1phigsmon.c\s+1\fR is adequate for the new device. .NP If the device is realized with a toolkit then add any required initialization or default settings to \fL\s-1cpm_tlkt.c\s+1\fR. .LP Most of the code is table driven from the workstation description table. For example, to add 2 more valuator devices of the same kind as the one provided it is only required to change the number of valuator devices in \fIinit_input_ws_st()\fR to 3. Adding other realizations of the devices will be more involved than this, but in general it is only necessary to add the device realization and update the workstation description table. Be careful not to exceed the maximum number of device allowed for in the input device state arrays. This value can be changed in \fL\s-1include/ws_type.h\fR\s+1. .H C "Porting InsPEX" .H 2 "Portability Goals and Non-Goals" .LP Ins\s-1PEX\s+1 is intended to work with 8-bit pseudocolor framebuffers. We assume Unix, and have the goal of working under both System V and \s-1BSD\s+1 systems. We also intend Ins\s-1PEX\s+1 to work on any 32-bit machine architecture. We do not have the goal of working on non-Unix systems or different frame buffer depths. .LP While support for other frame buffer depths is not built into Ins\s-1PEX\s+1, some provisions were made for porting to other depths. In the definition of the file format for saved images, found in the comment for \fIi_save_image()\fR in \fL\s-1mit/extensions/test/InsPEX/tools/pexint/pixutils.c\fR\s+1, the first byte is intended to identify the type of file. The only supported type is \s-1PSEUDOCOLOR\s+1, but other types could be defined and added. Their structure after the description string, width, and height fields would be different, and this first byte would be used to differentiate how the files were created and should be handled. .H 2 "Porting Tests and the Interpreter" .LP Some portable data types are declared in \fL\s-1portable.h\fR\s+1 in \s-1\fLINSPEXHOME/tools/pexint\fR\s+1, for use in the interpreter and other tests. .LP We have tried to use system calls that are common to both System V and \s-1BSD\s+1 Unix. Some System V incompatibilities reported by an alert sponsor have been fixed, though they require a \s-1SYSV\s+1 variable to be defined during compilation (see the description of \s-1I_CFLAGS\s+1 in the \fIRelease Notes\fR or \fL\s-1inspex.sh\fR\s+1, for a method to set this if it is not set by the compiler). .H 2 "Porting the Inspector" .LP The chief portability issue for the Inspector is the choice of Graphical User Interface toolkit. The current implementation uses the XView toolkit, which is available from \s-1MIT\s+1 and from Sun Microsystems. .LP To facilitate porting, however, all toolkit-specific code is isolated into two files, \fL\s-1toolkit.c\fR\s+1 and \fL\s-1toolkit.h\fR\s+1. Through typedefs and function definitions, these files create a separate interface layer on top of the toolkit being used. While this interface looks like a toolkit itself, it has no pretense of being a general-purpose toolkit \(em it was designed strictly to make this particular application easily portable. The interface types and functions should be implementable using any toolkit. A port to Athena Widgets is also included. .LP Notification, or call-back, procedures are attached to the buttons of the control panel; since we cannot be sure of of what arguments a given toolkit may supply to these procedures, they are expected to be defined without any arguments. The negative side to this solution is that it forces greater use of global variables. .LP The scrolling list could be implemented as a menu or other control item. Selecting the file name in the list could be used to control loading of files, rather than the current method of selecting and then hitting "load".