allanswers.org - comp.windows.x.intrinsics Frequently Asked Questions (FAQ)

 Home >  FAQ on different themes >
 comp.windows.x.intrinsics Frequently Asked Questions (FAQ)

Section 3 of 4 - Prev - Next
All sections - 1 - 2 - 3 - 4


First, I'd recomend getting "purify" from Pure Software.  This is a
great package for tracing memory problems on Sun's.  It's a bit pricey
at $2750 but I'd still recomend it.  Excuse the marketing blurb
(contact support@pure.com for more info).

	Purify inserts additional checking instructions directly into
	the object code produced by existing compilers.  These
	instructions check every memory read and write performed by
	the program under test and detect several types of access
	errors, such as reading unitialized memory, writing past
	malloc'd bounds, or writing to freed memory.  Purify inserts
	checking logic into all of the code in a program, including
	third party and vendor object-code libraries, and verifies
	system call interfaces.  In addition, Purify tracks memory
	usage and identifies individual memory leaks using a novel
	adaption of garbage collection techniques.  Purify's nearly
	comprehensive memory access checking slows the target program
	down typically by a factor of two to five.

An alternative package that isn't as pricey ($395 for a Sun), runs on
many Unix's and has pretty similar features is "The SENTINEL Debugging
Environment".  This replaces malloc() and several other C library
functions to add additional checks.  (contact cpcahil@virtech.vti.com
for more info)

Next, if you are getting any sort of Xlib error, you'll need to run in
synchronous mode, easily accomplished with the "-sync" command line
argument or by setting the variable Xdebug to 1 with your debugger.  Then
set a break point in exit().  This will let you trace back to the
original Xlib function being called.  If you don't run in synchronous
mode, then the actual error may have occured any number of calls to
Xlib previously since the Xlib calls are buffered and replies from the
server are asynchronous.

Next, if you are having trouble with window layout, you can use the
undocumented resource "xtIdentifyWindows" or the class resource
"XtDebug" to cause the widget name to be identified with each window.
For example:

    example% xload -xrm '*XtDebug:true' &
    example% xwininfo -tree
	     

will give the normal information but the widget name and class of each
window is included.  This can help for checking the location and size
of errant widgets.

Next, if you are having trouble with geometry managers or you want to
test the way a widget manages its children, you can try
file://ftp.x.org/contrib/libXtGeo.tar.Z.  This acts as a filter
between any children and a geometry manager and checks the behaviour
of both.  It's a very clever idea.

The most unfortunate problem is debugging a callback while the
application is executing a grab of the keyboard or mouse (such as from
a pulldown menu).  The server effectively locks up and you'll need to
go to another machine and kill the debugger manually.  The server
locks up because the application being debugged has said no one else
can have access to the keyboard but the application is not stopped
waiting because the debugger is waiting for your commands.
Unfortunately you can't give them because all the input is going to
your application which is stopped.

The best way to debug this kind of problem is with two machines on
your desk, running the program under a debugger (or other environment)
on one machine, and running the application on the other, possibly
using a command sequence like this:

	othermachine% xhost +thismachine
	thismachine% setenv DISPLAY othermachine:0;
	thismachine% gdb application	# Your favorite debugger.
	or this:
	othermachine% xhost +thismachine
	thismachine% gdb application
	(gdb) set environment DISPLAY othermachine:0
	(gdb) run ...

I believe CodeCenter, a C interpreter/graphical debugger has a method
of dealing with this by explicitely calling the Xlib functions to
release any grabs during breakpoints.

Debugging widget problems requires pretty good debugging skills and
knowledge of how widgets work.  You can go a long way without knowing
the internals of a particular widget but not very far without
understanding how a widget works.  Judicious use of conditional
breakpoints and adding print statements with the debugger help a great
deal.

----------------------------------------------------------------------
Subject: 26. Why don't XtAddInput(), XtAddTimeout() and XtAddWorkProc() work?
----------------------------------------------------------------------
   I have got a delicate problem with the three routines XtAddInput,
   XtAddTimeOut and XtAddWorkProc. The problem I have is that when
   I use them in my application they seem not to be registred properly.
   I have made a handy little testprogram where everything works
   perfect, but in my "real" application nothing happens. 

The introduction in R3 of the XtApp*() functions obsoleted those
routines (see Q19 for other changes in R3, R4, and R5).  What happens is
they use a default application context different then the one you may
have created.  Since events and timeouts are distributed on a per
application context basis and you are using two application contexts,
you won't get those events.

For example:

	...
	cnt = 0;
	toplevel = XtAppInitialize(&app, class,
				   Desc, XtNumber (Desc),
				   &argc, argv,
				   Fallback, args, cnt);

	XtAddTimeOut (...)
	XtAddWorkProc (...)

	XtAppMainLoop (app)

would never invoke the timeout.

----------------------------------------------------------------------
Subject: 27. What is and how can I implement drag and drop?
----------------------------------------------------------------------
(Courtesy of Roger Reynolds, rogerr@netcom.com; 19 Feb 93)

Drag-n-drop is a buzzword for moving data between clients, in an
``intuitive'' fashion.

Motif Version 1.2 supports drag-n-drop capabilities, OpenLook has
supported d-n-d all along.  The two protocols are not compatible with
each other, and so far as I know, they are not published.

I wrote a package called RDD which is designed to be a flexible public
protocol for doing drag 'n drop operations between clients.  My
intention was to provide a tool which would make it easy for people to
support a "standard" drag-n-drop protocol in the programs they develop
and contribute or sell, regardless of what widget set is used (as long
as it is based on Xt).

The implementation is based upon my understanding of the ICCCM
conventions, for more details read the code.

I have heard from dozens of people using RDD who like it and feel that
it works a whole lot better than Motif 1.2 stuff.  Also, there seem to
be many who think that it is neat but are constrained to use Motif
anyway.

The latest RDD (and some other stuff) is available for ftp from
netcom.com, in /pub/rogerr.  A (possibly older) version is also
available on ftp.x.org in /contrib.

----------------------------------------------------------------------
Subject: 28. How can I add a C++ member function as a widget callback?
----------------------------------------------------------------------
(Courtesy of lanzo@tekelec.com (Mark Lanzo), 7 Sep 1993)

You can not add a regular C++ member function as a callback to a 
widget, because the callback function won't be invoked with the
hidden object pointer "this" which all regular C++ member functions
require.  However, there is a way to get around this limitation:
"static" member functions.

A static member function is a function to which the usual scoping
and access rules apply, but which is not in fact actually associated
with a specific instance of an object, and it is NOT called using the 
special member function calling syntax.  In particular, there is no 
"this" pointer supplied to the function.  This means that a "static"
member function is really a lot like a "friend" function except that
its name is within the scope of the class (in other words, the name
is prefixed with the class name).

To demonstrate this, let's create a trivial class "Icon" which includes
a "button" widget, and a member function "select_CB" which is
installed as the "XmNselectCallback" on the button.  The class
declaration would then look something like this:

    class Icon
    {
    private:
            Widget      button;
            static void select_CB(Widget, XtPointer, XtPointer);

    public:
            Icon(Widget parent);        // Constructor
    };

For the example above, I can declare the constructor and callback
functions like this:
 
    Icon::Icon (Widget parent)
    {
	    button = XtVaCreateWidget ("icon_button", xmPushButtonWidgetClass,
				      parent, NULL);

	    //  Depending on your compiler, you may be able to specify
	    //  "&Icon::select_CB" simply as "select_CB" in the 
	    //  following statement:
	    XtAddCallback (button,  XmNselectCallback, &Icon::select_CB,
			  (XtPointer) this);
    }

    void Icon::select_CB (Widget w, XtPointer userData, XtPointer callData)
    {
	    Icon * icon = (Icon *) userData;        // Instead of "this"
 
            // do whatever you want to do when the icon is selected ...
    }

There are two things to note here:
 
 *) If you want the static member function to work on a specific 
    object, you must supply the object pointer (such as by "userData"
    in the example).  Just like a non-member function.
 
 *) Although the function is declared as "static" inside the class
    definition, you do NOT include the "static" keyword when you
    actually define the function.

----------------------------------------------------------------------
Subject: 29.!How can I identify the children of a manager widget?
----------------------------------------------------------------------

Use XtGetValues() on XtNchildren (array of widget IDs) and
XtNnumChildren (number of widgets in array).

	Widget		*children = NULL;
	Cardinal	count = 0;
	Arg		args[10];
	Cardinal	cnt;

	cnt = 0;
	XtSetArg (args[cnt], XtNchildren, &children); ++cnt;
	XtSetArg (args[cnt], XtNnumChildren, &count); ++cnt;
	XtGetValues (widget, args, cnt);

NOTE: This does not get the list of popup children.  One must access
the private members of Core to do so.

NOTE: The children may not be valid if the user is destroying widgets,
as the children may be only at phase 1 of the destroy.  So if they
destroy a child and then get the count before the child is Phase 2'd,
then it will show up -- and is probably not what most people want.


----------------------------------------------------------------------
Subject: 30. Can I use XtMoveWidget(), ... to move widgets I created?
----------------------------------------------------------------------

No.  In general, XtMoveWidget(), XtResizeWidget(),
XtMakeGeometryRequest(), and XtConfigureWidget() are for widget
internals only.  The only way for applications to change widget
geometry or configuration is through the XtSetValues() interface and
setting the XtNx, XtNy, XtNwidth and XtNheight resources.  If this
interface does not give you what you want, you should subclass the
widget to modify its geometry managers.

----------------------------------------------------------------------
Subject: 31. Why is XtGetValues() on XtNx, XtNy of my top level shell wrong?
----------------------------------------------------------------------

XtNx and XtNy are the coordinates relative to your shell's parent
window, which is usually a window manager's frame window.  To
translate to the root coordinate space, use XtTranslateCoords() or
XTranslateCoordinates().

NOTE: XtTranslateCoords() was broken in releases prior to R4.

----------------------------------------------------------------------
Subject: 32. Why do some people use XmN as resource names?
----------------------------------------------------------------------

Motif adopted the convention of prefixing all their resources with
XmN instead of XtN.  Why?  It makes some small amount of sense to not
pollute the Xt name space.  Unfortunately it is not really practical
because it means every widget set would have to define all the
resources, including ones defined by the Intrinsics.  Very messy.  But
heh, OSF is its own world, right?

----------------------------------------------------------------------
Subject: 33.!How do I make my life easier when designing an application?
----------------------------------------------------------------------

(From david@ora.com (David Flanagan) 10/2/93)
My Xmt "Motif Tools" library can also simplify application design and
development tremendously.  Its got most of the features of Wcl, but in
a more elegant (IMHO) way.  It is shareware, but cheap ($40/developer)
In early '94 it will be the subject of a book from O'Reilly
& Associates.  I've attached a blurb about it.

Wafe (Widget (Athena) Front End is good for fast prototyping of
applications in Perl or tcl.

        WINTERP -- THE OSF/MOTIF WIDGET INTERPRETER
   	by  Niels Mayer (mayer@eit.com, http://www.eit.com/people/mayer.html)
	WWW Home Page: http://www.eit.com/software/winterp/winterp.html
	Anonymous FTP: ftp://ftp.x.org/contrib/devel_tools/winterp-2.XX.tar.gz
		       (where XX represents the latest version, currently 03)
	Mailing List: winterp-request@netcom.com

WINTERP is an interactive, object-oriented, user interface language for
rapid prototyping, development and delivery of extensible applications with
Motif GUIs and Xtango graphics/animation. WINTERP 2.0 is a major update
release that is available on the X11r6 contrib distribution as well as a
number of ftp sites worldwide. WINTERP fills the same niche as TCL/TK, and
Python, while employing more proven, stable and standards-based underlying
technologies.  WINTERP uses a small, fast, object-oriented mini-Lisp
interpreter based on XLISP-PLUS (David Betz, Tom Almy, Luke Tierney, et
al), and has an object oriented interface to the OSF/Motif widget class
hierarchy, and a combination of high-level object and functional interfaces
to the Xtoolkit, Xlib, and underlying Unix system libraries.  This
environment significantly simplifies the construction of GUI-based
applications, and makes these applications easier to modify and extend
throughout the software life-cycle. WINTERP is a good tool for learning
about and experimenting with the capabilities of the OSF/Motif UI
toolkit. Its rapid prototyping features allow UI and application designers
to more easily play "what if" games with different interface styles.
   
WINTERP 2.0 features include: (1) A high-level animation/graphics
widget-class (based on Xtango by John Stasko) which lets you do the kinds
of graphics that Motif ignores, without the tedium of Xlib-level
programming; (2) The ability to easily create new widget classes employing
arbitrary graphical behavior without the tedium of programming in the Xt
intrinsics and Xlib; (3) Enable WINTERP-GUIs to communicate with multiple
asynchronous, interactive unix subprocesses, facilitating the construction
of GUI interfaces to existing line/terminal based programs. (This facility
based on Don Libes' expect library); (4) Object orientated intrface to
OSF/Motif and the Xtoolkit; (5) GUI application programming significantly
simplified via object oriented interface to Motif, automatic memory
management and automatic resource conversion; (6) Built-in RPC mechanism
allows other programs to send commands to a WINTERP-based application.

----------------------------------------------------------------------
Subject: 34. Why can't I override translations? Only the first item works.
----------------------------------------------------------------------

(Thanks to Timothy J. Horton, 5/91)

You probably have an extra space after the specification of the first 
item, like this:
	basic*text.translations:  #override \
	Ctrla:    beginning-of-line() \n\ 	
	Ctrle:    end-of-line()
					      ^ extra space
The newline after that space is ending the translation definition.

----------------------------------------------------------------------
Subject: 35. Why do I get "Warning: Widget class version mismatch"?
----------------------------------------------------------------------

This error, which typically goes on to say, "widget 11004 vs.
intrinsics 11003" indicates that the header files you included when
building your program didn't match the header files that the Xt
library you're linking against was built with; check your -I include
path and -L link-path to be sure.

However, the problem also occurs when linking against a version of the
X11R4 Xt library before patch 10; the version number was wrong.  Some
Sun OW systems, in particular, were shipped with the flawed version of
the library, and applications which link against the library typically
give the warnings you have seen.

----------------------------------------------------------------------
Subject: 36. Where can I get a good file-selector widget?
----------------------------------------------------------------------

The Free Widget Foundation set offers a FileSelector widget, with
separate directory path and file listing windows, and the
FileComplete, which has emacs-style file completion and ~ expansion.

Other available file-requestor widgets include the XiFileSelector from
Iris Software's book, the xdbx file-selector extracted by David Nedde
(daven@ivy.wpi.edu), and the FileNominator from the aXe distribution.

The GhostView, Xfig, and vimage packages also include file-selector
widgets.

----------------------------------------------------------------------
Subject: 37. Where can I find a hypertext widget or source code?
----------------------------------------------------------------------

A hypertext widget was posted to comp.sources.x.  It can be found in
volume 16 of the archives at ftp.uu.net under the name "hman".  The
distribution includes a hypertext widget with both Athena and Motif
compatibility (set at compile-time) and hman, a Motif-based man reference page
reader that uses the widget to look up other man topics.  [Joe Shelby
(shelby@dirac.physics.jmu.edu); 6/93]

----------------------------------------------------------------------
Subject: 38. What widget is appropriate to use as a drawing canvas?
----------------------------------------------------------------------

Some widget sets have a widget particularly for this purpose -- a
WorkSpace or DrawingArea which doesn't display anything but lets your Xt 
application know when it has been re-exposed, resized, and when it has received
user key and mouse input. 

The best thing to do for other widget sets -- including the Athena set 
-- is to create or obtain such a widget; this is preferable to drawing into a 
core widget and grabbing events with XtAddEventHandler(), which loses a number 
of benefits of Xt and encapsulation of the functionality .  

The publicly-available programs xball and xpic include other versions. 
The Display widget in the XG library (libXG-2.0.tar.Z on ftp.x.org) provides a 
generic way of drawing graphics in a widget.

The Athena Widget manual (mit/doc/Xaw/Template in the R5 distribution) 
includes a tutorial and source code to a simple widget which is suitable for 
use. 

The Free Widget Foundation set contains a Canvas widget.

----------------------------------------------------------------------
Subject: 39.!What is this link problem with _get_wmShellWidgetClass, XtInherit?
----------------------------------------------------------------------

Unresolved externals under SunOS 4.1.[23] is indicative of an incorrect 
configuration, specifically failure to set the OSTeenyVersion in sun.cf.

If you are running on SunOS 4.1.[23] you should apply all the fixes up
to fix-25. Make certain that you set the OSTeenyVersion correctly in 
mit/config/sun.cf.

[Above from kaleb@expo.lcs.mit.edu (Kaleb Keithley) 15 Oct 1993]

In SunOS 4.1.2 Sun fixed a shared-library bug in ld which conflicts
with the way X builds the shared Xmu library, causing these symbols,
notably, to be undefined when building some X11 clients:

	_get_wmShellWidgetClass
	_get_applicationShellWidgetClass

Compiling "-Bstatic -lXmu -Bdynamic" appears to work. 

To solve the problem if you are using OpenWindows 3.0 (X11R4-based
Xt), please contact your local Sun office and request the following
patches:

Patch i.d.      Description
100512-02       4.1.x OpenWindows 3.0 libXt Jumbo patch
100573-03       4.1.x OpenWindows 3.0 undefined symbols when using
                        shared libXmu

[Greg Earle, earle@Sun.COM; 7/92] 

A source patch for use with the MIT X11R4 libraries was developed by
Conrad Kimball (cek@sdc.boeing.com); it retrofits into R4 some fixes
made in R5 to get around this problem. The patch is on ftp.x.org in
[1/93] contrib/X11R4_sunos4.1.2_patch_version3.Z

----------------------------------------------------------------------
Subject: 40. Why does XtGetValues not work for me (sic)?
----------------------------------------------------------------------

The XtGetValues interface for retrieving resources from a widget is
sensitive to the type of variable. Your code may be doing something like this:

	{
	Arg args[3];
	int i;
	int sensitive;		/* oops; wrong data type */
	i=0;
	XtSetArg (args[i], XtNsensitive, &sensitive); i++;
	XtGetValues(widget, args, i );
	...
	}

But XtNsensitive is a Boolean, which on most machines is a single byte; 
declaring the variable "sensitive" as Boolean works properly. This problem 
comes up often when using particular toolkits that redefine the Xt types 
Dimension and Position; code that assumes they are int will have similar 
problems if those types are actually short. In general: you are safe if you
use the actual type of the resource, as it appears in the widget's man page.
[11/90]

----------------------------------------------------------------------
Subject: 41. Is this a memory leak in the X11R4 XtDestroyWidget()?!
----------------------------------------------------------------------

Yes. This is the "unofficial" fix-19 for the X11R4 Destroy.c:

*** Destroy.c.1.37	Thu Jul 11 15:41:25 1991
--- lib/Xt/Destroy.c	Thu Jul 11 15:42:23 1991
***************
*** 1,4 ****
--- 1,5 ----
  /* $XConsortium: Destroy.c,v 1.37 90/09/28 10:21:32 swick Exp $ */
+ /* Plus unofficial patches in revisions 1.40 and 1.41 */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 221,239 ****
       */
  
      int i = 0;
!     DestroyRec* dr = app->destroy_list;
      while (i < app->destroy_count) {
  	if (dr->dispatch_level >= dispatch_level)  {
  	    Widget w = dr->widget;
  	    if (--app->destroy_count)
  		bcopy( (char*)(dr+1), (char*)dr,
! 		       app->destroy_count*sizeof(DestroyRec)
  		      );
  	    XtPhase2Destroy(w);
  	}
  	else {
  	    i++;
- 	    dr++;
  	}
      }
  }
--- 222,245 ----
       */
  
      int i = 0;
!     DestroyRec* dr;
      while (i < app->destroy_count) {
+ 
+ 	/* XtPhase2Destroy can result in calls to XtDestroyWidget,
+ 	 * and these could cause app->destroy_list to be reallocated.
+ 	 */
+ 
+ 	dr = app->destroy_list + i;
  	if (dr->dispatch_level >= dispatch_level)  {
  	    Widget w = dr->widget;
  	    if (--app->destroy_count)
  		bcopy( (char*)(dr+1), (char*)dr,
! 		       (app->destroy_count - i) * sizeof(DestroyRec)
  		      );
  	    XtPhase2Destroy(w);
  	}
  	else {
  	    i++;
  	}
      }
  }

[from Donna Converse, converse@x.org]

----------------------------------------------------------------------
Subject: 42. Is this a memory leak in the X11R4 deletion of work procs?!
----------------------------------------------------------------------

Apparently the X11R4 NextEvent.c`CallWorkProc fails to properly replace
the work proc record back on the free list correctly.

        if (delete) {
            w->next = freeWorkRecs;
            freeWorkRecs = w->next;	/* should be  =w; */
        }

----------------------------------------------------------------------
Subject: 43. How do I query the user synchronously using Xt?
----------------------------------------------------------------------
	
It is possible to have code which looks like this trivial callback,
which has a clear flow of control. The calls to AskUser() block until
answer is set to one of the valid values. If it is not a "yes" answer,
the code drops out of the callback and back to an event-processing
loop:

	void quit(Widget w, XtPointer client, XtPointer call)
	{
		int             answer;
		answer = AskUser(w, "Really Quit?");
		if (RET_YES == answer)
			{
			answer = AskUser(w, "Are You Really Positive?");
			if (RET_YES == answer)
				exit(0);
                }
	}

A more realistic example might ask whether to create a file or whether
to overwrite it.

This is accomplished by entering a second event-processing loop and
waiting until the user answers the question; the answer is returned to
the calling function. That function AskUser() looks something like
this, where the Motif can be replaced with widget-set-specific code to
create some sort of dialog-box displaying the question string and
buttons for "OK", "Cancel" and "Help" or equivalents:

  int AskUser(w, string)
        Widget          w;
        char           *string;
  {
        int             answer=RET_NONE;	/* some not-used marker */
        Widget          dialog;			/* could cache&carry, but ...*/
        Arg             args[3];
        int             n = 0;
        XtAppContext    context;

        n=0;
        XtSetArg(args[n], XmNmessageString, XmStringCreateLtoR(string,
                XmSTRING_DEFAULT_CHARSET)); n++;
        XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++;
        dialog = XmCreateQuestionDialog(XtParent(w), string, args, n);
        XtAddCallback(dialog, XmNokCallback, response, &answer);
        XtAddCallback(dialog, XmNcancelCallback, response, &answer);
        XtAddCallback(dialog, XmNhelpCallback, response, &answer);
        XtManageChild(dialog);

        context = XtWidgetToApplicationContext (w);
        while (answer == RET_NONE || XtAppPending(context)) {
                XtAppProcessEvent (context, XtIMAll);
        }
        XtDestroyWidget(dialog);  /* blow away the dialog box and shell */
        return answer;
  }

The dialog supports three buttons, which are set to call the same
function when tickled by the user.  The variable answer is set when
the user finally selects one of those choices:

  void response(w, client, call)
        Widget          w;
        XtPointer client;
        XtPointer call;
  {
  int *answer = (int *) client;
  XmAnyCallbackStruct *reason = (XmAnyCallbackStruct *) call;
        switch (reason->reason) {
        case XmCR_OK:
                *answer = RET_YES;	/* some #define value */
                break;
        case XmCR_CANCEL:
                *answer = RET_NO; 
		break;
        case XmCR_HELP:
                *answer = RET_HELP;
                break;
        default:
                return;
        }
}

and the code unwraps back to the point at which an answer was needed and
continues from there.

[Thanks to Dan Heller (argv@sun.com); further code is in Dan's R3/contrib
WidgetWrap library. 2/91]

----------------------------------------------------------------------
Subject: 44. How do I simulate a button press/release event for a widget?
----------------------------------------------------------------------

You can do this using XSendEvent(); it's likely that you're not setting
the window field in the event, which Xt needs in order to match to the widget
which should receive the event.

 If you're sending events to your own application, then you can use 
XtDispatchEvent() instead. This is more efficient than XSendEvent() in that you
avoid a round-trip to the server.

Depending on how well the widget was written, you may be able to call
its action procedures in order to get the effects you want.

[courtesy Mark A. Horstman (mh2620@sarek.sbc.com), 11/90]

----------------------------------------------------------------------
Subject: 45. How to use Fallback resources (can I specify colors)?
----------------------------------------------------------------------

(Courtesy of Donna Converse, converse@x.org; 12/7/93)
See the R5 Intrinsics specification section 2.3 "Loading the 
Resource Database".   

Colors cannot be reliably specified in fallback resources.  The
only way you could force this to work would be to include in the
application the same algorithm that Xt uses to determine the display;
to open that display, determine if it is color, close the display;
and then set the appropriate fallback resources; and continue on
as usual.

The intended use of fallback resources is to provide a minimal number
of resources that will make the application usable (or at least terminate
with helpful diagnostic messages) when some problem exists in finding and 
loading the application class defaults file.

The application class defaults file is authored by the application
developer and can be used to specify default colors that apply only
to capable monitors.  

In addition, users of an Xt-based application can specify colors in
an application-specific user-specific resource file and have those
apply only to capable monitors.  The mechanism for setting this up
is introduced in R5 Xt and it is the customization resource and this
is noted in the Xt specification section 13.3.3.  Read that section,
read section 2.3, and look at this simple example for an application
whose class name is "Xmh".  (Maybe there's a tutorial about this
in one of the O'Reilly books?  Maybe I should write a book?)

The end-user must set the customization resource, at any point
earlier than when the Intrinsics goes to look for the application
defaults files.

#ifdef COLOR
Xmh.customization: -color
#endif

The application programmer supplies two application class defaults
files, and one has the string "-color" appended to the application
class name as the name of the file.  This file includes the other
file, and it also gives resources specific to color displays.  The
other file gives resources that generally apply.  

In the application class defaults file named "Xmh-color", it might say:

#include "Xmh"
xmh*borderColor: Red
xmh*background:	 Ivory

and so on.  In the application class defaults file named "Xmh"
it might say:

! AppDefaultsVersion should only be defined in the site-wide file
Xmh.AppDefaultsVersion:		1
Xmh.Geometry:			508x750
Xmh.ReplyInsertFilter:		cat
Xmh.SendBreakWidth:		2000

and so on.  The first line is a comment, and introduces another 
interesting mechanism that demonstrates how fallback resources 
can be useful in checking that the application class defaults file
is installed.  Xt will use the fallback resources only if the
application class (site-wide) defaults file is not found.  The
application itself, in this case xmh, checks the value of application
resource AppDefaultsVersion and if it is the default value, or of a
revision earlier than the application expects, it can recognize
that the correct default resources are not available and report it by 
popping up a dialog box with a message so the user can understand
what needs to be done to get these default resources.

The application class default files were intended to be modifiable by
a site administrator -- if you try to stuff all the default resources
into the fallback resources not only will you not have the power of the
customization resource but you might also have to tell people to edit
the source to change the default resources -- which is a disadvantage.

----------------------------------------------------------------------
Subject: 46. What is the preferred way of setting the application resources?
----------------------------------------------------------------------

(Courtesy of Donna Converse, converse@x.org; 1/8/94)
I advise using a site-wide application default file.

Advantages of using an application default file:

+ The site administrator can customize your application for all users
  at the site.

+ You can indicate in the application-defaults file which resources

Section 3 of 4 - Prev - Next
All sections - 1 - 2 - 3 - 4

Back to category FAQ on different themes - Discuss "comp.windows.x.intrinsics Frequently Asked Questions (FAQ)"
Home - Search - About the project - Forum - Feedback

© allanswers.org | Terms of use

rax