--- /dev/null
+/*
+Copyright (C) 2015 - 2016 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact:
+ SooChan Lim <sc1.lim@samsung.com>
+ Changyeon Lee <cyeon.lee@samsung.com>
+ JunKyeong Kim <jk0430.kim@samsung.com>
+ Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+
+#include <wayland-client.h>
+
+#define BUF_WIDTH 1920
+#define BUF_HEIGHT 1080
+
+#define RETURN_VAL_IF_FAIL(c,v) {\
+ if(!((c))){\
+ fprintf(stderr, "[%s(%d)] '%s' failed.", __func__, __LINE__, #c);\
+ return (v);\
+ }\
+}
+
+#define GOTO_IF_FAIL(c,l) {\
+ if(!(c)) {\
+ fprintf(stderr, "[%s(%d)] '%s' failed.", __func__, __LINE__, #c);\
+ goto l;\
+ }\
+}
+
+#define EXIT_IF_FAIL(c) {\
+ if(!(c)) {\
+ fprintf (stderr, "[%s(%d)] '%s' failed.\n",__func__,__LINE__,#c);\
+ exit(0);\
+ }\
+}
+
+struct wl_test_info {
+ int width;
+ int height;
+ int stride;
+ int format;
+ int size;
+
+ struct wl_display *display;
+ struct wl_registry *registry;
+
+ /* global objects */
+ struct wl_compositor *compositor;
+ struct wl_shm *shm;
+ struct wl_shell *shell;
+ struct wl_shm_pool *shm_pool;
+
+ /* objects */
+ struct wl_surface *surface;
+ struct wl_shell_surface *shell_surface;
+ struct wl_buffer *buffer;
+};
+
+static int
+_create_anonymous_file (off_t size)
+{
+ static const char template[] =
+ "/shooter-XXXXXX";
+ const char *path;
+ char *name = NULL;
+ int fd = -1;
+ int ret = -1;
+
+ path = getenv("XDG_RUNTIME_DIR");
+ if (!path) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ name = malloc(strlen(path) + sizeof(template));
+ GOTO_IF_FAIL(name != NULL, fail);
+
+ strcpy(name, path);
+ strcat(name, template);
+
+ fd = mkstemp(name);
+ if (fd >= 0)
+ unlink(name);
+
+ ret = ftruncate(fd, size);
+ GOTO_IF_FAIL(ret >= 0, fail);
+
+ free(name);
+
+ return fd;
+fail:
+ if (fd >= 0)
+ close(fd);
+
+ if (name)
+ free(name);
+
+ return -1;
+}
+
+static void
+_destroy_anonymous_file(int fd)
+{
+ if (fd < 0) return;
+
+ close(fd);
+}
+
+
+static struct wl_test_info *
+_create_wl_test_info (void)
+{
+ struct wl_test_info *test_info = NULL;
+
+ test_info = calloc(1, sizeof(struct wl_test_info));
+ RETURN_VAL_IF_FAIL(test_info != NULL, NULL);
+
+ return test_info;
+}
+
+static void
+_destroy_wl_test_info (struct wl_test_info *test_info)
+{
+ if (!test_info) return;
+
+ free(test_info);
+}
+
+static struct wl_shm_pool *
+_create_shm_pool(struct wl_shm *shm, int size)
+{
+ struct wl_shm_pool *shm_pool = NULL;
+ void *data = NULL;
+ int fd = -1;
+
+ fd = _create_anonymous_file(size);
+ GOTO_IF_FAIL(fd >= 0, fail);
+
+ data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ GOTO_IF_FAIL(data != NULL, fail);
+
+ memset(data, 0xff, size);
+ munmap(data, size);
+
+ shm_pool = wl_shm_create_pool(shm, fd, size);
+ GOTO_IF_FAIL(shm_pool != NULL, fail);
+
+ _destroy_anonymous_file(fd);
+
+ return shm_pool;
+
+fail:
+ if (fd > 0)
+ _destroy_anonymous_file(fd);
+
+ return NULL;
+}
+
+void
+_destroy_shm_pool(struct wl_shm_pool *shm_pool)
+{
+ if (!shm_pool) return;
+
+ wl_shm_pool_destroy(shm_pool);
+}
+
+static void
+handle_global(void *data, struct wl_registry *registry, uint32_t name,
+ const char *interface, uint32_t version)
+{
+ struct wl_test_info *ti = (struct wl_test_info *)data;
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ ti->compositor = wl_registry_bind(registry, name,
+ &wl_compositor_interface, 3);
+ if (!ti->compositor)
+ printf("%s(%d): Error. fail to bind %s.\n",
+ __func__, __LINE__, interface);
+ else
+ printf("%s(%d): bind %s.\n", __func__, __LINE__, interface);
+ } else if (strcmp(interface, "wl_shm") == 0) {
+ ti->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
+ if (!ti->shm)
+ printf("%s(%d): Error. fail to bind %s.\n",
+ __func__, __LINE__, interface);
+ else
+ printf("%s(%d): bind %s.\n", __func__, __LINE__, interface);
+
+ ti->shm_pool = _create_shm_pool(ti->shm, ti->size);
+ if (!ti->shm_pool)
+ printf("%s(%d): Error. fail to create wl_shm_pool.\n",
+ __func__, __LINE__);
+ else
+ printf("%s(%d): success to create wl_shm_pool.\n",
+ __func__, __LINE__);
+
+ } else if (strcmp(interface, "wl_shell") == 0) {
+ ti->shell = wl_registry_bind(registry, name, &wl_shell_interface, 1);
+ if (!ti->shell)
+ printf("%s(%d): Error. fail to bind %s.\n",
+ __func__, __LINE__, interface);
+ else
+ printf("%s(%d): bind %s.\n", __func__, __LINE__, interface);
+ } else {
+ printf("%s(%d): Not bind %s.\n", __func__, __LINE__, interface);
+ }
+}
+
+static void
+handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+
+}
+
+static const struct wl_registry_listener registry_listener = {
+ handle_global,
+ handle_global_remove
+};
+
+int main (void)
+{
+ struct wl_test_info *ti = NULL;
+ int ret = 0;
+
+ /* create test info */
+ ti = _create_wl_test_info ();
+ GOTO_IF_FAIL(ti != NULL, fail);
+
+ /* init */
+ ti->width = BUF_WIDTH;
+ ti->height = BUF_HEIGHT;
+ ti->stride = ti->width * 4;
+ ti->format = WL_SHM_FORMAT_XRGB8888;
+ ti->size = ti->stride * ti->height;
+
+ /* connect display */
+ ti->display = wl_display_connect(NULL);
+ GOTO_IF_FAIL(ti->display != NULL, fail);
+
+ /* get the registry */
+ ti->registry = wl_display_get_registry(ti->display);
+ GOTO_IF_FAIL(ti->registry != NULL, fail);
+
+ /* get the global objects */
+ wl_registry_add_listener(ti->registry, ®istry_listener, ti);
+ wl_display_dispatch(ti->display);
+ wl_display_roundtrip(ti->display);
+
+ /* check the global objects */
+ GOTO_IF_FAIL(ti->compositor != NULL, fail);
+ GOTO_IF_FAIL(ti->shm != NULL, fail);
+ GOTO_IF_FAIL(ti->shell != NULL, fail);
+ GOTO_IF_FAIL(ti->shm_pool != NULL, fail);
+
+ /* create objects */
+ ti->surface = wl_compositor_create_surface(ti->compositor);
+ GOTO_IF_FAIL(ti->surface != NULL, fail);
+
+ ti->shell_surface = wl_shell_get_shell_surface(ti->shell, ti->surface);
+ GOTO_IF_FAIL(ti->shell_surface != NULL, fail);
+
+ wl_shell_surface_set_toplevel(ti->shell_surface);
+
+ ti->buffer = wl_shm_pool_create_buffer(ti->shm_pool, 0,
+ ti->width, ti->height, ti->stride, ti->format);
+ GOTO_IF_FAIL(ti->buffer != NULL, fail);
+
+ wl_surface_attach(ti->surface, ti->buffer, 0, 0);
+ wl_surface_damage(ti->surface, 0, 0, ti->width, ti->height);
+ wl_surface_commit(ti->surface);
+
+ wl_display_roundtrip(ti->display);
+
+ /* main loop */
+ printf("%s(%d): loop start.\n", __func__, __LINE__);
+ while (ret >= 0) {
+ ret = wl_display_dispatch(ti->display);
+ printf("%s(%d): loop running(ret=%d).\n", __func__, __LINE__, ret);
+ }
+ printf("%s(%d): loop end.\n", __func__, __LINE__);
+
+fail:
+ /* destory objects */
+ if (ti->shell_surface)
+ wl_shell_surface_destroy(ti->shell_surface);
+ if (ti->surface)
+ wl_surface_destroy(ti->surface);
+ if (ti->buffer)
+ wl_buffer_destroy(ti->buffer);
+
+ /* destroy global objects */
+ if (ti->shell)
+ wl_shell_destroy(ti->shell);
+ if (ti->shm_pool)
+ _destroy_shm_pool(ti->shm_pool);
+ if (ti->shm)
+ wl_shm_destroy(ti->shm);
+ if (ti->compositor)
+ wl_compositor_destroy(ti->compositor);
+
+ /* destory registry and display */
+ if (ti->registry)
+ wl_registry_destroy(ti->registry);
+ if (ti->display)
+ wl_display_disconnect(ti->display);
+
+ /* destroy test_info */
+ if (ti)
+ _destroy_wl_test_info(ti);
+
+ return 0;
+}