struct shell_client
{
- desktop_shell_t *shell;
- struct wl_resource *resource;
- struct wl_list link;
+ desktop_shell_t *shell;
+ struct wl_resource *resource;
+ struct wl_client *client;
+
+ struct wl_listener client_destroy_listener;
+
+ /* Ping-Pong */
+ struct wl_event_source *ping_timer;
+ pepper_bool_t need_pong;
+ uint32_t ping_serial;
+ pepper_bool_t irresponsive;
+
+ struct wl_list link;
};
typedef enum
/* Data structures per surface type */
shell_surface_type_t type;
- /* Ping-Pong */
- struct wl_event_source *ping_timer;
- pepper_bool_t need_pong;
- uint32_t ping_serial;
- pepper_bool_t unresponsive;
-
/* Listeners */
struct wl_listener client_destroy_listener;
struct wl_listener surface_destroy_listener;
shell_surface_ping(shell_surface_t *shsurf);
void
+shell_client_handle_pong(shell_client_t *shell_client, uint32_t serial);
+
+void
+shell_surface_handle_pong(shell_surface_t *shsurf, uint32_t serial);
+
+void
+remove_ping_timer(shell_client_t *shell_client);
+
+void
shell_surface_set_type(shell_surface_t *shsurf, shell_surface_type_t type);
void
#include "desktop-shell-internal.h"
-#include <stdlib.h>
+#include "xdg-shell-server-protocol.h"
-static void
-remove_ping_timer(shell_surface_t *shsurf)
+void
+remove_ping_timer(shell_client_t *shell_client)
{
- if (shsurf->ping_timer)
+ if (shell_client->ping_timer)
{
- wl_event_source_remove(shsurf->ping_timer);
- shsurf->ping_timer = NULL;
+ wl_event_source_remove(shell_client->ping_timer);
+ shell_client->ping_timer = NULL;
}
}
if (!wl_list_empty(&shsurf->client_destroy_listener.link))
wl_list_remove(&shsurf->client_destroy_listener.link);
wl_list_init(&shsurf->client_destroy_listener.link);
-
- remove_ping_timer(shsurf);
-
- /* client_destroy -> client's surface destroy -> handle_surface_destroy */
}
static void
wl_list_remove(&shsurf->surface_destroy_listener.link);
- /* We don't need to destroy pepper_view_t */
-
if (shsurf->resource)
wl_resource_destroy(shsurf->resource);
if (shsurf->class_)
free(shsurf->class_);
- remove_ping_timer(shsurf);
-
wl_list_remove(&shsurf->parent_link);
wl_list_for_each_safe(child, tmp, &shsurf->child_list, parent_link)
/* Set shell_surface_t to pepper_surface_t */
set_shsurf_to_surface(surface, shsurf);
+ wl_list_init(&shsurf->link);
+ wl_list_insert(&shsurf->shell->shell_surface_list, &shsurf->link);
+
return shsurf;
error:
static int
handle_ping_timeout(void *data)
{
- shell_surface_t *shsurf = data;
+ shell_client_t *shell_client = data;
- shsurf->unresponsive = PEPPER_TRUE;
+ shell_client->irresponsive = PEPPER_TRUE;
/* TODO: Display wait cursor */
void
shell_surface_ping(shell_surface_t *shsurf)
{
- struct wl_display *display = pepper_compositor_get_display(shsurf->shell->compositor);
- const char *role;
+ shell_client_t *shell_client = shsurf->shell_client;
+ struct wl_display *display;
+ const char *role;
/* Already stucked, do not send another ping */
- if (shsurf->unresponsive)
+ if (shell_client->irresponsive)
{
- handle_ping_timeout(shsurf);
+ handle_ping_timeout(shell_client);
return ;
}
- if (!shsurf->ping_timer)
+ display = pepper_compositor_get_display(shsurf->shell->compositor);
+
+ if (!shell_client->ping_timer)
{
struct wl_event_loop *loop = wl_display_get_event_loop(display);
- shsurf->ping_timer = wl_event_loop_add_timer(loop, handle_ping_timeout, shsurf);
+ shell_client->ping_timer = wl_event_loop_add_timer(loop, handle_ping_timeout, shell_client);
- if (!shsurf->ping_timer)
+ if (!shell_client->ping_timer)
{
PEPPER_ERROR("Failed to add timer event source.\n");
return;
}
}
- wl_event_source_timer_update(shsurf->ping_timer, DESKTOP_SHELL_PING_TIMEOUT);
+ wl_event_source_timer_update(shell_client->ping_timer, DESKTOP_SHELL_PING_TIMEOUT);
- shsurf->ping_serial = wl_display_next_serial(display);
- shsurf->need_pong = PEPPER_TRUE;
+ shell_client->ping_serial = wl_display_next_serial(display);
+ shell_client->need_pong = PEPPER_TRUE;
role = pepper_surface_get_role(shsurf->surface);
if (!strcmp(role, "wl_shell_surface"))
- wl_shell_surface_send_ping(shsurf->resource, shsurf->ping_serial);
+ wl_shell_surface_send_ping(shsurf->resource, shell_client->ping_serial);
+ else if (!strcmp(role, "xdg_surface") || !strcmp(role, "xdg_popup"))
+ xdg_shell_send_ping(shell_client->resource, shell_client->ping_serial);
+ else
+ PEPPER_ASSERT(0);
+}
- /* TODO: Do another protocol specific ping. */
+void
+shell_client_handle_pong(shell_client_t *shell_client, uint32_t serial)
+{
+ /* Client response right ping_serial */
+ if (shell_client->need_pong && shell_client->ping_serial == serial)
+ {
+ wl_event_source_timer_update(shell_client->ping_timer, 0); /* disarms the timer */
+
+ shell_client->irresponsive = PEPPER_FALSE;
+ shell_client->need_pong = PEPPER_FALSE;
+ shell_client->ping_serial = 0;
+
+ /* TODO: Stop displaying wait cursor */
+ }
+}
+
+void
+shell_surface_handle_pong(shell_surface_t *shsurf, uint32_t serial)
+{
+ shell_client_handle_pong(shsurf->shell_client, serial);
}
void
#include "desktop-shell-internal.h"
#include <stdlib.h>
+static void
+handle_shell_client_destroy(struct wl_listener *listener, void *data)
+{
+ shell_client_t *shell_client = pepper_container_of(listener,
+ shell_client_t,
+ client_destroy_listener);
+
+ remove_ping_timer(shell_client);
+
+ wl_list_remove(&shell_client->link);
+
+ free(shell_client);
+}
+
shell_client_t *
shell_client_create(desktop_shell_t *shell, struct wl_client *client,
const struct wl_interface *interface, const void *implementation,
free(shell_client);
return NULL;
}
- wl_resource_set_implementation(shell_client->resource, implementation, shell_client, NULL);
+
+ shell_client->shell = shell;
+ shell_client->client = client;
+
+ shell_client->client_destroy_listener.notify = handle_shell_client_destroy;
+ wl_client_add_destroy_listener(client, &shell_client->client_destroy_listener);
wl_list_insert(&shell->shell_client_list, &shell_client->link);
- shell_client->shell = shell;
+ wl_resource_set_implementation(shell_client->resource, implementation, shell_client, NULL);
return shell_client;
}