modules/information/ext_storage: fix sigsegv
[apps/core/preloaded/indicator-win.git] / src / noti_win.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 <Ecore_X.h>
20 //#include <utilX.h>
21 #include <runtime_info.h>
22 #include <system_settings.h>
23 #include <efl_util.h>
24
25 #include "log.h"
26 #include "indicator.h"
27 #include "common.h"
28 #include "main.h"
29 #include "noti_win.h"
30
31 /* Using this macro to emphasize that some portion like stacking and
32 rotation handling are implemented for X based platform */
33 #ifndef __UNUSED__
34 #define __UNUSED__ __attribute__((unused))
35 #endif
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 };
44
45 #define PRIVATE_DATA_KEY_DATA "pdk_data"
46
47 static void _content_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
48 {
49         Evas_Coord h;
50         struct Internal_Data *wd = evas_object_data_get(data, PRIVATE_DATA_KEY_DATA);
51
52         ret_if(!wd);
53
54         evas_object_size_hint_min_get(obj, NULL, &h);
55         if ((h > 0)) {
56                 wd->h = h;
57                 evas_object_size_hint_min_set(obj, wd->w, wd->h);
58                 evas_object_size_hint_min_set(data, wd->w, wd->h);
59         }
60 }
61
62 static void _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
63 {
64         struct Internal_Data *wd = evas_object_data_get(obj, PRIVATE_DATA_KEY_DATA);
65         Evas_Object *sub = event_info;
66
67         ret_if(!wd);
68
69         if (sub == wd->content) {
70                 evas_object_event_callback_del(wd->content, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _content_changed_size_hints);
71                 wd->content = NULL;
72         }
73 }
74
75 static void _noti_win_destroy(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
76 {
77         Evas_Object *win = NULL;
78         struct Internal_Data *wd = NULL;
79
80         ret_if(!obj);
81
82         win = obj;
83
84         wd = evas_object_data_del(win, PRIVATE_DATA_KEY_DATA);
85         ret_if(!wd);
86
87         if (wd->rotation_event_handler) {
88                 ecore_event_handler_del(wd->rotation_event_handler);
89         }
90         free(wd);
91 #if 0
92         quickpanel_dbus_ticker_visibility_send(0);
93 #endif
94 }
95
96 static void _rotate_cb(void *data, Evas_Object *obj, void *event)
97 {
98         struct appdata *ad = data;
99         struct Internal_Data *wd = NULL;
100         Evas_Object *base = NULL;
101         int angle = 0;
102
103         ret_if(!obj);
104
105         wd =  evas_object_data_get(obj, PRIVATE_DATA_KEY_DATA);
106         ret_if(!wd);
107
108         base = evas_object_data_get(obj, DATA_KEY_BASE_RECT);
109         ret_if(!base);
110
111         angle = elm_win_rotation_get(obj);
112         angle %= 360;
113         if (angle < 0) {
114                 angle += 360;
115         }
116         _D("Ticker angle is %d degree", angle);
117
118         switch (angle) {
119         case 0:
120         case 180:
121                 evas_object_resize(base, ad->win.port_w, wd->h);
122                 evas_object_size_hint_min_set(base, ad->win.port_w, wd->h);
123                 evas_object_resize(obj, ad->win.port_w, wd->h);
124                 evas_object_move(obj, 0, 0);
125                 break;
126         case 90:
127                 evas_object_resize(base, ad->win.land_w, wd->h);
128                 evas_object_size_hint_min_set(base, ad->win.land_w, wd->h);
129                 evas_object_resize(obj, ad->win.land_w, wd->h);
130                 evas_object_move(obj, 0, 0);
131                 break;
132         case 270:
133                 evas_object_resize(base, ad->win.land_w, wd->h);
134                 evas_object_size_hint_min_set(base, ad->win.land_w, wd->h);
135                 evas_object_resize(obj, ad->win.land_w, wd->h);
136                 evas_object_move(obj, ad->win.port_w - wd->h, 0);
137                 break;
138         default:
139                 _E("cannot reach here");
140         }
141
142         wd->angle = angle;
143 }
144
145 Evas_Object *noti_win_add(Evas_Object *parent, struct appdata *ad)
146 {
147         Evas_Object *win = NULL;
148         struct Internal_Data *wd = NULL;
149
150         _D("A window is created for ticker notifications");
151         win = elm_win_add (NULL, "noti_win", ELM_WIN_NOTIFICATION);
152         retv_if(!win, NULL);
153
154         elm_win_alpha_set(win, EINA_FALSE);
155         elm_win_title_set(win, "noti_win");
156         elm_win_borderless_set(win, EINA_TRUE);
157         elm_win_autodel_set(win, EINA_TRUE);
158         //efl_util_set_notification_window_level(win, EFL_UTIL_NOTIFICATION_LEVEL_HIGH);
159         elm_win_prop_focus_skip_set(win, EINA_TRUE);
160         /* you can use evas_object_resize() and evas_object_move() by using elm_win_aux_hint_add().
161            elm_win_aux_hint_add() makes it possible to set the size and location of the notification window freely.
162            if you do not use elm_win_aux_hint_add(), notification window is displayed full screen. */
163 //      elm_win_aux_hint_add(win, "wm.policy.win.user.geometry", "1");
164         evas_object_resize(win, ad->win.w, ad->win.h);
165         evas_object_move(win, 0, 0);
166         evas_object_show(win);
167
168         if (elm_win_wm_rotation_supported_get(win)) {
169                 int rots[4] = { 0, 90, 180, 270 };
170                 elm_win_wm_rotation_available_rotations_set(win, rots, 4);
171         }
172         evas_object_smart_callback_add(win, "wm,rotation,changed", _rotate_cb, ad);
173
174         wd = (struct Internal_Data *) calloc(1, sizeof(struct Internal_Data));
175         if (!wd) {
176                 if (win) evas_object_del(win);
177                 return NULL;
178         }
179         evas_object_data_set(win, PRIVATE_DATA_KEY_DATA, wd);
180
181         wd->angle = 0;
182         wd->w = ad->win.w;
183         wd->h = ad->win.h;
184
185         evas_object_smart_callback_add(win, "sub-object-del", _sub_del, NULL);
186         evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _noti_win_destroy, NULL);
187
188         return win;
189 }
190
191 void noti_win_content_set(Evas_Object *obj, Evas_Object *content)
192 {
193         struct Internal_Data *wd;
194
195         ret_if (!obj);
196
197         wd = evas_object_data_get(obj, PRIVATE_DATA_KEY_DATA);
198         ret_if (!wd);
199
200         if (wd->content && content != NULL) {
201                 evas_object_del(content);
202                 content = NULL;
203         }
204
205         wd->content = content;
206         if (content) {
207                 evas_object_show(wd->content);
208                 evas_object_event_callback_add(wd->content, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _content_changed_size_hints, obj);
209         }
210 }
211 /*End of file */