0a802fadf35b33f89b667aec6a3181c9328492e6
[platform/core/uifw/libds-tizen.git] / src / embedded_compositor / embedded_compositor.c
1 #include <assert.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <errno.h>
9 #include <wayland-server.h>
10 #include <tizen-extension-server-protocol.h>
11 #include <libds/log.h>
12
13 #include "util.h"
14 #include "libds-tizen/embedded_compositor.h"
15
16 #define TIZEN_EMBEDDED_COMPOSITOR_VERSION 1
17
18 struct ds_tizen_embedded_compositor
19 {
20     struct wl_global *global;
21
22     struct wl_listener destroy;
23
24     struct {
25         struct wl_signal destroy;
26     } events;
27 };
28
29 struct ds_tizen_embedded_compositor_client
30 {
31     struct ds_tizen_embedded_compositor *embedded_compositor;
32
33     struct wl_resource *resource;
34     struct wl_client *wl_client;
35 };
36
37 static void embedded_compositor_handle_display_destroy(struct wl_listener *listener,
38         void *data);
39
40 static void embedded_compositor_bind(struct wl_client *wl_client, void *data,
41         uint32_t version, uint32_t id);
42
43 WL_EXPORT struct ds_tizen_embedded_compositor *
44 ds_tizen_embedded_compositor_create(struct wl_display *display)
45 {
46     struct ds_tizen_embedded_compositor *embedded_compositor;
47
48     embedded_compositor = calloc(1, sizeof *embedded_compositor);
49     if (!embedded_compositor) {
50         ds_err("calloc() failed.");
51         return NULL;
52     }
53
54     embedded_compositor->global = wl_global_create(display, &tizen_embedded_compositor_interface,
55             TIZEN_EMBEDDED_COMPOSITOR_VERSION, embedded_compositor, embedded_compositor_bind);
56     if (!embedded_compositor->global) {
57         ds_err("wl_global_create() failed. tizen_embedded_compositor_interface");
58         free(embedded_compositor);
59         return NULL;
60     }
61
62     embedded_compositor->destroy.notify = embedded_compositor_handle_display_destroy;
63     wl_display_add_destroy_listener(display, &embedded_compositor->destroy);
64
65     wl_signal_init(&embedded_compositor->events.destroy);
66
67     ds_inf("Global created: tizen_embedded_compositor(%p)", embedded_compositor);
68
69     return embedded_compositor;
70 }
71
72 WL_EXPORT void
73 ds_tizen_embedded_compositor_add_destroy_listener(
74         struct ds_tizen_embedded_compositor *embedded_compositor,
75         struct wl_listener *listener)
76 {
77     wl_signal_add(&embedded_compositor->events.destroy, listener);
78 }
79
80 static void
81 embedded_compositor_handle_display_destroy(struct wl_listener *listener, void *data)
82 {
83     struct ds_tizen_embedded_compositor *embedded_compositor;
84
85     embedded_compositor = wl_container_of(listener, embedded_compositor, destroy);
86
87     ds_inf("Global destroy: embedded_compositor(%p)", embedded_compositor);
88
89     wl_signal_emit_mutable(&embedded_compositor->events.destroy, embedded_compositor);
90     wl_list_remove(&embedded_compositor->destroy.link);
91     wl_global_destroy(embedded_compositor->global);
92     free(embedded_compositor);
93 }
94
95 static void
96 embedded_compositor_handle_get_socket(struct wl_client *wl_client,
97     struct wl_resource *resource)
98 {
99     struct ds_tizen_embedded_compositor_client *client;
100     int sock_fd=-1;
101     pid_t pid = 0;
102
103     ds_inf("tizen_embedded_compositor: get_socket");
104
105     client = wl_resource_get_user_data(resource);
106
107     wl_client_get_credentials(client->wl_client, &pid, NULL, NULL);
108
109     sock_fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
110     if (sock_fd < 0) {
111         ds_err("Could not create socket: %m, (client=%p, pid=%d)", client, pid);
112         return;
113      }
114
115     tizen_embedded_compositor_send_socket(resource, sock_fd);
116
117     ds_inf("tizen_embedded_compositor: (sock_fd,%d) sent! (client,%p) (pid,%d)",
118         sock_fd, client, pid);
119
120     close(sock_fd);
121 }
122
123 static void
124 embedded_compositor_handle_destroy(struct wl_client *wl_client,
125     struct wl_resource *resource)
126 {
127     wl_resource_destroy(resource);
128 }
129
130 static const struct tizen_embedded_compositor_interface embedded_compositor_impl =
131 {
132    embedded_compositor_handle_get_socket,
133    embedded_compositor_handle_destroy,
134 };
135
136 static void
137 _tizen_embedded_compositor_client_handle_destroy(struct wl_resource *resource)
138 {
139     struct ds_tizen_embedded_compositor_client *client;
140
141     client = wl_resource_get_user_data(resource);
142
143     ds_inf("_tizen_embedded_compositor_client_handle_destroy (client:%p)", client);
144
145     free(client);
146 }
147
148 static void
149 embedded_compositor_bind(struct wl_client *wl_client, void *data, uint32_t version,
150         uint32_t id)
151 {
152     struct ds_tizen_embedded_compositor *embedded_compositor = data;
153     struct ds_tizen_embedded_compositor_client *client;
154
155     client = calloc(1, sizeof *client);
156     if (client == NULL) {
157         ds_err("calloc() failed. tizen_embedded_compositor");
158         wl_client_post_no_memory(wl_client);
159         return;
160     }
161
162     ds_inf("tizen_embedded_compositor_client binds. (client:%p)", client);
163
164     client->embedded_compositor = embedded_compositor;
165     client->wl_client = wl_client;
166
167     client->resource = wl_resource_create(wl_client,
168             &tizen_embedded_compositor_interface,
169             MIN(version, TIZEN_EMBEDDED_COMPOSITOR_VERSION), id);
170
171     if (client->resource == NULL) {
172         ds_err("tizen_embedded_compositor : wl_resource_create() failed.");
173         free(client);
174         wl_client_post_no_memory(wl_client);
175         return;
176     }
177
178     wl_resource_set_implementation(client->resource, &embedded_compositor_impl,
179             client, _tizen_embedded_compositor_client_handle_destroy);
180 }