XtTypeConverter()XtTypeConverter()NameXtTypeConverter - interface definition for a new-style resource con‐
verter.
Synopsis
typedef Boolean (*XtTypeConverter)(Display *, XrmValue *, Cardinal *,
XrmValue *, XrmValue *, XtPointer *);
Display *display;
XrmValue *args;
Cardinal *num_args;
XrmValue *from;
XrmValue *to_in_out;
XtPointer *converter_data;
Inputs
display Specifies the Display connection with which this conversion
is associated.
args Specifies a list of additional XrmValue arguments to the con‐
verter, or NULL.
num_args Specifies the number of arguments in args.
from Specifies the address and size of the value to convert.
to_in_out Specifies the address at which the converted value is to be
stored, or NULL, and the number of bytes allocated for the
value at that address.
Outputs
to_in_out Returns the address at which the converted value was stored,
and the actual number of bytes occupied by that value.
converter_data
Returns arbitrary data which will be passed to the destructor
procedure, if any, associated with this converter when the
converted resource is freed from the resource cache.
Returns
True if the conversion was successful; False otherwise.
Availability
Release 4 and later.
Description
An XtTypeConverter is a "new-style" resource converter registered with
XtAppSetTypeConverter() or XtSetTypeConverter(). It is invoked by the
Intrinsics to convert resource values between the types for which it is
registered, or can be invoked explicitly with XtConvertAndStore() or
XtCallConverter().
An XtTypeConverter should convert the value pointed to by from->addr
(which is from->size bytes long) into the appropriate type and store
the converted value at to_in_out->addr. If this pointer is NULL, the
converter should store the converted value in its own storage and place
the size and address of this storage into to_in_out. This memory
remains under the ownership of the converter and must not be modified
by the caller. The type converter is permitted to use static storage
for this purpose and therefore the caller must immediately copy the
data upon return from the converter.
If to_in_out->addr is not NULL, the converter must check the size field
to insure that sufficient space has been allocated before storing the
converted value.
· If insufficient space is specified, the converter should update the
size field to indicate number of bytes required and should return
False without modifying the data pointed to by the addr field.
· If sufficient space was allocated by the caller, the converter
should store the converted value at the location pointed to by the
addr field and set the size field to the number of bytes actually
occupied by the converted value.
For converted values of type XtRString, the size should include the
NULL-terminating byte, if any.
The converter may return any value it wishes in converter_data; this
data is similar to the client_data argument to a callback and will be
passed to the destructor, if any, associated with this converter when
the resource value is freed by the Intrinsics. See XtDestructor(2) for
more information.
The args argument is an array of values (such as a Screen pointer or
Colormap ID) that the converter may need to perform the conversion.
The contents and interpretation of this array are determined by the
XtConvertArgList array supplied when the converter is registered. The
Intrinsics use the XtConvertArgList to compute an array of XrmValue to
pass to the converter each time it is invoked. An XtTypeConverter that
expects values in its args argument must be registered with a suitable
XtConvertArgList or it will not work correctly. See XtAppSetTypeCon‐
verter() for information on declaring XtConvertArgList arrays.
The display argument to an XtTypeConverter may be used by some convert‐
ers in the conversion process, and is also needed to obtain the appli‐
cation context (with the function XtDisplayToApplicationContext()) in
order to report warning messages. Note that one of the primary differ‐
ences between "new-style" and "old-style" converters is that new-style
converters have this display argument.
An XtTypeConverter should return True if the conversion was successful
and return False otherwise. If the conversion cannot be performed due
to an improper source value, a warning message should be issued with
XtAppWarningMsg() or XtDisplayStringConversionWarning().
Usage
Note that the num_args argument is a pointer to the number of elements
in args, and not the number of arguments itself. Be sure to derefer‐
ence this argument correctly before using it.
An XtTypeConverter must check both the addr and size fields of its
to_in_out argument, and be prepared to return the converted value in
different ways depending on the values in these fields. To encapsulate
all the requirements for returning a converted value, the standard con‐
verters defined by the Intrinsics all call a macro named done() which
is passed the converted value and returns it in the correct way depend‐
ing on the to_in_out argument. This done() macro is shown in the exam‐
ple below.
All type converters should define some set of values for which they are
guaranteed to succeed, so that these values can be used as widget and
application resource defaults. For some string converters, this may
mean defining a string value which will be handled specially by the
converter. It is useful if you give this string a symbolic name. The
special constants XtDefaultFont, XtDefaultForeground, and XtDefault‐
Background are strings of this type which are specially recognized by
their converters.
If you write a widget that has a resource which is of some enumerated
type, you should write a converter routine which will convert between
the symbolic names of each value and the values themselves. This con‐
verter should then be registered in your widget's class_initialize()
method.
If you are writing a programming library or an application that defines
non-standard types, it may be useful to provide string converters for
those types. This allows resources of that type to be specified from a
resource file. An application that supported user-configurable popup
menus, for example, might include a String-to-Menu converter.
If your converter needs additional arguments to perform the conversion,
you should declare and export the XtConvertArgList array to be regis‐
tered with the converter, or at least document the array that must be
registered. Since the wrong arguments will likely cause your converter
to dump core, you should consider defining the argument list part of
the process of writing the converter. Note that there are also two
XtConvertArgLists predefined by the Intrinsics: screenConvertArg passes
the widget's screen field to the converter in args[0], and colorConver‐
tArgs passes the widget's screen field to the converter in args[0] and
the widget's colormap field in args[1].
A type converter may invoke other converters to aid with its conver‐
sion. When converting complex types, this is a good idea because it
allows differing source types that convert into a common intermediate
type to make maximum use of the type converter cache.
The Intrinsics define a number of standard converters which do not need
to be registered. See XtConvertAndStore() for a list of these prede‐
fined converters. There are also a number of other useful converters
defined in the Xmu library which do need to be registered explicitly.
See XmuCvtStringToMisc(6).
Example
The done() macro below is from the X11R5 Intrinsics. It is used to
return a converted resource value correctly depending on the to_in_out
argument (which is here given the name toVal). Note that the type
argument is used to declare a static variable to store the value in
when to_in_out (or toVal) does not provide a location to store it.
#define done(type, value) { if (toVal->addr != NULL) { if (toVal->size < sizeof(type)) { toVal->size = sizeof(type); return False; } *(type*)(toVal->addr) = (value); } else { static type static_val; static_val = (value); toVal->addr = (XPointer)&static_val; } toVal->size = sizeof(type); return True; }
An XtTypeConverter from the X11R5 Intrinsics to convert between a
string and a Pixel is shown below, along with the XtConvertArgList that
it must be registered with. Note how it checks num_args and then
determines the screen and colormap from its args argument. Also note
that it tests for two special values: the strings with symbolic names
XtDefaultForeground and XtDefaultBackground. It is guaranteed to suc‐
cessfully convert these values. The pd variable is an Intrinsics
internal structure, and pd->rv indicates whether or not the reverseV‐
ideo application resource is specified in the resource database.
This converter returns a Boolean in its converter_data argument (called
closure_ret here) which indicates to the resource destructor whether or
not it should deallocate the color. The pixels associated with XtDe‐
faultForeground and XtDefaultBackground are never deallocated. See
XtDestructor(2) for the destructor procedure that accompanies this con‐
verter.
Finally, note that this converter uses the done macro five times, which
is inefficient because it expands to a large macro. With some simple
reorganization, it need only be called once.
XtConvertArgRec Const colorConvertArgs[] = {
{XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
sizeof(Screen *)},
{XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
sizeof(Colormap)}
};
Boolean XtCvtStringToPixel(dpy, args, num_args, fromVal, toVal, closure_ret)
Display* dpy;
XrmValuePtr args;
Cardinal *num_args;
XrmValuePtr fromVal;
XrmValuePtr toVal;
XtPointer *closure_ret;
{
String str = (String)fromVal->addr;
XColor screenColor;
XColor exactColor;
Screen *screen;
XtPerDisplay pd = _XtGetPerDisplay(dpy);
Colormap colormap;
Status status;
String params[1];
Cardinal num_params=1;
if (*num_args != 2) {
XtAppWarningMsg(pd->appContext, XtNwrongParameters, "cvtStringToPixel",
XtCXtToolkitError,
"String to pixel conversion needs screen and colormap arguments",
(String *)NULL, (Cardinal *)NULL);
return False;
}
screen = *((Screen **) args[0].addr);
colormap = *((Colormap *) args[1].addr);
if (CompareISOLatin1(str, XtDefaultBackground) == 0) {
*closure_ret = False;
if (pd->rv) done(Pixel, BlackPixelOfScreen(screen))
else done(Pixel, WhitePixelOfScreen(screen));
}
if (CompareISOLatin1(str, XtDefaultForeground) == 0) {
*closure_ret = False;
if (pd->rv) done(Pixel, WhitePixelOfScreen(screen))
else done(Pixel, BlackPixelOfScreen(screen));
}
status = XAllocNamedColor(DisplayOfScreen(screen), colormap,
(char*)str, &screenColor, &exactColor);
if (status == 0) {
String msg, type;
params[0] = str;
/* Server returns a specific error code but Xlib discards it. Ugh */
if (XLookupColor(DisplayOfScreen(screen), colormap, (char*)str,
&exactColor, &screenColor)) {
type = "noColormap";
msg = "Cannot allocate colormap entry for \"%s\"";
}
else {
type = "badValue";
msg = "Color name \"%s\" is not defined";
}
XtAppWarningMsg(pd->appContext, type, "cvtStringToPixel",
XtCXtToolkitError, msg, params, &num_params);
*closure_ret = False;
return False;
} else {
*closure_ret = (char*)True;
done(Pixel, screenColor.pixel);
}
}
Structures
The XrmValue structure is defined as follows:
typedef struct {
unsigned int size;
XPointer addr;
} XrmValue, *XrmValuePtr;
See AlsoXtAppSetTypeConverter(1), XtCallConverter(1), XtConvertAndStore(1),
XtDisplayStringConversionWarning(1), XtSetTypeConverter(1),
XmuCvtStringToMisc(6).
Xt - Resource Management XtTypeConverter()