wl_data_device interface in the base wayland protocol is the most complex one,
in my opinion, wayland.xml explains it fairly well, but every pieces are
scattered in the file, here I serialize it together, give you quick run through.
In brief, data device in wayland consists of four interfaces: The first is
wl_data_device_manager, it is the global. The second is wl_data_device,
can be created from wl_data_device_manager for a given seat, it is used to
set selection(ctrl-c ctrl-v) and drag-n-drop. The 3rd is wl_data_source,
also created from wl_data_device_manager, this source will be either a
selection source or drag-n-drop source. The last is wl_data_offer, which is
used for copying data from wl_data_source.
Now we talk about the dynamics of the those 4 objects. Firstly a client
creates a data_source (for example you pressed ctrl-C), gives it all the
MIME types it offers and mark it as a selection or a drag. Then it is server’s
responsibility to create wl_data_offer at a proper moment later(either a new
surface focused on a keyboard or pointer moves in a surface). Once the
data_offer created, server will immediately send all the acceptable MIME
types ot the offer, expects one of them accepted by the offer. If it is true,
the data_offer need to give a file desriptor for writing data to, the server
only need to transfer the call to the data_source and it writes to that
fd. After it is done, data_offer is happy then send a
wl_data_offer.finish to server can destroy the source. This process
roughly covers the selection process. The drag-n-drop is a little more
complicated.
The different in drag-n-drop starts with wl_data_offer creation. As we said
before, it happens at wl_surface.enter, here we would call
wl_data_device.enter for the data_offer. wl_data_device.motion is called
on cursor movement. Note that pratically you can drag through the entire
surface without releasing, then on the next surface, server will call
wl_data_device.leave first, then create another data_offer amid
wl_data_device.enter. During this process, there is a side story happening,
wl_data_source and wl_data_offer needs to negociating the
actions(copy/move) and acceptable MIMEs. When cursor released, data_source
is notified with wl_data_source.dnd_performed, finally it would be like in
selection, data_offer gives a file destriptor and data_source to write and
wl_data_offer.finish is used to finish the transaction.
Overall it is more complex protocol, multiple requests and events are executed in sequence and expected in a given order. This is unlike most interface, where requests/events are more like a single shot.