From 4754d62c2357fe309cf5f2c692f83d5e46ab813f Mon Sep 17 00:00:00 2001 From: Sung-jae Park Date: Thu, 6 Mar 2014 16:04:36 +0900 Subject: [PATCH] Enable wayland build Pixmap is not able to be used in wayland world. Change-Id: I0ad28017f7f7bfd53f0ce71491f04b16a4c52b14 --- CMakeLists.txt | 78 ++- include/util.h | 4 + packaging/data-provider-master.spec | 26 +- src/badge_service.c | 0 src/buffer_handler_wayland.c | 921 ++++++++++++++++++++++++++++++++++++ src/conf.c | 10 +- src/main.c | 7 +- src/notification_service.c | 0 src/util_wayland.c | 20 + src/util_x11.c | 23 + src/xmonitor_wayland.c | 251 ++++++++++ 11 files changed, 1309 insertions(+), 31 deletions(-) mode change 100755 => 100644 src/badge_service.c create mode 100644 src/buffer_handler_wayland.c mode change 100755 => 100644 src/main.c mode change 100755 => 100644 src/notification_service.c create mode 100644 src/util_wayland.c create mode 100644 src/util_x11.c create mode 100644 src/xmonitor_wayland.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d4d7f6..671d11a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/include/util.h b/include/util.h index f5e4dd0..4f32a76 100644 --- a/include/util.h +++ b/include/util.h @@ -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://" diff --git a/packaging/data-provider-master.spec b/packaging/data-provider-master.spec index 0df5e7d..9f128f9 100755 --- a/packaging/data-provider-master.spec +++ b/packaging/data-provider-master.spec @@ -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} diff --git a/src/badge_service.c b/src/badge_service.c old mode 100755 new mode 100644 diff --git a/src/buffer_handler_wayland.c b/src/buffer_handler_wayland.c new file mode 100644 index 0000000..947e1b4 --- /dev/null +++ b/src/buffer_handler_wayland.c @@ -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 +#include /* access */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#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 */ diff --git a/src/conf.c b/src/conf.c index 35fcf72..faf289d 100644 --- a/src/conf.c +++ b/src/conf.c @@ -14,11 +14,15 @@ * limitations under the License. */ -#include +#include #include +#include +#include +#include #include #include +#include #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; diff --git a/src/main.c b/src/main.c old mode 100755 new mode 100644 index 7fb5262..ff6b4fb --- a/src/main.c +++ b/src/main.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -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); diff --git a/src/notification_service.c b/src/notification_service.c old mode 100755 new mode 100644 diff --git a/src/util_wayland.c b/src/util_wayland.c new file mode 100644 index 0000000..14a1f8a --- /dev/null +++ b/src/util_wayland.c @@ -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 index 0000000..45d8b74 --- /dev/null +++ b/src/util_x11.c @@ -0,0 +1,23 @@ +#include + +#include +#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 index 0000000..488a3d3 --- /dev/null +++ b/src/xmonitor_wayland.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#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 */ + -- 2.7.4