e_screensaver: fix issue screensaver is not terminated
[platform/upstream/enlightenment.git] / src / bin / e_screensaver.c
1 #include "e.h"
2
3 typedef struct _E_Screensaver
4 {
5    Eina_List          *handlers;
6    Ecore_Idle_Enterer *idle_before;
7
8    double              idletime;
9    Ecore_Timer        *idletimer;
10
11    Eina_Bool           ev_update;
12    Eina_Bool           active; /* indicates that screensaver window is showing */
13    Eina_Bool           enable; /* indicates that screensaver feature is enabled */
14 } E_Screensaver;
15
16 static E_Screensaver *_saver = NULL;
17
18 E_API int E_EVENT_SCREENSAVER_ON = -1;
19 E_API int E_EVENT_SCREENSAVER_OFF = -1;
20 E_API int E_EVENT_SCREENSAVER_OFF_PRE = -1;
21
22 static Eina_Bool _e_scrsaver_cb_idletimeout(void *data EINA_UNUSED);
23 static void      _e_scrsaver_idletimeout_reset(void);
24 static Eina_Bool _e_scrsaver_cb_idle_before(void *data EINA_UNUSED);
25 static Eina_Bool _e_scrsaver_cb_input(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED);
26 static void      _e_scrsaver_active_set(Eina_Bool set);
27
28 static Eina_Bool
29 _e_scrsaver_cb_idletimeout(void *data EINA_UNUSED)
30 {
31    _e_scrsaver_active_set(EINA_TRUE);
32    _saver->idletimer = NULL;
33    return EINA_FALSE;
34 }
35
36 static void
37 _e_scrsaver_idletimeout_reset(void)
38 {
39    if (_saver->idletimer)
40      {
41         ecore_timer_del(_saver->idletimer);
42         _saver->idletimer = NULL;
43      }
44
45    if (!_saver->enable) return;
46
47    if (_saver->idletime != 0.0)
48      {
49         _saver->idletimer =
50            ecore_timer_add(_saver->idletime,
51                            _e_scrsaver_cb_idletimeout,
52                            NULL);
53      }
54 }
55
56 static Eina_Bool
57 _e_scrsaver_cb_idle_before(void *data EINA_UNUSED)
58 {
59    if (!_saver) return ECORE_CALLBACK_RENEW;
60    if (!_saver->ev_update) return ECORE_CALLBACK_RENEW;
61
62    _e_scrsaver_idletimeout_reset();
63    _e_scrsaver_active_set(EINA_FALSE);
64    _saver->ev_update = EINA_FALSE;
65
66    return ECORE_CALLBACK_RENEW;
67 }
68
69 static Eina_Bool
70 _e_scrsaver_cb_input(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
71 {
72    if (!_saver) return ECORE_CALLBACK_PASS_ON;
73    _saver->ev_update = EINA_TRUE;
74    return ECORE_CALLBACK_PASS_ON;
75 }
76
77 static void
78 _e_scrsaver_active_set(Eina_Bool set)
79 {
80    int ev = -1;
81    if (set == _saver->active) return;
82
83    if (set)
84      ev = E_EVENT_SCREENSAVER_ON;
85    else
86      ev = E_EVENT_SCREENSAVER_OFF;
87
88    ecore_event_add(ev, NULL, NULL, NULL);
89
90    _saver->active = set;
91 }
92
93 EINTERN void
94 e_screensaver_preinit(void)
95 {
96    E_EVENT_SCREENSAVER_ON = ecore_event_type_new();
97    E_EVENT_SCREENSAVER_OFF = ecore_event_type_new();
98    E_EVENT_SCREENSAVER_OFF_PRE = ecore_event_type_new();
99 }
100
101 EINTERN int
102 e_screensaver_init(void)
103 {
104    if (!_saver)
105      {
106         _saver = E_NEW(E_Screensaver, 1);
107         if (!_saver) return 0;
108
109         _saver->idletime = 0.0;
110      }
111    return 1;
112 }
113
114 EINTERN int
115 e_screensaver_shutdown(void)
116 {
117    e_screensaver_disable();
118    E_FREE(_saver);
119    return 1;
120 }
121
122 E_API void
123 e_screensaver_timeout_set(double time)
124 {
125    if (!_saver) return;
126
127    _saver->idletime = time;
128    _e_scrsaver_idletimeout_reset();
129 }
130
131 E_API double
132 e_screensaver_timeout_get(void)
133 {
134    if (!_saver) return 0.0;
135    return _saver->idletime;
136 }
137
138 static void
139 _e_scrsaver_cb_input_async(void *data)
140 {
141    _e_scrsaver_cb_input(NULL, 0, NULL);
142 }
143
144 E_API void
145 e_screensaver_notidle(void)
146 {
147    ecore_main_loop_thread_safe_call_async(_e_scrsaver_cb_input_async, NULL);
148 }
149
150 E_API void
151 e_screensaver_enable(void)
152 {
153    if (!_saver) return;
154    if (_saver->enable) return;
155
156    _saver->enable = EINA_TRUE;
157    _saver->idle_before = ecore_idle_enterer_before_add(_e_scrsaver_cb_idle_before, NULL);
158
159    E_LIST_HANDLER_APPEND(_saver->handlers, ECORE_EVENT_MOUSE_MOVE,        _e_scrsaver_cb_input, NULL);
160    E_LIST_HANDLER_APPEND(_saver->handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_scrsaver_cb_input, NULL);
161    E_LIST_HANDLER_APPEND(_saver->handlers, ECORE_EVENT_MOUSE_BUTTON_UP,   _e_scrsaver_cb_input, NULL);
162    E_LIST_HANDLER_APPEND(_saver->handlers, ECORE_EVENT_MOUSE_WHEEL,       _e_scrsaver_cb_input, NULL);
163
164    _e_scrsaver_idletimeout_reset();
165 }
166
167 E_API void
168 e_screensaver_disable(void)
169 {
170    if (!_saver) return;
171    if (!_saver->enable) return;
172
173    _saver->enable = EINA_FALSE;
174    _e_scrsaver_active_set(EINA_FALSE);
175
176    E_FREE_LIST(_saver->handlers, ecore_event_handler_del);
177    _saver->handlers = NULL;
178
179    if (_saver->idletimer)
180      {
181         ecore_timer_del(_saver->idletimer);
182         _saver->idletimer = NULL;
183      }
184
185    if (_saver->idle_before)
186      {
187         ecore_idle_enterer_del(_saver->idle_before);
188         _saver->idle_before = NULL;
189      }
190 }
191
192 E_API Eina_Bool
193 e_screensaver_enabled_get(void)
194 {
195    if (!_saver) return EINA_FALSE;
196
197    return _saver->enable;
198 }