hwc: Modify ds_tizen_hwc destruction logic
[platform/core/uifw/libds-tizen.git] / src / screenshooter / screenmirror.c
1 #include <tizen-extension-server-protocol.h>
2 #include "screenshooter.h"
3 #include "util.h"
4
5 static const struct tizen_screenmirror_interface _screenmirror_interface;
6
7 WL_EXPORT void
8 ds_tizen_screenmirror_add_destroy_listener(struct ds_tizen_screenmirror *mirror,
9         struct wl_listener *listener)
10 {
11     wl_signal_add(&mirror->events.destroy, listener);
12 }
13
14 WL_EXPORT void
15 ds_tizen_screenmirror_add_set_stretch_listener(struct ds_tizen_screenmirror *mirror,
16         struct wl_listener *listener)
17 {
18     wl_signal_add(&mirror->events.set_stretch, listener);
19 }
20
21 WL_EXPORT void
22 ds_tizen_screenmirror_add_queue_listener(struct ds_tizen_screenmirror *mirror,
23         struct wl_listener *listener)
24 {
25     wl_signal_add(&mirror->events.queue, listener);
26 }
27
28 WL_EXPORT void
29 ds_tizen_screenmirror_add_dequeue_listener(struct ds_tizen_screenmirror *mirror,
30         struct wl_listener *listener)
31 {
32     wl_signal_add(&mirror->events.dequeue, listener);
33 }
34
35 WL_EXPORT void
36 ds_tizen_screenmirror_add_start_listener(struct ds_tizen_screenmirror *mirror,
37         struct wl_listener *listener)
38 {
39     wl_signal_add(&mirror->events.start, listener);
40 }
41
42 WL_EXPORT void
43 ds_tizen_screenmirror_add_stop_listener(struct ds_tizen_screenmirror *mirror,
44         struct wl_listener *listener)
45 {
46     wl_signal_add(&mirror->events.stop, listener);
47 }
48
49 WL_EXPORT void
50 ds_tizen_screenmirror_add_auto_rotation_listener(struct ds_tizen_screenmirror *mirror,
51         struct wl_listener *listener)
52 {
53     wl_signal_add(&mirror->events.set_auto_rotation, listener);
54 }
55
56 WL_EXPORT void
57 ds_tizen_screenmirror_send_content(struct ds_tizen_screenmirror *mirror,
58         enum ds_tizen_screenmirror_content content)
59 {
60     if (content == DS_TIZEN_SCREENMIRROR_CONTENT_NORMAL)
61       tizen_screenmirror_send_content(mirror->resource, TIZEN_SCREENMIRROR_CONTENT_NORMAL);
62     else if (content == DS_TIZEN_SCREENMIRROR_CONTENT_VIDEO)
63       tizen_screenmirror_send_content(mirror->resource, TIZEN_SCREENMIRROR_CONTENT_VIDEO);
64 }
65
66 WL_EXPORT void
67 ds_tizen_screenmirror_send_dequeued(struct ds_tizen_screenmirror *mirror,
68         struct ds_buffer *buffer)
69 {
70     struct wl_resource *wl_buffer;
71
72     wl_buffer = ds_buffer_get_resource(buffer);
73     tizen_screenmirror_send_dequeued(mirror->resource, wl_buffer);
74 }
75
76 WL_EXPORT void
77 ds_tizen_screenmirror_send_stop(struct ds_tizen_screenmirror *mirror)
78 {
79     tizen_screenmirror_send_stop(mirror->resource);
80 }
81
82 void
83 ds_tizen_screenmirror_destroy(struct ds_tizen_screenmirror *mirror)
84 {
85     if (mirror == NULL)
86         return;
87
88     if (mirror->client_destroy_listener.notify)
89         wl_list_remove(&mirror->client_destroy_listener.link);
90     mirror->client_destroy_listener.notify = NULL;
91
92     if (mirror->resource)
93         wl_resource_set_destructor(mirror->resource, NULL);
94
95     wl_signal_emit_mutable(&mirror->events.destroy, NULL);
96     //should be called buffer_dequeued from server(ds_tizen_screenmirror_send_dequeued)
97
98     free(mirror);
99 }
100
101 static void
102 screenmirror_handle_resource_destroy(struct wl_resource *resource)
103 {
104     struct ds_tizen_screenmirror *mirror = wl_resource_get_user_data(resource);
105     ds_tizen_screenmirror_destroy(mirror);
106 }
107
108 static void
109 screenmirror_handle_client_destroy(struct wl_listener *listener, void *data)
110 {
111     struct ds_tizen_screenmirror *mirror = wl_container_of(listener, mirror, client_destroy_listener);
112     ds_tizen_screenmirror_destroy(mirror);
113 }
114
115 struct ds_tizen_screenmirror *
116 ds_tizen_screenmirror_create(struct ds_tizen_screenshooter_client *client,
117         int version, uint32_t id)
118 {
119     struct ds_tizen_screenmirror *mirror;
120
121     mirror = calloc(1, sizeof *mirror);
122     if (!mirror) {
123         ds_err("screenmirror create fail : memory alloc failed");
124         return NULL;
125     }
126  
127     mirror->resource = wl_resource_create(client->client, &tizen_screenmirror_interface,
128                                           version, id);
129     if (mirror->resource == NULL) {
130         ds_err("screenmirror wl_resource create fail : memory alloc failed");
131         free(mirror);
132         return NULL;
133     }
134
135     wl_signal_init(&mirror->events.destroy);
136     wl_signal_init(&mirror->events.set_stretch);
137     wl_signal_init(&mirror->events.queue);
138     wl_signal_init(&mirror->events.dequeue);
139     wl_signal_init(&mirror->events.start);
140     wl_signal_init(&mirror->events.stop);
141     wl_signal_init(&mirror->events.set_auto_rotation);
142
143     wl_resource_set_implementation(mirror->resource, &_screenmirror_interface,
144                                    mirror, screenmirror_handle_resource_destroy);
145
146
147     ds_inf("create : tizen_screenmirror(%p)", mirror);
148
149     mirror->client_destroy_listener.notify = screenmirror_handle_client_destroy;
150     wl_client_add_destroy_listener(client->client, &mirror->client_destroy_listener);
151
152     return mirror;
153 }
154
155 static void
156 _tizen_screenmirror_handle_destroy(struct wl_client *client, struct wl_resource *resource)
157 {
158     ds_inf("_tizen_screenmirror_handle_destroy (res:%p)", resource);
159     wl_resource_destroy(resource);
160 }
161
162 static void
163 _tizen_screenmirror_handle_set_stretch(struct wl_client *client, struct wl_resource *resource, uint32_t stretch)
164 {
165     struct ds_tizen_screenmirror *mirror = wl_resource_get_user_data(resource);
166     enum ds_tizen_screenmirror_stretch ds_stretch;
167
168     if (stretch > TIZEN_SCREENMIRROR_STRETCH_FULLY) {
169         ds_err("set stretch error : not supported stretch(%d)", stretch);
170         return;
171     }
172     if (stretch == TIZEN_SCREENMIRROR_STRETCH_KEEP_RATIO)
173         ds_stretch = DS_TIZEN_SCREENMIRROR_STRETCH_KEEP_RATIO;
174     else
175         ds_stretch = DS_TIZEN_SCREENMIRROR_STRETCH_FULLY;
176
177     wl_signal_emit_mutable(&mirror->events.set_stretch, &ds_stretch);
178 }
179
180 static void
181 _tizen_screenmirror_handle_queue(struct wl_client *client, struct wl_resource *resource, struct wl_resource *wl_buffer)
182 {
183     struct ds_tizen_screenmirror *mirror;
184     struct ds_buffer *buffer;
185
186     mirror = wl_resource_get_user_data(resource);
187     buffer = ds_buffer_from_resource(wl_buffer);
188     if (!buffer) {
189         ds_err("ds_buffer_from_resource fail");
190         return;
191     }
192
193     wl_signal_emit_mutable(&mirror->events.queue, &buffer);
194 }
195
196 static void
197 _tizen_screenmirror_handle_dequeue(struct wl_client *client, struct wl_resource *resource, struct wl_resource *wl_buffer)
198 {
199     struct ds_tizen_screenmirror *mirror;
200     struct ds_buffer *buffer;
201
202     mirror = wl_resource_get_user_data(resource);
203     buffer = ds_buffer_from_resource(wl_buffer);
204     if (!buffer) {
205         ds_err("ds_buffer_from_resource fail");
206         return;
207     }
208
209     wl_signal_emit_mutable(&mirror->events.dequeue, &buffer);
210 }
211
212 static void
213 _tizen_screenmirror_handle_start(struct wl_client *client, struct wl_resource *resource)
214 {
215     struct ds_tizen_screenmirror *mirror;
216
217     mirror = wl_resource_get_user_data(resource);
218     wl_signal_emit_mutable(&mirror->events.start, NULL);
219 }
220
221 static void
222 _tizen_screenmirror_handle_stop(struct wl_client *client, struct wl_resource *resource)
223 {
224     struct ds_tizen_screenmirror *mirror;
225
226     mirror = wl_resource_get_user_data(resource);
227     wl_signal_emit_mutable(&mirror->events.stop, NULL);
228 }
229
230 static void
231 _tizen_screenmirror_handle_set_auto_rotation(struct wl_client *client, struct wl_resource *resource, uint32_t set)
232 {
233     struct ds_tizen_screenmirror *mirror;
234
235     mirror = wl_resource_get_user_data(resource);
236     wl_signal_emit_mutable(&mirror->events.set_auto_rotation, &set);
237 }
238
239 static const struct tizen_screenmirror_interface _screenmirror_interface = {
240      _tizen_screenmirror_handle_destroy,
241      _tizen_screenmirror_handle_set_stretch,
242      _tizen_screenmirror_handle_queue,
243      _tizen_screenmirror_handle_dequeue,
244      _tizen_screenmirror_handle_start,
245      _tizen_screenmirror_handle_stop,
246      _tizen_screenmirror_handle_set_auto_rotation
247 };