Implement the PIXMAP based content sharing.
authorSung-jae Park <nicesj.park@samsung.com>
Mon, 27 Aug 2012 08:01:36 +0000 (17:01 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Wed, 29 Aug 2012 07:01:39 +0000 (16:01 +0900)
Change-Id: I32912b35f886ed724cca864198e231bb0cb0adf9

CMakeLists.txt
include/fb.h
include/livebox.h
live-viewer/src/CLiveBox.cpp
live-viewer/src/CLiveBoxMgr.cpp
packaging/liblivebox-viewer.spec
src/fb.c
src/livebox.c

index e406b02..7ef0a8e 100644 (file)
@@ -20,6 +20,8 @@ pkg_check_modules(pkgs REQUIRED
        glib-2.0
        gio-2.0
        com-core
+       x11
+       xext
 )
 
 FOREACH(flag ${pkgs_CFLAGS})
index f60954a..15f1844 100644 (file)
@@ -7,7 +7,7 @@ enum buffer_type { /*!< Must have to be sync with libprovider, liblivebox-viewer
        BUFFER_TYPE_ERROR,
 };
 
-extern int fb_init(void);
+extern int fb_init(void *disp);
 extern int fb_fini(void);
 extern const char *fb_id(struct fb_info *info);
 extern int fb_get_size(struct fb_info *info, int *w, int *h);
index 149256e..cf6eb08 100644 (file)
@@ -50,6 +50,7 @@ enum livebox_lb_type {
        LB_TYPE_IMAGE = 0x01,
        LB_TYPE_BUFFER = 0x02,
        LB_TYPE_TEXT = 0x04,
+       LB_TYPE_PIXMAP = 0x08,
 
        LB_TYPE_INVALID = 0xFF,
 };
@@ -57,6 +58,7 @@ enum livebox_lb_type {
 enum livebox_pd_type {
        PD_TYPE_BUFFER = 0x01,
        PD_TYPE_TEXT = 0x02,
+       PD_TYPE_PIXMAP = 0x04,
 
        PD_TYPE_INVALID = 0xFF,
 };
@@ -88,7 +90,7 @@ typedef void (*ret_cb_t)(struct livebox *handle, int ret, void *data);
  * \brief Initialize the livebox system
  * \return
  */
-extern int livebox_init(void);
+extern int livebox_init(void *disp);
 
 /*!
  * \brief Finalize the livebox system
@@ -543,6 +545,20 @@ extern int livebox_enumerate_category_list(const char *cluster, void (*cb)(const
  */
 extern int livebox_refresh_group(const char *cluster, const char *category);
 
+/*!
+ * Get the PIXMAP ID of the livebox content
+ * \param[in] livebox handler
+ * \return int pixmap ID of a content
+ */
+extern int livebox_lb_pixmap(struct livebox *handler);
+
+/*!
+ * Get the PIXMAP ID of the PD content
+ * \param[in] livebox handler
+ * \return int pixmap ID of a content
+ */
+extern int livebox_pd_pixmap(struct livebox *handler);
+
 #ifdef __cplusplus
 }
 #endif
index a501884..bdfb724 100644 (file)
@@ -55,12 +55,14 @@ static void s_OnLBMouseDown(void *data, Evas *e, Evas_Object *obj, void *event_i
        Evas_Event_Mouse_Down *down = (Evas_Event_Mouse_Down *)event_info;
        CLiveBox *box = (CLiveBox *)data;
        struct livebox *handler;
+       enum livebox_lb_type type;
 
        handler = box->Handler();
        if (!handler)
                return;
 
-       if (livebox_lb_type(handler) == LB_TYPE_BUFFER) {
+       type = livebox_lb_type(handler);
+       if (type == LB_TYPE_BUFFER || type == LB_TYPE_PIXMAP) {
                int ix, iy, iw, ih;
                double rx, ry;
                evas_object_geometry_get(obj, &ix, &iy, &iw, &ih);
@@ -77,12 +79,14 @@ static void s_OnLBMouseMove(void *data, Evas *e, Evas_Object *obj, void *event_i
        Evas_Event_Mouse_Move *move = (Evas_Event_Mouse_Move *)event_info;
        CLiveBox *box = (CLiveBox *)data;
        struct livebox *handler;
+       enum livebox_lb_type type;
 
        handler = box->Handler();
        if (!handler)
                return;
 
-       if (livebox_lb_type(handler) == LB_TYPE_BUFFER) {
+       type = livebox_lb_type(handler);
+       if (type == LB_TYPE_BUFFER || type == LB_TYPE_PIXMAP) {
                int ix, iy, iw, ih;
                double rx, ry;
                evas_object_geometry_get(obj, &ix, &iy, &iw, &ih);
@@ -99,6 +103,7 @@ static void s_OnLBMouseUp(void *data, Evas *e, Evas_Object *obj, void *event_inf
        Evas_Event_Mouse_Up *up = (Evas_Event_Mouse_Up *)event_info;
        CLiveBox *box = (CLiveBox *)data;
        struct livebox *handler;
+       enum livebox_lb_type type;
 
        handler = box->Handler();
        if (!handler)
@@ -111,7 +116,8 @@ static void s_OnLBMouseUp(void *data, Evas *e, Evas_Object *obj, void *event_inf
        rx = (double)(up->canvas.x - ix) / (double)iw;
        ry = (double)(up->canvas.y - iy) / (double)ih;
 
-       if (livebox_lb_type(handler) == LB_TYPE_BUFFER)
+       type = livebox_lb_type(handler);
+       if (type == LB_TYPE_BUFFER || type == LB_TYPE_PIXMAP)
                livebox_content_event(handler, LB_MOUSE_UP, rx, ry);
        else
                livebox_click(handler, rx, ry);
@@ -339,6 +345,7 @@ void CLiveBox::OnUpdateLB(void)
        int w, h;
        int ow, oh;
        char buffer[LOGSIZE];
+       enum livebox_lb_type type;
 
        if (!m_pIconSlot || !m_pLBImage)
                return;
@@ -358,7 +365,8 @@ void CLiveBox::OnUpdateLB(void)
        if (w == 0 && h == 0)
                return;
 
-       if (livebox_lb_type(m_pHandler) == LB_TYPE_BUFFER) {
+       type = livebox_lb_type(m_pHandler);
+       if (type == LB_TYPE_BUFFER || type == LB_TYPE_PIXMAP) {
                void *data;
 
                data = livebox_acquire_fb(m_pHandler);
@@ -445,6 +453,7 @@ void CLiveBox::OnUpdatePD(void)
        int w;
        int h;
        char buffer[LOGSIZE];
+       enum livebox_pd_type type;
 
        if (!m_pPDImage)
                return;
@@ -452,7 +461,7 @@ void CLiveBox::OnUpdatePD(void)
        if (livebox_get_pdsize(m_pHandler, &w, &h) < 0)
                return;
 
-       snprintf(buffer, sizeof(buffer), "PD size %dx%d", w, h);
+       snprintf(buffer, sizeof(buffer), "PD Updated (%dx%d)", w, h);
        CMain::GetInstance()->AppendLog(buffer);
 
        if (w < 0 || h < 0)
@@ -464,7 +473,8 @@ void CLiveBox::OnUpdatePD(void)
        if (w == 0 && h == 0)
                return;
 
-       if (livebox_pd_type(m_pHandler) == PD_TYPE_BUFFER) {
+       type = livebox_pd_type(m_pHandler);
+       if (type == PD_TYPE_BUFFER || type == PD_TYPE_PIXMAP) {
                void *data;
 
                data = livebox_acquire_pdfb(m_pHandler);
index 68b249f..3adce6a 100644 (file)
@@ -1,4 +1,5 @@
 #include <Elementary.h>
+#include <Ecore_X.h>
 #include <libgen.h>
 
 #include <livebox.h>
@@ -28,7 +29,7 @@ static int s_FaultHandler(const char *event, const char *pkgname, const char *fi
 
 CLiveBoxMgr::CLiveBoxMgr(void)
 {
-       livebox_init();
+       livebox_init(ecore_x_display_get());
        livebox_event_handler_set(s_EventHandler, this);
        livebox_fault_handler_set(s_FaultHandler, this);
        CResourceMgr::GetInstance()->RegisterObject("LiveBoxMgr", this);
index f16bbe3..f53c58d 100644 (file)
@@ -11,7 +11,8 @@ BuildRequires: pkgconfig(aul)
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(gio-2.0)
 BuildRequires: pkgconfig(com-core)
-BuildRequires: pkgconfig(elementary)
+BuildRequires: pkgconfig(x11)
+BuildRequires: pkgconfig(xext)
 
 %description
 Livebox viewer development library
index 21ec858..5ecee63 100644 (file)
--- a/src/fb.c
+++ b/src/fb.c
 #include <sys/shm.h>
 #include <sys/ipc.h>
 
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+#include <X11/Xutil.h>
+
 #include <dlog.h>
 
 #include "debug.h"
@@ -25,7 +29,7 @@ struct fb_info {
        int w;
        int h;
        int bufsz;
-       struct buffer *buffer;
+       void *buffer;
 
        int handle;
 };
@@ -40,81 +44,203 @@ struct buffer { /*!< Must has to be sync with slave & provider */
        char data[];
 };
 
-int fb_init(void)
+static struct {
+       Display *disp;
+       int screen;
+       int depth;
+       Visual *visual;
+       int disp_is_opened;
+} s_info = {
+       .disp = NULL,
+       .disp_is_opened = 0,
+       .screen = -1,
+       .depth = 0,
+       .visual = NULL,
+};
+
+int fb_init(void *disp)
 {
+       s_info.disp = disp;
+       if (s_info.disp) {
+               Screen *screen;
+
+               screen = DefaultScreenOfDisplay(s_info.disp);
+
+               s_info.screen = DefaultScreen(s_info.disp);
+               s_info.visual = DefaultVisualOfScreen(screen);
+               s_info.depth = sizeof(int); //DefaultDepthOfScreen(screen);
+       }
        return 0;
 }
 
 int fb_fini(void)
 {
-       return 0;
-}
+       if (s_info.disp_is_opened && s_info.disp) {
+               XCloseDisplay(s_info.disp);
+       }
 
-/*
-static inline struct flock *file_lock(short type, short whence)
-{
-       static struct flock ret;
-
-       ret.l_type = type;
-       ret.l_start = 0;
-       ret.l_whence = whence;
-       ret.l_len = 0;
-       ret.l_pid = getpid();
-       return &ret;
+       s_info.disp = NULL;
+       s_info.disp_is_opened = 0;
+       s_info.visual = NULL;
+       s_info.screen = -1;
+       s_info.depth = 0;
+       return 0;
 }
-*/
 
-int fb_sync(struct fb_info *info)
+static inline int sync_for_file(struct fb_info *info)
 {
        int fd;
+       struct buffer *buffer;
 
-       if (!info) {
-               ErrPrint("FB Handle is not valid\n");
+       buffer = info->buffer;
+
+       if (buffer->state != CREATED) {
+               ErrPrint("Invalid state of a FB\n");
                return -EINVAL;
        }
 
-       if (!info->buffer) {
-               DbgPrint("Buffer is not prepared\n");
+       if (buffer->type != BUFFER_TYPE_FILE) {
+               DbgPrint("Invalid buffer\n");
                return 0;
        }
 
-       if (info->buffer->state != CREATED) {
+       fd = open(util_uri_to_path(info->id), O_RDONLY);
+       if (fd < 0) {
+               ErrPrint("Failed to open a file (%s) because of (%s)\n", util_uri_to_path(info->id), strerror(errno));
+               return -EIO;
+       }
+
+       if (read(fd, buffer->data, info->bufsz) != info->bufsz) {
+               ErrPrint("read: %s\n", strerror(errno));
+               close(fd);
+               return -EIO;
+       }
+
+       close(fd);
+       DbgPrint("Sync done (%s, %p)\n", info->id, info->buffer);
+       return 0;
+}
+
+static inline int sync_for_pixmap(struct fb_info *info)
+{
+       struct buffer *buffer;
+       XShmSegmentInfo si;
+       XImage *xim;
+
+       if (!s_info.disp) {
+               s_info.disp = XOpenDisplay(NULL);
+               if (s_info.disp) {
+                       Screen *screen;
+
+                       s_info.disp_is_opened = 1;
+
+                       screen = DefaultScreenOfDisplay(s_info.disp);
+
+                       s_info.screen = DefaultScreen(s_info.disp);
+                       s_info.visual = DefaultVisualOfScreen(screen);
+                       s_info.depth = sizeof(int); // DefaultDepthOfScreen(screen);
+               } else {
+                       ErrPrint("Failed to open a display\n");
+                       return -EFAULT;
+               }
+       }
+
+       buffer = info->buffer;
+       if (buffer->state != CREATED) {
                ErrPrint("Invalid state of a FB\n");
                return -EINVAL;
        }
 
-       if (!info->id || info->id[0] == '\0') {
-               DbgPrint("Ingore sync\n");
+       if (buffer->type != BUFFER_TYPE_PIXMAP) {
+               DbgPrint("Invalid buffer\n");
                return 0;
        }
 
-       if (info->buffer->type != BUFFER_TYPE_FILE) {
-               DbgPrint("Ingore sync\n");
+       DbgPrint("PIXMAP: 0x%X\n", info->handle);
+       if (info->handle == 0) {
+               DbgPrint("Pixmap ID is not valid\n");
+               return -EINVAL;
+       }
+
+       if (info->bufsz == 0) {
+               DbgPrint("Nothing can be sync\n");
                return 0;
        }
 
-       if (strncmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) {
-               DbgPrint("Invalid URI: [%s]\n", info->id);
-               return -EINVAL;
+       si.shmid = shmget(IPC_PRIVATE, info->bufsz, IPC_CREAT | 0666);
+       if (si.shmid < 0) {
+               ErrPrint("shmget: %s\n", strerror(errno));
+               return -EFAULT;
        }
 
-       fd = open(util_uri_to_path(info->id), O_RDONLY);
-       if (fd < 0) {
-               ErrPrint("Failed to open a file (%s) because of (%s)\n", util_uri_to_path(info->id), strerror(errno));
-               return -EIO;
+       si.readOnly = False;
+       si.shmaddr = shmat(si.shmid, NULL, 0);
+       if (si.shmaddr == (void *)-1) {
+               if (shmctl(si.shmid, IPC_RMID, 0) < 0)
+                       ErrPrint("shmctl: %s\n", strerror(errno));
+               return -EFAULT;
        }
 
-       if (read(fd, info->buffer->data, info->bufsz) != info->bufsz) {
-               ErrPrint("read: %s\n", strerror(errno));
-               close(fd);
-               return -EIO;
+       xim = XShmCreateImage(s_info.disp, s_info.visual, (s_info.depth << 3), ZPixmap, NULL, &si, info->w, info->h);
+       if (xim == NULL) {
+               if (shmdt(si.shmaddr) < 0)
+                       ErrPrint("shmdt: %s\n", strerror(errno));
+
+               if (shmctl(si.shmid, IPC_RMID, 0) < 0)
+                       ErrPrint("shmctl: %s\n", strerror(errno));
+
+               return -EFAULT;
        }
 
-       close(fd);
-       DbgPrint("Sync done (%s, %p)\n", info->id, info->buffer);
+       DbgPrint("Depth: %d, %dx%d\n", s_info.depth, info->w, info->h);
+
+       xim->data = si.shmaddr;
+       XShmAttach(s_info.disp, &si);
+
+       XShmGetImage(s_info.disp, info->handle, xim, 0, 0, 0xFFFFFFFF);
+       XSync(s_info.disp, False);
+
+       memcpy(buffer->data, xim->data, info->bufsz);
+       DbgPrint("Buf size: %d\n", info->bufsz);
+
+       XShmDetach(s_info.disp, &si);
+       XDestroyImage(xim);
+
+       if (shmdt(si.shmaddr) < 0)
+               ErrPrint("shmdt: %s\n", strerror(errno));
+
+       if (shmctl(si.shmid, IPC_RMID, 0) < 0)
+               ErrPrint("shmctl: %s\n", strerror(errno));
+
        return 0;
 }
 
+int fb_sync(struct fb_info *info)
+{
+       if (!info) {
+               ErrPrint("FB Handle is not valid\n");
+               return -EINVAL;
+       }
+
+       if (!info->buffer) {
+               DbgPrint("Buffer is not prepared\n");
+               return 0;
+       }
+
+       if (!info->id || info->id[0] == '\0') {
+               DbgPrint("Ingore sync\n");
+               return 0;
+       }
+
+       if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) {
+               return sync_for_file(info);
+       } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
+               return sync_for_pixmap(info);
+       }
+
+       return -EINVAL;
+}
+
 struct fb_info *fb_create(const char *id, int w, int h)
 {
        struct fb_info *info;
@@ -138,7 +264,9 @@ struct fb_info *fb_create(const char *id, int w, int h)
        }
 
        if (sscanf(info->id, SCHEMA_SHM "%d", &info->handle) == 1) {
+               DbgPrint("SHMID: %d is gotten\n", info->handle);
        } else if (sscanf(info->id, SCHEMA_PIXMAP "%d", &info->handle) == 1) {
+               DbgPrint("PIXMAP-SHMID: %d is gotten\n", info->handle);
        } else {
                info->handle = -EINVAL;
        }
@@ -160,7 +288,7 @@ int fb_create_buffer(struct fb_info *info)
                return -EINVAL;
        }
 
-       info->bufsz = info->w * info->h * sizeof(int);
+       info->bufsz = info->w * info->h * s_info.depth;
        if (info->bufsz == 0) {
                DbgPrint("Buffer size is ZERO(%d)\n", info->bufsz);
                return 0;
@@ -192,17 +320,31 @@ int fb_create_buffer(struct fb_info *info)
                        return -EFAULT;
                }
        } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
-               buffer = NULL;
-               ErrPrint("pixmap is not supported yet\n");
+               if (info->handle < 0) {
+                       DbgPrint("PIXMAP is not prepared yet\n");
+                       info->bufsz = 0;
+                       return 0;
+               }
+
+               DbgPrint("PIXMAP-ID: 0x%X\n", info->handle);
+
+               buffer = calloc(1, sizeof(*buffer) + info->bufsz);
+               if (!buffer) {
+                       CRITICAL_LOG("Heap: %s\n", strerror(errno));
+                       info->bufsz = 0;
+                       return -ENOMEM;
+               }
+
+               buffer->type = BUFFER_TYPE_PIXMAP;
+               buffer->refcnt = 1;
+               buffer->state = CREATED;
        } else {
                ErrPrint("Invalid FB type\n");
                return -EINVAL;
        }
 
        info->buffer = buffer;
-
-       DbgPrint("FB allocated (%p)\n", info->buffer);
-
+       DbgPrint("FB(%s) allocated (%p)\n", info->id, info->buffer);
        return 0;
 }
 
@@ -215,7 +357,7 @@ int fb_destroy_buffer(struct fb_info *info)
                return -EINVAL;
        }
 
-       if (!info->buffer)
+       if (!info->buffer) /* PIXMAP */
                return 0;
 
        buffer = info->buffer;
@@ -263,7 +405,7 @@ void *fb_acquire_buffer(struct fb_info *info)
        }
 
        if (!info->buffer) {
-               ErrPrint("Buffer is not created\n");
+               ErrPrint("Buffer is not created (%s)\n", info->id);
                return NULL;
        }
 
@@ -275,12 +417,15 @@ void *fb_acquire_buffer(struct fb_info *info)
                        ErrPrint("shmat: %s\n", strerror(errno));
                        return NULL;
                }
+               DbgPrint("SHM buffer acquired\n");
        } else if (buffer->type == BUFFER_TYPE_PIXMAP) {
-               ErrPrint("Pixmap is not supported yet\n");
-               return NULL;
-       } else {
+               DbgPrint("Pixmap buffer acquired!!\n");
+               buffer->refcnt++;
+       } else if (buffer->type == BUFFER_TYPE_FILE) {
                buffer->refcnt++;
                DbgPrint("FB acquired (%p) %d\n", buffer, buffer->refcnt);
+       } else {
+               DbgPrint("Unknwon FP: %d\n", buffer->type);
        }
 
        return buffer->data;
@@ -306,9 +451,6 @@ int fb_release_buffer(void *data)
                if (shmdt(buffer) < 0)
                        ErrPrint("shmdt: %s\n", strerror(errno));
        } else if (buffer->type == BUFFER_TYPE_PIXMAP) {
-               ErrPrint("Pixmap is not supported yet\n");
-               return -ENOTSUP;
-       } else {
                buffer->refcnt--;
                if (buffer->refcnt == 0) {
                        DbgPrint("FB released (%p)\n", buffer);
@@ -317,6 +459,17 @@ int fb_release_buffer(void *data)
                } else {
                        DbgPrint("FB decrease[%p] refcnt: %d\n", buffer, buffer->refcnt);
                }
+       } else if (buffer->type == BUFFER_TYPE_FILE) {
+               buffer->refcnt--;
+               if (buffer->refcnt == 0) {
+                       DbgPrint("FB released (%p)\n", buffer);
+                       buffer->state = DESTROYED;
+                       free(buffer);
+               } else {
+                       DbgPrint("FB decrease[%p] refcnt: %d\n", buffer, buffer->refcnt);
+               }
+       } else {
+               ErrPrint("Unknwon buffer type\n");
        }
 
        return 0;
@@ -347,10 +500,11 @@ int fb_refcnt(void *data)
 
                ret = buf.shm_nattch;
        } else if (buffer->type == BUFFER_TYPE_PIXMAP) {
-               ErrPrint("Pixmap is not supported yet\n");
-               return -ENOTSUP;
-       } else {
                ret = buffer->refcnt;
+       } else if (buffer->type == BUFFER_TYPE_FILE) {
+               ret = buffer->refcnt;
+       } else {
+               ret = -EINVAL;
        }
 
        return ret;
index 5fa08e8..cec8890 100644 (file)
@@ -523,7 +523,7 @@ static int send_mouse_event(struct livebox *handler, const char *event, double x
        return master_rpc_async_request(handler, packet, 0, mouse_event_cb, NULL);
 }
 
-EAPI int livebox_init(void)
+EAPI int livebox_init(void *disp)
 {
 #if defined(FLOG)
        char filename[BUFSIZ];
@@ -532,6 +532,7 @@ EAPI int livebox_init(void)
        if (!__file_log_fp)
                __file_log_fp = fdopen(1, "w+t");
 #endif
+       fb_init(disp);
        critical_log_init();
 
        client_init();
@@ -541,6 +542,7 @@ EAPI int livebox_init(void)
 EAPI int livebox_fini(void)
 {
        client_fini();
+       fb_fini();
        return 0;
 }
 
@@ -1346,6 +1348,12 @@ EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
                return LB_TYPE_IMAGE;
        case _LB_TYPE_BUFFER:
        case _LB_TYPE_SCRIPT:
+               {
+                       const char *id;
+                       id = fb_id(handler->lb.data.fb);
+                       if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
+                               return LB_TYPE_PIXMAP;
+               }
                return LB_TYPE_BUFFER;
        case _LB_TYPE_TEXT:
                return LB_TYPE_TEXT;
@@ -1373,6 +1381,12 @@ EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
                return PD_TYPE_TEXT;
        case _PD_TYPE_BUFFER:
        case _PD_TYPE_SCRIPT:
+               {
+                       const char *id;
+                       id = fb_id(handler->pd.data.fb);
+                       if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
+                               return PD_TYPE_PIXMAP;
+               }
                return PD_TYPE_BUFFER;
        default:
                break;
@@ -1413,6 +1427,68 @@ EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script
        return 0;
 }
 
+EAPI int livebox_lb_id(struct livebox *handler)
+{
+       const char *id;
+       int pixmap = 0;
+
+       if (!handler) {
+               ErrPrint("Handler is NIL\n");
+               return pixmap;
+       }
+
+       if (handler->state != CREATE || !handler->id) {
+               ErrPrint("Invalid handle\n");
+               return pixmap;
+       }
+
+       if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
+               ErrPrint("Handler is not valid type\n");
+               return pixmap;
+       }
+
+       id = fb_id(handler->lb.data.fb);
+       if (strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
+               return pixmap;
+
+       if (sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1)
+               ErrPrint("Inavlid ID: %s\n", id);
+
+       DbgPrint("Pixmap: 0x%X\n", pixmap);
+       return pixmap;
+}
+
+EAPI int livebox_pd_id(struct livebox *handler)
+{
+       const char *id;
+       int pixmap = 0;
+
+       if (!handler) {
+               ErrPrint("Handler is NIL\n");
+               return pixmap;
+       }
+
+       if (handler->state != CREATE || !handler->id) {
+               ErrPrint("Invalid handle\n");
+               return pixmap;
+       }
+
+       if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
+               ErrPrint("Handler is not valid type\n");
+               return pixmap;
+       }
+
+       id = fb_id(handler->pd.data.fb);
+       if (strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
+               return pixmap;
+
+       if (sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1)
+               ErrPrint("Inavlid ID: %s\n", id);
+
+       DbgPrint("Pixmap: 0x%X\n", pixmap);
+       return pixmap;
+}
+
 EAPI void *livebox_acquire_fb(struct livebox *handler)
 {
        if (!handler) {
@@ -1650,6 +1726,64 @@ EAPI int livebox_text_emit_signal(struct livebox *handler, const char *emission,
        return master_rpc_async_request(handler, packet, 0, text_signal_cb, create_cb_info(cb, data));
 }
 
+EAPI int livebox_subscribe_group(const char *cluster, const char *category)
+{
+       struct packet *packet;
+
+       packet = packet_create("subscribe", "ss", cluster ? cluster : "", category ? category : "");
+       if (!packet) {
+               ErrPrint("Failed to create a packet\n");
+               return -EFAULT;
+       }
+
+       return master_rpc_async_request(NULL, packet, 0, NULL, NULL);
+}
+
+EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
+{
+       struct packet *packet;
+
+       packet = packet_create("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
+       if (!packet) {
+               ErrPrint("Failed to create a packet\n");
+               return -EFAULT;
+       }
+
+       return master_rpc_async_request(NULL, packet, 0, NULL, NULL);
+}
+
+EAPI int livebox_enumerate_cluster_list(void (*cb)(const char *cluster))
+{
+       DbgPrint("Not implemented\n");
+       /* Use the DB for this */
+       return -ENOSYS;
+}
+
+EAPI int livebox_enumerate_category_list(const char *cluster, void (*cb)(const char *category))
+{
+       DbgPrint("Not implemented\n");
+       /* Use the DB for this */
+       return -ENOSYS;
+}
+
+EAPI int livebox_refresh_group(const char *cluster, const char *category)
+{
+       struct packet *packet;
+
+       if (!cluster || !category) {
+               ErrPrint("Invalid argument\n");
+               return -EINVAL;
+       }
+
+       packet = packet_create("refresh_group", "ss", cluster, category);
+       if (!packet) {
+               ErrPrint("Failed to create a packet\n");
+               return -EFAULT;
+       }
+
+       return master_rpc_async_request(NULL, packet, 0, NULL, NULL);
+}
+
 int lb_set_group(struct livebox *handler, const char *cluster, const char *category)
 {
        void *pc = NULL;
@@ -2132,62 +2266,4 @@ int lb_send_delete(struct livebox *handler, ret_cb_t cb, void *data)
        return master_rpc_async_request(handler, packet, 0, del_ret_cb, create_cb_info(cb, data));
 }
 
-EAPI int livebox_subscribe_group(const char *cluster, const char *category)
-{
-       struct packet *packet;
-
-       packet = packet_create("subscribe", "ss", cluster ? cluster : "", category ? category : "");
-       if (!packet) {
-               ErrPrint("Failed to create a packet\n");
-               return -EFAULT;
-       }
-
-       return master_rpc_async_request(NULL, packet, 0, NULL, NULL);
-}
-
-EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
-{
-       struct packet *packet;
-
-       packet = packet_create("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
-       if (!packet) {
-               ErrPrint("Failed to create a packet\n");
-               return -EFAULT;
-       }
-
-       return master_rpc_async_request(NULL, packet, 0, NULL, NULL);
-}
-
-EAPI int livebox_enumerate_cluster_list(void (*cb)(const char *cluster))
-{
-       DbgPrint("Not implemented\n");
-       /* Use the DB for this */
-       return -ENOSYS;
-}
-
-EAPI int livebox_enumerate_category_list(const char *cluster, void (*cb)(const char *category))
-{
-       DbgPrint("Not implemented\n");
-       /* Use the DB for this */
-       return -ENOSYS;
-}
-
-EAPI int livebox_refresh_group(const char *cluster, const char *category)
-{
-       struct packet *packet;
-
-       if (!cluster || !category) {
-               ErrPrint("Invalid argument\n");
-               return -EINVAL;
-       }
-
-       packet = packet_create("refresh_group", "ss", cluster, category);
-       if (!packet) {
-               ErrPrint("Failed to create a packet\n");
-               return -EFAULT;
-       }
-
-       return master_rpc_async_request(NULL, packet, 0, NULL, NULL);
-}
-
 /* End of a file */