implement ds_tizen_remote_surface
[platform/core/uifw/libds-tizen.git] / src / dpms / dpms.c
1 #include <assert.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <wayland-server.h>
5 #include <libds/log.h>
6 #include <tizen-dpms-server-protocol.h>
7 #include "libds-tizen/dpms.h"
8 #include "util.h"
9
10 struct ds_tizen_dpms
11 {
12     struct wl_global *global;
13     struct wl_resource *res;
14
15     struct wl_listener destroy;
16
17     struct {
18         struct wl_signal destroy;
19         struct wl_signal set_dpms;
20         struct wl_signal get_dpms;
21     } events;
22
23     bool binded;
24 };
25
26 #define TIZEN_DPMS_VERSION 1
27
28 static void dpms_handle_display_destroy(struct wl_listener *listener,
29         void *data);
30 static void dpms_bind(struct wl_client *wl_client, void *data,
31         uint32_t version, uint32_t id);
32
33 static enum ds_tizen_dpms_mode
34 _ds_tizen_dpms_get_ds_dpms_mode(uint32_t mode)
35 {
36     if (mode == TIZEN_DPMS_MANAGER_MODE_ON)
37         return DS_TIZEN_DPMS_MODE_ON;
38     else if (mode == TIZEN_DPMS_MANAGER_MODE_STANDBY)
39         return DS_TIZEN_DPMS_MODE_STANDBY;
40     else if (mode == TIZEN_DPMS_MANAGER_MODE_SUSPEND)
41         return DS_TIZEN_DPMS_MODE_SUSPEND;
42     else //TIZEN_DPMS_MANAGER_MODE_OFF
43         return DS_TIZEN_DPMS_MODE_OFF;
44 }
45
46 static uint32_t
47 _ds_tizen_dpms_get_tizen_dpms_mode(enum ds_tizen_dpms_mode mode)
48 {
49     if (mode == DS_TIZEN_DPMS_MODE_ON)
50         return TIZEN_DPMS_MANAGER_MODE_ON;
51     else if (mode == DS_TIZEN_DPMS_MODE_STANDBY)
52         return TIZEN_DPMS_MANAGER_MODE_STANDBY;
53     else if (mode == DS_TIZEN_DPMS_MODE_SUSPEND)
54         return TIZEN_DPMS_MANAGER_MODE_SUSPEND;
55     else //DS_TIZEN_DPMS_MODE_OFF
56         return TIZEN_DPMS_MANAGER_MODE_OFF;
57 }
58
59 static uint32_t
60 _ds_tizen_dpms_get_tizen_dpms_error(enum ds_tizen_dpms_error error)
61 {
62     if (error == DS_TIZEN_DPMS_ERROR_NONE)
63         return TIZEN_DPMS_MANAGER_ERROR_NONE;
64     else if (error == DS_TIZEN_DPMS_ERROR_INVALID_PERMISSION)
65         return TIZEN_DPMS_MANAGER_ERROR_INVALID_PERMISSION;
66     else if (error == DS_TIZEN_DPMS_ERROR_INVALID_PARAMETER)
67         return TIZEN_DPMS_MANAGER_ERROR_INVALID_PARAMETER;
68     else if (error == DS_TIZEN_DPMS_ERROR_NOT_SUPPORTED)
69         return TIZEN_DPMS_MANAGER_ERROR_NOT_SUPPORTED;
70     else //DS_TIZEN_DPMS_ERROR_ALREADY_DONE
71         return TIZEN_DPMS_MANAGER_ERROR_ALREADY_DONE;
72 }
73
74 WL_EXPORT struct ds_tizen_dpms *
75 ds_tizen_dpms_create(struct wl_display *display)
76 {
77     struct ds_tizen_dpms *dpms;
78
79     dpms = calloc(1, sizeof *dpms);
80     if (!dpms) {
81         ds_err("dpms create fail : memory alloc failed");
82         return NULL;
83     }
84
85     dpms->global = wl_global_create(display, &tizen_dpms_manager_interface,
86             1, dpms, dpms_bind);
87     if (!dpms->global) {
88         ds_err("global create fail : tizen_dpms_manager_interface failed");
89         free(dpms);
90         return NULL;
91     }
92
93     wl_signal_init(&dpms->events.destroy);
94     wl_signal_init(&dpms->events.set_dpms);
95     wl_signal_init(&dpms->events.get_dpms);
96
97     dpms->destroy.notify = dpms_handle_display_destroy;
98     wl_display_add_destroy_listener(display, &dpms->destroy);
99
100     ds_inf("global create : tizen_dpms_manager(%p)", dpms);
101
102     return dpms;
103 }
104
105 WL_EXPORT void
106 ds_tizen_dpms_add_destroy_listener(struct ds_tizen_dpms *dpms,
107         struct wl_listener *listener)
108 {
109     wl_signal_add(&dpms->events.destroy, listener);
110 }
111
112 WL_EXPORT void
113 ds_tizen_dpms_add_set_dpms_listener(struct ds_tizen_dpms *dpms,
114         struct wl_listener *listener)
115 {
116     wl_signal_add(&dpms->events.set_dpms, listener);
117 }
118
119 WL_EXPORT void
120 ds_tizen_dpms_add_get_dpms_listener(struct ds_tizen_dpms *dpms,
121         struct wl_listener *listener)
122 {
123     wl_signal_add(&dpms->events.get_dpms, listener);
124 }
125
126 WL_EXPORT void
127 ds_tizen_dpms_send_set_result(struct ds_tizen_dpms *dpms,
128         enum ds_tizen_dpms_mode mode, enum ds_tizen_dpms_error error)
129 {
130     uint32_t tizen_dpms_mode;
131     uint32_t tizen_dpms_error;
132
133     if (mode > DS_TIZEN_DPMS_MODE_OFF || error > DS_TIZEN_DPMS_ERROR_ALREADY_DONE) {
134         ds_err("dpms send set result error invalid parameter");
135         return;
136     }
137     tizen_dpms_mode = _ds_tizen_dpms_get_tizen_dpms_mode(mode);
138     tizen_dpms_error = _ds_tizen_dpms_get_tizen_dpms_error(error);
139     ds_dbg("dpms send set result : mode(%d), error(%d)", tizen_dpms_mode, tizen_dpms_error);
140     tizen_dpms_manager_send_set_state(dpms->res, tizen_dpms_mode, tizen_dpms_error);
141 }
142
143 WL_EXPORT void
144 ds_tizen_dpms_send_get_result(struct ds_tizen_dpms *dpms,
145         enum ds_tizen_dpms_mode mode, enum ds_tizen_dpms_error error)
146 {
147     uint32_t tizen_dpms_mode;
148     uint32_t tizen_dpms_error;
149
150     if (mode > DS_TIZEN_DPMS_MODE_OFF || error > DS_TIZEN_DPMS_ERROR_ALREADY_DONE) {
151         ds_err("dpms send get result error invalid parameter");
152         return;
153     }
154     tizen_dpms_mode = _ds_tizen_dpms_get_tizen_dpms_mode(mode);
155     tizen_dpms_error = _ds_tizen_dpms_get_tizen_dpms_error(error);
156     ds_dbg("dpms send get result : mode(%d), error(%d)", tizen_dpms_mode, tizen_dpms_error);
157     tizen_dpms_manager_send_get_state(dpms->res, tizen_dpms_mode, tizen_dpms_error);
158 }
159
160 static void
161 dpms_handle_display_destroy(struct wl_listener *listener, void *data)
162 {
163     struct ds_tizen_dpms *dpms;
164
165     dpms = wl_container_of(listener, dpms, destroy);
166
167     ds_inf("global destroy : tizen_dpms_manager(%p)", dpms);
168
169     wl_signal_emit(&dpms->events.destroy, dpms);
170     wl_list_remove(&dpms->destroy.link);
171     if (dpms->res)
172         wl_resource_set_user_data(dpms->res, NULL);
173     wl_global_destroy(dpms->global);
174     free(dpms);
175 }
176
177 static void
178 _tizen_dpms_manager_handle_destroy(struct wl_client *client,
179         struct wl_resource *resource)
180 {
181     ds_inf("tizen_dpms_manager cb_destroy (res:%p)", resource);
182     wl_resource_destroy(resource);
183 }
184
185 static void
186 _tizen_dpms_manager_handle_set_dpms(struct wl_client *client,
187         struct wl_resource *resource, struct wl_resource *wl_output, uint32_t mode)
188 {
189     struct ds_tizen_dpms *dpms;
190     struct ds_output *output;
191     enum ds_tizen_dpms_mode ds_mode;
192
193     dpms = wl_resource_get_user_data(resource);
194
195     if (mode > TIZEN_DPMS_MANAGER_MODE_OFF) {
196         ds_err("set dpms error : not supported mode(%d)", mode);
197         tizen_dpms_manager_send_set_state(resource, TIZEN_DPMS_MANAGER_MODE_OFF,
198                 TIZEN_DPMS_MANAGER_ERROR_INVALID_PARAMETER);
199         return;
200     }
201
202     output = wl_resource_get_user_data(wl_output);
203     ds_mode = _ds_tizen_dpms_get_ds_dpms_mode(mode);
204     struct ds_tizen_dpms_event event = {
205         .output = output,
206         .mode = ds_mode,
207     };
208
209     wl_signal_emit(&dpms->events.set_dpms, &event);
210 }
211
212 static void
213 _tizen_dpms_manager_handle_get_dpms(struct wl_client *client,
214         struct wl_resource *resource, struct wl_resource *wl_output)
215 {
216     struct ds_tizen_dpms *dpms;
217     struct ds_output *output;
218
219     dpms = wl_resource_get_user_data(resource);
220     output = wl_resource_get_user_data(wl_output);
221
222     wl_signal_emit(&dpms->events.get_dpms, output);
223 }
224
225 static const struct tizen_dpms_manager_interface dpms_impl =
226 {
227     _tizen_dpms_manager_handle_destroy,
228     _tizen_dpms_manager_handle_set_dpms,
229     _tizen_dpms_manager_handle_get_dpms,
230 };
231
232 static void
233 _tizen_dpms_client_cb_destroy(struct wl_resource *resource)
234 {
235     struct ds_tizen_dpms *dpms;
236
237     ds_inf("tizen_dpms_client_cb_destroy (res:%p)", resource);
238
239     dpms = wl_resource_get_user_data(resource);
240     if (dpms) {
241         dpms->binded = false;
242         dpms->res = NULL;
243     }
244 }
245
246 static void
247 dpms_bind(struct wl_client *client, void *data, uint32_t version,
248         uint32_t id)
249 {
250     struct ds_tizen_dpms *dpms = data;
251
252     if (dpms->binded == true) {
253         //support only one client.
254         ds_err("dpms bind error : already binded.");
255         return;
256     }
257
258     dpms->res = wl_resource_create(client, &tizen_dpms_manager_interface,
259             MIN(version, TIZEN_DPMS_VERSION), id);
260     if (dpms->res == NULL) {
261         ds_err("dpms bind error : wl_resource_create failed.");
262         wl_client_post_no_memory(client);
263         return;
264     }
265
266     wl_resource_set_implementation(dpms->res, &dpms_impl, dpms,
267             _tizen_dpms_client_cb_destroy);
268
269     dpms->binded = true;
270 }