e_comp_screen: do not rotate pointer in e_comp
[platform/upstream/enlightenment.git] / src / bin / e_pointer.c
1 #include "e.h"
2 #include <Ecore_Drm.h>
3
4 /* local variables */
5 static Eina_List *_ptrs = NULL;
6 static Eina_Bool _initted = EINA_FALSE;
7
8 /* temp variable */
9 static Eina_Bool override = EINA_FALSE;
10
11 /* move the cursor image with the calcaultion of the hot spot */
12 static void
13 _e_pointer_position_update(E_Pointer *ptr)
14 {
15    int nx, ny;
16    int rotation;
17    int cursor_w, cursor_h;
18    E_Client *ec;
19
20    if (!ptr->o_ptr) return;
21
22    ec = e_comp_object_client_get(ptr->o_ptr);
23    EINA_SAFETY_ON_NULL_RETURN(ec);
24
25    rotation = ptr->rotation;
26
27    evas_object_geometry_get(ec->frame, NULL, NULL, &cursor_w, &cursor_h);
28
29    switch (rotation)
30      {
31       case 0:
32         nx = ptr->x - ptr->hot.x;
33         ny = ptr->y - ptr->hot.y;
34         break;
35       case 90:
36         nx = ptr->x - ptr->hot.y;
37         ny = ptr->y + ptr->hot.x - cursor_w;
38         break;
39       case 180:
40         nx = ptr->x + ptr->hot.x - cursor_w;
41         ny = ptr->y + ptr->hot.y - cursor_h;
42         break;
43       case 270:
44         nx = ptr->x + ptr->hot.y - cursor_h;
45         ny = ptr->y - ptr->hot.x;
46         break;
47       default:
48         nx = ptr->x - ptr->hot.x;
49         ny = ptr->y - ptr->hot.y;
50         break;
51      }
52
53    if (ptr->hwc)
54       e_comp_object_hwc_update_set(ptr->o_ptr, EINA_TRUE);
55    else
56       evas_object_move(ptr->o_ptr, nx, ny);
57 }
58
59 static void
60 _e_pointer_object_rotation(E_Pointer *ptr)
61 {
62    Evas_Map *map;
63    int x, y, w, h;
64    E_Client *ec;
65    int rotation;
66
67    EINA_SAFETY_ON_NULL_RETURN(ptr);
68    if (!ptr->o_ptr) return;
69
70    ec = e_comp_object_client_get(ptr->o_ptr);
71    EINA_SAFETY_ON_NULL_RETURN(ec);
72
73    rotation = ptr->rotation;
74
75    evas_object_geometry_get(ec->frame, &x, &y, &w, &h);
76
77    if ((rotation == 0) || (rotation % 90 != 0) || (rotation / 90 > 3))
78      {
79         evas_object_map_set(ec->frame, NULL);
80         evas_object_map_enable_set(ec->frame, EINA_FALSE);
81         return;
82      }
83
84    map = evas_map_new(4);
85    evas_map_util_points_populate_from_object_full(map, ec->frame, 0);
86    evas_map_util_points_color_set(map, 255, 255, 255, 255);
87
88    if (rotation == 90)
89      rotation = 270;
90    else if (rotation == 270)
91      rotation = 90;
92    evas_map_util_rotate(map, rotation, x + (w/2), y + (h/2));
93    evas_map_util_object_move_sync_set(map, EINA_TRUE);
94
95    evas_object_map_set(ec->frame, map);
96    evas_object_map_enable_set(ec->frame, map ? EINA_TRUE : EINA_FALSE);
97
98    evas_map_free(map);
99 }
100
101 static void
102 _e_pointer_hwc_rotation(E_Pointer *ptr)
103 {
104    E_Client *ec;
105
106    if (!ptr->o_ptr) return;
107
108    ec = e_comp_object_client_get(ptr->o_ptr);
109    EINA_SAFETY_ON_NULL_RETURN(ec);
110
111    // TODO: roatation cursor buffer with pixman
112 }
113
114 // TODO: transform the cursor position with hot spot...!!!!!!
115 static void
116 _e_pointer_rotation_apply(E_Pointer *ptr)
117 {
118    EINA_SAFETY_ON_NULL_RETURN(ptr);
119
120    if (ptr->hwc)
121       _e_pointer_hwc_rotation(ptr);
122    else
123       _e_pointer_object_rotation(ptr);
124 }
125
126 static void
127 _e_pointer_cb_free(E_Pointer *ptr)
128 {
129    _ptrs = eina_list_remove(_ptrs, ptr);
130
131    free(ptr);
132 }
133
134 EINTERN int
135 e_pointer_init(void)
136 {
137    _initted = EINA_TRUE;
138    return 1;
139 }
140
141 EINTERN int
142 e_pointer_shutdown(void)
143 {
144    _initted = EINA_FALSE;
145    return 1;
146 }
147
148 EINTERN E_Pointer *
149 e_pointer_canvas_new(Ecore_Evas *ee, Eina_Bool filled)
150 {
151    E_Pointer *ptr = NULL;
152
153    EINA_SAFETY_ON_FALSE_RETURN_VAL(ee, NULL);
154    if (!_initted) return NULL;
155
156    /* allocate space for new pointer */
157    if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
158      return NULL;
159
160    /* set default pointer properties */
161    ptr->canvas = EINA_TRUE;
162    ptr->w = ptr->h = e_config->cursor_size;
163    ptr->e_cursor = e_config->use_e_cursor;
164
165    ptr->ee = ee;
166    ptr->evas = ecore_evas_get(ee);
167
168    /* append this pointer to the list */
169    _ptrs = eina_list_append(_ptrs, ptr);
170
171    return ptr;
172 }
173
174 EINTERN void
175 e_pointer_object_set(E_Pointer *ptr, Evas_Object *obj, int x, int y)
176 {
177    E_Client *ec;
178
179    EINA_SAFETY_ON_NULL_RETURN(ptr);
180
181    /* don't show cursor if in hidden mode */
182    if ((!e_config->show_cursor) || (!e_comp_wl->ptr.enabled))
183      {
184         e_pointer_hide(ptr);
185         return;
186      }
187
188    /* hide and unset the existed ptr->o_ptr */
189    if (ptr->o_ptr)
190      {
191         ec = e_comp_object_client_get(ptr->o_ptr);
192         if ((ec) && (!e_object_is_del(E_OBJECT(ec))))
193           {
194              ec->hidden = 1;
195              ec->visible = EINA_FALSE;
196              ec->comp_data->mapped = EINA_FALSE;
197              ec->override = 1; /* ignore the previous cursor_ec */
198           }
199
200         if (ptr->o_ptr != obj)
201            ptr->hwc = EINA_FALSE;
202
203         /* hide cursor object */
204         evas_object_hide(ptr->o_ptr);
205         ptr->o_ptr = NULL;
206         ptr->device = E_POINTER_NONE;
207
208         /* Current if e_pointer set rotation, it can't' use hwc.
209             if it can use hwc, comp override will be removed. */
210         if (ptr->rotation !=0 && override)
211           {
212              e_comp_override_del();
213              override = EINA_FALSE;
214           }
215      }
216
217    /* update the hot spot of the cursor */
218    ptr->hot.x = x;
219    ptr->hot.y = y;
220
221    /* if obj is not null, set the obj to ptr->o_ptr */
222    if (obj)
223      {
224         ec = e_comp_object_client_get(obj);
225         if (ec && e_pixmap_usable_get(ec->pixmap))
226           {
227              ec->hidden = 0;
228              ec->visible = EINA_TRUE;
229              evas_object_geometry_set(ec->frame, ec->x, ec->y, ec->w, ec->h);
230              ec->comp_data->mapped = EINA_TRUE;
231              ec->override = 0; /* do not ignore the cursor_ec to set the image object */
232
233              if (e_comp_is_on_overlay(ec))
234                ptr->hwc = EINA_TRUE;
235           }
236
237         ptr->o_ptr = obj;
238
239         /* move the pointer to the current position */
240         _e_pointer_position_update(ptr);
241
242         /* apply the cursor obj rotation */
243         _e_pointer_rotation_apply(ptr);
244
245         /* Current if e_pointer set rotation, it can't' use hwc.
246            if it can use hwc, comp override will be removed. */
247         switch(ptr->rotation)
248           {
249             case 90:
250             case 180:
251             case 270:
252               if (!override)
253                 {
254                    e_comp_override_add();
255                    override = EINA_TRUE;
256                 }
257                break;
258           }
259
260         /* show cursor object */
261         evas_object_show(obj);
262      }
263 }
264
265 EINTERN void
266 e_pointer_touch_move(E_Pointer *ptr, int x, int y)
267 {
268    EINA_SAFETY_ON_NULL_RETURN(ptr);
269
270    if (!e_config->show_cursor) return;
271
272    /* save the current position */
273    ptr->x = x;
274    ptr->y = y;
275
276    if (ptr->device != E_POINTER_TOUCH) ptr->device = E_POINTER_TOUCH;
277
278    _e_pointer_position_update(ptr);
279 }
280
281 EINTERN void
282 e_pointer_mouse_move(E_Pointer *ptr, int x, int y)
283 {
284    EINA_SAFETY_ON_NULL_RETURN(ptr);
285
286    if (!e_config->show_cursor) return;
287
288    /* save the current position */
289    ptr->x = x;
290    ptr->y = y;
291
292    if (ptr->device != E_POINTER_MOUSE) ptr->device = E_POINTER_MOUSE;
293
294    _e_pointer_position_update(ptr);
295 }
296
297 E_API void
298 e_pointer_hide(E_Pointer *ptr)
299 {
300    EINA_SAFETY_ON_NULL_RETURN(ptr);
301    if (!ptr->o_ptr) return;
302    if (!evas_object_visible_get(ptr->o_ptr)) return;
303
304    evas_object_hide(ptr->o_ptr);
305
306    /* Current if e_pointer set rotation, it can't' use hwc.
307       if it can use hwc, comp override will be removed. */
308    if (ptr->rotation !=0 && override)
309      {
310         e_comp_override_del();
311         override = EINA_FALSE;
312      }
313 }
314
315 E_API Eina_Bool
316 e_pointer_is_hidden(E_Pointer *ptr)
317 {
318    EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_TRUE);
319
320    if (!e_config->show_cursor) return EINA_TRUE;
321    if (ptr->o_ptr && evas_object_visible_get(ptr->o_ptr)) return EINA_FALSE;
322
323    return EINA_TRUE;
324 }
325
326 E_API void
327 e_pointer_rotation_set(E_Pointer *ptr, int rotation)
328 {
329    const Eina_List *l;
330    Ecore_Drm_Device *dev;
331
332    if (ptr->rotation == rotation) return;
333
334    ptr->rotation = rotation;
335
336    _e_pointer_position_update(ptr);
337    _e_pointer_rotation_apply(ptr);
338
339    EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev)
340      ecore_drm_device_pointer_rotation_set(dev, rotation);
341
342    /* ptr->rotation shouldn't include the screen rotation value */
343    if (e_comp->e_comp_screen->rotation > 0)
344       rotation = (e_comp->e_comp_screen->rotation + rotation) % 360;
345
346    /* Current if e_pointer set rotation, it can't' use hwc.
347       if it can use hwc, comp override will be removed. */
348    if ((!ptr->o_ptr) || (ptr->o_ptr && !evas_object_visible_get(ptr->o_ptr))) return;
349
350    switch(rotation)
351      {
352        case 0:
353           if (override)
354             {
355                e_comp_override_del();
356                override = EINA_FALSE;
357             }
358           break;
359        case 90:
360        case 180:
361        case 270:
362           if (!override)
363             {
364                e_comp_override_add();
365                override = EINA_TRUE;
366             }
367           break;
368      }
369 }
370
371 E_API void
372 e_pointer_position_get(E_Pointer *ptr, int *x, int *y)
373 {
374    EINA_SAFETY_ON_NULL_RETURN(ptr);
375
376    if (!e_config->show_cursor) return;
377    if (!ptr->o_ptr) return;
378    if (!evas_object_visible_get(ptr->o_ptr)) return;
379
380    *x = ptr->x;
381    *y = ptr->y;
382 }
383
384 EINTERN Eina_Bool
385 e_pointer_hwc_set(E_Pointer *ptr, Eina_Bool set)
386 {
387    EINA_SAFETY_ON_FALSE_RETURN_VAL(ptr, EINA_FALSE);
388    EINA_SAFETY_ON_FALSE_RETURN_VAL(ptr->o_ptr, EINA_FALSE);
389
390    if (ptr->hwc == set) return EINA_TRUE;
391
392    ptr->hwc = set;
393
394    if (set)
395     {
396        e_comp_object_hwc_update_set(ptr->o_ptr, EINA_TRUE);
397     }
398    else
399     {
400        _e_pointer_position_update(ptr);
401        _e_pointer_rotation_apply(ptr);
402     }
403
404    return EINA_TRUE;
405 }
406
407 E_API E_Pointer *
408 e_pointer_get(E_Client *ec)
409 {
410    const Eina_List *l;
411    E_Pointer *ptr;
412    E_Client *ptr_ec = NULL;
413
414    if ((!ec) || (e_object_is_del(E_OBJECT(ec)))) return NULL;
415
416    EINA_LIST_FOREACH(_ptrs, l, ptr)
417      {
418         if (ptr->o_ptr)
419           {
420              ptr_ec = e_comp_object_client_get(ptr->o_ptr);
421              if (ptr_ec == ec)
422                 return ptr;
423           }
424      }
425
426   return NULL;
427 }