Enable wayland build
authorSung-jae Park <nicesj.park@samsung.com>
Thu, 6 Mar 2014 07:04:36 +0000 (16:04 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Thu, 6 Mar 2014 07:04:36 +0000 (16:04 +0900)
Pixmap is not able to be used in wayland world.

Change-Id: I0ad28017f7f7bfd53f0ce71491f04b16a4c52b14

CMakeLists.txt
include/util.h
packaging/data-provider-master.spec
src/badge_service.c [changed mode: 0755->0644]
src/buffer_handler_wayland.c [new file with mode: 0644]
src/conf.c
src/main.c [changed mode: 0755->0644]
src/notification_service.c [changed mode: 0755->0644]
src/util_wayland.c [new file with mode: 0644]
src/util_x11.c [new file with mode: 0644]
src/xmonitor_wayland.c [new file with mode: 0644]

index 7d4d7f6..671d11a 100755 (executable)
@@ -12,17 +12,8 @@ pkg_check_modules(pkg REQUIRED
        glib-2.0
        gio-2.0
        bundle
-       ecore-x
        ecore
        com-core
-       x11
-       libdri2
-       libdrm
-       libtbm
-       xfixes
-       dri2proto
-       xext
-       xdamage
        pkgmgr
        livebox-service
        notification
@@ -33,6 +24,26 @@ pkg_check_modules(pkg REQUIRED
        shortcut
 )
 
+IF (X11_SUPPORT)
+pkg_check_modules(pkg_extra REQUIRED
+       ecore-x
+       x11
+       libdri2
+       libdrm
+       libtbm
+       xfixes
+       dri2proto
+       xext
+       xdamage
+)
+ENDIF (X11_SUPPORT)
+
+IF (WAYLAND_SUPPORT)
+pkg_check_modules(pkg_extra REQUIRED
+       ecore-wayland
+)
+ENDIF (WAYLAND_SUPPORT)
+
 SET(PACKAGE "${PROJECT_NAME}")
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Winline -Werror -fno-builtin-malloc -fno-omit-frame-pointer -g")
 
@@ -66,12 +77,8 @@ ADD_DEFINITIONS("-DDEFAULT_MASTER_CONF=\"/usr/share/data-provider-master/conf.in
 ADD_DEFINITIONS("-DNDEBUG")
 
 ADD_DEFINITIONS("-D_USE_ECORE_TIME_GET")
-#ADD_DEFINITIONS("-D_APPLY_SCRIPT_ASYNC_UPDATE")
-#ADD_DEFINITIONS("-DFLOG")
-ADD_DEFINITIONS(${pkg_CFLAGS})
-ADD_DEFINITIONS(${pkg_LDFLAGS})
 
-ADD_EXECUTABLE(${PROJECT_NAME}
+SET(BUILD_SOURCE
        src/main.c
        src/util.c
        src/fault_manager.c
@@ -80,9 +87,7 @@ ADD_EXECUTABLE(${PROJECT_NAME}
        src/dead_monitor.c
        src/group.c
        src/script_handler.c
-       src/buffer_handler.c
        src/io.c
-       src/xmonitor.c
        src/slave_life.c
        src/slave_rpc.c
        src/client_life.c
@@ -104,7 +109,36 @@ ADD_EXECUTABLE(${PROJECT_NAME}
        src/service_common.c
 )
 
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkg_LDFLAGS} "-ldl -lrt")
+IF (WAYLAND_SUPPORT)
+       ADD_DEFINITIONS("-DHAVE_WAYLAND")
+       SET(BUILD_SOURCE 
+               ${BUILD_SOURCE}
+               src/xmonitor_wayland.c
+               src/buffer_handler_wayland.c
+               src/util_wayland.c
+       )
+ENDIF (WAYLAND_SUPPORT)
+
+IF (X11_SUPPORT)
+       ADD_DEFINITIONS("-DHAVE_X11")
+       SET(BUILD_SOURCE 
+               ${BUILD_SOURCE}
+               src/xmonitor.c
+               src/buffer_handler.c
+               src/util_x11.c
+       )
+ENDIF (X11_SUPPORT)
+
+#ADD_DEFINITIONS("-D_APPLY_SCRIPT_ASYNC_UPDATE")
+#ADD_DEFINITIONS("-DFLOG")
+ADD_DEFINITIONS(${pkg_CFLAGS})
+ADD_DEFINITIONS(${pkg_LDFLAGS})
+ADD_DEFINITIONS(${pkg_extra_CFLAGS})
+ADD_DEFINITIONS(${pkg_extra_LDFLAGS})
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${BUILD_SOURCE})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkg_LDFLAGS} ${pkg_extra_LDFLAGS} "-ldl -lrt")
 INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/abi.ini DESTINATION /usr/share/data-provider-master PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
 
 INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/${PRODUCT}.conf.ini DESTINATION /usr/share/data-provider-master RENAME "conf.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
@@ -118,6 +152,10 @@ ADD_SUBDIRECTORY(res)
 ADD_SUBDIRECTORY(data)
 ADD_SUBDIRECTORY(pkgmgr_livebox)
 
-if ("${ENGINEER_BINARY}" STREQUAL "true")
-ADD_SUBDIRECTORY(util_liveinfo)
-endif ("${ENGINEER_BINARY}" STREQUAL "true")
+IF (X11_SUPPORT)
+       IF ("${ENGINEER_BINARY}" STREQUAL "true")
+               ADD_SUBDIRECTORY(util_liveinfo)
+       ENDIF ("${ENGINEER_BINARY}" STREQUAL "true")
+ENDIF (X11_SUPPORT)
+
+# End of a file
index f5e4dd0..4f32a76 100644 (file)
@@ -34,6 +34,10 @@ extern void util_prepare_emergency_disk(void);
 extern int util_emergency_disk_is_mounted(void);
 extern int util_service_is_enabled(const char *tag);
 
+extern int util_screen_size_get(int *width, int *height);
+extern int util_screen_init(void);
+extern int util_screen_fini(void);
+
 #define SCHEMA_FILE    "file://"
 #define SCHEMA_PIXMAP  "pixmap://"
 #define SCHEMA_SHM     "shm://"
index 0df5e7d..9f128f9 100755 (executable)
@@ -1,6 +1,8 @@
+%bcond_with wayland
+
 Name: data-provider-master
 Summary: Master service provider for liveboxes
-Version: 0.35.0
+Version: 0.40.0
 Release: 1
 Group: HomeTF/Livebox
 License: Flora
@@ -17,10 +19,11 @@ BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(gio-2.0)
 BuildRequires: pkgconfig(libsmack)
 BuildRequires: pkgconfig(bundle)
+
+%if %{with wayland}
+BuildRequires: pkgconfig(ecore-wayland)
+%else
 BuildRequires: pkgconfig(ecore-x)
-BuildRequires: pkgconfig(ecore)
-BuildRequires: pkgconfig(com-core)
-BuildRequires: pkgconfig(libxml-2.0)
 BuildRequires: pkgconfig(x11)
 BuildRequires: pkgconfig(libdri2)
 BuildRequires: pkgconfig(libdrm)
@@ -29,6 +32,11 @@ BuildRequires: pkgconfig(xfixes)
 BuildRequires: pkgconfig(dri2proto)
 BuildRequires: pkgconfig(xext)
 BuildRequires: pkgconfig(xdamage)
+%endif
+
+BuildRequires: pkgconfig(ecore)
+BuildRequires: pkgconfig(com-core)
+BuildRequires: pkgconfig(libxml-2.0)
 BuildRequires: pkgconfig(pkgmgr)
 BuildRequires: pkgconfig(livebox-service)
 BuildRequires: pkgconfig(notification)
@@ -70,7 +78,15 @@ export LIVEBOX_SHM=baltic
 export LIVEBOX_SHM=private
 %endif
 
-%cmake . -DPRODUCT=${LIVEBOX_SHM} -DENGINEER_BINARY=${ENGINEER}
+%if %{with wayland}
+export WAYLAND_SUPPORT=On
+export X11_SUPPORT=Off
+%else
+export WAYLAND_SUPPORT=Off
+export X11_SUPPORT=On
+%endif
+
+%cmake . -DPRODUCT=${LIVEBOX_SHM} -DENGINEER_BINARY=${ENGINEER} -DWAYLAND_SUPPORT=${WAYLAND_SUPPORT} -DX11_SUPPORT=${X11_SUPPORT}
 
 CFLAGS="${CFLAGS} -Wall -Winline -Werror" LDFLAGS="${LDFLAGS}" make %{?jobs:-j%jobs}
 
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/src/buffer_handler_wayland.c b/src/buffer_handler_wayland.c
new file mode 100644 (file)
index 0000000..947e1b4
--- /dev/null
@@ -0,0 +1,921 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <unistd.h> /* access */
+#include <sys/mman.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/shm.h>
+#include <sys/ipc.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <Ecore.h>
+
+#include <dlog.h>
+#include <packet.h>
+#include <livebox-errno.h>
+
+#include "debug.h"
+#include "conf.h"
+#include "util.h"
+#include "instance.h"
+#include "package.h"
+#include "client_life.h"
+#include "client_rpc.h"
+#include "buffer_handler.h"
+#include "script_handler.h" // Reverse dependency. must has to be broken
+
+struct buffer {
+       enum {
+               CREATED = 0x00beef00,
+               DESTROYED = 0x00dead00
+       } state;
+       enum buffer_type type;
+       int refcnt;
+       void *info;
+       char data[];
+};
+
+struct buffer_info
+{
+       void *buffer;
+       char *id;
+       char *lock;
+       int lock_fd;
+
+       enum buffer_type type;
+
+       int w;
+       int h;
+       int pixel_size;
+       int is_loaded;
+
+       struct inst_info *inst;
+       void *data;
+};
+
+static int destroy_lock_file(struct buffer_info *info)
+{
+       if (!info->inst) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!info->lock) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (close(info->lock_fd) < 0) {
+               ErrPrint("close: %s\n", strerror(errno));
+       }
+       info->lock_fd = -1;
+
+       if (unlink(info->lock) < 0) {
+               ErrPrint("unlink: %s\n", strerror(errno));
+       }
+
+       DbgFree(info->lock);
+       info->lock = NULL;
+       return LB_STATUS_SUCCESS;
+}
+
+static int create_lock_file(struct buffer_info *info)
+{
+       const char *id;
+       int len;
+       char *file;
+       char target[3] = "pd";
+
+       if (!info->inst) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       id = instance_id(info->inst);
+       if (!id) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       len = strlen(id);
+       file = malloc(len + 20);
+       if (!file) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       if (script_handler_buffer_info(instance_pd_script(info->inst)) != info && instance_pd_buffer(info->inst) != info) {
+               target[0] = 'l';
+               target[1] = 'b';
+               /* target[2] = '\0'; // We already have this ;) */
+       }
+
+       snprintf(file, len + 20, "%s.%s.lck", util_uri_to_path(id), target);
+       info->lock_fd = open(file, O_WRONLY|O_CREAT, 0644);
+       if (info->lock_fd < 0) {
+               ErrPrint("open: %s\n", strerror(errno));
+               DbgFree(file);
+               return LB_STATUS_ERROR_IO;
+       }
+
+       info->lock = file;
+       return LB_STATUS_SUCCESS;
+}
+
+static int do_buffer_lock(struct buffer_info *buffer)
+{
+       struct flock flock;
+       int ret;
+
+       if (buffer->lock_fd < 0) {
+               return LB_STATUS_SUCCESS;
+       }
+
+       flock.l_type = F_WRLCK;
+       flock.l_whence = SEEK_SET;
+       flock.l_start = 0;
+       flock.l_len = 0;
+       flock.l_pid = getpid();
+
+       do {
+               ret = fcntl(buffer->lock_fd, F_SETLKW, &flock);
+               if (ret < 0) {
+                       ret = errno;
+                       ErrPrint("fcntl: %s\n", strerror(errno));
+               }
+       } while (ret == EINTR);
+
+       return LB_STATUS_SUCCESS;
+}
+
+static int do_buffer_unlock(struct buffer_info *buffer)
+{
+       struct flock flock;
+       int ret;
+
+       if (buffer->lock_fd < 0) {
+               return LB_STATUS_SUCCESS;
+       }
+
+       flock.l_type = F_UNLCK;
+       flock.l_whence = SEEK_SET;
+       flock.l_start = 0;
+       flock.l_len = 0;
+       flock.l_pid = getpid();
+
+       do {
+               ret = fcntl(buffer->lock_fd, F_SETLKW, &flock);
+               if (ret < 0) {
+                       ret = errno;
+                       ErrPrint("fcntl: %s\n", strerror(errno));
+               }
+       } while (ret == EINTR);
+
+       return LB_STATUS_SUCCESS;
+}
+
+static inline int load_file_buffer(struct buffer_info *info)
+{
+       struct buffer *buffer;
+       double timestamp;
+       int size;
+       char *new_id;
+       int len;
+
+       len = strlen(IMAGE_PATH) + 40;
+       new_id = malloc(len);
+       if (!new_id) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       timestamp = util_timestamp();
+       snprintf(new_id, len, SCHEMA_FILE "%s%lf", IMAGE_PATH, timestamp);
+
+       size = sizeof(*buffer) + info->w * info->h * info->pixel_size;
+       if (!size) {
+               ErrPrint("Canvas buffer size is ZERO\n");
+               DbgFree(new_id);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       buffer = calloc(1, size);
+       if (!buffer) {
+               ErrPrint("Failed to allocate buffer\n");
+               DbgFree(new_id);
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       buffer->type = BUFFER_TYPE_FILE;
+       buffer->refcnt = 0;
+       buffer->state = CREATED;
+       buffer->info = info;
+
+       DbgFree(info->id);
+       info->id = new_id;
+       info->buffer = buffer;
+       info->is_loaded = 1;
+
+       DbgPrint("FILE type %d created\n", size);
+       return LB_STATUS_SUCCESS;
+}
+
+static inline int load_shm_buffer(struct buffer_info *info)
+{
+       int id;
+       int size;
+       struct buffer *buffer; /* Just for getting a size */
+       char *new_id;
+       int len;
+
+       size = info->w * info->h * info->pixel_size;
+       if (!size) {
+               ErrPrint("Invalid buffer size\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       id = shmget(IPC_PRIVATE, size + sizeof(*buffer), IPC_CREAT | 0666);
+       if (id < 0) {
+               ErrPrint("shmget: %s\n", strerror(errno));
+               return LB_STATUS_ERROR_FAULT;
+       }
+
+       buffer = shmat(id, NULL, 0);
+       if (buffer == (void *)-1) {
+               ErrPrint("%s shmat: %s\n", info->id, strerror(errno));
+
+               if (shmctl(id, IPC_RMID, 0) < 0) {
+                       ErrPrint("%s shmctl: %s\n", info->id, strerror(errno));
+               }
+
+               return LB_STATUS_ERROR_FAULT;
+       }
+
+       buffer->type = BUFFER_TYPE_SHM;
+       buffer->refcnt = id;
+       buffer->state = CREATED; /*!< Needless */
+       buffer->info = (void *)size; /*!< Use this field to indicates the size of SHM */
+
+       len = strlen(SCHEMA_SHM) + 30; /* strlen("shm://") + 30 */
+
+       new_id = malloc(len);
+       if (!new_id) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               if (shmdt(buffer) < 0) {
+                       ErrPrint("shmdt: %s\n", strerror(errno));
+               }
+
+               if (shmctl(id, IPC_RMID, 0) < 0) {
+                       ErrPrint("shmctl: %s\n", strerror(errno));
+               }
+
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       snprintf(new_id, len, SCHEMA_SHM "%d", id);
+
+       DbgFree(info->id);
+       info->id = new_id;
+       info->buffer = buffer;
+       info->is_loaded = 1;
+       return LB_STATUS_SUCCESS;
+}
+
+EAPI int buffer_handler_load(struct buffer_info *info)
+{
+       int ret;
+
+       if (!info) {
+               ErrPrint("buffer handler is nil\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (info->is_loaded) {
+               DbgPrint("Buffer is already loaded\n");
+               return LB_STATUS_SUCCESS;
+       }
+
+       switch (info->type) {
+       case BUFFER_TYPE_FILE:
+               ret = load_file_buffer(info);
+               (void)create_lock_file(info);
+               break;
+       case BUFFER_TYPE_SHM:
+               ret = load_shm_buffer(info);
+               (void)create_lock_file(info);
+               break;
+       case BUFFER_TYPE_PIXMAP:
+       default:
+               ErrPrint("Invalid buffer\n");
+               ret = LB_STATUS_ERROR_INVALID;
+               break;
+       }
+
+       return ret;
+}
+
+static inline int unload_file_buffer(struct buffer_info *info)
+{
+       const char *path;
+       char *new_id;
+
+       new_id = strdup(SCHEMA_FILE "/tmp/.live.undefined");
+       if (!new_id) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       DbgFree(info->buffer);
+       info->buffer = NULL;
+
+       path = util_uri_to_path(info->id);
+       if (path && unlink(path) < 0) {
+               ErrPrint("unlink: %s\n", strerror(errno));
+       }
+
+       DbgFree(info->id);
+       info->id = new_id;
+       return LB_STATUS_SUCCESS;
+}
+
+static inline int unload_shm_buffer(struct buffer_info *info)
+{
+       int id;
+       char *new_id;
+
+       new_id = strdup(SCHEMA_SHM "-1");
+       if (!new_id) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       if (sscanf(info->id, SCHEMA_SHM "%d", &id) != 1) {
+               ErrPrint("%s Invalid ID\n", info->id);
+               DbgFree(new_id);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (id < 0) {
+               ErrPrint("(%s) Invalid id: %d\n", info->id, id);
+               DbgFree(new_id);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (shmdt(info->buffer) < 0) {
+               ErrPrint("Detach shm: %s\n", strerror(errno));
+       }
+
+       if (shmctl(id, IPC_RMID, 0) < 0) {
+               ErrPrint("Remove shm: %s\n", strerror(errno));
+       }
+
+       info->buffer = NULL;
+
+       DbgFree(info->id);
+       info->id = new_id;
+       return LB_STATUS_SUCCESS;
+}
+
+EAPI int buffer_handler_unload(struct buffer_info *info)
+{
+       int ret;
+
+       if (!info) {
+               ErrPrint("buffer handler is NIL\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!info->is_loaded) {
+               ErrPrint("Buffer is not loaded\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       switch (info->type) {
+       case BUFFER_TYPE_FILE:
+               (void)destroy_lock_file(info);
+               ret = unload_file_buffer(info);
+               break;
+       case BUFFER_TYPE_SHM:
+               (void)destroy_lock_file(info);
+               ret = unload_shm_buffer(info);
+               break;
+       case BUFFER_TYPE_PIXMAP:
+       default:
+               ErrPrint("Invalid buffer\n");
+               ret = LB_STATUS_ERROR_INVALID;
+               break;
+       }
+
+       if (ret == 0) {
+               info->is_loaded = 0;
+       }
+
+       return ret;
+}
+
+EAPI const char *buffer_handler_id(const struct buffer_info *info)
+{
+       return info ? info->id : "";
+}
+
+EAPI enum buffer_type buffer_handler_type(const struct buffer_info *info)
+{
+       return info ? info->type : BUFFER_TYPE_ERROR;
+}
+
+EAPI void *buffer_handler_fb(struct buffer_info *info)
+{
+       struct buffer *buffer;
+
+       if (!info) {
+               return NULL;
+       }
+
+       buffer = info->buffer;
+
+       if (info->type == BUFFER_TYPE_PIXMAP) {
+               return NULL;
+       }
+
+       return buffer->data;
+}
+
+EAPI int buffer_handler_pixmap(const struct buffer_info *info)
+{
+       return 0;
+}
+
+EAPI void *buffer_handler_pixmap_acquire_buffer(struct buffer_info *info)
+{
+       return NULL;
+}
+
+EAPI void *buffer_handler_pixmap_buffer(struct buffer_info *info)
+{
+       return NULL;
+}
+
+/*!
+ * \return "buffer" object (Not the buffer_info)
+ */
+EAPI void *buffer_handler_pixmap_ref(struct buffer_info *info)
+{
+       return NULL;
+}
+
+/*!
+ * \return "buffer"
+ */
+EAPI void *buffer_handler_pixmap_find(int pixmap)
+{
+       return NULL;
+}
+
+EAPI int buffer_handler_pixmap_release_buffer(void *canvas)
+{
+       return LB_STATUS_ERROR_NOT_EXIST;
+}
+
+/*!
+ * \note
+ *
+ * \return Return NULL if the buffer is in still uses.
+ *        Return buffer_ptr if it needs to destroy
+ */
+EAPI int buffer_handler_pixmap_unref(void *buffer_ptr)
+{
+       return LB_STATUS_SUCCESS;
+}
+
+EAPI int buffer_handler_is_loaded(const struct buffer_info *info)
+{
+       return info ? info->is_loaded : 0;
+}
+
+EAPI void buffer_handler_update_size(struct buffer_info *info, int w, int h)
+{
+       if (!info) {
+               return;
+       }
+
+       info->w = w;
+       info->h = h;
+}
+
+EAPI int buffer_handler_resize(struct buffer_info *info, int w, int h)
+{
+       int ret;
+
+       if (!info) {
+               ErrPrint("Invalid handler\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (info->w == w && info->h == h) {
+               DbgPrint("No changes\n");
+               return LB_STATUS_SUCCESS;
+       }
+
+       buffer_handler_update_size(info, w, h);
+
+       if (!info->is_loaded) {
+               DbgPrint("Buffer size is updated[%dx%d]\n", w, h);
+               return LB_STATUS_SUCCESS;
+       }
+
+       ret = buffer_handler_unload(info);
+       if (ret < 0) {
+               ErrPrint("Unload: %d\n", ret);
+       }
+
+       ret = buffer_handler_load(info);
+       if (ret < 0) {
+               ErrPrint("Load: %d\n", ret);
+       }
+
+       return LB_STATUS_SUCCESS;
+}
+
+EAPI int buffer_handler_get_size(struct buffer_info *info, int *w, int *h)
+{
+       if (!info) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (w) {
+               *w = info->w;
+       }
+       if (h) {
+               *h = info->h;
+       }
+
+       return LB_STATUS_SUCCESS;
+}
+
+EAPI struct inst_info *buffer_handler_instance(struct buffer_info *info)
+{
+       return info->inst;
+}
+
+EAPI void buffer_handler_flush(struct buffer_info *info)
+{
+       int fd;
+       int size;
+       struct buffer *buffer;
+
+       if (!info || !info->buffer) {
+               return;
+       }
+
+       buffer = info->buffer;
+
+       if (buffer->type == BUFFER_TYPE_PIXMAP) {
+               /*!
+                * \note
+                * Not supported for wayland or this should be ported correctly
+                */
+       } else if (buffer->type == BUFFER_TYPE_FILE) {
+               fd = open(util_uri_to_path(info->id), O_WRONLY | O_CREAT, 0644);
+               if (fd < 0) {
+                       ErrPrint("%s open falied: %s\n", util_uri_to_path(info->id), strerror(errno));
+                       return;
+               }
+
+               size = info->w * info->h * info->pixel_size;
+               do_buffer_lock(info);
+               if (write(fd, info->buffer, size) != size) {
+                       ErrPrint("Write is not completed: %s\n", strerror(errno));
+               }
+               do_buffer_unlock(info);
+
+               if (close(fd) < 0) {
+                       ErrPrint("close: %s\n", strerror(errno));
+               }
+       } else {
+               DbgPrint("Flush nothing\n");
+       }
+}
+
+HAPI int buffer_handler_init(void)
+{
+       /*!
+        * \TODO
+        * Implement this for wayland
+        */
+       if (USE_SW_BACKEND) {
+               DbgPrint("Fallback to the S/W Backend\n");
+               return LB_STATUS_SUCCESS;
+       }
+
+       return LB_STATUS_SUCCESS;
+}
+
+HAPI int buffer_handler_fini(void)
+{
+       /*!
+        * \TODO
+        * Implement this for wayland
+        */
+       return LB_STATUS_SUCCESS;
+}
+
+static inline struct buffer *raw_open_file(const char *filename)
+{
+       struct buffer *buffer;
+       int fd;
+       off_t off;
+       int ret;
+
+       fd = open(filename, O_RDONLY);
+       if (fd < 0) {
+               ErrPrint("open: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       off = lseek(fd, 0L, SEEK_END);
+       if (off == (off_t)-1) {
+               ErrPrint("lseek: %s\n", strerror(errno));
+
+               if (close(fd) < 0) {
+                       ErrPrint("close: %s\n", strerror(errno));
+               }
+
+               return NULL;
+       }
+
+       if (lseek(fd, 0L, SEEK_SET) == (off_t)-1) {
+               ErrPrint("lseek: %s\n", strerror(errno));
+
+               if (close(fd) < 0) {
+                       ErrPrint("close: %s\n", strerror(errno));
+               }
+
+               return NULL;
+       }
+
+       buffer = calloc(1, sizeof(*buffer) + off);
+       if (!buffer) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+
+               if (close(fd) < 0) {
+                       ErrPrint("close: %s\n", strerror(errno));
+               }
+
+               return NULL;
+       }
+
+       buffer->state = CREATED;
+       buffer->type = BUFFER_TYPE_FILE;
+       buffer->refcnt = 0;
+       buffer->info = (void *)off;
+
+       ret = read(fd, buffer->data, off);
+       if (ret < 0) {
+               ErrPrint("read: %s\n", strerror(errno));
+               DbgFree(buffer);
+
+               if (close(fd) < 0) {
+                       ErrPrint("close: %s\n", strerror(errno));
+               }
+
+               return NULL;
+       }
+
+       if (close(fd) < 0) {
+               ErrPrint("close: %s\n", strerror(errno));
+       }
+
+       return buffer;
+}
+
+static inline int raw_close_file(struct buffer *buffer)
+{
+       DbgFree(buffer);
+       return 0;
+}
+
+static inline struct buffer *raw_open_shm(int shm)
+{
+       struct buffer *buffer;
+
+       buffer = (struct buffer *)shmat(shm, NULL, SHM_RDONLY);
+       if (buffer == (struct buffer *)-1) {
+               ErrPrint("shmat: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       return buffer;
+}
+
+static inline int raw_close_shm(struct buffer *buffer)
+{
+       int ret;
+
+       ret = shmdt(buffer);
+       if (ret < 0) {
+               ErrPrint("shmdt: %s\n", strerror(errno));
+       }
+
+       return ret;
+}
+
+EAPI void *buffer_handler_raw_data(struct buffer *buffer)
+{
+       if (!buffer || buffer->state != CREATED) {
+               return NULL;
+       }
+
+       return buffer->data;
+}
+
+EAPI int buffer_handler_raw_size(struct buffer *buffer)
+{
+       if (!buffer || buffer->state != CREATED) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       return (int)buffer->info;
+}
+
+EAPI struct buffer *buffer_handler_raw_open(enum buffer_type buffer_type, void *resource)
+{
+       struct buffer *handle;
+
+       switch (buffer_type) {
+       case BUFFER_TYPE_SHM:
+               handle = raw_open_shm((int)resource);
+               break;
+       case BUFFER_TYPE_FILE:
+               handle = raw_open_file(resource);
+               break;
+       case BUFFER_TYPE_PIXMAP:
+       default:
+               handle = NULL;
+               break;
+       }
+
+       return handle;
+}
+
+EAPI int buffer_handler_raw_close(struct buffer *buffer)
+{
+       int ret;
+
+       switch (buffer->type) {
+       case BUFFER_TYPE_SHM:
+               ret = raw_close_shm(buffer);
+               break;
+       case BUFFER_TYPE_FILE:
+               ret = raw_close_file(buffer);
+               break;
+       case BUFFER_TYPE_PIXMAP:
+       default:
+               ret = LB_STATUS_ERROR_INVALID;
+               break;
+       }
+
+       return ret;
+}
+
+EAPI int buffer_handler_lock(struct buffer_info *buffer)
+{
+       if (buffer->type == BUFFER_TYPE_PIXMAP) {
+               return LB_STATUS_SUCCESS;
+       }
+
+       if (buffer->type == BUFFER_TYPE_FILE) {
+               return LB_STATUS_SUCCESS;
+       }
+
+       return do_buffer_lock(buffer);
+}
+
+EAPI int buffer_handler_unlock(struct buffer_info *buffer)
+{
+       if (buffer->type == BUFFER_TYPE_PIXMAP) {
+               return LB_STATUS_SUCCESS;
+       }
+
+       if (buffer->type == BUFFER_TYPE_FILE) {
+               return LB_STATUS_SUCCESS;
+       }
+
+       return do_buffer_unlock(buffer);
+}
+
+/*!
+ * \note
+ * Only can be used by master.
+ * Plugin cannot access the user data
+ */
+
+HAPI int buffer_handler_set_data(struct buffer_info *buffer, void *data)
+{
+       if (!buffer) {
+               ErrPrint("Invalid handle\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       buffer->data = data;
+       return LB_STATUS_SUCCESS;
+}
+
+HAPI void *buffer_handler_data(struct buffer_info *buffer)
+{
+       if (!buffer) {
+               ErrPrint("Invalid handle\n");
+               return NULL;
+       }
+
+       return buffer->data;
+}
+
+HAPI int buffer_handler_destroy(struct buffer_info *info)
+{
+       Eina_List *l;
+       struct buffer *buffer;
+
+       if (!info) {
+               DbgPrint("Buffer is not created yet. info is NIL\n");
+               return LB_STATUS_SUCCESS;
+       }
+
+       buffer_handler_unload(info);
+       DbgFree(info->id);
+       DbgFree(info);
+       return LB_STATUS_SUCCESS;
+}
+
+HAPI struct buffer_info *buffer_handler_create(struct inst_info *inst, enum buffer_type type, int w, int h, int pixel_size)
+{
+       struct buffer_info *info;
+
+       info = malloc(sizeof(*info));
+       if (!info) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       switch (type) {
+       case BUFFER_TYPE_SHM:
+               if (pixel_size != DEFAULT_PIXELS) {
+                       DbgPrint("SHM only supportes %d bytes pixels (requested: %d)\n", DEFAULT_PIXELS, pixel_size);
+                       pixel_size = DEFAULT_PIXELS;
+               }
+
+               info->id = strdup(SCHEMA_SHM "-1");
+               if (!info->id) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       DbgFree(info);
+                       return NULL;
+               }
+               break;
+       case BUFFER_TYPE_FILE:
+               if (pixel_size != DEFAULT_PIXELS) {
+                       DbgPrint("FILE only supportes %d bytes pixels (requested: %d)\n", DEFAULT_PIXELS, pixel_size);
+                       pixel_size = DEFAULT_PIXELS;
+               }
+
+               info->id = strdup(SCHEMA_FILE "/tmp/.live.undefined");
+               if (!info->id) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       DbgFree(info);
+                       return NULL;
+               }
+               break;
+       case BUFFER_TYPE_PIXMAP:
+       default:
+               ErrPrint("Invalid type\n");
+               DbgFree(info);
+               return NULL;
+       }
+
+       info->lock = NULL;
+       info->lock_fd = -1;
+       info->w = w;
+       info->h = h;
+       info->pixel_size = pixel_size;
+       info->type = type;
+       info->is_loaded = 0;
+       info->inst = inst;
+       info->buffer = NULL;
+       info->data = NULL;
+
+       return info;
+}
+
+/* End of a file */
index 35fcf72..faf289d 100644 (file)
  * limitations under the License.
  */
 
-#include <Ecore_X.h>
+#include <stdio.h>
 #include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
 
 #include <dlog.h>
 #include <livebox-errno.h>
+#include <Eina.h>
 
 #include "conf.h"
 #include "util.h"
@@ -76,11 +80,13 @@ static const double CONF_DEFAULT_SCALE_HEIGHT_FACTOR = 1.0f;
 static const double CONF_DEFAULT_PD_REQUEST_TIMEOUT = 5.0f;
 static const int CONF_DEFAULT_PIXELS = sizeof(int);
 
+int errno;
+
 HAPI struct conf g_conf;
 
 HAPI void conf_update_size(void)
 {
-       ecore_x_window_size_get(0, &g_conf.width, &g_conf.height);
+       util_screen_size_get(&g_conf.width, &g_conf.height);
 
        g_conf.scale_width_factor = (double)g_conf.width / (double)BASE_W;
        g_conf.scale_height_factor = (double)g_conf.height / (double)BASE_H;
old mode 100755 (executable)
new mode 100644 (file)
index 7fb5262..ff6b4fb
@@ -24,7 +24,6 @@
 #include <ctype.h>
 
 #include <Ecore.h>
-#include <Ecore_X.h>
 #include <glib.h>
 #include <glib-object.h>
 #include <aul.h>
@@ -390,7 +389,7 @@ int main(int argc, char *argv[])
                CRITICAL_LOG("Signal handler initiated: %d\n", ret);
        }
 
-       if (ecore_x_init(NULL) <= 0) {
+       if (util_screen_init() <= 0) {
                CRITICAL_LOG("Failed to ecore x init\n");
                ecore_shutdown();
                critical_log_fini();
@@ -405,7 +404,7 @@ int main(int argc, char *argv[])
 
        /*!
         * \note
-        * conf_update_size requires ecore_x_init.
+        * conf_update_size requires util_screen_init.
         */
        conf_update_size();
 
@@ -421,7 +420,7 @@ int main(int argc, char *argv[])
 
        app_terminate();
 
-       ecore_x_shutdown();
+       util_screen_fini();
 
        if (signal_handler) {
                ecore_main_fd_handler_del(signal_handler);
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/src/util_wayland.c b/src/util_wayland.c
new file mode 100644 (file)
index 0000000..14a1f8a
--- /dev/null
@@ -0,0 +1,20 @@
+#include "util.h"
+
+int util_screen_size_get(int *width, int *height)
+{
+       *width = 0;
+       *height = 0;
+       return LB_STATUS_ERROR_NOT_IMPLEMENTED;
+}
+
+int util_screen_init(void)
+{
+       return LB_STATUS_SUCCESS;
+}
+
+int util_screen_fini(void)
+{
+       return LB_STATUS_SUCCESS;
+}
+
+/* End of a file */
diff --git a/src/util_x11.c b/src/util_x11.c
new file mode 100644 (file)
index 0000000..45d8b74
--- /dev/null
@@ -0,0 +1,23 @@
+#include <Ecore_X.h>
+
+#include <livebox-errno.h>
+#include "util.h"
+
+int util_screen_size_get(int *width, int *height)
+{
+       ecore_x_window_size_get(0, width, height);
+       return LB_STATUS_SUCCESS;
+}
+
+int util_screen_init(void)
+{
+       return ecore_x_init(NULL);
+}
+
+int util_screen_fini(void)
+{
+       return ecore_x_shutdown();
+}
+
+/* End of a file */
+
diff --git a/src/xmonitor_wayland.c b/src/xmonitor_wayland.c
new file mode 100644 (file)
index 0000000..488a3d3
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <assert.h>
+#include <errno.h>
+#include <malloc.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <sqlite3.h>
+
+#include <gio/gio.h>
+#include <dlog.h>
+#include <livebox-errno.h>
+
+#include "conf.h"
+#include "debug.h"
+#include "client_life.h"
+#include "slave_life.h"
+#include "main.h"
+#include "util.h"
+#include "setting.h"
+#include "xmonitor.h"
+
+int errno;
+
+struct event_item {
+       int (*cb)(void *user_data);
+       void *user_data;
+};
+
+static struct info {
+       Ecore_Event_Handler *create_handler;
+       Ecore_Event_Handler *destroy_handler;
+       Ecore_Event_Handler *client_handler;
+
+       Eina_List *pause_list;
+       Eina_List *resume_list;
+
+       int paused;
+} s_info = {
+       .create_handler = NULL,
+       .destroy_handler = NULL,
+       .client_handler = NULL,
+
+       .pause_list = NULL,
+       .resume_list = NULL,
+
+       .paused = 1, /*!< The provider is treated as paused process when it is launched */
+};
+
+static inline void touch_paused_file(void)
+{
+       int fd;
+       fd = creat(PAUSED_FILE, 0644);
+       if (fd >= 0) {
+               if (close(fd) < 0) {
+                       ErrPrint("close: %s\n", strerror(errno));
+               }
+       } else {
+               ErrPrint("Create .live.paused: %s\n", strerror(errno));
+       }
+}
+
+static inline void remove_paused_file(void)
+{
+       if (unlink(PAUSED_FILE) < 0) {
+               ErrPrint("Unlink .live.paused: %s\n", strerror(errno));
+       }
+}
+
+HAPI void xmonitor_handle_state_changes(void)
+{
+       int paused;
+       Eina_List *l;
+       struct event_item *item;
+
+       paused = client_is_all_paused() || setting_is_lcd_off();
+       if (s_info.paused == paused) {
+               return;
+       }
+
+       s_info.paused = paused;
+
+       if (s_info.paused) {
+               EINA_LIST_FOREACH(s_info.pause_list, l, item) {
+                       if (item->cb) {
+                               item->cb(item->user_data);
+                       }
+               }
+
+               touch_paused_file();
+
+               sqlite3_release_memory(SQLITE_FLUSH_MAX);
+               malloc_trim(0);
+       } else {
+               remove_paused_file();
+
+               EINA_LIST_FOREACH(s_info.resume_list, l, item) {
+                       if (item->cb) {
+                               item->cb(item->user_data);
+                       }
+               }
+       }
+}
+
+HAPI int xmonitor_update_state(int target_pid)
+{
+       struct client_node *client;
+
+       if (!USE_XMONITOR || target_pid < 0) {
+               return LB_STATUS_SUCCESS;
+       }
+
+       /*!
+        * \TODO
+        * Find the top(focuesd) window's PID
+        * Compare it with target_pid.
+        * If it is what we finding, call the
+        * xmonitor_pause or xmonitor_resume
+        */
+
+       xmonitor_handle_state_changes();
+       return LB_STATUS_SUCCESS;
+}
+
+HAPI int xmonitor_pause(struct client_node *client)
+{
+       DbgPrint("%d is paused\n", client_pid(client));
+       client_paused(client);
+       xmonitor_handle_state_changes();
+       return LB_STATUS_SUCCESS;
+}
+
+HAPI int xmonitor_resume(struct client_node *client)
+{
+       DbgPrint("%d is resumed\n", client_pid(client));
+       client_resumed(client);
+       xmonitor_handle_state_changes();
+       return LB_STATUS_SUCCESS;
+}
+
+HAPI int xmonitor_init(void)
+{
+       if (USE_XMONITOR) {
+               return LB_STATUS_SUCCESS;
+       }
+
+       s_info.paused = client_is_all_paused() || setting_is_lcd_off();
+       if (s_info.paused) {
+               touch_paused_file();
+       } else {
+               remove_paused_file();
+       }
+
+       return LB_STATUS_SUCCESS;
+}
+
+HAPI void xmonitor_fini(void)
+{
+       if (USE_XMONITOR) {
+       }
+}
+
+HAPI int xmonitor_add_event_callback(enum xmonitor_event event, int (*cb)(void *user_data), void *user_data)
+{
+       struct event_item *item;
+
+       item = malloc(sizeof(*item));
+       if (!item) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       item->cb = cb;
+       item->user_data = user_data;
+
+       switch (event) {
+       case XMONITOR_PAUSED:
+               s_info.pause_list = eina_list_prepend(s_info.pause_list, item);
+               break;
+       case XMONITOR_RESUMED:
+               s_info.resume_list = eina_list_prepend(s_info.resume_list, item);
+               break;
+       default:
+               ErrPrint("Invalid event type\n");
+               DbgFree(item);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       return LB_STATUS_SUCCESS;
+}
+
+HAPI int xmonitor_del_event_callback(enum xmonitor_event event, int (*cb)(void *user_data), void *user_data)
+{
+       struct event_item *item;
+       Eina_List *l;
+       Eina_List *n;
+
+       switch (event) {
+       case XMONITOR_PAUSED:
+               EINA_LIST_FOREACH_SAFE(s_info.pause_list, l, n, item) {
+                       if (item->cb == cb && item->user_data == user_data) {
+                               s_info.pause_list = eina_list_remove(s_info.pause_list, item);
+                               DbgFree(item);
+                               return LB_STATUS_SUCCESS;
+                       }
+               }
+               break;
+
+       case XMONITOR_RESUMED:
+               EINA_LIST_FOREACH_SAFE(s_info.resume_list, l, n, item) {
+                       if (item->cb == cb && item->user_data == user_data) {
+                               s_info.resume_list = eina_list_remove(s_info.resume_list, item);
+                               DbgFree(item);
+                               return LB_STATUS_SUCCESS;
+                       }
+               }
+               break;
+       default:
+               ErrPrint("Invalid event type\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       return LB_STATUS_ERROR_NOT_EXIST;
+}
+
+HAPI int xmonitor_is_paused(void)
+{
+       return s_info.paused;
+}
+
+/* End of a file */
+