So far, we have focused on the work that widgets do to implement a UTM data transfer. However, it is possible that a Motif application will implement some or even all of a UTM data transfer. UTM allows application programmers to register two kinds of callbacks:
In addition, an application's XmNdestinationCallback procedure can provide its own transfer procedure.
UTM automatically calls any XmNconvertCallback procedures immediately prior to calling the convertProc trait method of the source widget. UTM automatically passes an XmConvertCallbackStruct to the application's XmNconvertCallback procedures. These procedures are free to modify the fields of this structure. UTM will pass this structure, modifications and all, to your source widget's convertProc trait method.
If the application does not provide any XmNconvertCallback procedures, then UTM simply calls the convertProc trait method. If the application does provide XmNconvertCallback procedures, then UTM conditionally calls convertProc depending on the value in the status member of the XmConvertCallbackStruct. If the status member holds XmCONVERT_DONE or XmCONVERT_REFUSE, then UTM will not call the source widget's convertProc trait method. If the status member holds some other value, then UTM will call the source widget's convertProc trait method.
Throughout this chapter, we use the term "conversion routines" to refer to a combination of the XmNconvertCallback procedures of the application and the convertProc trait method of the source widget.
UTM automatically calls any XmNdestinationCallback procedures immediately prior to calling the destinationProc trait method.
Throughout this chapter, we use the term "destination routines" to refer to a combination of the XmNdestinationCallback procedures of the application and the destinationProc trait method of the destination widget.
Broadly speaking, an application's UTM callbacks can interact with your widget's UTM trait methods in any of the following three ways:
In case 1, your widget must be prepared to do all the conversion and transfer work itself. Preparing for this case simply means that your widget's UTM trait methods must be self-sufficient. In other words, your widget must handle all the targets that your widget documentation says it handles.
In case 2, your widget's UTM trait methods never get called.
In case 3, your widget's UTM trait methods must react appropriately to data passed by the application's UTM callback procedures. Consider the following situation. Suppose you write a widget that displays text. Being a good widget writer, you code your widget so that its UTM trait methods support all the standard textual targets. However, suppose an application programmer decides to supplement your widget's list of targets by writing a UTM application callback that supports an additional textual target, _FORMATTED_TEXT. Therefore, the following things must happen:
Of the preceding three bulleted items, only the first requires extra coding by the widget writer. When an application adds a new target, the application must set the status member of the XmConvertCallbackStruct to XmCONVERT_MERGE. (Remember that UTM automatically passes an XmConvertCallbackStruct to your widget's convertProc trait method.) Therefore, your widget's convertProc trait method should always examine the status member to see if it holds XmCONVERT_MERGE. If it does, convertProc should call XmeConvertMerge. The following code illustrates how this is done:
if (cs -> status == XmCONVERT_MERGE) { XmeConvertMerge(value, type, format, length, cs); XtFree((char *) value); }
The XmeConvertMerge routine merges two groups of list-like targets. In this case, XmeConvertMerge merges the sole target from the application _FORMATTED_TEXT with the list of targets already supported by your widget.