summaryrefslogtreecommitdiffstats
path: root/demo3/horizontal/waltham-server/orig/src/wth-server-waltham-comm.c
diff options
context:
space:
mode:
Diffstat (limited to 'demo3/horizontal/waltham-server/orig/src/wth-server-waltham-comm.c')
-rw-r--r--demo3/horizontal/waltham-server/orig/src/wth-server-waltham-comm.c1179
1 files changed, 1179 insertions, 0 deletions
diff --git a/demo3/horizontal/waltham-server/orig/src/wth-server-waltham-comm.c b/demo3/horizontal/waltham-server/orig/src/wth-server-waltham-comm.c
new file mode 100644
index 0000000..bcd2cd4
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/src/wth-server-waltham-comm.c
@@ -0,0 +1,1179 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+** **
+** SRC-MODULE: **
+** **
+** TARGET : linux **
+** **
+** PROJECT : waltham-server **
+** **
+** AUTHOR : **
+** **
+** **
+** **
+** PURPOSE : This file acts as interface to waltham IPC library **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+#include "wth-server-waltham-comm.h"
+
+extern int wth_server_weston_main(struct window *);
+
+extern void wth_server_weston_shm_attach(struct window *, uint32_t data_sz, void * data,
+ int32_t width, int32_t height, int32_t stride, uint32_t format);
+extern void wth_server_weston_shm_damage(struct window *);
+extern void wth_server_weston_shm_commit(struct window *);
+
+extern bool get_verbosity(void);
+extern int verbose;
+
+/*
+ * utility functions
+ */
+static int
+watch_ctl(struct watch *w, int op, uint32_t events)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct epoll_event ee;
+
+ ee.events = events;
+ ee.data.ptr = w;
+ wth_verbose(" <<< %s \n",__func__);
+ return epoll_ctl(w->server->epoll_fd, op, w->fd, &ee);
+}
+
+static void
+client_post_out_of_memory(struct client *c)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct wth_display *disp;
+
+ disp = wth_connection_get_display(c->connection);
+ wth_object_post_error((struct wth_object *)disp, 1,
+ "out of memory");
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * waltham surface implementation
+ */
+static void
+surface_destroy(struct surface *surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("surface %p destroy\n", surface->obj);
+
+ wthp_surface_free(surface->obj);
+ wl_list_remove(&surface->link);
+ free(surface);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_destroy(struct wthp_surface *wthp_surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = wth_object_get_user_data((struct wth_object *)wthp_surface);
+
+ assert(wthp_surface == surface->obj);
+
+ surface_destroy(surface);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_attach(struct wthp_surface *wthp_surface,
+ struct wthp_buffer *wthp_buffer, int32_t x, int32_t y)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct buffer *buffr = wth_object_get_user_data((struct wth_object *)wthp_buffer);
+ struct surface *surf = wth_object_get_user_data((struct wth_object *)wthp_surface);
+ struct buffer *buf = NULL;
+
+ buf = container_of(wthp_buffer, struct buffer, obj);
+
+ if (surf->ivi_id != 0) {
+ wth_server_weston_shm_attach(surf->shm_window,
+ buf->data_sz,
+ buf->data,
+ buf->width,
+ buf->height,
+ buf->stride,
+ buf->format);
+
+ wthp_buffer_send_complete(wthp_buffer, 0);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_damage(struct wthp_surface *wthp_surface,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("surface %p damage(%d, %d, %d, %d)\n",
+ wthp_surface, x, y, width, height);
+
+ struct surface *surf = wth_object_get_user_data((struct wth_object *)wthp_surface);
+
+ if (surf->ivi_id != 0) {
+ wth_server_weston_shm_damage(surf->shm_window);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_frame(struct wthp_surface *wthp_surface,
+ struct wthp_callback *callback)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surf = wth_object_get_user_data((struct wth_object *)wthp_surface);
+ wth_verbose("surface %p callback(%p)\n",wthp_surface, callback);
+
+ surf->cb = callback;
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_set_opaque_region(struct wthp_surface *wthp_surface,
+ struct wthp_region *region)
+{
+ wth_verbose("surface %p set_opaque_region(%p)\n",
+ wthp_surface, region);
+}
+
+static void
+surface_handle_set_input_region(struct wthp_surface *wthp_surface,
+ struct wthp_region *region)
+{
+ wth_verbose("surface %p set_input_region(%p)\n",
+ wthp_surface, region);
+}
+
+static void
+surface_handle_commit(struct wthp_surface *wthp_surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct surface *surf = wth_object_get_user_data((struct wth_object *)wthp_surface);
+ wth_verbose("commit %p\n",wthp_surface);
+
+ if (surf->ivi_id != 0) {
+ wth_server_weston_shm_commit(surf->shm_window);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_set_buffer_transform(struct wthp_surface *wthp_surface,
+ int32_t transform)
+{
+ wth_verbose("surface %p et_buffer_transform(%d)\n",
+ wthp_surface, transform);
+}
+
+static void
+surface_handle_set_buffer_scale(struct wthp_surface *wthp_surface,
+ int32_t scale)
+{
+ wth_verbose("surface %p set_buffer_scale(%d)\n",
+ wthp_surface, scale);
+}
+
+static void
+surface_handle_damage_buffer(struct wthp_surface *wthp_surface,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ wth_verbose("surface %p damage_buffer(%d, %d, %d, %d)\n",
+ wthp_surface, x, y, width, height);
+}
+
+static const struct wthp_surface_interface surface_implementation = {
+ surface_handle_destroy,
+ surface_handle_attach,
+ surface_handle_damage,
+ surface_handle_frame,
+ surface_handle_set_opaque_region,
+ surface_handle_set_input_region,
+ surface_handle_commit,
+ surface_handle_set_buffer_transform,
+ surface_handle_set_buffer_scale,
+ surface_handle_damage_buffer
+};
+
+
+/* BEGIN wthp_region implementation */
+
+static void
+buffer_handle_destroy(struct wthp_buffer *wthp_buffer)
+{
+ struct buffer *buf = wth_object_get_user_data((struct wth_object *)wthp_buffer);
+
+ wthp_buffer_free(wthp_buffer);
+ wl_list_remove(&buf->link);
+ free(buf);
+}
+
+static const struct wthp_buffer_interface buffer_implementation = {
+ buffer_handle_destroy
+};
+
+/* END wthp_region implementation */
+
+/* BEGIN wthp_blob_factory implementation */
+
+static void
+blob_factory_create_buffer(struct wthp_blob_factory *blob_factory,
+ struct wthp_buffer *wthp_buffer, uint32_t data_sz, void *data,
+ int32_t width, int32_t height, int32_t stride, uint32_t format)
+{
+ struct blob_factory *blob = wth_object_get_user_data((struct wth_object *)blob_factory);
+ struct buffer *buffer;
+
+
+ wth_verbose("wthp_blob_factory %p create_buffer(%p, %d, %p, %d, %d, %d, %d)\n",
+ blob_factory, wthp_buffer, data_sz, data, width, height, stride, format);
+
+ buffer = zalloc(sizeof *buffer);
+ if (!buffer) {
+ client_post_out_of_memory(blob->client);
+ return;
+ }
+
+ wl_list_insert(&blob->client->buffer_list, &buffer->link);
+
+ buffer->data_sz = data_sz;
+ buffer->data = data;
+ buffer->width = width;
+ buffer->height = height;
+ buffer->stride = stride;
+ buffer->format = format;
+ buffer->obj = wthp_buffer;
+
+ wthp_buffer_set_interface(wthp_buffer, &buffer_implementation, buffer);
+}
+
+static const struct wthp_blob_factory_interface blob_factory_implementation = {
+ blob_factory_create_buffer
+};
+
+static void
+client_bind_blob_factory(struct client *c, struct wthp_blob_factory *obj)
+{
+ struct blob_factory *blob;
+
+ blob = zalloc(sizeof *blob);
+ if (!blob) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ blob->obj = obj;
+ blob->client = c;
+ wl_list_insert(&c->compositor_list, &blob->link);
+
+ wthp_blob_factory_set_interface(obj, &blob_factory_implementation,
+ blob);
+ fprintf(stderr, "client %p bound wthp_blob_factory\n", c);
+}
+
+/*
+ * waltam ivi surface implementation
+ */
+static void
+wthp_ivi_surface_destroy(struct wthp_ivi_surface * ivi_surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct ivisurface *ivisurf = wth_object_get_user_data((struct wth_object *)ivi_surface);
+ free(ivisurf);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wthp_ivi_surface_interface wthp_ivi_surface_implementation = {
+ wthp_ivi_surface_destroy,
+};
+
+
+/*
+ * waltham ivi application implementation
+ */
+static void
+wthp_ivi_application_surface_create(struct wthp_ivi_application * ivi_application, uint32_t ivi_id,
+ struct wthp_surface * wthp_surface, struct wthp_ivi_surface *obj)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("ivi_application %p surface_create(%d, %p, %p)\n",
+ ivi_application, ivi_id, wthp_surface, obj);
+ struct application *app = wth_object_get_user_data((struct wth_object *)ivi_application);
+ struct surface *surface = wth_object_get_user_data((struct wth_object *)wthp_surface);
+ wth_verbose("----------------------------------\n\n\n");
+ wth_verbose("surface [%p]\n", surface);
+ wth_verbose("shm_window [%p]\n\n\n", surface->shm_window);
+ wth_verbose("----------------------------------\n");
+
+ surface->ivi_id = ivi_id + 100;
+ surface->shm_window->id_ivisurf = surface->ivi_id;
+ struct ivisurface *ivisurf;
+
+ ivisurf = zalloc(sizeof *ivisurf);
+ if (!ivisurf) {
+ return;
+ }
+
+ ivisurf->obj = obj;
+ ivisurf->surf = surface;
+
+ wth_server_weston_main(surface->shm_window);
+
+ while (!surface->shm_window->ready)
+ usleep(1);
+
+ wthp_ivi_surface_set_interface(obj, &wthp_ivi_surface_implementation,
+ ivisurf);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wthp_ivi_application_interface wthp_ivi_application_implementation = {
+ wthp_ivi_application_surface_create,
+};
+
+static void
+client_bind_wthp_ivi_application(struct client *c, struct wthp_ivi_application *obj)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct application *app;
+
+ app = zalloc(sizeof *app);
+ if (!app) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ app->obj = obj;
+ app->client = c;
+ wl_list_insert(&c->compositor_list, &app->link);
+
+ wthp_ivi_application_set_interface(obj, &wthp_ivi_application_implementation,
+ app);
+ wth_verbose("client %p bound wthp_ivi_application\n", c);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * APIs to send pointer events to waltham client
+ */
+
+void
+waltham_pointer_enter(struct window *window, uint32_t serial,
+ wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wth_verbose("waltham_pointer_enter [%d]\n", window->server_surf->ivi_id);
+
+ wthp_pointer_send_enter (pointer->obj, serial, surface->obj, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_pointer_leave(struct window *window, uint32_t serial)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wth_verbose("waltham_pointer_leave [%d]\n", window->server_surf->ivi_id);
+
+ wthp_pointer_send_leave (pointer->obj, serial, surface->obj);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_pointer_motion(struct window *window, uint32_t time,
+ wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wthp_pointer_send_motion (pointer->obj, time, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_pointer_button(struct window *window, uint32_t serial,
+ uint32_t time, uint32_t button,
+ uint32_t state)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wthp_pointer_send_button (pointer->obj, serial, time, button, state);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_pointer_axis(struct window *window, uint32_t time,
+ uint32_t axis, wl_fixed_t value)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wthp_pointer_send_axis (pointer->obj, time, axis, value);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+/*
+ * waltham pointer implementation
+ */
+static void
+pointer_set_cursor(struct wthp_pointer *wthp_pointer, int32_t serial, struct wthp_surface *surface,
+ int32_t hotspot_x, int32_t hotspot_y)
+{
+ struct pointer *pointer = wth_object_get_user_data((struct wth_object *)wthp_pointer);
+
+ wth_verbose("wthp_pointer %p (%d, %p, %d, %d)\n",
+ wthp_pointer, serial, surface, hotspot_x, hotspot_y);
+
+}
+
+static void
+pointer_release(struct wthp_pointer *wthp_pointer)
+{
+ struct pointer *pointer = wth_object_get_user_data((struct wth_object *)wthp_pointer);
+
+ wth_verbose("wthp_pointer %p\n",wthp_pointer);
+}
+
+static const struct wthp_pointer_interface pointer_implementation = {
+ pointer_set_cursor,
+ pointer_release
+};
+
+/*
+ * APIs to send touch events to waltham client
+ */
+
+void
+waltham_touch_down(struct window *window, uint32_t serial,
+ uint32_t time, int32_t id,
+ wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wth_verbose("touch_handle_down surface [%d]\n", surface->ivi_id);
+ wthp_touch_send_down(touch->obj, serial, time, surface->obj, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_touch_up(struct window *window, uint32_t serial,
+ uint32_t time, int32_t id)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wthp_touch_send_up(touch->obj, serial, time, id);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_touch_motion(struct window *window, uint32_t time,
+ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wthp_touch_send_motion(touch->obj, time, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_touch_frame(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wthp_touch_send_frame(touch->obj);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_touch_cancel(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wthp_touch_send_cancel(touch->obj);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+/*
+ * waltham touch implementation
+ */
+static void
+touch_release(struct wthp_touch *wthp_touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct touch *touch = wth_object_get_user_data((struct wth_object *)wthp_touch);
+
+ wth_verbose("%p\n",wthp_touch);
+}
+
+static const struct wthp_touch_interface touch_implementation = {
+ touch_release,
+};
+
+/*
+ * waltham seat implementation
+ */
+static void
+seat_get_pointer(struct wthp_seat *wthp_seat, struct wthp_pointer *wthp_pointer)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("wthp_seat %p get_pointer(%p)\n",
+ wthp_seat, wthp_pointer);
+
+ struct seat *seat = wth_object_get_user_data((struct wth_object *)wthp_seat);
+ struct pointer *pointer;
+
+ pointer = zalloc(sizeof *pointer);
+ if (!pointer) {
+ client_post_out_of_memory(seat->client);
+ return;
+ }
+
+ pointer->obj = wthp_pointer;
+ pointer->seat = seat;
+ seat->pointer = pointer;
+ wl_list_insert(&seat->client->pointer_list, &pointer->link);
+
+ wthp_pointer_set_interface(wthp_pointer, &pointer_implementation, pointer);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+seat_get_touch(struct wthp_seat *wthp_seat, struct wthp_touch *wthp_touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("wthp_seat %p get_touch(%p)\n",
+ wthp_seat, wthp_touch);
+
+ struct seat *seat = wth_object_get_user_data((struct wth_object *)wthp_seat);
+ struct touch *touch;
+
+ touch = zalloc(sizeof *touch);
+ if (!touch) {
+ client_post_out_of_memory(seat->client);
+ return;
+ }
+
+ touch->obj = wthp_touch;
+ touch->seat = seat;
+ seat->touch = touch;
+ wl_list_insert(&seat->client->touch_list, &touch->link);
+
+ wthp_touch_set_interface(wthp_touch, &touch_implementation, touch);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+seat_release(struct wthp_seat *wthp_seat)
+{
+}
+
+static const struct wthp_seat_interface seat_implementation = {
+ seat_get_pointer,
+ NULL,
+ seat_get_touch,
+ seat_release,
+ NULL
+};
+
+static void
+seat_send_updated_caps(struct seat *seat)
+{
+ wth_verbose("%s >>> \n",__func__);
+ enum wthp_seat_capability caps = 0;
+
+ caps |= WTHP_SEAT_CAPABILITY_POINTER;
+ wth_verbose("WTHP_SEAT_CAPABILITY_POINTER %d\n", caps);
+
+ caps |= WTHP_SEAT_CAPABILITY_TOUCH;
+ wth_verbose("WTHP_SEAT_CAPABILITY_TOUCH %d\n", caps);
+
+ wthp_seat_send_capabilities(seat->obj, caps);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+client_bind_seat(struct client *c, struct wthp_seat *obj)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat;
+
+ seat = zalloc(sizeof *seat);
+ if (!seat) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ seat->obj = obj;
+ seat->client = c;
+ wl_list_insert(&c->seat_list, &seat->link);
+ wth_verbose("wthp_seat object=%p and seat=%p\n",obj,seat);
+ wthp_seat_set_interface(obj, &seat_implementation,
+ seat);
+ wth_verbose("client %p bound wthp_seat\n", c);
+ seat_send_updated_caps(seat);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * waltham region implementation
+ */
+
+static void
+region_destroy(struct region *region)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("region %p destroy\n", region->obj);
+
+ wthp_region_free(region->obj);
+ wl_list_remove(&region->link);
+ free(region);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+region_handle_destroy(struct wthp_region *wthp_region)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct region *region = wth_object_get_user_data((struct wth_object *)wthp_region);
+
+ assert(wthp_region == region->obj);
+
+ region_destroy(region);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+region_handle_add(struct wthp_region *wthp_region,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ wth_verbose("region %p add(%d, %d, %d, %d)\n",
+ wthp_region, x, y, width, height);
+}
+
+static void
+region_handle_subtract(struct wthp_region *wthp_region,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
+{
+ wth_verbose("region %p subtract(%d, %d, %d, %d)\n",
+ wthp_region, x, y, width, height);
+}
+
+static const struct wthp_region_interface region_implementation = {
+ region_handle_destroy,
+ region_handle_add,
+ region_handle_subtract
+};
+
+/*
+ * waltham compositor implementation
+ */
+static void
+compositor_destroy(struct compositor *comp)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("%s: %p\n", __func__, comp->obj);
+
+ wthp_compositor_free(comp->obj);
+ wl_list_remove(&comp->link);
+ free(comp);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+compositor_handle_create_surface(struct wthp_compositor *compositor,
+ struct wthp_surface *id)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct compositor *comp = wth_object_get_user_data((struct wth_object *)compositor);
+ struct client *client = comp->client;
+ struct surface *surface;
+ struct seat *seat, *tmp;
+
+ wth_verbose("client %p create surface %p\n",
+ comp->client, id);
+
+ surface = zalloc(sizeof *surface);
+ if (!surface) {
+ client_post_out_of_memory(comp->client);
+ return;
+ }
+
+ surface->obj = id;
+ wl_list_insert(&comp->client->surface_list, &surface->link);
+
+ wthp_surface_set_interface(id, &surface_implementation, surface);
+
+ surface->shm_window = calloc(1, sizeof *surface->shm_window);
+ if (!surface->shm_window)
+ return;
+
+ surface->shm_window->server_surf = surface;
+ surface->shm_window->ready = false;
+ surface->ivi_id = 0;
+
+ wl_list_for_each_safe(seat, tmp, &client->seat_list, link) {
+ surface->shm_window->server_seat = seat;
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+compositor_handle_create_region(struct wthp_compositor *compositor,
+ struct wthp_region *id)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct compositor *comp = wth_object_get_user_data((struct wth_object *)compositor);
+ struct region *region;
+
+ wth_verbose("client %p create region %p\n",
+ comp->client, id);
+
+ region = zalloc(sizeof *region);
+ if (!region) {
+ client_post_out_of_memory(comp->client);
+ return;
+ }
+
+ region->obj = id;
+ wl_list_insert(&comp->client->region_list, &region->link);
+
+ wthp_region_set_interface(id, &region_implementation, region);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wthp_compositor_interface compositor_implementation = {
+ compositor_handle_create_surface,
+ compositor_handle_create_region
+};
+
+static void
+client_bind_compositor(struct client *c, struct wthp_compositor *obj)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct compositor *comp;
+
+ comp = zalloc(sizeof *comp);
+ if (!comp) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ comp->obj = obj;
+ comp->client = c;
+ wl_list_insert(&c->compositor_list, &comp->link);
+
+ wthp_compositor_set_interface(obj, &compositor_implementation,
+ comp);
+ wth_verbose("client %p bound wthp_compositor\n", c);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * waltham registry implementation
+ */
+static void
+registry_destroy(struct registry *reg)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("%s: %p\n", __func__, reg->obj);
+
+ wthp_registry_free(reg->obj);
+ wl_list_remove(&reg->link);
+ free(reg);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+registry_handle_destroy(struct wthp_registry *registry)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct registry *reg = wth_object_get_user_data((struct wth_object *)registry);
+
+ registry_destroy(reg);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+registry_handle_bind(struct wthp_registry *registry,
+ uint32_t name,
+ struct wth_object *id,
+ const char *interface,
+ uint32_t version)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct registry *reg = wth_object_get_user_data((struct wth_object *)registry);
+ wth_verbose("Recieved registry : %s\n", interface);
+
+ if (strcmp(interface, "wthp_compositor") == 0) {
+ client_bind_compositor(reg->client, (struct wthp_compositor *)id);
+ } else if (strcmp(interface, "wthp_blob_factory") == 0) {
+ client_bind_blob_factory(reg->client, (struct wthp_blob_factory *)id);
+ struct client *client = reg->client;
+ struct seat *seat, *tmp,*get_seat;
+ wl_list_for_each_safe(seat, tmp, &client->seat_list, link) {
+ get_seat = seat;
+ }
+ wth_verbose("get_seat : %p\n", get_seat);
+ seat_send_updated_caps(get_seat);
+ } else if (strcmp(interface, "wthp_ivi_application") == 0) {
+ client_bind_wthp_ivi_application(reg->client, (struct wthp_ivi_application *)id);
+ } else if (strcmp(interface, "wthp_seat") == 0) {
+ client_bind_seat(reg->client, (struct wthp_seat *)id);
+ } else {
+ wth_object_post_error((struct wth_object *)registry, 0,
+ "%s: unknown name %u", __func__, name);
+ wth_object_delete(id);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wthp_registry_interface registry_implementation = {
+ registry_handle_destroy,
+ registry_handle_bind
+};
+
+/*
+ * waltham display implementation
+ */
+
+static void
+display_handle_client_version(struct wth_display *wth_display,
+ uint32_t client_version)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_object_post_error((struct wth_object *)wth_display, 0,
+ "unimplemented: %s", __func__);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+display_handle_sync(struct wth_display * wth_display, struct wthp_callback * callback)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c = wth_object_get_user_data((struct wth_object *)wth_display);
+
+ wth_verbose("Client %p requested wth_display.sync\n", c);
+ wthp_callback_send_done(callback, 0);
+ wthp_callback_free(callback);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+display_handle_get_registry(struct wth_display *wth_display,
+ struct wthp_registry *registry)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c = wth_object_get_user_data((struct wth_object *)wth_display);
+ struct registry *reg;
+
+ reg = zalloc(sizeof *reg);
+ if (!reg) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ reg->obj = registry;
+ reg->client = c;
+ wl_list_insert(&c->registry_list, &reg->link);
+ wthp_registry_set_interface(registry,
+ &registry_implementation, reg);
+
+ wthp_registry_send_global(registry, 1, "wthp_compositor", 4);
+ wthp_registry_send_global(registry, 1, "wthp_ivi_application", 1);
+ wthp_registry_send_global(registry, 1, "wthp_seat", 4);
+ wthp_registry_send_global(registry, 1, "wthp_blob_factory", 4);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+const struct wth_display_interface display_implementation = {
+ display_handle_client_version,
+ display_handle_sync,
+ display_handle_get_registry
+};
+
+/*
+ * functions to handle waltham client connections
+ */
+static void
+connection_handle_data(struct watch *w, uint32_t events)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c = container_of(w, struct client, conn_watch);
+ int ret;
+
+ if (events & EPOLLERR) {
+ wth_error("Client %p errored out.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+
+ if (events & EPOLLHUP) {
+ wth_error("Client %p hung up.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+
+ if (events & EPOLLOUT) {
+ ret = wth_connection_flush(c->connection);
+ if (ret == 0)
+ watch_ctl(&c->conn_watch, EPOLL_CTL_MOD, EPOLLIN);
+ else if (ret < 0 && errno != EAGAIN){
+ wth_error("Client %p flush error.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+ }
+
+ if (events & EPOLLIN) {
+ ret = wth_connection_read(c->connection);
+ if (ret < 0) {
+ wth_error("Client %p read error.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+
+ ret = wth_connection_dispatch(c->connection);
+ if (ret < 0 && errno != EPROTO) {
+ wth_error("Client %p dispatch error.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/**
+* client_create
+*
+* Create new client connection
+*
+* @param srv Server structure
+* @param wth_connection Waltham connection handle
+* @return Pointer to client structure
+*/
+static struct client *
+client_create(struct server *srv, struct wth_connection *conn)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c;
+ struct wth_display *disp;
+
+ c = zalloc(sizeof *c);
+ if (!c)
+ return NULL;
+
+ c->server = srv;
+ c->connection = conn;
+
+ c->conn_watch.server = srv;
+ c->conn_watch.fd = wth_connection_get_fd(conn);
+ c->conn_watch.cb = connection_handle_data;
+ if (watch_ctl(&c->conn_watch, EPOLL_CTL_ADD, EPOLLIN) < 0) {
+ free(c);
+ return NULL;
+ }
+
+ wth_verbose("Client %p connected.\n", c);
+
+ wl_list_insert(&srv->client_list, &c->link);
+
+ wl_list_init(&c->registry_list);
+ wl_list_init(&c->compositor_list);
+ wl_list_init(&c->seat_list);
+ wl_list_init(&c->pointer_list);
+ wl_list_init(&c->touch_list);
+ wl_list_init(&c->region_list);
+ wl_list_init(&c->surface_list);
+ wl_list_init(&c->buffer_list);
+
+ disp = wth_connection_get_display(c->connection);
+ wth_display_set_interface(disp, &display_implementation, c);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return c;
+}
+
+/**
+* client_destroy
+*
+* Destroy client connection
+*
+* @param names struct client *c
+* @param value client data
+* @return none
+*/
+void
+client_destroy(struct client *c)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct region *region;
+ struct compositor *comp;
+ struct registry *reg;
+ struct surface *surface;
+
+ wth_verbose("Client %p disconnected.\n", c);
+
+ /* clean up remaining client resources in case the client
+ * did not.
+ */
+ wl_list_last_until_empty(region, &c->region_list, link)
+ region_destroy(region);
+
+ wl_list_last_until_empty(comp, &c->compositor_list, link)
+ compositor_destroy(comp);
+
+ wl_list_last_until_empty(reg, &c->registry_list, link)
+ registry_destroy(reg);
+
+ wl_list_last_until_empty(surface, &c->surface_list, link)
+ surface_destroy(surface);
+
+ wl_list_remove(&c->link);
+ watch_ctl(&c->conn_watch, EPOLL_CTL_DEL, 0);
+ wth_connection_destroy(c->connection);
+ free(c);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/**
+* server_flush_clients
+*
+* write all the pending requests from the clients to socket
+*
+* @param names struct server *srv
+* @param value socket connection info and client data
+* @return none
+*/
+void
+server_flush_clients(struct server *srv)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c, *tmp;
+ int ret;
+
+ wl_list_for_each_safe(c, tmp, &srv->client_list, link) {
+ /* Flush out buffered requests. If the Waltham socket is
+ * full, poll it for writable too.
+ */
+ ret = wth_connection_flush(c->connection);
+ if (ret < 0 && errno == EAGAIN) {
+ watch_ctl(&c->conn_watch, EPOLL_CTL_MOD, EPOLLIN | EPOLLOUT);
+ } else if (ret < 0) {
+ perror("Connection flush failed");
+ client_destroy(c);
+ return;
+ }
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+
+}
+
+/**
+* server_accept_client
+*
+* Accepts new waltham client connection and instantiates client structure
+*
+* @param names struct server *srv
+* @param value socket connection info and client data
+* @return none
+*/
+void
+server_accept_client(struct server *srv)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *client;
+ struct wth_connection *conn;
+ struct sockaddr_in addr;
+ socklen_t len;
+
+ len = sizeof addr;
+ conn = wth_accept(srv->listen_fd, (struct sockaddr *)&addr, &len);
+ if (!conn) {
+ wth_error("Failed to accept a connection.\n");
+ return;
+ }
+
+ client = client_create(srv, conn);
+ if (!client) {
+ wth_error("Failed client_create().\n");
+ return;
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}