2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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
8 * http://floralicense.org/license/
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.
17 #include <Elementary.h>
20 #define NOTI_HEIGHT 50
22 #define __UNUSED__ __attribute__((unused))
24 /* Using this macro to emphasize that some portion like stacking and
25 rotation handling are implemented for X based platform
34 struct Internal_Data {
36 Ecore_Event_Handler *rotation_event_handler;
40 enum Noti_Orient orient;
43 static const char *data_key = "_data";
45 static void _set_win_type_notification_level(Evas_Object *win)
47 retif(win == NULL, , "invalid parameter");
49 Ecore_X_Window w = elm_win_xwindow_get(win);
52 ecore_x_icccm_hints_set(w, 0, ECORE_X_WINDOW_STATE_HINT_NONE, 0, 0,
54 ecore_x_netwm_opacity_set(w, 0);
56 ecore_x_netwm_window_type_set(w,
57 ECORE_X_WINDOW_TYPE_NOTIFICATION);
58 utilx_set_system_notification_level(ecore_x_display_get(), w,
59 UTILX_NOTIFICATION_LEVEL_HIGH);
63 static void _show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
64 void *event_info __UNUSED__)
66 struct Internal_Data *wd = evas_object_data_get(obj, data_key);
71 evas_object_show(wd->content);
74 static void _content_hide(void *data, Evas *e __UNUSED__,
75 Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
77 evas_object_hide(data);
80 static void _content_changed_size_hints(void *data, Evas *e __UNUSED__,
81 Evas_Object *obj, void *event_info __UNUSED__)
84 struct Internal_Data *wd = evas_object_data_get(data, data_key);
89 evas_object_size_hint_min_get(obj, NULL, &h);
92 evas_object_size_hint_min_set(obj, wd->w, wd->h);
93 evas_object_size_hint_min_set(data, wd->w, wd->h);
94 evas_object_resize(data, wd->w, wd->h);
98 static void _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
100 struct Internal_Data *wd = evas_object_data_get(obj, data_key);
101 Evas_Object *sub = event_info;
105 if (sub == wd->content) {
106 evas_object_event_callback_del(wd->content, EVAS_CALLBACK_HIDE,
108 evas_object_event_callback_del(wd->content,
109 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
110 _content_changed_size_hints);
115 static void _del(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
116 void *event_info __UNUSED__)
118 struct Internal_Data *wd = evas_object_data_get(obj, data_key);
122 if (wd->rotation_event_handler)
123 ecore_event_handler_del(wd->rotation_event_handler);
124 evas_object_data_set(data, data_key, NULL);
129 static void _update_geometry_on_rotation(Evas_Object *obj, int angle,
130 int *x, int *y, int *w)
132 Evas_Coord root_w, root_h;
133 struct Internal_Data *wd = evas_object_data_get(obj, data_key);
138 ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w,
145 if (wd->orient == NOTI_ORIENT_BOTTOM)
150 if (!(wd->orient == NOTI_ORIENT_BOTTOM))
155 if (!wd->orient == NOTI_ORIENT_BOTTOM)
161 if (wd->orient == NOTI_ORIENT_BOTTOM)
167 static void _win_rotated(Evas_Object *obj)
173 struct Internal_Data *wd = evas_object_data_get(obj, data_key);
177 angle = elm_win_rotation_get(obj);
185 _update_geometry_on_rotation(obj, wd->angle, &x, &y, &w);
187 evas_object_move(obj, x, y);
189 evas_object_resize(obj, wd->w, wd->h);
192 static Eina_Bool _prop_change(void *data, int type __UNUSED__, void *event)
194 Ecore_X_Event_Window_Property *ev;
195 struct Internal_Data *wd = evas_object_data_get(data, data_key);
198 return ECORE_CALLBACK_PASS_ON;
200 if (ev->atom == ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE)
201 if (ev->win == elm_win_xwindow_get(data))
203 return ECORE_CALLBACK_PASS_ON;
207 HAPI Evas_Object *noti_win_add(Evas_Object *parent)
211 struct Internal_Data *wd;
214 win = elm_win_add(parent, "noti_win", ELM_WIN_NOTIFICATION);
215 elm_win_alpha_set(win, EINA_TRUE);
219 elm_win_title_set(win, "noti_win");
220 elm_win_borderless_set(win, EINA_TRUE);
221 elm_win_autodel_set(win, EINA_TRUE);
222 evas_object_size_hint_weight_set(win, EVAS_HINT_EXPAND,
224 evas_object_size_hint_align_set(win, EVAS_HINT_FILL, EVAS_HINT_FILL);
225 bg = elm_bg_add(win);
226 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND,
228 elm_win_resize_object_add(win, bg);
230 _set_win_type_notification_level(win);
232 wd = (struct Internal_Data *) calloc(1, sizeof(struct Internal_Data));
235 evas_object_data_set(win, data_key, wd);
237 wd->orient = NOTI_ORIENT_TOP;
238 evas_object_move(win, 0, 0);
240 ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, NULL);
241 evas_object_resize(win, w, NOTI_HEIGHT);
242 wd->rotation_event_handler = ecore_event_handler_add(
243 ECORE_X_EVENT_WINDOW_PROPERTY, _prop_change, win);
247 evas_object_smart_callback_add(win, "sub-object-del", _sub_del, NULL);
248 evas_object_event_callback_add(win, EVAS_CALLBACK_SHOW, _show, NULL);
249 evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _del, NULL);
253 HAPI void noti_win_content_set(Evas_Object *obj, Evas_Object *content)
256 struct Internal_Data *wd;
260 wd = evas_object_data_get(obj, data_key);
264 evas_object_del(content);
265 wd->content = content;
267 evas_object_size_hint_weight_set(wd->content, EVAS_HINT_EXPAND,
269 elm_win_resize_object_add(obj, wd->content);
270 evas_object_size_hint_min_get(wd->content, NULL, &h);
273 evas_object_size_hint_min_set(wd->content, wd->w, wd->h);
274 evas_object_resize(obj, wd->w, wd->h);
275 evas_object_event_callback_add(wd->content, EVAS_CALLBACK_HIDE,
277 evas_object_event_callback_add(wd->content,
278 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
279 _content_changed_size_hints, obj);
283 HAPI void noti_win_orient_set(Evas_Object *obj, enum Noti_Orient orient)
286 Evas_Coord root_w, root_h;
288 struct Internal_Data *wd = evas_object_data_get(obj, data_key);
292 if (orient >= NOTI_ORIENT_LAST)
295 ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w,
299 case NOTI_ORIENT_BOTTOM:
301 evas_object_move(obj, 0, root_h - wd->h);
303 wd->orient = NOTI_ORIENT_BOTTOM;
305 case NOTI_ORIENT_TOP:
308 evas_object_move(obj, 0, 0);
310 wd->orient = NOTI_ORIENT_TOP;