X11/Motif portability concerns, Unix -> OpenVMS
Version 1.1  9-JUN-1997
David Mathog, Biology Division, Caltech
comments/corrections/additions to mathog@seqaxp.bio.caltech.edu

This is a list of all known areas where a compatibility problems 
_may_ occur when porting an X11/Motif application from Unix to 
OpenVMS.  The specific sections indicating operating system
dependencies are indicated with a "*".  

( A valuable reference, if you can find it:  X/Open Portability Guide )

1.  XSetFontPath
2.  XReadBitmapFile
3.  WM_CLASS Property
4.  XtResolvePathname
5.  XtFindFile
6.  XtAppAddInput
7.  Exiting  from an  Application
8.  use of select()
9.  use of ConnectionNumber();
10. XMultiplexInput()  (OpenVMS specific select() replacement)

1.  XSetFontPath          "X Window System 6.5.3"

   "The XSetFontPath function defines the directory search
    path for font lookup.  There is only one search path per
*   X server, not one per client.  The interpretation of the
*   strings is operating system dependent, but they are
    intended to specify directories to be searched in the
    order listed.  Also, the contents of these strings are
    operating system dependent and are not intended to be
    used by client applications."

2.  XReadBitmapFile      "X Window System 10.10"

  "int XReadBitmapFile(display, d, filename, width_return, height_return, 
         bitmap_return, x_hot_return , y_hot_return )

*  filename         Specifies the file name to use.  The format of the file
*                   name is operating system dependent. "

3.  WM_CLASS Property    "X Window System 4.1.2.5"

   "The WM_CLASS property (of type STRING without
    control characters) contains two consecutive null-
    terminated strings.  These specify the Instance and
    Class names to be used by both the client and the win-
    dow manager for looking up resources for the applica-
    tion or as identifying information. This property must be
    present when the window leaves the Withdrawn state
    and may be changed only while the window is in the
    Withdrawn state. Window managers may examine the
    property only when they start up and when the window
    leaves the Withdrawn state, but there should be no need
    for a client to change its state dynamically.

    The two strings, respectively, are:

       A string that names the particular instance of the
       application to which the client that owns this window
       belongs. Resources that are specified by instance
       name override any resources that are specified by
*      class name. Instance names can be specified by the
*      user in an operating-system specific manner. On
       POSIX-conformant systems, the following conven-
       tions are used:"


4.  XtResolvePathname  "X Window System Toolkit 2.2"
                   "also,  Personal communication: Dom Maddalone,
                    dgm@cronus.colorado.edu"

   "The application-specific class resource file name is con-
    structed from the language string and class name of the
    application. It points to a site-specific resource file that
    usually is installed by the site manager when the appli-
    cation is installed.  The file is found by calling XtResol-
    vePathname with the parameters (display, app-
    defaults, NULL , NULL , NULL , NULL , 0, NULL ); see Sec-
    tion 11.11.  This file is expected to be provided by the
    developer of the application and may be required for the
    application to function properly.  A simple application
    that wants to be assured of having a minimal set of
    resources in the absence of its class resource file can
    declare fallback resource specifications with XtAppSet
    FallbackResources.

    The application-specific user resource file name is con-
    structed from the language string and class name of the
    application and points to a user-specific resource file. 
    This file is owned by the application and typically stores
    user customizations.  Its name is found by calling
    XtResolvePathname with the parameters (display,
    NULL , NULL , NULL , path, NULL , 0, NULL ) where path
*   is defined in an operating-system-specific way. On
*   POSIX-based systems, path is defined to be the value of
    the environment variable XUSERFILESEARCHPATH  if this
    is defined. If XUSERFILESEARCHPATH  is not defined but
    the environment variable XAPPLRESDIR is defined, path
    is

    $XAPPLRESDIR/%L/%N:$XAPPLRESDIR/%l/%N:$XAPPLRESDIR/%N:$HOME/%N

    where $XAPPLRESDIR is replaced by the value of that
    environment variable and $HOME is replaced by the
    user's home directory. If XAPPLRESDIR is not defined,
    path is

    $HOME/%L/%N:$HOME/%l/%N:$HOME/%N
    "

    From the above we can see that ":" is a delimiter for each
    path to check, but ":" has other uses on OpenVMS, and so it
    must be escaped to work properly.  Example:

      filename = XtResolvePathname(XtDisplay(toplevel),NULL,"TED",
      #ifdef __VMS
            ".HELP","SYS$HELP%:%N%S",NULL,0,NULL);
      #else
            ".HELP",NULL,NULL,0,NULL);
      #endif


5. XtFindFile   "X Window System Toolkit 11.11"

  "XtFindFile(path, substitutions, num_substitutions, predicate)

*       path            Specifies a path of file names, including
*                       substitution characters. "

    Path should be treated as in XtResolvePathName


6. XtAppAddInput   "X Window System Toolkit 7.1.1"

   "To register a new file as an input source for a given
    application context, use XtAppAddInput. 

    XtInputId XtAppAddInput(app_context, source, condition, proc, 
         client_data)
             XtAppContext app_context;
             int source;
             XtPointer condition;
             XtInputCallbackProc proc;
             XtPointer client_data;

    app_context      Specifies the application context that
                     identifies the application.

*   source           Specifies the source file descriptor on a
*                    POSIX-based system or other
*                    operating-system-dependent device
*                    specification. 

*   condition        Specifies the mask that indicates a read,
*                    write, or exception condition or some
*                    other operating-system-dependent condition."

   From "VMS DECwindows Motif Guide to Application Programming 3.7"

   Source and condition on OpenVMS are

  "2. An event flag to monitor. When the intrinsics notices
      that this flag is set, it calls the XtInputCallbackProc
      routine you specify. Event flag numbers are restricted to
      cluster 0, which contains event flag numbers 0 to 31. (See
      the VMS System Services Reference Manual for more
      information.) Note that event flag 0 cannot be used as the
      XtAddInput event flag.

   3. An I/O status byte (IOSB) for the condition return code.
      This argument can be zero.

  Your application needs a way to set the event flag to indicate
  that input is available. The most common method of setting
  the event flag is by using an AST completion routine. For
  example, in Example 3-13, the START_READ routine
  starts a $QIO read and specifies CompletionAst as the AST
  completion routine. CompletionAst sets the event flag."


7. Exiting  from an  Application  "X Window System Toolkit 2.8"

   "All X Toolkit applications should terminate by calling
*   XtDestroyApplicationContext  and then exiting using
*   the standard method for their operating system (typi-
*   cally, by calling exit for POSIX -based systems).  The
    quickest way to make the windows disappear while
    exiting is to call XtUnmapWidget on each top-level
    shell widget.  The X Toolkit has no resources beyond
    those in the program image, and the X server will free
    its resources when its connection to the application is
    broken."

8.  use of select()    "James Cameron, cameron@stl.dec.com"

 "Not a problem as such, but on Unix it is often assumed that
  communication with an X server is implemented in the X
  library via a socket file descriptor, which can be obtained
  from X using the DISPLAY structure or a specific
  function/macro. 

  I'm not sure what X as such thinks of this, but in my
  personal opinion it is delving too deeply into things that
  are X's domain. 

  So Unix code that then goes and uses the file descriptor on
  a call to select() so as to be told when X events arrive is
  difficult to port to OpenVMS's implementation of X."

  Here is some example code showing how to work around the select()
  problem (look at VMSUTILS.C and INPUT.C and X11WINDOW.C)

  ftp://ftp.risc.uni-linz.ac.at/pub/netrek/cow/COW.2.02pl1.tar.gz


9.  use of ConnectionNumber() "DECwindows Motif for OpenVMS Guide to 
        Non-C Bindings

     "CONNECTION NUMBER returns an integer that
      identifies the connection. This routine is defined to
      be operating system specific by MIT, and there is
      no direct analogue to the UNIX file descriptor in
      OpenVMS."

  This is related to select(), above.  Some X11 applications use
  ConnectionNumber() to retrieve a file descriptor that they
  then pass to a select() statement.  This will not work on OpenVMS,
  since ConnectionNumber() returns an event flag, and select()
  cannot be used.

10. XMultiplexInput()  

  XMultiplexInput() is apparently the heart and soul of DECwindows
  multiplexed input, serving as an OpenVMS specific select() replacement.
  The following information from Wolfgang J. Moeller documents the
  interface to this routine.  This routine is NOT officially supported by
  Digital, however, since it is apparently at the very core of DECwindows/
  Motif asynchronous processing, and it doesn't seem like EDS (who now 
  maintains it) is likely to rewrite it, this routine should be fairly safe
  to use.  (Moreover, we know from recent ECOs for DECwindows that
  XMultiplexInput() is still the base upon which XtAddAppInput() is built.)
  The two options flags are contained in current versions of X.h:

     /* For users of XMultiplexInput.  This routine is VMS only */
     #ifdef VMS
     #define XMINoBlock              1
     #define XMINewInput             2
     #endif /* VMS */

  It is unclear what the actual minimum timeout value is.  
  The documentation seems to imply that you could set it to
  1 millisecond, but some, maybe all systems, might not be
  able to set that short a timer, for instance, LIB$WAIT
  has a minimum setting of 10 milliseconds.

  Information from "Wolfgang J. Moeller,moeller@decus.decus.de,w.moeller@ieee.org"

  XMultiplexInput() = MULTIPLEX INPUT (VMS only)

  Locate a source of input ready to be processed by a caller.
  Sources of input handled by this function are:
      o  any number of Displays
      o  user-defined input based on event flags in cluster 0
      o  a timer event
  Not needed on ULTRIX [:-)]

  "VAX" Format:
      X$MULTIPLEX_INPUT(num_displays.rlu.r,displays.ra.ra,
           ef_mask.rlu.r,timeout.rlu.r,
           options.rlu.r,retval.wl.r)

   MIT C Format:
      XMultiplexInput(
           long num_displays,
           Display *displays[/*num_displays*/],
           unsigned long ef_mask,
           unsigned long timeout,
           unsigned long options,
           long *retval_pointer)

   Arguments:
      num_displays, displays[]
                 number of displays to check, and array
                 of same [a single display can be passed
                 as `1, &dpy'].

      ef_mask    
                 mask of event flags (in cluster 0)
                 to be monitored for non-X "input".
                 [Note that event flags 24..31 are
                 reserved for DIGITAL software, e.g.
                 XLIB uses 24 & 25 internally.]

      timeout    
                 zero to indicate no timeout, or a number
                 of milliseconds to wait for "input".

      options    
                 flag word, may be zero, or either
                    X$M_MI_NO_BLOCK == XMINoBlock
                            - do not wait for "input"
                        or
                    X$M_MI_NEW_INPUT == XMINewInput
                            - ignore X events already queued

      retval     
                 output, describing the sort of "input"
                 detected on successful completion:
                     1..num_displays  - index (1-based)
                                        into `displays[]'
                     -1               - some event flag in
                                       `ef_mask' is set
                     0                - no "input" (only
                                        with XMINoBlock)

  Function returns:
   "VAX" Format       | MIT C Format
    ----------------+-------------
      SS$_NORMAL      |      1  - successful completion;
                      |           `retval' has additional information.
                      |
      SS$_TIMEOUT     |      0  - operation timed out.
                      |
      failure status  |      -1 - an error occurred.
   ------------------------------------------------------------------

   The routine _is_ present in all sorts of (VMS)
   DECW$XLIBSHR.EXE known to me, and at least the "MIT C
   format" works as documented [above :-)]. 

   Of course, I'd _never_ use the `XMINewInput' option: X
   events arrive asynchronously, so the concept of "old" vs.
   "new" events is very vague ... 

   BTW, neither routine name is declared in the language-specific
   DECW$ "include" files, but the two option values are there.