2 * Copyright (C) 2014 DENSO CORPORATION
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 * ivi-shell-ext supports a type of shell for standard wayland.
34 #include <linux/input.h>
36 #include "ivi-shell-ext.h"
37 #include "ivi-shell.h"
38 #include "compositor.h"
39 #include "ivi-layout-export.h"
45 struct wl_event_source *source;
51 struct wl_resource *resource;
53 struct weston_surface *surface;
54 struct weston_view *view;
55 struct wl_listener surface_destroy_listener;
57 struct ivi_shell_ext *shell;
58 struct ping_timer *ping_timer;
68 const struct weston_shell_client *client;
69 struct weston_output *output;
74 struct link_weston_surface
76 struct wl_listener destroy_listener;
77 struct weston_surface *surface;
83 struct wl_listener destroy_listener;
84 struct wl_list list_weston_surface;
85 struct wl_list list_shell_surface;
88 /* ------------------------------------------------------------------------- */
89 /* common functions */
90 /* ------------------------------------------------------------------------- */
92 static struct ivi_shell_ext *
95 static struct ivi_shell_ext *shell = NULL;
98 shell = calloc(1, sizeof(*shell));
99 wl_list_init(&shell->list_shell_surface);
100 wl_list_init(&shell->list_weston_surface);
107 configure(struct weston_view *view, float x, float y)
110 weston_view_set_position(view, x, y);
111 weston_view_update_transform(view);
116 * Implementation of wl_shell
120 shell_surface_configure(struct weston_surface *, int32_t, int32_t);
122 static struct shell_surface *
123 get_shell_surface(struct weston_surface *surface)
125 if (surface->configure == shell_surface_configure) {
126 return surface->configure_private;
133 ping_timer_destroy(struct shell_surface *shsurf)
135 if (!shsurf || !shsurf->ping_timer) {
139 if (shsurf->ping_timer->source) {
140 wl_event_source_remove(shsurf->ping_timer->source);
143 free(shsurf->ping_timer);
144 shsurf->ping_timer = NULL;
148 destroy_shell_surface(struct shell_surface *shsurf)
150 wl_list_remove(&shsurf->surface_destroy_listener.link);
153 shsurf->surface->configure = NULL;
156 ping_timer_destroy(shsurf);
159 shsurf->title = NULL;
161 wl_list_remove(&shsurf->link);
167 shell_handle_surface_destroy(struct wl_listener *listener, void *data)
169 struct shell_surface *shsurf = NULL;
171 shsurf = container_of(listener,
172 struct shell_surface,
173 surface_destroy_listener);
175 if (wl_resource_get_client(shsurf->resource)) {
176 wl_resource_destroy(shsurf->resource);
178 wl_resource_destroy(shsurf->resource);
179 destroy_shell_surface(shsurf);
184 shell_surface_configure(struct weston_surface *es,
185 int32_t sx, int32_t sy)
187 struct shell_surface *shsurf = get_shell_surface(es);
193 if ((es == NULL) || (shsurf == NULL)) {
197 if (shsurf->width != es->width || shsurf->height != es->height) {
199 shsurf->width = es->width;
200 shsurf->height = es->height;
202 weston_view_to_global_float(shsurf->view, 0, 0, &from_x, &from_y);
203 weston_view_to_global_float(shsurf->view, sx, sy, &to_x, &to_y);
204 configure(shsurf->view,
205 shsurf->view->geometry.x + to_x - from_x,
206 shsurf->view->geometry.y + to_y - from_y);
211 send_configure(struct weston_surface *surface,
212 /* uint32_t edges, */ int32_t width, int32_t height)
214 struct shell_surface *shsurf = get_shell_surface(surface);
216 wl_shell_surface_send_configure(shsurf->resource,
217 0 /* edges */, width, height);
220 static const struct weston_shell_client shell_client = {
225 shell_destroy_shell_surface(struct wl_resource *resource)
227 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
229 destroy_shell_surface(shsurf);
233 shell_surface_pong(struct wl_client *client,
234 struct wl_resource *resource, uint32_t serial)
236 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
238 if (shsurf->ping_timer == NULL) {
242 if (shsurf->ping_timer->serial == serial) {
243 ping_timer_destroy(shsurf);
248 shell_surface_move(struct wl_client *client, struct wl_resource *resource,
249 struct wl_resource *seat_resource, uint32_t serial)
259 shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
260 struct wl_resource *seat_resource, uint32_t serial,
272 shell_surface_set_toplevel(struct wl_client *client,
273 struct wl_resource *resource)
281 shell_surface_set_transient(struct wl_client *client,
282 struct wl_resource *resource,
283 struct wl_resource *parent_resource,
284 int x, int y, uint32_t flags)
289 (void)parent_resource;
296 shell_surface_set_fullscreen(struct wl_client *client,
297 struct wl_resource *resource,
300 struct wl_resource *output_resource)
307 (void)output_resource;
311 shell_surface_set_popup(struct wl_client *client,
312 struct wl_resource *resource,
313 struct wl_resource *seat_resource,
315 struct wl_resource *parent_resource,
316 int32_t x, int32_t y, uint32_t flags)
323 (void)parent_resource;
330 shell_surface_set_maximized(struct wl_client *client,
331 struct wl_resource *resource,
332 struct wl_resource *output_resource)
337 (void)output_resource;
341 shell_surface_set_title(struct wl_client *client,
342 struct wl_resource *resource, const char *title)
344 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
348 shsurf->title = strdup(title);
350 shsurf->title = strdup("");
353 send_wl_shell_info(shsurf->pid, shsurf->title);
357 shell_surface_set_class(struct wl_client *client,
358 struct wl_resource *resource, const char *class)
360 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
363 shsurf->class = strdup(class);
366 static const struct wl_shell_surface_interface shell_surface_implementation = {
369 shell_surface_resize,
370 shell_surface_set_toplevel,
371 shell_surface_set_transient,
372 shell_surface_set_fullscreen,
373 shell_surface_set_popup,
374 shell_surface_set_maximized,
375 shell_surface_set_title,
376 shell_surface_set_class
380 shell_weston_surface_destroy(struct wl_listener *listener, void *data)
382 struct link_weston_surface *lsurf = NULL;
384 lsurf = container_of(listener,
385 struct link_weston_surface,
388 wl_list_remove(&lsurf->link);
393 static struct shell_surface *
394 create_shell_surface(struct ivi_shell_ext *shell,
395 struct wl_client *client,
396 uint32_t id_wl_shell,
397 struct weston_surface *surface,
398 const struct weston_shell_client *shell_client)
400 struct shell_surface *shsurf = NULL;
403 if (surface->configure) {
404 weston_log("surface->configure already set\n");
409 shsurf = calloc(1, sizeof *shsurf);
410 if (shsurf == NULL) {
411 weston_log("fails to allocate memory\n");
416 surface->configure = shell_surface_configure;
417 surface->configure_private = shsurf;
420 shsurf->shell = shell;
421 shsurf->surface = surface;
422 shsurf->ping_timer = NULL;
423 shsurf->title = strdup("");
425 /* init link so its safe to always remove it in destroy_shell_surface */
426 wl_list_init(&shsurf->link);
428 shsurf->client = shell_client;
429 shsurf->resource = wl_resource_create(client, &wl_shell_surface_interface,
432 wl_resource_set_implementation(shsurf->resource,
433 &shell_surface_implementation,
434 shsurf, shell_destroy_shell_surface);
436 shsurf->surface_destroy_listener.notify = shell_handle_surface_destroy;
437 wl_resource_add_destroy_listener(surface->resource,
438 &shsurf->surface_destroy_listener);
444 create_link_weston_surface(struct ivi_shell_ext *shell,
445 struct weston_surface *surface)
447 struct link_weston_surface *lsurf = NULL;
449 lsurf = calloc(1, sizeof *lsurf);
451 weston_log("fails to allocate memory\n");
455 lsurf->surface = surface;
457 wl_list_init(&lsurf->link);
458 wl_list_insert(&shell->list_weston_surface, &lsurf->link);
460 lsurf->destroy_listener.notify = shell_weston_surface_destroy;
461 wl_resource_add_destroy_listener(surface->resource,
462 &lsurf->destroy_listener);
466 shell_get_shell_surface(struct wl_client *client,
467 struct wl_resource *resource,
468 uint32_t id_wl_shell,
469 struct wl_resource *surface_resource)
471 struct ivi_shell_ext *shell = wl_resource_get_user_data(resource);
472 struct weston_surface *surface = NULL;
473 struct shell_surface *shsurf = NULL;
478 surface = wl_resource_get_user_data(surface_resource);
479 if (get_shell_surface(surface)) {
480 wl_resource_post_error(surface_resource,
481 WL_DISPLAY_ERROR_INVALID_OBJECT,
482 "get_shell_surface already requested");
486 shsurf = create_shell_surface(shell, client, id_wl_shell, surface, &shell_client);
488 wl_resource_post_error(surface_resource,
489 WL_DISPLAY_ERROR_INVALID_OBJECT,
490 "surface->configure already set");
494 create_link_weston_surface(shell, surface);
496 wl_client_get_credentials(client, &pid, &uid, &gid);
499 wl_list_insert(&shell->list_shell_surface, &shsurf->link);
501 send_wl_shell_info(shsurf->pid, shsurf->title);
504 static const struct wl_shell_interface shell_implementation = {
505 shell_get_shell_surface
509 bind_shell(struct wl_client *client, void *data,
510 uint32_t version, uint32_t id)
512 struct ivi_shell_ext *shell = data;
513 struct wl_resource *resource = NULL;
515 resource = wl_resource_create(client, &wl_shell_interface, 1, id);
516 wl_resource_set_implementation(resource,
517 &shell_implementation,
522 * Initialization/destruction method of ivi-shell-ext
525 shell_ext_destroy(struct wl_listener *listener, void *data)
527 struct ivi_shell_ext *shell = NULL;
529 shell = container_of(listener, struct ivi_shell_ext, destroy_listener);
535 /* ------------------------------------------------------------------------- */
536 /* export functions */
537 /* ------------------------------------------------------------------------- */
539 ivi_shell_get_shell_surfaces(struct wl_array *surfaces)
541 struct ivi_shell_ext *shell = get_instance();
542 wl_array_init(surfaces);
544 struct shell_surface *surface = NULL;
545 wl_list_for_each(surface, &shell->list_shell_surface, link) {
546 struct shell_surface **add = wl_array_add(surfaces, sizeof(surface));
552 shell_surface_get_process_id(struct shell_surface *surface)
558 shell_surface_get_title(struct shell_surface* surface)
560 return surface->title;
563 WL_EXPORT struct weston_surface *
564 shell_surface_get_surface(struct shell_surface* surface)
566 return surface->surface;
570 * Initialization of ivi-shell-ext. wl_shell is supported here.
575 init_ivi_shell_ext(struct weston_compositor *ec,
576 int *argc, char *argv[])
578 struct ivi_shell_ext *shell = get_instance();
580 wl_list_init(&shell->list_weston_surface);
581 wl_list_init(&shell->list_shell_surface);
583 shell->destroy_listener.notify = shell_ext_destroy;
584 wl_signal_add(&ec->destroy_signal, &shell->destroy_listener);
586 if (wl_global_create(ec->wl_display, &wl_shell_interface, 1,
587 shell, bind_shell) == NULL) {