[MOVE] Add Zone rotation Lock / Unlock
[framework/uifw/e17-extra-modules.git] / move-tizen / src / e_mod_move_util.c
1 #include <utilX.h>
2 #include "e_mod_move_shared_types.h"
3 #include "e_mod_move_debug.h"
4 #include "e_mod_move_atoms.h"
5
6 /* local subsystem globals */
7 static E_Move *_m = NULL;
8
9 /* externally accessible functions */
10 EINTERN void
11 e_mod_move_util_set(E_Move        *m,
12                     E_Manager *man __UNUSED__)
13 {
14    _m = m;
15 }
16
17 EINTERN E_Move *
18 e_mod_move_util_get(void)
19 {
20    return _m;
21 }
22
23 EINTERN Eina_Bool
24 e_mod_move_util_border_visible_get(E_Move_Border *mb)
25 {
26    return EINA_TRUE;
27 }
28
29 EINTERN Ecore_X_Window
30 e_mod_move_util_client_xid_get(E_Move_Border *mb)
31 {
32    E_CHECK_RETURN(mb, 0);
33    if (mb->bd) return mb->bd->client.win;
34    else return 0;
35 }
36
37 #define _WND_REQUEST_ANGLE_IDX 0
38 #define _WND_CURR_ANGLE_IDX    1
39
40 EINTERN Eina_Bool
41 e_mod_move_util_win_prop_angle_get(Ecore_X_Window win,
42                                    int           *req,
43                                    int           *curr)
44 {
45    Eina_Bool res = EINA_FALSE;
46    int ret, count;
47    int angle[2] = {-1, -1};
48    unsigned char* prop_data = NULL;
49
50    ret = ecore_x_window_prop_property_get(win,
51                                           ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
52                                           ECORE_X_ATOM_CARDINAL,
53                                           32,
54                                           &prop_data,
55                                           &count);
56    if (ret <= 0)
57      {
58         if (prop_data) free(prop_data);
59         return res;
60      }
61    if (ret && prop_data)
62      {
63         memcpy (&angle, prop_data, sizeof (int)*count);
64         if (count == 2) res = EINA_TRUE;
65      }
66
67    if (prop_data) free(prop_data);
68
69    *req  = angle[_WND_REQUEST_ANGLE_IDX];
70    *curr = angle[_WND_CURR_ANGLE_IDX];
71
72    if (angle[0] == -1 && angle[1] == -1) res = EINA_FALSE;
73
74    return res;
75 }
76
77 EINTERN void
78 e_mod_move_util_border_hidden_set(E_Move_Border *mb,
79                                   Eina_Bool      hidden)
80 {
81    E_Move *m = NULL;
82    E_Border *bd = NULL;
83    E_Manager_Comp_Source *comp_src = NULL;
84    Eina_Bool comp_hidden;
85
86    E_CHECK(mb);
87    m = mb->m;
88
89    if (m->man->comp)
90      {
91         bd = e_border_find_all_by_client_window(mb->client_win);
92         E_CHECK_GOTO(bd, error_cleanup);
93         comp_src = e_manager_comp_src_get(m->man, bd->win);
94         E_CHECK_GOTO(comp_src, error_cleanup);
95         comp_hidden = e_manager_comp_src_hidden_get(m->man, comp_src);
96
97         if (comp_hidden == hidden)
98           return;
99         else
100           e_manager_comp_src_hidden_set(m->man, comp_src, hidden);
101      }
102
103 error_cleanup:
104    return;
105 }
106
107 EINTERN void
108 e_mod_move_util_rotation_lock(E_Move *m)
109 {
110    unsigned int val = 1;
111    E_Manager   *man = NULL;
112    E_Zone      *zone = NULL;
113
114    E_CHECK(m);
115
116    man = m->man;
117    E_CHECK(man);
118
119    zone = e_util_zone_current_get(man);
120    E_CHECK(zone);
121
122    e_zone_rotation_block_set(zone, "move-tizen", EINA_TRUE);
123    ecore_x_window_prop_card32_set(m->man->root, ATOM_ROTATION_LOCK, &val, 1);
124 }
125
126 EINTERN void
127 e_mod_move_util_rotation_unlock(E_Move *m)
128 {
129    unsigned int val = 0;
130    E_Manager   *man = NULL;
131    E_Zone      *zone = NULL;
132
133    E_CHECK(m);
134
135    man = m->man;
136    E_CHECK(man);
137
138    zone = e_util_zone_current_get(man);
139    E_CHECK(zone);
140
141    e_zone_rotation_block_set(zone, "move-tizen", EINA_FALSE);
142    ecore_x_window_prop_card32_set(m->man->root, ATOM_ROTATION_LOCK, &val, 1);
143 }
144
145 EINTERN Eina_Bool
146 e_mod_move_util_compositor_object_visible_get(E_Move_Border *mb)
147 {
148    // get Evas_Object from Compositor
149    E_Move *m = NULL;
150    E_Border *bd = NULL;
151    Evas_Object *comp_obj = NULL;
152    E_Manager_Comp_Source *comp_src = NULL;
153    Eina_Bool ret = EINA_FALSE;
154
155    E_CHECK_RETURN(mb, EINA_FALSE);
156    m = mb->m;
157    E_CHECK_RETURN(m, EINA_FALSE);
158
159    if (m->man->comp)
160      {
161         bd = e_border_find_all_by_client_window(mb->client_win);
162         E_CHECK_RETURN(bd, EINA_FALSE);
163
164         comp_src = e_manager_comp_src_get(m->man, bd->win);
165         E_CHECK_RETURN(comp_src, EINA_FALSE);
166
167         comp_obj = e_manager_comp_src_shadow_get(m->man, comp_src);
168         E_CHECK_RETURN(comp_obj, EINA_FALSE);
169         ret = evas_object_visible_get(comp_obj);
170      }
171
172    return ret;
173 }
174
175 EINTERN E_Move_Border *
176 e_mod_move_util_visible_fullscreen_window_find(void)
177 {
178    E_Move        *m = NULL;
179    E_Move_Border *mb = NULL;
180    E_Move_Border *ret_mb = NULL;
181    E_Zone        *zone = NULL;
182
183    m = e_mod_move_util_get();
184    E_CHECK_RETURN(m, 0);
185
186    EINA_INLIST_REVERSE_FOREACH(m->borders, mb)
187      {
188         zone = mb->bd->zone;
189         if ( (zone->x == mb->x)
190              && (zone->y == mb->y)
191              && (zone->w == mb->w)
192              && (zone->h == mb->h))
193           {
194              if (mb->visibility == E_MOVE_VISIBILITY_STATE_VISIBLE)
195                ret_mb = mb;
196              break;
197           }
198      }
199    return ret_mb;
200 }
201
202 EINTERN void
203 e_mod_move_util_compositor_composite_mode_set(E_Move   *m,
204                                               Eina_Bool set)
205 {
206    E_Zone    *zone = NULL;
207    E_Manager *man = NULL;
208    E_CHECK(m);
209    man = m->man;
210    E_CHECK(man);
211    E_CHECK(man->comp);
212
213    zone = e_util_zone_current_get(man);
214    E_CHECK(zone);
215    e_manager_comp_composite_mode_set(man, zone, set);
216 }
217
218 EINTERN void
219 e_mod_move_util_fb_move(int angle,
220                         int cw,
221                         int ch,
222                         int x,
223                         int y)
224 {
225    Ecore_X_Display *d = ecore_x_display_get();
226    int fb_x = 0, fb_y = 0;
227    E_CHECK(d);
228
229    switch (angle)
230      {
231       case   0: fb_x = 0;      fb_y = y + ch; break;
232       case  90: fb_x = x + cw; fb_y = 0;      break;
233       case 180: fb_x = 0;      fb_y = y - ch; break;
234       case 270: fb_x = x - cw; fb_y = 0;      break;
235       default :
236          break;
237      }
238
239    utilx_set_video_offset(d, fb_x, fb_y);
240 }
241
242 EINTERN int
243 e_mod_move_util_layer_policy_get(E_Move_Layer_Policy layer)
244 {
245    int ret = 100;
246    switch (layer)
247      {
248       case E_MOVE_QUICKPANEL_LAYER:
249       case E_MOVE_NOTIFICATION_LAYER:
250       case E_MOVE_INDICATOR_LAYER:
251            ret = 300; break;
252       case E_MOVE_FULLSCREEN_LAYER:
253            ret = 250; break;
254       case E_MOVE_STATE_ABOVE_LAYER:
255       case E_MOVE_ACTIVATE_LAYER:
256       case E_MOVE_DIALOG_LAYER:
257       case E_MOVE_SPLASH_LAYER:
258       case E_MOVE_SOFTKEY_LAYER:
259            ret = 150; break;
260       case E_MOVE_CLIPBOARD_LAYER:
261       case E_MOVE_KEYBOARD_LAYER:
262       case E_MOVE_CONFORMANT_LAYER:
263       case E_MOVE_APP_LAYER:
264       case E_MOVE_HOME_LAYER:
265            ret = 100; break;
266       case E_MOVE_STATE_BELOW_LAYER:
267            ret = 50; break;
268       default:
269            break;
270      }
271   return ret;
272 }
273
274 EINTERN E_Move_Scroll_Region_Indicator
275 e_mod_move_indicator_region_scroll_check(int        angle,
276                                          Evas_Point input)
277 {
278    E_Move *m = NULL;
279    int w = 0, h = 0;
280    int region_always = 0;
281    int region_quickpanel = 0;
282    int region_apptray = 0;
283    E_Move_Border *indi_mb = NULL;
284    E_Move_Scroll_Region_Indicator ret = E_MOVE_SCROLL_REGION_NONE;
285
286    m = e_mod_move_util_get();
287    E_CHECK_RETURN(m, E_MOVE_SCROLL_REGION_NONE);
288
289    if (!m->elm_indicator_mode) // Indicator Window mode
290      {
291         indi_mb = e_mod_move_indicator_find();
292         E_CHECK_RETURN(indi_mb, E_MOVE_SCROLL_REGION_NONE);
293         w = indi_mb->w;
294         h = indi_mb->h;
295      }
296
297    switch (angle)
298      {
299       case  0:
300          if (m->elm_indicator_mode)
301            w = m->indicator_widget_geometry[E_MOVE_ANGLE_0].w;
302
303          region_always = (m->indicator_always_region_ratio.portrait * w);
304          region_quickpanel = (m->indicator_quickpanel_region_ratio.portrait * w);
305          region_apptray = (m->indicator_apptray_region_ratio.portrait * w);
306
307          if (input.x < region_always) ret = E_MOVE_SCROLL_REGION_NONE; // Always scroll region
308          else if ( input.x < region_quickpanel ) ret = E_MOVE_SCROLL_REGION_QUICKPANEL;
309          else  ret = E_MOVE_SCROLL_REGION_NONE; // Apptray scroll region
310          break;
311       case  90:
312          if (m->elm_indicator_mode)
313            h = m->indicator_widget_geometry[E_MOVE_ANGLE_90].h;
314
315          region_always = (h - (m->indicator_always_region_ratio.landscape * h));
316          region_quickpanel = (h - (m->indicator_quickpanel_region_ratio.landscape * h));
317          region_apptray = (h - (m->indicator_apptray_region_ratio.landscape * h));
318
319          if (input.y > region_always) ret = E_MOVE_SCROLL_REGION_NONE; // Always scroll region
320          else if ( input.y > region_quickpanel ) ret = E_MOVE_SCROLL_REGION_QUICKPANEL;
321          else  ret = E_MOVE_SCROLL_REGION_NONE; // Apptray scroll region
322          break;
323       case  180:
324          if (m->elm_indicator_mode)
325            w = m->indicator_widget_geometry[E_MOVE_ANGLE_180].w;
326
327          region_always = (w - (m->indicator_always_region_ratio.portrait * w));
328          region_quickpanel = (w - (m->indicator_quickpanel_region_ratio.portrait * w));
329          region_apptray = (w - (m->indicator_apptray_region_ratio.portrait * w));
330
331          if (input.x > region_always) ret = E_MOVE_SCROLL_REGION_NONE; // Always scroll region
332          else if ( input.x > region_quickpanel ) ret = E_MOVE_SCROLL_REGION_QUICKPANEL;
333          else  ret = E_MOVE_SCROLL_REGION_NONE; // Apptray scroll region
334          break;
335       case  270:
336          if (m->elm_indicator_mode)
337            h = m->indicator_widget_geometry[E_MOVE_ANGLE_270].h;
338
339          region_always = (m->indicator_always_region_ratio.landscape * h);
340          region_quickpanel = (m->indicator_quickpanel_region_ratio.landscape * h);
341          region_apptray = (m->indicator_apptray_region_ratio.landscape * h);
342
343          if (input.y < region_always) ret = E_MOVE_SCROLL_REGION_NONE; // Always scroll region
344          else if ( input.y < region_quickpanel ) ret = E_MOVE_SCROLL_REGION_QUICKPANEL;
345          else  ret = E_MOVE_SCROLL_REGION_NONE; // Apptray scroll region
346          break;
347       default:
348          break;
349      }
350    return ret;
351 }
352
353 EINTERN Eina_Bool
354 e_mod_move_panel_scrollable_state_init(E_Move_Panel_Scrollable_State *panel_scrollable_state)
355 {
356    E_CHECK_RETURN(panel_scrollable_state, EINA_FALSE);
357
358    panel_scrollable_state->always = EINA_TRUE;
359    panel_scrollable_state->quickpanel = EINA_TRUE;
360    panel_scrollable_state->apptray = EINA_TRUE;
361
362    return EINA_TRUE;
363 }
364
365 EINTERN Eina_Bool
366 e_mod_move_panel_scrollable_state_get(Ecore_X_Window                 win,
367                                       E_Move_Panel_Scrollable_State *panel_scrollable_state)
368 {
369    unsigned int *vals = NULL;
370    Eina_Bool res = EINA_FALSE;
371    int num = 0;
372
373    E_CHECK_RETURN(panel_scrollable_state, EINA_FALSE);
374    E_CHECK_RETURN(win, EINA_FALSE);
375
376    num = ecore_x_window_prop_card32_list_get
377            (win, ATOM_MV_PANEL_SCROLLABLE_STATE, &vals);
378    E_CHECK_GOTO((num == 3), cleanup); // currently, we uses only 3 panel type
379    E_CHECK_GOTO(vals, cleanup);
380
381    panel_scrollable_state->always = (vals[0] ? EINA_TRUE : EINA_FALSE);
382    panel_scrollable_state->quickpanel = (vals[1] ? EINA_TRUE : EINA_FALSE);
383    panel_scrollable_state->apptray = (vals[2] ? EINA_TRUE : EINA_FALSE);
384    res = EINA_TRUE;
385
386 cleanup:
387
388    if (vals) E_FREE(vals);
389    return res;
390 }
391
392 EINTERN Eina_Bool
393 e_mod_move_panel_scrollable_get(E_Move_Border *mb, E_Move_Panel_Type type)
394 {
395    Eina_Bool res = EINA_FALSE;
396
397    E_CHECK_RETURN(mb, EINA_FALSE);
398
399    switch (type)
400      {
401       case E_MOVE_PANEL_TYPE_ALWAYS:
402         res = mb->panel_scrollable_state.always;
403         break;
404       case E_MOVE_PANEL_TYPE_QUICKPANEL:
405         res = mb->panel_scrollable_state.quickpanel;
406         break;
407       case E_MOVE_PANEL_TYPE_APPTRAY:
408         res = mb->panel_scrollable_state.apptray;
409         break;
410       case E_MOVE_PANEL_TYPE_NONE:
411       default:
412         break;
413      }
414
415    return res;
416 }
417
418 EINTERN E_Border*
419 e_mod_move_util_border_find_by_pointer(int x,
420                                        int y)
421 {
422    E_Border_List *bl = NULL;
423    E_Border      *temp_bd = NULL;
424    E_Border      *find_bd = NULL;
425    E_Border      *focused_bd = NULL;
426
427    focused_bd = e_border_focused_get();
428    E_CHECK_RETURN(focused_bd, NULL);
429
430    bl = e_container_border_list_last(focused_bd->zone->container);
431
432    while ((temp_bd = e_container_border_list_prev(bl)))
433      {
434        if (!temp_bd) continue;
435
436        if (!E_INSIDE(x, y, temp_bd->x, temp_bd->y, temp_bd->w, temp_bd->h))
437          continue;
438        if (!find_bd)
439          {
440             find_bd = temp_bd;
441             break;
442          }
443      }
444    e_container_border_list_free(bl);
445
446    return find_bd;
447 }
448
449 EINTERN int
450 e_mod_move_util_root_angle_get(void)
451 {
452    E_Move        *m = NULL;
453    unsigned char *data = NULL;
454    int            ret;
455    int            cnt;
456    int            angle = 0;
457
458    m = e_mod_move_util_get();
459    E_CHECK_RETURN(m, 0);
460
461    ret = ecore_x_window_prop_property_get(m->man->root,
462                                           ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE,
463                                           ECORE_X_ATOM_CARDINAL,
464                                           32,
465                                           &data,
466                                           &cnt);
467    if (ret && data) memcpy (&angle, data, sizeof(int));
468    if (data) free (data);
469    if (angle) angle %= 360;
470
471    return angle;
472 }