This section details primary transfers.
A primary transfer involves interaction among a user, an application, a source widget, and a destination widget. Following are the steps involved in a typical primary transfer:
The ExmStringTransfer demonstration widget supports primary transfer. The following translations are relevant to the primary transfer:
<Btn1Down>: ExmStringTransferMoveFocus()ExmStringTransferCopyPrimary()\n\ <Btn2Down>: ExmStringTransferProcessDrag()\n\
A user starts a primary copy by pressing Btn1Down. However, the Btn2Down translation is far more puzzling because Btn2Down could mean either a primary paste or the start of a drag operation. ExmStringTransferProcessDrag solves this puzzle by determining whether or not ExmStringTransfer currently owns the primary selection. If it does, ExmStringTransferProcessDrag calls the ExmStringTransferPastePrimary routine.
The ExmStringTransfer widget contains the following relatively simple copy primary routine:
static void
ExmStringTransferCopyPrimary(
     Widget w,
     XEvent *event,
     String *params,
     Cardinal *num_params)
{
 Time time;
 ExmStringTransfer stw = (ExmStringTransfer) w;
  /* First we must obtain a timestamp. This is required for
     ICCCM compliance. XtLastTimestampProcessed holds the timestamp
     from the last event the Intrinsics saw with a timestamp. */
  time = XtLastTimestampProcessed(XtDisplay(w));
 
  /* Own the primary selection. Indicate this to the user by
     reversing the foreground and background in the text rendition
     (eventually) */
  stw->string_transfer.own_primary = True;
 
  /* Once we call XmePrimarySource,  the widget's transfer trait
     convert method will get called if a destination wishes to
     obtain the PRIMARY selection. */
  XmePrimarySource(w, time);
 
  /* Update the widget to show the new state */
  stw->core.widget_class->core_class.expose(w, NULL, NULL);
}
In the preceding code, stw->string_transfer.own_primary is a Boolean field. ExmStringTransfer sets this field to True when the widget holds the primary selection and False when the widget relinquishes the primary selection.
The most important part of the paste primary routine of ExmStringTransfer is its call to XmePrimarySink. Following is the complete ExmStringTransferPastePrimary routine:
static void
ExmStringTransferPastePrimary(
     Widget w,
     XEvent *event,
     String *params,
     Cardinal *num_params)
{
  Time time;
  unsigned int op;
  /* First we must obtain a timestamp. This is required for
     ICCCM compliant ownership of a selection. We use
     XtLastTimestampProcessed which holds the timestamp
     from the last event the Intrinsics saw with a timestamp. */
  time = XtLastTimestampProcessed(XtDisplay(w));
 
  /* We determine the right operation to perform by looking
     at the modifiers present */
  if (event -> xbutton.state & ShiftMask) {
    if (event -> xbutton.state & ControlMask)
      op = XmLINK;
    else
      op = XmMOVE;
  } else
    op = XmCOPY;
 
  /* Calling XmePrimarySink will start the process of requesting
     the PRIMARY selection to be pasted using the transfer trait
     destination callback for this widget class */
  XmePrimarySink(w, op, NULL, time);
}
The second argument to XmePrimarySink (called op in the preceding code) describes the kind of operation that the user has requested. UTM will copy the value of op into the operation member of the XmDestinationCallbackStruct.