[CBHM] refactoring
authordeasung.kim <deasung.kim@samsung.com>
Fri, 6 Jan 2012 04:32:50 +0000 (13:32 +0900)
committerdeasung.kim <deasung.kim@samsung.com>
Mon, 30 Jan 2012 12:03:55 +0000 (21:03 +0900)
Change-Id: I1e9cf43a5029451a6c6f9a16036ca51e98e808ac

26 files changed:
CMakeLists.txt [changed mode: 0755->0644]
src/cbhm.h [new file with mode: 0644]
src/clipdrawer.c
src/clipdrawer.h
src/item_manager.c [new file with mode: 0644]
src/item_manager.h [new file with mode: 0644]
src/main.c [new file with mode: 0644]
src/old/cbhm_main.c [moved from src/cbhm_main.c with 100% similarity]
src/old/cbhm_main.h [moved from src/cbhm_main.h with 100% similarity]
src/old/clipdrawer.c [new file with mode: 0644]
src/old/clipdrawer.h [new file with mode: 0644]
src/old/common.h [moved from src/common.h with 100% similarity]
src/old/scrcapture.c [new file with mode: 0644]
src/old/scrcapture.h [new file with mode: 0644]
src/old/storage.c [new file with mode: 0644]
src/old/storage.h [new file with mode: 0644]
src/old/xcnphandler.c [moved from src/xcnphandler.c with 100% similarity]
src/old/xcnphandler.h [moved from src/xcnphandler.h with 100% similarity]
src/scrcapture.c
src/scrcapture.h
src/storage.c
src/storage.h
src/xconverter.c [new file with mode: 0644]
src/xconverter.h [new file with mode: 0644]
src/xhandler.c [new file with mode: 0644]
src/xhandler.h [new file with mode: 0644]

old mode 100755 (executable)
new mode 100644 (file)
index d101d85..c5609de
@@ -1,17 +1,19 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 PROJECT(cbhm C)
 
-SET(SRCS src/cbhm_main.c
+SET(SRCS src/main.c
+       src/item_manager.c
+       src/xconverter.c
+       src/xhandler.c
        src/clipdrawer.c
-       src/storage.c
-       src/xcnphandler.c
        src/scrcapture.c
+       src/storage.c
 )
 
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED elementary appcore-efl appcore-common x11 ecore-x utilX eina evas ecore ecore-evas edje ecore-input xext xcomposite svi pixman-1)
+pkg_check_modules(pkgs REQUIRED elementary eet appcore-efl appcore-common x11 ecore-x utilX eina evas ecore ecore-file ecore-evas edje ecore-input xext xcomposite svi pixman-1)
 
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
diff --git a/src/cbhm.h b/src/cbhm.h
new file mode 100644 (file)
index 0000000..07db153
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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.
+ *
+ */
+
+#ifndef _CBHM_H_
+#define _CBHM_H_
+
+#include <Elementary.h>
+#include <Ecore_X.h>
+
+#if !defined(PACKAGE)
+#  define PACKAGE "CBHM"
+#endif
+
+#if !defined(APPNAME)
+#  define APPNAME "Clipboard History Manager"
+#endif
+
+#if !defined(LOCALEDIR)
+#  define LOCALEDIR "/usr/share/locale"
+#endif
+
+#define CBHM_MAGIC 0xad960009
+
+typedef struct _TargetHandler TargetHandler;
+typedef struct _AppData AppData;
+typedef struct _ClipdrawerData ClipdrawerData;
+typedef struct _CNP_ITEM CNP_ITEM;
+typedef struct _XHandlerData XHandlerData;
+typedef struct _SCaptureData SCaptureData;
+typedef struct _StorageData StorageData;
+typedef char *(*text_converter_func)(AppData *ad, int type_index, const char *str);
+
+#include "clipdrawer.h"
+#include "item_manager.h"
+#include "xhandler.h"
+#include "xconverter.h"
+#include "scrcapture.h"
+#include "storage.h"
+
+struct _TargetHandler {
+       Ecore_X_Atom *atom;
+       char **name;
+       int atom_cnt;
+       text_converter_func convert_for_entry;
+       text_converter_func convert_to_target[ATOM_INDEX_MAX];
+};
+
+struct _AppData {
+       int magic;
+       Ecore_X_Display *x_disp;
+       Ecore_X_Window x_root_win;
+       Ecore_X_Window x_event_win;
+       Ecore_X_Window x_active_win;
+       Eina_List *item_list;
+
+       Eina_Bool (*draw_item_add)(AppData *ad, CNP_ITEM *item);
+       Eina_Bool (*draw_item_del)(AppData *ad, CNP_ITEM *item);
+       Eina_Bool (*storage_item_add)(AppData *ad, CNP_ITEM *item);
+       Eina_Bool (*storage_item_del)(AppData *ad, CNP_ITEM *item);
+//     CNP_ITEM *(*storage_item_load)(AppData *ad, int index);
+
+       ClipdrawerData *clipdrawer;
+       XHandlerData *xhandler;
+       SCaptureData *screencapture;
+       StorageData *storage;
+
+       CNP_ITEM *clip_selected_item;
+       TargetHandler targetAtoms[ATOM_INDEX_MAX];
+};
+
+void *d_malloc(char *func, int line, size_t size);
+void *d_calloc(char *func, int line, size_t n, size_t size);
+void d_free(char *func, int line, void *m);
+
+#define DEBUG
+
+#ifdef DEBUG
+#define DTRACE(fmt, args...) \
+{do { fprintf(stderr, "[%s:%04d] " fmt, __func__,__LINE__, ##args); } while (0); }
+#define DMSG(fmt, args...) printf("[%s] " fmt, __func__, ## args )
+#define CALLED() printf("called %s, %s\n", __FILE__, __func__);
+#define DTIME(fmt, args...) \
+{do { struct timeval tv1; gettimeofday(&tv1, NULL); double t1=tv1.tv_sec+(tv1.tv_usec/1000000.0); fprintf(stderr, "[CBHM][time=%lf:%s:%04d] " fmt, t1, __func__, __LINE__, ##args); } while (0); }
+#ifdef MEM_DEBUG
+#define MALLOC(size) d_malloc(__func__, __LINE__, size)
+#define CALLOC(n, size) d_calloc(__func__, __LINE__, n, size)
+#define FREE(p) d_free(__func__, __LINE__, p)
+#else
+#define MALLOC(size) malloc(size)
+#define CALLOC(n, size) calloc(n, size)
+#define FREE(p) free(p)
+#endif
+#else
+#define DMSG(fmt, args...)
+#define CALLED()
+#define DTIME(fmt, args...)
+#define MALLOC(size) malloc(size)
+#define CALLOC(n, size) calloc(n, size)
+#define FREE(p) free(p)
+#endif
+
+#endif // _CBHM_H_
index 669d9d0..c308b8e 100644 (file)
  *
  */
 
-#include "common.h"
-#include "cbhm_main.h"
-#include "storage.h"
-#include "xcnphandler.h"
+#include <utilX.h>
 #include "clipdrawer.h"
+#include "item_manager.h"
+#include "xconverter.h"
 
-#define DELETE_ICON_PATH "/usr/share/cbhm/icons/05_delete.png"
-#define IM     "/usr/share/cbhm/icons/"
-static const char *g_images_path[] = {
-       IM"cbhm_default_img.png",
-};
-#define N_IMAGES (1)
+#define EDJ_PATH "/usr/share/edje"
+#define APP_EDJ_FILE EDJ_PATH"/cbhmdrawer.edj"
+#define GRP_MAIN "cbhmdrawer"
 
+#define ANIM_DURATION 30 // 1 seconds
+#define ANIM_FLOPS (0.5/30)
+#define CLIPDRAWER_HEIGHT 360
+#define CLIPDRAWER_HEIGHT_LANDSCAPE 228
+#define DEFAULT_WIDTH 720
 #define GRID_ITEM_SPACE_W 6
 #define GRID_ITEM_SINGLE_W 185
 #define GRID_ITEM_SINGLE_H 161
@@ -36,494 +37,418 @@ static const char *g_images_path[] = {
 #define GRID_IMAGE_LIMIT_W 91
 #define GRID_IMAGE_LIMIT_H 113
 
-#define ANIM_DURATION 30 // 1 seconds
-#define ANIM_FLOPS (0.5/30)
+static Evas_Object *create_win(ClipdrawerData *cd, const char *name);
+static Evas_Object *_grid_content_get(void *data, Evas_Object *obj, const char *part);
+static void _grid_del(void *data, Evas_Object *obj);
+static Eina_Bool clipdrawer_add_item(AppData *ad, CNP_ITEM *item);
+static Eina_Bool clipdrawer_del_item(AppData *ad, CNP_ITEM *item);
+static void clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _grid_item_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void setting_win(Ecore_X_Display *x_disp, Ecore_X_Window x_main_win);
+static void set_transient_for(Ecore_X_Window x_main_win, Ecore_X_Window x_active_win);
+static void unset_transient_for(Ecore_X_Window x_main_win, Ecore_X_Window x_active_win);
+
+static void _change_gengrid_paste_textonly_mode(ClipdrawerData *cd)
+{
+       CNP_ITEM *item = NULL;
 
-// gic should live at gengrid callback functions
-Elm_Gengrid_Item_Class gic;
-static Ecore_Timer *anim_timer = NULL;
+       Elm_Gengrid_Item *gitem = elm_gengrid_first_item_get(cd->gengrid);
 
-typedef struct tag_griditem
-{
-       int itype;
-       Elm_Gengrid_Item *item;
-       const char *ipathdata;
-       Eina_Strbuf *istrdata;
-       Evas_Object *delbtn;
-       Evas_Object *ilayout;
-} griditem_t;
-
-const char *
-remove_tags(const char *p)
+       while (gitem)
+       {
+               item = elm_gengrid_item_data_get(gitem);
+               if ((item->type_index == ATOM_INDEX_IMAGE) && (item->layout))
+               {
+                       if (cd->paste_text_only)
+                               edje_object_signal_emit(elm_layout_edje_get(item->layout), "elm,state,show,dim", "elm");
+                       else
+                               edje_object_signal_emit(elm_layout_edje_get(item->layout), "elm,state,hide,dim", "elm");
+               }
+               gitem = elm_gengrid_item_next_get(gitem);
+       }
+}
+
+void clipdrawer_paste_textonly_set(AppData *ad, Eina_Bool textonly)
 {
-   char *q,*ret;
-   int i;
-   if (!p) return NULL;
-
-   q = malloc(strlen(p) + 1);
-   if (!q) return NULL;
-   ret = q;
-
-   while (*p)
-     {
-        if ((*p != '<')) *q++ = *p++;
-        else if (*p == '<')
-          {
-             if ((p[1] == 'b') && (p[2] == 'r') &&
-                 ((p[3] == ' ') || (p[3] == '/') || (p[3] == '>')))
-               *q++ = '\n';
-             while ((*p) && (*p != '>')) p++;
-             p++;
-          }
-     }
-   *q = 0;
-
-   return ret;
+       ClipdrawerData *cd = ad->clipdrawer;
+       if (cd->paste_text_only != textonly)
+               cd->paste_text_only = textonly;
+       DTRACE("paste textonly mode = %d\n", textonly);
+
+       _change_gengrid_paste_textonly_mode(cd);
 }
 
-const char* clipdrawer_get_plain_string_from_escaped(char *escstr)
+Eina_Bool clipdrawer_paste_textonly_get(AppData *ad)
 {
-       /* NOTE : return string should be freed */
-       return remove_tags(escstr);
+       ClipdrawerData *cd = ad->clipdrawer;
+       return cd->paste_text_only;
 }
 
-static char* _get_string_for_entry(char *str)
+static Evas_Object *_load_edj(Evas_Object* win, const char *file, const char *group)
 {
-       if (!str)
+       Evas_Object *layout = elm_layout_add(win);
+       if (!layout)
+       {
+               DMSG("ERROR: elm_layout_add return NULL\n");
                return NULL;
+       }
 
-       Eina_Strbuf *strbuf = eina_strbuf_new();
-       if (!strbuf)
-               return strdup(str);
-       eina_strbuf_prepend(strbuf, "<font_size=18><color=#000000FF>");
+       if (!elm_layout_file_set(layout, file, group))
+       {
+               DMSG("ERROR: elm_layout_file_set return FALSE\n");
+               evas_object_del(layout);
+               return NULL;
+       }
 
-       char *trail = str;
+       evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_win_resize_object_add(win, layout);
 
-       while (trail && *trail)
-       {
-               char *pretrail = trail;
-               unsigned long length;
-               char *temp;
-               char *endtag;
+       evas_object_show(layout);
+       return layout;
+}
 
-               trail = strchr(trail, '<');
-               if (!trail)
-               {
-                       eina_strbuf_append(strbuf, pretrail);
-                       break;
-               }
-               endtag = strchr(trail, '>');
-               if (!endtag)
-                       break;
+static Eina_Bool keydown_cb(void *data, int type, void *event)
+{
+       AppData *ad = data;
+       Ecore_Event_Key *ev = event;
+       if (!strcmp(ev->keyname, KEY_END))
+               clipdrawer_lower_view(ad);
 
-               length = trail - pretrail;
+       return ECORE_CALLBACK_PASS_ON;
+}
 
-               temp = strndup(pretrail, length);
-               if (!temp)
-               {
-                       trail++;
-                       continue;
-               }
+ClipdrawerData* init_clipdrawer(AppData *ad)
+{
+       ClipdrawerData *cd = calloc(1, sizeof(ClipdrawerData));
 
-               DTRACE("temp str: %s \n", temp);
-               eina_strbuf_append(strbuf, temp);
-               free(temp);
-               trail++;
+       /* create and setting window */
+       if (!cd)
+               return NULL;
+       if (!(cd->main_win = create_win(cd, APPNAME)))
+       {
+               free(cd);
+               return NULL;
+       }
+       cd->x_main_win = elm_win_xwindow_get(cd->main_win);
+       setting_win(ad->x_disp, cd->x_main_win);
 
-               if (trail[0] == '/')
-               {
-                       trail = endtag + 1;
-                       continue;
-               }
+       /* edj setting */
+       if (!(cd->main_layout = _load_edj(cd->main_win, APP_EDJ_FILE, GRP_MAIN)))
+       {
+               evas_object_del(cd->main_win);
+               free(cd);
+               return NULL;
+       }
 
-               if (strncmp(trail, "br", 2) == 0)
-               {
-                       eina_strbuf_append(strbuf, "<br>");
-                       trail = endtag + 1;
-                       continue;
-               }
+       /* create and setting gengrid */
+       elm_theme_extension_add(NULL, APP_EDJ_FILE);
+       edje_object_signal_callback_add(elm_layout_edje_get(cd->main_layout),
+                       "mouse,up,1", "*", clipdrawer_ly_clicked, ad);
 
-               if (strncmp(trail, "img", 3) == 0)
-               {
-                       char *src = strstr(trail, "file://");
-                       char *src_endtag = strchr(trail, '>');
-                       if (!src || !src_endtag || src_endtag < src)
-                               continue;
+       cd->gengrid = elm_gengrid_add(cd->main_win);
+       elm_layout_content_set(cd->main_layout, "historyitems", cd->gengrid);
+       elm_gengrid_item_size_set(cd->gengrid, GRID_ITEM_W+2, GRID_ITEM_H);
+       elm_gengrid_align_set(cd->gengrid, 0.5, 0.5);
+       elm_gengrid_horizontal_set(cd->gengrid, EINA_TRUE);
+       elm_gengrid_bounce_set(cd->gengrid, EINA_TRUE, EINA_FALSE);
+       elm_gengrid_multi_select_set(cd->gengrid, EINA_FALSE);
+//     evas_object_smart_callback_add(cd->gengrid, "selected", _grid_click_paste, ad);
+       evas_object_size_hint_weight_set(cd->gengrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
 
-                       length = src_endtag - src;
+       elm_gengrid_clear(cd->gengrid);
 
-                       src = strndup(src, length);
-                       if (!src)
-                       {
-                               trail = endtag + 1;
-                               continue;
-                       }
-                       temp = src;
-                       while(*temp)
-                       {
-                               if (*temp == '\"' || *temp == '>')
-                                       *temp = '\0';
-                               else
-                                       temp++;
-                       }
+       cd->gic.item_style = "default_grid";
+       cd->gic.func.label_get = NULL;
+       cd->gic.func.content_get = _grid_content_get;
+       cd->gic.func.state_get = NULL;
+       cd->gic.func.del = _grid_del;
 
-                       eina_strbuf_append_printf(strbuf, "<item absize=66x62 href=%s></item>", src);
-                       DTRACE("src str: %s \n", src);
-                       free(src);
-               }
-               trail = endtag + 1;
-       }
+       evas_object_show(cd->gengrid);
+
+       ad->draw_item_add = clipdrawer_add_item;
+       ad->draw_item_del = clipdrawer_del_item;
+//     ad->x_main_win = cd->x_main_win;
 
-       char *ret = eina_strbuf_string_steal(strbuf);
-       eina_strbuf_free(strbuf);
-       DTRACE("result str: %s \n", ret);
-       return ret;
+       cd->keydown_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, keydown_cb, ad);
+       cd->evas = evas_object_evas_get(cd->main_win);
+
+       return cd;
 }
 
-static void _grid_del_response_cb(void *data, Evas_Object *obj, void *event_info)
+void depose_clipdrawer(ClipdrawerData *cd)
 {
-       Elm_Gengrid_Item *it = (Elm_Gengrid_Item *)data;
-       evas_object_del(obj);
+       evas_object_del(cd->main_win);
+       if (cd->anim_timer)
+               ecore_timer_del(cd->anim_timer);
+       if (cd->keydown_handler)
+               ecore_event_handler_del(cd->keydown_handler);
+       free(cd);
+}
 
-       if((int)event_info == ELM_POPUP_RESPONSE_OK)
+static Eina_Bool clipdrawer_add_item(AppData *ad, CNP_ITEM *item)
+{
+       ClipdrawerData *cd = ad->clipdrawer;
+       if (item->type_index == ATOM_INDEX_IMAGE)
        {
-               struct appdata *ad = g_get_main_appdata();
-               elm_gengrid_item_del(it);
-               ad->hicount--;
-               if (ad->hicount < 0)
+               Elm_Gengrid_Item *gitem = elm_gengrid_first_item_get(cd->gengrid);
+               while (gitem)
                {
-                       int cnt = 0;
-                       Elm_Gengrid_Item *trail = elm_gengrid_first_item_get(ad->hig);
-                       while(trail)
+                       CNP_ITEM *gitem_data = elm_gengrid_item_data_get(gitem);
+                       gitem = elm_gengrid_item_next_get(gitem);
+                       if ((gitem_data->type_index == item->type_index) && (!strcmp(item->data, gitem_data->data)))
                        {
-                               cnt++;
-                               elm_gengrid_item_next_get(trail);
+                               DMSG("duplicated file path = %s\n", item->data);
+                               item_delete_by_CNP_ITEM(ad, gitem_data);
                        }
-                       ad->hicount = cnt;
-                       DTRACE("ERR: cbhm history cnt < 0, gengrid item cnt: %d\n", cnt);
                }
        }
+
+       item->gitem = elm_gengrid_item_prepend(cd->gengrid, &cd->gic, item, NULL, NULL);
+
+       return EINA_TRUE;
 }
 
-static void _grid_click_delete(void *data, Evas_Object *obj, void *event_info)
+static Eina_Bool clipdrawer_del_item(AppData *ad, CNP_ITEM *item)
 {
-       struct appdata *ad = data;
+       if (item->gitem)
+               elm_gengrid_item_del(item->gitem);
+       return EINA_TRUE;
 }
 
-static void
-_grid_item_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
+static void _grid_del(void *data, Evas_Object *obj)
 {
-       struct appdata *ad = g_get_main_appdata();
-
-       if (ad->anim_status != STATUS_NONE)
-               return;
+       CNP_ITEM *item = data;
+       item->gitem = NULL;
+       item->layout = NULL;
+}
 
-       Elm_Gengrid_Item *sgobj = NULL;
-       sgobj = elm_gengrid_selected_item_get(ad->hig);
-       griditem_t *ti = NULL;
-       ti = elm_gengrid_item_data_get(sgobj);
+static Evas_Object *_grid_content_get(void *data, Evas_Object *obj, const char *part)
+{
+       CNP_ITEM *item = data;
+       AppData *ad = item->ad;
+       ClipdrawerData *cd = ad->clipdrawer;
 
-       #define EDJE_DELBTN_PART_PREFIX "delbtn"
-       if (strncmp(source, EDJE_DELBTN_PART_PREFIX, strlen(EDJE_DELBTN_PART_PREFIX)))
+       if (strcmp(part, "elm.swallow.icon"))
+               return NULL;
+       if (item->type_index == ATOM_INDEX_IMAGE) /* text/uri */
        {
-               if (!sgobj || !ti)
-               {
-                       DTRACE("ERR: cbhm can't get the selected image\n");
-                       return;
-               }
+               Evas_Object *layout = elm_layout_add(obj);
+               elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout");
+               edje_object_signal_callback_add(elm_layout_edje_get(layout),
+                               "mouse,up,1", "*", _grid_item_ly_clicked, data);
 
-               elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
+               Evas_Object *sicon;
+               sicon = evas_object_image_add(evas_object_evas_get(obj));
+               evas_object_image_load_size_set(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
+               evas_object_image_file_set(sicon, item->data, NULL);
+               evas_object_image_fill_set(sicon, 0, 0, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
+               evas_object_resize(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
+               elm_layout_content_set(layout, "elm.swallow.icon", sicon);
 
-               if (ti->itype == GI_TEXT)
-               {
-                       char *p = strdup(eina_strbuf_string_get(ti->istrdata));
+               if (cd->paste_text_only)
+                       edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,show,dim", "elm");
+               else
+                       edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,hide,dim", "elm");
 
-                       elm_selection_set(1, ad->hig, /*ELM_SEL_FORMAT_HTML*/0x10, p);
-               }
-               else //if (ti->itype == GI_IMAGE)
-               {
-                       if (!clipdrawer_paste_textonly_get(ad))
-                       {
-                               int len = strlen(ti->ipathdata);
-                               char *p = malloc(len + 10);
-                               snprintf(p,len+10, "file:///%s", ti->ipathdata);
-
-                               elm_selection_set(/*secondary*/1, ad->hig,/*ELM_SEL_FORMAT_IMAGE*/4,p);
-                       }
-                       else
-                       {
-                               DTRACE("ERR: cbhm image paste mode is false\n");
-                       }
-               }
-               return;
-       }
-
-       if (!sgobj)
-       {
-               DTRACE("ERR: cbhm can't get the selected item\n");
-               return;
+               item->layout = layout;
        }
-
-       elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
-
-       Evas_Object *popup = elm_popup_add(ad->win_main);
-       elm_popup_timeout_set(popup, 5);
-       evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-       elm_popup_desc_set(popup, "Are you sure delete this?");
-       elm_popup_buttons_add(popup, 2,
-                                                 "Yes", ELM_POPUP_RESPONSE_OK,
-                                                 "No", ELM_POPUP_RESPONSE_CANCEL,
-                                                 NULL);
-       evas_object_smart_callback_add(popup, "response", _grid_del_response_cb, sgobj);
-       evas_object_show(popup);
-}
-
-Evas_Object* _grid_icon_get(const void *data, Evas_Object *obj, const char *part)
-{
-       griditem_t *ti = (griditem_t *)data;
-
-       if (!strcmp(part, "elm.swallow.icon"))
+       else
        {
-               if (ti->itype == GI_TEXT)
+               Evas_Object *layout = elm_layout_add(obj);
+               elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout");
+               edje_object_signal_callback_add(elm_layout_edje_get(layout), 
+                               "mouse,up,1", "*", _grid_item_ly_clicked, data);
+               Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(obj));
+               evas_object_resize(rect, GRID_ITEM_W, GRID_ITEM_H);
+               evas_object_color_set(rect, 242, 233, 183, 255);
+               evas_object_show(rect);
+               elm_layout_content_set(layout, "elm.swallow.icon", rect);
+
+               Evas_Object *ientry = elm_entry_add(obj);
+               evas_object_size_hint_weight_set(ientry, 0, 0);
+               elm_entry_scrollable_set(ientry, EINA_TRUE);
+
+               char *entry_text = string_for_entry_get(ad, item->type_index, item->data);
+               if (entry_text)
                {
-                       Evas_Object *layout = elm_layout_add (obj);
-                       elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout");
-                       edje_object_signal_callback_add(elm_layout_edje_get(layout), 
-                                                                                       "mouse,up,1", "*", _grid_item_ly_clicked, data);
-                       Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(obj));
-                       evas_object_resize(rect, GRID_ITEM_W, GRID_ITEM_H);
-                       evas_object_color_set(rect, 242, 233, 183, 255);
-                       evas_object_show(rect);
-                       elm_layout_content_set(layout, "elm.swallow.icon", rect);
-
-                       // FIXME: add string length check
-                       Evas_Object *ientry = elm_entry_add(obj);
-                       evas_object_size_hint_weight_set(ientry, 0, 0);
-                       Eina_Strbuf *strent = NULL;
-                       char *strdata = eina_strbuf_string_get(ti->istrdata);
-                       int i, skipflag, strcnt;
-                       
-                       strent = eina_strbuf_new();
-                       skipflag = 0;
-                       strcnt = 0;
-                       for (i = 0; i < eina_strbuf_length_get(ti->istrdata); i++)
-                       {
-                               switch (strdata[i])
-                               {
-                                       case '>':
-                                               skipflag = 0;
-                                               break;
-                                       case '<':
-                                               skipflag = 1;
-                                               break;
-                                       default:
-                                               if (!skipflag)
-                                                       strcnt++;
-                                               break;
-                               }
-                               if (strcnt > 100)
-                                       break;
-                       }
-                       eina_strbuf_append_n(strent, strdata, i);
-                       eina_strbuf_replace_all(strent, " absize=240x180 ", " absize=52x39 ");
-                       if (strcnt > 100)
-                               eina_strbuf_append(strent, "...");
-                       elm_entry_scrollable_set(ientry, EINA_TRUE);
-                       char *entry_text = eina_strbuf_string_get(strent);
-                       entry_text = _get_string_for_entry(entry_text);
-                       if (entry_text)
-                       {
-                               elm_object_part_text_set(ientry, NULL, entry_text);
-                               free(entry_text);
-                       }
-                       elm_entry_editable_set(ientry, EINA_FALSE);
-                       elm_entry_context_menu_disabled_set(ientry, EINA_TRUE);
-                       evas_object_show(ientry);
-                       elm_layout_content_set(layout, "elm.swallow.inner", ientry);
-
-                       eina_strbuf_free(strent);
-
-                       return layout;
+                       elm_object_part_text_set(ientry, NULL, entry_text);
+                       free(entry_text);
                }
-               else// if (ti->itype == GI_IMAGE)
+               else
                {
-                       Evas_Object *layout = elm_layout_add (obj);
-                       elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout");
-                       edje_object_signal_callback_add(elm_layout_edje_get(layout), 
-                                                                                       "mouse,up,1", "*", _grid_item_ly_clicked, data);
-
-                       Evas_Object *sicon;
-                       sicon = evas_object_image_add(evas_object_evas_get(obj));
-                       evas_object_image_load_size_set(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
-                       evas_object_image_file_set(sicon, ti->ipathdata, NULL);
-                       evas_object_image_fill_set(sicon, 0, 0, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
-                       evas_object_resize(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
-                       elm_layout_content_set(layout, "elm.swallow.icon", sicon);
-
-                       struct appdata *ad = g_get_main_appdata();
-                       
-                       if (clipdrawer_paste_textonly_get(ad))
-                               edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,show,dim", "elm");
-                       else
-                               edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,hide,dim", "elm");
-
-                       ti->ilayout = layout;
-                       return layout;
+                       elm_object_part_text_set(ientry, NULL, item->data);
                }
+               elm_entry_editable_set(ientry, EINA_FALSE);
+               elm_entry_context_menu_disabled_set(ientry, EINA_TRUE);
+               evas_object_show(ientry);
+               elm_layout_content_set(layout, "elm.swallow.inner", ientry);
+
+               item->layout = layout;
        }
 
-       return NULL;
+       return item->layout;
 }
 
-static void _grid_longpress(void *data, Evas_Object *obj, void *event_info)
+static void clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
 {
-       struct appdata *ad = data;
-}
+       AppData *ad = data;
 
-static void _grid_click_paste(void *data, Evas_Object *obj, void *event_info)
-{
-       struct appdata *ad = data;
-       if (ad->anim_status != STATUS_NONE)
+       if (ad->clipdrawer->anim_status != STATUS_NONE)
                return;
 
-       Elm_Gengrid_Item *sgobj = NULL;
-       sgobj = elm_gengrid_selected_item_get(ad->hig);
-       griditem_t *ti = NULL;
-       ti = elm_gengrid_item_data_get(sgobj);
-}
-
-void _grid_del(const void *data, Evas_Object *obj)
-{
-       griditem_t *ti = (griditem_t *)data;
-       if (ti->itype == GI_TEXT)
-               eina_strbuf_free(ti->istrdata);
-       else
-               eina_stringshare_del(ti->ipathdata);
-       free(ti);
+#define EDJE_CLOSE_PART_PREFIX "background/close"
+       if (!strncmp(source, EDJE_CLOSE_PART_PREFIX, strlen(EDJE_CLOSE_PART_PREFIX)))
+       {
+               clipdrawer_lower_view(ad);
+       }
 }
 
-char* clipdrawer_get_item_data(void *data, int pos)
+static void _grid_del_response_cb(void *data, Evas_Object *obj, void *event_info)
 {
-       struct appdata *ad = data;
-       griditem_t *ti = NULL;
-       griditem_t *newgi = NULL;
-       int count = 0;
+       CNP_ITEM *item = data;
+       AppData *ad = item->ad;
+       ClipdrawerData *cd = ad->clipdrawer;
 
-       if (pos < 0 || pos > ad->hicount)
-               return NULL;
+       /* delete popup */
+       evas_object_del(obj);
 
-       Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
-       while (item)
+       if((int)event_info == ELM_POPUP_RESPONSE_OK)
        {
-               ti = elm_gengrid_item_data_get(item);
-               if (count == pos)
-               {
-                       if (!ti)
-                               break;
-                       if (ti->itype == GI_TEXT)
-                               return (char*)eina_strbuf_string_get(ti->istrdata);
-                       else
-                               return ti->ipathdata;
-               }
-               count++;
-               item = elm_gengrid_item_next_get(item);
+               item_delete_by_CNP_ITEM(ad, item);
        }
-
-       return NULL;
 }
 
-// FIXME: how to remove calling g_get_main_appdata()? 
-//        it's mainly used at 'clipdrawer_image_item'
-int clipdrawer_add_item(char *idata, int type)
+static void _grid_item_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
 {
-       struct appdata *ad = g_get_main_appdata();
-       griditem_t *newgi = NULL;
+       CNP_ITEM *item = data;
+       AppData *ad = item->ad;
+       ClipdrawerData *cd = ad->clipdrawer;
 
-       newgi = malloc(sizeof(griditem_t));
-       newgi->itype = type;
+       if (cd->anim_status != STATUS_NONE)
+               return;
 
-       fprintf(stderr, "## add - %d : %s\n", newgi->itype, idata);
-       if (type == GI_TEXT)
+       Elm_Gengrid_Item *sgobj = NULL;
+       sgobj = elm_gengrid_selected_item_get(cd->gengrid);
+       item = elm_gengrid_item_data_get(sgobj);
+
+       if (!sgobj || !item)
        {
-               newgi->istrdata = eina_strbuf_new();
-               eina_strbuf_append(newgi->istrdata, idata);
+               DTRACE("ERR: cbhm can't get the selected item\n");
+               return;
        }
-       else //if (type == GI_IMAGE)
-       {
-               Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
-               griditem_t *ti = NULL;
 
-               if (!check_regular_file(idata))
-               {
-                       DTRACE("Error : it isn't normal file = %s\n", idata);
-                       return -1;
-               }
+       #define EDJE_DELBTN_PART_PREFIX "delbtn"
+       if (strncmp(source, EDJE_DELBTN_PART_PREFIX, strlen(EDJE_DELBTN_PART_PREFIX)))
+       {
+               elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
 
-               while (item)
+               if (item->type_index != ATOM_INDEX_IMAGE || !cd->paste_text_only)
                {
-                       ti = elm_gengrid_item_data_get(item);
-                       if ((ti->itype == type) && !strcmp(ti->ipathdata, idata))
-                       {
-                               DTRACE("Error : duplicated file path = %s\n", idata);
-                               return -1;
-                       }
-                       item = elm_gengrid_item_next_get(item);
+                       set_selection_owner(ad, ECORE_X_SELECTION_SECONDARY, item);
                }
-               newgi->ipathdata = eina_stringshare_add(idata);
        }
-
-       if (ad->hicount >= HISTORY_QUEUE_MAX_ITEMS)
+       else
        {
-               ad->hicount--;
-               // FIXME: add routine that is removing its elements
-               elm_gengrid_item_del(elm_gengrid_last_item_get(ad->hig));
+               elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
+
+               Evas_Object *popup = elm_popup_add(cd->main_win);
+               elm_popup_timeout_set(popup, 5);
+               evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+               elm_popup_desc_set(popup, "Are you sure delete this?");
+               elm_popup_buttons_add(popup, 2,
+                               "Yes", ELM_POPUP_RESPONSE_OK,
+                               "No", ELM_POPUP_RESPONSE_CANCEL,
+                               NULL);
+               evas_object_smart_callback_add(popup, "response", _grid_del_response_cb, item);
+               evas_object_show(popup);
        }
+}
 
-       ad->hicount++;
-       newgi->item = elm_gengrid_item_prepend(ad->hig, &gic, newgi, NULL, NULL);
+void set_transient_for(Ecore_X_Window x_main_win, Ecore_X_Window x_active_win)
+{
+       ecore_x_icccm_transient_for_set(x_main_win, x_active_win);
+       ecore_x_event_mask_set(x_active_win,
+                               ECORE_X_EVENT_MASK_WINDOW_PROPERTY | ECORE_X_EVENT_MASK_WINDOW_CONFIGURE);
+}
 
-       return TRUE;
+void unset_transient_for(Ecore_X_Window x_main_win, Ecore_X_Window x_active_win)
+{
+       ecore_x_event_mask_unset(x_active_win,
+                       ECORE_X_EVENT_MASK_WINDOW_PROPERTY | ECORE_X_EVENT_MASK_WINDOW_CONFIGURE);
+       ecore_x_icccm_transient_for_unset(x_main_win);
 }
 
-static void
-clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
+static void set_focus_for_app_window(Ecore_X_Window x_main_win, Eina_Bool enable)
 {
-       struct appdata *ad = data;
+       CALLED();
+       Eina_Bool accepts_focus;
+       Ecore_X_Window_State_Hint initial_state;
+       Ecore_X_Pixmap icon_pixmap;
+       Ecore_X_Pixmap icon_mask;
+       Ecore_X_Window icon_window;
+       Ecore_X_Window window_group;
+       Eina_Bool is_urgent;
+
+       ecore_x_icccm_hints_get (x_main_win,
+                       &accepts_focus, &initial_state, &icon_pixmap, &icon_mask, &icon_window, &window_group, &is_urgent);
+       ecore_x_icccm_hints_set (x_main_win,
+                       enable, initial_state, icon_pixmap, icon_mask, icon_window, window_group, is_urgent);
+       DMSG("set focus mode = %d\n", enable);
+}
 
-       if (ad->anim_status != STATUS_NONE)
-               return;
+void setting_win(Ecore_X_Display *x_disp, Ecore_X_Window x_main_win)
+{
+       CALLED();
+       // disable window effect
+       utilx_set_window_effect_state(x_disp, x_main_win, 0);
 
-       #define EDJE_CLOSE_PART_PREFIX "background/close"
-       if (!strncmp(source, EDJE_CLOSE_PART_PREFIX, strlen(EDJE_CLOSE_PART_PREFIX)))
+       ecore_x_icccm_name_class_set(x_main_win, "NORMAL_WINDOW", "NORMAL_WINDOW");
+
+       set_focus_for_app_window(x_main_win, EINA_FALSE);
+
+}
+
+Evas_Object *create_win(ClipdrawerData *cd, const char *name)
+{
+       CALLED();
+
+       Evas_Object *win = elm_win_add(NULL, name, ELM_WIN_BASIC);
+       if (!win)
        {
-               clipdrawer_lower_view(ad);
+               DMSG("ERROR: elm_win_add return NULL\n");
+               return NULL;
        }
+       elm_win_title_set(win, name);
+       elm_win_borderless_set(win, EINA_TRUE);
+       ecore_x_window_size_get(ecore_x_window_root_first_get(), &cd->root_w, &cd->root_h);
+       DMSG("root_w: %d, root_h: %d\n", cd->root_w, cd->root_h);
+       evas_object_resize(win, cd->root_w, cd->root_h);
+
+       elm_scale_set((double)cd->root_w/DEFAULT_WIDTH);
+       return win;
 }
 
-static void set_sliding_win_geometry(void *data)
+static void set_sliding_win_geometry(ClipdrawerData *cd)
 {
-       struct appdata *ad = data;
-       Ecore_X_Window zone, xwin;
+       CALLED();
+       Ecore_X_Window zone;
        Evas_Coord x, y, w, h;
-       xwin = elm_win_xwindow_get(ad->win_main);
-       zone = ecore_x_e_illume_zone_get(xwin);
-       DTRACE("[CBHM] xwin:%x, zone:%x\n", xwin, zone);
-
-//     ecore_evas_geometry_get(ecore_evas_ecore_evas_get(evas_object_evas_get(ad->win_main)), &x, &y, &w, &h);
+       zone = ecore_x_e_illume_zone_get(cd->x_main_win);
+       DTRACE(" zone:%x\n", zone);
 
-       if (ad->o_degree == 90 || ad->o_degree == 270)
+       if (cd->o_degree == 90 || cd->o_degree == 270)
        {
-               h = ad->anim_count * CLIPDRAWER_HEIGHT_LANDSCAPE / ANIM_DURATION;
+               h = cd->anim_count * CLIPDRAWER_HEIGHT_LANDSCAPE / ANIM_DURATION;
                x = 0;
-               y = ad->root_w - h;
-               w = ad->root_h;
+               y = cd->root_w - h;
+               w = cd->root_h;
        }
        else
        {
-               h = ad->anim_count * CLIPDRAWER_HEIGHT / ANIM_DURATION;
+               h = cd->anim_count * CLIPDRAWER_HEIGHT / ANIM_DURATION;
                x = 0;
-               y = ad->root_h - h;
-               w = ad->root_w;
+               y = cd->root_h - h;
+               w = cd->root_w;
        }
 
        if (!h)
@@ -531,13 +456,13 @@ static void set_sliding_win_geometry(void *data)
 
        DTRACE("[CBHM] change degree geometry... (%d, %d, %d x %d)\n", x, y, w, h);
        ecore_x_e_illume_sliding_win_geometry_set(zone, x, y, w, h);
-       ecore_x_e_illume_sliding_win_state_set(zone, ad->anim_count != 0);
+       ecore_x_e_illume_sliding_win_state_set(zone, cd->anim_count != 0);
 }
 
-void set_rotation_to_clipdrawer(void *data)
+void set_rotation_to_clipdrawer(ClipdrawerData *cd)
 {
-       struct appdata *ad = data;
-       int angle = ad->o_degree;
+       CALLED();
+       int angle = cd->o_degree;
        int x, y, w, h;
 
        if (angle == 180) // reverse
@@ -545,142 +470,62 @@ void set_rotation_to_clipdrawer(void *data)
                h = CLIPDRAWER_HEIGHT;
                x = 0;
                y = 0;
-               w = ad->root_w;
+               w = cd->root_w;
        }
        else if (angle == 90) // right rotate
        {
                h = CLIPDRAWER_HEIGHT_LANDSCAPE;
-               x = ad->root_w - h;
+               x = cd->root_w - h;
                y = 0;
-               w = ad->root_h;
+               w = cd->root_h;
        }
        else if (angle == 270) // left rotate
        {
                h = CLIPDRAWER_HEIGHT_LANDSCAPE;
                x = 0;
                y = 0;
-               w = ad->root_h;
+               w = cd->root_h;
        }
        else // angle == 0
        {
                h = CLIPDRAWER_HEIGHT;
                x = 0;
-               y = ad->root_h - h;
-               w = ad->root_w;
+               y = cd->root_h - h;
+               w = cd->root_w;
        }
 
-       evas_object_resize(ad->win_main, w, h);
-       evas_object_move(ad->win_main, x, y);
-       if (ad->anim_count == ANIM_DURATION)
-               set_sliding_win_geometry(data);
+       evas_object_resize(cd->main_win, w, h);
+       evas_object_move(cd->main_win, x, y);
+       if (cd->anim_count == ANIM_DURATION)
+               set_sliding_win_geometry(cd);
 }
 
-int clipdrawer_init(void *data)
-{
-       struct appdata *ad = data;
-       double cdy, cdw;
-
-       ad->windowshow = EINA_FALSE;
-       ad->hicount = 0;
-       ad->pastetextonly = EINA_TRUE;
-       ad->anim_status = STATUS_NONE;
-       ad->anim_count = 0;
-
-       // for elm_check
-       elm_theme_extension_add(NULL, APP_EDJ_FILE);
-
-       edje_object_signal_callback_add(elm_layout_edje_get(ad->ly_main), 
-                                                                       "mouse,up,1", "*", clipdrawer_ly_clicked, ad);
-
-       ad->hig = NULL;
-       ad->hig = elm_gengrid_add(ad->win_main);
-       elm_layout_content_set(ad->ly_main, "historyitems", ad->hig);
-       elm_gengrid_item_size_set(ad->hig, GRID_ITEM_W+2, GRID_ITEM_H);
-       elm_gengrid_align_set(ad->hig, 0.5, 0.5);
-       elm_gengrid_horizontal_set(ad->hig, EINA_TRUE);
-       elm_gengrid_bounce_set(ad->hig, EINA_TRUE, EINA_FALSE);
-       elm_gengrid_multi_select_set(ad->hig, EINA_FALSE);
-       evas_object_smart_callback_add(ad->hig, "selected", _grid_click_paste, ad);
-//     evas_object_smart_callback_add(ad->hig, "longpressed", _grid_longpress, ad);
-       evas_object_size_hint_weight_set(ad->hig, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-
-       elm_gengrid_clear(ad->hig);
-
-       gic.item_style = "default_grid";
-       gic.func.label_get = NULL;
-       gic.func.content_get = _grid_icon_get;
-       gic.func.state_get = NULL;
-       gic.func.del = _grid_del;
-
-/*     int i;
-       griditem_t *newgi;
-
-       for (i = 0; i < N_IMAGES; i++)
-       {
-               clipdrawer_add_item(g_images_path[0], GI_IMAGE);
-       }
-
-       clipdrawer_add_item("clipboard history", GI_TEXT);*/
-
-       evas_object_show (ad->hig);
-
-// for debugging, calc history pos
-/*
-   Evas_Coord x, y, w, h;
-   Evas_Coord vx, vy, vw, vh;
-
-   edje_object_part_geometry_get(elm_layout_edje_get(ad->ly_main),"imagehistory/list",&x,&y,&w,&h);
-   evas_object_geometry_get (ad->hig, &vx,&vy,&vw,&vh);
-   fprintf(stderr, "## x = %d, y = %d, w = %d, h = %d\n", x, y, w, h);
-   fprintf(stderr, "## vx = %d, vy = %d, vw = %d, vh = %d\n", vx, vy, vw, vh);
-*/
-
-//     if (get_item_counts() != 0)
-//             clipdrawer_update_contents(ad);
-
-       return 0;
-}
-
-int clipdrawer_create_view(void *data)
-{
-       struct appdata *ad = data;
-
-       clipdrawer_init(ad);
-
-       // for debug
-       // at starting, showing app view
-       //clipdrawer_activate_view(ad);
-
-       return 0;
-}
-
-Eina_Bool _get_anim_pos(void *data, int *sp, int *ep)
+static Eina_Bool _get_anim_pos(ClipdrawerData *cd, int *sp, int *ep)
 {
        if (!sp || !ep)
                return EINA_FALSE;
 
-       struct appdata *ad = data;
-       int angle = ad->o_degree;
+       int angle = cd->o_degree;
        int anim_start, anim_end;
 
        if (angle == 180) // reverse
        {
-               anim_start = -(ad->root_h - CLIPDRAWER_HEIGHT);
+               anim_start = -(cd->root_h - CLIPDRAWER_HEIGHT);
                anim_end = 0;
        }
        else if (angle == 90) // right rotate
        {
-               anim_start = ad->root_w;
+               anim_start = cd->root_w;
                anim_end = anim_start - CLIPDRAWER_HEIGHT_LANDSCAPE;
        }
        else if (angle == 270) // left rotate
        {
-               anim_start = -(ad->root_w - CLIPDRAWER_HEIGHT_LANDSCAPE);
+               anim_start = -(cd->root_w - CLIPDRAWER_HEIGHT_LANDSCAPE);
                anim_end = 0;
        }
        else // angle == 0
        {
-               anim_start = ad->root_h;
+               anim_start = cd->root_h;
                anim_end = anim_start - CLIPDRAWER_HEIGHT;
        }
 
@@ -689,13 +534,12 @@ Eina_Bool _get_anim_pos(void *data, int *sp, int *ep)
        return EINA_TRUE;
 }
 
-Eina_Bool _do_anim_delta_pos(void *data, int sp, int ep, int ac, int *dp)
+static Eina_Bool _do_anim_delta_pos(ClipdrawerData *cd, int sp, int ep, int ac, int *dp)
 {
        if (!dp)
                return EINA_FALSE;
 
-       struct appdata *ad = data;
-       int angle = ad->o_degree;
+       int angle = cd->o_degree;
        int delta;
        double posprop;
        posprop = 1.0*ac/ANIM_DURATION;
@@ -703,22 +547,22 @@ Eina_Bool _do_anim_delta_pos(void *data, int sp, int ep, int ac, int *dp)
        if (angle == 180) // reverse
        {
                delta = (int)((ep-sp)*posprop);
-               evas_object_move(ad->win_main, 0, sp+delta);
+               evas_object_move(cd->main_win, 0, sp+delta);
        }
        else if (angle == 90) // right rotate
        {
                delta = (int)((ep-sp)*posprop);
-               evas_object_move(ad->win_main, sp+delta, 0);
+               evas_object_move(cd->main_win, sp+delta, 0);
        }
        else if (angle == 270) // left rotate
        {
                delta = (int)((ep-sp)*posprop);
-               evas_object_move(ad->win_main, sp+delta, 0);
+               evas_object_move(cd->main_win, sp+delta, 0);
        }
        else // angle == 0
        {
                delta = (int)((sp-ep)*posprop);
-               evas_object_move(ad->win_main, 0, sp-delta);
+               evas_object_move(cd->main_win, 0, sp-delta);
        }
        
        *dp = delta;
@@ -726,147 +570,110 @@ Eina_Bool _do_anim_delta_pos(void *data, int sp, int ep, int ac, int *dp)
        return EINA_TRUE;
 }
 
-static void stop_animation(void *data)
+static void stop_animation(AppData *ad)
 {
-       struct appdata *ad = data;
-
-       ad->anim_status = STATUS_NONE;
-       if (anim_timer)
+       CALLED();
+       ClipdrawerData *cd = ad->clipdrawer;
+       cd->anim_status = STATUS_NONE;
+       if (cd->anim_timer)
        {
-               ecore_timer_del(anim_timer);
-               anim_timer = NULL;
+               ecore_timer_del(cd->anim_timer);
+               cd->anim_timer = NULL;
        }
 
-       set_sliding_win_geometry(data);
+       set_sliding_win_geometry(cd);
 }
 
-Eina_Bool anim_pos_calc_cb(void *data)
+static Eina_Bool anim_pos_calc_cb(void *data)
 {
-       struct appdata *ad = data;
-
+       AppData *ad = data;
+       ClipdrawerData *cd = ad->clipdrawer;
        int anim_start, anim_end, delta;
 
-       _get_anim_pos(ad, &anim_start, &anim_end);
+       _get_anim_pos(cd, &anim_start, &anim_end);
 
-       if (ad->anim_status == SHOW_ANIM)
+       if (cd->anim_status == SHOW_ANIM)
        {
-               if (ad->anim_count > ANIM_DURATION)
+               if (cd->anim_count > ANIM_DURATION)
                {
-                       ad->anim_count = ANIM_DURATION;
-                       stop_animation(data);
+                       cd->anim_count = ANIM_DURATION;
+                       stop_animation(ad);
                        return EINA_FALSE;
                }
-               _do_anim_delta_pos(ad, anim_start, anim_end, ad->anim_count, &delta);
-               ad->anim_count++;
+               _do_anim_delta_pos(cd, anim_start, anim_end, cd->anim_count, &delta);
+               if (cd->anim_count == 1)
+                       evas_object_show(cd->main_win);
+               cd->anim_count++;
        }
-       else if (ad->anim_status == HIDE_ANIM)
+       else if (cd->anim_status == HIDE_ANIM)
        {
-               if (ad->anim_count < 0)
+               if (cd->anim_count < 0)
                {
-                       ad->anim_count = 0;
-                       evas_object_hide(ad->win_main);
-                       elm_win_lower(ad->win_main);
-                       unset_transient_for(ad);
-                       stop_animation(data);
+                       cd->anim_count = 0;
+                       evas_object_hide(cd->main_win);
+                       elm_win_lower(cd->main_win);
+                       unset_transient_for(cd->x_main_win, ad->x_active_win);
+                       stop_animation(ad);
                        return EINA_FALSE;
                }
-               _do_anim_delta_pos(ad, anim_start, anim_end, ad->anim_count, &delta);
-               ad->anim_count--;
+               _do_anim_delta_pos(cd, anim_start, anim_end, cd->anim_count, &delta);
+               cd->anim_count--;
        }
        else
        {
-               stop_animation(data);
+               stop_animation(ad);
                return EINA_FALSE;
        }
 
        return EINA_TRUE;
 }
 
-Eina_Bool clipdrawer_anim_effect(void *data, anim_status_t atype)
+static Eina_Bool clipdrawer_anim_effect(AppData *ad, AnimStatus atype)
 {
-       struct appdata *ad = data;
-
-       if (atype == ad->anim_status)
+       CALLED();
+       ClipdrawerData *cd = ad->clipdrawer;
+       if (atype == cd->anim_status)
        {
                DTRACE("Warning: Animation effect is already in progress. \n");
                return EINA_FALSE;
        }
 
-       ad->anim_status = atype;
-
-       if (anim_timer)
-               ecore_timer_del(anim_timer);
+       cd->anim_status = atype;
 
-       anim_timer = ecore_timer_add(ANIM_FLOPS, anim_pos_calc_cb, ad);
+       if (cd->anim_timer)
+               ecore_timer_del(cd->anim_timer);
+       cd->anim_timer = ecore_timer_add(ANIM_FLOPS, anim_pos_calc_cb, ad);
 
        return EINA_TRUE;
 }
 
-void clipdrawer_activate_view(void *data)
+void clipdrawer_activate_view(AppData* ad)
 {
-       struct appdata *ad = data;
-
-       if (ad->win_main)
-       {
-               set_focus_for_app_window(ad->win_main, EINA_TRUE);
-               set_transient_for(ad);
-               ad->o_degree = get_active_window_degree(ad->active_win);
-               elm_win_rotation_set(ad->win_main, ad->o_degree);
-               set_rotation_to_clipdrawer(data);
-               evas_object_show(ad->win_main);
-               elm_win_activate(ad->win_main);
-               if (clipdrawer_anim_effect(ad, SHOW_ANIM))
-                       ad->windowshow = EINA_TRUE;
+       CALLED();
+       ClipdrawerData *cd = ad->clipdrawer;
+       if (cd->main_win)
+       {
+               set_focus_for_app_window(cd->x_main_win, EINA_TRUE);
+               set_transient_for(cd->x_main_win, ad->x_active_win);
+               cd->o_degree = get_active_window_degree(ad->x_active_win);
+               elm_win_rotation_set(cd->main_win, cd->o_degree);
+               set_rotation_to_clipdrawer(cd);
+       //      evas_object_show(cd->main_win);
+               elm_win_activate(cd->main_win);
+       //      if (clipdrawer_anim_effect(ad, SHOW_ANIM))
+               clipdrawer_anim_effect(ad, SHOW_ANIM);
        }
 }
 
-void clipdrawer_lower_view(void *data)
+void clipdrawer_lower_view(AppData* ad)
 {
-       struct appdata *ad = data;
-       
-       if (ad->win_main && ad->windowshow)
-       {
-               set_focus_for_app_window(ad->win_main, EINA_FALSE);
-               if (clipdrawer_anim_effect(ad, HIDE_ANIM))
-                       ad->windowshow = EINA_FALSE;
-       }
-}
-
-void _change_gengrid_paste_textonly_mode(void *data)
-{
-       struct appdata *ad = data;
-
-       griditem_t *ti = NULL;
-
-       Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
-
-       while (item)
+       CALLED();
+       ClipdrawerData *cd = ad->clipdrawer;
+       if (cd->main_win && cd->anim_count)
        {
-               ti = elm_gengrid_item_data_get(item);
-               if ((ti->itype == GI_IMAGE) && (ti->ilayout))
-               {
-                       if (clipdrawer_paste_textonly_get(ad))
-                               edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,show,dim", "elm");
-                       else
-                               edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,hide,dim", "elm");
-               }
-               item = elm_gengrid_item_next_get(item);
+               set_focus_for_app_window(cd->x_main_win, EINA_FALSE);
+       //      if (clipdrawer_anim_effect(ad, HIDE_ANIM))
+       //              ad->windowshow = EINA_FALSE;
+               clipdrawer_anim_effect(ad, HIDE_ANIM);
        }
 }
-
-void clipdrawer_paste_textonly_set(void *data, Eina_Bool textonly)
-{
-       struct appdata *ad = data;
-       textonly = !!textonly;
-       if (ad->pastetextonly != textonly)
-               ad->pastetextonly = textonly;
-       DTRACE("paste textonly mode = %d\n", textonly);
-
-       _change_gengrid_paste_textonly_mode(ad);
-}
-
-Eina_Bool clipdrawer_paste_textonly_get(void *data)
-{
-       struct appdata *ad = data;
-       return ad->pastetextonly;
-}
index 0135ffc..eb7fafd 100644 (file)
  *
  */
 
-#ifndef _clipdrawer_h_
-#define _clipdrawer_h_
+#ifndef _CLIPDRAWER_H_
+#define _CLIPDRAWER_H_
 
-#define CLIPDRAWER_HEIGHT 360
-#define CLIPDRAWER_HEIGHT_LANDSCAPE 228
+#include <Ecore_X.h>
+#include <Elementary.h>
 
-enum {
-       GI_TEXT = 0,
-       GI_IMAGE,
-
-       GI_MAX_ITEMS,
+typedef enum _AnimStatus AnimStatus;
+enum _AnimStatus {
+       STATUS_NONE = 0,
+       SHOW_ANIM,
+       HIDE_ANIM
 };
 
-/* view maintains */
-int clipdrawer_init(void *data);
-int clipdrawer_create_view(void *data);
-void clipdrawer_activate_view(void *data);
-//void clipdrawer_hide_view(void *data);
-void clipdrawer_lower_view(void *data);
+struct _ClipdrawerData {
+       Evas_Object *main_win;
+       Ecore_X_Window x_main_win;
+       Evas_Object *gengrid;
+       Evas_Object *main_layout;
+       Elm_Gengrid_Item_Class gic;
+
+       int o_degree;
 
-void set_rotation_to_clipdrawer(void *data);
+       int root_w;
+       int root_h;
 
-const char* clipdrawer_get_plain_string_from_escaped(char *escstr);
+       Ecore_Event_Handler *keydown_handler;
+       Evas *evas;
 
-char *clipdrawer_get_item_data(void *data, int pos);
-int clipdrawer_add_item(char *idata, int type);
+       Ecore_Timer *anim_timer;
+       AnimStatus anim_status;
+       int anim_count;
+       Eina_Bool paste_text_only:1;
+};
 
-void clipdrawer_paste_textonly_set(void *data, Eina_Bool textonly);
-Eina_Bool clipdrawer_paste_textonly_get(void *data);
+#include "cbhm.h"
 
-#endif // _clipdrawer_h_
+void set_rotation_to_clipdrawer(ClipdrawerData *ad);
+void clipdrawer_activate_view(AppData* ad);
+void clipdrawer_lower_view(AppData* ad);
+ClipdrawerData *init_clipdrawer(AppData *ad);
+void depose_clipdrawer(ClipdrawerData *cd);
+#endif // _CLIPDRAWER_H_
diff --git a/src/item_manager.c b/src/item_manager.c
new file mode 100644 (file)
index 0000000..19c54df
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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 "item_manager.h"
+
+#define ITEM_CNT_MAX 12
+
+static void item_free(CNP_ITEM *item)
+{
+       CALLED();
+       if (!item)
+       {
+               DMSG("WRONG PARAMETER in %s\n", __func__);
+               return;
+       }
+       // remove gengrid
+       if (item->ad)
+       {
+               if (item->ad->draw_item_del)
+                       item->ad->draw_item_del(item->ad, item);
+               if (item->ad->storage_item_del)
+                       item->ad->storage_item_del(item->ad, item);
+       }
+       if (item->data)
+               FREE(item->data);
+
+       if (item->ad->clip_selected_item == item)
+               item->ad->clip_selected_item = NULL;
+       FREE(item);
+}
+
+CNP_ITEM *item_add_by_CNP_ITEM(AppData *ad, CNP_ITEM *item)
+{
+       if (!ad || !item)
+       {
+               DMSG("WRONG PARAMETER in %s, ad: 0x%x, item: 0x%x\n", __func__, ad, item);
+               return NULL;
+       }
+       item->ad = ad;
+
+       ad->item_list = eina_list_prepend(ad->item_list, item);
+       if (ad && ad->draw_item_add)
+               ad->draw_item_add(ad, item);
+       if (ad && ad->storage_item_add)
+               ad->storage_item_add(ad, item);
+
+       while (ITEM_CNT_MAX < eina_list_count(ad->item_list))
+       {
+               CNP_ITEM *ditem = eina_list_nth(ad->item_list, ITEM_CNT_MAX);
+
+               ad->item_list = eina_list_remove(ad->item_list, ditem);
+               item_free(ditem);
+       }
+
+       return item;
+}
+
+CNP_ITEM *item_add_by_data(AppData *ad, Ecore_X_Atom type, void *data, int len)
+{
+       if (!ad || !data)
+       {
+               DMSG("WRONG PARAMETER in %s\n", __func__);
+               return NULL;
+       }
+       CNP_ITEM *item;
+       item = CALLOC(1, sizeof(CNP_ITEM));
+       if (!item)
+               return NULL;
+       item->type_index = atom_type_index_get(ad, type);
+       item->data = data;
+       item->len = len;
+
+       item = item_add_by_CNP_ITEM(ad, item);
+       return item;
+}
+
+CNP_ITEM *item_get_by_index(AppData *ad, int index)
+{
+       if (!ad || eina_list_count(ad->item_list) <= index || 0 > index)
+       {
+               DMSG("WRONG PARAMETER in %s\n", __func__);
+               return NULL;
+       }
+       CNP_ITEM *item;
+       item = eina_list_nth(ad->item_list, index);
+       return item;
+}
+
+CNP_ITEM *item_get_by_data(AppData *ad, void *data)
+{
+       if (!ad || !data)
+       {
+               DMSG("WRONG PARAMETER in %s\n", __func__);
+               return NULL;
+       }
+       CNP_ITEM *item;
+       Eina_List *l;
+       EINA_LIST_FOREACH(ad->item_list, l, item)
+       {
+               if (item && item->data == data)
+               {
+                       return item;
+               }
+       }
+       return NULL;
+}
+
+CNP_ITEM *item_get_last(AppData *ad)
+{
+       if (!ad)
+       {
+               DMSG("WRONG PARAMETER in %s\n", __func__);
+               return NULL;
+       }
+       return eina_list_data_get(ad->item_list);
+}
+
+void item_delete_by_CNP_ITEM(AppData *ad, CNP_ITEM *item)
+{
+       CALLED();
+       if (!ad || !item)
+       {
+               DMSG("WRONG PARAMETER in %s\n", __func__);
+               return;
+       }
+       DMSG("item: 0x%x, item->gitem: 0x%x\n", item, item->gitem);
+       ad->item_list = eina_list_remove(ad->item_list, item);
+       item_free(item);
+}
+
+void item_delete_by_data(AppData *ad, void *data)
+{
+       CALLED();
+       if (!ad || !data)
+       {
+               DMSG("WRONG PARAMETER in %s\n", __func__);
+               return;
+       }
+       CNP_ITEM *item;
+       item = item_get_by_data(ad, data);
+       item_delete_by_CNP_ITEM(ad, item);
+}
+
+void item_delete_by_index(AppData *ad, int index)
+{
+       CALLED();
+       if (!ad || eina_list_count(ad->item_list) <= index || 0 > index)
+       {
+               DMSG("WRONG PARAMETER in %s\n", __func__);
+               return;
+       }
+       CNP_ITEM *item;
+       item = item_get_by_index(ad, index);
+       item_delete_by_CNP_ITEM(ad, item);
+}
+
+void item_clear_all(AppData *ad)
+{
+       CALLED();
+       while(ad->item_list)
+       {
+               CNP_ITEM *item = eina_list_data_get(ad->item_list);
+               ad->item_list = eina_list_remove(ad->item_list, item);
+               if (item)
+                       item_free(item);
+       }
+}
+
+int item_count_get(AppData *ad)
+{
+       return eina_list_count(ad->item_list);
+}
diff --git a/src/item_manager.h b/src/item_manager.h
new file mode 100644 (file)
index 0000000..1c8210c
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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.
+ *
+ */
+
+#ifndef _ITEM_MANAGER_H_
+#define _ITEM_MANAGER_H_
+
+#include "cbhm.h"
+
+struct _CNP_ITEM {
+       int type_index;
+       void *data;
+       size_t len;
+
+       Elm_Gengrid_Item *gitem;
+       Evas_Object *layout;
+       AppData *ad;
+};
+
+CNP_ITEM *item_add_by_CNP_ITEM(AppData *ad, CNP_ITEM *item);
+CNP_ITEM *item_add_by_data(AppData *ad, Ecore_X_Atom type, void *data, int len);
+
+CNP_ITEM *item_get_by_index(AppData *ad, int index);
+CNP_ITEM *item_get_by_data(AppData *ad, void *data);
+CNP_ITEM *item_get_last(AppData *ad);
+
+void item_delete_by_CNP_ITEM(AppData *ad, CNP_ITEM *item);
+void item_delete_by_data(AppData *ad, void *data);
+void item_delete_by_index(AppData *ad, int index);
+void item_clear_all(AppData *ad);
+int item_count_get(AppData *ad);
+
+#endif /*_ITEM_MANAGER_H_*/
+
diff --git a/src/main.c b/src/main.c
new file mode 100644 (file)
index 0000000..d088d4a
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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 <appcore-efl.h>
+#include <Ecore_X.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/XInput.h>
+#include <X11/extensions/XInput2.h>
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XIproto.h>
+
+#include "cbhm.h"
+
+#define CLIPBOARD_MANAGER_WINDOW_TITLE_STRING "X11_CLIPBOARD_HISTORY_MANAGER"
+#define ATOM_CLIPBOARD_MANAGER_NAME "CLIPBOARD_MANAGER"
+
+static AppData *g_main_ad = NULL;
+
+void *d_malloc(char *func, int line, size_t size)
+{
+       char *m = malloc(size);
+       printf("in %s, %d: 0x%x = malloc(%d)\n", func, line, m, size);
+       return m;
+}
+void *d_calloc(char *func, int line, size_t n, size_t size)
+{
+       char *m = calloc(n, size);
+       printf("in %s, %d: 0x%x = calloc(%d)\n", func, line, m, size);
+       return m;
+}
+void d_free(char *func, int line, void *m)
+{
+       printf("in %s, %d: free(0x%x)\n", func, line, m);
+       free(m);
+}
+
+static Eina_Bool setClipboardManager(AppData *ad)
+{
+       ad->x_disp = ecore_x_display_get();
+       DMSG("x_disp: 0x%x\n", ad->x_disp);
+       if (ad->x_disp)
+       {
+               Ecore_X_Atom clipboard_manager_atom = XInternAtom(ad->x_disp, ATOM_CLIPBOARD_MANAGER_NAME, False);
+               Ecore_X_Window clipboard_manager = XGetSelectionOwner(ad->x_disp, clipboard_manager_atom);
+               DMSG("clipboard_manager_window: 0x%x\n");
+               if (!clipboard_manager)
+               {
+                       ad->x_root_win = DefaultRootWindow(ad->x_disp);
+                       if (ad->x_root_win)
+                       {
+                               ad->x_event_win = ecore_x_window_new(ad->x_root_win, 0, 0, 19, 19);
+                               DMSG("x_event_win: 0x%x\n", ad->x_event_win);
+                               if (ad->x_event_win)
+                               {
+                                       XSetSelectionOwner(ad->x_disp, clipboard_manager_atom, ad->x_event_win, CurrentTime);
+                                       Ecore_X_Window clipboard_manager = XGetSelectionOwner(ad->x_disp, clipboard_manager_atom);
+                                       DMSG("clipboard_manager: 0x%x\n", clipboard_manager);
+                                       if (ad->x_event_win == clipboard_manager)
+                                       {
+                                               return EINA_TRUE;
+                                       }
+                               }
+                       }
+               }
+       }
+       return EINA_FALSE;
+}
+
+static void set_x_window(Ecore_X_Window x_event_win, Ecore_X_Window x_root_win)
+{
+       ecore_x_netwm_name_set(x_event_win, CLIPBOARD_MANAGER_WINDOW_TITLE_STRING);
+       ecore_x_event_mask_set(x_event_win,
+                       ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
+       ecore_x_event_mask_set(x_root_win,
+                       ECORE_X_EVENT_MASK_WINDOW_CONFIGURE);
+       ecore_x_window_prop_property_set(
+                       x_root_win, ecore_x_atom_get("CBHM_XWIN"),
+                       XA_WINDOW, 32, &x_event_win, 1);
+       ecore_x_flush();
+}
+
+static int app_create(void *data)
+{
+       AppData *ad = data;
+
+       if (!setClipboardManager(ad))
+       {
+               DMSG("Clipboard Manager set failed\n");
+               return EXIT_FAILURE;
+       }
+
+       set_x_window(ad->x_event_win, ad->x_root_win);
+
+       if (!ecore_init()) return EXIT_FAILURE;
+       if (!ecore_evas_init()) return EXIT_FAILURE;
+       if (!edje_init()) return EXIT_FAILURE;
+       ad->magic = CBHM_MAGIC;
+       init_target_atoms(ad);
+       if (!(ad->clipdrawer = init_clipdrawer(ad))) return EXIT_FAILURE;
+       if (!(ad->xhandler = init_xhandler(ad))) return EXIT_FAILURE;
+       if (!(ad->screencapture = init_screencapture(ad))) return EXIT_FAILURE;
+       if (!(ad->storage = init_storage(ad))) return EXIT_FAILURE;
+
+       set_selection_owner(ad, ECORE_X_SELECTION_CLIPBOARD, NULL);
+       return 0;
+}
+
+static int app_terminate(void *data)
+{
+       AppData *ad = data;
+
+       depose_clipdrawer(ad->clipdrawer);
+       depose_xhandler(ad->xhandler);
+       depose_screencapture(ad->screencapture);
+       depose_storage(ad->storage);
+       item_clear_all(ad);
+       depose_target_atoms(ad);
+       FREE(ad);
+
+       return 0;
+}
+
+static int app_pause(void *data)
+{
+       AppData *ad = data;
+       return 0;
+}
+
+static int app_resume(void *data)
+{
+       AppData *ad = data;
+       return 0;
+}
+
+static int app_reset(bundle *b, void *data)
+{
+       AppData *ad = data;
+
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+       AppData *ad;
+       struct appcore_ops ops = {
+               .create = app_create,
+               .terminate = app_terminate,
+               .pause = app_pause,
+               .resume = app_resume,
+               .reset = app_reset,
+       };
+       ad = CALLOC(1, sizeof(AppData));
+       ops.data = ad;
+       g_main_ad = ad;
+
+       appcore_set_i18n(PACKAGE, LOCALEDIR);
+
+       return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
+}
similarity index 100%
rename from src/cbhm_main.c
rename to src/old/cbhm_main.c
similarity index 100%
rename from src/cbhm_main.h
rename to src/old/cbhm_main.h
diff --git a/src/old/clipdrawer.c b/src/old/clipdrawer.c
new file mode 100644 (file)
index 0000000..6da8a9b
--- /dev/null
@@ -0,0 +1,872 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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 "common.h"
+#include "cbhm_main.h"
+#include "storage.h"
+#include "xcnphandler.h"
+#include "clipdrawer.h"
+
+#define DELETE_ICON_PATH "/usr/share/cbhm/icons/05_delete.png"
+#define IM     "/usr/share/cbhm/icons/"
+static const char *g_images_path[] = {
+       IM"cbhm_default_img.png",
+};
+#define N_IMAGES (1)
+
+#define GRID_ITEM_SPACE_W 6
+#define GRID_ITEM_SINGLE_W 185
+#define GRID_ITEM_SINGLE_H 161
+#define GRID_ITEM_W (GRID_ITEM_SINGLE_W+(GRID_ITEM_SPACE_W*2))
+#define GRID_ITEM_H (GRID_ITEM_SINGLE_H)
+#define GRID_IMAGE_LIMIT_W 91
+#define GRID_IMAGE_LIMIT_H 113
+
+#define ANIM_DURATION 30 // 1 seconds
+#define ANIM_FLOPS (0.5/30)
+
+// gic should live at gengrid callback functions
+Elm_Gengrid_Item_Class gic;
+static Ecore_Timer *anim_timer = NULL;
+
+typedef struct tag_griditem
+{
+       int itype;
+       Elm_Gengrid_Item *item;
+       const char *ipathdata;
+       Eina_Strbuf *istrdata;
+       Evas_Object *delbtn;
+       Evas_Object *ilayout;
+} griditem_t;
+
+const char *
+remove_tags(const char *p)
+{
+   char *q,*ret;
+   int i;
+   if (!p) return NULL;
+
+   q = malloc(strlen(p) + 1);
+   if (!q) return NULL;
+   ret = q;
+
+   while (*p)
+     {
+        if ((*p != '<')) *q++ = *p++;
+        else if (*p == '<')
+          {
+             if ((p[1] == 'b') && (p[2] == 'r') &&
+                 ((p[3] == ' ') || (p[3] == '/') || (p[3] == '>')))
+               *q++ = '\n';
+             while ((*p) && (*p != '>')) p++;
+             p++;
+          }
+     }
+   *q = 0;
+
+   return ret;
+}
+
+const char* clipdrawer_get_plain_string_from_escaped(char *escstr)
+{
+       /* NOTE : return string should be freed */
+       return remove_tags(escstr);
+}
+
+static char* _get_string_for_entry(char *str)
+{
+       if (!str)
+               return NULL;
+
+       Eina_Strbuf *strbuf = eina_strbuf_new();
+       if (!strbuf)
+               return strdup(str);
+       eina_strbuf_prepend(strbuf, "<font_size=18><color=#000000FF>");
+
+       char *trail = str;
+
+       while (trail && *trail)
+       {
+               char *pretrail = trail;
+               unsigned long length;
+               char *temp;
+               char *endtag;
+
+               trail = strchr(trail, '<');
+               if (!trail)
+               {
+                       eina_strbuf_append(strbuf, pretrail);
+                       break;
+               }
+               endtag = strchr(trail, '>');
+               if (!endtag)
+                       break;
+
+               length = trail - pretrail;
+
+               temp = strndup(pretrail, length);
+               if (!temp)
+               {
+                       trail++;
+                       continue;
+               }
+
+               DTRACE("temp str: %s \n", temp);
+               eina_strbuf_append(strbuf, temp);
+               free(temp);
+               trail++;
+
+               if (trail[0] == '/')
+               {
+                       trail = endtag + 1;
+                       continue;
+               }
+
+               if (strncmp(trail, "br", 2) == 0)
+               {
+                       eina_strbuf_append(strbuf, "<br>");
+                       trail = endtag + 1;
+                       continue;
+               }
+
+               if (strncmp(trail, "img", 3) == 0)
+               {
+                       char *src = strstr(trail, "file://");
+                       char *src_endtag = strchr(trail, '>');
+                       if (!src || !src_endtag || src_endtag < src)
+                               continue;
+
+                       length = src_endtag - src;
+
+                       src = strndup(src, length);
+                       if (!src)
+                       {
+                               trail = endtag + 1;
+                               continue;
+                       }
+                       temp = src;
+                       while(*temp)
+                       {
+                               if (*temp == '\"' || *temp == '>')
+                                       *temp = '\0';
+                               else
+                                       temp++;
+                       }
+
+                       eina_strbuf_append_printf(strbuf, "<item absize=66x62 href=%s></item>", src);
+                       DTRACE("src str: %s \n", src);
+                       free(src);
+               }
+               trail = endtag + 1;
+       }
+
+       char *ret = eina_strbuf_string_steal(strbuf);
+       eina_strbuf_free(strbuf);
+       DTRACE("result str: %s \n", ret);
+       return ret;
+}
+
+static void _grid_del_response_cb(void *data, Evas_Object *obj, void *event_info)
+{
+       Elm_Gengrid_Item *it = (Elm_Gengrid_Item *)data;
+       evas_object_del(obj);
+
+       if((int)event_info == ELM_POPUP_RESPONSE_OK)
+       {
+               struct appdata *ad = g_get_main_appdata();
+               elm_gengrid_item_del(it);
+               ad->hicount--;
+               if (ad->hicount < 0)
+               {
+                       int cnt = 0;
+                       Elm_Gengrid_Item *trail = elm_gengrid_first_item_get(ad->hig);
+                       while(trail)
+                       {
+                               cnt++;
+                               elm_gengrid_item_next_get(trail);
+                       }
+                       ad->hicount = cnt;
+                       DTRACE("ERR: cbhm history cnt < 0, gengrid item cnt: %d\n", cnt);
+               }
+       }
+}
+
+static void _grid_click_delete(void *data, Evas_Object *obj, void *event_info)
+{
+       struct appdata *ad = data;
+}
+
+static void
+_grid_item_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+       struct appdata *ad = g_get_main_appdata();
+
+       if (ad->anim_status != STATUS_NONE)
+               return;
+
+       Elm_Gengrid_Item *sgobj = NULL;
+       sgobj = elm_gengrid_selected_item_get(ad->hig);
+       griditem_t *ti = NULL;
+       ti = elm_gengrid_item_data_get(sgobj);
+
+       #define EDJE_DELBTN_PART_PREFIX "delbtn"
+       if (strncmp(source, EDJE_DELBTN_PART_PREFIX, strlen(EDJE_DELBTN_PART_PREFIX)))
+       {
+               if (!sgobj || !ti)
+               {
+                       DTRACE("ERR: cbhm can't get the selected image\n");
+                       return;
+               }
+
+               elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
+
+               if (ti->itype == GI_TEXT)
+               {
+                       char *p = strdup(eina_strbuf_string_get(ti->istrdata));
+
+                       elm_selection_set(1, ad->hig, /*ELM_SEL_FORMAT_HTML*/0x10, p);
+               }
+               else //if (ti->itype == GI_IMAGE)
+               {
+                       if (!clipdrawer_paste_textonly_get(ad))
+                       {
+                               int len = strlen(ti->ipathdata);
+                               char *p = malloc(len + 10);
+                               snprintf(p,len+10, "file:///%s", ti->ipathdata);
+
+                               elm_selection_set(/*secondary*/1, ad->hig,/*ELM_SEL_FORMAT_IMAGE*/4,p);
+                       }
+                       else
+                       {
+                               DTRACE("ERR: cbhm image paste mode is false\n");
+                       }
+               }
+               return;
+       }
+
+       if (!sgobj)
+       {
+               DTRACE("ERR: cbhm can't get the selected item\n");
+               return;
+       }
+
+       elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
+
+       Evas_Object *popup = elm_popup_add(ad->win_main);
+       elm_popup_timeout_set(popup, 5);
+       evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_popup_desc_set(popup, "Are you sure delete this?");
+       elm_popup_buttons_add(popup, 2,
+                                                 "Yes", ELM_POPUP_RESPONSE_OK,
+                                                 "No", ELM_POPUP_RESPONSE_CANCEL,
+                                                 NULL);
+       evas_object_smart_callback_add(popup, "response", _grid_del_response_cb, sgobj);
+       evas_object_show(popup);
+}
+
+Evas_Object* _grid_icon_get(const void *data, Evas_Object *obj, const char *part)
+{
+       griditem_t *ti = (griditem_t *)data;
+
+       if (!strcmp(part, "elm.swallow.icon"))
+       {
+               if (ti->itype == GI_TEXT)
+               {
+                       Evas_Object *layout = elm_layout_add (obj);
+                       elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout");
+                       edje_object_signal_callback_add(elm_layout_edje_get(layout),
+                                                                                       "mouse,up,1", "*", _grid_item_ly_clicked, data);
+                       Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(obj));
+                       evas_object_resize(rect, GRID_ITEM_W, GRID_ITEM_H);
+                       evas_object_color_set(rect, 242, 233, 183, 255);
+                       evas_object_show(rect);
+                       elm_layout_content_set(layout, "elm.swallow.icon", rect);
+
+                       // FIXME: add string length check
+                       Evas_Object *ientry = elm_entry_add(obj);
+                       evas_object_size_hint_weight_set(ientry, 0, 0);
+                       Eina_Strbuf *strent = NULL;
+                       char *strdata = eina_strbuf_string_get(ti->istrdata);
+                       int i, skipflag, strcnt;
+
+                       strent = eina_strbuf_new();
+                       skipflag = 0;
+                       strcnt = 0;
+                       for (i = 0; i < eina_strbuf_length_get(ti->istrdata); i++)
+                       {
+                               switch (strdata[i])
+                               {
+                                       case '>':
+                                               skipflag = 0;
+                                               break;
+                                       case '<':
+                                               skipflag = 1;
+                                               break;
+                                       default:
+                                               if (!skipflag)
+                                                       strcnt++;
+                                               break;
+                               }
+                               if (strcnt > 100)
+                                       break;
+                       }
+                       eina_strbuf_append_n(strent, strdata, i);
+                       eina_strbuf_replace_all(strent, " absize=240x180 ", " absize=52x39 ");
+                       if (strcnt > 100)
+                               eina_strbuf_append(strent, "...");
+                       elm_entry_scrollable_set(ientry, EINA_TRUE);
+                       char *entry_text = eina_strbuf_string_get(strent);
+                       entry_text = _get_string_for_entry(entry_text);
+                       if (entry_text)
+                       {
+                               elm_object_part_text_set(ientry, NULL, entry_text);
+                               free(entry_text);
+                       }
+                       elm_entry_editable_set(ientry, EINA_FALSE);
+                       elm_entry_context_menu_disabled_set(ientry, EINA_TRUE);
+                       evas_object_show(ientry);
+                       elm_layout_content_set(layout, "elm.swallow.inner", ientry);
+
+                       eina_strbuf_free(strent);
+
+                       return layout;
+               }
+               else// if (ti->itype == GI_IMAGE)
+               {
+                       Evas_Object *layout = elm_layout_add (obj);
+                       elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout");
+                       edje_object_signal_callback_add(elm_layout_edje_get(layout),
+                                                                                       "mouse,up,1", "*", _grid_item_ly_clicked, data);
+
+                       Evas_Object *sicon;
+                       sicon = evas_object_image_add(evas_object_evas_get(obj));
+                       evas_object_image_load_size_set(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
+                       evas_object_image_file_set(sicon, ti->ipathdata, NULL);
+                       evas_object_image_fill_set(sicon, 0, 0, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
+                       evas_object_resize(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
+                       elm_layout_content_set(layout, "elm.swallow.icon", sicon);
+
+                       struct appdata *ad = g_get_main_appdata();
+
+                       if (clipdrawer_paste_textonly_get(ad))
+                               edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,show,dim", "elm");
+                       else
+                               edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,hide,dim", "elm");
+
+                       ti->ilayout = layout;
+                       return layout;
+               }
+       }
+
+       return NULL;
+}
+
+static void _grid_longpress(void *data, Evas_Object *obj, void *event_info)
+{
+       struct appdata *ad = data;
+}
+
+static void _grid_click_paste(void *data, Evas_Object *obj, void *event_info)
+{
+       struct appdata *ad = data;
+       if (ad->anim_status != STATUS_NONE)
+               return;
+
+       Elm_Gengrid_Item *sgobj = NULL;
+       sgobj = elm_gengrid_selected_item_get(ad->hig);
+       griditem_t *ti = NULL;
+       ti = elm_gengrid_item_data_get(sgobj);
+}
+
+void _grid_del(const void *data, Evas_Object *obj)
+{
+       griditem_t *ti = (griditem_t *)data;
+       if (ti->itype == GI_TEXT)
+               eina_strbuf_free(ti->istrdata);
+       else
+               eina_stringshare_del(ti->ipathdata);
+       free(ti);
+}
+
+char* clipdrawer_get_item_data(void *data, int pos)
+{
+       struct appdata *ad = data;
+       griditem_t *ti = NULL;
+       griditem_t *newgi = NULL;
+       int count = 0;
+
+       if (pos < 0 || pos > ad->hicount)
+               return NULL;
+
+       Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
+       while (item)
+       {
+               ti = elm_gengrid_item_data_get(item);
+               if (count == pos)
+               {
+                       if (!ti)
+                               break;
+                       if (ti->itype == GI_TEXT)
+                               return (char*)eina_strbuf_string_get(ti->istrdata);
+                       else
+                               return ti->ipathdata;
+               }
+               count++;
+               item = elm_gengrid_item_next_get(item);
+       }
+
+       return NULL;
+}
+
+// FIXME: how to remove calling g_get_main_appdata()?
+//        it's mainly used at 'clipdrawer_image_item'
+int clipdrawer_add_item(char *idata, int type)
+{
+       struct appdata *ad = g_get_main_appdata();
+       griditem_t *newgi = NULL;
+
+       newgi = malloc(sizeof(griditem_t));
+       newgi->itype = type;
+
+       fprintf(stderr, "## add - %d : %s\n", newgi->itype, idata);
+       if (type == GI_TEXT)
+       {
+               newgi->istrdata = eina_strbuf_new();
+               eina_strbuf_append(newgi->istrdata, idata);
+       }
+       else //if (type == GI_IMAGE)
+       {
+               Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
+               griditem_t *ti = NULL;
+
+               if (!check_regular_file(idata))
+               {
+                       DTRACE("Error : it isn't normal file = %s\n", idata);
+                       return -1;
+               }
+
+               while (item)
+               {
+                       ti = elm_gengrid_item_data_get(item);
+                       if ((ti->itype == type) && !strcmp(ti->ipathdata, idata))
+                       {
+                               DTRACE("Error : duplicated file path = %s\n", idata);
+                               return -1;
+                       }
+                       item = elm_gengrid_item_next_get(item);
+               }
+               newgi->ipathdata = eina_stringshare_add(idata);
+       }
+
+       if (ad->hicount >= HISTORY_QUEUE_MAX_ITEMS)
+       {
+               ad->hicount--;
+               // FIXME: add routine that is removing its elements
+               elm_gengrid_item_del(elm_gengrid_last_item_get(ad->hig));
+       }
+
+       ad->hicount++;
+       newgi->item = elm_gengrid_item_prepend(ad->hig, &gic, newgi, NULL, NULL);
+
+       return TRUE;
+}
+
+static void
+clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+       struct appdata *ad = data;
+
+       if (ad->anim_status != STATUS_NONE)
+               return;
+
+       #define EDJE_CLOSE_PART_PREFIX "background/close"
+       if (!strncmp(source, EDJE_CLOSE_PART_PREFIX, strlen(EDJE_CLOSE_PART_PREFIX)))
+       {
+               clipdrawer_lower_view(ad);
+       }
+}
+
+static void set_sliding_win_geometry(void *data)
+{
+       struct appdata *ad = data;
+       Ecore_X_Window zone, xwin;
+       Evas_Coord x, y, w, h;
+       xwin = elm_win_xwindow_get(ad->win_main);
+       zone = ecore_x_e_illume_zone_get(xwin);
+       DTRACE("[CBHM] xwin:%x, zone:%x\n", xwin, zone);
+
+//     ecore_evas_geometry_get(ecore_evas_ecore_evas_get(evas_object_evas_get(ad->win_main)), &x, &y, &w, &h);
+
+       if (ad->o_degree == 90 || ad->o_degree == 270)
+       {
+               h = ad->anim_count * CLIPDRAWER_HEIGHT_LANDSCAPE / ANIM_DURATION;
+               x = 0;
+               y = ad->root_w - h;
+               w = ad->root_h;
+       }
+       else
+       {
+               h = ad->anim_count * CLIPDRAWER_HEIGHT / ANIM_DURATION;
+               x = 0;
+               y = ad->root_h - h;
+               w = ad->root_w;
+       }
+
+       if (!h)
+               w = 0;
+
+       DTRACE("[CBHM] change degree geometry... (%d, %d, %d x %d)\n", x, y, w, h);
+       ecore_x_e_illume_sliding_win_geometry_set(zone, x, y, w, h);
+       ecore_x_e_illume_sliding_win_state_set(zone, ad->anim_count != 0);
+}
+
+void set_rotation_to_clipdrawer(void *data)
+{
+       struct appdata *ad = data;
+       int angle = ad->o_degree;
+       int x, y, w, h;
+
+       if (angle == 180) // reverse
+       {
+               h = CLIPDRAWER_HEIGHT;
+               x = 0;
+               y = 0;
+               w = ad->root_w;
+       }
+       else if (angle == 90) // right rotate
+       {
+               h = CLIPDRAWER_HEIGHT_LANDSCAPE;
+               x = ad->root_w - h;
+               y = 0;
+               w = ad->root_h;
+       }
+       else if (angle == 270) // left rotate
+       {
+               h = CLIPDRAWER_HEIGHT_LANDSCAPE;
+               x = 0;
+               y = 0;
+               w = ad->root_h;
+       }
+       else // angle == 0
+       {
+               h = CLIPDRAWER_HEIGHT;
+               x = 0;
+               y = ad->root_h - h;
+               w = ad->root_w;
+       }
+
+       evas_object_resize(ad->win_main, w, h);
+       evas_object_move(ad->win_main, x, y);
+       if (ad->anim_count == ANIM_DURATION)
+               set_sliding_win_geometry(data);
+}
+
+int clipdrawer_init(void *data)
+{
+       struct appdata *ad = data;
+       double cdy, cdw;
+
+       ad->windowshow = EINA_FALSE;
+       ad->hicount = 0;
+       ad->pastetextonly = EINA_TRUE;
+       ad->anim_status = STATUS_NONE;
+       ad->anim_count = 0;
+
+       // for elm_check
+       elm_theme_extension_add(NULL, APP_EDJ_FILE);
+
+       edje_object_signal_callback_add(elm_layout_edje_get(ad->ly_main),
+                                                                       "mouse,up,1", "*", clipdrawer_ly_clicked, ad);
+
+       ad->hig = NULL;
+       ad->hig = elm_gengrid_add(ad->win_main);
+       elm_layout_content_set(ad->ly_main, "historyitems", ad->hig);
+       elm_gengrid_item_size_set(ad->hig, GRID_ITEM_W+2, GRID_ITEM_H);
+       elm_gengrid_align_set(ad->hig, 0.5, 0.5);
+       elm_gengrid_horizontal_set(ad->hig, EINA_TRUE);
+       elm_gengrid_bounce_set(ad->hig, EINA_TRUE, EINA_FALSE);
+       elm_gengrid_multi_select_set(ad->hig, EINA_FALSE);
+       evas_object_smart_callback_add(ad->hig, "selected", _grid_click_paste, ad);
+//     evas_object_smart_callback_add(ad->hig, "longpressed", _grid_longpress, ad);
+       evas_object_size_hint_weight_set(ad->hig, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+       elm_gengrid_clear(ad->hig);
+
+       gic.item_style = "default_grid";
+       gic.func.label_get = NULL;
+       gic.func.content_get = _grid_icon_get;
+       gic.func.state_get = NULL;
+       gic.func.del = _grid_del;
+
+/*     int i;
+       griditem_t *newgi;
+
+       for (i = 0; i < N_IMAGES; i++)
+       {
+               clipdrawer_add_item(g_images_path[0], GI_IMAGE);
+       }
+
+       clipdrawer_add_item("clipboard history", GI_TEXT);*/
+
+       evas_object_show (ad->hig);
+
+// for debugging, calc history pos
+/*
+   Evas_Coord x, y, w, h;
+   Evas_Coord vx, vy, vw, vh;
+
+   edje_object_part_geometry_get(elm_layout_edje_get(ad->ly_main),"imagehistory/list",&x,&y,&w,&h);
+   evas_object_geometry_get (ad->hig, &vx,&vy,&vw,&vh);
+   fprintf(stderr, "## x = %d, y = %d, w = %d, h = %d\n", x, y, w, h);
+   fprintf(stderr, "## vx = %d, vy = %d, vw = %d, vh = %d\n", vx, vy, vw, vh);
+*/
+
+//     if (get_item_counts() != 0)
+//             clipdrawer_update_contents(ad);
+
+       return 0;
+}
+
+int clipdrawer_create_view(void *data)
+{
+       struct appdata *ad = data;
+
+       clipdrawer_init(ad);
+
+       // for debug
+       // at starting, showing app view
+       //clipdrawer_activate_view(ad);
+
+       return 0;
+}
+
+Eina_Bool _get_anim_pos(void *data, int *sp, int *ep)
+{
+       if (!sp || !ep)
+               return EINA_FALSE;
+
+       struct appdata *ad = data;
+       int angle = ad->o_degree;
+       int anim_start, anim_end;
+
+       if (angle == 180) // reverse
+       {
+               anim_start = -(ad->root_h - CLIPDRAWER_HEIGHT);
+               anim_end = 0;
+       }
+       else if (angle == 90) // right rotate
+       {
+               anim_start = ad->root_w;
+               anim_end = anim_start - CLIPDRAWER_HEIGHT_LANDSCAPE;
+       }
+       else if (angle == 270) // left rotate
+       {
+               anim_start = -(ad->root_w - CLIPDRAWER_HEIGHT_LANDSCAPE);
+               anim_end = 0;
+       }
+       else // angle == 0
+       {
+               anim_start = ad->root_h;
+               anim_end = anim_start - CLIPDRAWER_HEIGHT;
+       }
+
+       *sp = anim_start;
+       *ep = anim_end;
+       return EINA_TRUE;
+}
+
+Eina_Bool _do_anim_delta_pos(void *data, int sp, int ep, int ac, int *dp)
+{
+       if (!dp)
+               return EINA_FALSE;
+
+       struct appdata *ad = data;
+       int angle = ad->o_degree;
+       int delta;
+       double posprop;
+       posprop = 1.0*ac/ANIM_DURATION;
+
+       if (angle == 180) // reverse
+       {
+               delta = (int)((ep-sp)*posprop);
+               evas_object_move(ad->win_main, 0, sp+delta);
+       }
+       else if (angle == 90) // right rotate
+       {
+               delta = (int)((ep-sp)*posprop);
+               evas_object_move(ad->win_main, sp+delta, 0);
+       }
+       else if (angle == 270) // left rotate
+       {
+               delta = (int)((ep-sp)*posprop);
+               evas_object_move(ad->win_main, sp+delta, 0);
+       }
+       else // angle == 0
+       {
+               delta = (int)((sp-ep)*posprop);
+               evas_object_move(ad->win_main, 0, sp-delta);
+       }
+
+       *dp = delta;
+
+       return EINA_TRUE;
+}
+
+static void stop_animation(void *data)
+{
+       struct appdata *ad = data;
+
+       ad->anim_status = STATUS_NONE;
+       if (anim_timer)
+       {
+               ecore_timer_del(anim_timer);
+               anim_timer = NULL;
+       }
+
+       set_sliding_win_geometry(data);
+}
+
+Eina_Bool anim_pos_calc_cb(void *data)
+{
+       struct appdata *ad = data;
+
+       int anim_start, anim_end, delta;
+
+       _get_anim_pos(ad, &anim_start, &anim_end);
+
+       if (ad->anim_status == SHOW_ANIM)
+       {
+               if (ad->anim_count > ANIM_DURATION)
+               {
+                       ad->anim_count = ANIM_DURATION;
+                       stop_animation(data);
+                       return EINA_FALSE;
+               }
+               _do_anim_delta_pos(ad, anim_start, anim_end, ad->anim_count, &delta);
+               ad->anim_count++;
+       }
+       else if (ad->anim_status == HIDE_ANIM)
+       {
+               if (ad->anim_count < 0)
+               {
+                       ad->anim_count = 0;
+                       evas_object_hide(ad->win_main);
+                       elm_win_lower(ad->win_main);
+                       unset_transient_for(ad);
+                       stop_animation(data);
+                       return EINA_FALSE;
+               }
+               _do_anim_delta_pos(ad, anim_start, anim_end, ad->anim_count, &delta);
+               ad->anim_count--;
+       }
+       else
+       {
+               stop_animation(data);
+               return EINA_FALSE;
+       }
+
+       return EINA_TRUE;
+}
+
+Eina_Bool clipdrawer_anim_effect(void *data, anim_status_t atype)
+{
+       struct appdata *ad = data;
+
+       if (atype == ad->anim_status)
+       {
+               DTRACE("Warning: Animation effect is already in progress. \n");
+               return EINA_FALSE;
+       }
+
+       ad->anim_status = atype;
+
+       if (anim_timer)
+               ecore_timer_del(anim_timer);
+
+       anim_timer = ecore_timer_add(ANIM_FLOPS, anim_pos_calc_cb, ad);
+
+       return EINA_TRUE;
+}
+
+void clipdrawer_activate_view(void *data)
+{
+       struct appdata *ad = data;
+
+       if (ad->win_main)
+       {
+               set_focus_for_app_window(ad->win_main, EINA_TRUE);
+               set_transient_for(ad);
+               ad->o_degree = get_active_window_degree(ad->active_win);
+               elm_win_rotation_set(ad->win_main, ad->o_degree);
+               set_rotation_to_clipdrawer(data);
+               evas_object_show(ad->win_main);
+               elm_win_activate(ad->win_main);
+               if (clipdrawer_anim_effect(ad, SHOW_ANIM))
+                       ad->windowshow = EINA_TRUE;
+       }
+}
+
+void clipdrawer_lower_view(void *data)
+{
+       struct appdata *ad = data;
+
+       if (ad->win_main && ad->windowshow)
+       {
+               set_focus_for_app_window(ad->win_main, EINA_FALSE);
+               if (clipdrawer_anim_effect(ad, HIDE_ANIM))
+                       ad->windowshow = EINA_FALSE;
+       }
+}
+
+void _change_gengrid_paste_textonly_mode(void *data)
+{
+       struct appdata *ad = data;
+
+       griditem_t *ti = NULL;
+
+       Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
+
+       while (item)
+       {
+               ti = elm_gengrid_item_data_get(item);
+               if ((ti->itype == GI_IMAGE) && (ti->ilayout))
+               {
+                       if (clipdrawer_paste_textonly_get(ad))
+                               edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,show,dim", "elm");
+                       else
+                               edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,hide,dim", "elm");
+               }
+               item = elm_gengrid_item_next_get(item);
+       }
+}
+
+void clipdrawer_paste_textonly_set(void *data, Eina_Bool textonly)
+{
+       struct appdata *ad = data;
+       textonly = !!textonly;
+       if (ad->pastetextonly != textonly)
+               ad->pastetextonly = textonly;
+       DTRACE("paste textonly mode = %d\n", textonly);
+
+       _change_gengrid_paste_textonly_mode(ad);
+}
+
+Eina_Bool clipdrawer_paste_textonly_get(void *data)
+{
+       struct appdata *ad = data;
+       return ad->pastetextonly;
+}
diff --git a/src/old/clipdrawer.h b/src/old/clipdrawer.h
new file mode 100644 (file)
index 0000000..0135ffc
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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.
+ *
+ */
+
+#ifndef _clipdrawer_h_
+#define _clipdrawer_h_
+
+#define CLIPDRAWER_HEIGHT 360
+#define CLIPDRAWER_HEIGHT_LANDSCAPE 228
+
+enum {
+       GI_TEXT = 0,
+       GI_IMAGE,
+
+       GI_MAX_ITEMS,
+};
+
+/* view maintains */
+int clipdrawer_init(void *data);
+int clipdrawer_create_view(void *data);
+void clipdrawer_activate_view(void *data);
+//void clipdrawer_hide_view(void *data);
+void clipdrawer_lower_view(void *data);
+
+void set_rotation_to_clipdrawer(void *data);
+
+const char* clipdrawer_get_plain_string_from_escaped(char *escstr);
+
+char *clipdrawer_get_item_data(void *data, int pos);
+int clipdrawer_add_item(char *idata, int type);
+
+void clipdrawer_paste_textonly_set(void *data, Eina_Bool textonly);
+Eina_Bool clipdrawer_paste_textonly_get(void *data);
+
+#endif // _clipdrawer_h_
similarity index 100%
rename from src/common.h
rename to src/old/common.h
diff --git a/src/old/scrcapture.c b/src/old/scrcapture.c
new file mode 100644 (file)
index 0000000..d535200
--- /dev/null
@@ -0,0 +1,768 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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 "common.h"
+#include "cbhm_main.h"
+#include "xcnphandler.h"
+#include "scrcapture.h"
+#include "clipdrawer.h"
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include <Ecore.h>
+#include <Ecore_X.h>
+#include <Ecore_Input.h>
+#include <utilX.h>
+
+//#define IMAGE_SAVE_DIR "/opt/media/Images and videos/My photo clips"
+#define IMAGE_SAVE_DIR "/opt/media/Images"
+#define IMAGE_SAVE_FILE_TYPE ".png"
+
+#include <errno.h>
+#include <sys/time.h>
+#include <svi/svi.h>
+#include <sys/types.h>
+
+#include <X11/Xutil.h>
+#include <X11/extensions/XShm.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/Xrandr.h>
+#include <pixman.h>
+
+static int svi_handle = -1;
+static Eina_Bool g_shot = EINA_FALSE;
+static XImage *ximage;
+static XShmSegmentInfo x_shm_info;
+static char *rot_buffer;
+
+
+typedef struct tag_captureimginfo
+{
+       char filename[256];
+       Evas_Object *eo;
+       char *imgdata;
+} captureimginfo_t;
+
+static const char *createScreenShotSW(Display *d, int width, int height);
+void releaseScreenShotSW(Display *d, const char * ss);
+static Eina_Bool get_image_filename_with_date(char *dstr)
+{
+       time_t tim = time(NULL);
+       struct tm *now = localtime(&tim);
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       sprintf(dstr, "%s/screen-%d%02d%02d%02d%02d%02d%0ld%s",
+                       IMAGE_SAVE_DIR,
+                       now->tm_year+1900, now->tm_mon+1, now->tm_mday,
+                       now->tm_hour, now->tm_min,
+                       now->tm_sec, tv.tv_usec,
+                       IMAGE_SAVE_FILE_TYPE);
+       return EINA_TRUE;
+}
+
+
+static void _play_capture_sound()
+{
+       int ret = SVI_ERROR;
+
+       if (svi_handle != -1)
+               ret = svi_play(svi_handle, SVI_VIB_OPERATION_SHUTTER, SVI_SND_OPERATION_SCRCAPTURE);
+
+       if (ret != SVI_SUCCESS)
+       {
+               DTRACE("play file failed\n");
+       }
+       else
+       {
+               DTRACE("play file success\n");
+       }
+}
+
+static Eina_Bool hide_small_popup(void *data)
+{
+       struct appdata *ad = data;
+       ad->popup_timer = NULL;
+       evas_object_hide(ad->small_popup);
+       return ECORE_CALLBACK_CANCEL;
+}
+
+static void show_small_popup(struct appdata *ad, char* msg)
+{
+       if (!ad->small_popup)
+               ad->small_popup = elm_tickernoti_add(NULL);
+       if (!ad->small_win)
+               ad->small_win = elm_tickernoti_win_get(ad->small_popup);
+
+       elm_object_style_set(ad->small_popup, "info");
+       elm_tickernoti_label_set(ad->small_popup, msg);
+       elm_tickernoti_orientation_set(ad->small_popup, ELM_TICKERNOTI_ORIENT_BOTTOM);
+       evas_object_show(ad->small_popup);
+       ad->popup_timer = ecore_timer_add(2, hide_small_popup, ad);
+}
+
+static void play_screen_capture_effect()
+{
+       struct appdata *ad = g_get_main_appdata();
+       show_small_popup(ad, "Screen capture success");
+       Ecore_X_Display *disp = ecore_x_display_get();
+       Ecore_X_Window root_win = ecore_x_window_root_first_get();
+       DTRACE("disp: 0x%x, root_win: 0x%x\n", disp, root_win);
+       utilx_show_capture_effect(disp, root_win);
+       _play_capture_sound();
+}
+
+static Eina_Bool _scrcapture_capture_postprocess(void* data)
+{
+       captureimginfo_t *capimginfo = data;
+
+       DTIME("start capture postprocess - %s\n", capimginfo->filename);
+
+       if (!evas_object_image_save(capimginfo->eo, capimginfo->filename, NULL, "compress=1"))
+       {
+               DTRACE("screen capture save fail\n");
+               g_shot = EINA_FALSE;
+               return EINA_FALSE;
+       }
+
+       DTIME("end capture postprocess - %s\n", capimginfo->filename);
+
+       char *imgpath = NULL;
+       imgpath = malloc(strlen(capimginfo->filename)+strlen("file://")+2);
+       snprintf(imgpath, strlen(capimginfo->filename)+strlen("file://")+1,
+                        "%s%s", "file://", capimginfo->filename);
+       DTRACE("add to image history = %s\n", imgpath+strlen("file://"));
+       clipdrawer_add_item(imgpath+strlen("file://"), GI_IMAGE);
+       free(imgpath);
+
+       evas_object_del(capimginfo->eo);
+       free(capimginfo->imgdata);
+       free(capimginfo);
+       play_screen_capture_effect();
+       DTIME("end current capture\n");
+
+       g_shot = EINA_FALSE;
+
+       return EINA_FALSE;
+}
+
+Eina_Bool capture_current_screen(void *data)
+{
+       struct appdata *ad = data;
+       if (!utilx_get_screen_capture(XOpenDisplay(NULL)))
+       {
+               show_small_popup(ad, "Screen capture disabled");
+               DTRACE("utilx_get_screen_capture: disable\n");
+               return EINA_FALSE;
+       }
+       else
+               DTRACE("utilx_get_screen_capture: enable\n");
+
+       if (g_shot)
+       {
+               DTRACE("too early to capture current screen\n");
+               return EINA_FALSE;
+       }
+       g_shot = EINA_TRUE;
+
+       DTIME("start current capture\n");
+
+       captureimginfo_t *capimginfo = NULL;
+       capimginfo = malloc(sizeof(captureimginfo_t) * 1);
+       get_image_filename_with_date(capimginfo->filename);
+       DTRACE("capture current screen\n");
+
+       int width, height;
+       width = ad->root_w;
+       height = ad->root_h;
+       capimginfo->imgdata = malloc(sizeof(char) * (width*height*4) + 1);
+       capimginfo->eo = evas_object_image_add(ad->evas);
+
+       char *scrimage = NULL;
+       scrimage = createScreenShotSW(ecore_x_display_get(), width, height);
+       if (scrimage)
+               memcpy(capimginfo->imgdata, scrimage, width*height*4);
+       releaseScreenShotSW(ecore_x_display_get(), scrimage);
+
+       if (scrimage == NULL || capimginfo->eo == NULL || capimginfo->imgdata == NULL)
+       {
+               DTRACE("screen capture fail\n");
+               free(capimginfo->imgdata);
+               if (capimginfo->eo)
+                       evas_object_del(capimginfo->eo);
+               free(capimginfo);
+               g_shot = EINA_FALSE;
+               return EINA_FALSE;
+       }
+
+       DTRACE("screen capture prepared\n");
+
+       evas_object_image_data_set(capimginfo->eo, NULL);
+       evas_object_image_size_set(capimginfo->eo, width, height);
+       evas_object_image_data_set(capimginfo->eo, capimginfo->imgdata);
+       evas_object_image_data_update_add(capimginfo->eo, 0, 0, width, height);
+       evas_object_resize(capimginfo->eo, width, height);
+
+       ecore_idler_add(_scrcapture_capture_postprocess, capimginfo);
+
+       return EINA_TRUE;
+}
+
+static Eina_Bool scrcapture_keydown_cb(void *data, int type, void *event)
+{
+       struct appdata *ad = data;
+       Ecore_Event_Key *ev = event;
+
+       if (!strcmp(ev->keyname, KEY_END))
+               clipdrawer_lower_view(ad);
+
+       return ECORE_CALLBACK_PASS_ON;
+}
+
+int init_scrcapture(void *data)
+{
+       struct appdata *ad = data;
+
+       int result = 0;
+
+       /* Key Grab */
+//     Ecore_X_Display *xdisp = ecore_x_display_get();
+//     Ecore_X_Window xwin = (Ecore_X_Window)ecore_evas_window_get(ecore_evas_ecore_evas_get(ad->evas));
+
+       ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, scrcapture_keydown_cb, ad);
+
+       if (svi_init(&svi_handle) != SVI_SUCCESS)
+       {
+               DTRACE("svi init failed\n");
+               svi_handle = -1;
+               return -1;
+       }
+
+       return 0;
+}
+
+void close_scrcapture(void *data)
+{
+       struct appdata *ad = data;
+
+//     Ecore_X_Display *xdisp = ecore_x_display_get();
+//     Ecore_X_Window xwin = (Ecore_X_Window)ecore_evas_window_get(ecore_evas_ecore_evas_get(ad->evas));
+
+       if (svi_handle != -1)
+               svi_fini(svi_handle);
+       if (ad->small_popup)
+               evas_object_del(ad->small_popup);
+       if (ad->small_win)
+               evas_object_del(ad->small_win);
+}
+
+static int get_window_attribute(Window id, int *depth, Visual **visual, int *width, int *height)
+{
+//     assert(id);
+       XWindowAttributes attr;
+
+       DTRACE("XGetWindowAttributes\n");
+       if (!XGetWindowAttributes(ecore_x_display_get(), id, &attr))
+       {
+               return -1;
+       }
+
+       if (attr.map_state == IsViewable && attr.class == InputOutput)
+       {
+               *depth = attr.depth;
+               *width = attr.width;
+               *height= attr.height;
+               *visual= attr.visual;
+       }
+
+       return 0;
+}
+
+static Window _get_parent_window( Window id )
+{
+       Window root;
+       Window parent;
+       Window* children;
+       unsigned int num;
+
+       DTRACE("XQeuryTree\n");
+
+       if (!XQueryTree(ecore_x_display_get(), id, &root, &parent, &children, &num))
+       {
+               return 0;
+       }
+
+       if (children)
+       {
+               DTRACE("XFree\n");
+               XFree(children);
+       }
+
+       return parent;
+}
+
+static Window find_capture_available_window( Window id, Visual** visual, int* depth, int* width, int* height)
+{
+       XWindowAttributes attr;
+       Window parent = id;
+       Window orig_id = id;
+
+       if (id == 0)
+       {
+               return (Window) -1;
+       }
+
+       do
+       {
+               id = parent;
+               DTRACE("find_capture - XGetWindowAttributes\n");
+
+               if (!XGetWindowAttributes(ecore_x_display_get(), id, &attr))
+               {
+                       return (Window) -1;
+               }
+
+               parent = _get_parent_window( id );
+
+               if (attr.map_state == IsViewable
+                               && attr.override_redirect == True
+                               && attr.class == InputOutput && parent == attr.root )
+               {
+                       *depth = attr.depth;
+                       *width = attr.width;
+                       *height = attr.height;
+                       *visual = attr.visual;
+                       return id;
+               }
+       } while( parent != attr.root && parent != 0 ); //Failed finding a redirected window
+
+
+       DTRACE( "find_capture - cannot find id\n");
+       XGetWindowAttributes (ecore_x_display_get(), orig_id, &attr);
+       *depth = attr.depth;
+       *width = attr.width;
+       *height = attr.height;
+       *visual = attr.visual;
+
+       return (Window) 0;
+
+}
+
+char *scrcapture_screen_capture(Window oid, int *size)
+{
+       XImage *xim;
+       XShmSegmentInfo si;
+       Pixmap pix;
+       int depth;
+       int width;
+       int height;
+       Visual *visual;
+       char *captured_image;
+       Window id;
+
+       id = find_capture_available_window(ecore_x_window_focus_get(), &visual, &depth, &width, &height);
+
+       if (id == 0 || id == -1 || id == oid)
+       {
+               DTRACE("Window : 0x%lX\n", id);
+               if (get_window_attribute(id, &depth, &visual, &width, &height) < 0)
+               {
+                       DTRACE("Failed to get the attributes from 0x%x\n", (unsigned int)id);
+                       return NULL;
+               }
+       }
+
+       DTRACE("WxH : %dx%d\n", width, height);
+       DTRACE("Depth : %d\n", depth >> 3);
+
+       // NOTE: just add one more depth....
+       si.shmid = shmget(IPC_PRIVATE, width * height * ((depth >> 3)+1), IPC_CREAT | 0666);
+       if (si.shmid < 0)
+       {
+               DTRACE("error at shmget\n");
+               return NULL;
+       }
+       si.readOnly = False;
+       si.shmaddr = shmat(si.shmid, NULL, 0);
+       if (si.shmaddr == (char*)-1)
+       {
+               shmdt(si.shmaddr);
+               shmctl(si.shmid, IPC_RMID, 0);
+               DTRACE("can't get shmat\n");
+               return NULL;
+       }
+
+/*
+       if (!need_redirecting)
+       {
+               Window border;
+               if (get_border_window(id, &border) < 0)
+               {
+                       need_redirecting = 1;
+                       printf("Failed to find a border, forcely do redirecting\n");
+               }
+               else
+               {
+                       id = border;
+                       printf("Border window is found, use it : 0x%X\n", (unsigned int)id);
+               }
+       }
+
+       if (need_redirecting)
+       {
+               printf("XCompositeRedirectWindow");
+               XCompositeRedirectWindow(ecore_x_display_get(), id, CompositeRedirectManual);
+       }
+*/
+
+
+       DTRACE("XShmCreateImage\n");
+       xim = XShmCreateImage(ecore_x_display_get(), visual, depth, ZPixmap, NULL, &si, width, height);
+       if (!xim)
+       {
+               shmdt(si.shmaddr);
+               shmctl(si.shmid, IPC_RMID, 0);
+
+/*
+               if (need_redirecting)
+               {
+                       printf("XCompositeUnredirectWindow");
+                       XCompositeUnredirectWindow(ecore_x_display_get(), id, CompositeRedirectManual);
+               }
+*/
+               return NULL;
+       }
+
+       *size = xim->bytes_per_line * xim->height;
+       xim->data = si.shmaddr;
+
+       DTRACE("XCompositeNameWindowPixmap\n");
+       pix = XCompositeNameWindowPixmap(ecore_x_display_get(), id);
+
+       DTRACE("XShmAttach\n");
+       XShmAttach(ecore_x_display_get(), &si);
+
+       DTRACE("XShmGetImage\n");
+       XShmGetImage(ecore_x_display_get(), pix, xim, 0, 0, 0xFFFFFFFF);
+
+       //XUnmapWindow(disp, id);
+       //XMapWindow(disp, id);
+       DTRACE("XSync\n");
+       XSync(ecore_x_display_get(), False);
+
+       //sleep(1);
+       // We can optimize this!
+       captured_image = calloc(1, *size);
+       if (captured_image)
+       {
+               memcpy(captured_image, xim->data, *size);
+       }
+       else
+       {
+               DTRACE("calloc error");
+       }
+
+       DTRACE("XShmDetach");
+       XShmDetach(ecore_x_display_get(), &si);
+       DTRACE("XFreePixmap\n");
+       XFreePixmap(ecore_x_display_get(), pix);
+       DTRACE("XDestroyImage\n");
+       XDestroyImage(xim);
+
+/*
+       if (need_redirecting) {
+               printf("XCompositeUnredirectWindow");
+               XCompositeUnredirectWindow(ecore_x_display_get(), id, CompositeRedirectManual);
+       }
+*/
+
+       shmdt(si.shmaddr);
+       shmctl(si.shmid, IPC_RMID, 0);
+       return captured_image;
+}
+
+char *scrcapture_capture_screen_by_x11(Window xid, int *size)
+{
+       XImage *xim;
+       int depth;
+       int width;
+       int height;
+       Visual *visual;
+       char *captured_image;
+
+
+       DTRACE("Window : 0x%lX\n", xid);
+       if (get_window_attribute(xid, &depth, &visual, &width, &height) < 0)
+       {
+               DTRACE("Failed to get the attributes from 0x%x\n", (unsigned int)xid);
+               return NULL;
+       }
+
+       DTRACE("WxH : %dx%d\n", width, height);
+       DTRACE("Depth : %d\n", depth >> 3);
+
+       xim = XGetImage(ecore_x_display_get(), xid, 0, 0,
+                                        width, height, AllPlanes, ZPixmap);
+
+       *size = xim->bytes_per_line * xim->height;
+
+       captured_image = calloc(1, *size);
+       if (captured_image)
+       {
+               memcpy(captured_image, xim->data, *size);
+       }
+       else
+       {
+               DTRACE("calloc error");
+       }
+
+       return captured_image;
+}
+
+#define return_if_fail(cond)          {if (!(cond)) { printf ("%s : '%s' failed.\n", __FUNCTION__, #cond); return; }}
+#define return_val_if_fail(cond, val) {if (!(cond)) { printf ("%s : '%s' failed.\n", __FUNCTION__, #cond); return val; }}
+#define goto_if_fail(cond, dst)       {if (!(cond)) { printf ("%s : '%s' failed.\n", __FUNCTION__, #cond); goto dst; }}
+
+int convert_image (uint32_t       *srcbuf,
+               uint32_t       *dstbuf,
+               pixman_format_code_t src_format,
+               pixman_format_code_t dst_format,
+               int src_width, int src_height,
+               int dst_width, int dst_height,
+               int             rotate)
+{
+       pixman_image_t *   src_img;
+       pixman_image_t *   dst_img;
+       pixman_transform_t transform;
+       pixman_region16_t  clip;
+       int                src_stride, dst_stride;
+       int                src_bpp;
+       int                dst_bpp;
+       pixman_op_t        op;
+       int                rotate_step;
+       int                ret = False;
+
+       return_val_if_fail (srcbuf != NULL, False);
+       return_val_if_fail (dstbuf != NULL, False);
+       return_val_if_fail (rotate <= 360 && rotate >= -360, False);
+
+       op = PIXMAN_OP_SRC;
+
+       src_bpp = PIXMAN_FORMAT_BPP (src_format) / 8;
+       return_val_if_fail (src_bpp > 0, False);
+
+       dst_bpp = PIXMAN_FORMAT_BPP (dst_format) / 8;
+       return_val_if_fail (dst_bpp > 0, False);
+
+       rotate_step = (rotate + 360) / 90 % 4;
+
+       src_stride = src_width * src_bpp;
+       dst_stride = dst_width * dst_bpp;
+
+       src_img = pixman_image_create_bits (src_format, src_width, src_height, srcbuf, src_stride);
+       dst_img = pixman_image_create_bits (dst_format, dst_width, dst_height, dstbuf, dst_stride);
+
+       goto_if_fail (src_img != NULL, CANT_CONVERT);
+       goto_if_fail (dst_img != NULL, CANT_CONVERT);
+
+       pixman_transform_init_identity (&transform);
+
+       if (rotate_step > 0)
+       {
+               int c, s, tx = 0, ty = 0;
+               switch (rotate_step)
+               {
+               case 1:
+                       /* 270 degrees */
+                       c = 0;
+                       s = -pixman_fixed_1;
+                       ty = pixman_int_to_fixed (dst_width);
+                       break;
+               case 2:
+                       /* 180 degrees */
+                       c = -pixman_fixed_1;
+                       s = 0;
+                       tx = pixman_int_to_fixed (dst_width);
+                       ty = pixman_int_to_fixed (dst_height);
+                       break;
+               case 3:
+                       /* 90 degrees */
+                       c = 0;
+                       s = pixman_fixed_1;
+                       tx = pixman_int_to_fixed (dst_height);
+                       break;
+               default:
+                       /* 0 degrees */
+                       c = 0;
+                       s = 0;
+                       break;
+               }
+               pixman_transform_rotate (&transform, NULL, c, s);
+               pixman_transform_translate (&transform, NULL, tx, ty);
+       }
+
+       pixman_image_set_transform (src_img, &transform);
+
+       pixman_image_composite (op, src_img, NULL, dst_img,
+                               0, 0, 0, 0, 0, 0, dst_width, dst_height);
+
+       ret = True;
+
+CANT_CONVERT:
+       if (src_img)
+               pixman_image_unref (src_img);
+       if (dst_img)
+               pixman_image_unref (dst_img);
+
+       return ret;
+}
+
+int
+getXwindowProperty (Display *d, Window          xwindow,
+                    Atom            prop_atom,
+                    Atom            type_atom,
+                    unsigned char  *value,
+                    int             nvalues)
+{
+       int    ret = 0;
+       Atom    ret_type = None;
+       int    ret_format;
+       unsigned long  ret_nitems;
+       unsigned long  ret_bytes_after;
+       unsigned char *data = NULL;
+       int    result;
+
+       result = XGetWindowProperty (d,  xwindow,
+                                    prop_atom, 0, 0x7fffffff, False, type_atom,
+                                    &ret_type, &ret_format, &ret_nitems, &ret_bytes_after,
+                                    &data);
+
+       if (result != Success)
+       {
+               DTRACE("Getting a property is failed!");
+               ret = 0;
+       }
+       else if (type_atom != ret_type)
+               ret = 0;
+       else if (ret_format != 32)
+       {
+               DTRACE("Format is not matched! (%d)", ret_format);
+               ret = 0;
+       }
+       else if (ret_nitems == 0 || !data)
+               ret = 0;
+       else
+       {
+               if (ret_nitems < nvalues)
+                       nvalues = ret_nitems;
+
+               memcpy (value, data, nvalues*sizeof(int));
+               ret = nvalues;
+       }
+
+       if (data)
+               XFree(data);
+
+       return ret;
+}
+
+const char *createScreenShotSW(Display *d, int width, int height)
+{
+       Window  root;
+       int     rotate;
+       Atom    atom_rotaion;
+       char   *ret = NULL;
+
+       if (ximage)
+       {
+               XDestroyImage (ximage);
+               ximage = NULL;
+       }
+
+       root  = RootWindow (d, DefaultScreen(d));
+
+       ximage = XShmCreateImage (d, DefaultVisualOfScreen (DefaultScreenOfDisplay (d)), 24, ZPixmap, NULL,
+                                 &x_shm_info, (unsigned int)width, (unsigned int)height);
+       if (!ximage)
+       {
+               DTRACE("XShmCreateImage failed !\n");
+               return NULL;
+       }
+
+       x_shm_info.shmid    = shmget (IPC_PRIVATE,
+                                     ximage->bytes_per_line * ximage->height,
+                                     IPC_CREAT | 0777);
+       x_shm_info.shmaddr  = ximage->data = shmat (x_shm_info.shmid, 0, 0);
+       x_shm_info.readOnly = False;
+
+       if (!XShmAttach (d, &x_shm_info))
+       {
+               DTRACE("XShmAttach failed !\n");
+               return NULL;
+       }
+
+       if (!XShmGetImage (d, root, ximage, 0, 0, AllPlanes))
+       {
+               DTRACE("XShmGetImage failed !\n");
+               return NULL;
+       }
+
+       ret = ximage->data;
+
+       atom_rotaion = XInternAtom (d, "X_SCREEN_ROTATION", True);
+       if (!atom_rotaion ||
+               !getXwindowProperty (d, root, atom_rotaion, XA_CARDINAL, (unsigned char*)&rotate, 1))
+       {
+               rotate = RR_Rotate_0;
+       }
+
+       if (rotate == RR_Rotate_90 || rotate == RR_Rotate_270)
+       {
+               rot_buffer = calloc (ximage->bytes_per_line * ximage->height, 1);
+
+               convert_image ((uint32_t*)ximage->data,
+                       (uint32_t*)rot_buffer,
+                       PIXMAN_x8b8g8r8, PIXMAN_x8b8g8r8,
+                       height, width, width, height,
+                       (rotate == RR_Rotate_90) ? 90 : 270);
+
+               ret = rot_buffer;
+       }
+
+       XSync (d, False);
+
+       return ret;
+}
+
+void releaseScreenShotSW(Display *d, const char * ss)
+{
+       if (ximage)
+       {
+               XShmDetach (d, &x_shm_info);
+               shmdt (x_shm_info.shmaddr);
+               shmctl (x_shm_info.shmid, IPC_RMID, NULL);
+
+               XDestroyImage (ximage);
+               ximage = NULL;
+
+               if (rot_buffer)
+               {
+                       free (rot_buffer);
+                       rot_buffer = NULL;
+               }
+       }
+}
diff --git a/src/old/scrcapture.h b/src/old/scrcapture.h
new file mode 100644 (file)
index 0000000..f81f333
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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.
+ *
+ */
+
+#ifndef _scrcapture_h_
+#define _scrcapture_h_
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/XShm.h>
+#include <X11/Xatom.h>
+
+// XV extension API - start
+const char* createScreenShot(int width, int height);
+void releaseScreenShot(const char *ss);
+// XV extension API - end
+
+Eina_Bool capture_current_screen(void *data);
+char *scrcapture_capture_screen_by_x11(Window xid, int *size);
+char *scrcapture_capture_screen_by_xv_ext(int width, int height);
+void scrcapture_release_screen_by_xv_ext(const char *s);
+
+int init_scrcapture(void *data);
+void close_scrcapture(void *data);
+
+#endif // _scrcapture_h_
diff --git a/src/old/storage.c b/src/old/storage.c
new file mode 100644 (file)
index 0000000..b2acf88
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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 "common.h"
+#include "cbhm_main.h"
+#include "storage.h"
+
+/*
+   file structure
+
+   /---------------------------------------------------------------------------
+    |header|current_position|total_count|item_header|item_body(512kib)|item...|
+    --------------------------------------------------------------------------/
+
+*/
+
+#define STORAGE_FILEPATH "/opt/var/.savecbh"
+#define STORAGE_MAX_ITEMS HISTORY_QUEUE_MAX_ITEMS
+#define HEADER_ITEM_SIZE (sizeof(int))
+#define BODY_ITEM_SIZE HISTORY_QUEUE_ITEM_SIZE
+#define STORAGE_HEADER_SIZE (STORAGE_MAX_ITEMS * HEADER_ITEM_SIZE)
+#define STORAGE_BODY_SIZE (STORAGE_MAX_ITEMS * BODY_ITEM_SIZE)
+#define TOTAL_STORAGE_SIZE (STORAGE_HEADER_SIZE+STORAGE_BODY_SIZE)
+
+#define GET_HEADER_ADDR_BY_POSITION(pos) (STORAGE_HEADER_SIZE+pos*(HEADER_ITEM_SIZE+BODY_ITEM_SIZE))
+#define GET_BODY_ADDR_BY_POSITION(pos) (GET_HEADER_ADDR_BY_POSITION(pos)+HEADER_ITEM_SIZE)
+
+static FILE *g_storage_file = NULL;
+static unsigned int g_storage_serial_number = 0;
+
+int init_storage(void *data)
+{
+       struct appdata *ad = data;
+
+       int i;
+       int result = 0;
+
+       if (g_storage_file)
+               return 1;
+
+       g_storage_file = fopen(STORAGE_FILEPATH, "r+");
+       if (!g_storage_file)
+       {  // making data savefile
+               g_storage_file = fopen(STORAGE_FILEPATH, "w+");
+
+               if (!g_storage_file)
+               {
+                       close_storage(ad);
+                       DTRACE("Error : failed openning file for writing\n");
+                       return -1;
+               }
+
+               result = fseek(g_storage_file, TOTAL_STORAGE_SIZE-1, SEEK_SET);
+               if (!result)
+               {
+                       close_storage(ad);
+                       DTRACE("Error : failed moving file position to file's end\n");
+                       return -1;
+               }
+
+               result = fputc(0, g_storage_file);
+               if (result == EOF)
+               {
+               DTRACE("Error : failed writing to file's end\n");
+               return -1;
+               }
+       }
+
+       DTRACE("Success : storage init is done\n");
+
+       g_storage_serial_number = 0;
+
+       return 0;
+}
+
+int sync_storage(void *data)
+{
+//     struct appdata *ad = data;
+
+       if (!g_storage_file)
+       {
+               DTRACE("g_storage_file is null\n");
+               return -1;
+       }
+       fsync(g_storage_file);
+
+       return 0;
+}
+
+unsigned int get_storage_serial_code(void *data)
+{
+//     struct appdata *ad = data;
+
+       return g_storage_serial_number;
+}
+
+int adding_item_to_storage(void *data, int pos, char *idata)
+{
+//     struct appdata *ad = data;
+       if (!g_storage_file)
+       {
+               DTRACE("g_storage_file is null\n");
+               return -1;
+       }
+
+       int result;
+       result = fseek(g_storage_file, GET_HEADER_ADDR_BY_POSITION(pos), SEEK_SET);
+       // FIXME : replace from fprintf to fwrite
+       fprintf(g_storage_file, "%d", strlen(idata));
+       fprintf(g_storage_file, "%s", idata);
+
+       g_storage_serial_number++;
+       return 0;
+}
+
+int get_item_counts(void *data)
+{
+       struct appdata *ad = data;
+
+       return ad->hicount;
+}
+
+int close_storage(void *data)
+{
+       struct appdata *ad = data;
+
+       if (g_storage_file)
+               fclose(g_storage_file);
+       g_storage_file = NULL;
+       g_storage_serial_number = 0;
+
+       return 0;
+}
+
+int check_regular_file(char *path)
+{
+       struct stat fattr;
+       if (stat(path, &fattr))
+       {
+               DTRACE("Cannot get file at path = %s\n", path);
+               return FALSE;
+       }
+
+       return S_ISREG(fattr.st_mode);
+}
+
diff --git a/src/old/storage.h b/src/old/storage.h
new file mode 100644 (file)
index 0000000..e895ee4
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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.
+ *
+ */
+
+#ifndef _storage_h_
+#define _storage_h_
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+int init_storage(void *data);
+int sync_storage(void *data);
+unsigned int get_storage_serial_code(void *data);
+int adding_item_to_storage(void *data, int pos, char *idata);
+int get_item_counts(void *data);
+int close_storage(void *data);
+
+int check_regular_file(char *path);
+
+#endif // _storage_h_
similarity index 100%
rename from src/xcnphandler.c
rename to src/old/xcnphandler.c
similarity index 100%
rename from src/xcnphandler.h
rename to src/old/xcnphandler.h
index 11b1296..92b5843 100644 (file)
  *
  */
 
-#include "common.h"
-#include "cbhm_main.h"
-#include "xcnphandler.h"
-#include "scrcapture.h"
-#include "clipdrawer.h"
-
+#include <utilX.h>
+#include <sys/time.h>
+#include <svi/svi.h>
+#include <pixman.h>
 #include <sys/ipc.h>
-#include <sys/shm.h>
-
-#include <Ecore.h>
 #include <Ecore_X.h>
-#include <Ecore_Input.h>
-#include <utilX.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/XShm.h>
+#include <X11/extensions/Xrandr.h>
+
+#ifdef USE_SYSPOPUP
+#include <bundle.h>
+#include <syspopup_caller.h>
+#endif
+
+#include "scrcapture.h"
+#include "cbhm.h"
+#include "item_manager.h"
 
 //#define IMAGE_SAVE_DIR "/opt/media/Images and videos/My photo clips"
 #define IMAGE_SAVE_DIR "/opt/media/Images"
 #define IMAGE_SAVE_FILE_TYPE ".png"
 
-#include <errno.h>
-#include <sys/time.h>
-#include <svi/svi.h>
-#include <sys/types.h>
-
-#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/Xrandr.h>
-#include <pixman.h>
+#ifdef USE_SYSPOPUP
+enum syspopup_type {
+       SCREEN_CAPTURE_SUCCESS = 0,
+       SCREEN_CAPTURE_DISABLED
+};
+#define SYSPOPUP_PARAM_LEN 3
+#define SYSPOPUP_TYPE 0
+#define CBHM_SYSPOPUP "cbhm_syspopup"
+#else
+#define SCREEN_CAPTURE_SUCCESS "Screen capture success"
+#define SCREEN_CAPTURE_DISABLED "Screen capture disabled"
+#endif
+
+static char *createScreenShotSW(AppData *ad, int width, int height, XImage **ximage_ret, XShmSegmentInfo *x_shm_info);
+static void releaseScreenShotSW(Ecore_X_Display *x_disp, char *ss, XImage *ximage, XShmSegmentInfo *x_shm_info);
+
+SCaptureData *init_screencapture(AppData *ad)
+{
+       SCaptureData *sd = CALLOC(1, sizeof(SCaptureData));
 
-static int svi_handle = -1;
-static Eina_Bool g_shot = EINA_FALSE;
-static XImage *ximage;
-static XShmSegmentInfo x_shm_info;
-static char *rot_buffer;
+       int ret;
+       ret = svi_init(&sd->svi_handle);
+       if(ret != SVI_SUCCESS)
+       {
+               DMSG("svi_init failed %d\n", ret);
+               sd->svi_init = EINA_FALSE;
+       }
+       else
+               sd->svi_init = EINA_TRUE;
 
+       return sd;
+}
 
-typedef struct tag_captureimginfo
+void depose_screencapture(SCaptureData *sd)
 {
-       char filename[256];
-       Evas_Object *eo;
-       char *imgdata;
-} captureimginfo_t;
-
-static const char *createScreenShotSW(Display *d, int width, int height);
-void releaseScreenShotSW(Display *d, const char * ss);
-static Eina_Bool get_image_filename_with_date(char *dstr)
+       if (sd->svi_init)
+               svi_fini(sd->svi_handle);
+       if (sd->stimer)
+               ecore_timer_del(sd->stimer);
+       if (sd->spopup)
+               evas_object_del(sd->spopup);
+       if (sd->swin)
+               evas_object_del(sd->swin);
+       FREE(sd);
+}
+
+static char *get_image_filename_with_date()
 {
        time_t tim = time(NULL);
        struct tm *now = localtime(&tim);
        struct timeval tv;
        gettimeofday(&tv, NULL);
-       sprintf(dstr, "%s/screen-%d%02d%02d%02d%02d%02d%0ld%s",
+
+       size_t len = snprintf(NULL, 0, "%s/screen-%d%02d%02d%02d%02d%02d%0ld%s",
                        IMAGE_SAVE_DIR,
                        now->tm_year+1900, now->tm_mon+1, now->tm_mday,
                        now->tm_hour, now->tm_min,
                        now->tm_sec, tv.tv_usec,
-                       IMAGE_SAVE_FILE_TYPE);
-       return EINA_TRUE;
-}
-
-
-static void _play_capture_sound()
-{
-       int ret = SVI_ERROR;
-
-       if (svi_handle != -1)
-               ret = svi_play(svi_handle, SVI_VIB_OPERATION_SHUTTER, SVI_SND_OPERATION_SCRCAPTURE);
-
-       if (ret != SVI_SUCCESS)
+                       IMAGE_SAVE_FILE_TYPE) + 1;
+       char *filepath = MALLOC(sizeof(char) * len);
+       if (!filepath)
        {
-               DTRACE("play file failed\n");
-       }
-       else
-       {
-               DTRACE("play file success\n");
+               DTRACE("can't alloc filepath buffer\n");
+               return NULL;
        }
-}
 
-static Eina_Bool hide_small_popup(void *data)
-{
-       struct appdata *ad = data;
-       ad->popup_timer = NULL;
-       evas_object_hide(ad->small_popup);
-       return ECORE_CALLBACK_CANCEL;
+       snprintf(filepath, len, "%s/screen-%d%02d%02d%02d%02d%02d%0ld%s",
+                       IMAGE_SAVE_DIR,
+                       now->tm_year+1900, now->tm_mon+1, now->tm_mday,
+                       now->tm_hour, now->tm_min,
+                       now->tm_sec, tv.tv_usec,
+                       IMAGE_SAVE_FILE_TYPE);
+       return filepath;
 }
 
-static void show_small_popup(struct appdata *ad, char* msg)
-{
-       if (!ad->small_popup)
-               ad->small_popup = elm_tickernoti_add(NULL);
-       if (!ad->small_win)
-               ad->small_win = elm_tickernoti_win_get(ad->small_popup);
-
-       elm_object_style_set(ad->small_popup, "info");
-       elm_tickernoti_label_set(ad->small_popup, msg);
-       elm_tickernoti_orientation_set(ad->small_popup, ELM_TICKERNOTI_ORIENT_BOTTOM);
-       evas_object_show(ad->small_popup);
-       ad->popup_timer = ecore_timer_add(2, hide_small_popup, ad);
-}
+#ifdef USE_SYSPOPUP
+#define PRINT_CASE_WITH_FUNC(func, param) \
+       case param: \
+               DMSG(#func" fail: "#param"\n"); \
+               break;
 
-static void play_screen_capture_effect()
-{
-       struct appdata *ad = g_get_main_appdata();
-       show_small_popup(ad, "Screen capture success");
-       Ecore_X_Display *disp = ecore_x_display_get();
-       Ecore_X_Window root_win = ecore_x_window_root_first_get();
-       DTRACE("disp: 0x%x, root_win: 0x%x\n", disp, root_win);
-       utilx_show_capture_effect(disp, root_win);
-       _play_capture_sound();
-}
+#define PRINT_ERROR(error) \
+       print_bundle_error(__func__, error);
 
-static Eina_Bool _scrcapture_capture_postprocess(void* data)
+static void print_bundle_error(const char *func, int err)
 {
-       captureimginfo_t *capimginfo = data;
-
-       DTIME("start capture postprocess - %s\n", capimginfo->filename);
-
-       if (!evas_object_image_save(capimginfo->eo, capimginfo->filename, NULL, "compress=1"))
+       switch(errno)
        {
-               DTRACE("screen capture save fail\n");
-               g_shot = EINA_FALSE;
-               return EINA_FALSE;
+               PRINT_CASE_WITH_FUNC(func, EKEYREJECTED);
+               PRINT_CASE_WITH_FUNC(func, EPERM);
+               PRINT_CASE_WITH_FUNC(func, EINVAL);
+               default:
+                       DMSG("unknown errno in %s: %d", func, err);
+                       break;
        }
-
-       DTIME("end capture postprocess - %s\n", capimginfo->filename);
-
-       char *imgpath = NULL;
-       imgpath = malloc(strlen(capimginfo->filename)+strlen("file://")+2);
-       snprintf(imgpath, strlen(capimginfo->filename)+strlen("file://")+1,
-                        "%s%s", "file://", capimginfo->filename);
-       DTRACE("add to image history = %s\n", imgpath+strlen("file://"));
-       clipdrawer_add_item(imgpath+strlen("file://"), GI_IMAGE);
-       free(imgpath);
-
-       evas_object_del(capimginfo->eo);
-       free(capimginfo->imgdata);
-       free(capimginfo);
-       play_screen_capture_effect();
-       DTIME("end current capture\n");
-
-       g_shot = EINA_FALSE;
-
-       return EINA_FALSE;
 }
 
-Eina_Bool capture_current_screen(void *data)
+#undef PRINT_ERROR
+#undef PRINT_CASE_WITH_FUNC
+
+static void launch_cbhm_syspopup(SCaptureData *sd, int type)
 {
-       struct appdata *ad = data;
-       if (!utilx_get_screen_capture(XOpenDisplay(NULL)))
-       {
-               show_small_popup(ad, "Screen capture disabled");
-               DTRACE("utilx_get_screen_capture: disable\n");
-               return EINA_FALSE;
-       }
-       else
-               DTRACE("utilx_get_screen_capture: enable\n");
+       char syspopup_type[SYSPOPUP_PARAM_LEN];
 
-       if (g_shot)
+       bundle *b = bundle_create();
+       if (!b)
        {
-               DTRACE("too early to capture current screen\n");
-               return EINA_FALSE;
+               DMSG("bundle_create() fail\n");
+               return;
        }
-       g_shot = EINA_TRUE;
-
-       DTIME("start current capture\n");
-
-       captureimginfo_t *capimginfo = NULL;
-       capimginfo = malloc(sizeof(captureimginfo_t) * 1);
-       get_image_filename_with_date(capimginfo->filename);
-       DTRACE("capture current screen\n");
 
-       int width, height;
-       width = ad->root_w;
-       height = ad->root_h;
-       capimginfo->imgdata = malloc(sizeof(char) * (width*height*4) + 1);
-       capimginfo->eo = evas_object_image_add(ad->evas);
-
-       char *scrimage = NULL;
-       scrimage = createScreenShotSW(ecore_x_display_get(), width, height);
-       if (scrimage)
-               memcpy(capimginfo->imgdata, scrimage, width*height*4);
-       releaseScreenShotSW(ecore_x_display_get(), scrimage);
-
-       if (scrimage == NULL || capimginfo->eo == NULL || capimginfo->imgdata == NULL) 
+       snprintf(syspopup_type, SYSPOPUP_PARAM_LEN, "%d", type);
+       int ret = bundle_add(b, "CBHM_MSG_TYPE", syspopup_type);
+       if (ret == -1)
        {
-               DTRACE("screen capture fail\n");
-               free(capimginfo->imgdata);
-               if (capimginfo->eo)
-                       evas_object_del(capimginfo->eo);
-               free(capimginfo);
-               g_shot = EINA_FALSE;
-               return EINA_FALSE;
+               PRINT_ERROR(errno);
        }
-
-       DTRACE("screen capture prepared\n");
-
-       evas_object_image_data_set(capimginfo->eo, NULL);
-       evas_object_image_size_set(capimginfo->eo, width, height);
-       evas_object_image_data_set(capimginfo->eo, capimginfo->imgdata);
-       evas_object_image_data_update_add(capimginfo->eo, 0, 0, width, height);
-       evas_object_resize(capimginfo->eo, width, height);
-
-       ecore_idler_add(_scrcapture_capture_postprocess, capimginfo);
-
-       return EINA_TRUE;
-}
-
-static Eina_Bool scrcapture_keydown_cb(void *data, int type, void *event)
-{
-       struct appdata *ad = data;
-       Ecore_Event_Key *ev = event;
-
-       if (!strcmp(ev->keyname, KEY_END))
-               clipdrawer_lower_view(ad);
-
-       return ECORE_CALLBACK_PASS_ON;
-}
-
-int init_scrcapture(void *data)
-{
-       struct appdata *ad = data;
-
-       int result = 0;
-
-       /* Key Grab */
-//     Ecore_X_Display *xdisp = ecore_x_display_get();
-//     Ecore_X_Window xwin = (Ecore_X_Window)ecore_evas_window_get(ecore_evas_ecore_evas_get(ad->evas));
-
-       ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, scrcapture_keydown_cb, ad);
-
-       if (svi_init(&svi_handle) != SVI_SUCCESS)
+       else
        {
-               DTRACE("svi init failed\n");
-               svi_handle = -1;
-               return -1;
+               ret = syspopup_launch(CBHM_SYSPOPUP, b);
+               if (ret < 0)
+                       DMSG("syspopup_launch() fail: %d, %d\n", ret, errno);
        }
+       ret = bundle_free(b);
+       if (ret == -1)
+               DMSG("bundle_free() fail: %d\n", errno);
 
-       return 0;
+       return;
 }
-
-void close_scrcapture(void *data)
+#else
+static Eina_Bool hide_spopup(void *data)
 {
-       struct appdata *ad = data;
-
-//     Ecore_X_Display *xdisp = ecore_x_display_get();
-//     Ecore_X_Window xwin = (Ecore_X_Window)ecore_evas_window_get(ecore_evas_ecore_evas_get(ad->evas));
-
-       if (svi_handle != -1)
-               svi_fini(svi_handle);
-       if (ad->small_popup)
-               evas_object_del(ad->small_popup);
-       if (ad->small_win)
-               evas_object_del(ad->small_win);
+       SCaptureData *sd = data;
+       ecore_timer_del(sd->stimer);
+       sd->stimer = NULL;
+       evas_object_hide(sd->spopup);
+       return ECORE_CALLBACK_CANCEL;
 }
 
-static int get_window_attribute(Window id, int *depth, Visual **visual, int *width, int *height)
+static void show_spopup(SCaptureData *sd, char *msg)
 {
-//     assert(id);
-       XWindowAttributes attr;
-
-       DTRACE("XGetWindowAttributes\n");
-       if (!XGetWindowAttributes(ecore_x_display_get(), id, &attr))
-       {
-               return -1;
-       }
-
-       if (attr.map_state == IsViewable && attr.class == InputOutput)
-       {
-               *depth = attr.depth;
-               *width = attr.width;
-               *height= attr.height;
-               *visual= attr.visual;
-       }
-
-       return 0;
+       if (!sd->spopup)
+               sd->spopup = elm_tickernoti_add(NULL);
+       if (!sd->swin)
+               sd->swin = elm_tickernoti_win_get(sd->spopup);
+
+       elm_object_style_set(sd->spopup, "info");
+       elm_tickernoti_label_set(sd->spopup, msg);
+       elm_tickernoti_orientation_set(sd->spopup, ELM_TICKERNOTI_ORIENT_BOTTOM);
+       evas_object_show(sd->spopup);
+       sd->stimer = ecore_timer_add(2, hide_spopup, sd);
 }
+#endif
 
-static Window _get_parent_window( Window id )
+static void play_scrcapture_effect(AppData *ad)
 {
-       Window root;
-       Window parent;
-       Window* children;
-       unsigned int num;
-
-       DTRACE("XQeuryTree\n");
+       SCaptureData *sd = ad->screencapture;
 
-       if (!XQueryTree(ecore_x_display_get(), id, &root, &parent, &children, &num))
-       {
-               return 0;
-       }
+#ifdef USE_SYSPOPUP
+       launch_cbhm_syspopup(sd, SCREEN_CAPTURE_SUCCESS);
+#else
+       show_spopup(sd, SCREEN_CAPTURE_SUCCESS);
+       utilx_show_capture_effect(ad->x_disp, ad->x_root_win);
+#endif
 
-       if (children)
+       int ret = 0;
+       if (sd->svi_init)
        {
-               DTRACE("XFree\n");
-               XFree(children);
+               ret = svi_play(sd->svi_handle, SVI_VIB_OPERATION_SHUTTER, SVI_SND_OPERATION_SCRCAPTURE);
+               DMSG("svi_play return: %d\n", ret);
        }
-
-       return parent;
 }
 
-static Window find_capture_available_window( Window id, Visual** visual, int* depth, int* width, int* height)
+void capture_current_screen(AppData *ad)
 {
-       XWindowAttributes attr;
-       Window parent = id;
-       Window orig_id = id;
-
-       if (id == 0)
-       {
-               return (Window) -1;
-       }
-
-       do
-       {
-               id = parent;
-               DTRACE("find_capture - XGetWindowAttributes\n");
-
-               if (!XGetWindowAttributes(ecore_x_display_get(), id, &attr))
-               {
-                       return (Window) -1;
-               }
-
-               parent = _get_parent_window( id );
-
-               if (attr.map_state == IsViewable
-                               && attr.override_redirect == True
-                               && attr.class == InputOutput && parent == attr.root )
-               {
-                       *depth = attr.depth;
-                       *width = attr.width;
-                       *height = attr.height;
-                       *visual = attr.visual;
-                       return id;
-               }
-       } while( parent != attr.root && parent != 0 ); //Failed finding a redirected window 
+       SCaptureData *sd = ad->screencapture;
+       ClipdrawerData *cd = ad->clipdrawer;
+       Ecore_X_Display *disp = XOpenDisplay(NULL);
 
+       DMSG("ad->x_disp: 0x%x, disp: 0x%x\n", ad->x_disp, disp);
 
-       DTRACE( "find_capture - cannot find id\n");
-       XGetWindowAttributes (ecore_x_display_get(), orig_id, &attr);
-       *depth = attr.depth;
-       *width = attr.width;
-       *height = attr.height;
-       *visual = attr.visual;
-
-       return (Window) 0;
-
-}
-
-char *scrcapture_screen_capture(Window oid, int *size)
-{
-       XImage *xim;
-       XShmSegmentInfo si;
-       Pixmap pix;
-       int depth;
-       int width;
-       int height;
-       Visual *visual;
-       char *captured_image;
-       Window id;
-
-       id = find_capture_available_window(ecore_x_window_focus_get(), &visual, &depth, &width, &height);
-
-       if (id == 0 || id == -1 || id == oid)
+       if (!utilx_get_screen_capture(disp))
        {
-               DTRACE("Window : 0x%lX\n", id);
-               if (get_window_attribute(id, &depth, &visual, &width, &height) < 0)
-               {
-                       DTRACE("Failed to get the attributes from 0x%x\n", (unsigned int)id);
-                       return NULL;
-               }
+#ifdef USE_SYSPOPUP
+               launch_cbhm_syspopup(sd, SCREEN_CAPTURE_DISABLED);
+#else
+               show_spopup(sd, SCREEN_CAPTURE_DISABLED);
+#endif
+               DMSG("utilx_get_screen_capture: disable\n");
+               return;
        }
 
-       DTRACE("WxH : %dx%d\n", width, height);
-       DTRACE("Depth : %d\n", depth >> 3);
+       DTIME("start current capture\n");
 
-       // NOTE: just add one more depth....
-       si.shmid = shmget(IPC_PRIVATE, width * height * ((depth >> 3)+1), IPC_CREAT | 0666);
-       if (si.shmid < 0)
-       {
-               DTRACE("error at shmget\n");
-               return NULL;
-       }
-       si.readOnly = False;
-       si.shmaddr = shmat(si.shmid, NULL, 0);
-       if (si.shmaddr == (char*)-1)
+       int width, height;
+       width = cd->root_w;
+       height = cd->root_h;
+
+       char *imgdata = MALLOC(sizeof(char) * (width*height*4) + 1);
+       if (!imgdata)
        {
-               shmdt(si.shmaddr);
-               shmctl(si.shmid, IPC_RMID, 0);
-               DTRACE("can't get shmat\n");
-               return NULL;
+               DMSG("image buffer alloc fail\n");
+               goto do_done;
        }
 
-/*
-       if (!need_redirecting) 
+       Evas_Object *image = evas_object_image_add(cd->evas);
+       if (!image)
        {
-               Window border;
-               if (get_border_window(id, &border) < 0) 
-               {
-                       need_redirecting = 1;
-                       printf("Failed to find a border, forcely do redirecting\n");
-               } 
-               else 
-               {
-                       id = border;
-                       printf("Border window is found, use it : 0x%X\n", (unsigned int)id);
-               }
+               DMSG("image add fail\n");
+               goto do_done;
        }
 
-       if (need_redirecting) 
+       XImage *ximage;
+       XShmSegmentInfo x_shm_info;
+       char *scrimage = createScreenShotSW(ad, width, height, &ximage, &x_shm_info);
+       if (!scrimage)
        {
-               printf("XCompositeRedirectWindow");
-               XCompositeRedirectWindow(ecore_x_display_get(), id, CompositeRedirectManual);
+               DMSG("screen capture fail\n");
+               goto do_done;
        }
-*/
 
+       memcpy(imgdata, scrimage, width*height*4);
+       releaseScreenShotSW(ad->x_disp, scrimage, ximage, &x_shm_info);
 
-       DTRACE("XShmCreateImage\n");
-       xim = XShmCreateImage(ecore_x_display_get(), visual, depth, ZPixmap, NULL, &si, width, height);
-       if (!xim)
+       evas_object_image_data_set(image, NULL);
+       evas_object_image_size_set(image, width, height);
+       evas_object_image_data_set(image, imgdata);
+       evas_object_image_data_update_add(image, 0, 0, width, height);
+       evas_object_resize(image, width, height);
+       char *filepath = get_image_filename_with_date();
+       if (filepath)
        {
-               shmdt(si.shmaddr);
-               shmctl(si.shmid, IPC_RMID, 0);
-
-/*
-               if (need_redirecting) 
+               if (!evas_object_image_save(image, filepath, NULL, "compress=1"))
                {
-                       printf("XCompositeUnredirectWindow");
-                       XCompositeUnredirectWindow(ecore_x_display_get(), id, CompositeRedirectManual);
+                       DMSG("screen capture save fail\n");
+                       goto do_done;
                }
-*/
-               return NULL;
-       }
-
-       *size = xim->bytes_per_line * xim->height;
-       xim->data = si.shmaddr;
-
-       DTRACE("XCompositeNameWindowPixmap\n");
-       pix = XCompositeNameWindowPixmap(ecore_x_display_get(), id);
-
-       DTRACE("XShmAttach\n");
-       XShmAttach(ecore_x_display_get(), &si);
-
-       DTRACE("XShmGetImage\n");
-       XShmGetImage(ecore_x_display_get(), pix, xim, 0, 0, 0xFFFFFFFF);
-
-       //XUnmapWindow(disp, id);
-       //XMapWindow(disp, id);
-       DTRACE("XSync\n");
-       XSync(ecore_x_display_get(), False);
-
-       //sleep(1);
-       // We can optimize this!
-       captured_image = calloc(1, *size);
-       if (captured_image)
-       {
-               memcpy(captured_image, xim->data, *size);
-       }
-       else
-       {
-               DTRACE("calloc error");
-       }
-
-       DTRACE("XShmDetach");
-       XShmDetach(ecore_x_display_get(), &si);
-       DTRACE("XFreePixmap\n");
-       XFreePixmap(ecore_x_display_get(), pix);
-       DTRACE("XDestroyImage\n");
-       XDestroyImage(xim);
-
-/*
-       if (need_redirecting) {
-               printf("XCompositeUnredirectWindow");
-               XCompositeUnredirectWindow(ecore_x_display_get(), id, CompositeRedirectManual);
-       }
-*/
-
-       shmdt(si.shmaddr);
-       shmctl(si.shmid, IPC_RMID, 0);
-       return captured_image;
-}
-
-char *scrcapture_capture_screen_by_x11(Window xid, int *size)
-{
-       XImage *xim;
-       int depth;
-       int width;
-       int height;
-       Visual *visual;
-       char *captured_image;
+               item_add_by_data(ad, ad->targetAtoms[ATOM_INDEX_IMAGE].atom[0], filepath, strlen(filepath) + 1);
 
-
-       DTRACE("Window : 0x%lX\n", xid);
-       if (get_window_attribute(xid, &depth, &visual, &width, &height) < 0)
-       {
-               DTRACE("Failed to get the attributes from 0x%x\n", (unsigned int)xid);
-               return NULL;
-       }
-
-       DTRACE("WxH : %dx%d\n", width, height);
-       DTRACE("Depth : %d\n", depth >> 3);
-
-       xim = XGetImage(ecore_x_display_get(), xid, 0, 0,
-                                        width, height, AllPlanes, ZPixmap);
-
-       *size = xim->bytes_per_line * xim->height;
-
-       captured_image = calloc(1, *size);
-       if (captured_image)
-       {
-               memcpy(captured_image, xim->data, *size);
-       }
-       else
-       {
-               DTRACE("calloc error");
+               play_scrcapture_effect(ad);
+               DTIME("end current capture\n");
        }
 
-       return captured_image;
+do_done:
+       if (image)
+               evas_object_del(image);
+       if (imgdata)
+               FREE(imgdata);
+       return;
 }
 
 #define return_if_fail(cond)          {if (!(cond)) { printf ("%s : '%s' failed.\n", __FUNCTION__, #cond); return; }}
 #define return_val_if_fail(cond, val) {if (!(cond)) { printf ("%s : '%s' failed.\n", __FUNCTION__, #cond); return val; }}
 #define goto_if_fail(cond, dst)       {if (!(cond)) { printf ("%s : '%s' failed.\n", __FUNCTION__, #cond); goto dst; }}
 
-int convert_image (uint32_t       *srcbuf,
-               uint32_t       *dstbuf,
-               pixman_format_code_t src_format,
-               pixman_format_code_t dst_format,
-               int src_width, int src_height,
-               int dst_width, int dst_height,
+int convert_image(uint32_t *srcbuf, uint32_t *dstbuf,
+               pixman_format_code_t src_format, pixman_format_code_t dst_format,
+               int src_width, int src_height, int dst_width, int dst_height,
                int             rotate)
 {
-       pixman_image_t *   src_img;
-       pixman_image_t *   dst_img;
+       pixman_image_t *src_img;
+       pixman_image_t *dst_img;
        pixman_transform_t transform;
-       pixman_region16_t  clip;
-       int                src_stride, dst_stride;
-       int                src_bpp;
-       int                dst_bpp;
-       pixman_op_t        op;
-       int                rotate_step;
-       int                ret = False;
+       pixman_region16_t clip;
+       int src_stride, dst_stride;
+       int src_bpp;
+       int dst_bpp;
+       pixman_op_t op;
+       int rotate_step;
+       int ret = False;
 
        return_val_if_fail (srcbuf != NULL, False);
        return_val_if_fail (dstbuf != NULL, False);
@@ -562,24 +315,24 @@ int convert_image (uint32_t       *srcbuf,
 
        op = PIXMAN_OP_SRC;
 
-       src_bpp = PIXMAN_FORMAT_BPP (src_format) / 8;
-       return_val_if_fail (src_bpp > 0, False);
+       src_bpp = PIXMAN_FORMAT_BPP(src_format) / 8;
+       return_val_if_fail(src_bpp > 0, False);
 
-       dst_bpp = PIXMAN_FORMAT_BPP (dst_format) / 8;
-       return_val_if_fail (dst_bpp > 0, False);
+       dst_bpp = PIXMAN_FORMAT_BPP(dst_format) / 8;
+       return_val_if_fail(dst_bpp > 0, False);
 
        rotate_step = (rotate + 360) / 90 % 4;
 
        src_stride = src_width * src_bpp;
        dst_stride = dst_width * dst_bpp;
 
-       src_img = pixman_image_create_bits (src_format, src_width, src_height, srcbuf, src_stride);
-       dst_img = pixman_image_create_bits (dst_format, dst_width, dst_height, dstbuf, dst_stride);
+       src_img = pixman_image_create_bits(src_format, src_width, src_height, srcbuf, src_stride);
+       dst_img = pixman_image_create_bits(dst_format, dst_width, dst_height, dstbuf, dst_stride);
 
        goto_if_fail (src_img != NULL, CANT_CONVERT);
        goto_if_fail (dst_img != NULL, CANT_CONVERT);
 
-       pixman_transform_init_identity (&transform);
+       pixman_transform_init_identity(&transform);
 
        if (rotate_step > 0)
        {
@@ -611,130 +364,83 @@ int convert_image (uint32_t       *srcbuf,
                        s = 0;
                        break;
                }
-               pixman_transform_rotate (&transform, NULL, c, s);
-               pixman_transform_translate (&transform, NULL, tx, ty);
+               pixman_transform_rotate(&transform, NULL, c, s);
+               pixman_transform_translate(&transform, NULL, tx, ty);
        }
 
-       pixman_image_set_transform (src_img, &transform);
+       pixman_image_set_transform(src_img, &transform);
 
-       pixman_image_composite (op, src_img, NULL, dst_img,
+       pixman_image_composite(op, src_img, NULL, dst_img,
                                0, 0, 0, 0, 0, 0, dst_width, dst_height);
 
        ret = True;
 
 CANT_CONVERT:
        if (src_img)
-               pixman_image_unref (src_img);
+               pixman_image_unref(src_img);
        if (dst_img)
-               pixman_image_unref (dst_img);
+               pixman_image_unref(dst_img);
 
        return ret;
 }
 
-int
-getXwindowProperty (Display *d, Window          xwindow,
-                    Atom            prop_atom,
-                    Atom            type_atom,
-                    unsigned char  *value,
-                    int             nvalues)
+static char *createScreenShotSW(AppData *ad, int width, int height, XImage **ximage_ret, XShmSegmentInfo *x_shm_info)
 {
-       int    ret = 0;
-       Atom    ret_type = None;
-       int    ret_format;
-       unsigned long  ret_nitems;
-       unsigned long  ret_bytes_after;
-       unsigned char *data = NULL;
-       int    result;
-
-       result = XGetWindowProperty (d,  xwindow,
-                                    prop_atom, 0, 0x7fffffff, False, type_atom,
-                                    &ret_type, &ret_format, &ret_nitems, &ret_bytes_after,
-                                    &data);
-
-       if (result != Success)
-       {
-               DTRACE("Getting a property is failed!");
-               ret = 0;
-       }
-       else if (type_atom != ret_type)
-               ret = 0;
-       else if (ret_format != 32)
-       {
-               DTRACE("Format is not matched! (%d)", ret_format);
-               ret = 0;
-       }
-       else if (ret_nitems == 0 || !data)
-               ret = 0;
-       else
-       {
-               if (ret_nitems < nvalues)
-                       nvalues = ret_nitems;
+       char *ret = NULL;
 
-               memcpy (value, data, nvalues*sizeof(int));
-               ret = nvalues;
-       }
-
-       if (data)
-               XFree(data);
-
-       return ret;
-}
+       XImage *ximage;
 
-const char *createScreenShotSW(Display *d, int width, int height)
-{
-       Window  root;
-       int     rotate;
-       Atom    atom_rotaion;
-       char   *ret = NULL;
-
-       if (ximage)
-       {
-               XDestroyImage (ximage);
-               ximage = NULL;
-       }
-
-       root  = RootWindow (d, DefaultScreen(d));
-
-       ximage = XShmCreateImage (d, DefaultVisualOfScreen (DefaultScreenOfDisplay (d)), 24, ZPixmap, NULL,
-                                 &x_shm_info, (unsigned int)width, (unsigned int)height);
+       ximage = XShmCreateImage(ad->x_disp, DefaultVisualOfScreen(DefaultScreenOfDisplay(ad->x_disp)), 24, ZPixmap, NULL,
+                                 x_shm_info, (unsigned int)width, (unsigned int)height);
        if (!ximage)
        {
                DTRACE("XShmCreateImage failed !\n");
                return NULL;
        }
 
-       x_shm_info.shmid    = shmget (IPC_PRIVATE,
+       x_shm_info->shmid = shmget(IPC_PRIVATE,
                                      ximage->bytes_per_line * ximage->height,
                                      IPC_CREAT | 0777);
-       x_shm_info.shmaddr  = ximage->data = shmat (x_shm_info.shmid, 0, 0);
-       x_shm_info.readOnly = False;
+       ximage->data = (void *)shmat(x_shm_info->shmid, NULL, 0);
+       x_shm_info->shmaddr = ximage->data;
+       x_shm_info->readOnly = False;
 
-       if (!XShmAttach (d, &x_shm_info))
+       if (!XShmAttach(ad->x_disp, x_shm_info))
        {
                DTRACE("XShmAttach failed !\n");
+               releaseScreenShotSW(ad->x_disp, NULL, ximage, x_shm_info);
                return NULL;
        }
 
-       if (!XShmGetImage (d, root, ximage, 0, 0, AllPlanes))
+       if (!XShmGetImage(ad->x_disp, ad->x_root_win, ximage, 0, 0, AllPlanes))
        {
                DTRACE("XShmGetImage failed !\n");
+               releaseScreenShotSW(ad->x_disp, NULL, ximage, x_shm_info);
                return NULL;
        }
 
        ret = ximage->data;
 
-       atom_rotaion = XInternAtom (d, "X_SCREEN_ROTATION", True);
-       if (!atom_rotaion ||
-               !getXwindowProperty (d, root, atom_rotaion, XA_CARDINAL, (unsigned char*)&rotate, 1))
+       Ecore_X_Atom atom_rotation = ecore_x_atom_get("X_SCREEN_ROTATION");
+
+       int cnt;
+       unsigned char *prop_data = NULL;
+       int rotate = RR_Rotate_0;
+       if (ecore_x_window_prop_property_get(ad->x_root_win, atom_rotation, ECORE_X_ATOM_CARDINAL, 32, &prop_data, &cnt))
        {
-               rotate = RR_Rotate_0;
+               if (prop_data)
+               {
+                       memcpy(&rotate, prop_data, sizeof(int));
+                       FREE(prop_data);
+               }
        }
 
        if (rotate == RR_Rotate_90 || rotate == RR_Rotate_270)
        {
-               rot_buffer = calloc (ximage->bytes_per_line * ximage->height, 1);
+               char *rot_buffer;
+               rot_buffer = CALLOC(ximage->bytes_per_line * ximage->height, 1);
 
-               convert_image ((uint32_t*)ximage->data,
+               convert_image((uint32_t*)ximage->data,
                        (uint32_t*)rot_buffer,
                        PIXMAN_x8b8g8r8, PIXMAN_x8b8g8r8,
                        height, width, width, height,
@@ -743,26 +449,23 @@ const char *createScreenShotSW(Display *d, int width, int height)
                ret = rot_buffer;
        }
 
-       XSync (d, False);
+       ecore_x_sync();
 
+       *ximage_ret = ximage;
        return ret;
 }
 
-void releaseScreenShotSW(Display *d, const char * ss)
+static void releaseScreenShotSW(Ecore_X_Display *x_disp, char *ss, XImage *ximage, XShmSegmentInfo *x_shm_info)
 {
        if (ximage)
        {
-               XShmDetach (d, &x_shm_info);
-               shmdt (x_shm_info.shmaddr);
-               shmctl (x_shm_info.shmid, IPC_RMID, NULL);
+               XShmDetach(x_disp, x_shm_info);
+               shmdt(x_shm_info->shmaddr);
+               shmctl(x_shm_info->shmid, IPC_RMID, NULL);
 
-               XDestroyImage (ximage);
-               ximage = NULL;
+               if (ss != ximage->data)
+                       FREE(ss);
 
-               if (rot_buffer)
-               {
-                       free (rot_buffer);
-                       rot_buffer = NULL;
-               }
+               XDestroyImage(ximage);
        }
 }
index 0a68206..b1fc5cf 100644 (file)
  *
  */
 
-#ifndef _scrcapture_h_
-#define _scrcapture_h_
+#ifndef _SCRCAPTURE_H_
+#define _SCRCAPTURE_H_
 
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/Xcomposite.h>
-#include <X11/extensions/XShm.h>
-#include <X11/Xatom.h>
+#include <Elementary.h>
 
-// XV extension API - start 
-const char* createScreenShot(int width, int height);
-void releaseScreenShot(const char *ss);
-// XV extension API - end
+struct _SCaptureData {
+       int svi_handle;
 
-Eina_Bool capture_current_screen(void *data);
-char *scrcapture_capture_screen_by_x11(Window xid, int *size);
-char *scrcapture_capture_screen_by_xv_ext(int width, int height);
-void scrcapture_release_screen_by_xv_ext(const char *s);
+       Evas_Object *spopup;
+       Evas_Object *swin;
+       Ecore_Timer *stimer;
 
-int init_scrcapture(void *data);
-void close_scrcapture(void *data);
+       Eina_Bool svi_init:1;
+};
 
-#endif // _scrcapture_h_
+#include "cbhm.h"
+
+SCaptureData *init_screencapture(AppData *ad);
+void depose_screencapture(SCaptureData *sd);
+void capture_current_screen(AppData *ad);
+#endif // _SCRCAPTURE_H_
index 1fe56a9..6d44c0b 100644 (file)
  *
  */
 
-#include "common.h"
-#include "cbhm_main.h"
-#include "storage.h"
-
-/*
-   file structure 
+#include <Ecore_File.h>
 
-   /---------------------------------------------------------------------------
-    |header|current_position|total_count|item_header|item_body(512kib)|item...|
-    --------------------------------------------------------------------------/
+#include "storage.h"
+#define STORAGE_FILEPATH "/opt/var/.savecbh"
+#define STORAGE_KEY_INDEX "index"
+#define STORAGE_KEY_FORMAT "data%02d"
+#define STORAGE_INDEX_ITEM_NONE 0.0
 
-*/
+static void storage_item_index_wrote(StorageData *sd);
+static Eina_Bool item_write(Eet_File *ef, int index, CNP_ITEM *item);
+static void storage_rewrite_all_items(StorageData *sd);
+static Eina_Bool storage_index_write(StorageData *sd);
+static Eina_Bool storage_item_write(AppData *ad, CNP_ITEM *item);
+static Eina_Bool storage_item_delete(AppData *ad, CNP_ITEM *item);
+static CNP_ITEM *storage_item_load(StorageData *sd, int index);
+#ifdef DEBUG
+static void dump_items(StorageData *sd);
+#else
+#define dunp_items(a)
+#endif
 
-#define STORAGE_FILEPATH "/opt/var/.savecbh"
-#define STORAGE_MAX_ITEMS HISTORY_QUEUE_MAX_ITEMS
-#define HEADER_ITEM_SIZE (sizeof(int)) 
-#define BODY_ITEM_SIZE HISTORY_QUEUE_ITEM_SIZE
-#define STORAGE_HEADER_SIZE (STORAGE_MAX_ITEMS * HEADER_ITEM_SIZE)
-#define STORAGE_BODY_SIZE (STORAGE_MAX_ITEMS * BODY_ITEM_SIZE) 
-#define TOTAL_STORAGE_SIZE (STORAGE_HEADER_SIZE+STORAGE_BODY_SIZE)
+static int getMinIndex(indexType *indexTable, int len)
+{
+       int i = 0;
+       int minIndex;
+       indexType min;
+       min = indexTable[i];
+       minIndex = i;
 
-#define GET_HEADER_ADDR_BY_POSITION(pos) (STORAGE_HEADER_SIZE+pos*(HEADER_ITEM_SIZE+BODY_ITEM_SIZE))
-#define GET_BODY_ADDR_BY_POSITION(pos) (GET_HEADER_ADDR_BY_POSITION(pos)+HEADER_ITEM_SIZE)
+       for (i = 1; i < len; i++)
+       {
+               if ((min > indexTable[i]))
+               {
+                       min = indexTable[i];
+                       minIndex = i;
+               }
+       }
+       return minIndex;
+}
 
-static FILE *g_storage_file = NULL;
-static unsigned int g_storage_serial_number = 0;
+static int getMaxIndex(indexType *indexTable, int len)
+{
+       int i = 0;
+       indexType max = indexTable[i];
+       int maxIndex = i;
+       for (i = 1; i < len; i++)
+       {
+               if (max < indexTable[i])
+               {
+                       max = indexTable[i];
+                       maxIndex = i;
+               }
+       }
+       return maxIndex;
+}
 
-int init_storage(void *data)
+StorageData *init_storage(AppData *ad)
 {
-       struct appdata *ad = data;
+       CALLED();
+       StorageData *sd = CALLOC(1, sizeof(StorageData));
+       eet_init();
+       ecore_file_init();
 
-       int i;
-       int result = 0;
+       sd->ef = eet_open(STORAGE_FILEPATH, EET_FILE_MODE_READ_WRITE);
+       /*
+       if (sd->ef)
+       {
+               int read_size;
+               indexType *read_data;
+               read_data = eet_read(sd->ef, STORAGE_KEY_INDEX, &read_size);
 
-       if (g_storage_file)
-               return 1;
+               int storage_size = sizeof(indexType) * STORAGE_ITEM_CNT;
 
-       g_storage_file = fopen(STORAGE_FILEPATH, "r+");
-       if (!g_storage_file)
-       {  // making data savefile
-               g_storage_file = fopen(STORAGE_FILEPATH, "w+");
+               int copy_size = storage_size < read_size ? storage_size : read_size;
 
-               if (!g_storage_file)
+               if (read_data)
                {
-                       close_storage(ad);
-                       DTRACE("Error : failed openning file for writing\n");
-                       return -1;
-               }
+                       indexType *temp = MALLOC(read_size);
+                       if (!temp)
+                               return sd;
+                       memcpy(temp, read_data, read_size);
 
-               result = fseek(g_storage_file, TOTAL_STORAGE_SIZE-1, SEEK_SET);
-               if (!result) 
-               {
-                       close_storage(ad);
-                       DTRACE("Error : failed moving file position to file's end\n");
-                       return -1;
-               }
+                       int i;
+                       int copy_cnt = copy_size/sizeof(indexType);
+                       for (i = 0; i < copy_cnt; i++)
+                       {
+                               int maxIndex = getMaxIndex(temp, copy_cnt);
+                               if (temp[maxIndex] == STORAGE_INDEX_ITEM_NONE)
+                                       break;
+                               sd->itemTable[i] = storage_item_load(sd, maxIndex);
+                               if (sd->itemTable[i])
+                                       sd->indexTable[i] = temp[maxIndex];
+                               temp[maxIndex] = STORAGE_INDEX_ITEM_NONE;
 
-               result = fputc(0, g_storage_file);
-               if (result == EOF)
+                               DMSG("load storage item index %d\n", i);
+                       }
+                       for (i = copy_cnt - 1; i >= 0; i--)
+                       {
+                               if (sd->itemTable[i])
+                                       item_add_by_CNP_ITEM(ad, sd->itemTable[i]);
+                       }
+               }
+               else
                {
-               DTRACE("Error : failed writing to file's end\n");
-               return -1;
+                       DMSG("load storage index failed\n");
                }
        }
+       else
+               DMSG("storage ef is NULLd\n");
+       */
+       dump_items(sd);
 
-       DTRACE("Success : storage init is done\n");
+       ad->storage_item_add = storage_item_write;
+       ad->storage_item_del = storage_item_delete;
+//     ad->storage_item_load = storage_item_load;
 
-       g_storage_serial_number = 0;
-
-       return 0;
+       return sd;
 }
 
-int sync_storage(void *data)
+void depose_storage(StorageData *sd)
 {
-//     struct appdata *ad = data;
+       CALLED();
+       storage_rewrite_all_items(sd);
+       dump_items(sd);
+       if (sd->ef)
+               eet_close(sd->ef);
+       sd->ef = NULL;
+       eet_shutdown();
+       ecore_file_shutdown();
+}
 
-       if (!g_storage_file)
+#ifdef DEBUG
+static void dump_items(StorageData *sd)
+{
+       CALLED();
+       int i;
+       for (i = 0; i < STORAGE_ITEM_CNT; i++)
        {
-               DTRACE("g_storage_file is null\n");
-               return -1;
+               CNP_ITEM *item = storage_item_load(sd, i);
+               if (item)
+                       printf("item #%d type: 0x%x, data: %s\n, len: %d\n", i, item->type_index, item->data, item->len);
        }
-       fsync(g_storage_file);
-
-       return 0;
 }
+#endif
 
-unsigned int get_storage_serial_code(void *data)
+static Eina_Bool item_write(Eet_File *ef, int index, CNP_ITEM *item)
 {
-//     struct appdata *ad = data;
+       if (!ef)
+       {
+               DMSG("eet_file is NULL\n");
+               return EINA_FALSE;
+       }
+       char datakey[10];
+       snprintf(datakey, 10, STORAGE_KEY_FORMAT, index);
+       int buf_size = item->len + sizeof(int);
+       char *buf = MALLOC(buf_size);
+       if (!buf)
+               return EINA_FALSE;
+       ((int *)buf)[0] = item->type_index;
+       char *data = buf + sizeof(int);
+       memcpy(data, item->data, item->len);
 
-       return g_storage_serial_number;
+       int ret = eet_write(ef, datakey, buf, buf_size, 1);
+       DMSG("write result: %d, datakey: %s, buf_size: %d, item_len: %d\n", ret, datakey, buf_size, item->len);
+/*     if (ret)
+               eet_sync(ef);*/
+       return ret != 0;
 }
 
-int adding_item_to_storage(void *data, int pos, char *idata)
+static void storage_rewrite_all_items(StorageData *sd)
 {
-//     struct appdata *ad = data;
-       if (!g_storage_file)
+       CALLED();
+       if (sd->ef)
+               eet_close(sd->ef);
+       ecore_file_remove(STORAGE_FILEPATH);
+       sd->ef = eet_open(STORAGE_FILEPATH, EET_FILE_MODE_READ_WRITE);
+
+       int i;
+       for (i = 0; i < STORAGE_ITEM_CNT; i++)
        {
-               DTRACE("g_storage_file is null\n");
-               return -1;
+               if ((sd->indexTable[i] != STORAGE_INDEX_ITEM_NONE) && (sd->itemTable[i]))
+                       item_write(sd->ef, i, sd->itemTable[i]);
        }
+       storage_index_write(sd);
+}
 
-       int result;
-       result = fseek(g_storage_file, GET_HEADER_ADDR_BY_POSITION(pos), SEEK_SET);
-       // FIXME : replace from fprintf to fwrite
-       fprintf(g_storage_file, "%d", strlen(idata));
-       fprintf(g_storage_file, "%s", idata);
-       
-       g_storage_serial_number++;
-       return 0;
+static Eina_Bool storage_item_write(AppData *ad, CNP_ITEM *item)
+{
+       CALLED();
+       StorageData *sd = ad->storage;
+       int index = getMinIndex(sd->indexTable, STORAGE_ITEM_CNT);
+       sd->indexTable[index] = ecore_time_unix_get();
+       sd->itemTable[index] = item;
+
+       item_write(sd->ef, index, item);
+       storage_index_write(sd);
+       dump_items(sd);
+       return EINA_TRUE;
 }
 
-int get_item_counts(void *data)
+static Eina_Bool storage_item_delete(AppData *ad, CNP_ITEM *item)
 {
-       struct appdata *ad = data;
+       CALLED();
+       StorageData *sd = ad->storage;
+       int index;
+       for (index = 0; index < STORAGE_ITEM_CNT; index++)
+       {
+               if (sd->itemTable[index] == item)
+                       break;
+       }
 
-       return ad->hicount;
+       if (index < STORAGE_ITEM_CNT)
+       {
+               sd->indexTable[index] = STORAGE_INDEX_ITEM_NONE;
+               storage_index_write(sd);
+       }
+       return EINA_TRUE;
 }
 
-int close_storage(void *data)
+static CNP_ITEM *storage_item_load(StorageData *sd, int index)
 {
-       struct appdata *ad = data;
+       if (!sd->ef)
+       {
+               DMSG("eet_file is NULL\n");
+               return EINA_FALSE;
+       }
+       if (index >= STORAGE_ITEM_CNT)
+               return NULL;
 
-       if (g_storage_file)
-               fclose(g_storage_file);
-       g_storage_file = NULL;
-       g_storage_serial_number = 0;
+       indexType copyTable[STORAGE_ITEM_CNT];
+       memcpy(copyTable, sd->indexTable, sizeof(copyTable));
+       int i;
+       for (i = 0; i < index; i++)
+       {
+               int maxIndex = getMaxIndex(copyTable, STORAGE_ITEM_CNT);
+               if (maxIndex == -1)
+                       maxIndex = 0;
+               copyTable[maxIndex] = 0;
+       }
 
-       return 0;
+       char datakey[10];
+       snprintf(datakey, 10, STORAGE_KEY_FORMAT, i);
+
+       int read_size;
+       char *read_data = eet_read(sd->ef, datakey, &read_size);
+
+       if (!read_data)
+       {
+               DMSG("read failed index: %d\n", index);
+               return NULL;
+       }
+       CNP_ITEM *item = CALLOC(1, sizeof(CNP_ITEM));
+       if (item)
+       {
+               char *data = read_data + sizeof(int);
+               int data_size = read_size - sizeof(int);
+               char *buf = CALLOC(1, data_size);
+               if (!buf)
+               {
+                       FREE(item);
+                       return NULL;
+               }
+               item->type_index = ((int *)read_data)[0];
+               memcpy(buf, data, data_size);
+               item->data = buf;
+               item->len = data_size;
+       }
+       return item;
 }
 
-int check_regular_file(char *path)
+static Eina_Bool storage_index_write(StorageData *sd)
 {
-       struct stat fattr;
-       if (stat(path, &fattr))
+       CALLED();
+       int ret;
+       if (!sd->ef)
        {
-               DTRACE("Cannot get file at path = %s\n", path);
-               return FALSE;
+               DMSG("eet_file is NULL\n");
+               return EINA_FALSE;
        }
-       
-       return S_ISREG(fattr.st_mode);
+#ifdef DEBUG
+       for (ret = 0; ret < STORAGE_ITEM_CNT; ret++)
+               printf(", index %d: %lf", ret, sd->indexTable[ret]);
+       printf("\n");
+#endif
+       ret = eet_write(sd->ef, STORAGE_KEY_INDEX, sd->indexTable, sizeof(indexType) * STORAGE_ITEM_CNT, 1);
+       if (ret)
+               eet_sync(sd->ef);
+       return ret != 0;
 }
-
index e895ee4..6e06d9e 100644 (file)
  *
  */
 
-#ifndef _storage_h_
-#define _storage_h_
+#ifndef _STORAGE_H_
+#define _STORAGE_H_
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/mman.h>
+#include <Eet.h>
+#include <Eina.h>
+#include <Ecore.h>
 
-int init_storage(void *data);
-int sync_storage(void *data);
-unsigned int get_storage_serial_code(void *data);
-int adding_item_to_storage(void *data, int pos, char *idata);
-int get_item_counts(void *data);
-int close_storage(void *data);
+#include "item_manager.h"
 
-int check_regular_file(char *path);
+typedef double indexType; /* Ecore_Time */
 
-#endif // _storage_h_
+#define STORAGE_ITEM_CNT 12
+struct _StorageData {
+       Eet_File *ef;
+       indexType indexTable[STORAGE_ITEM_CNT];
+       CNP_ITEM *itemTable[STORAGE_ITEM_CNT];
+};
+
+StorageData *init_storage(AppData *ad);
+void depose_storage(StorageData *sd);
+#endif
diff --git a/src/xconverter.c b/src/xconverter.c
new file mode 100644 (file)
index 0000000..55ef5ae
--- /dev/null
@@ -0,0 +1,1476 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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 "xconverter.h"
+
+static char *html_to_entry(AppData *ad, int type_index, const char *str);
+static char *efl_to_entry(AppData *ad, int type_index, const char *str);
+static char *text_to_entry(AppData *ad, int type_index, const char *str);
+static char *image_path_to_entry(AppData *ad, int type_index, const char *str);
+
+static char *make_close_tag(Eina_List* nodes);
+static char *do_not_convert(AppData *ad, int type_index, const char *str);
+static char *html_to_efl(AppData *ad, int type_index, const char *str);
+static char *efl_to_html(AppData *ad, int type_index, const char *str);
+static char *text_to_html(AppData *ad, int type_index, const char *str);
+static char *text_to_efl(AppData *ad, int type_index, const char *str);
+static char *to_text(AppData *ad, int type_index, const char *str);
+static char *image_path_to_html(AppData *ad, int type_index, const char *str);
+static char *image_path_to_efl(AppData *ad, int type_index, const char *str);
+static char *image_path_to_text(AppData *ad, int type_index, const char *str);
+//static char *efl_to_efl(AppData *ad, int type_index, const char *str);
+//static char *html_to_html(AppData *ad, int type_index, const char *str);
+static char *image_path_to_image_path(AppData *ad, int type_index, const char *str);
+
+int atom_type_index_get(AppData *ad, Ecore_X_Atom atom)
+{
+       int i, j;
+       for (i = 0; i < ATOM_INDEX_MAX; i++)
+       {
+               for (j = 0; j < ad->targetAtoms[i].atom_cnt; j++)
+                       if (ad->targetAtoms[i].atom[j] == atom)
+                               return i;
+       }
+       return -1;
+}
+
+void init_target_atoms(AppData *ad)
+{
+       int atom_cnt[ATOM_INDEX_MAX] = {
+               1, 5, 2, 1, 2
+       };
+       char *targetAtomNames[][5] = {
+               { "TARGETS" },
+               { "UTF8-STRING", "STRING", "TEXT", "text/plain;charset=utf-8", "text/plain" },
+               { "text/html;charset=utf-8", "text/html" },
+               { "application/x-elementary-markup" },
+               { "text/uri", "text/uri-list" }
+       };
+       text_converter_func converts_for_entry[ATOM_INDEX_MAX] = {
+               NULL, text_to_entry, html_to_entry, efl_to_entry, image_path_to_entry
+       };
+
+       text_converter_func converts[ATOM_INDEX_MAX][ATOM_INDEX_MAX] = {
+               {NULL, NULL, NULL, NULL, NULL},
+               {NULL, do_not_convert, text_to_html, text_to_efl, NULL},
+               {NULL, to_text, do_not_convert, html_to_efl, NULL},
+               {NULL, to_text, efl_to_html, do_not_convert, NULL},
+               {NULL, image_path_to_text, image_path_to_html, image_path_to_efl, image_path_to_image_path}
+       };
+
+       int i, j;
+       for (i = 0; i < ATOM_INDEX_MAX; i++)
+       {
+               ad->targetAtoms[i].atom_cnt = atom_cnt[i];
+               ad->targetAtoms[i].name = MALLOC(sizeof(char *) * atom_cnt[i]);
+               ad->targetAtoms[i].atom = MALLOC(sizeof(Ecore_X_Atom) * atom_cnt[i]);
+               for (j = 0; j < atom_cnt[i]; j++)
+               {
+                       DMSG("atomName: %s\n", targetAtomNames[i][j]);
+                       ad->targetAtoms[i].name[j] = strdup(targetAtomNames[i][j]);
+                       ad->targetAtoms[i].atom[j] = ecore_x_atom_get(targetAtomNames[i][j]);
+               }
+               ad->targetAtoms[i].convert_for_entry = converts_for_entry[i];
+
+               for (j = 0; j < ATOM_INDEX_MAX; j++)
+                       ad->targetAtoms[i].convert_to_target[j] = converts[i][j];
+               //ecore_x_selection_converter_atom_add(ad->targetAtoms[i].atom, target_converters[i]);
+               //ecore_x_selection_converter_atom_add(ad->targetAtoms[i].atom, generic_converter);
+       }
+}
+
+void depose_target_atoms(AppData *ad)
+{
+       int i, j;
+       for (i = 0; i < ATOM_INDEX_MAX; i++)
+       {
+               for (j = 0; j < ad->targetAtoms[i].atom_cnt; j++)
+               {
+                       if (ad->targetAtoms[i].name[j])
+                               FREE(ad->targetAtoms[i].name[j]);
+               }
+               if (ad->targetAtoms[i].name)
+                       FREE(ad->targetAtoms[i].name);
+               if (ad->targetAtoms[i].atom)
+                       FREE(ad->targetAtoms[i].atom);
+       }
+}
+
+static Eina_Bool targets_converter(AppData *ad, Ecore_X_Atom reqAtom, CNP_ITEM *item, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *tsize)
+{
+       CALLED();
+
+       int count;
+       int i, j;
+
+       for (i = 0, count = 0; i < ATOM_INDEX_MAX; i++)
+       {
+               if (ad->targetAtoms[item->type_index].convert_to_target[i])
+                       count += ad->targetAtoms[i].atom_cnt;
+       }
+
+       *data_ret = MALLOC(sizeof(Ecore_X_Atom) * count);
+       DMSG("item_type: %d, target Atom cnt: %d\n", item->type_index, count);
+       if (!*data_ret)
+               return EINA_FALSE;
+
+       for (i = 0, count = 0; i < ATOM_INDEX_MAX; i++)
+       {
+               if (ad->targetAtoms[item->type_index].convert_to_target[i])
+               {
+                       for(j = 0; j < ad->targetAtoms[i].atom_cnt; j++)
+                       {
+                               ((Ecore_X_Atom *)*data_ret)[count++] = ad->targetAtoms[i].atom[j];
+                               DMSG("send target atom: %s\n", ad->targetAtoms[i].name[j]);
+                       }
+               }
+       }
+
+       if (size_ret) *size_ret = count;
+       if (ttype) *ttype = ECORE_X_ATOM_ATOM;
+       if (tsize) *tsize = 32;
+       return EINA_TRUE;
+}
+
+Eina_Bool generic_converter(AppData *ad, Ecore_X_Atom reqAtom, CNP_ITEM *item, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *tsize)
+{
+       CALLED();
+
+       if (ad->targetAtoms[ATOM_INDEX_TARGET].atom[0] == reqAtom)
+               return targets_converter(ad, reqAtom, item, data_ret, size_ret, ttype, tsize);
+
+       int req_index = atom_type_index_get(ad, reqAtom);
+       int type_index = item->type_index;
+
+       if (ad->targetAtoms[type_index].convert_to_target[req_index])
+       {
+               *data_ret = ad->targetAtoms[type_index].convert_to_target[req_index](ad, type_index, item->data);
+               if (!*data_ret)
+                       return EINA_FALSE;
+               if (size_ret) *size_ret = strlen(*data_ret);
+               if (ttype) *ttype = ad->targetAtoms[item->type_index].atom[0];
+               if (tsize) *tsize = 8;
+               return EINA_TRUE;
+       }
+
+       return EINA_FALSE;
+}
+
+/* For convert EFL to HTML */
+
+#define TAGPOS_START    0x00000001
+#define TAGPOS_END      0x00000002
+#define TAGPOS_ALONE    0x00000003
+
+/* TEXTBLOCK tag using stack but close tag word has no mean maybe bug...
+ * TEXTBLOCK <b>bold<font>font</b>bold</font>
+ * HTML <b>bold<font>font bold</b>font</font> */
+
+typedef struct _TagTable {
+       char *src;
+       char *dst;
+}TagTable;
+
+TagTable _EFLtoHTMLConvertTable[] = {
+       {"font", "font"},
+       {"underline", "del"},
+       {"strikethrough", "ins"},
+       {"br", "br"},
+       {"ps", "br"},
+       {"b", "b"},
+       {"item", "img"}
+};
+
+TagTable _HTMLtoEFLConvertTable[] = {
+       {"font", ""},
+       {"del", "underline"},
+       {"u", "underline"},
+       {"ins", "strikethrough"},
+       {"s", "strikethrough"},
+       {"br", "br"},
+       {"b", "b"},
+       {"strong", "b"},
+       {"img", "item"}
+};
+
+
+typedef struct _TagNode TagNode, *PTagNode;
+struct _TagNode {
+       char *tag;  //EINA_STRINGSHARE if NULL just str
+       char *tag_str;
+       char *str;
+       const char *pos_in_ori_str;
+       PTagNode matchTag;
+       void *tagData;
+       unsigned char tagPosType;
+};
+
+typedef struct _FontTagData FontTagData, *PFontTagData;
+struct _FontTagData {
+       char *name;
+       char *color;
+       char *size;
+       char *bg_color;
+};
+
+
+typedef struct _ItemTagData ItemTagData, *PItemTagData;
+struct _ItemTagData {
+       char *href;
+       char *width;
+       char *height;
+};
+
+#define SAFEFREE(ptr) \
+       do\
+{\
+       if (ptr)\
+       FREE(ptr);\
+       ptr = NULL;\
+} while(0);\
+
+#define freeAndAssign(dst, value) \
+       do\
+{\
+       if (value)\
+       {\
+               SAFEFREE(dst);\
+               dst = value;\
+       }\
+} while(0);
+
+static PTagNode _new_tag_node(char *tag, char *tag_str, char* str, const char *pos_in_ori_str);
+static PTagNode _get_start_node(const char *str);
+static PTagNode _get_next_node(PTagNode prev);
+static void _delete_node(PTagNode node);
+static void _link_match_tags(Eina_List *nodes);
+static char *_get_tag_value(const char *tag_str, const char *tag_name);
+static char *_convert_to_html(Eina_List* nodes);
+static void _set_EFL_tag_data(Eina_List* nodes);
+static char *_convert_to_edje(Eina_List* nodes);
+static void _set_HTML_tag_data(Eina_List* nodes);
+static void cleanup_tag_list(Eina_List *nodeList);
+static PFontTagData _set_EFL_font_data(PFontTagData data, const char *tag_str);
+static PItemTagData _set_EFL_item_data(PItemTagData data, const char *tag_str);
+static PFontTagData _set_HTML_font_data(PFontTagData data, const char *tag_str);
+static PItemTagData _set_HTML_img_data(PItemTagData data, const char *tag_str);
+
+#ifdef DEBUG
+static void _dumpNode(Eina_List* nodes);
+#endif
+
+static PTagNode
+_new_tag_node(char *tag, char *tag_str, char* str, const char *pos_in_ori_str)
+{
+       PTagNode newNode = CALLOC(1, sizeof(TagNode));
+       if (tag)
+               eina_str_tolower(&tag);
+       newNode->tag = tag;
+       if (tag_str)
+               eina_str_tolower(&tag_str);
+       newNode->tag_str = tag_str;
+       newNode->str = str;
+       newNode->pos_in_ori_str = pos_in_ori_str;
+       return newNode;
+}
+
+static PTagNode
+_get_start_node(const char *str)
+{
+       char *startStr = NULL;
+       if (!str || str[0] == '\0')
+               return NULL;
+
+       if (str[0] != '<')
+       {
+               char *tagStart = strchr(str, '<');
+               if (!tagStart)
+                       startStr = strdup(str);
+               else
+               {
+                       int strLength = tagStart - str;
+                       startStr = MALLOC(sizeof(char) * (strLength + 1));
+                       strncpy(startStr, str, strLength);
+                       startStr[strLength] = '\0';
+               }
+       }
+
+       return _new_tag_node(NULL, NULL, startStr, str);
+}
+
+static PTagNode
+_get_next_node(PTagNode prev)
+{
+       PTagNode retTag = NULL;
+       char *tagStart;
+       char *tagEnd;
+       char *tagNameEnd = NULL;
+       char *nextTagStart;
+
+       if (prev->tag == NULL)
+               tagStart = strchr(prev->pos_in_ori_str, '<');
+       else
+               tagStart = strchr(prev->pos_in_ori_str + 1, '<');
+
+       if (!tagStart)
+               return retTag;
+
+       tagEnd = strchr(tagStart, '>');
+       nextTagStart = strchr(tagStart + 1, '<');
+
+       if (!tagEnd || (nextTagStart && (nextTagStart < tagEnd)))
+               return _get_start_node(tagStart + 1);
+
+       int spCnt = 5;
+       char *spArray[spCnt];
+       spArray[0] = strchr(tagStart, '=');
+       spArray[1] = strchr(tagStart, '_');
+       spArray[2] = strchr(tagStart, ' ');
+       spArray[3] = strchr(tagStart, '\t');
+       spArray[4] = strchr(tagStart, '\n');
+       tagNameEnd = tagEnd;
+
+       int i;
+       for (i = 0; i < spCnt; i++)
+       {
+               if (spArray[i] && spArray[i] < tagNameEnd)
+                       tagNameEnd = spArray[i];
+       }
+
+       int tagLength = tagNameEnd - tagStart - 1;
+       char *tagName = NULL;
+       if (!strncmp(&tagStart[1], "color", tagLength))
+               tagName = strndup("font", 4);
+       else if (!strncmp(&tagStart[1], "/color", tagLength))
+               tagName = strndup("/font", 5);
+       else if (!strncmp(&tagStart[1], "/item", tagLength))
+               tagName = strdup("");
+       else
+               tagName = strndup(&tagStart[1], tagLength);
+
+       int tagStrLength = 0;
+       char *tagStr = NULL;
+       if (tagName)
+       {
+               tagStrLength = tagEnd - tagStart + 1;
+               tagStr = strndup(tagStart, tagStrLength);
+       }
+
+       unsigned int strLength = nextTagStart ? (unsigned int)(nextTagStart - tagEnd - 1) : strlen(&tagEnd[1]);
+       char *str = strndup(&tagEnd[1], strLength);
+
+       retTag = _new_tag_node(tagName, tagStr, str, tagStart);
+       return retTag;
+}
+
+
+static void
+_delete_node(PTagNode node)
+{
+       if (node)
+       {
+               SAFEFREE(node->tag_str);
+               SAFEFREE(node->str);
+
+               if (node->tagData)
+               {
+                       if (node->tag)
+                       {
+                               if (!strcmp("font", node->tag))
+                               {
+                                       PFontTagData data = node->tagData;
+                                       SAFEFREE(data->name);
+                                       SAFEFREE(data->color);
+                                       SAFEFREE(data->size);
+                                       SAFEFREE(data->bg_color);
+                               }
+                               if (!strcmp("item", node->tag))
+                               {
+                                       PItemTagData data = node->tagData;
+                                       SAFEFREE(data->href);
+                                       SAFEFREE(data->width);
+                                       SAFEFREE(data->height);
+                               }
+
+                       }
+                       SAFEFREE(node->tagData);
+               }
+               SAFEFREE(node->tag);
+               SAFEFREE(node);
+       }
+}
+
+static void
+_link_match_tags(Eina_List *nodes)
+{
+       Eina_List *stack = NULL;
+
+       PTagNode trail, popData;
+       Eina_List *l, *r;
+
+       EINA_LIST_FOREACH(nodes, l, trail)
+       {
+               if (!trail->tag || trail->tag[0] == '\0')
+                       continue;
+               if (!strcmp("br", trail->tag))
+               {
+                       trail->tagPosType = TAGPOS_ALONE;
+                       continue;
+               }
+               else if (!strcmp("item", trail->tag) || !strcmp("img", trail->tag))
+               {
+                       trail->tagPosType = TAGPOS_ALONE;
+                       continue;
+               }
+
+               if (trail->tag[0] != '/') // PUSH
+               {
+                       stack = eina_list_append(stack, trail);
+                       /*             eina_array_push(stack, trail);
+                                                  DMSG("stack: %d, tag %s\n", eina_array_count_get(stack), trail->tag);*/
+                       DMSG("stack: %d, tag %s\n", eina_list_count(stack), trail->tag);
+               }
+               else // POP
+               {
+                       if (!eina_list_count(stack))
+                       {
+                               DMSG("tag not matched %s\n", trail->tag);
+                               continue;
+                       }
+
+                       EINA_LIST_REVERSE_FOREACH(stack, r, popData)
+                       {
+                               if (popData->tag && !strcmp(popData->tag, &trail->tag[1]))
+                               {
+                                       popData->tagPosType = TAGPOS_START;
+                                       trail->tagPosType = TAGPOS_END;
+                                       popData->matchTag = trail;
+                                       trail->matchTag = popData;
+                                       stack = eina_list_remove_list(stack, r);
+                                       break;
+                               }
+                       }
+                       /*             popData = eina_array_pop(stack);
+
+                                                  popData->tagPosType = TAGPOS_START;
+                                                  trail->tagPosType = TAGPOS_END;
+                                                  popData->matchTag = trail;
+                                                  trail->matchTag = popData;
+                                                  DMSG("pop stack: %d, tag %s\n", eina_array_count_get(stack), trail->tag);
+                        */
+               }
+       }
+
+       /*   if (eina_array_count_get(stack))
+                DMSG("stack state: %d, tag %s\n", eina_array_count_get(stack), trail->tag);*/
+
+       /* Make Dummy close tag */
+       /*   while ((popData = eina_array_pop(stack)))  */
+
+       EINA_LIST_REVERSE_FOREACH(stack, r, popData)
+       {
+               PTagNode newData;
+               int tagLength = strlen(popData->tag);
+               char *tagName = MALLOC(sizeof(char) * (tagLength + 2));
+
+               tagName[0] = '/';
+               tagName[1] = '\0';
+               strcat(tagName, popData->tag);
+
+               newData = _new_tag_node(tagName, NULL, NULL, NULL);
+               popData->tagPosType = TAGPOS_START;
+               newData->tagPosType = TAGPOS_END;
+               popData->matchTag = newData;
+               newData->matchTag = popData;
+               nodes = eina_list_append(nodes, newData);
+               /*        DMSG("stack: %d, tag %s\n", eina_array_count_get(stack), popData->tag);*/
+       }
+       /*   DMSG("stack_top: %d\n", eina_array_count_get(stack));
+                eina_array_free(stack);*/
+       eina_list_free(stack);
+}
+
+static char *
+_get_tag_value(const char *tag_str, const char *tag_name)
+{
+       if (!tag_name || !tag_str)
+               return NULL;
+
+       char *tag;
+       if ((tag = strstr(tag_str, tag_name)))
+       {
+               if (tag[strlen(tag_name)] == '_')
+                       return NULL;
+               char *value = strchr(tag, '=');
+               if (value)
+               {
+                       do
+                       {
+                               value++;
+                       } while (!isalnum(*value) && *value != '#');
+
+                       int spCnt = 6;
+                       char *spArray[spCnt];
+                       spArray[0] = strchr(value, ' ');
+                       spArray[1] = strchr(value, '>');
+                       spArray[2] = strchr(value, '\"');
+                       spArray[3] = strchr(value, '\'');
+                       spArray[4] = strchr(value, '\t');
+                       spArray[5] = strchr(value, '\n');
+                       char *valueEnd = strchr(value, '\0');
+
+                       int i;
+                       int start = 0;
+                       if ((!strncmp(tag_str, "<item", 5) && !strcmp(tag_name, "href")) // EFL img tag
+               || (!strncmp(tag_str, "<img", 4) && !strcmp(tag_name, "src"))) // HTML img tag
+               start = 1;
+
+                       for (i = start; i < spCnt; i++)
+                       {
+                               if (spArray[i] && spArray[i] < valueEnd)
+                                       valueEnd = spArray[i];
+                       }
+
+                       int valueLength = valueEnd - value;
+                       return strndup(value, valueLength);
+               }
+       }
+       return NULL;
+}
+
+static PFontTagData
+_set_EFL_font_data(PFontTagData data, const char *tag_str)
+{
+       char *value;
+
+       if (!data)
+               data = CALLOC(1, sizeof(FontTagData));
+       value = _get_tag_value(tag_str, "font_size");
+       freeAndAssign(data->size, value);
+       value = _get_tag_value(tag_str, "color");
+       freeAndAssign(data->color, value);
+       value = _get_tag_value(tag_str, "bgcolor");
+       freeAndAssign(data->bg_color, value);
+       value = _get_tag_value(tag_str, "font");
+       freeAndAssign(data->name, value);
+
+       return data;
+}
+
+static PItemTagData
+_set_EFL_item_data(PItemTagData data, const char *tag_str)
+{
+       char *value;
+
+       if (!data)
+               data = CALLOC(1, sizeof(ItemTagData));
+       value = _get_tag_value(tag_str, "href");
+       if (value)
+       {
+               char *path = strstr(value, "file://");
+               if (path)
+               {
+                       char *modify = MALLOC(sizeof(char) * (strlen(value) + 1));
+                       strncpy(modify, "file://", 8);
+                       path += 7;
+                       while (path[1] && path[0] && path[1] == '/' && path[0] == '/')
+                       {
+                               path++;
+                       }
+                       strcat(modify, path);
+                       data->href = modify;
+                       DMSG("image href ---%s---\n", data->href);
+                       FREE(value);
+               }
+               else
+                       freeAndAssign(data->href, value);
+       }
+
+       value = _get_tag_value(tag_str, "absize");
+       if (value)
+       {
+               char *xpos = strchr(value, 'x');
+               if (xpos)
+               {
+                       int absizeLen = strlen(value);
+                       freeAndAssign(data->width, strndup(value, xpos - value));
+                       freeAndAssign(data->height, strndup(xpos + 1, absizeLen - (xpos - value) - 1));
+                       DMSG("image width: -%s-, height: -%s-\n", data->width, data->height);
+               }
+               FREE(value);
+       }
+       return data;
+}
+
+static void
+_set_EFL_tag_data(Eina_List* nodes)
+{
+       PTagNode trail;
+       Eina_List *l;
+
+       EINA_LIST_FOREACH(nodes, l, trail)
+       {
+               if (!trail->tag)
+                       continue;
+               if (!strcmp("font", trail->tag))
+                       trail->tagData = _set_EFL_font_data(trail->tagData, trail->tag_str);
+               else if (!strcmp("item", trail->tag))
+                       trail->tagData = _set_EFL_item_data(trail->tagData, trail->tag_str);
+       }
+}
+
+static PFontTagData
+_set_HTML_font_data(PFontTagData data, const char *tag_str)
+{
+       char *value;
+
+       if (!data)
+               data = CALLOC(1, sizeof(FontTagData));
+       value = _get_tag_value(tag_str, "size");
+       freeAndAssign(data->size, value);
+       value = _get_tag_value(tag_str, "color");
+       freeAndAssign(data->color, value);
+       value = _get_tag_value(tag_str, "bgcolor");
+       freeAndAssign(data->bg_color, value);
+       value = _get_tag_value(tag_str, "face");
+       freeAndAssign(data->name, value);
+
+       return data;
+}
+
+static PItemTagData
+_set_HTML_img_data(PItemTagData data, const char *tag_str)
+{
+       char *value;
+
+       if (!data)
+               data = CALLOC(1, sizeof(ItemTagData));
+       value = _get_tag_value(tag_str, "src");
+       if (value)
+       {
+               char *path = strstr(value, "file://");
+               if (path)
+               {
+                       char *modify = MALLOC(sizeof(char) * (strlen(value) + 1));
+                       strncpy(modify, "file://", 8);
+                       path += 7;
+                       while (path[1] && path[0] && path[1] == '/' && path[0] == '/')
+                       {
+                               path++;
+                       }
+                       strcat(modify, path);
+                       data->href = modify;
+                       DMSG("image src ---%s---\n", data->href);
+                       FREE(value);
+               }
+               else
+                       freeAndAssign(data->href, value);
+       }
+
+       value = _get_tag_value(tag_str, "width");
+       freeAndAssign(data->width, value);
+       value = _get_tag_value(tag_str, "height");
+       freeAndAssign(data->height, value);
+       return data;
+}
+
+static void
+_set_HTML_tag_data(Eina_List* nodes)
+{
+       PTagNode trail;
+       Eina_List *l;
+
+       EINA_LIST_FOREACH(nodes, l, trail)
+       {
+               if (!trail->tag)
+                       continue;
+               if (!strcmp("font", trail->tag))
+                       trail->tagData = _set_HTML_font_data(trail->tagData, trail->tag_str);
+               else if (!strcmp("img", trail->tag))
+                       trail->tagData = _set_HTML_img_data(trail->tagData, trail->tag_str);
+       }
+}
+
+#ifdef DEBUG
+static void
+_dumpNode(Eina_List* nodes)
+{
+       PTagNode trail;
+       Eina_List *l;
+
+       EINA_LIST_FOREACH(nodes, l, trail)
+       {
+               DMSG("tag: %s, tag_str: %s, str: %s, tagPosType: %d\n",
+                               trail->tag, trail->tag_str, trail->str, trail->tagPosType);
+               DMSG("matchTag: %x ", (unsigned int)trail->matchTag);
+               if (trail->matchTag)
+                       DMSG("matchTag->tag_str: %s", trail->matchTag->tag_str);
+               if (trail->tagData)
+               {
+                       if (!strcmp(trail->tag, "font"))
+                       {
+                               PFontTagData data = trail->tagData;
+                               DMSG(" tagData->name: %s, tagData->color: %s, tagData->size: %s, tagData->bg_color: %s",
+                                               data->name, data->color, data->size, data->bg_color);
+                       }
+                       else if (!strcmp(trail->tag, "item") || !strcmp(trail->tag, "img"))
+                       {
+                               PItemTagData data = trail->tagData;
+                               DMSG(" tagData->href: %s, tagData->width: %s, tagData->height: %s",
+                                               data->href, data->width, data->height);
+                       }
+                       else
+                               DMSG("\nERROR!!!! not need tagData");
+               }
+               DMSG("\n");
+       }
+}
+#endif
+
+static char *
+_convert_to_html(Eina_List* nodes)
+{
+       PTagNode trail;
+       Eina_List *l;
+
+       Eina_Strbuf *html = eina_strbuf_new();
+
+       int tableCnt = sizeof(_EFLtoHTMLConvertTable) / sizeof(TagTable);
+
+       EINA_LIST_FOREACH(nodes, l, trail)
+       {
+               if (trail->tag)
+               {
+                       char *tagName = trail->tagPosType == TAGPOS_END ?
+                               trail->matchTag->tag : trail->tag;
+                       int j;
+                       for(j = 0; j < tableCnt; j++)
+                       {
+                               if (!strcmp(_EFLtoHTMLConvertTable[j].src, tagName))
+                               {
+                                       switch(trail->tagPosType)
+                                       {
+                                               case TAGPOS_END:
+                                                       eina_strbuf_append(html, "</");
+                                                       break;
+                                               default:
+                                                       eina_strbuf_append(html, "<");
+                                                       break;
+                                       }
+
+                                       eina_strbuf_append(html, _EFLtoHTMLConvertTable[j].dst);
+                                       if (trail->tagPosType != TAGPOS_END)
+                                       {
+                                               if (!strcmp(_EFLtoHTMLConvertTable[j].src, "font"))
+                                               {
+                                                       PFontTagData data = trail->tagData;
+                                                       if (data->name)
+                                                       {
+                                                       }
+                                                       if (data->color)
+                                                       {
+                                                               char *color = strdup(data->color);
+                                                               if (color && color[0] == '#' && strlen(color) == 9)
+                                                               {
+                                                                       color[7] = '\0';
+                                                                       eina_strbuf_append_printf(html, " color=\"%s\"", color);
+                                                                       FREE(color);
+                                                               }
+                                                               else
+                                                                       eina_strbuf_append_printf(html, " color=\"%s\"", data->color);
+                                                       }
+                                                       if (data->size)
+                                                               eina_strbuf_append_printf(html, " size=\"%s\"", data->size);
+                                                       if (data->bg_color)
+                                                       {
+                                                       }
+                                               }
+                                               else if (!strcmp(_EFLtoHTMLConvertTable[j].src, "item"))
+                                               {
+                                                       PItemTagData data = trail->tagData;
+                                                       if (data->href)
+                                                               eina_strbuf_append_printf(html, " src=\"%s\"", data->href);
+                                                       if (data->width)
+                                                               eina_strbuf_append_printf(html, " width=\"%s\"", data->width);
+                                                       if (data->height)
+                                                               eina_strbuf_append_printf(html, " height=\"%s\"", data->height);
+                                               }
+                                       }
+                                       switch(trail->tagPosType)
+                                       {
+                                               /* closed tag does not need in HTML
+                                                  case TAGPOS_ALONE:
+                                                  eina_strbuf_append(html, " />");
+                                                  break;*/
+                                               default:
+                                                       eina_strbuf_append(html, ">");
+                                                       break;
+                                       }
+                                       break;
+                               }
+                       }
+               }
+               if (trail->str)
+                       eina_strbuf_append(html, trail->str);
+       }
+
+       eina_strbuf_replace_all(html, "  ", " &nbsp;");
+       char *ret = eina_strbuf_string_steal(html);
+       eina_strbuf_free(html);
+       return ret;
+}
+
+#define IMAGE_DEFAULT_WIDTH "240"
+#define IMAGE_DEFAULT_HEIGHT "180"
+
+
+static char *
+_convert_to_edje(Eina_List* nodes)
+{
+       PTagNode trail;
+       Eina_List *l;
+
+       Eina_Strbuf *edje = eina_strbuf_new();
+
+       int tableCnt = sizeof(_HTMLtoEFLConvertTable) / sizeof(TagTable);
+
+       EINA_LIST_FOREACH(nodes, l, trail)
+       {
+               if (trail->tag)
+               {
+                       char *tagName = trail->tagPosType == TAGPOS_END ?
+                               trail->matchTag->tag : trail->tag;
+                       int j;
+                       for(j = 0; j < tableCnt; j++)
+                       {
+                               if (!strcmp(_HTMLtoEFLConvertTable[j].src, tagName))
+                               {
+                                       if (_HTMLtoEFLConvertTable[j].dst[0] != '\0')
+                                       {
+                                               switch(trail->tagPosType)
+                                               {
+                                                       case TAGPOS_END:
+                                                               eina_strbuf_append(edje, "</");
+                                                               break;
+                                                       default:
+                                                               eina_strbuf_append(edje, "<");
+                                                               break;
+                                               }
+
+                                               eina_strbuf_append(edje, _HTMLtoEFLConvertTable[j].dst);
+                                       }
+                                       if (trail->tagPosType != TAGPOS_END)
+                                       {
+                                               if (!strcmp(_HTMLtoEFLConvertTable[j].src, "font"))
+                                               {
+                                                       PFontTagData data = trail->tagData;
+                                                       if (data->name)
+                                                       {
+                                                       }
+                                                       if (data->color)
+                                                       {
+                                                               if (data->color[0] == '#' && strlen(data->color) == 7)
+                                                                       eina_strbuf_append_printf(edje, "<color=%sff>", data->color);
+                                                               else
+                                                                       eina_strbuf_append_printf(edje, "<color=%s>", data->color);
+
+                                                       }
+                                                       if (data->size)
+                                                               eina_strbuf_append_printf(edje, "<font_size=%s>", data->size);
+                                                       if (data->bg_color)
+                                                       {
+                                                       }
+                                                       break;
+                                               }
+                                               else if (!strcmp(_HTMLtoEFLConvertTable[j].src, "img"))
+                                               {
+                                                       PItemTagData data = trail->tagData;
+                                                       char *width = IMAGE_DEFAULT_WIDTH, *height = IMAGE_DEFAULT_HEIGHT;
+                                                       if (data->width)
+                                                               width = data->width;
+                                                       if (data->height)
+                                                               height = data->height;
+                                                       eina_strbuf_append_printf(edje, " absize=%sx%s", width, height);
+                                                       if (data->href)
+                                                               eina_strbuf_append_printf(edje, " href=%s></item>", data->href);
+                                                       break;
+                                               }
+                                       }
+                                       else
+                                       {
+                                               if (_HTMLtoEFLConvertTable[j].dst[0] == '\0')
+                                               {
+                                                       if (!strcmp(_HTMLtoEFLConvertTable[j].src, "font"))
+                                                       {
+                                                               if (trail->matchTag->tagData)
+                                                               {
+                                                                       PFontTagData data = trail->matchTag->tagData;
+                                                                       if (data->name)
+                                                                       {
+                                                                       }
+                                                                       if (data->color)
+                                                                               eina_strbuf_append_printf(edje, "</color>");
+                                                                       if (data->size)
+                                                                               eina_strbuf_append_printf(edje, "</font>");
+                                                                       if (data->bg_color)
+                                                                       {
+                                                                       }
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       switch(trail->tagPosType)
+                                       {
+                                               /* not support in efl
+                                                  case TAGPOS_ALONE:
+                                                  eina_strbuf_append(edje, " />");
+                                                  break;
+                                                */
+                                               default:
+                                                       eina_strbuf_append(edje, ">");
+                                                       break;
+                                       }
+                                       break;
+                               }
+                       }/* for(j = 0; j < tableCnt; j++) end */
+               }
+               if (trail->str)
+                       eina_strbuf_append(edje, trail->str);
+       }
+
+       eina_strbuf_replace_all(edje, "&nbsp;", " ");
+       char *ret = eina_strbuf_string_steal(edje);
+       eina_strbuf_free(edje);
+       return ret;
+}
+
+char *string_for_entry_get(AppData *ad, int type_index, const char *str)
+{
+       DMSG("type_index: %d ", type_index);
+       DMSG("str: %s\n", str);
+       if (ad->targetAtoms[type_index].convert_for_entry)
+               return ad->targetAtoms[type_index].convert_for_entry(ad, type_index, str);
+       return NULL;
+}
+
+static char *make_close_tag(Eina_List* nodes)
+{
+       CALLED();
+       PTagNode trail;
+       Eina_List *l;
+
+       Eina_Strbuf *tag_str = eina_strbuf_new();
+
+       EINA_LIST_FOREACH(nodes, l, trail)
+       {
+               if (trail->tag)
+               {
+                       eina_strbuf_append(tag_str, "<");
+                       eina_strbuf_append(tag_str, trail->tag);
+                       eina_strbuf_append(tag_str, ">");
+               }
+               if (trail->str)
+                       eina_strbuf_append(tag_str, trail->str);
+       }
+
+       char *ret = eina_strbuf_string_steal(tag_str);
+       eina_strbuf_free(tag_str);
+       return ret;
+}
+
+static char *do_not_convert(AppData *ad, int type_index, const char *str)
+{
+       DMSG("str: %s\n", str);
+       if (type_index != ATOM_INDEX_TEXT)
+       {
+               Eina_List *nodeList = NULL;
+               PTagNode nodeData;
+
+               nodeData = _get_start_node(str);
+
+               while (nodeData)
+               {
+                       nodeList = eina_list_append(nodeList, nodeData);
+                       nodeData = _get_next_node(nodeData);
+               }
+
+               _link_match_tags(nodeList);
+
+#ifdef DEBUG
+               _dumpNode(nodeList);
+#endif
+               char *ret = make_close_tag(nodeList);
+               cleanup_tag_list(nodeList);
+               DMSG("convert str: %s\n", ret);
+               return ret;
+       }
+       return strdup(str);
+}
+/*
+   static char *efl_to_efl(AppData *ad, int type_index, const char *str)
+   {
+   CALLED();
+   return NULL;
+   }
+
+   static char *html_to_html(AppData *ad, int type_index, const char *str)
+   {
+   CALLED();
+   return NULL;
+   }
+ */
+
+/*
+ * remove_tags, mark_up function from elm_cnp_helper
+ */
+
+typedef struct _Escape {
+       char *escape;
+       char *value;
+} Escape;
+
+#define _PARAGRAPH_SEPARATOR "\xE2\x80\xA9"
+
+/* Optimisation: Turn this into a 256 byte table:
+ *  *  then can lookup in one index, not N checks */
+static const Escape escapes[] = {
+       { "<ps>",  _PARAGRAPH_SEPARATOR },
+       { "<br>",  "\n" },
+       { "<\t>",  "\t" },
+       { "&gt;",   ">" },
+       { "&lt;",    "<" },
+       { "&amp;",   "&" },
+       { "&quot;",  "'" },
+       { "&dquot;", "\"" }
+};
+#define N_ESCAPES ((int)(sizeof(escapes) / sizeof(escapes[0])))
+
+static char *remove_tags(const char *p, int *len)
+{
+   char *q,*ret;
+   int i;
+   if (!p) return NULL;
+
+   q = malloc(strlen(p) + 1);
+   if (!q) return NULL;
+   ret = q;
+
+   while (*p)
+     {
+        Eina_Bool esc = EINA_TRUE;
+        const char *x;
+        switch (p[0])
+          {
+           case '<':
+             x = strchr(p + 3, '>');
+             if (!x)
+               {
+                  strcpy(q, p);
+                  if (len) *len = strlen(ret);
+                  return ret;
+               }
+             if (memcmp(p + 1, "br", 2) && memcmp(p + 1, "ps", 2))
+               {
+                  strncpy(q, p, x - p + 1);
+                  p = x + 1;
+                  break;
+               }
+             i = x - p - 1;
+             if (p[i] == '/') i--;
+             for (; i > 2; i++)
+               {
+                  if (p[i] != ' ')
+                    {
+                       esc = EINA_FALSE;
+                       break;
+                    }
+               }
+             if (!esc)
+               {
+                  strncpy(q, p, x - p + 1);
+                  p = x + 1;
+                  break;
+               }
+             if (p[1] == 'b')
+               *q++ = '\n';
+             else
+               {
+                  strcpy(q, _PARAGRAPH_SEPARATOR);
+                  q += sizeof(_PARAGRAPH_SEPARATOR) - 1;
+               }
+             p = x + 1;
+             break;
+           case '&':
+             for (i = 3 ; i < N_ESCAPES ; i++)
+               {
+                  if (strncmp(p, escapes[i].escape, strlen(escapes[i].escape)))
+                    continue;
+                  p += strlen(escapes[i].escape);
+                  strcpy(q, escapes[i].value);
+                  q += strlen(escapes[i].value);
+                  break;
+               }
+             if (i == N_ESCAPES) *q ++= '&';
+             break;
+           default:
+             *q++ = *p++;
+          }
+     }
+   *q = 0;
+   if (len) *len = q - ret;
+   return ret;
+}
+
+/* Mark up */
+static char *mark_up(const char *start, int inlen, int *lenp)
+{
+   int l, i;
+   const char *p;
+   char *q, *ret;
+   const char *endp = NULL;
+
+   if (!start) return NULL;
+   if (inlen >= 0) endp = start + inlen;
+   /* First pass: Count characters */
+   for (l = 0, p = start; ((!endp) || (p < endp)) && (*p); p++)
+     {
+        for (i = 0 ; i < N_ESCAPES ; i ++)
+          {
+             if (*p == escapes[i].value[0])
+               {
+                  if (!strncmp(p, escapes[i].value, strlen(escapes[i].value)))
+                    l += strlen(escapes[i].escape);
+                  break;
+               }
+          }
+        if (i == N_ESCAPES) l++;
+     }
+
+   q = ret = malloc(l + 1);
+
+   /* Second pass: Change characters */
+   for (p = start; ((!endp) || (p < endp)) && (*p); )
+     {
+        for (i = 0; i < N_ESCAPES; i++)
+          {
+             if (*p == escapes[i].value[0])
+               {
+                  if (!strncmp(p, escapes[i].value, strlen(escapes[i].value)))
+                    {
+                       strcpy(q, escapes[i].escape);
+                       q += strlen(escapes[i].escape);
+                       p += strlen(escapes[i].value);
+                    }
+                  break;
+               }
+          }
+        if (i == N_ESCAPES) *q++ = *p++;
+     }
+   *q = 0;
+
+   if (lenp) *lenp = l;
+   return ret;
+}
+
+
+
+#define IMAGE_DEFAULT_WIDTH "240"
+#define IMAGE_DEFAULT_HEIGHT "180"
+static char *make_image_path_tag(int type_index, const char *str)
+{
+       char *img_tag_str = "file://%s";
+       char *efl_img_tag = "<item absize="IMAGE_DEFAULT_WIDTH"x"IMAGE_DEFAULT_HEIGHT" href=file://%s>";
+       char *html_img_tag = "<img src=\"file://%s\">";
+
+       switch (type_index)
+       {
+               case ATOM_INDEX_HTML:
+                       img_tag_str = html_img_tag;
+                       break;
+               case ATOM_INDEX_EFL:
+                       img_tag_str = efl_img_tag;
+                       break;
+               case ATOM_INDEX_TEXT:
+               case ATOM_INDEX_IMAGE:
+                       break;
+               default:
+                       DMSG("ERROR: wrong type_index: %d\n", type_index);
+                       return NULL;
+       }
+
+       size_t len = snprintf(NULL, 0, img_tag_str, str) + 1;
+       char *ret = MALLOC(sizeof(char) * len);
+       if (ret)
+               snprintf(ret, len, img_tag_str, str);
+       return ret;
+}
+
+static char *image_path_to_text(AppData *ad, int type_index, const char *str)
+{
+       DMSG("str: %s\n", str);
+       return make_image_path_tag(ATOM_INDEX_TEXT, str);
+}
+
+static char *image_path_to_html(AppData *ad, int type_index, const char *str)
+{
+       DMSG("str: %s\n", str);
+       return make_image_path_tag(ATOM_INDEX_HTML, str);
+}
+
+static char *image_path_to_efl(AppData *ad, int type_index, const char *str)
+{
+       DMSG("str: %s\n", str);
+       return make_image_path_tag(ATOM_INDEX_EFL, str);
+}
+
+static char *image_path_to_image_path(AppData *ad, int type_index, const char *str)
+{
+       DMSG("str: %s\n", str);
+       return make_image_path_tag(ATOM_INDEX_IMAGE, str);;
+}
+static char *markup_to_entry(AppData *ad, int type_index, const char *str)
+{
+       CALLED();
+       if (!str)
+               return NULL;
+
+       Eina_Strbuf *strbuf = eina_strbuf_new();
+       if (!strbuf)
+               return strdup(str);
+       eina_strbuf_prepend(strbuf, "<font_size=18><color=#000000FF>");
+
+       const char *trail = str;
+       char *image_tag_str = NULL;
+       char *html_img_tag = "img";
+       char *efl_img_tag = "item";
+       if (type_index == ATOM_INDEX_HTML) /* HTML */
+               image_tag_str = html_img_tag;
+       else if (type_index == ATOM_INDEX_EFL) /* EFL */
+               image_tag_str = efl_img_tag;
+
+       while (trail && *trail)
+       {
+               const char *pretrail = trail;
+               unsigned long length;
+               char *temp;
+               char *endtag;
+
+               trail = strchr(trail, '<');
+               if (!trail)
+               {
+                       eina_strbuf_append(strbuf, pretrail);
+                       break;
+               }
+               endtag = strchr(trail, '>');
+               if (!endtag)
+                       break;
+
+               length = trail - pretrail;
+
+               temp = strndup(pretrail, length);
+               if (!temp)
+               {
+                       trail++;
+                       continue;
+               }
+
+               eina_strbuf_append(strbuf, temp);
+               FREE(temp);
+               trail++;
+
+               if (trail[0] == '/')
+               {
+                       trail = endtag + 1;
+                       continue;
+               }
+
+               if (strncmp(trail, "br", 2) == 0)
+               {
+                       eina_strbuf_append(strbuf, "<br>");
+                       trail = endtag + 1;
+                       continue;
+               }
+
+               if (image_tag_str && strncmp(trail, image_tag_str, strlen(image_tag_str)) == 0)
+               {
+                       char *src = strstr(trail, "file://");
+                       char *src_endtag = strchr(trail, '>');
+                       if (!src || !src_endtag || src_endtag < src)
+                               continue;
+
+                       length = src_endtag - src;
+
+                       src = strndup(src, length);
+                       if (!src)
+                       {
+                               trail = endtag + 1;
+                               continue;
+                       }
+                       temp = src;
+                       while(*temp)
+                       {
+                               if (*temp == '\"' || *temp == '>')
+                                       *temp = '\0';
+                               else
+                                       temp++;
+                       }
+
+                       eina_strbuf_append_printf(strbuf, "<item absize=66x62 href=%s></item>", src);
+                       DTRACE("src str: %s \n", src);
+                       FREE(src);
+               }
+               trail = endtag + 1;
+       }
+
+       if (type_index == ATOM_INDEX_HTML)
+               eina_strbuf_replace_all(strbuf, "&nbsp;", " ");
+
+       char *entry_str = eina_strbuf_string_steal(strbuf);
+       eina_strbuf_free(strbuf);
+       return entry_str;
+}
+
+static char *html_to_entry(AppData *ad, int type_index, const char *str)
+{
+       DMSG("str: %s\n", str);
+       return markup_to_entry(ad, type_index, str);
+}
+
+static char *efl_to_entry(AppData *ad, int type_index, const char *str)
+{
+       DMSG("str: %s\n", str);
+       return markup_to_entry(ad, type_index, str);
+}
+
+static char *image_path_to_entry(AppData *ad, int type_index, const char *str)
+{
+       CALLED();
+       return NULL;
+}
+
+static char *text_to_entry(AppData *ad, int type_index, const char *str)
+{
+       DMSG("str: %s\n", str);
+       char *markup = mark_up(str, strlen(str), NULL);
+       char *for_entry = markup_to_entry(ad, type_index, markup);
+       FREE(markup);
+       return for_entry;
+}
+
+static Eina_List *make_tag_list(int type_index, const char *str)
+{
+       Eina_List *nodeList = NULL;
+       PTagNode nodeData;
+
+       nodeData = _get_start_node(str);
+
+       while (nodeData)
+       {
+               nodeList = eina_list_append(nodeList, nodeData);
+               nodeData = _get_next_node(nodeData);
+       }
+
+       _link_match_tags(nodeList);
+
+       switch(type_index)
+       {
+               case ATOM_INDEX_EFL:
+                       _set_EFL_tag_data(nodeList);
+                       break;
+               case ATOM_INDEX_HTML:
+                       _set_HTML_tag_data(nodeList);
+                       break;
+               default:
+                       DMSG("wrong index: %d\n");
+       }
+
+#ifdef DEBUG
+       _dumpNode(nodeList);
+#endif
+       return nodeList;
+}
+
+static void cleanup_tag_list(Eina_List *nodeList)
+{
+       Eina_List *trail;
+       PTagNode nodeData;
+
+       EINA_LIST_FOREACH(nodeList, trail, nodeData)
+               _delete_node(nodeData);
+       eina_list_free(nodeList);
+}
+
+static char *html_to_efl(AppData *ad, int type_index, const char *str)
+{
+       CALLED();
+       Eina_List *nodeList = NULL;
+       nodeList = make_tag_list(type_index, str);
+       char *ret = _convert_to_edje(nodeList);
+       DMSG("efl: %s\n", ret);
+       cleanup_tag_list(nodeList);
+
+       return ret;
+}
+
+static char *efl_to_html(AppData *ad, int type_index, const char *str)
+{
+       CALLED();
+       Eina_List *nodeList = NULL;
+       nodeList = make_tag_list(type_index, str);
+       char *ret = _convert_to_html(nodeList);
+       DMSG("html: %s\n", ret);
+       cleanup_tag_list(nodeList);
+
+       return ret;
+}
+
+static char *text_to_html(AppData *ad, int type_index, const char *str)
+{
+       DMSG("str: %s\n", str);
+       char *markup = mark_up(str, strlen(str), NULL);
+       char *html = efl_to_html(ad, ATOM_INDEX_EFL, markup);
+       FREE(markup);
+       return html;
+}
+
+static char *text_to_efl(AppData *ad, int type_index, const char *str)
+{
+       DMSG("str: %s\n", str);
+       return mark_up(str, strlen(str), NULL);
+}
+
+static char *to_text(AppData *ad, int type_index, const char *str)
+{
+       DMSG("str: %s\n", str);
+       if (type_index == ATOM_INDEX_HTML)
+       {
+               Eina_Strbuf *buf = eina_strbuf_new();
+               if (buf)
+               {
+                       char *text, *html;
+                       eina_strbuf_append(buf, str);
+                       eina_strbuf_replace_all(buf, "&nbsp;", " ");
+                       html = eina_strbuf_string_steal(buf);
+                       eina_strbuf_free(buf);
+                       text = remove_tags(html, NULL);
+                       free(html);
+                       return text;
+               }
+       }
+       return remove_tags(str, NULL);
+}
diff --git a/src/xconverter.h b/src/xconverter.h
new file mode 100644 (file)
index 0000000..b4a81f3
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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.
+ *
+ */
+
+#ifndef _X_ATOM_H_
+#define _X_ATOM_H_
+
+enum ATOM_INDEX {
+       ATOM_INDEX_TARGET = 0,
+       ATOM_INDEX_TEXT = 1,
+       ATOM_INDEX_HTML = 2,
+       ATOM_INDEX_EFL = 3,
+       ATOM_INDEX_IMAGE = 4,
+       ATOM_INDEX_MAX = 5
+};
+
+#include "cbhm.h"
+
+void init_target_atoms(AppData *ad);
+void depose_target_atoms(AppData *ad);
+int atom_type_index_get(AppData *ad, Ecore_X_Atom atom);
+char *string_for_entry_get(AppData *ad, int type_index, const char *str);
+Eina_Bool generic_converter(AppData *ad, Ecore_X_Atom reqAtom, CNP_ITEM *item, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *tsize);
+
+#endif
diff --git a/src/xhandler.c b/src/xhandler.c
new file mode 100644 (file)
index 0000000..3c758ad
--- /dev/null
@@ -0,0 +1,621 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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 "xhandler.h"
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+
+Ecore_X_Window get_selection_owner(AppData *ad, Ecore_X_Selection selection)
+{
+       CALLED();
+       if (!ad) return 0;
+       Ecore_X_Atom sel = 0;
+       switch(selection)
+       {
+               case ECORE_X_SELECTION_SECONDARY:
+                       sel = ECORE_X_ATOM_SELECTION_SECONDARY;
+                       break;
+               case ECORE_X_SELECTION_CLIPBOARD:
+                       sel = ECORE_X_ATOM_SELECTION_CLIPBOARD;
+                       break;
+               default:
+                       return 0;
+       }
+       return XGetSelectionOwner(ad->x_disp, sel);
+}
+
+Eina_Bool is_cbhm_selection_owner(AppData *ad, Ecore_X_Selection selection)
+{
+       CALLED();
+       if (!ad) return EINA_FALSE;
+       Ecore_X_Window sel_owner = get_selection_owner(ad, selection);
+       DMSG("selection_owner: 0x%x, x_event_win: 0x%x \n", sel_owner, ad->x_event_win);
+       if (sel_owner == ad->x_event_win)
+               return EINA_TRUE;
+       return EINA_FALSE;
+}
+
+Eina_Bool set_selection_owner(AppData *ad, Ecore_X_Selection selection, CNP_ITEM *item)
+{
+       CALLED();
+       if (!ad) return EINA_FALSE;
+
+       if (!item && is_cbhm_selection_owner(ad, selection))
+               return EINA_TRUE;
+
+       Ecore_X_Atom sel = 0;
+       Eina_Bool (*selection_func)(Ecore_X_Window win, const void *data, int size) = NULL;
+
+       switch(selection)
+       {
+               case ECORE_X_SELECTION_SECONDARY:
+//                     ecore_x_selection_secondary_clear();
+                       selection_func = ecore_x_selection_secondary_set;
+                       ad->clip_selected_item = item;
+                       break;
+               case ECORE_X_SELECTION_CLIPBOARD:
+//                     ecore_x_selection_clipboard_clear();
+                       selection_func = ecore_x_selection_clipboard_set;
+                       break;
+               default:
+                       return EINA_FALSE;
+       }
+
+       if (selection_func(ad->x_event_win, NULL, 0))
+               return EINA_TRUE;
+
+       DMSG("ERROR: set selection failed\n");
+       return EINA_FALSE;
+}
+
+static Eina_Bool selection_timer_cb(void *data)
+{
+       CALLED();
+       AppData *ad = data;
+       XHandlerData *xd = ad->xhandler;
+
+       set_selection_owner(ad, ECORE_X_SELECTION_CLIPBOARD, NULL);
+       if (is_cbhm_selection_owner(ad, ECORE_X_SELECTION_CLIPBOARD))
+       {
+               ecore_timer_del(xd->selection_timer);
+               xd->selection_timer = NULL;
+               return ECORE_CALLBACK_CANCEL;
+       }
+       return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool _xsel_clear_cb(void *data, int type, void *event)
+{
+       CALLED();
+       if (!data || !event) return EINA_TRUE;
+       AppData *ad = data;
+       XHandlerData *xd = ad->xhandler;
+       Ecore_X_Event_Selection_Clear *ev = event;
+
+       DMSG("in %s, ev->win: 0x%x\n", __func__, ev->win);
+
+       if (is_cbhm_selection_owner(ad, ev->selection)) return EINA_TRUE;
+       if (ev->selection != ECORE_X_SELECTION_CLIPBOARD)
+               return ECORE_CALLBACK_PASS_ON;
+
+       ecore_x_selection_clipboard_request(ad->x_event_win, ECORE_X_SELECTION_TARGET_TARGETS);
+
+       if (xd->selection_timer)
+       {
+               ecore_timer_del(xd->selection_timer);
+               xd->selection_timer = NULL;
+       }
+       xd->selection_timer = ecore_timer_add(SELECTION_CHECK_TIME, selection_timer_cb, ad);
+
+       return ECORE_CALLBACK_DONE;
+}
+
+static Eina_Bool _xsel_request_cb(void *data, int type, void *event)
+{
+       CALLED();
+       if (!data || !event) return ECORE_CALLBACK_PASS_ON;
+       AppData *ad = data;
+       Ecore_X_Event_Selection_Request *ev = event;
+
+#ifdef DEBUG
+       char *names[3];
+       DMSG("selection_owner: 0x%x, ev->... owner: 0x%x, req: 0x%x, selection: %s, target: %s, property: %s\n",
+                       get_selection_owner(ad, ECORE_X_SELECTION_CLIPBOARD), ev->owner, ev->requestor,
+                       names[0] = ecore_x_atom_name_get(ev->selection),
+                       names[1] = ecore_x_atom_name_get(ev->target),
+                       names[2] = ecore_x_atom_name_get(ev->property));
+       FREE(names[0]);
+       FREE(names[1]);
+       FREE(names[2]);
+#endif
+
+       CNP_ITEM *item;
+       if (ev->selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+               item = item_get_last(ad);
+       else if (ev->selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+               item = ad->clip_selected_item;
+       else
+               return ECORE_CALLBACK_PASS_ON;
+
+       if (!item)
+               return ECORE_CALLBACK_PASS_ON;
+
+
+       Ecore_X_Atom property = None;
+       void *data_ret = NULL;
+       int size_ret;
+       Ecore_X_Atom ttype;
+       int tsize;
+
+       if (!generic_converter(ad, ev->target, item, &data_ret, &size_ret, &ttype, &tsize))
+               /*      if (!ecore_x_selection_convert(ev->selection,
+                       ev->target,
+                       &data_ret, &len, &typeAtom, &typesize))*/
+
+       {
+               /* Refuse selection, conversion to requested target failed */
+               DMSG("converter return FALSE\n");
+       }
+       else if (data_ret)
+       {
+               /* FIXME: This does not properly handle large data transfers */
+               ecore_x_window_prop_property_set(
+                               ev->requestor,
+                               ev->property,
+                               ttype,
+                               tsize,
+                               data_ret,
+                               size_ret);
+               property = ev->property;
+               FREE(data_ret);
+               DMSG("change property\n");
+       }
+
+       ecore_x_selection_notify_send(ev->requestor,
+                       ev->selection,
+                       ev->target,
+                       property,
+                       CurrentTime);
+       DMSG("change property notify\n");
+       ecore_x_flush();
+       return ECORE_CALLBACK_DONE;
+}
+
+static void send_convert_selection_target(AppData *ad, Ecore_X_Selection_Data_Targets *targets_data)
+{
+       CALLED();
+       /*      struct _Ecore_X_Selection_Data_Targets {
+               Ecore_X_Selection_Data data;
+               struct _Ecore_X_Selection_Data {
+               enum {
+               ECORE_X_SELECTION_CONTENT_NONE,
+               ECORE_X_SELECTION_CONTENT_TEXT,
+               ECORE_X_SELECTION_CONTENT_FILES,
+               ECORE_X_SELECTION_CONTENT_TARGETS,
+               ECORE_X_SELECTION_CONTENT_CUSTOM
+               } content;
+               unsigned char *data;
+               int            length;
+               int            format;
+               int            (*FREE)(void *data);
+               };
+
+               char                 **targets;
+               int                    num_targets;
+               };*/
+       if (!targets_data || !ad)
+               return;
+       Ecore_X_Atom *atomlist = (Ecore_X_Atom *)targets_data->data.data;
+       if (!atomlist)
+               return;
+
+       DMSG("targets_data->num_targets: 0x%x\n", targets_data->num_targets);
+       int i, j, k;
+       for (i = 0; i < targets_data->num_targets; i++)
+       {
+               DMSG("get target: %s\n", targets_data->targets[i]);
+               for (j = 0; j < ATOM_INDEX_MAX; j++)
+               {
+                       for (k = 0; k < ad->targetAtoms[j].atom_cnt; k++)
+                       {
+                               if (!strcmp(targets_data->targets[i], ad->targetAtoms[j].name[k]))
+                               {
+                                       DMSG("find matched target: %s\n", ad->targetAtoms[j].name[k]);
+                                       ecore_x_selection_clipboard_request(ad->x_event_win, ad->targetAtoms[j].name[k]);
+                                       return;
+                               }
+                       }
+               }
+       }
+       DMSG("ERROR: get target atom failed\n");
+}
+
+static Eina_Bool _add_selection_imagepath(AppData* ad, char *str)
+{
+       if (!ad || !str)
+               return EINA_FALSE;
+       DMSG("get FILE: %s\n", str);
+       char *slash = strchr(str, '/');
+       while (slash && slash[0] == '/')
+       {
+               if (slash[1] != '/')
+               {
+                       char *filepath;
+                       filepath = strdup(slash);
+                       if (filepath)
+                       {
+                               if (ecore_file_exists(filepath))
+                               {
+                                       item_add_by_data(ad, ad->targetAtoms[ATOM_INDEX_IMAGE].atom[0], filepath, strlen(filepath) + 1);
+                                       return EINA_TRUE;
+                               }
+                               else
+                                       FREE(filepath);
+                       }
+                       break;
+               }
+               slash++;
+       }
+       DMSG("Error : it isn't normal file = %s\n", str);
+       return EINA_FALSE;
+}
+
+static void _get_selection_data_files(AppData* ad, Ecore_X_Selection_Data_Files *files_data)
+{
+/*     struct _Ecore_X_Selection_Data_Files {
+               Ecore_X_Selection_Data data;
+               char                 **files;
+               int                    num_files;
+       }; */
+
+       int i;
+       for (i = 0; i < files_data->num_files; i++)
+       {
+               _add_selection_imagepath(ad, files_data->files[i]);
+       }
+}
+
+static Eina_Bool _xsel_notify_cb(void *data, int type, void *event)
+{
+       CALLED();
+       if (!data || !event)
+               return ECORE_CALLBACK_PASS_ON;
+
+       AppData *ad = data;
+       XHandlerData *xd = ad->xhandler;
+       if (xd->selection_timer)
+       {
+               ecore_timer_del(xd->selection_timer);
+               xd->selection_timer = NULL;
+       }
+
+/*     struct _Ecore_X_Event_Selection_Notify
+       {
+               Ecore_X_Window    win;
+               Ecore_X_Time      time;
+               Ecore_X_Selection selection;
+               Ecore_X_Atom      atom;
+               char             *target;
+               void             *data;
+       };*/
+       Ecore_X_Event_Selection_Notify *ev = event;
+
+       switch (ev->selection)
+       {
+               case ECORE_X_SELECTION_CLIPBOARD:
+                       break;
+               case ECORE_X_SELECTION_SECONDARY:
+               case ECORE_X_SELECTION_PRIMARY:
+               case ECORE_X_SELECTION_XDND:
+               default:
+                       return ECORE_CALLBACK_PASS_ON;
+       }
+       if (!ev->data)
+               goto set_clipboard_selection_owner;
+
+/*     struct _Ecore_X_Selection_Data {
+               enum {
+                       ECORE_X_SELECTION_CONTENT_NONE,
+                       ECORE_X_SELECTION_CONTENT_TEXT,
+                       ECORE_X_SELECTION_CONTENT_FILES,
+                       ECORE_X_SELECTION_CONTENT_TARGETS,
+                       ECORE_X_SELECTION_CONTENT_CUSTOM
+               } content;
+               unsigned char *data;
+               int            length;
+               int            format;
+               int            (*FREE)(void *data);
+       };*/
+       Ecore_X_Selection_Data *sel_data = ev->data;
+       switch (sel_data->content)
+       {
+               case ECORE_X_SELECTION_CONTENT_NONE:
+                       DMSG("ECORE_X_SELECTION_CONTENT_NONE\n");
+                       break;
+               case ECORE_X_SELECTION_CONTENT_TEXT:
+                       DMSG("ECORE_X_SELECTION_CONTENT_TEXT\n");
+               /*      struct _Ecore_X_Selection_Data_Text {
+                               Ecore_X_Selection_Data data;
+                               char                  *text;
+                       };
+                       Ecore_X_Selection_Data_Text *text_data = ev->data;*/
+               //      DMSG("sel_data->data: 0x%x, text_data->text: 0x%x\n", sel_data->data, text_data->text);
+                       break;
+               case ECORE_X_SELECTION_CONTENT_FILES:
+                       DMSG("ECORE_X_SELECTION_CONTENT_FILES\n");
+                       _get_selection_data_files(ad, ev->data);
+                       goto set_clipboard_selection_owner;
+                       break;
+               case ECORE_X_SELECTION_CONTENT_TARGETS:
+                       DMSG("ECORE_X_SELECTION_CONTENT_TARGETS\n");
+                       send_convert_selection_target(ad, ev->data);
+                       goto set_clipboard_selection_owner;
+                       break;
+               case ECORE_X_SELECTION_CONTENT_CUSTOM:
+                       DMSG("ECORE_X_SELECTION_CONTENT_CUSTOM\n");
+                       break;
+       }
+#ifdef DEBUG
+       char *name;
+       DMSG("get atom: %d(%s), target: %s, length: %d, format: %d\n",
+                       ev->atom, name = ecore_x_atom_name_get(ev->atom), ev->target, sel_data->length, sel_data->format);
+       FREE(name);
+#endif
+
+       Ecore_X_Atom targetAtom = ecore_x_atom_get(ev->target);
+       char *stripstr = strndup(sel_data->data, sel_data->length);
+       DMSG("get data: %s, len: %d\n", stripstr, strlen(stripstr));
+       if (atom_type_index_get(ad, targetAtom) == ATOM_INDEX_IMAGE)
+       {
+               _add_selection_imagepath(ad, stripstr);
+               FREE(stripstr);
+       }
+       else
+               item_add_by_data(ad, targetAtom, stripstr, strlen(stripstr) + 1);
+
+//     FREE(stripstr);
+
+set_clipboard_selection_owner:
+       set_selection_owner(ad, ECORE_X_SELECTION_CLIPBOARD, NULL);
+       if (!is_cbhm_selection_owner(ad, ECORE_X_SELECTION_CLIPBOARD))
+               xd->selection_timer = ecore_timer_add(SELECTION_CHECK_TIME, selection_timer_cb, ad);
+
+       return ECORE_CALLBACK_DONE;
+}
+
+static Eina_Bool _xclient_msg_cb(void *data, int type, void *event)
+{
+       CALLED();
+       AppData *ad = data;
+       XHandlerData *xd = ad->xhandler;
+
+       /*      struct _Ecore_X_Event_Client_Message {
+               Ecore_X_Window win;
+               Ecore_X_Atom   message_type;
+               int            format;
+               union
+               {
+                       char        b[20];
+                       short       s[10];
+                       long        l[5];
+               } data;
+               Ecore_X_Time   time;
+       };*/
+       Ecore_X_Event_Client_Message *ev = event;
+
+       if (ev->message_type == xd->atomXKey_MSG)
+       {
+               DTRACE("XE:ClientMessage for Screen capture\n");
+               capture_current_screen(ad);
+               return TRUE;
+       }
+
+       if (ev->message_type != xd->atomCBHM_MSG)
+               return -1;
+
+       DTRACE("## %s\n", ev->data.b);
+
+/*     Atom cbhm_atoms[ITEM_CNT_MAX];
+       char atomname[10];
+       Ecore_X_Window reqwin = ev->win;*/
+
+       if (strncmp("show", ev->data.b, 4) == 0)
+       {
+               ad->x_active_win = ev->win;
+               if (ev->data.b[4] == '1')
+                       clipdrawer_paste_textonly_set(ad, EINA_FALSE);
+               else
+                       clipdrawer_paste_textonly_set(ad, EINA_TRUE);
+
+               clipdrawer_activate_view(ad);
+       }
+       else if (!strcmp("cbhm_hide", ev->data.b))
+       {
+               clipdrawer_lower_view(ad);
+       }
+       else if (!strcmp("get count", ev->data.b))
+       {
+               int icount = item_count_get(ad);
+               char countbuf[10];
+               DMSG("## cbhm count : %d\n", icount);
+               snprintf(countbuf, 10, "%d", icount);
+               ecore_x_window_prop_property_set(
+                               ev->win,
+                               xd->atomCBHMCount,
+                               xd->atomUTF8String,
+                               8,
+                               countbuf,
+                               strlen(countbuf));
+       }
+/*     else if (strncmp("get #", ev->data.b, 5) == 0)
+       {
+               // FIXME : handle greater than 9
+               int num = ev->data.b[5] - '0';
+               int cur = get_current_history_position();
+               num = cur + num - 1;
+               if (num > ITEMS_CNT_MAX-1)
+                       num = num-ITEMS_CNT_MAX;
+
+               if (num >= 0 && num < ITEMS_CNT_MAX)
+               {
+                       DTRACE("## pos : #%d\n", num);
+                       // FIXME : handle with correct atom
+                       sprintf(atomname, "CBHM_c%d", num);
+                       cbhm_atoms[0] = XInternAtom(g_disp, atomname, False);
+
+                       CNP_ITEM *item = clipdr;
+
+
+                       if (clipdrawer_get_item_data(ad, num) != NULL)
+                       {
+                               XChangeProperty(g_disp, reqwin, cbhm_atoms[0], atomUTF8String,
+                                                               8, PropModeReplace,
+                                                               (unsigned char *) clipdrawer_get_item_data(ad, num),
+                                                               (int) strlen(clipdrawer_get_item_data(ad, num)));
+                       }
+               }
+       }
+       else if (strcmp("get all", ev->data.b) == 0)
+       {
+//             print_history_buffer();
+               pos = get_current_history_position();
+               for (i = 0; i < 5; i++)
+               {
+                       DTRACE("## %d -> %d\n", i, pos);
+                       sprintf(atomname, "CBHM_c%d", i);
+                       cbhm_atoms[i] = XInternAtom(g_disp, atomname, False);
+                       if (clipdrawer_get_item_data(ad, pos) != NULL)
+                       {
+                               XChangeProperty(g_disp, reqwin, cbhm_atoms[i], atomUTF8String,
+                                                               8, PropModeReplace,
+                                                               (unsigned char *) clipdrawer_get_item_data(ad, pos),
+                                                               (int) strlen(clipdrawer_get_item_data(ad, pos)));
+                       }
+                       pos--;
+                       if (pos < 0)
+                               pos = ITEMS_CNT_MAX-1;
+               }
+       }*/
+/*     else if (strcmp("get raw", ev->data.b) == 0)
+       {
+
+               if (get_storage_start_addr != NULL)
+               {
+                       XChangeProperty(g_disp, reqwin, atomCBHM_cRAW, atomUTF8String,
+                                                       8, PropModeReplace,
+                                                       (unsigned char *) get_storage_start_addr(),
+                                                       (int) get_total_storage_size());
+               }
+       }
+       */
+       XFlush(ad->x_disp);
+
+       return EINA_TRUE;
+}
+
+static Eina_Bool _xfocus_out_cb(void *data, int type, void *event)
+{
+       CALLED();
+       AppData *ad = data;
+       DTRACE("XE:FOCUS OUT\n");
+       clipdrawer_lower_view(ad);
+       return EINA_TRUE;
+}
+
+static Eina_Bool _xproperty_notify_cb(void *data, int type, void *event)
+{
+//     CALLED();
+       AppData *ad = data;
+       XHandlerData *xd = ad->xhandler;
+       ClipdrawerData *cd = ad->clipdrawer;
+       Ecore_X_Event_Window_Property *pevent = (Ecore_X_Event_Window_Property *)event;
+
+       if (ad->x_active_win != pevent->win)
+               return EINA_TRUE;
+
+       if (xd->atomWindowRotate == pevent->atom)
+       {
+               int angle = get_active_window_degree(ad->x_active_win);
+               if (angle != cd->o_degree)
+               {
+                       cd->o_degree = angle;
+                       elm_win_rotation_set(cd->main_win, angle);
+                       set_rotation_to_clipdrawer(cd);
+               }
+       }
+
+       return EINA_TRUE;
+}
+
+static Eina_Bool _xwin_destroy_cb(void *data, int type, void *event)
+{
+       CALLED();
+       AppData *ad = data;
+       Ecore_X_Event_Window_Destroy *pevent = event;
+       if (ad->x_active_win != pevent->win)
+               return EINA_TRUE;
+       clipdrawer_lower_view(ad);
+}
+
+XHandlerData *init_xhandler(AppData *ad)
+{
+       XHandlerData *xd = CALLOC(1, sizeof(XHandlerData));
+       if (!xd)
+               return NULL;
+       xd->xsel_clear_handler = ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR, _xsel_clear_cb, ad);
+       xd->xsel_request_handler = ecore_event_handler_add(ECORE_X_EVENT_SELECTION_REQUEST, _xsel_request_cb, ad);
+       xd->xsel_notify_handler = ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY, _xsel_notify_cb, ad);
+       xd->xclient_msg_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _xclient_msg_cb, ad);
+       xd->xfocus_out_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _xfocus_out_cb, ad);
+       xd->xproperty_notify_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _xproperty_notify_cb, ad);
+       xd->xwindow_destroy_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _xwin_destroy_cb, ad);
+
+       xd->atomInc = ecore_x_atom_get("INCR");
+       xd->atomWindowRotate = ecore_x_atom_get("_E_ILLUME_ROTATE_WINDOW_ANGLE");
+       xd->atomCBHM_MSG = ecore_x_atom_get("CBHM_MSG");
+       xd->atomXKey_MSG = ecore_x_atom_get("_XKEY_COMPOSITION");
+       xd->atomCBHMCount = ecore_x_atom_get("CBHM_cCOUNT");
+       xd->atomUTF8String = ecore_x_atom_get("UTF8_STRING");
+       return xd;
+}
+
+void depose_xhandler(XHandlerData *xd)
+{
+       ecore_event_handler_del(xd->xsel_clear_handler);
+       ecore_event_handler_del(xd->xsel_request_handler);
+       ecore_event_handler_del(xd->xsel_notify_handler);
+       ecore_event_handler_del(xd->xclient_msg_handler);
+       ecore_event_handler_del(xd->xfocus_out_handler);
+       ecore_event_handler_del(xd->xproperty_notify_handler);
+       ecore_event_handler_del(xd->xwindow_destroy_handler);
+       FREE(xd);
+}
+
+int get_active_window_degree(Ecore_X_Window active)
+{
+       //ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE
+
+       int rotation = 0;
+       unsigned char *prop_data = NULL;
+       int count;
+       int ret = ecore_x_window_prop_property_get(
+                       active, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
+                       ECORE_X_ATOM_CARDINAL, 32, &prop_data, &count);
+       if (ret && prop_data) memcpy(&rotation, prop_data, sizeof(int));
+       if (prop_data) FREE(prop_data);
+       return rotation;
+}
diff --git a/src/xhandler.h b/src/xhandler.h
new file mode 100644 (file)
index 0000000..18a446a
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  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.
+ *
+ */
+
+#ifndef _XCNPHANDLER_H_
+#define _XCNPHANDLER_H_
+
+#include <Ecore_X.h>
+#include <Ecore.h>
+
+struct _XHandlerData {
+       Ecore_Event_Handler *xsel_clear_handler;
+       Ecore_Event_Handler *xsel_request_handler;
+       Ecore_Event_Handler *xsel_notify_handler;
+       Ecore_Event_Handler *xclient_msg_handler;
+       Ecore_Event_Handler *xfocus_out_handler;
+       Ecore_Event_Handler *xproperty_notify_handler;
+       Ecore_Event_Handler *xwindow_destroy_handler;
+
+       Ecore_X_Atom atomInc;
+       Ecore_X_Atom atomWindowRotate;
+
+       Ecore_X_Atom atomCBHM_MSG;
+       Ecore_X_Atom atomXKey_MSG;
+
+       Ecore_X_Atom atomUTF8String;
+       Ecore_X_Atom atomCBHMCount;
+
+       Ecore_Timer *selection_timer;
+};
+
+#include "cbhm.h"
+#include "item_manager.h"
+#include "xconverter.h"
+
+XHandlerData *init_xhandler(AppData *data);
+void depose_xhandler(XHandlerData *xd);
+Eina_Bool set_selection_owner(AppData *ad, Ecore_X_Selection selection, CNP_ITEM *item);
+#define SELECTION_CHECK_TIME 0.5
+
+#endif