Top Document: comp.windows.x.intrinsics Frequently Asked Questions (FAQ) Previous Document: 16. How do I pass a float value to XtSetValues? Next Document: 18. How do I open multiple displays? See reader questions & answers on this topic! - Help others by sharing your knowledge ---------------------------------------------------------------------- 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 User Contributions:Top Document: comp.windows.x.intrinsics Frequently Asked Questions (FAQ) Previous Document: 16. How do I pass a float value to XtSetValues? Next Document: 18. How do I open multiple displays? Single Page [ Usenet FAQs | Web FAQs | Documents | RFC Index ] Send corrections/additions to the FAQ Maintainer: ware@cis.ohio-state.edu
Last Update March 27 2014 @ 02:11 PM
|
Comment about this article, ask questions, or add new information about this topic: