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}")
--- /dev/null
+/*
+ * 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_
*
*/
-#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
#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)
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
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;
}
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;
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;
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;
-}
*
*/
-#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_
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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_*/
+
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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);
+}
+
--- /dev/null
+/*
+ * 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_
*
*/
-#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);
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)
{
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,
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);
}
}
*
*/
-#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_
*
*/
-#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;
}
-
*
*/
-#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
--- /dev/null
+/*
+ * 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, " ", " ");
+ 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, " ", " ");
+ 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" },
+ { ">", ">" },
+ { "<", "<" },
+ { "&", "&" },
+ { """, "'" },
+ { "&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, " ", " ");
+
+ 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, " ", " ");
+ html = eina_strbuf_string_steal(buf);
+ eina_strbuf_free(buf);
+ text = remove_tags(html, NULL);
+ free(html);
+ return text;
+ }
+ }
+ return remove_tags(str, NULL);
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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