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

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

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


your eyes open and expect some change about the same time a language
other than C _starts_ gaining acceptance.

----------------------------------------------------------------------
Subject: 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?

The following macro is from the Athena widgets document and I am now
recomending it over the previous suggestions.

#define XtSetFloatArg(arg, n, d) \
    if (sizeof(float) > sizeof(XtArgVal)) { \
        XtSetArg(arg, n, &(d)); \
    } else { \
        XtArgVal *ld = (XtArgVal *)&(d); \
        XtSetArg(arg, n, *ld); \
    }


----------------------------------------------------------------------
Subject: 17. How do I write a resource converter?
----------------------------------------------------------------------

Courtesy of Rich Thomson (rthomson@dsd.es.com):

The following discussion of resource converters assumes R4 (or R5)
Intrinsics.  Resource converters changed between R3 and R4 to allow
for destructors and caching of converted values.

There are several main types of resource converters:

    string to data type
    data type to string
    data type to data type

i) string to data type
    Usually a string to data type converter has a fixed set of strings
    that will be converted to data type values.  This is most often
    used to map enumerated names to enumerated values:

	Name		Value
	"True"		1
	"False"		0

    In this case, the string to data type converter needs to compare
    the resource value to the list of fixed strings.  This is most
    readily accomplished by the use of the "quark" mechanism of the
    resource manager.  The resource value is turned into a quark,
    which is a unique representation of the string that fits into a
    single word.  Then the resource quark is compared against the
    quarks for the fixed strings representing the enumerated values.

    If there are many enumerated strings in the converter (or many
    converters, each with a small number of enumeration strings), then
    a global initialization routine might be used to turn all the
    resource strings into quarks.  That way, the first time one of
    these converters is used, the strings will be turned into quarks
    and held in static variables for use in the next invocation of one
    of the converters.

ii) data type to string
    This type of converter is slightly easier than the string to data
    type converters since the use of quarks isn't necessary.  Instead,
    the data type value is simply converted to a string value,
    probably by the use of sprintf.

    Data type to string converters are useful for applications that
    wish to convert an internal data type value into a string so that
    they can write out a valid resource specification to a file.  This
    mechanism can be used to provide a "snapshot" of application state
    into a file.  This snapshot can be used to restore the program to
    a known state via the usual X resource database mechanisms.

    If you are taking the trouble to write a string to data type
    converter, it isn't much extra effort to write the data type to
    string converter.  Writing both at the same time helps to ensure
    that they are consistent.

iii) data type to data type
    This type of converter is used to convert an existing data type
    value to another data type.  For instance, an X pixel value can be
    converted to an RGB data type that contains separate fields for
    red, green and blue.


The type signature for a resource converter is as follows:

typedef Boolean (*XtTypeConverter)(Display *, XrmValuePtr, Cardinal *,
	XrmValuePtr, XrmValuePtr, XtPointer *);
    Display *dpy;
    XrmValuePtr args;
    Cardinal *num_args;
    XrmValuePtr fromVal;
    XrmValuePtr toVal;
    XtPointer *converter_data;

When the converter is invoked, the "fromVal" argument points to the source
X resource manager value and the "toVal" argument points to the
destination X resource manager value.  The "converter_data" argument
is an opaque pointer to some converter-specific data that is specified
when the converter is registered.  The "args" and "num_args" arguments
allow extra information to be passed to the converter when it is
invoked.  For instance, the Pixel to RGB structure converter discussed
above would need colormap and visual arguments in which to lookup the
Pixel to obtain the RGB values corresponding to that pixel.

Care must be taken with the "toVal" argument.  An XrmValue has the
following type definition and specifies a size and location for a
converted value:

typedef struct {
    unsigned int    size;
    caddr_t         addr;
} XrmValue, *XrmValuePtr;

When the converter is invoked, the address may point to a location of
the given size for the converted value or the location can be NULL.
In the former case, the converter should ensure that the size of the
destination area is large enough to handle the converted value.  If
the destination area is not large enough, then the converter should
set the size to the amount of space needed and return False.  The
caller can then ensure that enough space is allocated and reinvoke the
converter.  If the size is large enough, then the converter can simply
copy the converted value into the space given and return True.

If the location is NULL, then the converter can assign the location to
the address of a static variable containing the converted value and
return True.

When writing a group of converters, this code is often repeated and it
becomes convenient to define a macro:

    #define DONE(var, type) \
      if (toVal->addr) \
	{ \
	  if (toVal->size < sizeof(type)) \
	    { \
	      toVal->size = sizeof(type); \
	      return False; \
	    } \
	  else \
	    *((type *) toVal->addr) = var; \
	} \
      else \
	toVal->addr = (caddr_t) &var; \
      toVal->size = sizeof(type); \
      return True;

    #define DONESTR(str) \
      if (toVal->addr && toVal->size < sizeof(String)) \
	{ \
	  toVal->size = sizeof(String); \
	  return False; \
	} \
      else \
	toVal->addr = (caddr_t) str; \
      toVal->size = sizeof(String); \
      return True;

Inside the converter, it is a good idea to perform a little safety
checking on the "num_args" and "args" arguments to ensure that your
converter is being called properly.

Once you have written your converter, you need to register it with the
Intrinsics.  The Intrinsics invokes resource converters when creating
widgets and fetching their resource values from the resource database.

To register a converter with a single application context, use
XtAppSetTypeConverter:

void XtAppSetTypeConverter(context, from, to, converter, args, num_args,
	cache, destructor)
    XtAppContext context;
    String from;
    String to;
    XtTypeConverter converter;
    XtConvertArgList args;
    Cardinal num_args;
    XtCacheType cache;
    XtDestructor destructor;

To register a converter with all application contexts, use
XtSetTypeConverter:

void XtSetTypeConverter(from, to, converter, args, num_args,
	cache, destructor)
    String from;
    String to;
    XtTypeConverter converter;
    XtConvertArgList args;
    Cardinal num_args;
    XtCacheType cache;
    XtDestructor destructor;

In the R3 Intrinsics, there were the routines XtAppAddConverter and
XtAddConverter; these have been superseded by XtAppSetTypeConverter
and XtSetTypeConverter.  Whenever possible, the newer routines should be
used.

When a converter is registered with the Intrinsics, a "cache" argument
specifies how converted resource values are to be cached:

    XtCacheNone		Don't cache any converted values
    XtCacheAll		Cache all converted values
    XtCacheByDisplay	Cache converted values on a per display basis

Caching converted values that require a round-trip to the server is a
good idea (for instance string to Pixel conversions).

The "destructor" argument is a routine that is invoked then the
resource is destroyed, either because its cached reference count has
been decremented to zero or because the widget owning the value is
being destroyed.  XtDestructor has the following type definition:

typedef void (*XtDestructor)(XtAppContext, XrmValuePtr, XtPointer,
	XrmValuePtr, Cardinal *);
    XtAppContext context;
    XrmValuePtr to;
    XtPointer converter_data;
    XrmValuePtr args;
    Cardinal *num_args;

The destructor is invoked to free any auxiliary storage associated
with the "to" argument, but does not actually free the storage pointed
to by the "to" argument itself (to->addr).  The destructor is passed
the extra arguments that were passed to the converter when the
conversion was performed (for instance, colormap and visual arguments
for the string to Pixel converter since the destructor would need to
free the allocated Pixel from the colormap) as well as the private
data passed in when the converter was registered.

Sample converter code can be found in the following files in the MIT
R5 distribution:

    mit/lib/Xt/Converters.c
    contrib/lib/PEXt/Converters.c
    contrib/lib/PEXt/Converters.h

----------------------------------------------------------------------
Subject: 18. How do I open multiple displays?
----------------------------------------------------------------------

See "Multi-user Application Software Using Xt", The X Resource, Issue 3,
(Summer 1992) by Oliver Jones for a complete coverage of the issues
involved.  Most of this answer is based on that article.  In a
nutshell, one uses XtOpenDisplay() to add each display to a _single_
application context and then XtCloseDisplay() to shutdown each display
and remove it from the application context.

The real problems occur when trying to close down a display.  This can
happen 3 ways:
	1. User selects a "quit" button on one of the displays,
	2. User has window manager send a WM_DELETE_WINDOW message,
	3. Server disconnect -- possibly from a KillClient message,
	   server shutdown/crash, or network failure.

I'll assume you can deal gracefully with 1 & 2 since it is _merely_ a
problem of translating a Widget to a display and removing that
display.  If not, then read the Oliver Jones article.

The third one is difficult to handle.  The following is based on the
Oliver Jones article and I include it here because it is a difficult
problem.

The difficulty arises because the Xlib design presumed that an I/O
error is always unrecoverable and so fatal.  This is essentially true
for a single display X based application, but not true for a
multiple display program or an application that does things other than
display information on an X server.  When an X I/O error occurs the
I/O error handler is called and _if_ it returns then an exit()
happens.  The only way around this is to use setjmp/longjmp to avoid
returning to the I/O error handler.  The following code fragment
demonstrates this:

#include 
jmp_buf XIOrecover;

void
XIOHandler (dpy)
	Display		*dpy;
{
	destroyDisplay (dpy);
	longjmp (XIOrecover, 1);
}

main ()
{
	...
	if (setjmp (XIOrecover) == 0)
		XSetIOErrorHandler (XIOHandler);
	XtAppMainLoop (app_context);
}

The destroyDisplay() is something that given a Display pointer can go
back to the application specific data and perform any necessary
cleanup.  It should also call XtCloseDisplay().

For those of you unfamiliar with setjmp/longjmp, when setjmp() is
first called it returns a 0 and save's enough information in the
jmp_buf that a latter execution of longjmp() can return the program to
the same state as if the setjmp() was just executed.  The return value
of this second setjmp() is the value of the second argument to
longjmp().  There are several caveats about using these but for this
purpose it is adequate.

Some other problems you might run into are resource converters that
improperly cache resources.  The most likely symptoms are Xlib errors
such as BadColor, BadAtom, or BadFont.  There may be problems with the
total number of displays you can open since typically only a limited
number of file descriptors are available with 32 being a typical
value.  You may also run into authorization problems when trying to
connect to a display.

There was much discussion in comp.windows.x about this topic in
November of 91.  Robert Scheifler posted an article which basically
said this is the way it will be and Xlib will not change.

----------------------------------------------------------------------
Subject: 19. What changed from R3 to R4 to R5?
----------------------------------------------------------------------

This addresses only changes in the Intrinsics.  First, the general
changes for each release are described.  Then a, certainly incomplete,
list of new functions added and others that are now deprecated are
listed.  Brevity is a primary goal.

Much of the following information is retrieved from Chapter 13 of the MIT
Xt Intrinsics Manual and from O'Reilly Volume 5, 3rd edition.

From R3 to R4
- Addition of gadgets (windowless widgets)
- New resource type converter interface to handle cacheing and
  additional  data.
- Variable argument list interface.
- #define XtSpecificationRelease 4  (added with this release)
- WMShellPart, TopLevelShellPart & TransientShellPart changed
  incompatibly.
- core.initialize, core.set_values added ArgList and count parameters
- event handlers had continue_to_dispatch parameter added
- core.set_values_almost specification changed.
- core.compress_exposure changed to an enumerated data type from Boolean
- core.class_inited changed to enumerated data type from Boolean
- constraint.get_values_hook added to extension record
- core.initialize_hook obsolete as info is passed to core.initialize
- shell.root_geometry_manager added to extension record
- core.set_values_hook obsolete as info is passed to core.set_values
- Calling XtQueryGeometry() must store complete geometry.
- Added UnrealizeCallback.
- XtTranslateCoords() actually works under R4.

From R4 to R5:
- Psuedo resource baseTranslation added.
- Searching for app-default, and other files, made more flexible
- customization resource added.
- Per-screen resource database.
- Support permanently allocated strings.
- Permanetly allocated strings required for several class fields.
- The args argument to XtAppInitialize, XtVaAppInitialize,
  XtOpenDisplay, XtDisplayInitialize, and XtInitialize were changed
  from Cardinal* to int*
- Many performance improvements (this is summarized from the article
  "Xt Performance Improvements in Release 5" by Gabe Beged-Dov in "The
  X Resource", Issue 3):
	- XrmStringToQuark() augmented with XrmPermStringToQuark() to
	  avoid string copies.  Several fields in the class record are
	  indicated as needing permanent strings.
	- Using an array of Strings for resources
	- Callback lists redesigned to use less memory
	- Translation manager redesigned and rewritten so it takes
	  less memory, translation tables merges are faster, cache of
	  action bindings
	- Keycode to Keysyms are cached.
	- Better sharing of GC's with modifiable fields
	- Window to Widget translation uses less space and faster
	- Does not malloc space for widget name since quark is available
	- Widget space is allocated to include the constraints
	- Over several example programs, about a 26% reduction in
	  memory usage.

Functions new with R5:
----------------------
XtAllocateGC()		- sharable GC with modifiable fields  
XtGetActionList()	- get the action table of a class
XtScreenDatabase()	- return resource database for a screen
XtSetLanguageProc()	- register language procedure called to set locale


Functions new with R4:
----------------------
XtAppAddActionHook()	- procedure to call before _every_ action.
XtAppInitialize()	- lots of initialization work.
XtAppReleaseCacheRefs()	- decrement cache reference count for converter
XtAppSetFallbackResources() - specify default resources
XtAppSetTypeConverter()	- register a new style converter
XtCallCallbackList()	- directly execute a callback list
XtCallConverter	()	- invoke a new style converter
XtCallbackReleaseCacheRef() - release a cached resource value
XtCallbackReleaseCacheRefList() - release a list of cached resource values
XtConvertAndStore()	- find and call a resource converter
XtDirectConvert()	- Invoke old-style converter
XtDisplayOfObject()	- Return the display
XtDisplayStringConversionWarning() - issue a warning about conversion
XtFindFile()		- Find a file
XtGetActionKeysym()	- Retrieve keysym & modifies for this action
XtGetApplicationNameAndClass() - return name and class
XtGetConstraintResourceList() - get constraints for a widget
XtGetKeysymTable()	- return keycode-to-keysym mapping table
XtGetMultiClickTime()	- read the multi-click time
XtGetSelectionRequest()	- retrieve the SelectionRequest event
XtGetSelectionValueIncremental() - obtain the selection value incrementally
XtGetSelectionValuesIncremental() - obtain the selection value incrementally
XtInitializeWidgetClass() - initialize a widget class manually
XtInsertEventHanlder()	- register event handler before/after others
XtInsertRawEventHandler() - register event handler without modify input mask
XtIsObject()		- test if subclass of Object
XtIsRectObj()		- test if subclass of RectObj
XtKeysymToKeyCodeList()	- return list of keycodes
XtLastTimestampProcessed() - retrieve most recent event time
XtMenuPopdown		- Action for popping down a widget
XtMenuPopup		- Action for popping up a widget
XtOffsetOf		- macro for structure offsets
XtOwnSelectionIncremental() - make selection data availabe incrementally
XtPoupSpringLoaded()	- map a spring-loaded popup
XtRegisterGrabAction()	- indicate action procedure needs a passive grab
XtRemoveActiohHook()	- remove function called after every action
XtResolvePathname()	- find a file
XtScreenOfObject()	- return screen of object.
XtSetMultiClickTime()	- set the multi-click time
XtSetWMColormapWindows() - set WM_COLORMAP_WINDOWS for custom colormaps
XtUngrabButton()	- cancel a passive button grab
XtUngrabKey()		- cancel a passive key grab
XtUngrabKeybard()	- release an active keyboard grab
XtUngrabPointer()	- release an active pointer grab
XtVa*()			- varags interfaces to a bunch of functions
XtWindowOfObject()	- return Window of nearest widget ancestor


Deprecated		Replacement			When
----------------------------------------------------------------------
XtAddActions()		XtAppAddActions()		R3
XtAddConverter()	XtAppAddConverter()		R3
XtAddInput()		XtAppAddInput ()		R3
XtAddTimeout()		XtAppAddTimeout()		R3
XtAddWorkProc()		XtAppAddWorkProc()		R3
XtConvert()		XtConvertAndStore()		R4
XtCreateApplicationShell XtAppCreateShell()		R3
XtDestroyGC()		XtReleaseGC()			R3
XtError()		XtAppError()			R3
XtGetErrorDatabase()	XtAppGetErrorDatabase		R3
XtGetErrorDatabaseText() XtAppGetErrorDatabaseText	R3
XtGetSelectionTimeout()	XtAppGetSelectionTimeout	R3
XtInitialize()		XtAppInitialize()		R3
XtMainLoop()		XtAppMainLoop()			R3
MenuPopdown(action)	XtMenuPopdown(action)		R4
MenuPopup(action)	XtMenuPopup(action)		R4
XtNextEvent()		XtAppNextEvent()		R3
XtPeekEvent()		XtAppPeekEvent()		R3
XtPending()		XtAppPending()			R3
XtSetErrorHandler()	XtAppSetErrorHandler()		R3
XtSetErrorMsgHandler	XtAppSetErrorMsgHandler()	R3
XtSetSelectionTimeout()	XtAppSetSelectionTimeout()	R3
XtSetWarningHandler()	XtAppSetWarningHandler()	R3
XtSetWarningMsgHandler() XtAppSetWarningMsgHandler()	R3
XtWarning()		XtAppWarning()			R3
XtWarningMsg()		XtAppWarningMsg()		R3

----------------------------------------------------------------------
Subject: 20. Where are the resources loaded from?
----------------------------------------------------------------------

The resources of a widget are filled in from the following places
(from highest priority to lowest priority):

	1. Args passed at creation time.
	2. Command line arguments.
	3. User's per host defaults file
	4. User's defaults file.
	5. User's per application default file.
	6. System wide per application default file.

Note that 2-6 are read only once on application startup.  The result
of steps 3-6 is a single resource database used for further queries.

The per host defaults file contains customizations for all
applications executing on a specific computer.  This file is either
specified with the XENVIRONMENT environment variable or if that is not
set then the file $HOME/.Xdefaults- is used.

The user defaults file is either obtained from the RESOURCE_MANAGER
property on the root window of the display or if that is not set then
the file $HOME/.Xdefaults is used.  Typically, the program "xrdb" is
used to set the RESOURCE_MANAGER property.  Please note that this
should be kept relatively small as each client that connects to the
display must transfer the property.  A size of around 1-3KByte is
reasonable.  Some toolkits may track changes to the RESOURCE_MANAGER
but most do not.

A user may have many per application default files containing
customizations specific to each application.  The intrinsics are quite
flexible on how this file is found.  Read the next part that describes
the various environment variables and how they effect where this file
is found.

The system wide per application default files are typically found in
/usr/lib/X11/app-defaults.  If such a file is not found then the
fallback resources are used.  The intrinsics are quite flexible on how
this file is found.  Read the next part that describes the various
environment variables and how they effect where this file is found.

[Thanks to Oliver Jones (oj@pictel.com) for the following, 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/app-defaults/%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.

NOTE: when looking for app-default files with XUSERFILESEARCHPATH,
      for some  bizarre reason, neither the type nor file suffix is
      defined so %T and %S are useless.

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/app-defaults/%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.


----------------------------------------------------------------------
Subject: 21. What order are callbacks executed in?
----------------------------------------------------------------------
(Courtesy of Donna Converse, converse@x.org; 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 so 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.

----------------------------------------------------------------------
Subject: 22. How do I know if a widget is visible?
----------------------------------------------------------------------
(Courtesy of Donna Converse, converse@x.org; 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.

----------------------------------------------------------------------
Subject: 23. How do I reparent a widget in Xt, i.e. XtReparentWidget()?
----------------------------------------------------------------------

You can't.

----------------------------------------------------------------------
Subject: 24. Why use XtMalloc, XtFree, etc?
----------------------------------------------------------------------

Unfortunately, most code that calls malloc(), realloc() or calloc()
tends to ignore the possibility of returning NULL.  At best it is
handled something like:

	ptr = (type *) malloc (sizeof (type))
	if (!ptr)
	{
		perror ("malloc in xyzzy()");
		exit (1)
	}
To handle this common case the Intrinsics define the functions
XtMalloc(), XtCalloc(), XtNew(), XtNewString() and XtRealloc() which
all use the standard C language functions malloc(), calloc() and
realloc() but execute XtErrorMsg() if a NULL value is returned.  Xt
error handlers are not supposed to return so this effectively exits.

In addition, if XtRealloc() is called with a NULL pointer, it uses
XtMalloc() to get the initial space.  This allows code like:

	if (!ptr)
		ptr = (type *) malloc (sizeof (type));
	else
		ptr = (type *) realloc (ptr, sizeof (type) * (count + 1));
	++count;

to be written as:

	ptr = XtRealloc (ptr, sizeof (ptr) * ++count);

Also, XtFree() accepts a NULL pointer as an argument.  Generally, I've
found the Xt functions conveniant to use.  However, anytime I'm
allocating anything potentially large I use the standard functions so
I can fully recover from not enough memory errors.

XtNew() and XtNewString() are conveniant macros for allocating a
structure or copying a string:

	  struct abc *xyzzy;
	  char	     *ptr;
	  char	     *str = "abcdef";

	  xyzzy = XtNew (struct abc);	/* takes care of type casting */
	  ptr = XtNewString (str);

A strict interpretation of the Intrinsics reference manual allow an
implementation to provide functions that are not exchangable with
malloc() and free().  I.e. code such as:

	 char	      *ptr;

	 ptr = XtMalloc (100);
	 /* ... */
	 free (ptr);

may not work.  Personally, I'd call any implementation that did this
broken and complain to the vendor.

A common error for Motif programmers is to use XtFree() on a string
when they should really be using XmStringFree().

----------------------------------------------------------------------
Subject: 25. How to debug an Xt application?
----------------------------------------------------------------------

Section 2 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