* SOFTWARE.
*/
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
+#include <time.h>
-#include <pepper.h>
+#include <dlog.h>
#include <tbm_bufmgr.h>
+#include <wayland-server.h>
+#include <libds/compositor.h>
+#include <libds/surface.h>
+#include <libds-tizen/tbm_server.h>
+
#include <headless_server.h>
+typedef struct headless_server headless_server_t;
+
+typedef struct headless_view headless_view_t;
+
+struct headless_server
+{
+ struct wl_display *display;
+ struct ds_compositor *compositor;
+ struct ds_tbm_server *tbm_server;
+
+ led_output_t *output;
+ headless_shell_t *shell;
+
+ headless_view_t *focus_view;
+ headless_view_t *top_view;
+
+ struct wl_event_source *sigint_source;
+ struct wl_event_source *idle_source;
+
+ const char *name;
+
+ struct wl_listener new_shell_surface;
+
+ struct wl_list views; // headless_view::link
+
+ bool boot_animating;
+};
+
+struct headless_view
+{
+ headless_server_t *server;
+ headless_shell_surface_t *shell_surface;
+ struct ds_surface *surface;
+ struct ds_buffer *buffer;
+
+ struct wl_listener shell_surface_destroy;
+ struct wl_listener commit;
+ struct wl_listener map;
+ struct wl_listener unmap;
+ struct wl_listener request_activate;
+ struct wl_listener set_skip_focus;
+ struct wl_listener unset_skip_focus;
+
+ struct wl_list link; // headless_server::views
+
+ bool mapped;
+ bool skip_focus;
+};
+
int use_output = 1;
+static void server_handle_new_shell_surface(struct wl_listener *listener, void *data);
+
static int
handle_sigint(int signal_number, void *data)
{
return 0;
}
-static pepper_bool_t
-init_signal(pepper_compositor_t *compositor)
+static bool
+init_signal(struct wl_display *display)
{
- struct wl_display *display;
struct wl_event_loop *loop;
struct wl_event_source *sigint;
- display = pepper_compositor_get_display(compositor);
loop = wl_display_get_event_loop(display);
sigint = wl_event_loop_add_signal(loop, SIGINT, handle_sigint, display);
if (!sigint)
- return PEPPER_FALSE;
+ return false;
+
+ return true;
+}
+
+static int
+dlog_level_from_ds_log_level(enum ds_log_level level)
+{
+ switch (level) {
+ case DS_INF:
+ return DLOG_INFO;
+ case DS_DBG:
+ return DLOG_DEBUG;
+ default:
+ case DS_ERR:
+ return DLOG_ERROR;
+ }
+}
- return PEPPER_TRUE;
+static void
+handle_ds_log(enum ds_log_level level, const char *fmt, va_list args)
+{
+ dlog_vprint(dlog_level_from_ds_log_level(level), "HEADLESS_SERVER",
+ fmt, args);
}
int main(int argc, char *argv[])
{
+ headless_server_t server = { 0, };
const char *socket_name = NULL;
- pepper_compositor_t *compositor = NULL;
- pepper_bool_t ret;
+ bool ret;
tbm_bufmgr bufmgr = NULL;
/* set STDOUT/STDERR bufferless */
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
- if (getenv("PEPPER_DLOG_ENABLE")) {
- PEPPER_TRACE("pepper log will be written to dlog !\n");
- pepper_log_dlog_enable(1);
+ if (getenv("HEADLESS_SERVER_DLOG_ENABLE")) {
+ HEADLESS_TRACE("ds log will be written to dlog !\n");
+ ds_log_init(DS_INF, handle_ds_log);
}
socket_name = getenv("WAYLAND_DISPLAY");
use_output = 0;
}
- /* create pepper compositir */
- compositor = pepper_compositor_create(socket_name, NULL);
- PEPPER_CHECK(compositor, return EXIT_FAILURE, "Failed to create compositor !");
+ server.display = wl_display_create();
+ if (!server.display) {
+ ds_err("Could not create wl_display");
+ return EXIT_FAILURE;
+ }
+ wl_list_init(&server.views);
+
+ server.compositor = ds_compositor_create(server.display);
+ HEADLESS_CHECK(server.compositor, goto end, "Failed to create ds_compositor");
+
+ server.tbm_server = ds_tbm_server_create(server.display);
+ HEADLESS_CHECK(server.tbm_server, goto end, "Failed to create ds_tbm_server");
+
+#ifndef DISABLE_INPUT
/* Init event trace */
ret = headless_debug_init(compositor);
- PEPPER_CHECK(ret, goto end, "headless_debug_init() failed\n");
+ HEADLESS_CHECK(ret, goto end, "headless_debug_init() failed\n");
/* Init input for headless */
ret = headless_input_init(compositor);
- PEPPER_CHECK(ret, goto end, "headless_input_init() failed\n");
+ HEADLESS_CHECK(ret, goto end, "headless_input_init() failed\n");
+#endif
/* Init Output */
if(use_output)
{
- ret = headless_output_init(compositor);
- PEPPER_CHECK(ret, goto end, "headless_output_init() failed.\n");
+ server.output = headless_output_create(server.display);
+ HEADLESS_CHECK(server.output, goto end, "headless_output_create() failed.");
+
+ headless_output_start_boot_ani(server.output);
+ server.boot_animating = true;
}
else {
bufmgr = tbm_bufmgr_server_init();
- PEPPER_CHECK(bufmgr, goto end, "Failed to init tbm buffer manager !\n");
- ret = tbm_bufmgr_bind_native_display(bufmgr, (void *)pepper_compositor_get_display(compositor));
- PEPPER_CHECK(ret, goto end, "Failed to bind native display with tbm buffer manager !\n");
+ HEADLESS_CHECK(bufmgr, goto end, "Failed to init tbm buffer manager !\n");
+ ret = tbm_bufmgr_bind_native_display(bufmgr, (void *)server.display);
+ HEADLESS_CHECK(ret, goto end, "Failed to bind native display with tbm buffer manager !\n");
}
/* Init Shell */
- ret = headless_shell_init(compositor);
- PEPPER_CHECK(ret, goto end, "headless_shell_init() failed.\n");
+ server.shell = headless_shell_create(server.display);
+ HEADLESS_CHECK(server.shell, goto end, "headless_shell_create() failed.\n");
+
+ server.new_shell_surface.notify = server_handle_new_shell_surface;
+ headless_shell_add_new_surface_listener(server.shell, &server.new_shell_surface);
/* Init Signal for SIGINT */
- init_signal(compositor);
+ init_signal(server.display);
+
+ server.name = wl_display_add_socket_auto(server.display);
+ HEADLESS_CHECK(server.name, goto end, "Could not add socket for wayland");
+
+ setenv("WAYLAND_DISPLAY", server.name, true);
+
+ ds_inf("Running headless server on WAYLAND_DISPLAY=%s", server.name);
/* run event loop */
- wl_display_run(pepper_compositor_get_display(compositor));
+ wl_display_run(server.display);
end:
/* Deinit Process */
- headless_shell_deinit(compositor);
- headless_input_deinit(compositor);
- if(use_output)
- headless_output_deinit(compositor);
+ if (server.shell)
+ headless_shell_destroy(server.shell);
+
+ if(use_output && server.output)
+ headless_output_destroy(server.output);
if (bufmgr)
{
tbm_bufmgr_deinit(bufmgr);
bufmgr = NULL;
}
+
+#ifndef DISABLE_INPUT
+ headless_input_deinit(compositor);
headless_debug_deinit(compositor);
- pepper_compositor_destroy(compositor);
+#endif
+
+ wl_display_destroy_clients(server.display);
+ wl_display_destroy(server.display);
return EXIT_SUCCESS;
}
+
+static void
+server_schedule_idle_task(headless_server_t *server);
+static void
+server_set_focus_view(headless_server_t *server, headless_view_t *view);
+static void
+server_set_top_view(headless_server_t *server, headless_view_t *view);
+
+static void
+destroy_view(headless_view_t *view)
+{
+ ds_inf("view(%p) destroyed", view);
+
+ wl_list_remove(&view->commit.link);
+ wl_list_remove(&view->map.link);
+ wl_list_remove(&view->unmap.link);
+ wl_list_remove(&view->request_activate.link);
+ wl_list_remove(&view->set_skip_focus.link);
+ wl_list_remove(&view->unset_skip_focus.link);
+ wl_list_remove(&view->link);
+
+ free(view);
+}
+
+static void
+view_handle_shell_surface_destroy(struct wl_listener *listener, void *data)
+{
+ headless_view_t *view;
+ headless_server_t *server;
+
+ view = wl_container_of(listener, view, shell_surface_destroy);
+ server = view->server;
+
+ if (server->top_view == view)
+ server_set_top_view(server, NULL);
+
+ if (server->focus_view == view)
+ server_set_focus_view(server, NULL);
+
+ server_schedule_idle_task(server);
+
+ destroy_view(view);
+}
+
+static void
+view_handle_surface_commit(struct wl_listener *listener, void *data)
+{
+ headless_view_t *view;
+
+ view = wl_container_of(listener, view, commit);
+ view->buffer = ds_surface_get_buffer(view->surface);
+
+ server_schedule_idle_task(view->server);
+}
+
+static void
+view_handle_shell_surface_map(struct wl_listener *listener, void *data)
+{
+ headless_view_t *view;
+
+ view = wl_container_of(listener, view, map);
+ view->mapped = true;
+
+ server_schedule_idle_task(view->server);
+}
+
+static void
+view_handle_shell_surface_unmap(struct wl_listener *listener, void *data)
+{
+ headless_view_t *view;
+
+ view = wl_container_of(listener, view, unmap);
+ view->mapped = false;
+
+ server_schedule_idle_task(view->server);
+}
+
+static void
+view_handle_request_activate(struct wl_listener *listener, void *data)
+{
+ headless_view_t *view;
+
+ view = wl_container_of(listener, view, request_activate);
+
+ wl_list_remove(&view->link);
+ wl_list_insert(&view->server->views, &view->link);
+
+ server_schedule_idle_task(view->server);
+}
+
+static void
+view_handle_shell_surface_set_skip_focus(struct wl_listener *listener,
+ void *data)
+{
+ headless_view_t *view;
+
+ view = wl_container_of(listener, view, set_skip_focus);
+ view->skip_focus = true;
+
+ server_schedule_idle_task(view->server);
+}
+
+static void
+view_handle_shell_surface_unset_skip_focus(struct wl_listener *listener,
+ void *data)
+{
+ headless_view_t *view;
+
+ view = wl_container_of(listener, view, unset_skip_focus);
+ view->skip_focus = false;
+
+ server_schedule_idle_task(view->server);
+}
+
+static bool
+create_view(headless_server_t *server, headless_shell_surface_t *shell_surface)
+{
+ headless_view_t *view;
+
+ view = calloc(1, sizeof *view);
+ if (!view)
+ return false;
+
+ view->server = server;
+ view->shell_surface = shell_surface;
+ view->surface = headless_shell_surface_get_surface(shell_surface);
+
+ view->shell_surface_destroy.notify = view_handle_shell_surface_destroy;
+ headless_shell_surface_add_destroy_listener(shell_surface,
+ &view->shell_surface_destroy);
+
+ view->commit.notify = view_handle_surface_commit;
+ ds_surface_add_commit_listener(view->surface, &view->commit);
+
+ view->map.notify = view_handle_shell_surface_map;
+ headless_shell_surface_add_map_listener(shell_surface, &view->map);
+
+ view->unmap.notify = view_handle_shell_surface_unmap;
+ headless_shell_surface_add_unmap_listener(shell_surface, &view->unmap);
+
+ view->request_activate.notify = view_handle_request_activate;
+ headless_shell_surface_add_request_activate_listener(shell_surface,
+ &view->request_activate);
+
+ view->set_skip_focus.notify = view_handle_shell_surface_set_skip_focus;
+ headless_shell_surface_add_set_skip_focus_listener(shell_surface,
+ &view->set_skip_focus);
+
+ view->unset_skip_focus.notify = view_handle_shell_surface_unset_skip_focus;
+ headless_shell_surface_add_unset_skip_focus_listener(shell_surface,
+ &view->unset_skip_focus);
+
+ wl_list_insert(&server->views, &view->link);
+
+ ds_inf("Create view(%p)", view);
+
+ return true;
+}
+
+static void
+server_handle_new_shell_surface(struct wl_listener *listener, void *data)
+{
+ headless_server_t *server;
+ headless_shell_surface_t *shell_surface = data;
+
+ server = wl_container_of(listener, server, new_shell_surface);
+
+ ds_inf("shell surface added, server(%p)", server);
+
+ if (server->boot_animating) {
+ server->boot_animating = false;
+ headless_output_stop_boot_ani(server->output);
+ }
+
+ HEADLESS_CHECK(create_view(server, shell_surface), return,
+ "Could not create headless_view");
+}
+
+static void
+server_set_focus_view(headless_server_t *server, headless_view_t *view)
+{
+ if (server->focus_view == view)
+ return;
+
+ server->focus_view = view;
+
+ // TODO handle input and debug
+}
+
+static void
+server_set_top_view(headless_server_t *server, headless_view_t *view)
+{
+ if (server->top_view == view)
+ return;
+
+ // TODO handle input and debug
+
+ if (server->top_view) {
+ headless_shell_send_visibility(server->top_view->shell_surface,
+ TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED);
+ }
+
+ if (view) {
+ headless_shell_send_visibility(view->shell_surface,
+ TIZEN_VISIBILITY_VISIBILITY_UNOBSCURED);
+ }
+
+ server->top_view = view;
+}
+
+static void
+server_repaint(headless_server_t *server)
+{
+ struct ds_surface *surface = NULL;
+ struct ds_buffer *buffer = NULL;
+ struct timespec now;
+ void *data = NULL;
+ uint32_t format;
+ size_t stride;
+ bool access = false;
+
+ if (server->top_view) {
+ surface = server->top_view->surface;
+ buffer = server->top_view->buffer;
+ }
+
+ if (buffer) {
+ access = ds_buffer_begin_data_ptr_access(buffer,
+ DS_BUFFER_DATA_PTR_ACCESS_READ, &data, &format, &stride);
+ if (!access)
+ ds_err("Could not access ds_buffer(%p)", buffer);
+ }
+
+ headless_output_update_led(server->output, data);
+
+ if (access)
+ ds_buffer_end_data_ptr_access(buffer);
+
+ if (surface) {
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ ds_surface_send_frame_done(surface, &now);
+ }
+}
+
+static void
+idle_task(void *data)
+{
+ headless_server_t *server = data;
+ headless_view_t *view, *focus_view = NULL, *top_view = NULL;
+
+ server->idle_source = NULL;
+
+ /* This iterates over all our views and attemps to find focusable and
+ * visible views on the top. This relies on server->views being ordered
+ * from top-to-bottom. */
+ wl_list_for_each(view, &server->views, link) {
+ if (!view->mapped)
+ continue;
+
+ if (!top_view)
+ top_view = view;
+
+ if (!focus_view && !view->skip_focus)
+ focus_view = view;
+
+ if (focus_view && top_view)
+ break;
+ }
+
+ server_set_focus_view(server, focus_view);
+ server_set_top_view(server, top_view);
+ server_repaint(server);
+}
+
+static void
+server_schedule_idle_task(headless_server_t *server)
+{
+ if (server->idle_source)
+ return;
+
+ server->idle_source =
+ wl_event_loop_add_idle(wl_display_get_event_loop(server->display),
+ idle_task, server);
+}
* DEALINGS IN THE SOFTWARE.
*/
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <tbm_bufmgr.h>
-#include <wayland-tbm-server.h>
-#include <pepper-output-backend.h>
+#include "headless_server.h"
#include "HL_UI_LED.h"
#include "output_internal.h"
-static const int KEY_OUTPUT;
-static void led_output_add_frame_done(led_output_t *output);
-static void led_output_update(led_output_t *output);
-
-static void
-led_output_destroy(void *data)
+led_output_t *
+headless_output_create(struct wl_display *display)
{
- led_output_t *output = (led_output_t *)data;
- PEPPER_TRACE("Output Destroy %p base %p\n", output, output->output);
+ led_output_t *output = (led_output_t*)calloc(sizeof(led_output_t), 1);
- if (output->ui_led) {
- HL_UI_LED_Close(output->ui_led);
- output->ui_led = NULL;
- }
+ HEADLESS_TRACE("Output Init\n");
- if (output->tbm_server) {
- wayland_tbm_server_deinit(output->tbm_server);
- output->tbm_server = NULL;
+ if (!output) {
+ HEADLESS_ERROR("Failed to allocate memory in %s\n", __FUNCTION__);
+ return false;
}
-}
-
-static int32_t
-led_output_get_subpixel_order(void *o)
-{
- return 0;
-}
-
-static const char *
-led_output_get_maker_name(void *o)
-{
- return "PePPer LED";
-}
-
-static const char *
-led_output_get_model_name(void *o)
-{
- return "PePPer LED";
-}
-
-static int
-led_output_get_mode_count(void *o)
-{
- return 1;
-}
-static void
-led_output_get_mode(void *o, int index, pepper_output_mode_t *mode)
-{
- led_output_t *output = (led_output_t *)o;
+ output->display = display;
- PEPPER_TRACE("[OUTPUT]\n");
+ // FIXME Should we create wl_global for wl_output?
- if (index != 0)
- return;
+ output->num_led = NUM_LED;
+ output->ui_led = HL_UI_LED_Init(output->num_led);
+ if (output->ui_led) HL_UI_LED_Change_Brightness(output->ui_led, 0x1);
- mode->flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
- mode->w = output->num_led;
- mode->h = output->num_led;
- mode->refresh = 60000;
-}
+ if (!output->ui_led)
+ HEADLESS_ERROR("HL_UI_LED_Init() failed.\n");
-static pepper_bool_t
-led_output_set_mode(void *o, const pepper_output_mode_t *mode)
-{
- return PEPPER_FALSE;
+ return output;
}
-static void
-led_output_assign_planes(void *o, const pepper_list_t *view_list)
+void
+headless_output_destroy(led_output_t *output)
{
- led_output_t *output = (led_output_t *)o;
- pepper_list_t *l;
- pepper_view_t *view, *top_view = NULL;
-
- PEPPER_TRACE("[OUTPUT] Assign plane\n");
- pepper_list_for_each_list(l, view_list) {
- view = (pepper_view_t*)l->item;
+ HEADLESS_TRACE("Output Destroy %p", output);
- if (pepper_view_is_mapped(view) && pepper_view_is_visible(view)) {
- top_view = view;
- break;
- }
+ if (output->boot_ani) {
+ boot_ani_stop(output);
}
- if (output->top_view != top_view)
- PEPPER_TRACE("\tTop-View is changed(%p -> %p)\n", output->top_view, top_view);
-
- output->top_view = top_view;
-}
-
-static void
-led_output_start_repaint_loop(void *o)
-{
- led_output_t *output = (led_output_t *)o;
- struct timespec ts;
-
- PEPPER_TRACE("[OUTPUT] Start reapint loop\n");
- pepper_compositor_get_time(output->compositor, &ts);
- pepper_output_finish_frame(output->output, &ts);
-}
-
-static void
-led_output_repaint(void *o, const pepper_list_t *plane_list)
-{
- pepper_list_t *l;
- pepper_plane_t *plane;
- led_output_t *output = (led_output_t *)o;
-
- PEPPER_TRACE("[OUTPUT] Repaint\n");
-
- pepper_list_for_each_list(l, plane_list) {
- plane = (pepper_plane_t *)l->item;
- pepper_plane_clear_damage_region(plane);
+ if (output->ui_led) {
+ HL_UI_LED_Close(output->ui_led);
+ output->ui_led = NULL;
}
- led_output_update(output);
- led_output_add_frame_done(output);
-}
+ free(output);
-static void
-led_output_attach_surface(void *o, pepper_surface_t *surface, int *w, int *h)
-{
- *w = 10;
- *h = 10;
- PEPPER_TRACE("[OUTPUT] attach surface:%p\n", surface);
+ HEADLESS_TRACE("Output Destroy... DONE\n");
}
-static void
-led_output_flush_surface_damage(void *o, pepper_surface_t *surface, pepper_bool_t *keep_buffer)
-{
- *keep_buffer = PEPPER_TRUE;
- PEPPER_TRACE("[OUTPUT] flush_surface_damage surface:%p\n", surface);
-}
-
-struct pepper_output_backend led_output_backend = {
- led_output_destroy,
-
- led_output_get_subpixel_order,
- led_output_get_maker_name,
- led_output_get_model_name,
-
- led_output_get_mode_count,
- led_output_get_mode,
- led_output_set_mode,
-
- led_output_assign_planes,
- led_output_start_repaint_loop,
- led_output_repaint,
- led_output_attach_surface,
- led_output_flush_surface_damage,
-};
-
-static void
-led_output_update_led(led_output_t *output, unsigned char *data)
+void
+headless_output_update_led(led_output_t *output, unsigned char *data)
{
int i;
uint8_t *ptr = (uint8_t *)data;
if (data == NULL) {
- PEPPER_TRACE("[OUTPUT] update LED to empty\n");
+ HEADLESS_TRACE("[OUTPUT] update LED to empty\n");
HL_UI_LED_Clear_All(output->ui_led);
return;
}
HL_UI_LED_Refresh(output->ui_led);
}
-static void
-led_output_update(led_output_t *output)
-{
- pepper_buffer_t *buf;
- pepper_surface_t *surface;
- struct wl_resource *buf_res;
- tbm_surface_h tbm_surface;
- tbm_surface_info_s info;
- int ret;
-
- if (!output->top_view) {
- if (!output->ui_led)
- PEPPER_TRACE("[UPDATE LED] Empty Display\n");
- else
- led_output_update_led(output, NULL);
-
- return;
- }
-
- surface = pepper_view_get_surface(output->top_view);
- PEPPER_CHECK(surface, return, "fail to get a surafce from a view(%p)\n", output->top_view);
-
- buf = pepper_surface_get_buffer(surface);
- PEPPER_CHECK(buf, return, "fail to get a pepper_buffer from a surface(%p)\n", surface);
-
- buf_res = pepper_buffer_get_resource(buf);
- tbm_surface = wayland_tbm_server_get_surface(NULL, buf_res);
- PEPPER_CHECK(tbm_surface, return, "fail to get a tbm_surface from a pepper_buffer(%p)\n", buf);
-
- ret = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info);
- PEPPER_CHECK(ret == TBM_SURFACE_ERROR_NONE, return, "fail to map the tbm_surface\n");
-
- if (!output->ui_led)
- PEPPER_TRACE("[UPDATE LED] %s\n", (char*)info.planes[0].ptr);
- else
- led_output_update_led(output, info.planes[0].ptr);
-
- tbm_surface_unmap(tbm_surface);
-}
-
-static void
-led_output_cb_frame_done(void *data)
-{
- led_output_t *output = (led_output_t *)data;
-
- PEPPER_TRACE("[OUTPUT] frame_done %p\n", output);
- output->frame_done = NULL;
-
- pepper_output_finish_frame(output->output, NULL);
-}
-
-static void
-led_output_add_frame_done(led_output_t *output)
+void
+headless_output_start_boot_ani(led_output_t *output)
{
- struct wl_event_loop *loop;
-
- if (!output || output->frame_done) {
- PEPPER_TRACE("[OUTPUT] skip add frame_done\n");
+ if (output->boot_ani)
return;
- }
-
- PEPPER_TRACE("[OUTPUT] Add idle for frame(output:%p, frame_done:%p)\n", output, output->frame_done);
-
- loop = wl_display_get_event_loop(pepper_compositor_get_display(output->compositor));
- PEPPER_CHECK(loop, return, "[OUTPUT] fail to get event loop\n");
-
- output->frame_done = wl_event_loop_add_idle(loop, led_output_cb_frame_done, output);
- PEPPER_CHECK(output->frame_done, return, "[OUTPUT] fail to add idle\n");
-}
-
-static void
-pepper_output_bind_display(led_output_t *output)
-{
- tbm_bufmgr bufmgr = NULL;
-
- PEPPER_CHECK(getenv("TBM_DISPLAY_SERVER"), return, "[TBM] run the subcompoitor mode\n");
-
- bufmgr = wayland_tbm_server_get_bufmgr(output->tbm_server);
- PEPPER_CHECK(bufmgr, return, "fail to get tbm_bufmgr\n");
-
- if (!tbm_bufmgr_bind_native_display(bufmgr, (void *)pepper_compositor_get_display(output->compositor)))
- {
- PEPPER_CHECK(0, return, "fail to tbm_bufmgr_bind_native_display\n");
- }
-
- return;
-}
-
-pepper_bool_t
-headless_output_init(pepper_compositor_t *compositor)
-{
- led_output_t *output = (led_output_t*)calloc(sizeof(led_output_t), 1);
-
- PEPPER_TRACE("Output Init\n");
-
- if (!output) {
- PEPPER_ERROR("Failed to allocate memory in %s\n", __FUNCTION__);
- return PEPPER_FALSE;
- }
-
- output->compositor = compositor;
- output->tbm_server = wayland_tbm_server_init(pepper_compositor_get_display(compositor), NULL, -1, 0);
- PEPPER_CHECK(output->tbm_server, goto error, "failed to wayland_tbm_server_init.\n");
-
- pepper_output_bind_display(output);
-
- output->num_led = NUM_LED;
- output->ui_led = HL_UI_LED_Init(output->num_led);
- if (output->ui_led) HL_UI_LED_Change_Brightness(output->ui_led, 0x1);
-
- if (!output->ui_led)
- PEPPER_ERROR("HL_UI_LED_Init() failed.\n");
- else
- boot_ani_start(output);
-
- output->output = pepper_compositor_add_output(compositor,
- &led_output_backend, "led_output",
- output, WL_OUTPUT_TRANSFORM_NORMAL, 1);
- PEPPER_CHECK(output->output, goto error, "pepper_compositor_add_output() failed.\n");
- output->plane = pepper_output_add_plane(output->output, NULL);
- PEPPER_CHECK(output->plane, goto error, "pepper_output_add_plane() failed.\n");
-
- pepper_object_set_user_data((pepper_object_t *)compositor,
- &KEY_OUTPUT, output, NULL);
- PEPPER_TRACE("\t Add Output %p, base %p\n", output, output->output);
- PEPPER_TRACE("\t Add Output %p, plane %p\n", output, output->plane);
- PEPPER_TRACE("\t Userdata %p\n", pepper_object_get_user_data((pepper_object_t *)compositor,&KEY_OUTPUT));
- return PEPPER_TRUE;
-
-error:
- if (output->ui_led)
- HL_UI_LED_Close(output->ui_led);
-
- if (output->tbm_server)
- wayland_tbm_server_deinit(output->tbm_server);
-
- if (output->output)
- pepper_output_destroy(output->output);
-
- if (output)
- free(output);
- return PEPPER_FALSE;
+ boot_ani_start(output);
}
void
-headless_output_deinit(pepper_compositor_t *compositor)
+headless_output_stop_boot_ani(led_output_t *output)
{
- led_output_t *output;
-
-
- output = pepper_object_get_user_data((pepper_object_t *)compositor, &KEY_OUTPUT);
-
- if (output) {
- pepper_object_set_user_data((pepper_object_t *)compositor, &KEY_OUTPUT, NULL, NULL);
-
- if (output->boot_ani) {
- boot_ani_stop(output);
- }
-
- pepper_output_destroy(output->output);
- led_output_destroy(output);
-
- free(output);
- }
+ if (!output->boot_ani)
+ return;
- PEPPER_TRACE("Output Deinit ... DONE\n");
+ boot_ani_stop(output);
}
* DEALINGS IN THE SOFTWARE.
*/
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <pepper.h>
-#include <pepper-output-backend.h>
+#include <libds/surface.h>
#include <xdg-shell-unstable-v6-server-protocol.h>
-#include <tizen-extension-server-protocol.h>
#include "headless_server.h"
typedef struct HEADLESS_SHELL_SURFACE headless_shell_surface_t;
struct HEADLESS_SHELL{
- pepper_compositor_t *compositor;
+ struct wl_display *display;
struct wl_global *zxdg_shell;
struct wl_global *tizen_policy;
struct wl_event_source *cb_idle;
- pepper_view_t *focus;
- pepper_view_t *top_mapped;
- pepper_view_t *top_visible;
-
- pepper_event_listener_t *surface_add_listener;
- pepper_event_listener_t *surface_remove_listener;
- pepper_event_listener_t *view_remove_listener;
+ struct {
+ struct wl_signal new_surface;
+ } events;
};
struct HEADLESS_SHELL_SURFACE{
headless_shell_t *hs_shell;
- pepper_surface_t *surface;
- pepper_view_t *view;
+ struct ds_surface *ds_surface;
uint32_t updates;
uint8_t visibility;
struct wl_resource *tizen_visibility;
uint32_t last_ack_configure;
- pepper_bool_t skip_focus;
-
- pepper_event_listener_t *cb_commit;
-};
-
-static void
-headless_shell_cb_surface_commit(pepper_event_listener_t *listener,
- pepper_object_t *object,
- uint32_t id, void *info, void *data);
-static void
-headless_shell_add_idle(headless_shell_t *shell);
+ struct wl_listener surface_destroy;
+ struct {
+ struct wl_signal destroy;
+ struct wl_signal map;
+ struct wl_signal unmap;
+ struct wl_signal request_activate;
+ struct wl_signal set_skip_focus;
+ struct wl_signal unset_skip_focus;
+ } events;
-static void
-headless_shell_send_visiblity(pepper_view_t *view, uint8_t visibility);
+ bool added;
+ bool mapped;
+};
-const static int KEY_SHELL = 0;
+static void reset_headless_shell_surface(headless_shell_surface_t *hs_surface);
+static void destroy_headless_shell_surface(headless_shell_surface_t *hs_surface);
+static void map_headless_shell_surface(headless_shell_surface_t *hs_surface);
+static void unmap_headless_shell_surface(headless_shell_surface_t *hs_surface);
static void
zxdg_toplevel_cb_resource_destroy(struct wl_resource *resource)
{
headless_shell_surface_t *hs_surface = (headless_shell_surface_t *)wl_resource_get_user_data(resource);
- PEPPER_CHECK(hs_surface, return, "fail to get headless_surface.\n");
- PEPPER_CHECK((hs_surface->surface_type == HEADLESS_SURFACE_TOPLEVEL), return, "Invalid surface type.\n");
- PEPPER_CHECK((hs_surface->zxdg_surface == resource), return, "Invalid surface.");
-
- PEPPER_TRACE("[SHELL] zxdg_toplevel_cb_resource_destroy: view:%p, hs_surface:%p\n", hs_surface->view, hs_surface);
-
- if (hs_surface->view) {
- pepper_view_unmap(hs_surface->view);
- headless_shell_add_idle(hs_surface->hs_shell);
- }
+ if (!hs_surface)
+ return;
- hs_surface->surface_type = HEADLESS_SURFACE_NONE;
- hs_surface->zxdg_surface = NULL;
- SET_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE);
+ reset_headless_shell_surface(hs_surface);
}
static void
{
headless_shell_surface_t *hs_surface = (headless_shell_surface_t *)wl_resource_get_user_data(resource);
- PEPPER_CHECK(hs_surface, return, "fail to get headless_surface.\n");
- PEPPER_CHECK((hs_surface->surface_type == HEADLESS_SURFACE_POPUP), return, "Invalid surface type.\n");
- PEPPER_CHECK((hs_surface->zxdg_surface == resource), return, "Invalid surface.");
+ HEADLESS_CHECK(hs_surface, return, "fail to get headless_surface.\n");
+ HEADLESS_CHECK((hs_surface->surface_type == HEADLESS_SURFACE_POPUP), return, "Invalid surface type.\n");
+ HEADLESS_CHECK((hs_surface->zxdg_surface == resource), return, "Invalid surface.");
hs_surface->surface_type = HEADLESS_SURFACE_NONE;
hs_surface->zxdg_surface = NULL;
headless_shell_surface_t *hs_surface;
hs_surface = wl_resource_get_user_data(resource);
- PEPPER_CHECK(hs_surface, return, "fail to get hs_surface\n");
-
- PEPPER_TRACE("[SHELL] zxdg_surface_cb_resource_destroy: hs_surface:%p view:%p\n", hs_surface, hs_surface->view);
-
- if (hs_surface->view) {
- pepper_view_destroy(hs_surface->view);
- hs_surface->view = NULL;
- }
-
- if (hs_surface->cb_commit) {
- pepper_event_listener_remove(hs_surface->cb_commit);
- hs_surface->cb_commit = NULL;
- }
+ if (!hs_surface)
+ return;
- hs_surface->zxdg_shell_surface = NULL;
- hs_surface->skip_focus = PEPPER_FALSE;
- hs_surface->visibility = TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED;
+ HEADLESS_TRACE("[SHELL] zxdg_surface_cb_resource_destroy: hs_surface:%p", hs_surface);
- SET_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE);
- headless_shell_add_idle(hs_surface->hs_shell);
+ destroy_headless_shell_surface(hs_surface);
}
static void
}
static void
+headless_toplevel_handle_surface_commit(struct ds_surface *ds_surface)
+{
+ headless_shell_surface_t *hs_surface;
+
+ hs_surface = ds_surface_get_role_data(ds_surface);
+ if (!hs_surface)
+ return;
+
+ if (!hs_surface->added) {
+ hs_surface->added = true;
+ wl_signal_emit(&hs_surface->hs_shell->events.new_surface, hs_surface);
+ }
+
+ if (ds_surface_get_buffer(hs_surface->ds_surface) &&
+ !hs_surface->mapped) {
+ map_headless_shell_surface(hs_surface);
+ }
+ else if (!ds_surface_get_buffer(hs_surface->ds_surface) &&
+ hs_surface->mapped) {
+ unmap_headless_shell_surface(hs_surface);
+ }
+}
+
+static const struct ds_surface_role xdg_toplevel_role =
+{
+ .name = "headless_shell_surface",
+ .commit = headless_toplevel_handle_surface_commit,
+};
+
+static void
zxdg_surface_cb_toplevel_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
{
headless_shell_surface_t *hs_surface = (headless_shell_surface_t *)wl_resource_get_user_data(resource);
struct wl_resource *new_res;
- PEPPER_CHECK(hs_surface, return, "fail to get headless_surface\n");
- PEPPER_CHECK((hs_surface->zxdg_surface == NULL), return, "alwreay assign zdg_surface:%p role:%d\n", hs_surface->zxdg_surface, hs_surface->surface_type);
+ HEADLESS_CHECK(hs_surface, return, "fail to get headless_surface\n");
+
+ if (!ds_surface_set_role(hs_surface->ds_surface, &xdg_toplevel_role,
+ hs_surface, resource, ZXDG_SHELL_V6_ERROR_ROLE))
+ return;
+
+ if (hs_surface->surface_type != HEADLESS_SURFACE_NONE) {
+ wl_resource_post_error(hs_surface->zxdg_shell_surface,
+ ZXDG_SURFACE_V6_ERROR_ALREADY_CONSTRUCTED,
+ "xdg-surface has already been constructed");
+ return;
+ }
new_res = wl_resource_create(client, &zxdg_toplevel_v6_interface, 1, id);
if (!new_res) {
- PEPPER_ERROR("fail to create zxdg_toplevel");
+ HEADLESS_ERROR("fail to create zxdg_toplevel");
wl_resource_post_no_memory(resource);
return;
}
hs_surface->surface_type = HEADLESS_SURFACE_TOPLEVEL;
hs_surface->zxdg_surface = new_res;
-
- SET_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE);
}
static void
headless_shell_surface_t *hs_surface = (headless_shell_surface_t *)wl_resource_get_user_data(resource);
struct wl_resource *new_res;
- PEPPER_CHECK(hs_surface, return, "fail to get headless_surface\n");
- PEPPER_CHECK((hs_surface->zxdg_surface == NULL), return, "alwreay assign zdg_surface:%p role:%d\n", hs_surface->zxdg_surface, hs_surface->surface_type);
+ HEADLESS_CHECK(hs_surface, return, "fail to get headless_surface\n");
+ HEADLESS_CHECK((hs_surface->zxdg_surface == NULL), return, "alwreay assign zdg_surface:%p role:%d\n", hs_surface->zxdg_surface, hs_surface->surface_type);
new_res = wl_resource_create(client, &zxdg_popup_v6_interface, 1, id);
if (!new_res) {
- PEPPER_ERROR("fail to create popup");
+ HEADLESS_ERROR("fail to create popup");
wl_resource_post_no_memory(resource);
return;
}
headless_shell_surface_t *hs_surface;
hs_surface = wl_resource_get_user_data(resource);
- PEPPER_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
+ HEADLESS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
hs_surface->last_ack_configure = serial;
}
static void
zxdg_shell_cb_destroy(struct wl_client *client, struct wl_resource *resource)
{
- PEPPER_TRACE("Destroy zxdg_shell\n");
+ HEADLESS_TRACE("Destroy zxdg_shell\n");
wl_resource_destroy(resource);
}
{
struct wl_resource *new_res;
- PEPPER_TRACE("Create zxdg_positoiner\n");
+ HEADLESS_TRACE("Create zxdg_positoiner\n");
new_res = wl_resource_create(client, &zxdg_positioner_v6_interface, 1, id);
if (!new_res)
{
- PEPPER_ERROR("fail to create zxdg_positioner\n");
+ HEADLESS_ERROR("fail to create zxdg_positioner\n");
wl_resource_post_no_memory(resource);
return;
}
}
static void
+map_headless_shell_surface(headless_shell_surface_t *hs_surface)
+{
+ if (hs_surface->mapped)
+ return;
+
+ hs_surface->mapped = true;
+ wl_signal_emit(&hs_surface->events.map, hs_surface);
+}
+
+static void
+unmap_headless_shell_surface(headless_shell_surface_t *hs_surface)
+{
+ if (!hs_surface->mapped)
+ return;
+
+ hs_surface->mapped = false;
+ wl_signal_emit(&hs_surface->events.unmap, hs_surface);
+}
+
+static void
+reset_headless_shell_surface(headless_shell_surface_t *hs_surface)
+{
+ if (hs_surface->surface_type != HEADLESS_SURFACE_NONE)
+ unmap_headless_shell_surface(hs_surface);
+
+ if (hs_surface->added) {
+ wl_signal_emit(&hs_surface->events.destroy, hs_surface);
+ hs_surface->added = false;
+ }
+
+ if (hs_surface->zxdg_surface) {
+ wl_resource_set_user_data(hs_surface->zxdg_surface, NULL);
+ hs_surface->zxdg_surface = NULL;
+ }
+
+ hs_surface->surface_type = HEADLESS_SURFACE_NONE;
+}
+
+static void
+destroy_headless_shell_surface(headless_shell_surface_t *hs_surface)
+{
+ HEADLESS_TRACE("[SHELL] hs_surface free ds_surface:%p, "
+ "zxdg_shell_surface:%p, zxdg_surface:%p",
+ hs_surface->ds_surface, hs_surface->zxdg_shell_surface,
+ hs_surface->zxdg_surface);
+
+ reset_headless_shell_surface(hs_surface);
+
+ wl_resource_set_user_data(hs_surface->zxdg_shell_surface, NULL);
+
+ if (hs_surface->tizen_visibility)
+ wl_resource_set_user_data(hs_surface->tizen_visibility, NULL);
+
+ ds_surface_reset_role_data(hs_surface->ds_surface);
+
+ wl_list_remove(&hs_surface->surface_destroy.link);
+
+ free(hs_surface);
+}
+
+static void
+headless_shell_surface_cb_surface_destroy(struct wl_listener *listener,
+ void *data)
+{
+ headless_shell_surface_t *hs_surface;
+
+ hs_surface = wl_container_of(listener, hs_surface, surface_destroy);
+ destroy_headless_shell_surface(hs_surface);
+}
+
+static void
zxdg_shell_cb_surface_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *wsurface)
{
headless_shell_t *hs;
headless_shell_surface_t *hs_surface = NULL;
- pepper_surface_t *psurface;
- const char *role;
+ struct ds_surface *ds_surface;
hs = wl_resource_get_user_data(resource);
if (!hs) {
- PEPPER_ERROR("fail to get headless_shell\n");
+ HEADLESS_ERROR("fail to get headless_shell\n");
wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
"failed to get headless shell");
return;
}
- psurface = wl_resource_get_user_data(wsurface);
- PEPPER_CHECK(psurface, goto error, "faile to get pepper_surface\n");
+ ds_surface = ds_surface_from_resource(wsurface);
+ HEADLESS_CHECK(ds_surface, goto error, "faile to get ds_surface\n");
- hs_surface = (headless_shell_surface_t *)pepper_object_get_user_data((pepper_object_t *)psurface, wsurface);
+ hs_surface = calloc(1, sizeof *hs_surface);
if (!hs_surface) {
- PEPPER_ERROR("fail to get headless_shell_surface_t: %p key:%p\n", psurface, wsurface);
wl_resource_post_no_memory(resource);
return;
}
+ hs_surface->hs_shell = hs;
+ hs_surface->ds_surface = ds_surface;
+ hs_surface->visibility = TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED;
+
+ wl_signal_init(&hs_surface->events.destroy);
+ wl_signal_init(&hs_surface->events.map);
+ wl_signal_init(&hs_surface->events.unmap);
+ wl_signal_init(&hs_surface->events.request_activate);
+ wl_signal_init(&hs_surface->events.set_skip_focus);
+ wl_signal_init(&hs_surface->events.unset_skip_focus);
+
hs_surface->zxdg_shell_surface = wl_resource_create(client, &zxdg_surface_v6_interface, 1, id);
if (!hs_surface->zxdg_shell_surface) {
- PEPPER_ERROR("fail to create the zxdg_surface\n");
+ HEADLESS_ERROR("fail to create the zxdg_surface\n");
wl_resource_post_no_memory(resource);
goto error;
}
hs_surface,
zxdg_surface_cb_resource_destroy);
- hs_surface->view = pepper_compositor_add_view(hs->compositor);
- if (!hs_surface->view) {
- PEPPER_ERROR("fail to create the pepper_view\n");
- wl_resource_post_no_memory(resource);
- goto error;
- }
-
- if (!pepper_view_set_surface(hs_surface->view, psurface)) {
- PEPPER_ERROR("fail to set surface\n");
- wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
- "Assign set psurface to pview");
- goto error;
- }
+ hs_surface->surface_destroy.notify =
+ headless_shell_surface_cb_surface_destroy;
+ ds_surface_add_destroy_listener(ds_surface, &hs_surface->surface_destroy);
- hs_surface->cb_commit = pepper_object_add_event_listener((pepper_object_t *)psurface,
- PEPPER_EVENT_SURFACE_COMMIT, 0, headless_shell_cb_surface_commit, hs_surface);
-
- role = pepper_surface_get_role(psurface);
- if (!role) {
- if (!pepper_surface_set_role(psurface, "xdg_surface")) {
- PEPPER_ERROR("fail to set role\n");
- wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
- "Assign \"xdg_surface\" to wl_surface failed\n");
- goto error;
- }
- } else {
- PEPPER_CHECK(!strcmp(role, "xdg_surface"), goto error, "surface has alweady role %s\n", role);
- }
-
- PEPPER_TRACE("[SHELL] create zxdg_surface:%p, pview:%p, psurface:%p\n",
+ HEADLESS_TRACE("[SHELL] create zxdg_surface:%p, ds_surface:%p\n",
hs_surface->zxdg_shell_surface,
- hs_surface->view,
- psurface);
+ hs_surface->ds_surface);
return;
error:
if (hs_surface) {
- if (hs_surface->view) {
- pepper_view_destroy(hs_surface->view);
- hs_surface->view = NULL;
- }
-
if (hs_surface->zxdg_shell_surface) {
wl_resource_destroy(hs_surface->zxdg_shell_surface);
hs_surface->zxdg_shell_surface = NULL;
}
+
+ free(hs_surface);
}
}
struct wl_resource *resource;
headless_shell_t *hs = (headless_shell_t *)data;
- PEPPER_TRACE("Bind zxdg_shell\n");
+ HEADLESS_TRACE("Bind zxdg_shell\n");
/* Create resource for zxdg_shell_v6 */
resource = wl_resource_create(client,
&zxdg_shell_v6_interface,
version,
id);
- PEPPER_CHECK(resource, goto err_shell, "fail to create the zxdg_shell_v6\n");
+ HEADLESS_CHECK(resource, goto err_shell, "fail to create the zxdg_shell_v6\n");
wl_resource_set_implementation(resource, &zxdg_shell_interface, hs, NULL);
wl_client_post_no_memory(client);
}
-static pepper_bool_t
+static bool
zxdg_init(headless_shell_t *shell)
{
- struct wl_display *display;
-
- display = pepper_compositor_get_display(shell->compositor);
+ shell->zxdg_shell = wl_global_create(shell->display, &zxdg_shell_v6_interface, 1, shell, zxdg_shell_cb_bind);
+ HEADLESS_CHECK(shell->zxdg_shell, return false, "fail to create zxdg_shell\n");
- shell->zxdg_shell = wl_global_create(display, &zxdg_shell_v6_interface, 1, shell, zxdg_shell_cb_bind);
- PEPPER_CHECK(shell->zxdg_shell, return PEPPER_FALSE, "fail to create zxdg_shell\n");
-
- return PEPPER_TRUE;
+ return true;
}
void
{
headless_shell_surface_t *hs_surface = (headless_shell_surface_t *)wl_resource_get_user_data(res_tzvis);
- PEPPER_CHECK(hs_surface, return, "[SHELL] cannot get headless_shell_surface_t\n");
+ if (!hs_surface)
+ return;
+
hs_surface->tizen_visibility = NULL;
}
{
}
+static headless_shell_surface_t *
+headless_shell_surface_from_ds_surface(struct ds_surface *ds_surface)
+{
+ if (ds_surface_get_role(ds_surface) != &xdg_toplevel_role)
+ return NULL;
+ return ds_surface_get_role_data(ds_surface);
+}
+
static void
tizen_policy_cb_vis_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surf)
{
- pepper_surface_t *psurface;
+ struct ds_surface *ds_surface;
headless_shell_surface_t *hs_surface;
struct wl_resource *new_res;
- psurface = wl_resource_get_user_data(surf);
- PEPPER_CHECK(psurface, return, "fail to get pepper_surface_t\n");
+ ds_surface = ds_surface_from_resource(surf);
+ HEADLESS_CHECK(ds_surface, return, "fail to get ds_surface_t\n");
- hs_surface = pepper_object_get_user_data((pepper_object_t *)psurface, surf);
- PEPPER_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
+ hs_surface = headless_shell_surface_from_ds_surface(ds_surface);
+ HEADLESS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
new_res = wl_resource_create(client, &tizen_visibility_interface, 5, id);
if (!new_res) {
- PEPPER_ERROR("fail to create tizen_visibility");
+ HEADLESS_ERROR("fail to create tizen_visibility");
wl_resource_post_no_memory(resource);
return;
}
new_res = wl_resource_create(client, &tizen_position_interface, 1, id);
if (!new_res) {
- PEPPER_ERROR("fail to create tizen_visibility");
+ HEADLESS_ERROR("fail to create tizen_visibility");
wl_resource_post_no_memory(resource);
return;
}
static void
tizen_policy_cb_activate(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
{
- pepper_surface_t *psurface;
+ struct ds_surface *ds_surface;
headless_shell_surface_t *hs_surface;
- psurface = wl_resource_get_user_data(surf);
- PEPPER_CHECK(psurface, return, "fail to get pepper_surface_t\n");
+ ds_surface = ds_surface_from_resource(surf);
+ HEADLESS_CHECK(ds_surface, return, "fail to get ds_surface\n");
- hs_surface = pepper_object_get_user_data((pepper_object_t *)psurface, surf);
- PEPPER_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
- PEPPER_CHECK(hs_surface->view, return, "invalid view from headless_shell_surface\n");
+ hs_surface = headless_shell_surface_from_ds_surface(ds_surface);
+ HEADLESS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
- pepper_view_stack_top(hs_surface->view, PEPPER_TRUE);
-
- headless_shell_add_idle(hs_surface->hs_shell);
+ wl_signal_emit(&hs_surface->events.request_activate, hs_surface);
}
static void
static void
tizen_policy_cb_focus_skip_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
{
- pepper_surface_t *psurface;
+ struct ds_surface *ds_surface;
headless_shell_surface_t *hs_surface;
- psurface = wl_resource_get_user_data(surf);
- PEPPER_CHECK(psurface, return, "fail to get pepper_surface_t\n");
+ ds_surface = ds_surface_from_resource(surf);
+ HEADLESS_CHECK(ds_surface, return, "fail to get ds_surface\n");
- hs_surface = pepper_object_get_user_data((pepper_object_t *)psurface, surf);
- PEPPER_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
+ hs_surface = headless_shell_surface_from_ds_surface(ds_surface);
+ HEADLESS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
- hs_surface->skip_focus = PEPPER_TRUE;
+ wl_signal_emit(&hs_surface->events.set_skip_focus, hs_surface);
}
static void
tizen_policy_cb_focus_skip_unset(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
{
- pepper_surface_t *psurface;
+ struct ds_surface *ds_surface;
headless_shell_surface_t *hs_surface;
- psurface = wl_resource_get_user_data(surf);
- PEPPER_CHECK(psurface, return, "fail to get pepper_surface_t\n");
+ ds_surface = ds_surface_from_resource(surf);
+ HEADLESS_CHECK(ds_surface, return, "fail to get ds_surface\n");
- hs_surface = pepper_object_get_user_data((pepper_object_t *)psurface, surf);
- PEPPER_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
+ hs_surface = headless_shell_surface_from_ds_surface(ds_surface);
+ HEADLESS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
- hs_surface->skip_focus = PEPPER_FALSE;
+ wl_signal_emit(&hs_surface->events.unset_skip_focus, hs_surface);
}
static void
headless_shell_t *shell = (headless_shell_t *)data;
struct wl_resource *resource;
- PEPPER_CHECK(shell, goto err, "data is NULL\n");
+ HEADLESS_CHECK(shell, goto err, "data is NULL\n");
resource = wl_resource_create(client,
&tizen_policy_interface,
ver,
id);
- PEPPER_CHECK(resource, goto err, "fail to create tizen_policy\n");
+ HEADLESS_CHECK(resource, goto err, "fail to create tizen_policy\n");
wl_resource_set_implementation(resource,
&tizen_policy_iface,
wl_client_post_no_memory(client);
}
-static pepper_bool_t
+static bool
tizen_policy_init(headless_shell_t *shell)
{
- struct wl_display *display;
+ shell->tizen_policy = wl_global_create(shell->display, &tizen_policy_interface, 7, shell, tizen_policy_cb_bind);
+ HEADLESS_CHECK(shell->tizen_policy, return false, "faile to create tizen_policy\n");
- display = pepper_compositor_get_display(shell->compositor);
-
- shell->tizen_policy = wl_global_create(display, &tizen_policy_interface, 7, shell, tizen_policy_cb_bind);
- PEPPER_CHECK(shell->tizen_policy, return PEPPER_FALSE, "faile to create tizen_policy\n");
-
- return PEPPER_TRUE;
+ return true;
}
void
wl_global_destroy(shell->tizen_policy);
}
-static void
-headless_shell_send_visiblity(pepper_view_t *view, uint8_t visibility)
+void
+headless_shell_destroy(headless_shell_t *shell)
{
- pepper_surface_t *surface;
- headless_shell_surface_t *hs_surface;
-
- if (view == NULL) return;
-
- surface = pepper_view_get_surface(view);
- PEPPER_CHECK(surface, return, "[SHELL] Invalid object surface:%p\n", surface);
-
- hs_surface = pepper_object_get_user_data((pepper_object_t *)surface, pepper_surface_get_resource(surface));
- PEPPER_CHECK(hs_surface, return, "[SHELL] Invalid object headless_surface:%p\n", hs_surface);
-
- if (hs_surface->visibility == visibility) {
- PEPPER_TRACE("[SHELL] Same Visibility hs_surface:%p, visibility:%d\n", hs_surface, visibility);
+ if (!shell)
return;
- }
-
- if (hs_surface->tizen_visibility)
- tizen_visibility_send_notify(hs_surface->tizen_visibility, visibility);
- hs_surface->visibility = visibility;
- PEPPER_TRACE("[SHELL] Set Visibility hs_surface:%p, visibility:%d\n", hs_surface, visibility);
+ zxdg_deinit(shell);
+ tizen_policy_deinit(shell);
+ free(shell);
}
-static void
-headless_shell_cb_idle(void *data)
+headless_shell_t *
+headless_shell_create(struct wl_display *display)
{
- headless_shell_t *hs_shell = (headless_shell_t *)data;
- const pepper_list_t *list;
- pepper_list_t *l = NULL;
- pepper_view_t *view;
- pepper_surface_t *surface;
- headless_shell_surface_t *hs_surface;
-
- pepper_view_t *focus = NULL, *top = NULL, *top_visible = NULL;
-
- PEPPER_TRACE("[SHELL] Enter Idle\n");
- list = pepper_compositor_get_view_list(hs_shell->compositor);
-
- pepper_list_for_each_list(l, list) {
- if (!l) break;
-
- view = (pepper_view_t *)l->item;
- PEPPER_CHECK(view, continue, "[SHELL] idle_cb, Invalid object view:%p\n", view);
-
- surface = pepper_view_get_surface(view);
- PEPPER_CHECK(surface, continue, "[SHELL] idle_cb, Invalid object surface:%p\n", surface);
-
- hs_surface = pepper_object_get_user_data((pepper_object_t *)surface, pepper_surface_get_resource(surface));
- PEPPER_CHECK(hs_surface, continue, "[SHELL] idle_cb, Invalid object headless_surface:%p\n", hs_surface);
-
- if (!pepper_view_is_mapped(view)) {
- headless_shell_send_visiblity(view, TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED);
- continue;
- }
-
- if (!top)
- top = view;
+ headless_shell_t *shell;
- if (!focus && !hs_surface->skip_focus)
- focus = view;
+ shell = (headless_shell_t*)calloc(sizeof(headless_shell_t), 1);
+ HEADLESS_CHECK(shell, goto error, "fail to alloc for shell\n");
- if (!top_visible && pepper_surface_get_buffer(surface))
- top_visible = view;
+ shell->display = display;
- if (focus && top_visible)
- break;
- }
+ wl_signal_init(&shell->events.new_surface);
- if (top != hs_shell->top_mapped) {
- const pepper_list_t *l;
- pepper_list_t *ll;
+ HEADLESS_CHECK(zxdg_init(shell), goto error, "zxdg_init() failed\n");
+ HEADLESS_CHECK(tizen_policy_init(shell), goto error, "tizen_policy_init() failed\n");
- PEPPER_TRACE("[SHELL] IDLE : top-view change: %p to %p\n", hs_shell->top_mapped , top);
- hs_shell->top_mapped = top;
- headless_input_set_top_view(hs_shell->compositor, hs_shell->top_mapped);
- headless_debug_set_top_view(hs_shell->compositor, hs_shell->top_mapped);
+ return shell;
- /*Force update the output*/
- l = pepper_compositor_get_output_list(hs_shell->compositor);
- pepper_list_for_each_list(ll, l) {
- pepper_output_add_damage_region((pepper_output_t *)ll->item, NULL);
- }
- }
-
- if (focus != hs_shell->focus) {
- PEPPER_TRACE("[SHELL] IDLE : focus-view change: %p to %p\n", hs_shell->focus , focus);
- hs_shell->focus = focus;
- headless_input_set_focus_view(hs_shell->compositor, hs_shell->focus);
- headless_debug_set_focus_view(hs_shell->compositor, hs_shell->focus);
- }
-
- if (top_visible != hs_shell->top_visible) {
- PEPPER_TRACE("[SHELL] IDLE : visible-view change: %p to %p\n", hs_shell->top_visible, top_visible);
- headless_shell_send_visiblity(hs_shell->top_visible, TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED);
- headless_shell_send_visiblity(top_visible, TIZEN_VISIBILITY_VISIBILITY_UNOBSCURED);
- hs_shell->top_visible = top_visible;
- }
+error:
+ headless_shell_destroy(shell);
- hs_shell->cb_idle = NULL;
+ return NULL;
}
-static void
-headless_shell_cb_surface_commit(pepper_event_listener_t *listener,
- pepper_object_t *object,
- uint32_t id, void *info, void *data)
+void
+headless_shell_add_new_surface_listener(headless_shell_t *shell,
+ struct wl_listener *listener)
{
- headless_shell_surface_t * hs_surface = (headless_shell_surface_t *)data;
-
- PEPPER_CHECK(((pepper_object_t *)hs_surface->surface == object), return, "Invalid object\n");
-
- /*TODO
- 1. Check the changes(buffer, map status...)
- */
- if (IS_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE)) {
- if (hs_surface->surface_type != HEADLESS_SURFACE_NONE)
- pepper_view_map(hs_surface->view);
- else
- pepper_view_unmap(hs_surface->view);
-
- PEPPER_TRACE("Surface type change. view:%p, type:%d, res:%p\n", hs_surface->view, hs_surface->surface_type, hs_surface->zxdg_surface);
- }
-
- hs_surface->updates = 0;
-
- headless_shell_add_idle(hs_surface->hs_shell);
+ wl_signal_add(&shell->events.new_surface, listener);
}
-static void
-headless_shell_cb_surface_free(void *data)
+void
+headless_shell_surface_add_destroy_listener(
+ headless_shell_surface_t *hs_surface, struct wl_listener *listener)
{
- headless_shell_surface_t *surface = (headless_shell_surface_t *)data;
-
- PEPPER_TRACE("[SHELL] hs_surface free surface:%p, view:%p, zxdg_shell_surface:%p, zxdg_surface:%p\n",
- surface->surface, surface->view,
- surface->zxdg_shell_surface, surface->zxdg_surface);
-
- free(surface);
+ wl_signal_add(&hs_surface->events.destroy, listener);
}
-static void
-headless_shell_cb_surface_add(pepper_event_listener_t *listener,
- pepper_object_t *object,
- uint32_t id, void *info, void *data)
+void
+headless_shell_surface_add_map_listener(
+ headless_shell_surface_t *hs_surface, struct wl_listener *listener)
{
- headless_shell_surface_t *hs_surface;
- pepper_surface_t *surface = (pepper_surface_t *)info;
-
- hs_surface = (headless_shell_surface_t*)calloc(sizeof(headless_shell_surface_t), 1);
- PEPPER_CHECK(hs_surface, return, "fail to alloc for headless_shell_surface\n");
-
- hs_surface->hs_shell = (headless_shell_t *)data;
- hs_surface->surface = (pepper_surface_t *)surface;
- hs_surface->visibility = TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED;
-
- pepper_object_set_user_data((pepper_object_t *)surface,
- pepper_surface_get_resource(surface),
- hs_surface,
- headless_shell_cb_surface_free);
- PEPPER_TRACE("[SHELL] surface_Add: pepper_surface:%, headless_shell:%p to p\n", surface, hs_surface);
+ wl_signal_add(&hs_surface->events.map, listener);
}
-static void
-headless_shell_cb_surface_remove(pepper_event_listener_t *listener,
- pepper_object_t *object,
- uint32_t id, void *info, void *data)
-{
- headless_shell_surface_t *hs_surface;
- pepper_surface_t *surface = (pepper_surface_t *)info;
-
- hs_surface = pepper_object_get_user_data((pepper_object_t *)surface, pepper_surface_get_resource(surface));
- PEPPER_CHECK(hs_surface, return, "[SHELL] cb_surface_remove, Invalid object headless_surface:%p\n", hs_surface);
- PEPPER_TRACE("[SHELL] surface_remove: pepper_surface:%p, headless_shell:%p\n", object, hs_surface);
-
- if (hs_surface->zxdg_surface) {
- wl_resource_set_user_data(hs_surface->zxdg_surface, NULL);
- hs_surface->zxdg_surface = NULL;
- }
-
- if (hs_surface->zxdg_shell_surface) {
- wl_resource_set_user_data(hs_surface->zxdg_shell_surface, NULL);
- hs_surface->zxdg_shell_surface = NULL;
- }
-
- if (hs_surface->view) {
- pepper_view_destroy(hs_surface->view);
- hs_surface->view = NULL;
- }
-
- SET_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE);
- headless_shell_add_idle(hs_surface->hs_shell);
-}
-
-static void
-headless_shell_cb_view_remove(pepper_event_listener_t *listener,
- pepper_object_t *object,
- uint32_t id, void *info, void *data)
+void
+headless_shell_surface_add_unmap_listener(
+ headless_shell_surface_t *hs_surface, struct wl_listener *listener)
{
- pepper_view_t *view = (pepper_view_t *)info;
- headless_shell_t *shell = (headless_shell_t *)data;
-
- if (view == shell->top_mapped)
- shell->top_mapped = NULL;
-
- if (view == shell->top_visible)
- shell->top_visible = NULL;
-
- if (view == shell->focus)
- shell->focus = NULL;
-
- headless_shell_add_idle(shell);
+ wl_signal_add(&hs_surface->events.unmap, listener);
}
-static void
-headless_shell_add_idle(headless_shell_t *shell)
+void
+headless_shell_surface_add_request_activate_listener(
+ headless_shell_surface_t *hs_surface, struct wl_listener *listener)
{
- struct wl_event_loop *loop;
-
- if (!shell || shell->cb_idle)
- return;
-
- loop = wl_display_get_event_loop(pepper_compositor_get_display(shell->compositor));
- PEPPER_CHECK(loop, return, "fail to get event loop\n");
-
- shell->cb_idle = wl_event_loop_add_idle(loop, headless_shell_cb_idle, shell);
- PEPPER_CHECK(shell->cb_idle, return, "fail to add idle\n");
+ wl_signal_add(&hs_surface->events.request_activate, listener);
}
-static void
-headless_shell_init_listeners(headless_shell_t *shell)
+void
+headless_shell_surface_add_set_skip_focus_listener(
+ headless_shell_surface_t *hs_surface, struct wl_listener *listener)
{
- shell->surface_add_listener = pepper_object_add_event_listener((pepper_object_t *)shell->compositor,
- PEPPER_EVENT_COMPOSITOR_SURFACE_ADD,
- 0, headless_shell_cb_surface_add, shell);
-
- shell->surface_remove_listener = pepper_object_add_event_listener((pepper_object_t *)shell->compositor,
- PEPPER_EVENT_COMPOSITOR_SURFACE_REMOVE,
- 0, headless_shell_cb_surface_remove, shell);
-
- shell->view_remove_listener = pepper_object_add_event_listener((pepper_object_t *)shell->compositor,
- PEPPER_EVENT_COMPOSITOR_VIEW_REMOVE,
- 0, headless_shell_cb_view_remove, shell);
+ wl_signal_add(&hs_surface->events.set_skip_focus, listener);
}
-static void
-headless_shell_deinit_listeners(headless_shell_t *shell)
+void
+headless_shell_surface_add_unset_skip_focus_listener(
+ headless_shell_surface_t *hs_surface, struct wl_listener *listener)
{
- pepper_event_listener_remove(shell->surface_add_listener);
- pepper_event_listener_remove(shell->surface_remove_listener);
- pepper_event_listener_remove(shell->view_remove_listener);
+ wl_signal_add(&hs_surface->events.unset_skip_focus, listener);
}
-static void
-headless_shell_destroy(headless_shell_t *shell)
+struct ds_surface *
+headless_shell_surface_get_surface(headless_shell_surface_t *hs_surface)
{
- if (!shell)
- return;
-
- if (shell->cb_idle)
- wl_event_source_remove(shell->cb_idle);
-
- headless_shell_deinit_listeners(shell);
- zxdg_deinit(shell);
- tizen_policy_deinit(shell);
+ return hs_surface->ds_surface;
}
void
-headless_shell_deinit(pepper_compositor_t *compositor)
-{
- headless_shell_t *shell;
-
- PEPPER_CHECK(compositor, return, "compositor is NULL\n");
-
- shell = (headless_shell_t *)pepper_object_get_user_data((pepper_object_t *)compositor, &KEY_SHELL);
- PEPPER_CHECK(shell, return, "shell is NULL\n");
-
- headless_shell_destroy(shell);
-
- pepper_object_set_user_data((pepper_object_t *)shell->compositor, &KEY_SHELL, NULL, NULL);
- free(shell);
-}
-
-pepper_bool_t
-headless_shell_init(pepper_compositor_t *compositor)
+headless_shell_send_visibility(headless_shell_surface_t *hs_surface,
+ uint8_t visibility)
{
- headless_shell_t *shell;
-
- shell = (headless_shell_t*)calloc(sizeof(headless_shell_t), 1);
- PEPPER_CHECK(shell, goto error, "fail to alloc for shell\n");
- shell->compositor = compositor;
-
- headless_shell_init_listeners(shell);
- PEPPER_CHECK(zxdg_init(shell), goto error, "zxdg_init() failed\n");
- PEPPER_CHECK(tizen_policy_init(shell), goto error, "tizen_policy_init() failed\n");
-
- pepper_object_set_user_data((pepper_object_t *)compositor, &KEY_SHELL, shell, NULL);
+ if (hs_surface->visibility == visibility) {
+ HEADLESS_TRACE("[SHELL] Same Visibility hs_surface:%p, visibility:%d\n", hs_surface, visibility);
+ return;
+ }
- return PEPPER_TRUE;
+ if (hs_surface->tizen_visibility)
+ tizen_visibility_send_notify(hs_surface->tizen_visibility, visibility);
-error:
- if (shell) {
- headless_shell_destroy(shell);
- free(shell);
- }
- return PEPPER_FALSE;
+ hs_surface->visibility = visibility;
+ HEADLESS_TRACE("[SHELL] Set Visibility hs_surface:%p, visibility:%d\n", hs_surface, visibility);
}