From fogel@antares.mcs.anl.gov Mon Nov 16 15:42:22 1992 Received: from altair.mcs.anl.gov by antares.mcs.anl.gov (4.1/SMI-GAR) id AA18980; Mon, 16 Nov 92 14:43:52 CST Received: by altair.mcs.anl.gov (4.1/GeneV4) id AA03406; Mon, 16 Nov 92 14:43:46 CST Message-Id: <9211162043.AA03406@altair.mcs.anl.gov> From: fogel@antares.mcs.anl.gov (Mr. Karl Fogel) To: kfogel@antares.mcs.anl.gov Date: Mon, 16 Nov 92 14:43:46 CST The X Toolkit Intrinsics F.A.Q $Id$ This article contains the answers to some Frequently Asked Questions (FAQ) from comp.windows.x about the X Toolkit Intrinsics. To submit questions (preferably with an answer) send email to: ware@cis.ohio-state.edu All code fragments are public domain. Contents 0. Xt Glossary 1. Software Versions 2. Related FAQ's 3. Why does my application core dump when I use signals/alarms/cthreads? 4. How do I use a different visual than the default? 5. Which visual should an application use? 6. Why do only Shell widgets have a Visual? 7. Which visual, depth and colormap do Shells inherit? 8. I've done all the above and I still get a BadMatch error. Why? 9. Why doesn't my widget get destroyed when I call XtDestroyWidget()? 10. How do I exit but still execute the DestroyCallbacks? 11. How do I resize a Shell widget? 12. Why can't XtAppAddInput() handle files? 13. What good books/magazines are there on Xt? 14. What Widgets are available? 15. What alternatives to the Intrinsics are there? 16. How do I pass a float value to XtSetValues? 17. +++How do I write a resource converter? 18. +++How do I open multiple displays? 19. +++What changed from R3 to R4 to R5? 20. Where are the resources loaded from? 21. What order are callbacks executed in? 22. How do I know if a widget is visible? 23. How do I reparent a widget in Xt, i.e. XtReparentWidget()? The "+++" indicates the question needs more of an answer. ---------------------------------------------------------------------- 0. Xt Glossary ---------------------------------------------------------------------- o The Xt Intrinsics implement an object oriented interface to C code to allow useful graphical components to be created. Included with this are classes that provide the base functionality: Object, RectObj, Core, Composite, Constraint, Shell, OverrideShell, WMShell, etc. The terms "Xt" and "Intrinsics" are used interchangeably. This is used very precisely to mean a specific library of the X window system. In particular, it does not include the Athena, Motif, OLIT or any other widget set. Without further widgets the Intrinsics are not especially useful. o A widget refers to a user interface abstraction created via Xt. The precise use, is any object that is a subclass of the Core class. It is used loosely to refer to anything that is a subclass of the Object class although these are more accurately called windowless widgets or gadgets. o Xlib is the C interface to the X11 protocol. It is one layer below the Xt Intrinsics. Typically a widget uses relatively few Xlib functions because Xt provides most such services although an understanding of Xlib helps with problems. ---------------------------------------------------------------------- 1. Software Versions ---------------------------------------------------------------------- The following are the latest versions of Xt based software: _____________________________________________________________ Software Version Released Next Expected _____________________________________________________________ X11R4 patch 18 (none) X11R5 patch 16 8/1/92 ?? Athena Widgets (see X11R5) Motif 1.2 5/92 ?? OLIT ?? ?? ?? Xtra 2.5 6/15/92 ?? Xw X11R4 (none) Xcu X11R5 (none) fwf 3.2 6/08/92 ?? _____________________________________________________________ ---------------------------------------------------------------------- 2. Related FAQ's ---------------------------------------------------------------------- David B. Lewis (uunet!craft!faq) maintains the FAQ on X. It is posted monthly on comp.windows.x and located on export in contrib/FAQ. Liam R. E. Quin (lee@sq.sq.com) posts an FAQ list on Open Look to comp.windows.x. Jan Newmarch (jan@pandonia.canberra.edu.au) posts an FAQ list on Motif to comp.windows.x.motif. Peter Ware (ware@cis.ohio-state.edu) is developing an FAQ list for comp.windows.x.intrinsics; it is on export in contrib/FAQ-Xt. ---------------------------------------------------------------------- 3. Why does my application core dump when I use signals/alarms/cthreads? ---------------------------------------------------------------------- In brief, Xlib, Xt and most widget sets have no mutual exclusion for critical sections. Any interrupt handler is likely to leave one of the above libraries in an inconsistent state -- such as all the appropriate flags not yet set, dangling pointers, in the middle of a list traversal, etc. Note that the ANSI C standard points out that behavior of a signal handler is undefined if the signal handler calls any function other than signal() itself, so this is not a problem specific to Xlib and Xt; the POSIX specification mentions other functions which may be called safely but it may not be assumed that these functions are called by Xlib or Xt functions. The only safe way to deal with signals is to set a flag in the interrupt handler. This flag later needs to be checked either by a work procedure or a timeout callback. It is incorrect to add either of these in the interrupt handler. As another note, it is dangerous to add a work procedure that never finishes. This effectively preempts any work procedures previously added and so they will never be called. Another option is to open a pipe, tell the event loop about the read end using XtAppAddInput() and then the signal handler can write a byte to the write end of the pipe for each signal. However, this could deadlock your process if the pipe fills up. Why don't the Intrinsics deal with this problem? Primarily because it is supposed to be a portable layer to any hardware and operating system. Is that a good enough reason -- I don't think so. Note: the article in The X Journal 1:4 and the example in O'Reilly Volume 6 are in error. ---------------------------------------------------------------------- 4. How do I use a different visual than the default? ---------------------------------------------------------------------- This requires a more complicated answer than it should. A window has three things that are visual specific -- the visual, colormap and border pixmap. All widgets have their own Colormap and BorderPixmap resource; only shell widgets have Visual resources (another questions deals with why shells have a Visual). The default value of these resources is CopyFromParent which does exactly what it says. In the shell widget CopyFromParent gets evalulated as DefaultVisualOfScreen and DefaultColormapOfScreen. When any one of the three resources is not properly set, a BadMatch error occurs when the window is created. They are not properly set because each of the values depends on the visual being used. How to get this to work? There are two parts to the answer. The first is if you want an application to start with a particular visual and the second is if you want a particular shell within an application to start with a different visual. The second is actually easier because the basic information you need is available. The first is a little harder because you'll need to initialize much of the toolkit yourself in order to determine the needed information. /* * Some sample code to start up an application using something other * than the default visual. * * To compile: * cc -g visual.c -o visual -lXaw -lXmu -lXt -lXext -lX11 -lm * * To run: * ./visual -geometry 300x300 -visual StaticColor -fg blue -bg yellow * * you need to move the mouse to get the particular visuals colormap * to install. */ #include #include #include typedef struct { Visual *visual; } OptionsRec; OptionsRec Options; XtResource resources[] = { {"visual", "Visual", XtRVisual, sizeof (Visual *), XtOffsetOf (OptionsRec, visual), XtRImmediate, NULL}, }; XrmOptionDescRec Desc[] = { {"-visual", "*visual", XrmoptionSepArg, NULL} }; int main (argc, argv) int argc; char **argv; { XtAppContext app; /* the application context */ Widget top; /* toplevel widget */ Display *dpy; /* display */ char **xargv; /* saved argument vector */ int xargc; /* saved argument count */ Colormap colormap; /* created colormap */ XVisualInfo vinfo; /* template for find visual */ XVisualInfo *vinfo_list; /* returned list of visuals */ int count; /* number of matchs (only 1?) */ Arg args[10]; Cardinal cnt; char *name = "test"; char *class = "Test"; /* * save the command line arguments */ xargc = argc; xargv = (char **) XtMalloc (argc * sizeof (char *)); bcopy ((char *) argv, (char *) xargv, argc * sizeof (char *)); /* * The following creates a _dummy_ toplevel widget so we can * retrieve the appropriate visual resource. */ cnt = 0; top = XtAppInitialize (&app, class, Desc, XtNumber (Desc), &argc, argv, (String *) NULL, args, cnt); dpy = XtDisplay (top); cnt = 0; XtGetApplicationResources (top, &Options, resources, XtNumber (resources), args, cnt); cnt = 0; if (Options.visual && Options.visual != DefaultVisualOfScreen (XtScreen (top))) { XtSetArg (args[cnt], XtNvisual, Options.visual); ++cnt; /* * Now we create an appropriate colormap. We could * use a default colormap based on the class of the * visual; we could examine some property on the * rootwindow to find the right colormap; we could * do all sorts of things... */ colormap = XCreateColormap (dpy, RootWindowOfScreen (XtScreen (top)), Options.visual, AllocNone); XtSetArg (args[cnt], XtNcolormap, colormap); ++cnt; /* * Now find some information about the visual. */ vinfo.visualid = XVisualIDFromVisual (Options.visual); vinfo_list = XGetVisualInfo (dpy, VisualIDMask, &vinfo, &count); if (vinfo_list && count > 0) { XtSetArg (args[cnt], XtNdepth, vinfo_list[0].depth); ++cnt; XFree ((XPointer) vinfo_list); } } XtDestroyWidget (top); /* * Now create the real toplevel widget. */ XtSetArg (args[cnt], XtNargv, xargv); ++cnt; XtSetArg (args[cnt], XtNargc, xargc); ++cnt; top = XtAppCreateShell ((char *) NULL, class, applicationShellWidgetClass, dpy, args, cnt); /* * Display the application and loop handling all events. */ XtRealizeWidget (top); XtAppMainLoop (app); return (0); } ---------------------------------------------------------------------- 5. Which visual should an application use? ---------------------------------------------------------------------- This is a point that can be argued about but one opinion is there is no way for an application to know the appropriate visual -- it has to be specified by the user. If you disagree with this then your application probably falls into the category of always using the default visual or it is hardware specific and expects some particular visual such as 24bit TrueColor with an OverlayPlane extension (or some such). Why? No application runs in isolation. Depending on the way a server allocates resources I may not always want your application to run in TrueColor mode if it is going to mess up my other applications. I may be very upset if it chooses to run in GreyScale instead of PsuedoColor or just monochrome. As an example, on a low end color Sun server there are many different possible visuals: monochrome, 256 entry colormap, static gray, static color, and a 3/3/2 TrueColor. The SGI Iris's offer all the above plus 12 bit TrueColor, 24 bit TrueColor, an Overlay Plane. ---------------------------------------------------------------------- 6. Why do only Shell widgets have a Visual? ---------------------------------------------------------------------- This is strictly by convention. It makes it possible for an arbitrary widget to know that the visual it uses can be found by looking for the shell widget that is its ancestor and obtaining the visual of that shell. A widget can have its own visual resource. If it does, it must have its own realize method to use the visual when it calls XCreateWindow(). You should also make this a resource that can be obtained with XtGetValues() so other widgets can find it. A reasonable value is probably XtNvisual. ---------------------------------------------------------------------- 7. Which visual, depth and colormap do Shells inherit? ---------------------------------------------------------------------- The default value for these resources are set to CopyFromParent. This is interpreted as the DefaultColormapOfScreen(), DefaultDepthOfScreen() and the default visual of the screen if the widget has no parent -- i.e. it is an applicationShellWidgetClass and the root of your widget tree. If the parent of the widget is not null, then the shell copies colormap and depth from its parent and uses CopyFromParent as the visual. ---------------------------------------------------------------------- 8. I've done all the above and I still get a BadMatch error. Why? ---------------------------------------------------------------------- Some resource converters improperly cache references. This was especially true of X11R3 and earlier versions of Motif. ---------------------------------------------------------------------- 9. Why doesn't my widget get destroyed when I call XtDestroyWidget()? ---------------------------------------------------------------------- See section 2.8 of the Xt specification. It eventually does get destroyed, just not immediately. The Intrinsics destroy a widget in a two-phase process. First it and all of its children have a flag set that indicate it is being destroyed. It is then put on a list of widgets to be destroyed. This way any pending X events or further references to that widget can be cleaned up before the memory is actually freed. The second phase is then performed after all callbacks, event handlers, and actions have completed, before checking for the next X event. At this point the list is traversed and each widget's memory is actually free()'d, among other things. As some further caveats/trivia, the widgets may be destroyed if the Intrinsics determine that they have no further references to the widgets on the list. If so, then the phase 2 destruction occurs immediately. Also, if nested event loops are used, widgets placed on the destroy list before entering the inner event loop are not destroyed until returning to the outer event loop. ---------------------------------------------------------------------- 10. How do I exit but still execute the DestroyCallbacks? ---------------------------------------------------------------------- The problem is if a simple and entirely reasonable approach to exiting an application is used, such as calling exit() directly, then a widget may not have a chance to clean up any external state -- such as open sockets, temporary files, allocated X resources, etc. (this code for simplicity reasons assumes only a single toplevel widget): Widget ToplevelGet (gw) Widget gw; /* widget to find toplevel */ { Widget top; for (top = gw; XtParent (top); top = XtParent (top)) /* empty */; return (top); } void ExitCallback (gw, closure, call_data) Widget gw; /* widget */ XtPointer closure; /* data the app specified */ XtPointer call_data; /* widget specific data */ { Widget toplevel; toplevel = ToplevelGet (gw); XtUnmapWidget (toplevel); /* make it disappear quickly */ XtDestroyWidget (toplevel); exit (0); } One can see that the above code exit's immediately after destroying the toplevel widget. The trouble is the phase 2 destruction may never occur. This will work for most widgets and most applications. Remember that part of the reason an object oriented approach is used is so one can be ignorant of the implementation details for each widget -- which I always interpret to mean that the widget may change and someday require that the some external state is cleaned up by the Destroy callbacks. One alternative is to modify ExitCallback() to set a global flag and then test for that flag in a private event loop. However, private event loops are frowned upon because it tends to encourage sloppy, and difficult to maintain practices. Try the following code instead: #include extern Widget ToplevelGet ( #if NeedFunctionPrototypes Widget gw #endif ); extern Boolean ExitWorkProc ( #if NeedFunctionPrototypes XtPointer closure #endif ); extern void ExitCallback ( #if NeedFunctionPrototypes Widget gw, XtPointer closure, XtPointer call_data #endif ); Widget ToplevelGet (gw) Widget gw; /* widget to find toplevel */ { Widget top; for (top = gw; XtParent (top); top = XtParent (top)) /* empty */; return (top); } void ExitCallback (gw, closure, call_data) Widget gw; /* widget */ XtPointer closure; /* data the app specified */ XtPointer call_data; /* widget specific data */ { Widget toplevel; toplevel = ToplevelGet (gw); XtUnmapWidget (toplevel); /* make it disappear quickly */ XtDestroyWidget (toplevel); XtAppAddWorkProc (XtWidgetToApplicationContext (gw), ExitWorkProc, (XtPointer) NULL); } Boolean ExitWorkProc (closure) XtPointer closure; { exit (0); /*NOTREACHED*/ } This adds a work procedure that will get called when the application is next idle -- which happens after all the events are processed and the destroy callbacks are executed. ---------------------------------------------------------------------- 11. How do I resize a Shell widget? ---------------------------------------------------------------------- After it is realized, one doesn't resize a Shell widget. The proper thing to do is to resize the currently managed child of the Shell widget using XtSetValues(). The geometry change is then propagated to the Shell which asks the window manager which may or may not allow the request. However, the Shell must have the resource XtNallowShellResize set to True otherwise it will not even ask the window manager to grant the request and the Shell will not resize. To change the position of a Shell, use XtSetValues() on the Shell, not the child, and within the limits of the window manager it should be granted. ---------------------------------------------------------------------- 12. Why can't XtAppAddInput() handle files? ---------------------------------------------------------------------- It does, however Unix semantics for when I/O is ready for a file does not fit most peoples' intuitive model. In Unix terms a file descriptor is ready for reading whenever the read() call would not block, ignoring the setting of optional flags that indicate not to block. This works as expected for terminals, sockets and pipes. For a file the read() will always return but the return indicates an EOF -- i.e. no more data. The result is the code in the Intrinsics always calls the input handler because it always thinks something is about to be read. The culprit is the select() system call or on SYSV based OS's it is the poll() system call. How to get around this on a Unix system? The best approach is to use another process to check for available input on the file. Use a pipe to connect the application with this other process and pass the file descriptor from the pipe to XtAppAddInput(). A suitable program on BSD systems is "tail -f filename". Note that all the above descriptions used Unix terminology such as read(), file descriptor, pipes, etc. This is an OS dependent area and may not be identical on all systems. However the Intrinsic designers felt it was a common enough operation that it should be included with part of the toolkit. Why they didn't also deal with signals at this point I don't know. ---------------------------------------------------------------------- 13. What good books/magazines are there on Xt? ---------------------------------------------------------------------- I have a favorite that is the definitive reference. To my perspective it offers a reasonable introduction but also goes into the full details of the Intrinsics. When I started using it I was already familiar with Xt and the concepts behind it, so newcomers may or may not find it useful. I've always found it accurate and complete, which means its a 1000 pages. Asente, Paul J., and Swick, Ralph R., "X Window System Toolkit, The Complete Programmer's Guide and Specification", Digital Press, 1990. The bible on Xt. A treasury of information, excellent and invaluable. Distributed by Digital Press, ISBN 1-55558-051-3, order number EY-E757E-DP; and by Prentice-Hall, ISBN 0-13-972191-6. Also available through DEC Direct at 1-800-DIGITAL. [The examples are on export.lcs.mit.edu in contrib/ and on gatekeeper.dec.com (16.1.0.2) in pub/X11/contrib as asente-swick.examples.tar.Z. They were also posted to comp.sources.x as xt-examples/part0[1-5].] The other book I commonly recomend to novices is: Young, Doug. "The X Window System: Applications and Programming with Xt (Motif Version)," Prentice Hall, 1989 (ISBN 0-13-497074-8). The excellent tutorial "X Window Systems Programming and Applications with Xt," (ISBN 0-13-972167-3) updated for Motif. [The examples are available on export; the ones from the Motif version are in ~ftp/contrib/young.motif.tar.Z.] And of course O'Reilly has an entire series of manuals on X and Xt. O'Reilly ordering is 800-998-9938. (The above details are extracted from the X FAQ, available on export.lcs.mit.edu in contrib/FAQ.) I read two periodicals, "The X Resource" and the "The X Journal". These are the only two dealing specifically with X. "The X Resource" is published quarterly, by O'Reilly, with one of the issues being the MIT X Consortium Technical Conference Proceedings. There is no advertising. I've found it informative with pretty good depth. For orders, call 1-800-998-9938, or email cathyr@ora.com. For editorial matters, email adrian@ora.com. Table of contents are posted at math.utah.edu in ~ftp/pub/tex/bib in TeX form and on ftp.uu.net in "The X Journal" is a bimonthly trade rag with lots of advertising. The articles are informative and oriented toward a less technical audience. I read it more to see what's going on then with an expectation of learning a great deal (but remember, I represent a fairly small percentage of people). Also, they have a pretty good collection of people on the advisory board and as columnists. Call (908) 563-9033. ---------------------------------------------------------------------- 14. What Widgets are available? ---------------------------------------------------------------------- There are three popular widget sets: Athena - The set provided with X11. This is sufficient for most purposes but is on the ugly side. Recently, a 3d look is available for ftp on export.lcs.mit.edu:/contrib/Xaw3d.tar.Z. Motif - From OSF available for a license fee and commonly shipped on many workstation vendors platforms (almost everyone but Sun). It looks good and works well but personally I think it is poorly implemented. OLIT - The Open Look Intrinsics Toolkit is a set of widgets implementing Sun's Open Look specification. Developed by AT&T. I've never used it so can't comment on its quality. I've heard rumours that it is a pain to actually get. In addition the following collection of widgets are also available: Xtra - a library of widgets for sale from Graphical Software Technology (310-328-9338). It includes bar graph, stacked bar graph, line graph, pie chart, xy plot, hypertext, help, spreadsheet, and data entry form widgets. I've never seen them so I can't comment. FWF - The Free Widget Foundation is attempting to collect a set of freely available widgets. Included are a Pixmap editor, FileDialog, and a few others. The current set of widgets can be obtained via anonymous ftp from the machine a.cs.uiuc.edu (128.174.252.1) in the file pub/fwf.shar.Z. Xcu - The Cornell University widgets from Gene Dykes. One of the early widget sets released. Provides a nice appearance for buttons and has a mini command language. Probably not so widely used. Xs - The Sony widget set. This was around during R3 days but seemed to disappear. It looked like it had promise. Xw - The HP widgets. The precursor to Motif. Originally written for R3 there exists diffs to get it to work under R4 & R5. Again, a pretty good widget set but has more or less died. The precursor to this was the Xray toolkit which was originally implemented for X10R4 and apparently provided much experience for the designers of Xt. Xo - A widget set I'm working on. It's still primitive but you can give it a try in archive.cis.ohio-state.edu:pub/Xo/* The following specialized widgets are also available: Tbl - Implements a tabular layout of widgets. Supports Motif widgets as children. Part of Wcl. Plots - The Athena Plotting widgets (not the Athena widgets). Contact gnb@bby.oz.au or joe@Athena.MIT.EDU. ---------------------------------------------------------------------- 15. What alternatives to the Intrinsics are there? ---------------------------------------------------------------------- __________________________________________ Name Language Vendor __________________________________________ Xview C Sun OI C++ Solbourne Interviews C++ Stanford __________________________________________ ---------------------------------------------------------------------- 16. How do I pass a float value to XtSetValues? ---------------------------------------------------------------------- First, what is going wrong is the structure for an Arg is (essentially) typdef struct { String name; long value; } Arg; and the code: Arg arg; XtSetArg (arg, "name", 3.2) expands to Arg arg; arg.name = "name"; arg.value = 3.2; you can see that with normal C type conversions, the arg.value gets the integer "3" instead of the floating point value "3.2". When the value is copied into the widget resource, the bit pattern is wildly different than that required for a floating point value. So, how to get around this? There are two choices. The first just directly copies the value and the second uses a union to get around the problem. Instead of using XtSetArg(), try the following (you may need to use memcpy() instead of bcopy()): Arg arg; float value; arg.name = "name"; value = 3.2; if (sizeof (value) > sizeof (arg.value)) arg.value = &value; else bcopy (&value, &arg.value, sizeof (value)); The second approach yields: Arg arg; union { int int_value; float float_value; } value; value.float_value = 3.2; XtSetArg (arg, "name", value.int_value); Although the safe thing to do is to check that sizeof(float) <= sizeof (arg.value), just as before. ---------------------------------------------------------------------- 17. +++How do I write a resource converter? ---------------------------------------------------------------------- See section 9.6 of the Xt specification, and/or, start with a previously written resource converter, and modify it. ---------------------------------------------------------------------- 18. +++How do I open multiple displays? ---------------------------------------------------------------------- See the forthcoming issue of The X Resource. - include problems with shutting down the proper connection on KillClient (oj@roadrunner.pictel.com (Oliver Jones)) - include resource converters improperly caching info (i.e. who are the offendors). ---------------------------------------------------------------------- 19. +++What changed from R3 to R4 to R5? ---------------------------------------------------------------------- See Chapter 13 of the Xt specification. ---------------------------------------------------------------------- 20. Where are the resources loaded from? ---------------------------------------------------------------------- [Thanks to Oliver Jones (oj@pictel.com), 6/92] You can use several environment variables to control how resources are loaded for your Xt-based programs -- XFILESEARCHPATH, XUSERFILESEARCHPATH, and XAPPLRESDIR. These environment variables control where Xt looks for application-defaults files as an application is initializing. Xt loads at most one app-defaults file from the path defined in XFILESEARCHPATH and another from the path defined in XUSERFILESEARCHPATH. Set XFILESEARCHPATH if software is installed on your system in such a way that app-defaults files appear in several different directory hierarchies. Suppose, for example, that you are running Sun's Open Windows, and you also have some R4 X applications installed in /usr/lib/X11/app-defaults. You could set a value like this for XFILESEARCHPATH, and it would cause Xt to look up app-defaults files in both /usr/lib/X11 and /usr/openwin/lib (or wherever your OPENWINHOME is located): setenv XFILESEARCHPATH /usr/lib/X11/%T/%N:$OPENWINHOME/lib/%T/%N The value of this environment variable is a colon-separated list of pathnames. The pathnames contain replacement characters as follows (see XtResolvePathname()): %N The value of the filename parameter, or the application's class name. %T The value of the file "type". In this case, the literal string "app-defaults" %C customization resource (R5 only) %S Suffix. None for app-defaults. %L Language, locale, and codeset (e.g. "ja_JP.EUC") %l Language part of %L (e.g. "ja") %t The territory part of the display's language string %c The codeset part of the display's language string Let's take apart the example. Suppose the application's class name is "Myterm". Also, suppose Open Windows is installed in /usr/openwin. (Notice the example omits locale-specific lookup.) /usr/lib/X11/%T/%N means /usr/lib/X11/app-defaults/Myterm $OPENWINHOME/lib/%T/%N means /usr/openwin/lib/app-defaults/Myterm As the application initializes, Xt tries to open both of the above app-defaults files, in the order shown. As soon as it finds one, it reads it and uses it, and stops looking for others. The effect of this path is to search first in /usr/lib/X11, then in /usr/openwin. Let's consider another example. This time, let's set XUSERFILESEARCHPATH so it looks for the file Myterm.ad in the current working directory, then for Myterm in the directory ~/app-defaults. setenv XUSERFILESEARCHPATH ./%N.ad:$HOME/%T/%N The first path in the list expands to ./Myterm.ad. The second expands to $HOME/app-defaults/Myterm. This is a convenient setting for debugging because it follows the Imake convention of naming the app-defaults file Myterm.ad in the application's source directory, so you can run the application from the directory in which you are working and still have the resources loaded properly. With R5, there's another twist. You may specify a customization resource value. For example, you might run the "myterm" application like this: myterm -xrm "*customization: -color" If one of your pathname specifications had the value "/usr/lib/X11/%T/%N%C" then the expanded pathname would be "/usr/lib/X11/app-defaults/Myterm-color" because the %C substitution character takes on the value of the customization resource. The default XFILESEARCHPATH, compiled into Xt, is: /usr/lib/X11/%L/%T/%N%C:\ (R5) /usr/lib/X11/%l/%T/%N%C:\ (R5) /usr/lib/X11/%T/%N%C:\ (R5) /usr/lib/X11/%L/%T/%N:\ /usr/lib/X11/%l/%T/%N:\ /usr/lib/X11/%T/%N (Note: some sites replace /usr/lib/X11 with a ProjectRoot in this batch of default settings.) The default XUSERFILESEARCHPATH, also compiled into Xt, is /%L/%N%C:\ (R5) /%l/%N%C:\ (R5) /%N%C:\ (R5) /%L/%N:\ /%l/%N:\ /%N: is either the value of XAPPLRESDIR or the user's home directory if XAPPLRESDIR is not set. If you set XUSERFILESEARCHPATH to some value other than the default, Xt ignores XAPPLRESDIR altogether. Notice that the quick and dirty way of making your application find your app-defaults file in your current working directory is to set XAPPLRESDIR to ".", a single dot. In R3, all this machinery worked differently; for R3 compatibilty, many people set their XAPPLRESDIR value to "./", a dot followed by a slash. ---------------------------------------------------------------------- 21. What order are callbacks executed in? ---------------------------------------------------------------------- (Courtesy of Donna Converse, converse@expo.lcs.mit.edu; 5/10/92) The Intrinsics library do not guarantee an order. This is because both the widget writer and the application writer have the ability to modify the entire contents of the callback list. Neither one currently knows what the other is doing and the Intrinsics cannot guarantee the order of execution. The application programmer cannot rely on the widget writer; the widget writer is not required to document when the widget will add and remove callbacks from the list or what effect this will have; therefore the functionality contained in a callback should be independent of the functionality contained in other callbacks on the list. Even though the Xt standard in the definition of XtAddCallback says: "callback_name: Specifies the callback list to which the procedure is to be appended." you may not infer from the word "appended" that the callback routines are called in the same order as they have been added to the callback list. ---------------------------------------------------------------------- 22. How do I know if a widget is visible? ---------------------------------------------------------------------- (Courtesy of Donna Converse, converse@expo.lcs.mit.edu; 5/14/92) > I am building a widget needs to know if it is visible. I set the visible > interest field in Core and if my window is completely obscured, the Core > visible flag goes FALSE. However, if my window is iconified, the flag > stays set to TRUE. Right, everything is implemented correctly. This demonstrates a "deficiency" in the X protocol, and the Core widget is reflecting the capabilities of the protocol. (The "deficiency" is that the information is available in one way, in this case an inconvenient way.) The Xt specification is accurate, in the second and third paragraphs of section 7.10.2, so read this section carefully. The visible field will not change in response to iconification. A VisibilityNotify event will not be received when the window goes from viewable to unviewable, that is, when the widget or an ancestor is unmapped; that is, when iconification occurs. This is the protocol deficiency. Visibility state and viewable state have specific meanings in the X protocol; see the glossary in your Xlib and X protocol reference manual. > Is this a problem with "mwm" or is there something > else which needs to be done? You'll see this with any window manager, with no window manager. > If the problem is "mwm", what is the fastest > way to determine if a window is iconified? As an application writer, keep track with a global Boolean in an action routine with translations for MapNotify and UnmapNotify on the Shell widget which contains your custom widget. As the custom widget writer, see the map_state field returned by a call to XGetWindowAttributes. These are suggestions. ---------------------------------------------------------------------- 23. How do I reparent a widget in Xt, i.e. XtReparentWidget()? ---------------------------------------------------------------------- You can't.