1 /**
2  * @defgroup CopyPaste CopyPaste
3  * @ingroup Elementary
4  *
5  * Copy and paste feature implementations.
6  *
7  * Implements the following functionality
8  * a. select, copy/cut and paste
9  * b. clipboard
10  * c. drag and drop
11  * in order to share data across application windows.
12  *
13  * Contains functions to select text or a portion of data,
14  * send it to a buffer, and paste the data into a target.
15  *
16  * elm_cnp provides a generic copy and paste facility based on its windowing system.
17  * It is not necessary to know the details of each windowing system,
18  * but some terms and behavior are common.
19  * Currently the X11 window system is widely used, and only X11 functionality is implemented.
20  *
21  * In X11R6 window system, CopyPaste works like a peer-to-peer communication.
22  * Copying is an operation on an object in an X server.
23  * X11 calls those objects 'selections' which have names.
24  * Generally, two selection types are needed for copy and paste:
25  * The Primary selection and the Clipboard selection.
26  * Primary selection is for selecting text (that means highlighted text).
27  * Clipboard selection is for explicit copying behavior
28  * (such as ctrl+c, or 'copy' in a menu).
29  * Thus, in applications most cases only use the clipboard selection.
30  * As stated before, taking ownership of a selection doesn't move any actual data.
31  * Copying and Pasting is described as follows:
32  *  1. Copy text in Program A : Program A takes ownership of the selection
33  *  2. Paste text in Program B : Program B notes that Program A owns the selection
34  *  3. Program B asks A for the text
35  *  4. Program A responds and sends the text to program B
36  *  5. Program B pastes the response
37  * More information is on
38  *  - http://www.jwz.org/doc/x-cut-and-paste.html
39  *  - X11R6 Inter-Client Communication Conventions Manual, section 2
40  *
41  * TODO: add for other window system.
42  *
43  * @{
44  */
45 
46 /**
47  * Event notifying that the selection has changed
48  * @see Elm_Cnp_Event_Selection_Changed
49  * @since 1.20
50  */
51 EAPI extern int ELM_CNP_EVENT_SELECTION_CHANGED;
52 
53 /**
54  * Defines the types of selection property names.
55  * @see http://www.x.org/docs/X11/xlib.pdf
56  * for more details.
57  */
58 
59 typedef enum
60 {
61   ELM_SEL_TYPE_PRIMARY = 0, /**< Primary text selection (highlighted or
62                                       * selected text) */
63   ELM_SEL_TYPE_SECONDARY, /**< Used when primary selection is in use */
64   ELM_SEL_TYPE_XDND, /**< Drag and Drop */
65   ELM_SEL_TYPE_CLIPBOARD /**< Clipboard selection (ctrl+C) */
66 } Elm_Sel_Type;
67 
68 /**
69  * Defines the types of content.
70  */
71 typedef enum
72 {
73   ELM_SEL_FORMAT_TARGETS = -1 /* +1 */, /**< For matching every
74                                                   * possible atom */
75   ELM_SEL_FORMAT_NONE = 0, /**< Content is from outside of Elementary
76                                      */
77   ELM_SEL_FORMAT_TEXT = 1, /**< Plain unformatted text: Used for things
78                                      * that don't want rich markup */
79   ELM_SEL_FORMAT_MARKUP = 2, /**< Edje textblock markup, including
80                                        * inline images */
81   ELM_SEL_FORMAT_IMAGE = 4, /**< Images */
82   ELM_SEL_FORMAT_VCARD = 8, /**< Vcards */
83   ELM_SEL_FORMAT_HTML = 16 /**< Raw HTML-like data (eg. webkit) */
84 } Elm_Sel_Format;
85 
86 /**
87  * Defines the kind of action associated with the drop data if for XDND
88  * @since 1.8
89  */
90 typedef enum
91 {
92   ELM_XDND_ACTION_UNKNOWN = 0, /**< Action type is unknown */
93   ELM_XDND_ACTION_COPY, /**< Copy the data */
94   ELM_XDND_ACTION_MOVE, /**< Move the data */
95   ELM_XDND_ACTION_PRIVATE, /**< Private action type */
96   ELM_XDND_ACTION_ASK, /**< Ask the user what to do */
97   ELM_XDND_ACTION_LIST, /**< List the data */
98   ELM_XDND_ACTION_LINK, /**< Link the data */
99   ELM_XDND_ACTION_DESCRIPTION /**< Describe the data */
100 } Elm_Xdnd_Action;
101 /**
102  * Structure holding the info about selected data.
103  */
104 struct _Elm_Selection_Data
105 {
106    Evas_Coord       x, y; /**< The coordinates of the drop (DND operations only) */
107    Elm_Sel_Format   format; /**< The format of the selection */
108    void            *data; /**< The selection data, type determined by format member */
109    size_t           len; /**< The length of the selection data */
110    Elm_Xdnd_Action  action; /**< The action to perform with the data @since 1.8 */
111 };
112 typedef struct _Elm_Selection_Data Elm_Selection_Data;
113 
114 
115 /** Event to notify when a display server's selection has changed
116  * Only sent for PRIMARY and CLIPBOARD selections
117  * @since 1.20
118  */
119 typedef struct Elm_Cnp_Event_Selection_Changed
120 {
121    Elm_Sel_Type type; /**< The selection type */
122    unsigned int seat_id; /**< The seat on which the selection changed, or @c NULL for "default" */
123    void *display; /**< The display connection object, @c NULL under X11 */
124    Eina_Bool exists; /**< @c EINA_TRUE if the selection has an owner */
125 } Elm_Cnp_Event_Selection_Changed;
126 
127 /**
128  * Callback invoked in when the selected data is 'dropped' at its destination.
129  *
130  * @param data Application specific data
131  * @param obj The evas object where selected data is 'dropped'.
132  * @param ev struct holding information about selected data
133  * FIXME: this should probably be a smart callback
134  */
135 typedef Eina_Bool (*Elm_Drop_Cb)(void *data, Evas_Object *obj, Elm_Selection_Data *ev);
136 
137 /**
138  * Callback invoked to find out what object is under (x,y) coords
139  *
140  * @param obj The container object
141  * @param x cord to check
142  * @param y cord to check
143  * @param xposret Position relative to item (left (-1), middle (0), right (1)
144  * @param yposret Position relative to item (upper (-1), middle (0), bottom (1)
145  * @return object under x,y cords or NULL if not found.
146  */
147 typedef Elm_Object_Item *(*Elm_Xy_Item_Get_Cb)(Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *xposret, int *yposret);
148 
149 /**
150  * Callback invoked in when the selection ownership for a given selection is lost.
151  *
152  * @param data Application specific data
153  * @param selection The selection that is lost
154  * @since 1.7
155  */
156 typedef void (*Elm_Selection_Loss_Cb)(void *data, Elm_Sel_Type selection);
157 
158 /**
159  * Callback called to create a drag icon object
160  *
161  * @param data Application specific data
162  * @param win The window to create the objects relative to
163  * @param xoff A return coordinate for the X offset at which to place the drag icon object relative to the source drag object
164  * @param yoff A return coordinate for the Y offset at which to place the drag icon object relative to the source drag object
165  * @return An object to fill the drag window with or NULL if not needed
166  * @since 1.8
167  */
168 typedef Evas_Object *(*Elm_Drag_Icon_Create_Cb) (void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff);
169 
170 /**
171  * Callback called when a drag is finished, enters, or leaves an object
172  *
173  * @param data Application specific data
174  * @param obj The object where the drag started
175  * @since 1.8
176  */
177 typedef void (*Elm_Drag_State) (void *data, Evas_Object *obj);
178 
179 /**
180  * Callback called when a drag is finished.
181  *
182  * @param data Application specific data
183  * @param obj The object where the drag started
184  * @param accepted TRUE if the dropped data is accepted on drop
185  * @since 1.8
186  */
187 typedef void (*Elm_Drag_Done) (void *data, Evas_Object *obj, Eina_Bool accepted);
188 
189 /**
190  * Callback called when a drag is responded to with an accept or deny
191  *
192  * @param data Application specific data
193  * @param obj The object where the drag started
194  * @param doaccept A boolean as to if the target accepts the drag or not
195  * @since 1.8
196  */
197 typedef void (*Elm_Drag_Accept) (void *data, Evas_Object *obj, Eina_Bool doaccept);
198 
199 /**
200  * Callback called when a drag is over an object, and gives object-relative coordinates
201  *
202  * @param data Application specific data
203  * @param obj The object where the drag started
204  * @param x The X coordinate relative to the top-left of the object
205  * @param y The Y coordinate relative to the top-left of the object
206  * @since 1.8
207  */
208 typedef void (*Elm_Drag_Pos) (void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action);
209 
210 /**
211  * Callback called when a drag starts from an item container
212  *
213  * @param data Application specific data
214  * @param obj The object where the drag started
215  * @since 1.8
216  */
217 typedef void (*Elm_Drag_Start) (void *data, Evas_Object *obj);
218 
219 /**
220  * @brief Set copy data for a widget.
221  *
222  * Set copy data and take ownership of selection. Format is used for specifying the selection type,
223  * and this is used during pasting.
224  *
225  * @param selection Selection type for copying and pasting
226  * @param obj The source widget pointer
227  * @param format Selection format
228  * @param buf The data selected
229  * @param buflen The size of @p buf
230  * @return If @c EINA_TRUE, setting data was successful.
231  *
232  * @ingroup CopyPaste
233  *
234  */
235 EAPI Eina_Bool elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type selection,
236                                      Elm_Sel_Format format,
237                                      const void *buf, size_t buflen);
238 
239 /**
240  * @brief Get data from a widget that has a selection.
241  *
242  * Get the current selection data from a widget.
243  * The widget input here will usually be elm_entry,
244  * in which case @p datacb and @p udata can be NULL.
245  * If a different widget is passed, @p datacb and @p udata are used for retrieving data.
246  *
247  * @see also elm_cnp_selection_set()
248  *
249  * @param selection Selection type for copying and pasting
250  * @param format Selection format
251  * @param obj The source widget
252  * @param datacb The user data callback if the target widget isn't elm_entry
253  * @param udata The user data pointer for @p datacb
254  * @return If @c EINA_TRUE, getting selection data was successful.
255  *
256  * @ingroup CopyPaste
257  */
258 EAPI Eina_Bool elm_cnp_selection_get(const Evas_Object *obj, Elm_Sel_Type selection,
259                                      Elm_Sel_Format format,
260                                      Elm_Drop_Cb datacb, void *udata);
261 
262 /**
263  * @brief Clear the selection data of a widget.
264  *
265  * Clear all data from the selection which is owned by a widget.
266  *
267  * @see also elm_cnp_selection_set()
268  *
269  * @param obj The source widget
270  * @param selection Selection type for copying and pasting
271  * @return If @c EINA_TRUE, clearing data was successful.
272  *
273  * @ingroup CopyPaste
274  *
275  */
276 EAPI Eina_Bool elm_object_cnp_selection_clear(Evas_Object *obj,
277                                               Elm_Sel_Type selection);
278 
279 
280 /**
281  * @brief Set a function to be called when a selection is lost
282  *
283  * The function @p func is set of be called when selection @p selection is lost
284  * to another process or when elm_cnp_selection_set() is called. If @p func
285  * is NULL then it is not called. @p data is passed as the data parameter to
286  * the callback functions and selection is passed in as the selection that
287  * has been lost.
288  *
289  * elm_cnp_selection_set() and elm_object_cnp_selection_clear() automatically
290  * set this los callback to NULL when called. If you wish to take the selection
291  * and then be notified of loss please do this (for example):
292  *
293  * @code
294  * elm_cnp_selection_set(obj, ELM_SEL_TYPE_PRIMARY, ELM_SEL_FORMAT_TEXT, "hello", strlen(hello));
295  * elm_cnp_selection_loss_callback_set(obj, ELM_SEL_TYPE_PRIMARY, loss_cb, NULL);
296  * @endcode
297  *
298  * @see also elm_cnp_selection_set()
299  *
300  * @param obj The object to indicate the window target/display system.
301  * @param selection Selection to be notified of for loss
302  * @param func The function to call
303  * @param data The data pointer passed to the function.
304  *
305  * @ingroup CopyPaste
306  *
307  * @since 1.7
308  */
309 EAPI void elm_cnp_selection_loss_callback_set(Evas_Object *obj, Elm_Sel_Type selection, Elm_Selection_Loss_Cb func, const void *data);
310 
311 /**
312  * @brief Determine whether the clipboard selection has an owner
313  *
314  * @param win The window object to check for
315  * @return @c EINA_TRUE if the clipboard has a selection
316  * @ingroup CopyPaste
317  * @since 1.20
318  */
319 EAPI Eina_Bool elm_cnp_clipboard_selection_has_owner(Evas_Object *win);
320 
321 /**
322  * @brief Set the given object as a target for drops for drag-and-drop
323  *
324  * @param obj The target object
325  * @param format The formats supported for dropping
326  * @param entercb The function to call when the object is entered with a drag
327  * @param enterdata The application data to pass to enterdata
328  * @param leavecb The function to call when the object is left with a drag
329  * @param leavedata The application data to pass to leavedata
330  * @param poscb The function to call when the object has a drag over it
331  * @param posdata The application data to pass to posdata
332  * @param dropcb The function to call when a drop has occurred
333  * @param dropdata The application data to pass to dropcb
334  * @return Returns @c EINA_TRUE, if successful, or @c EINA_FALSE if not.
335  *
336  * @ingroup CopyPaste
337  *
338  * @since 1.8
339  */
340 EAPI Eina_Bool elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format,
341                                    Elm_Drag_State entercb, void *enterdata,
342                                    Elm_Drag_State leavecb, void *leavedata,
343                                    Elm_Drag_Pos poscb, void *posdata,
344                                    Elm_Drop_Cb dropcb, void *dropdata);
345 
346 /**
347  * @brief Deletes the drop target status of an object
348  *
349  * @param obj The target object
350  * @param format The formats supported for dropping
351  * @param entercb The function to call when the object is entered with a drag
352  * @param enterdata The application data to pass to enterdata
353  * @param leavecb The function to call when the object is left with a drag
354  * @param leavedata The application data to pass to leavedata
355  * @param poscb The function to call when the object has a drag over it
356  * @param posdata The application data to pass to posdata
357  * @param dropcb The function to call when a drop has occurred
358  * @param dropdata The application data to pass to dropcb
359  * @return Returns @c EINA_TRUE, if successful, or @c EINA_FALSE if not.
360  *
361  * @ingroup CopyPaste
362  *
363  * @since 1.8
364  */
365 EAPI Eina_Bool elm_drop_target_del(Evas_Object *obj, Elm_Sel_Format format,
366                                    Elm_Drag_State entercb, void *enterdata,
367                                    Elm_Drag_State leavecb, void *leavedata,
368                                    Elm_Drag_Pos poscb, void *posdata,
369                                    Elm_Drop_Cb dropcb, void *dropdata);
370 
371 /**
372  * @brief Begins a drag given a source object
373  *
374  * @param obj The source object
375  * @param format The drag formats supported by the data
376  * @param data The drag data itself (a string)
377  * @param action The drag action to be done
378  * @param createicon Function to call to create a drag object, or NULL if not wanted
379  * @param createdata Application data passed to @p createicon
380  * @param dragpos Function called with each position of the drag, x, y being screen coordinates if possible, and action being the current action.
381  * @param dragdata Application data passed to @p dragpos
382  * @param acceptcb Function called indicating if drop target accepts (or does not) the drop data while dragging
383  *
384  * @param acceptdata Application data passed to @p acceptcb
385  * @param dragdone Function to call when drag is done
386  * @param donecbdata Application data to pass to @p dragdone
387  * @return Returns @c EINA_TRUE, if successful, or @c EINA_FALSE if not.
388  *
389  * @ingroup CopyPaste
390  *
391  * @since 1.8
392  */
393 EAPI Eina_Bool elm_drag_start(Evas_Object *obj, Elm_Sel_Format format,
394                               const char *data, Elm_Xdnd_Action action,
395                               Elm_Drag_Icon_Create_Cb createicon,
396                               void *createdata,
397                               Elm_Drag_Pos dragpos, void *dragdata,
398                               Elm_Drag_Accept acceptcb, void *acceptdata,
399                               Elm_Drag_State dragdone, void *donecbdata);
400 
401 /**
402  * @brief Cancels the current drag operation
403  *
404  * It can only be initiated from the source window.
405  *
406  * @param obj The source of the current drag.
407  * @return Returns @c EINA_TRUE, if successful, or @c EINA_FALSE if not.
408  *
409  * @ingroup CopyPaste
410  *
411  * @since 1.9
412  */
413 EAPI Eina_Bool elm_drag_cancel(Evas_Object *obj);
414 
415 /**
416  * @brief Changes the current drag action
417  *
418  * @param obj The source of a drag if a drag is underway
419  * @param action The drag action to be done
420  * @return Returns @c EINA_TRUE, if successful, or @c EINA_FALSE if not.
421  *
422  * @ingroup CopyPaste
423  *
424  * @since 1.8
425  */
426 EAPI Eina_Bool elm_drag_action_set(Evas_Object *obj, Elm_Xdnd_Action action);
427 
428 /**
429  * Callback called when a drag is over an object
430  *
431  * @param data Application specific data
432  * @param cont The container object where the drag started
433  * @param it The object item in container where mouse-over
434  * @param x The X coordinate relative to the top-left of the object
435  * @param y The Y coordinate relative to the top-left of the object
436  * @param xposret Position relative to item (left (-1), middle (0), right (1)
437  * @param yposret Position relative to item (upper (-1), middle (0), bottom (1)
438  * @param action The drag action to be done
439  * @since 1.8
440  */
441 typedef void (*Elm_Drag_Item_Container_Pos) (void *data, Evas_Object *cont, Elm_Object_Item *it, Evas_Coord x, Evas_Coord y, int xposret, int yposret, Elm_Xdnd_Action action);
442 
443 /**
444  * Callback invoked in when the selected data is 'dropped' on container.
445  *
446  * @param data Application specific data
447  * @param obj The evas object where selected data is 'dropped'.
448  * @param it The item in container where drop-cords
449  * @param ev struct holding information about selected data
450  * @param xposret Position relative to item (left (-1), middle (0), right (1)
451  * @param yposret Position relative to item (upper (-1), middle (0), bottom (1)
452  */
453 typedef Eina_Bool (*Elm_Drop_Item_Container_Cb)(void *data, Evas_Object *obj, Elm_Object_Item *it, Elm_Selection_Data *ev, int xposret, int yposret);
454 
455 /**
456  * Structure describing user information for the drag process.
457  *
458  * @param format The drag formats supported by the data (output)
459  * @param data The drag data itself (a string) (output)
460  * @param icons if value not NULL, play default anim (output)
461  * @param action The drag action to be done (output)
462  * @param createicon Function to call to create a drag object, or NULL if not wanted (output)
463  * @param createdata Application data passed to @p createicon (output)
464  * @param dragpos Function called with each position of the drag, x, y being screen coordinates if possible, and action being the current action. (output)
465  * @param dragdata Application data passed to @p dragpos (output)
466  * @param acceptcb Function called indicating if drop target accepts (or does not) the drop data while dragging (output)
467  * @param acceptdata Application data passed to @p acceptcb (output)
468  * @param dragdone Function to call when drag is done (output)
469  * @param donecbdata Application data to pass to @p dragdone (output)
470  */
471 typedef struct _Elm_Drag_User_Info Elm_Drag_User_Info;
472 
473 struct _Elm_Drag_User_Info
474 {
475    Elm_Sel_Format format;
476    const char *data;
477    Eina_List *icons;
478    Elm_Xdnd_Action action;
479    Elm_Drag_Icon_Create_Cb createicon;
480    void *createdata;
481    Elm_Drag_Start dragstart;
482    void *startcbdata;
483    Elm_Drag_Pos dragpos;
484    void *dragdata;
485    Elm_Drag_Accept acceptcb;
486    void *acceptdata;
487    Elm_Drag_Done dragdone;
488    void *donecbdata;
489 };
490 
491 /**
492  * Callback invoked when starting to drag for a container.
493  *
494  * @param obj The container object
495  * @param it The Elm_Object_Item pointer where drag-start
496  * @return Returns @c EINA_TRUE, if successful, or @c EINA_FALSE if not.
497  */
498 typedef Eina_Bool (*Elm_Item_Container_Data_Get_Cb)(
499       Evas_Object *obj,
500       Elm_Object_Item *it,
501       Elm_Drag_User_Info *info);
502 
503 /**
504  * @brief Set a item container (list, genlist, grid) as source of drag
505  *
506  * @param obj The container object.
507  * @param tm_to_anim Time period to wait before start animation.
508  * @param tm_to_drag Time period to wait before start dragging.
509  * @param itemgetcb Callback to get Evas_Object pointer for item at (x,y)
510  * @param data_get  Callback to get drag info
511  * @return Returns @c EINA_TRUE, if successful, or @c EINA_FALSE if not.
512  *
513  * @ingroup CopyPaste
514  *
515  * @since 1.8
516  */
517 EAPI Eina_Bool elm_drag_item_container_add(Evas_Object *obj, double tm_to_anim, double tm_to_drag, Elm_Xy_Item_Get_Cb itemgetcb, Elm_Item_Container_Data_Get_Cb data_get);
518 
519 /**
520  * @brief Deletes a item container from drag-source list
521  *
522  * @param obj The target object
523  * @return Returns @c EINA_TRUE, if successful, or @c EINA_FALSE if not.
524  *
525  * @ingroup CopyPaste
526  *
527  * @since 1.8
528  */
529 EAPI Eina_Bool elm_drag_item_container_del(Evas_Object *obj);
530 
531 /**
532  * @brief Set a item container (list, genlist, grid) as target for drop.
533  *
534  * @param obj The container object.
535  * @param format The formats supported for dropping
536  * @param itemgetcb Callback to get Evas_Object pointer for item at (x,y)
537  * @param entercb The function to call when the object is entered with a drag
538  * @param enterdata The application data to pass to enterdata
539  * @param leavecb The function to call when the object is left with a drag
540  * @param leavedata The application data to pass to leavedata
541  * @param poscb The function to call when the object has a drag over it
542  * @param posdata The application data to pass to posdata
543  * @param dropcb The function to call when a drop has occurred
544  * @param dropdata The application data to pass to dropcb
545  * @return Returns @c EINA_TRUE, if successful, or @c EINA_FALSE if not.
546  *
547  * @ingroup CopyPaste
548  *
549  * @since 1.8
550  */
551 EAPI Eina_Bool elm_drop_item_container_add(Evas_Object *obj,
552       Elm_Sel_Format format,
553       Elm_Xy_Item_Get_Cb itemgetcb,
554       Elm_Drag_State entercb, void *enterdata,
555       Elm_Drag_State leavecb, void *leavedata,
556       Elm_Drag_Item_Container_Pos poscb, void *posdata,
557       Elm_Drop_Item_Container_Cb dropcb, void *dropdata);
558 
559 /**
560  * @brief Removes a container from list of drop targets.
561  *
562  * @param obj The container object
563  * @return Returns EINA_TRUE, if successful, or @c EINA_FALSE if not.
564  *
565  * @ingroup CopyPaste
566  *
567  * @since 1.8
568  */
569 EAPI Eina_Bool elm_drop_item_container_del(Evas_Object *obj);
570 
571 /**
572  * @}
573  */
574