Update minictrl and assistive_light
[apps/core/preloaded/quickpanel.git] / daemon / notifications / noti_win_x11.c
1 /*
2  * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <Elementary.h>
19 #include <utilX.h>
20 #include <efl_util.h>
21
22 #define NOTI_HEIGHT 200
23 #define NOTI_BTN_HEIGHT 80
24
25 #ifndef __UNUSED__
26 #define __UNUSED__ __attribute__((unused))
27 #endif
28 /* Using this macro to emphasize that some portion like stacking and
29 rotation handling are implemented for X based platform
30 */
31
32 #include <Ecore_X.h>
33 #include "common.h"
34 #include "noti_win.h"
35 #include "dbus_utility.h"
36
37 struct Internal_Data {
38         Evas_Object *content;
39         Ecore_Event_Handler *rotation_event_handler;
40         Evas_Coord w;
41         Evas_Coord h;
42         int angle;
43         enum Noti_Orient orient;
44 };
45
46 static const char *data_key = "_data";
47
48 static void _show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
49         void *event_info __UNUSED__)
50 {
51         struct Internal_Data *wd = evas_object_data_get(obj, data_key);
52
53         if (!wd) {
54                 return;
55         }
56         if (wd->content) {
57                 evas_object_show(wd->content);
58         }
59 }
60
61 static void _content_changed_size_hints(void *data, Evas *e __UNUSED__,
62         Evas_Object *obj, void *event_info __UNUSED__)
63 {
64         Evas_Coord h = 0;
65         struct Internal_Data *wd = evas_object_data_get(data, data_key);
66
67         if (!wd) {
68                 return;
69         }
70
71         evas_object_size_hint_min_get(obj, NULL, &h);
72         if ((h > 0)) {
73                 wd->h = h;
74                 evas_object_size_hint_min_set(obj, wd->w, wd->h);
75                 evas_object_size_hint_min_set(data, wd->w, wd->h);
76                 evas_object_resize(data, wd->w, wd->h);
77         }
78 }
79
80 static void _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
81 {
82         struct Internal_Data *wd = evas_object_data_get(obj, data_key);
83         Evas_Object *sub = event_info;
84
85         if (!wd) {
86                 return;
87         }
88         if (sub == wd->content) {
89                 evas_object_event_callback_del(wd->content,
90                         EVAS_CALLBACK_CHANGED_SIZE_HINTS,
91                         _content_changed_size_hints);
92                 wd->content = NULL;
93         }
94 }
95
96 static void _resized(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
97         void *event_info __UNUSED__)
98 {
99         evas_object_show(obj);
100 }
101
102 static void _del(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
103         void *event_info __UNUSED__)
104 {
105
106         struct Internal_Data *wd = evas_object_data_get(obj, data_key);
107
108         if (wd) {
109                 if (wd->rotation_event_handler) {
110                         ecore_event_handler_del(wd->rotation_event_handler);
111                 }
112                 free(wd);
113         }
114
115         evas_object_data_set(data, data_key, NULL);
116 }
117
118 static void _update_geometry_on_rotation(Evas_Object *obj, int angle,
119                 int *x, int *y, int *w)
120 {
121         Evas_Coord root_w, root_h;
122         struct Internal_Data *wd = evas_object_data_get(obj, data_key);
123
124         if (!wd) {
125                 return;
126         }
127
128         ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w, &root_h);
129
130         switch (angle) {
131         case 90:
132                 *w = root_h;
133                 if (wd->orient == NOTI_ORIENT_BOTTOM) {
134                         *x = root_w - wd->h;
135                 }
136                 break;
137         case 270:
138                 *w = root_h;
139                 if (!(wd->orient == NOTI_ORIENT_BOTTOM)) {
140                         *x = root_w - wd->h;
141                 }
142                 break;
143         case 180:
144                 *w = root_w;
145                 if (!wd->orient == NOTI_ORIENT_BOTTOM) {
146                         *y = root_h - wd->h;
147                 }
148                 break;
149         case 0:
150         default:
151                 *w = root_w;
152                 if (wd->orient == NOTI_ORIENT_BOTTOM) {
153                         *y = root_h - wd->h;
154                 }
155                 break;
156         }
157 }
158 static void _win_rotated(Evas_Object *obj)
159 {
160         int x = 0;
161         int y = 0;
162         int w = 0;
163         int angle = 0;
164         struct Internal_Data *wd =  evas_object_data_get(obj, data_key);
165
166         if (!wd) {
167                 return;
168         }
169         angle = elm_win_rotation_get(obj);
170         if (angle % 90) {
171                 return;
172         }
173         angle %= 360;
174         if (angle < 0)
175                 angle += 360;
176         wd->angle = angle;
177
178         _update_geometry_on_rotation(obj, wd->angle, &x, &y, &w);
179
180         evas_object_move(obj, x, y);
181         wd->w = w;
182         evas_object_resize(obj, wd->w, wd->h);
183 }
184
185 static void _ui_rotation_wm_cb(void *data, Evas_Object *obj, void *event)
186 {
187         int angle = 0;
188         angle = elm_win_rotation_get((Evas_Object *)obj);
189
190         DBG("ACTIVENOTI ROTATE:%d", angle);
191
192         _win_rotated(obj);
193 }
194
195 HAPI Evas_Object *quickpanel_noti_win_add(Evas_Object *parent)
196 {
197         Evas_Object *win;
198         Evas_Object *bg;
199         struct Internal_Data *wd;
200         Evas_Coord w = 0, h = 0;
201
202         win = elm_win_add(parent, "noti_win", ELM_WIN_NOTIFICATION);
203         if (!win) {
204                 return NULL;
205         }
206
207         elm_win_indicator_mode_set(win, ELM_WIN_INDICATOR_SHOW);
208         elm_win_alpha_set(win, EINA_FALSE);
209         elm_win_indicator_type_set(win,ELM_WIN_INDICATOR_TYPE_1);
210         elm_win_title_set(win, "noti_win");
211         elm_win_borderless_set(win, EINA_TRUE);
212         elm_win_autodel_set(win, EINA_TRUE);
213         evas_object_size_hint_weight_set(win, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
214         evas_object_size_hint_align_set(win, EVAS_HINT_FILL, EVAS_HINT_FILL);
215
216         efl_util_set_notification_window_level(win, EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT); 
217         elm_win_aux_hint_add(win, "wm.policy.win.user.geometry", "1");
218         elm_win_prop_focus_skip_set(win, EINA_TRUE);
219
220         bg = elm_bg_add(win);
221         evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
222         elm_win_resize_object_add(win, bg);
223
224         if (elm_win_wm_rotation_supported_get(win)) {
225                 int rots[4] = { 0, 90, 180, 270 };
226                 elm_win_wm_rotation_available_rotations_set(win, rots, 4);
227         }
228         evas_object_smart_callback_add(win, "wm,rotation,changed", _ui_rotation_wm_cb, NULL);
229
230         wd = (struct Internal_Data *) calloc(1, sizeof(struct Internal_Data));
231         if (!wd) {
232                 if (win) {
233                         evas_object_del(win);
234                 }
235                 return NULL;
236         }
237         evas_object_data_set(win, data_key, wd);
238         wd->angle = 0;
239         wd->orient = NOTI_ORIENT_TOP;
240         evas_object_move(win, 0, 0);
241         elm_win_screen_size_get(win, NULL, NULL, &w, &h);
242
243         wd->w = w;
244         wd->h = NOTI_HEIGHT;
245
246         evas_object_resize(win, w, wd->h);
247         evas_object_event_callback_add(win, EVAS_CALLBACK_SHOW, _show, NULL);
248         evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _del, NULL);
249         evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, _resized, NULL);
250
251         return win;
252 }
253
254 HAPI void quickpanel_noti_win_content_set(Evas_Object *obj, Evas_Object *content, int btn_cnt)
255 {
256         Evas_Coord h;
257         struct Internal_Data *wd;
258
259         if (!obj) {
260                 return;
261         }
262         wd = evas_object_data_get(obj, data_key);
263         if (!wd) {
264                 return;
265         }
266         if (wd->content && content != NULL) {
267                 evas_object_del(content);
268                 content = NULL;
269         }
270         wd->content = content;
271
272         if (btn_cnt > 0) {
273                 wd->h += NOTI_BTN_HEIGHT;
274         }
275         if (content) {
276                 evas_object_size_hint_weight_set(wd->content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
277                 elm_win_resize_object_add(obj, wd->content);
278                 evas_object_size_hint_min_set(wd->content, wd->w, wd->h);
279                 evas_object_resize(obj, wd->w, wd->h);
280                 evas_object_event_callback_add(wd->content,     EVAS_CALLBACK_CHANGED_SIZE_HINTS, _content_changed_size_hints, obj);
281         }
282 }
283
284 HAPI void quickpanel_noti_win_orient_set(Evas_Object *obj, enum Noti_Orient orient)
285 {
286         Evas_Coord root_w, root_h;
287         struct Internal_Data *wd = evas_object_data_get(obj, data_key);
288
289         if (!wd) {
290                 return;
291         }
292         if (orient >= NOTI_ORIENT_LAST) {
293                 return;
294         }
295         ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w, &root_h);
296         switch (orient) {
297         case NOTI_ORIENT_BOTTOM:
298                 evas_object_move(obj, 0, root_h - wd->h);
299                 wd->orient = NOTI_ORIENT_BOTTOM;
300                 break;
301         case NOTI_ORIENT_TOP:
302         default:
303                 evas_object_move(obj, 0, 0);
304                 wd->orient = NOTI_ORIENT_TOP;
305                 break;
306         }
307 }