X11/Motif portability concerns, Unix -> OpenVMS Version 1.1 9-JUN-1997 David Mathog, Biology Division, Caltech comments/corrections/additions to mathog@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.