change wl_signal_emit_mutable into wl_signal_emit
[platform/core/uifw/libds-tizen.git] / src / screenshooter / screenshooter.c
1 #include <tizen-extension-server-protocol.h>
2 #include "screenshooter.h"
3 #include "util.h"
4
5 #define TIZEN_SCREENSHOOTER_VERSION 3
6
7 static void screenshooter_handle_display_destroy(struct wl_listener *listener,
8         void *data);
9
10 static void screenshooter_bind(struct wl_client *wl_client, void *data,
11         uint32_t version, uint32_t id);
12
13 WL_EXPORT struct ds_tizen_screenshooter *
14 ds_tizen_screenshooter_create(struct wl_display *display)
15 {
16     struct ds_tizen_screenshooter *shot;
17
18     shot = calloc(1, sizeof *shot);
19     if (!shot) {
20         ds_err("screenshooter create fail : memory alloc failed");
21         return NULL;
22     }
23
24     shot->global = wl_global_create(display, &tizen_screenshooter_interface,
25                                     TIZEN_SCREENSHOOTER_VERSION, NULL, screenshooter_bind);
26
27     wl_list_init(&shot->clients);
28     wl_signal_init(&shot->events.destroy);
29     wl_signal_init(&shot->events.shoot);
30
31     shot->destroy.notify = screenshooter_handle_display_destroy;
32     wl_display_add_destroy_listener(display, &shot->destroy);
33
34     ds_inf("create : tizen_screenshooter(%p)", shot);
35
36     return shot;
37 }
38
39 WL_EXPORT void
40 ds_tizen_screenshooter_add_destroy_listener(struct ds_tizen_screenshooter *shot,
41         struct wl_listener *listener)
42 {
43     wl_signal_add(&shot->events.destroy, listener);
44 }
45
46 WL_EXPORT void
47 ds_tizen_screenshooter_add_get_screenmirror_listener(struct ds_tizen_screenshooter *shot,
48         struct wl_listener *listener)
49 {
50     wl_signal_add(&shot->events.get_screenmirror, listener);
51 }
52
53 WL_EXPORT void
54 ds_tizen_screenshooter_add_shoot_listener(struct ds_tizen_screenshooter *shot,
55         struct wl_listener *listener)
56 {
57     wl_signal_add(&shot->events.shoot, listener);
58 }
59
60 WL_EXPORT void
61 ds_tizen_screenshooter_send_shoot_done(struct ds_tizen_screenshooter *shot,
62         struct ds_tizen_screenshooter_client *client)
63 {
64     struct ds_tizen_screenshooter_client *temp;
65
66     wl_list_for_each(temp, &shot->clients, link) {
67         if (temp == client) {
68             ds_dbg("screenshooter send shoot done");
69             tizen_screenshooter_send_done(client->res);
70         }
71     }
72 }
73
74 static void
75 screenshooter_handle_display_destroy(struct wl_listener *listener, void *data)
76 {
77     struct ds_tizen_screenshooter *shot;
78
79     shot = wl_container_of(listener, shot, destroy);
80
81     ds_inf("global destroy : tizen_screenshooter(%p)", shot);
82
83     wl_signal_emit(&shot->events.destroy, shot);
84     wl_list_remove(&shot->destroy.link);
85     wl_global_destroy(shot->global);
86     free(shot);
87 }
88
89 static void
90 _tizen_screenshooter_handle_get_screenmirror(struct wl_client *client,
91         struct wl_resource *resource, uint32_t id, struct wl_resource *output)
92 {
93     struct ds_tizen_screenshooter *shot;
94     struct ds_tizen_screenshooter_client *shot_client;
95     int version = wl_resource_get_version(resource);
96
97     shot_client = wl_resource_get_user_data(resource);
98     shot = shot_client->shot;
99
100     if (shot_client->mirror) {
101         ds_err("screenshooter get_screenmirror error : already created");
102         return;
103     }
104
105     shot_client->mirror = ds_tizen_screenmirror_create(shot_client, version, id);
106     if (shot_client->mirror == NULL)
107         wl_client_post_no_memory(client);
108     else
109         wl_signal_emit(&shot->events.get_screenmirror, shot_client->mirror);
110 }
111
112 static void
113 _tizen_screenshooter_handle_set_oneshot_auto_rotation(struct wl_client *client,
114         struct wl_resource *resource, uint32_t set)
115 {
116     struct ds_tizen_screenshooter *shot;
117     struct ds_tizen_screenshooter_client *shot_client;
118
119     shot_client = wl_resource_get_user_data(resource);
120     shot = shot_client->shot;
121     if (set)
122         shot->auto_rotation = true;
123     else
124         shot->auto_rotation = false;
125 }
126
127 static void
128 _tizen_screenshooter_handle_destroy(struct wl_client *client,
129         struct wl_resource *resource)
130 {
131     ds_inf("_tizen_screenshooter_handle_destroy (res:%p)", resource);
132     wl_resource_destroy(resource);
133 }
134
135 static void
136 _tizen_screenshooter_handle_shoot(struct wl_client *client,
137         struct wl_resource *resource, struct wl_resource *wl_output,
138         struct wl_resource *wl_buffer)
139 {
140     struct ds_tizen_screenshooter *shot;
141     struct ds_tizen_screenshooter_client *shot_client;
142     struct ds_output *output = NULL;
143     struct ds_buffer *buffer = NULL;
144
145     shot_client = wl_resource_get_user_data(resource);
146     shot = shot_client->shot;
147     output = wl_resource_get_user_data(wl_output);
148     buffer = ds_buffer_from_resource(wl_buffer);
149     if (!buffer) {
150         ds_err("ds_buffer_from_resource fail");
151         return;
152     }
153
154     struct ds_tizen_screenshooter_event_shoot event = {
155         .output = output,
156         .buffer = buffer,
157         .client = shot_client,
158         .auto_rotation = shot->auto_rotation,
159     };
160
161     wl_signal_emit(&shot->events.shoot, &event);
162 }
163
164 static const struct tizen_screenshooter_interface _tizen_screenshooter_interface =
165 {
166    _tizen_screenshooter_handle_get_screenmirror,
167    _tizen_screenshooter_handle_set_oneshot_auto_rotation,
168    _tizen_screenshooter_handle_destroy,
169    _tizen_screenshooter_handle_shoot,
170 };
171
172 static void
173 _screenshooter_client_cb_destroy(struct wl_resource *resource)
174 {
175     struct ds_tizen_screenshooter_client *shot_client;
176
177     ds_inf("_screenshooter_client_cb_destroy (res:%p)", resource);
178
179     shot_client = wl_resource_get_user_data(resource);
180     if (shot_client) {
181         wl_list_remove(&shot_client->link);
182         free(shot_client);
183     }
184 }
185
186 static void
187 screenshooter_bind(struct wl_client *client, void *data, uint32_t version,
188         uint32_t id)
189 {
190     struct ds_tizen_screenshooter *shot = data;
191     struct ds_tizen_screenshooter_client *shot_client;
192
193     shot_client = calloc(1, sizeof *shot_client);
194     if (shot_client == NULL) {
195         wl_client_post_no_memory(client);
196         return;
197     }
198
199     shot_client->shot = shot;
200     shot_client->client = client;
201
202     shot_client->res = wl_resource_create(client, &tizen_screenshooter_interface,
203             MIN(version, TIZEN_SCREENSHOOTER_VERSION), id);
204     if (shot_client->res == NULL) {
205         ds_err("screenshooter bind error : wl_resource_create failed.");
206         wl_client_post_no_memory(client);
207         free(shot_client);
208         return;
209     }
210
211     wl_resource_set_implementation(shot_client->res, &_tizen_screenshooter_interface,
212             shot_client, _screenshooter_client_cb_destroy);
213
214     wl_list_insert(&shot->clients, &shot_client->link);
215 }