The PrimitiveClassPart structure is the second chunk of the widget class record. In the PrimitiveClassPart structure, you must define values for seven different fields. For example, following is the PrimitiveClassPart structure of the ExmSimple widget:
{ /* border_highlight */ XmInheritBorderHighlight, /* border_unhighlight */ XmInheritBorderUnhighlight, /* translations */ XtInheritTranslations, /* arm_and_activate */ NULL, /* syn_resources */ syn_resources, /* num_syn_resources */ XtNumber(syn_resources), /* extension */ (XtPointer)&primClassExtRec, },
The following subsections detail the fields of the PrimitiveClassPart structure.
The border_highlight field holds the name of a method that highlights the perimeter of the widget. The border_highlight method is typically called by the Redisplay method.
You should probably set the border_highlight field to one of the following:
Most primitive widgets should inherit the border_highlight method of XmPrimitive. The border_highlight method of XmPrimitive provides the standard Motif highlighting style for primitive widgets. In particular, the border_highlight method of XmPrimitive does the following:
If you do write your own border_highlight method, it must have the following prototype:
void BorderHighlight( Widget w)
where widget specifies the widget ID.
If you do write your own border_highlight method, you should probably use the XmeDrawHighlight function to draw the border highlight. In addition, your border_highlight method must set the value of instance data member primitive.highlighted to True immediately after drawing the border highlight.
The ExmTabButton and ExmMenuButton widgets both have special requirements for border highlights. Therefore, both of these widgets provide their own border_highlight methods rather than inherit them.
The border_unhighlight field holds the name of a method that removes a widget's border. For example, if your primitive widget has a different background color than its parent, then it may be wise to remove the border (possibly in preparation for a redraw of the border). You should probably set the border_unhighlight field to one of the following:
If the border_highlight field of your widget is set to XmInheritBorderHighlight, then you should set the border_unhighlight field to XmInheritBorderUnhighlight.
The border_unhighlight method of XmPrimitive does the following:
If you do write your own border_unhighlight method, it must have the following prototype:
void BorderUnhighlight( Widget w)
where widget specifies the widget ID.
If your widget provides its own border_unhighlight method, then it must set the value of instance data member primitive.highlighted to False. To remove highlights, your method should probably call the same internal function that drew the highlights, namely, XmeDrawHighlight . One trick to unhighlighting is to paint over the existing highlight with the background color and background pixmap of your widget's parent. Your widget's parent stores its background color and background pixmap in the manager.background_GC instance data member.
The translations field holds a string that implements your widget's keyboard traversals. The complete keyboard traversal policy depends not only on the value of the translations field but also on the values of two resources.
You can set this field to one of the following:
(See Chapter 7 for details.)
The arm_and_activate field holds the name of a method that is activated by an osfActivate event. The named method must provide the visual simulation of a push button being pushed in as a response to the osfActivate event.
Your widget should specify one of the following for the arm_and_activate field:
In the standard Motif widget set, all the button widgets provide an arm_and_activate method. All other primitive widgets set this field to NULL.
The ExmCommandButton widget provides the following arm_and_activate method:
static void ArmAndActivate ( Widget w, XEvent *event, String *params, Cardinal *num_params) { ExmCommandButtonWidgetClass wc = (ExmCommandButtonWidgetClass)XtClass(w); ExmCommandButtonWidget cw = (ExmCommandButtonWidget)w; XmAnyCallbackStruct cb; /* Call DrawShadow. */ cw->command_button.visual_armed = True; if (wc->simple_class.draw_shadow) (*(wc->simple_class.draw_shadow)) (w); /* Eliminate any data waiting in the X Window's output buffer. */ XFlush (XtDisplay (cw)); /* Assuming that the XmNactivateCallback resource is set, call the callback routine. */ if (cw->command_button.activate_callback) { cb.reason = XmCR_ACTIVATE; cb.event = event; XtCallCallbackList((Widget)cw, cw->command_button.activate_callback, &cb); } /* Provide a short delay prior to the appearance of any new windows created by the callback. The net effect is that the ExmCommandButton will appear to flash on and off immediately prior to the appearance of any window that may overwrite it. */ if ((cw->core.being_destroyed == False) && (cw->command_button.visual_timer == 0)) cw->command_button.visual_timer = XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)cw), (unsigned long) VISUAL_DELAY, VisualDisarm, /* method that disarms */ (XtPointer)(cw)); /* pass this widget to VisualDisarm */ }
The syn_resources field holds the name of the array that defines the widget's synthetic resources. Synthetic resources provide a mechanism for translating widget resource values between different formats. (See Chapter 6 for information on synthetic resources.)
Most primitive widgets in the standard Motif widget set provide a syn_resources array.
If you do not wish to define synthetic resources for your widget, set the value of this field to NULL.
The num_syn_resources field holds the number of synthetic resources defined by the array in the syn_resources field. If your widget does not provide a syn_resources array, then you should specify 0 for the num_syn_resources field. If your widget does provide a syn_resources array, then your widget should use the the XtNumber macro to count these resources.
Nearly every primitive widget displays text or graphics. Any widget that does must specify a primitive class extension record. The extension field holds an XtPointer to the name of this record. You should always name your primitive class extension record primClassExtRec; for example:
/* extension */ (XtPointer)&primClassExtRec,
If your primitive widget does not display any text or graphics, then you should set the extensions field to NULL. If your primitive widget does need to define an extension record, see the next section for details.