Merge "[Password]: New design based changes, a new style removed password mode contro...
[framework/uifw/elementary.git] / src / lib / els_cursor.c
1 #include <Elementary.h>
2 #include <Elementary_Cursor.h>
3 #include "elm_priv.h"
4
5 #ifdef HAVE_ELEMENTARY_X
6 #include <Ecore_X.h>
7 #include <Ecore_X_Cursor.h>
8 #endif
9
10 /**
11  * @defgroup Cursors Cursors
12  *
13  * The Cursor is an internal smart object used to customize the
14  * cursor displayed over objects (or widgets).
15  * It can use default X cursors (if using X), or cursors from a
16  * theme.
17  */
18
19 #define _cursor_key "_elm_cursor"
20
21 struct _Cursor_Id 
22 {
23    const char *name;
24 #ifdef HAVE_ELEMENTARY_X
25    int id;
26 #endif
27 };
28
29 #ifdef HAVE_ELEMENTARY_X
30 #define CURSOR(_name, _xid) \
31    {_name , _xid}
32 # else
33 #define CURSOR(_name, _xid) \
34    {_name}
35 #endif
36
37 /* Please keep order in sync with Ecore_X_Cursor.h values! */
38 struct _Cursor_Id _cursors[] =
39 {
40    CURSOR(ELM_CURSOR_X                  , ECORE_X_CURSOR_X                  ),
41    CURSOR(ELM_CURSOR_ARROW              , ECORE_X_CURSOR_ARROW              ),
42    CURSOR(ELM_CURSOR_BASED_ARROW_DOWN   , ECORE_X_CURSOR_BASED_ARROW_DOWN   ),
43    CURSOR(ELM_CURSOR_BASED_ARROW_UP     , ECORE_X_CURSOR_UP                 ),
44    CURSOR(ELM_CURSOR_BOAT               , ECORE_X_CURSOR_BOAT               ),
45    CURSOR(ELM_CURSOR_BOGOSITY           , ECORE_X_CURSOR_BOGOSITY           ),
46    CURSOR(ELM_CURSOR_BOTTOM_LEFT_CORNER , ECORE_X_CURSOR_BOTTOM_LEFT_CORNER ),
47    CURSOR(ELM_CURSOR_BOTTOM_RIGHT_CORNER, ECORE_X_CURSOR_BOTTOM_RIGHT_CORNER),
48    CURSOR(ELM_CURSOR_BOTTOM_SIDE        , ECORE_X_CURSOR_BOTTOM_SIDE        ),
49    CURSOR(ELM_CURSOR_BOTTOM_TEE         , ECORE_X_CURSOR_BOTTOM_TEE         ),
50    CURSOR(ELM_CURSOR_BOX_SPIRAL         , ECORE_X_CURSOR_BOX_SPIRAL         ),
51    CURSOR(ELM_CURSOR_CENTER_PTR         , ECORE_X_CURSOR_CENTER_PTR         ),
52    CURSOR(ELM_CURSOR_CIRCLE             , ECORE_X_CURSOR_CIRCLE             ),
53    CURSOR(ELM_CURSOR_CLOCK              , ECORE_X_CURSOR_CLOCK              ),
54    CURSOR(ELM_CURSOR_COFFEE_MUG         , ECORE_X_CURSOR_COFFEE_MUG         ),
55    CURSOR(ELM_CURSOR_CROSS              , ECORE_X_CURSOR_CROSS              ),
56    CURSOR(ELM_CURSOR_CROSS_REVERSE      , ECORE_X_CURSOR_CROSS_REVERSE      ),
57    CURSOR(ELM_CURSOR_CROSSHAIR          , ECORE_X_CURSOR_CROSSHAIR          ),
58    CURSOR(ELM_CURSOR_DIAMOND_CROSS      , ECORE_X_CURSOR_DIAMOND_CROSS      ),
59    CURSOR(ELM_CURSOR_DOT                , ECORE_X_CURSOR_DOT                ),
60    CURSOR(ELM_CURSOR_DOT_BOX_MASK       , ECORE_X_CURSOR_DOT_BOX_MASK       ),
61    CURSOR(ELM_CURSOR_DOUBLE_ARROW       , ECORE_X_CURSOR_DOUBLE_ARROW       ),
62    CURSOR(ELM_CURSOR_DRAFT_LARGE        , ECORE_X_CURSOR_DRAFT_LARGE        ),
63    CURSOR(ELM_CURSOR_DRAFT_SMALL        , ECORE_X_CURSOR_DRAFT_SMALL        ),
64    CURSOR(ELM_CURSOR_DRAPED_BOX         , ECORE_X_CURSOR_DRAPED_BOX         ),
65    CURSOR(ELM_CURSOR_EXCHANGE           , ECORE_X_CURSOR_EXCHANGE           ),
66    CURSOR(ELM_CURSOR_FLEUR              , ECORE_X_CURSOR_FLEUR              ),
67    CURSOR(ELM_CURSOR_GOBBLER            , ECORE_X_CURSOR_GOBBLER            ),
68    CURSOR(ELM_CURSOR_GUMBY              , ECORE_X_CURSOR_GUMBY              ),
69    CURSOR(ELM_CURSOR_HAND1              , ECORE_X_CURSOR_HAND1              ),
70    CURSOR(ELM_CURSOR_HAND2              , ECORE_X_CURSOR_HAND2              ),
71    CURSOR(ELM_CURSOR_HEART              , ECORE_X_CURSOR_HEART              ),
72    CURSOR(ELM_CURSOR_ICON               , ECORE_X_CURSOR_ICON               ),
73    CURSOR(ELM_CURSOR_IRON_CROSS         , ECORE_X_CURSOR_IRON_CROSS         ),
74    CURSOR(ELM_CURSOR_LEFT_PTR           , ECORE_X_CURSOR_LEFT_PTR           ),
75    CURSOR(ELM_CURSOR_LEFT_SIDE          , ECORE_X_CURSOR_LEFT_SIDE          ),
76    CURSOR(ELM_CURSOR_LEFT_TEE           , ECORE_X_CURSOR_LEFT_TEE           ),
77    CURSOR(ELM_CURSOR_LEFTBUTTON         , ECORE_X_CURSOR_LEFTBUTTON         ),
78    CURSOR(ELM_CURSOR_LL_ANGLE           , ECORE_X_CURSOR_LL_ANGLE           ),
79    CURSOR(ELM_CURSOR_LR_ANGLE           , ECORE_X_CURSOR_LR_ANGLE           ),
80    CURSOR(ELM_CURSOR_MAN                , ECORE_X_CURSOR_MAN                ),
81    CURSOR(ELM_CURSOR_MIDDLEBUTTON       , ECORE_X_CURSOR_MIDDLEBUTTON       ),
82    CURSOR(ELM_CURSOR_MOUSE              , ECORE_X_CURSOR_MOUSE              ),
83    CURSOR(ELM_CURSOR_PENCIL             , ECORE_X_CURSOR_PENCIL             ),
84    CURSOR(ELM_CURSOR_PIRATE             , ECORE_X_CURSOR_PIRATE             ),
85    CURSOR(ELM_CURSOR_PLUS               , ECORE_X_CURSOR_PLUS               ),
86    CURSOR(ELM_CURSOR_QUESTION_ARROW     , ECORE_X_CURSOR_QUESTION_ARROW     ),
87    CURSOR(ELM_CURSOR_RIGHT_PTR          , ECORE_X_CURSOR_RIGHT_PTR          ),
88    CURSOR(ELM_CURSOR_RIGHT_SIDE         , ECORE_X_CURSOR_RIGHT_SIDE         ),
89    CURSOR(ELM_CURSOR_RIGHT_TEE          , ECORE_X_CURSOR_RIGHT_TEE          ),
90    CURSOR(ELM_CURSOR_RIGHTBUTTON        , ECORE_X_CURSOR_RIGHTBUTTON        ),
91    CURSOR(ELM_CURSOR_RTL_LOGO           , ECORE_X_CURSOR_RTL_LOGO           ),
92    CURSOR(ELM_CURSOR_SAILBOAT           , ECORE_X_CURSOR_SAILBOAT           ),
93    CURSOR(ELM_CURSOR_SB_DOWN_ARROW      , ECORE_X_CURSOR_SB_DOWN_ARROW      ),
94    CURSOR(ELM_CURSOR_SB_H_DOUBLE_ARROW  , ECORE_X_CURSOR_SB_H_DOUBLE_ARROW  ),
95    CURSOR(ELM_CURSOR_SB_LEFT_ARROW      , ECORE_X_CURSOR_SB_LEFT_ARROW      ),
96    CURSOR(ELM_CURSOR_SB_RIGHT_ARROW     , ECORE_X_CURSOR_SB_RIGHT_ARROW     ),
97    CURSOR(ELM_CURSOR_SB_UP_ARROW        , ECORE_X_CURSOR_SB_UP_ARROW        ),
98    CURSOR(ELM_CURSOR_SB_V_DOUBLE_ARROW  , ECORE_X_CURSOR_SB_V_DOUBLE_ARROW  ),
99    CURSOR(ELM_CURSOR_SHUTTLE            , ECORE_X_CURSOR_SHUTTLE            ),
100    CURSOR(ELM_CURSOR_SIZING             , ECORE_X_CURSOR_SIZING             ),
101    CURSOR(ELM_CURSOR_SPIDER             , ECORE_X_CURSOR_SPIDER             ),
102    CURSOR(ELM_CURSOR_SPRAYCAN           , ECORE_X_CURSOR_SPRAYCAN           ),
103    CURSOR(ELM_CURSOR_STAR               , ECORE_X_CURSOR_STAR               ),
104    CURSOR(ELM_CURSOR_TARGET             , ECORE_X_CURSOR_TARGET             ),
105    CURSOR(ELM_CURSOR_TCROSS             , ECORE_X_CURSOR_TCROSS             ),
106    CURSOR(ELM_CURSOR_TOP_LEFT_ARROW     , ECORE_X_CURSOR_TOP_LEFT_ARROW     ),
107    CURSOR(ELM_CURSOR_TOP_LEFT_CORNER    , ECORE_X_CURSOR_TOP_LEFT_CORNER    ),
108    CURSOR(ELM_CURSOR_TOP_RIGHT_CORNER   , ECORE_X_CURSOR_TOP_RIGHT_CORNER   ),
109    CURSOR(ELM_CURSOR_TOP_SIDE           , ECORE_X_CURSOR_TOP_SIDE           ),
110    CURSOR(ELM_CURSOR_TOP_TEE            , ECORE_X_CURSOR_TOP_TEE            ),
111    CURSOR(ELM_CURSOR_TREK               , ECORE_X_CURSOR_TREK               ),
112    CURSOR(ELM_CURSOR_UL_ANGLE           , ECORE_X_CURSOR_UL_ANGLE           ),
113    CURSOR(ELM_CURSOR_UMBRELLA           , ECORE_X_CURSOR_UMBRELLA           ),
114    CURSOR(ELM_CURSOR_UR_ANGLE           , ECORE_X_CURSOR_UR_ANGLE           ),
115    CURSOR(ELM_CURSOR_WATCH              , ECORE_X_CURSOR_WATCH              ),
116    CURSOR(ELM_CURSOR_XTERM              , ECORE_X_CURSOR_XTERM              )
117 };
118 static const int _cursors_count = sizeof(_cursors)/sizeof(struct _Cursor_Id);
119
120 #define ELM_CURSOR_GET_OR_RETURN(cur, obj, ...)         \
121   Elm_Cursor *cur;                                      \
122   do                                                    \
123     {                                                   \
124        if (!(obj))                                      \
125          {                                              \
126             CRITICAL("Null pointer: " #obj);            \
127             return __VA_ARGS__;                         \
128          }                                              \
129        cur = evas_object_data_get((obj), _cursor_key);  \
130        if (!cur)                                        \
131          {                                              \
132             ERR("Object does not have cursor: " #obj);  \
133             return __VA_ARGS__;                         \
134          }                                              \
135     }                                                   \
136   while (0)
137
138 struct _Elm_Cursor
139 {
140    Evas_Object *obj;
141    Evas_Object *eventarea, *owner;
142    const char *style, *cursor_name;
143    int hot_x, hot_y;
144    Ecore_Evas *ee;
145    Evas *evas;
146 #ifdef HAVE_ELEMENTARY_X
147    Ecore_X_Cursor cursor;
148    Ecore_X_Window win;
149 #endif
150    Eina_Bool visible:1;
151    Eina_Bool use_engine:1;
152    Eina_Bool engine_only:1;
153 };
154
155 static void
156 _elm_cursor_obj_del(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
157 {
158    Elm_Cursor *cur = data;
159
160    if (cur) cur->obj = NULL;
161 }
162
163 static Eina_Bool
164 _elm_cursor_obj_add(Evas_Object *obj, Elm_Cursor *cur)
165 {
166    int x, y;
167
168    cur->obj = edje_object_add(cur->evas);
169
170    if (!cur->obj)
171      return EINA_FALSE;
172
173    if (!_elm_theme_object_set(obj, cur->obj, "cursor", cur->cursor_name,
174                               cur->style ? cur->style : "default"))
175      {
176         evas_object_del(cur->obj);
177         cur->obj = NULL;
178         return EINA_FALSE;
179      }
180
181    evas_object_event_callback_add(cur->obj, EVAS_CALLBACK_DEL,
182                                   _elm_cursor_obj_del, cur);
183
184    edje_object_size_min_get(cur->obj, &x, &y);
185    evas_object_resize(cur->obj, x, y);
186    return EINA_TRUE;
187 }
188
189 static void
190 _elm_cursor_set_hot_spots(Elm_Cursor *cur)
191 {
192    const char *str;
193
194    str = edje_object_data_get(cur->obj, "hot_x");
195    if (str) cur->hot_x = atoi(str);
196    else cur->hot_x = 0;
197
198    str = edje_object_data_get(cur->obj, "hot_y");
199    if (str) cur->hot_y = atoi(str);
200    else cur->hot_y = 0;
201 }
202
203 static void
204 _elm_cursor_mouse_in(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
205 {
206    Elm_Cursor *cur = data;
207
208    if (cur->visible) return;
209    evas_event_freeze(cur->evas);
210    cur->visible = EINA_TRUE;
211    if ((!cur->engine_only) && (!cur->use_engine))
212      {
213         if (!cur->obj)
214           _elm_cursor_obj_add(cur->eventarea, cur);
215         ecore_evas_object_cursor_set(cur->ee, cur->obj,
216                                      ELM_OBJECT_LAYER_CURSOR, cur->hot_x,
217                                      cur->hot_y);
218      }
219    else
220      {
221 #ifdef HAVE_ELEMENTARY_X
222         ecore_x_window_cursor_set(cur->win, cur->cursor);
223 #endif
224      }
225    evas_event_thaw(cur->evas);
226 }
227
228 static void
229 _elm_cursor_mouse_out(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
230 {
231    Evas_Object *sobj_parent;
232    Elm_Cursor *pcur = NULL;
233    Elm_Cursor *cur = data;
234
235    if (!cur->visible) return;
236    evas_event_freeze(cur->evas);
237    cur->visible = EINA_FALSE;
238
239    sobj_parent = evas_object_data_get(cur->eventarea, "elm-parent");
240    while (sobj_parent)
241      {
242         pcur = evas_object_data_get((sobj_parent), _cursor_key);
243         if ((pcur) && (pcur->visible)) break;
244         sobj_parent = evas_object_data_get(sobj_parent, "elm-parent");
245      }
246
247    if (pcur)
248      {
249         pcur->visible = EINA_FALSE;
250         evas_event_thaw(cur->evas);
251         _elm_cursor_mouse_in(pcur, NULL, NULL, NULL);
252         return;
253      }
254
255    if ((!cur->engine_only) || (!cur->use_engine))
256      {
257         ecore_evas_object_cursor_set(cur->ee, NULL, ELM_OBJECT_LAYER_CURSOR,
258                                      cur->hot_x, cur->hot_y);
259      }
260    else
261      {
262 #ifdef HAVE_ELEMENTARY_X
263         ecore_x_window_cursor_set(cur->win, ECORE_X_CURSOR_X);
264 #endif
265      }
266    evas_event_thaw(cur->evas);
267 }
268
269 static void
270 _elm_cursor_del(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
271 {
272    elm_object_cursor_unset(obj);
273 }
274
275 static int
276 _elm_cursor_strcmp(const void *data1, const void *data2)
277 {
278    const struct _Cursor_Id *c1 = data1;
279    const struct _Cursor_Id *c2 = data2;
280    return strcmp (c1->name, c2->name);
281 }
282
283 static void
284 _elm_cursor_cur_set(Elm_Cursor *cur)
285 {
286    if (cur->engine_only)
287      {
288         INF("Using only engine cursors");
289         cur->use_engine = EINA_TRUE;
290      }
291    else if (_elm_cursor_obj_add(cur->eventarea, cur))
292      {
293         _elm_cursor_set_hot_spots(cur);
294         cur->use_engine = EINA_FALSE;
295         elm_widget_cursor_add(cur->owner, cur);
296      }
297    else
298      {
299         INF("Cursor couldn't be found on theme: %s", cur->cursor_name);
300         cur->use_engine = EINA_TRUE;
301      }
302
303    if (cur->use_engine)
304      {
305 #ifdef HAVE_ELEMENTARY_X
306         struct _Cursor_Id cur_search, *cur_id;
307
308         cur_search.name = cur->cursor_name;
309         cur_id = bsearch(&(cur->cursor_name), _cursors, _cursors_count,
310                          sizeof(struct _Cursor_Id), _elm_cursor_strcmp);
311
312         cur->win = elm_win_xwindow_get(cur->eventarea);
313         if (!cur_id)
314           {
315              INF("X cursor couldn't be found: %s. Using default.",
316                  cur->cursor_name);
317              cur->cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_X);
318           }
319         else
320            cur->cursor = ecore_x_cursor_shape_get(cur_id->id);
321 #endif
322      }
323 }
324
325 /**
326  * Set the cursor to be shown when mouse is over the object
327  *
328  * Set the cursor that will be displayed when mouse is over the
329  * object. The object can have only one cursor set to it, so if
330  * this function is called twice for an object, the previous set
331  * will be unset.
332  * If using X cursors, a definition of all the valid cursor names
333  * is listed on Elementary_Cursors.h. If an invalid name is set
334  * the default cursor will be used.
335  *
336  * This is an internal function that is used by objects with sub-items
337  * that want to provide different cursors for each of them. The @a
338  * owner object should be an elm_widget and will be used to track
339  * theme changes and to feed @a func and @a del_cb. The @a eventarea
340  * may be any object and is the one that should be used later on with
341  * elm_object_cursor apis, such as elm_object_cursor_unset().
342  *
343  * @param eventarea the object being attached a cursor.
344  * @param owner the elm_widget that owns this object, will be used to
345  *        track theme changes and to be used in @a func or @a del_cb.
346  * @param cursor the cursor name to be used.
347  *
348  * @internal
349  * @ingroup Cursors
350  */
351 void
352 elm_object_sub_cursor_set(Evas_Object *eventarea, Evas_Object *owner, const char *cursor)
353 {
354    Elm_Cursor *cur = NULL;
355
356    cur = evas_object_data_get(eventarea, _cursor_key);
357    if (cur)
358      elm_object_cursor_unset(eventarea);
359
360    if (!cursor) return;
361
362    cur = ELM_NEW(Elm_Cursor);
363    if (!cur) return;
364
365    cur->owner = owner;
366    cur->eventarea = eventarea;
367    cur->engine_only = _elm_config->cursor_engine_only;
368    cur->visible = EINA_FALSE;
369
370    cur->cursor_name = eina_stringshare_add(cursor);
371    if (!cur->cursor_name)
372      ERR("Could not store cursor name %s", cursor);
373
374    cur->evas = evas_object_evas_get(eventarea);
375    cur->ee = ecore_evas_ecore_evas_get(cur->evas);
376
377    _elm_cursor_cur_set(cur);
378
379    evas_object_data_set(eventarea, _cursor_key, cur);
380
381    evas_object_event_callback_add(eventarea, EVAS_CALLBACK_MOUSE_IN,
382                                   _elm_cursor_mouse_in, cur);
383    evas_object_event_callback_add(eventarea, EVAS_CALLBACK_MOUSE_OUT,
384                                   _elm_cursor_mouse_out, cur);
385    evas_object_event_callback_add(eventarea, EVAS_CALLBACK_DEL,
386                                   _elm_cursor_del, cur);
387 }
388
389 /**
390  * Set the cursor to be shown when mouse is over the object
391  *
392  * Set the cursor that will be displayed when mouse is over the
393  * object. The object can have only one cursor set to it, so if
394  * this function is called twice for an object, the previous set
395  * will be unset.
396  * If using X cursors, a definition of all the valid cursor names
397  * is listed on Elementary_Cursors.h. If an invalid name is set
398  * the default cursor will be used.
399  *
400  * @param obj the object being set a cursor.
401  * @param cursor the cursor name to be used.
402  *
403  * @ingroup Cursors
404  */
405 EAPI void
406 elm_object_cursor_set(Evas_Object *obj, const char *cursor)
407 {
408    EINA_SAFETY_ON_NULL_RETURN(obj);
409    elm_object_sub_cursor_set(obj, obj, cursor);
410 }
411
412 /**
413  * Get the cursor to be shown when mouse is over the object
414  *
415  * @param obj an object with cursor already set.
416  * @return the cursor name.
417  *
418  * @ingroup Cursors
419  */
420 EAPI const char *
421 elm_object_cursor_get(const Evas_Object *obj)
422 {
423    ELM_CURSOR_GET_OR_RETURN(cur, obj, NULL);
424    return cur->cursor_name;
425 }
426
427 /**
428  * Unset cursor for object
429  *
430  * Unset cursor for object, and set the cursor to default if the mouse
431  * was over this object.
432  *
433  * @param obj Target object
434  * @see elm_object_cursor_set()
435  *
436  * @ingroup Cursors
437  */
438 EAPI void
439 elm_object_cursor_unset(Evas_Object *obj)
440 {
441    ELM_CURSOR_GET_OR_RETURN(cur, obj);
442
443    eina_stringshare_del(cur->cursor_name);
444    eina_stringshare_del(cur->style);
445
446    if (cur->owner)
447      elm_widget_cursor_del(cur->owner, cur);
448
449    if (cur->obj)
450      evas_object_del(cur->obj);
451
452    if (cur->visible)
453      {
454         if (!cur->use_engine)
455           ecore_evas_object_cursor_set(cur->ee, NULL, ELM_OBJECT_LAYER_CURSOR,
456                                        cur->hot_x, cur->hot_y);
457 #ifdef HAVE_ELEMENTARY_X
458         else
459           ecore_x_window_cursor_set(cur->win, ECORE_X_CURSOR_X);
460 #endif
461      }
462
463    evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_IN,
464                                   _elm_cursor_mouse_in);
465    evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_OUT,
466                                   _elm_cursor_mouse_out);
467    evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _elm_cursor_del);
468
469    evas_object_data_del(obj, _cursor_key);
470    free(cur);
471 }
472
473 /**
474  * Sets a different style for this object cursor.
475  *
476  * @note before you set a style you should define a cursor with
477  *       elm_object_cursor_set()
478  *
479  * @param obj an object with cursor already set.
480  * @param style the theme style to use (default, transparent, ...)
481  *
482  * @ingroup Cursors
483  */
484 EAPI void
485 elm_object_cursor_style_set(Evas_Object *obj, const char *style)
486 {
487    ELM_CURSOR_GET_OR_RETURN(cur, obj);
488
489    if (!eina_stringshare_replace(&cur->style, style))
490      ERR("Could not set current style=%s", style);
491
492    if (cur->use_engine) return;
493
494    if (!cur->obj)
495      {
496         if (!_elm_cursor_obj_add(obj, cur))
497           ERR("Could not create cursor object");
498         else
499           _elm_cursor_set_hot_spots(cur);
500      }
501    else
502      {
503         if (!_elm_theme_object_set(obj, cur->obj, "cursor", cur->cursor_name,
504                                    style))
505           ERR("Could not apply the theme to the cursor style=%s", style);
506         else
507           _elm_cursor_set_hot_spots(cur);
508      }
509 }
510
511 /**
512  * Get the style for this object cursor.
513  *
514  * @param obj an object with cursor already set.
515  * @return style the theme style in use, defaults to "default". If the
516  *         object does not have a cursor set, then NULL is returned.
517  *
518  * @ingroup Cursors
519  */
520 EAPI const char *
521 elm_object_cursor_style_get(const Evas_Object *obj)
522 {
523    ELM_CURSOR_GET_OR_RETURN(cur, obj, NULL);
524    return cur->style ? cur->style : "default";
525 }
526
527 /**
528  * Notify cursor should recalculate its theme.
529  * @internal
530  */
531 void
532 elm_cursor_theme(Elm_Cursor *cur)
533 {
534    if ((!cur) || (!cur->obj)) return;
535    if (!_elm_theme_object_set(cur->eventarea, cur->obj, "cursor",
536                               cur->cursor_name, cur->style))
537      ERR("Could not apply the theme to the cursor style=%s", cur->style);
538    else
539      _elm_cursor_set_hot_spots(cur);
540 }
541
542 /**
543  * Set if the cursor set should be searched on the theme or should use
544  * the provided by the engine, only.
545  *
546  * @note before you set if should look on theme you should define a cursor
547  * with elm_object_cursor_set(). By default it will only look for cursors
548  * provided by the engine.
549  *
550  * @param obj an object with cursor already set.
551  * @param engine_only boolean to define it cursors should be looked only
552  * between the provided by the engine or searched on widget's theme as well.
553  *
554  * @ingroup Cursors
555  */
556 EAPI void
557 elm_object_cursor_engine_only_set(Evas_Object *obj, Eina_Bool engine_only)
558 {
559    ELM_CURSOR_GET_OR_RETURN(cur, obj);
560    cur->engine_only = engine_only;
561    if (cur->obj)
562      {
563         evas_object_del(cur->obj);
564         cur->obj = NULL;
565      }
566    _elm_cursor_cur_set(cur);
567 }
568
569 /**
570  * Get the cursor engine only usage for this object cursor.
571  *
572  * @param obj an object with cursor already set.
573  * @return engine_only boolean to define it cursors should be looked only
574  * between the provided by the engine or searched on widget's theme as well. If
575  *         the object does not have a cursor set, then EINA_FALSE is returned.
576  *
577  * @ingroup Cursors
578  */
579 EAPI Eina_Bool
580 elm_object_cursor_engine_only_get(const Evas_Object *obj)
581 {
582    ELM_CURSOR_GET_OR_RETURN(cur, obj, EINA_FALSE);
583    return cur->engine_only;
584 }
585
586 /**
587  * Get the configured cursor engine only usage
588  *
589  * This gets the globally configured exclusive usage of engine cursors.
590  *
591  * @return 1 if only engine cursors should be used
592  * @ingroup Cursors
593  */
594 EAPI int
595 elm_cursor_engine_only_get(void)
596 {
597    return _elm_config->cursor_engine_only;
598 }
599
600 /**
601  * Set the configured cursor engine only usage
602  *
603  * This sets the globally configured exclusive usage of engine cursors.
604  * It won't affect cursors set before changing this value.
605  *
606  * @param engine_only If 1 only engine cursors will be enabled, if 0 will
607  * look for them on theme before.
608  * @return EINA_TRUE if value is valid and setted (0 or 1)
609  * @ingroup Cursors
610  */
611 EAPI Eina_Bool
612 elm_cursor_engine_only_set(int engine_only)
613 {
614    if ((engine_only < 0) || (engine_only > 1)) return EINA_FALSE;
615    _elm_config->cursor_engine_only = engine_only;
616    return EINA_TRUE;
617 }