You define the resources of a Motif widget as you would define resources for any Intrinsics-based widget. Each resource is defined in a seven-field resource record. For example, the ExmString widget defines a resource record for a new XmNalignment resource as follows:
static XtResource resources[] = { { XmNalignment, /* name of resource */ XmCAlignment, /* class of resource */ XmRAlignment, /* representation type of resource value */ sizeof(unsigned char), /* space to hold resource value */ /* the next field defines the position of the resource within the class record */ XtOffsetOf( ExmStringRec, string.alignment), XmRImmediate, /* kind of default value */ (XtPointer) XmALIGNMENT_CENTER /* default value */ }, }
The third field of each resource record should contain the name of a Motif representation type. We will detail Motif representation types later in this chapter.
Overriding the default of an inherited resource is straightforward. The subclass simply needs to redefine the resource. For example, the XmPrimitive widget defines the XmNhighlightThickness resource and sets its default value to 2. However, the ExmString widget needs to change its default value from 2 to 0. Therefore, the resource table of ExmString contains the following code:
static XtResource resources[] = { { XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension, sizeof(Dimension), XtOffsetOf( XmPrimitiveRec, primitive.highlight_thickness), XmRImmediate, (XtPointer) 0 /* new default value */ }, }
The sixth field of most resource records is set to XmRImmediate, meaning that the seventh field holds the resource's default value. However, you may wish to have Motif calculate the resource's default value at runtime. In order to do so, you must do the following:
For example, consider the following definition of the XmNrenderTable resource from the ExmString demonstration widget:
{ XmNrenderTable, XmCRenderTable, XmRRenderTable, sizeof(XmRenderTable), XtOffsetOf( ExmStringRec,string.render_table), XtRCallProc, (XtPointer) DefaultFont },
The function specified in the seventh field must take three arguments:
For example, the DefaultFont function is coded as follows:
static void DefaultFont ( Widget w, int offset, XrmValue *value) { ExmStringWidgetClass wc = (ExmStringWidgetClass)XtClass(w); static XmRenderTable f1; /* Find the default render table associated with the default render table type. */ f1 = XmeGetDefaultRenderTable (w, wc->string_class.default_render_table_type); value->addr = (XtPointer)&f1; value->size = sizeof(f1); }
The XmeGetDefaultPixel function is particularly useful for dynamic resource defaulting. This function returns the default background, foreground, top shadow, bottom shadow, or select colors for a given widget. For example, suppose you are creating a widget that displays a graph. Further suppose that your widget defines a new resource called XmNgraphSelectColor, which holds the select color of the new widget. Suppose you want the XmNgraphSelectColor resource to have a default value equal to the default select color of the widget. To do this, you must first define the resource record to take an XmRCallProc as follows:
{ XmNgraphSelectColor, XmCGraphSelectColor, XmRPixel, sizeof(Pixel), XtOffsetOf(MyGraphRec, graph.graph_select_color), XmRCallProc, (XtPointer) GetDefaultSelectColor },
Then, you have to write a function that calls XmeGetDefaultPixel; for example:
static void GetDefaultSelectColor( Widget widget, int offset, XrmValue *value) { XmeGetDefaultPixel (widget, XmSELECT, offset, value); }