From 73764c88c6014358c0e770f4cfeefe7c92117fba Mon Sep 17 00:00:00 2001 From: "deasung.kim" Date: Fri, 6 Jan 2012 13:32:50 +0900 Subject: [PATCH] [CBHM] refactoring Change-Id: I1e9cf43a5029451a6c6f9a16036ca51e98e808ac --- CMakeLists.txt | 10 +- src/cbhm.h | 116 ++++ src/clipdrawer.c | 1009 ++++++++++++----------------- src/clipdrawer.h | 55 +- src/item_manager.c | 186 ++++++ src/item_manager.h | 47 ++ src/main.c | 174 +++++ src/{ => old}/cbhm_main.c | 0 src/{ => old}/cbhm_main.h | 0 src/old/clipdrawer.c | 872 +++++++++++++++++++++++++ src/old/clipdrawer.h | 48 ++ src/{ => old}/common.h | 0 src/old/scrcapture.c | 768 ++++++++++++++++++++++ src/old/scrcapture.h | 40 ++ src/old/storage.c | 160 +++++ src/old/storage.h | 35 + src/{ => old}/xcnphandler.c | 0 src/{ => old}/xcnphandler.h | 0 src/scrcapture.c | 805 ++++++++--------------- src/scrcapture.h | 34 +- src/storage.c | 332 +++++++--- src/storage.h | 31 +- src/xconverter.c | 1476 +++++++++++++++++++++++++++++++++++++++++++ src/xconverter.h | 38 ++ src/xhandler.c | 621 ++++++++++++++++++ src/xhandler.h | 54 ++ 26 files changed, 5608 insertions(+), 1303 deletions(-) mode change 100755 => 100644 CMakeLists.txt create mode 100644 src/cbhm.h create mode 100644 src/item_manager.c create mode 100644 src/item_manager.h create mode 100644 src/main.c rename src/{ => old}/cbhm_main.c (100%) rename src/{ => old}/cbhm_main.h (100%) create mode 100644 src/old/clipdrawer.c create mode 100644 src/old/clipdrawer.h rename src/{ => old}/common.h (100%) create mode 100644 src/old/scrcapture.c create mode 100644 src/old/scrcapture.h create mode 100644 src/old/storage.c create mode 100644 src/old/storage.h rename src/{ => old}/xcnphandler.c (100%) rename src/{ => old}/xcnphandler.h (100%) create mode 100644 src/xconverter.c create mode 100644 src/xconverter.h create mode 100644 src/xhandler.c create mode 100644 src/xhandler.h diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 index d101d85..c5609de --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,17 +1,19 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(cbhm C) -SET(SRCS src/cbhm_main.c +SET(SRCS src/main.c + src/item_manager.c + src/xconverter.c + src/xhandler.c src/clipdrawer.c - src/storage.c - src/xcnphandler.c src/scrcapture.c + src/storage.c ) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED elementary appcore-efl appcore-common x11 ecore-x utilX eina evas ecore ecore-evas edje ecore-input xext xcomposite svi pixman-1) +pkg_check_modules(pkgs REQUIRED elementary eet appcore-efl appcore-common x11 ecore-x utilX eina evas ecore ecore-file ecore-evas edje ecore-input xext xcomposite svi pixman-1) FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/src/cbhm.h b/src/cbhm.h new file mode 100644 index 0000000..07db153 --- /dev/null +++ b/src/cbhm.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _CBHM_H_ +#define _CBHM_H_ + +#include +#include + +#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_ diff --git a/src/clipdrawer.c b/src/clipdrawer.c index 669d9d0..c308b8e 100644 --- a/src/clipdrawer.c +++ b/src/clipdrawer.c @@ -15,19 +15,20 @@ * */ -#include "common.h" -#include "cbhm_main.h" -#include "storage.h" -#include "xcnphandler.h" +#include #include "clipdrawer.h" +#include "item_manager.h" +#include "xconverter.h" -#define DELETE_ICON_PATH "/usr/share/cbhm/icons/05_delete.png" -#define IM "/usr/share/cbhm/icons/" -static const char *g_images_path[] = { - IM"cbhm_default_img.png", -}; -#define N_IMAGES (1) +#define EDJ_PATH "/usr/share/edje" +#define APP_EDJ_FILE EDJ_PATH"/cbhmdrawer.edj" +#define GRP_MAIN "cbhmdrawer" +#define ANIM_DURATION 30 // 1 seconds +#define ANIM_FLOPS (0.5/30) +#define CLIPDRAWER_HEIGHT 360 +#define CLIPDRAWER_HEIGHT_LANDSCAPE 228 +#define DEFAULT_WIDTH 720 #define GRID_ITEM_SPACE_W 6 #define GRID_ITEM_SINGLE_W 185 #define GRID_ITEM_SINGLE_H 161 @@ -36,494 +37,418 @@ static const char *g_images_path[] = { #define GRID_IMAGE_LIMIT_W 91 #define GRID_IMAGE_LIMIT_H 113 -#define ANIM_DURATION 30 // 1 seconds -#define ANIM_FLOPS (0.5/30) +static Evas_Object *create_win(ClipdrawerData *cd, const char *name); +static Evas_Object *_grid_content_get(void *data, Evas_Object *obj, const char *part); +static void _grid_del(void *data, Evas_Object *obj); +static Eina_Bool clipdrawer_add_item(AppData *ad, CNP_ITEM *item); +static Eina_Bool clipdrawer_del_item(AppData *ad, CNP_ITEM *item); +static void clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source); +static void _grid_item_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source); +static void setting_win(Ecore_X_Display *x_disp, Ecore_X_Window x_main_win); +static void set_transient_for(Ecore_X_Window x_main_win, Ecore_X_Window x_active_win); +static void unset_transient_for(Ecore_X_Window x_main_win, Ecore_X_Window x_active_win); + +static void _change_gengrid_paste_textonly_mode(ClipdrawerData *cd) +{ + CNP_ITEM *item = NULL; -// gic should live at gengrid callback functions -Elm_Gengrid_Item_Class gic; -static Ecore_Timer *anim_timer = NULL; + Elm_Gengrid_Item *gitem = elm_gengrid_first_item_get(cd->gengrid); -typedef struct tag_griditem -{ - int itype; - Elm_Gengrid_Item *item; - const char *ipathdata; - Eina_Strbuf *istrdata; - Evas_Object *delbtn; - Evas_Object *ilayout; -} griditem_t; - -const char * -remove_tags(const char *p) + while (gitem) + { + item = elm_gengrid_item_data_get(gitem); + if ((item->type_index == ATOM_INDEX_IMAGE) && (item->layout)) + { + if (cd->paste_text_only) + edje_object_signal_emit(elm_layout_edje_get(item->layout), "elm,state,show,dim", "elm"); + else + edje_object_signal_emit(elm_layout_edje_get(item->layout), "elm,state,hide,dim", "elm"); + } + gitem = elm_gengrid_item_next_get(gitem); + } +} + +void clipdrawer_paste_textonly_set(AppData *ad, Eina_Bool textonly) { - char *q,*ret; - int i; - if (!p) return NULL; - - q = malloc(strlen(p) + 1); - if (!q) return NULL; - ret = q; - - while (*p) - { - if ((*p != '<')) *q++ = *p++; - else if (*p == '<') - { - if ((p[1] == 'b') && (p[2] == 'r') && - ((p[3] == ' ') || (p[3] == '/') || (p[3] == '>'))) - *q++ = '\n'; - while ((*p) && (*p != '>')) p++; - p++; - } - } - *q = 0; - - return ret; + ClipdrawerData *cd = ad->clipdrawer; + if (cd->paste_text_only != textonly) + cd->paste_text_only = textonly; + DTRACE("paste textonly mode = %d\n", textonly); + + _change_gengrid_paste_textonly_mode(cd); } -const char* clipdrawer_get_plain_string_from_escaped(char *escstr) +Eina_Bool clipdrawer_paste_textonly_get(AppData *ad) { - /* NOTE : return string should be freed */ - return remove_tags(escstr); + ClipdrawerData *cd = ad->clipdrawer; + return cd->paste_text_only; } -static char* _get_string_for_entry(char *str) +static Evas_Object *_load_edj(Evas_Object* win, const char *file, const char *group) { - if (!str) + Evas_Object *layout = elm_layout_add(win); + if (!layout) + { + DMSG("ERROR: elm_layout_add return NULL\n"); return NULL; + } - Eina_Strbuf *strbuf = eina_strbuf_new(); - if (!strbuf) - return strdup(str); - eina_strbuf_prepend(strbuf, ""); + 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, "
"); - 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, "", src); - DTRACE("src str: %s \n", src); - free(src); - } - trail = endtag + 1; - } + evas_object_show(cd->gengrid); + + ad->draw_item_add = clipdrawer_add_item; + ad->draw_item_del = clipdrawer_del_item; +// ad->x_main_win = cd->x_main_win; - char *ret = eina_strbuf_string_steal(strbuf); - eina_strbuf_free(strbuf); - DTRACE("result str: %s \n", ret); - return ret; + cd->keydown_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, keydown_cb, ad); + cd->evas = evas_object_evas_get(cd->main_win); + + return cd; } -static void _grid_del_response_cb(void *data, Evas_Object *obj, void *event_info) +void depose_clipdrawer(ClipdrawerData *cd) { - Elm_Gengrid_Item *it = (Elm_Gengrid_Item *)data; - evas_object_del(obj); + evas_object_del(cd->main_win); + if (cd->anim_timer) + ecore_timer_del(cd->anim_timer); + if (cd->keydown_handler) + ecore_event_handler_del(cd->keydown_handler); + free(cd); +} - if((int)event_info == ELM_POPUP_RESPONSE_OK) +static Eina_Bool clipdrawer_add_item(AppData *ad, CNP_ITEM *item) +{ + ClipdrawerData *cd = ad->clipdrawer; + if (item->type_index == ATOM_INDEX_IMAGE) { - struct appdata *ad = g_get_main_appdata(); - elm_gengrid_item_del(it); - ad->hicount--; - if (ad->hicount < 0) + Elm_Gengrid_Item *gitem = elm_gengrid_first_item_get(cd->gengrid); + while (gitem) { - int cnt = 0; - Elm_Gengrid_Item *trail = elm_gengrid_first_item_get(ad->hig); - while(trail) + CNP_ITEM *gitem_data = elm_gengrid_item_data_get(gitem); + gitem = elm_gengrid_item_next_get(gitem); + if ((gitem_data->type_index == item->type_index) && (!strcmp(item->data, gitem_data->data))) { - cnt++; - elm_gengrid_item_next_get(trail); + DMSG("duplicated file path = %s\n", item->data); + item_delete_by_CNP_ITEM(ad, gitem_data); } - ad->hicount = cnt; - DTRACE("ERR: cbhm history cnt < 0, gengrid item cnt: %d\n", cnt); } } + + item->gitem = elm_gengrid_item_prepend(cd->gengrid, &cd->gic, item, NULL, NULL); + + return EINA_TRUE; } -static void _grid_click_delete(void *data, Evas_Object *obj, void *event_info) +static Eina_Bool clipdrawer_del_item(AppData *ad, CNP_ITEM *item) { - struct appdata *ad = data; + if (item->gitem) + elm_gengrid_item_del(item->gitem); + return EINA_TRUE; } -static void -_grid_item_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source) +static void _grid_del(void *data, Evas_Object *obj) { - struct appdata *ad = g_get_main_appdata(); - - if (ad->anim_status != STATUS_NONE) - return; + CNP_ITEM *item = data; + item->gitem = NULL; + item->layout = NULL; +} - Elm_Gengrid_Item *sgobj = NULL; - sgobj = elm_gengrid_selected_item_get(ad->hig); - griditem_t *ti = NULL; - ti = elm_gengrid_item_data_get(sgobj); +static Evas_Object *_grid_content_get(void *data, Evas_Object *obj, const char *part) +{ + CNP_ITEM *item = data; + AppData *ad = item->ad; + ClipdrawerData *cd = ad->clipdrawer; - #define EDJE_DELBTN_PART_PREFIX "delbtn" - if (strncmp(source, EDJE_DELBTN_PART_PREFIX, strlen(EDJE_DELBTN_PART_PREFIX))) + if (strcmp(part, "elm.swallow.icon")) + return NULL; + if (item->type_index == ATOM_INDEX_IMAGE) /* text/uri */ { - if (!sgobj || !ti) - { - DTRACE("ERR: cbhm can't get the selected image\n"); - return; - } + Evas_Object *layout = elm_layout_add(obj); + elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout"); + edje_object_signal_callback_add(elm_layout_edje_get(layout), + "mouse,up,1", "*", _grid_item_ly_clicked, data); - elm_gengrid_item_selected_set(sgobj, EINA_FALSE); + Evas_Object *sicon; + sicon = evas_object_image_add(evas_object_evas_get(obj)); + evas_object_image_load_size_set(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H); + evas_object_image_file_set(sicon, item->data, NULL); + evas_object_image_fill_set(sicon, 0, 0, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H); + evas_object_resize(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H); + elm_layout_content_set(layout, "elm.swallow.icon", sicon); - if (ti->itype == GI_TEXT) - { - char *p = strdup(eina_strbuf_string_get(ti->istrdata)); + if (cd->paste_text_only) + edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,show,dim", "elm"); + else + edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,hide,dim", "elm"); - elm_selection_set(1, ad->hig, /*ELM_SEL_FORMAT_HTML*/0x10, p); - } - else //if (ti->itype == GI_IMAGE) - { - if (!clipdrawer_paste_textonly_get(ad)) - { - int len = strlen(ti->ipathdata); - char *p = malloc(len + 10); - snprintf(p,len+10, "file:///%s", ti->ipathdata); - - elm_selection_set(/*secondary*/1, ad->hig,/*ELM_SEL_FORMAT_IMAGE*/4,p); - } - else - { - DTRACE("ERR: cbhm image paste mode is false\n"); - } - } - return; - } - - if (!sgobj) - { - DTRACE("ERR: cbhm can't get the selected item\n"); - return; + item->layout = layout; } - - elm_gengrid_item_selected_set(sgobj, EINA_FALSE); - - Evas_Object *popup = elm_popup_add(ad->win_main); - elm_popup_timeout_set(popup, 5); - evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_popup_desc_set(popup, "Are you sure delete this?"); - elm_popup_buttons_add(popup, 2, - "Yes", ELM_POPUP_RESPONSE_OK, - "No", ELM_POPUP_RESPONSE_CANCEL, - NULL); - evas_object_smart_callback_add(popup, "response", _grid_del_response_cb, sgobj); - evas_object_show(popup); -} - -Evas_Object* _grid_icon_get(const void *data, Evas_Object *obj, const char *part) -{ - griditem_t *ti = (griditem_t *)data; - - if (!strcmp(part, "elm.swallow.icon")) + else { - if (ti->itype == GI_TEXT) + Evas_Object *layout = elm_layout_add(obj); + elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout"); + edje_object_signal_callback_add(elm_layout_edje_get(layout), + "mouse,up,1", "*", _grid_item_ly_clicked, data); + Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(obj)); + evas_object_resize(rect, GRID_ITEM_W, GRID_ITEM_H); + evas_object_color_set(rect, 242, 233, 183, 255); + evas_object_show(rect); + elm_layout_content_set(layout, "elm.swallow.icon", rect); + + Evas_Object *ientry = elm_entry_add(obj); + evas_object_size_hint_weight_set(ientry, 0, 0); + elm_entry_scrollable_set(ientry, EINA_TRUE); + + char *entry_text = string_for_entry_get(ad, item->type_index, item->data); + if (entry_text) { - Evas_Object *layout = elm_layout_add (obj); - elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout"); - edje_object_signal_callback_add(elm_layout_edje_get(layout), - "mouse,up,1", "*", _grid_item_ly_clicked, data); - Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(obj)); - evas_object_resize(rect, GRID_ITEM_W, GRID_ITEM_H); - evas_object_color_set(rect, 242, 233, 183, 255); - evas_object_show(rect); - elm_layout_content_set(layout, "elm.swallow.icon", rect); - - // FIXME: add string length check - Evas_Object *ientry = elm_entry_add(obj); - evas_object_size_hint_weight_set(ientry, 0, 0); - Eina_Strbuf *strent = NULL; - char *strdata = eina_strbuf_string_get(ti->istrdata); - int i, skipflag, strcnt; - - strent = eina_strbuf_new(); - skipflag = 0; - strcnt = 0; - for (i = 0; i < eina_strbuf_length_get(ti->istrdata); i++) - { - switch (strdata[i]) - { - case '>': - skipflag = 0; - break; - case '<': - skipflag = 1; - break; - default: - if (!skipflag) - strcnt++; - break; - } - if (strcnt > 100) - break; - } - eina_strbuf_append_n(strent, strdata, i); - eina_strbuf_replace_all(strent, " absize=240x180 ", " absize=52x39 "); - if (strcnt > 100) - eina_strbuf_append(strent, "..."); - elm_entry_scrollable_set(ientry, EINA_TRUE); - char *entry_text = eina_strbuf_string_get(strent); - entry_text = _get_string_for_entry(entry_text); - if (entry_text) - { - elm_object_part_text_set(ientry, NULL, entry_text); - free(entry_text); - } - elm_entry_editable_set(ientry, EINA_FALSE); - elm_entry_context_menu_disabled_set(ientry, EINA_TRUE); - evas_object_show(ientry); - elm_layout_content_set(layout, "elm.swallow.inner", ientry); - - eina_strbuf_free(strent); - - return layout; + elm_object_part_text_set(ientry, NULL, entry_text); + free(entry_text); } - else// if (ti->itype == GI_IMAGE) + else { - Evas_Object *layout = elm_layout_add (obj); - elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout"); - edje_object_signal_callback_add(elm_layout_edje_get(layout), - "mouse,up,1", "*", _grid_item_ly_clicked, data); - - Evas_Object *sicon; - sicon = evas_object_image_add(evas_object_evas_get(obj)); - evas_object_image_load_size_set(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H); - evas_object_image_file_set(sicon, ti->ipathdata, NULL); - evas_object_image_fill_set(sicon, 0, 0, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H); - evas_object_resize(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H); - elm_layout_content_set(layout, "elm.swallow.icon", sicon); - - struct appdata *ad = g_get_main_appdata(); - - if (clipdrawer_paste_textonly_get(ad)) - edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,show,dim", "elm"); - else - edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,hide,dim", "elm"); - - ti->ilayout = layout; - return layout; + elm_object_part_text_set(ientry, NULL, item->data); } + elm_entry_editable_set(ientry, EINA_FALSE); + elm_entry_context_menu_disabled_set(ientry, EINA_TRUE); + evas_object_show(ientry); + elm_layout_content_set(layout, "elm.swallow.inner", ientry); + + item->layout = layout; } - return NULL; + return item->layout; } -static void _grid_longpress(void *data, Evas_Object *obj, void *event_info) +static void clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source) { - struct appdata *ad = data; -} + AppData *ad = data; -static void _grid_click_paste(void *data, Evas_Object *obj, void *event_info) -{ - struct appdata *ad = data; - if (ad->anim_status != STATUS_NONE) + if (ad->clipdrawer->anim_status != STATUS_NONE) return; - Elm_Gengrid_Item *sgobj = NULL; - sgobj = elm_gengrid_selected_item_get(ad->hig); - griditem_t *ti = NULL; - ti = elm_gengrid_item_data_get(sgobj); -} - -void _grid_del(const void *data, Evas_Object *obj) -{ - griditem_t *ti = (griditem_t *)data; - if (ti->itype == GI_TEXT) - eina_strbuf_free(ti->istrdata); - else - eina_stringshare_del(ti->ipathdata); - free(ti); +#define EDJE_CLOSE_PART_PREFIX "background/close" + if (!strncmp(source, EDJE_CLOSE_PART_PREFIX, strlen(EDJE_CLOSE_PART_PREFIX))) + { + clipdrawer_lower_view(ad); + } } -char* clipdrawer_get_item_data(void *data, int pos) +static void _grid_del_response_cb(void *data, Evas_Object *obj, void *event_info) { - struct appdata *ad = data; - griditem_t *ti = NULL; - griditem_t *newgi = NULL; - int count = 0; + CNP_ITEM *item = data; + AppData *ad = item->ad; + ClipdrawerData *cd = ad->clipdrawer; - if (pos < 0 || pos > ad->hicount) - return NULL; + /* delete popup */ + evas_object_del(obj); - Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig); - while (item) + if((int)event_info == ELM_POPUP_RESPONSE_OK) { - ti = elm_gengrid_item_data_get(item); - if (count == pos) - { - if (!ti) - break; - if (ti->itype == GI_TEXT) - return (char*)eina_strbuf_string_get(ti->istrdata); - else - return ti->ipathdata; - } - count++; - item = elm_gengrid_item_next_get(item); + item_delete_by_CNP_ITEM(ad, item); } - - return NULL; } -// FIXME: how to remove calling g_get_main_appdata()? -// it's mainly used at 'clipdrawer_image_item' -int clipdrawer_add_item(char *idata, int type) +static void _grid_item_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source) { - struct appdata *ad = g_get_main_appdata(); - griditem_t *newgi = NULL; + CNP_ITEM *item = data; + AppData *ad = item->ad; + ClipdrawerData *cd = ad->clipdrawer; - newgi = malloc(sizeof(griditem_t)); - newgi->itype = type; + if (cd->anim_status != STATUS_NONE) + return; - fprintf(stderr, "## add - %d : %s\n", newgi->itype, idata); - if (type == GI_TEXT) + Elm_Gengrid_Item *sgobj = NULL; + sgobj = elm_gengrid_selected_item_get(cd->gengrid); + item = elm_gengrid_item_data_get(sgobj); + + if (!sgobj || !item) { - newgi->istrdata = eina_strbuf_new(); - eina_strbuf_append(newgi->istrdata, idata); + DTRACE("ERR: cbhm can't get the selected item\n"); + return; } - else //if (type == GI_IMAGE) - { - Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig); - griditem_t *ti = NULL; - if (!check_regular_file(idata)) - { - DTRACE("Error : it isn't normal file = %s\n", idata); - return -1; - } + #define EDJE_DELBTN_PART_PREFIX "delbtn" + if (strncmp(source, EDJE_DELBTN_PART_PREFIX, strlen(EDJE_DELBTN_PART_PREFIX))) + { + elm_gengrid_item_selected_set(sgobj, EINA_FALSE); - while (item) + if (item->type_index != ATOM_INDEX_IMAGE || !cd->paste_text_only) { - ti = elm_gengrid_item_data_get(item); - if ((ti->itype == type) && !strcmp(ti->ipathdata, idata)) - { - DTRACE("Error : duplicated file path = %s\n", idata); - return -1; - } - item = elm_gengrid_item_next_get(item); + set_selection_owner(ad, ECORE_X_SELECTION_SECONDARY, item); } - newgi->ipathdata = eina_stringshare_add(idata); } - - if (ad->hicount >= HISTORY_QUEUE_MAX_ITEMS) + else { - ad->hicount--; - // FIXME: add routine that is removing its elements - elm_gengrid_item_del(elm_gengrid_last_item_get(ad->hig)); + elm_gengrid_item_selected_set(sgobj, EINA_FALSE); + + Evas_Object *popup = elm_popup_add(cd->main_win); + elm_popup_timeout_set(popup, 5); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_popup_desc_set(popup, "Are you sure delete this?"); + elm_popup_buttons_add(popup, 2, + "Yes", ELM_POPUP_RESPONSE_OK, + "No", ELM_POPUP_RESPONSE_CANCEL, + NULL); + evas_object_smart_callback_add(popup, "response", _grid_del_response_cb, item); + evas_object_show(popup); } +} - ad->hicount++; - newgi->item = elm_gengrid_item_prepend(ad->hig, &gic, newgi, NULL, NULL); +void set_transient_for(Ecore_X_Window x_main_win, Ecore_X_Window x_active_win) +{ + ecore_x_icccm_transient_for_set(x_main_win, x_active_win); + ecore_x_event_mask_set(x_active_win, + ECORE_X_EVENT_MASK_WINDOW_PROPERTY | ECORE_X_EVENT_MASK_WINDOW_CONFIGURE); +} - return TRUE; +void unset_transient_for(Ecore_X_Window x_main_win, Ecore_X_Window x_active_win) +{ + ecore_x_event_mask_unset(x_active_win, + ECORE_X_EVENT_MASK_WINDOW_PROPERTY | ECORE_X_EVENT_MASK_WINDOW_CONFIGURE); + ecore_x_icccm_transient_for_unset(x_main_win); } -static void -clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source) +static void set_focus_for_app_window(Ecore_X_Window x_main_win, Eina_Bool enable) { - struct appdata *ad = data; + CALLED(); + Eina_Bool accepts_focus; + Ecore_X_Window_State_Hint initial_state; + Ecore_X_Pixmap icon_pixmap; + Ecore_X_Pixmap icon_mask; + Ecore_X_Window icon_window; + Ecore_X_Window window_group; + Eina_Bool is_urgent; + + ecore_x_icccm_hints_get (x_main_win, + &accepts_focus, &initial_state, &icon_pixmap, &icon_mask, &icon_window, &window_group, &is_urgent); + ecore_x_icccm_hints_set (x_main_win, + enable, initial_state, icon_pixmap, icon_mask, icon_window, window_group, is_urgent); + DMSG("set focus mode = %d\n", enable); +} - if (ad->anim_status != STATUS_NONE) - return; +void setting_win(Ecore_X_Display *x_disp, Ecore_X_Window x_main_win) +{ + CALLED(); + // disable window effect + utilx_set_window_effect_state(x_disp, x_main_win, 0); - #define EDJE_CLOSE_PART_PREFIX "background/close" - if (!strncmp(source, EDJE_CLOSE_PART_PREFIX, strlen(EDJE_CLOSE_PART_PREFIX))) + ecore_x_icccm_name_class_set(x_main_win, "NORMAL_WINDOW", "NORMAL_WINDOW"); + + set_focus_for_app_window(x_main_win, EINA_FALSE); + +} + +Evas_Object *create_win(ClipdrawerData *cd, const char *name) +{ + CALLED(); + + Evas_Object *win = elm_win_add(NULL, name, ELM_WIN_BASIC); + if (!win) { - clipdrawer_lower_view(ad); + DMSG("ERROR: elm_win_add return NULL\n"); + return NULL; } + elm_win_title_set(win, name); + elm_win_borderless_set(win, EINA_TRUE); + ecore_x_window_size_get(ecore_x_window_root_first_get(), &cd->root_w, &cd->root_h); + DMSG("root_w: %d, root_h: %d\n", cd->root_w, cd->root_h); + evas_object_resize(win, cd->root_w, cd->root_h); + + elm_scale_set((double)cd->root_w/DEFAULT_WIDTH); + return win; } -static void set_sliding_win_geometry(void *data) +static void set_sliding_win_geometry(ClipdrawerData *cd) { - struct appdata *ad = data; - Ecore_X_Window zone, xwin; + CALLED(); + Ecore_X_Window zone; Evas_Coord x, y, w, h; - xwin = elm_win_xwindow_get(ad->win_main); - zone = ecore_x_e_illume_zone_get(xwin); - DTRACE("[CBHM] xwin:%x, zone:%x\n", xwin, zone); - -// ecore_evas_geometry_get(ecore_evas_ecore_evas_get(evas_object_evas_get(ad->win_main)), &x, &y, &w, &h); + zone = ecore_x_e_illume_zone_get(cd->x_main_win); + DTRACE(" zone:%x\n", zone); - if (ad->o_degree == 90 || ad->o_degree == 270) + if (cd->o_degree == 90 || cd->o_degree == 270) { - h = ad->anim_count * CLIPDRAWER_HEIGHT_LANDSCAPE / ANIM_DURATION; + h = cd->anim_count * CLIPDRAWER_HEIGHT_LANDSCAPE / ANIM_DURATION; x = 0; - y = ad->root_w - h; - w = ad->root_h; + y = cd->root_w - h; + w = cd->root_h; } else { - h = ad->anim_count * CLIPDRAWER_HEIGHT / ANIM_DURATION; + h = cd->anim_count * CLIPDRAWER_HEIGHT / ANIM_DURATION; x = 0; - y = ad->root_h - h; - w = ad->root_w; + y = cd->root_h - h; + w = cd->root_w; } if (!h) @@ -531,13 +456,13 @@ static void set_sliding_win_geometry(void *data) DTRACE("[CBHM] change degree geometry... (%d, %d, %d x %d)\n", x, y, w, h); ecore_x_e_illume_sliding_win_geometry_set(zone, x, y, w, h); - ecore_x_e_illume_sliding_win_state_set(zone, ad->anim_count != 0); + ecore_x_e_illume_sliding_win_state_set(zone, cd->anim_count != 0); } -void set_rotation_to_clipdrawer(void *data) +void set_rotation_to_clipdrawer(ClipdrawerData *cd) { - struct appdata *ad = data; - int angle = ad->o_degree; + CALLED(); + int angle = cd->o_degree; int x, y, w, h; if (angle == 180) // reverse @@ -545,142 +470,62 @@ void set_rotation_to_clipdrawer(void *data) h = CLIPDRAWER_HEIGHT; x = 0; y = 0; - w = ad->root_w; + w = cd->root_w; } else if (angle == 90) // right rotate { h = CLIPDRAWER_HEIGHT_LANDSCAPE; - x = ad->root_w - h; + x = cd->root_w - h; y = 0; - w = ad->root_h; + w = cd->root_h; } else if (angle == 270) // left rotate { h = CLIPDRAWER_HEIGHT_LANDSCAPE; x = 0; y = 0; - w = ad->root_h; + w = cd->root_h; } else // angle == 0 { h = CLIPDRAWER_HEIGHT; x = 0; - y = ad->root_h - h; - w = ad->root_w; + y = cd->root_h - h; + w = cd->root_w; } - evas_object_resize(ad->win_main, w, h); - evas_object_move(ad->win_main, x, y); - if (ad->anim_count == ANIM_DURATION) - set_sliding_win_geometry(data); + evas_object_resize(cd->main_win, w, h); + evas_object_move(cd->main_win, x, y); + if (cd->anim_count == ANIM_DURATION) + set_sliding_win_geometry(cd); } -int clipdrawer_init(void *data) -{ - struct appdata *ad = data; - double cdy, cdw; - - ad->windowshow = EINA_FALSE; - ad->hicount = 0; - ad->pastetextonly = EINA_TRUE; - ad->anim_status = STATUS_NONE; - ad->anim_count = 0; - - // for elm_check - elm_theme_extension_add(NULL, APP_EDJ_FILE); - - edje_object_signal_callback_add(elm_layout_edje_get(ad->ly_main), - "mouse,up,1", "*", clipdrawer_ly_clicked, ad); - - ad->hig = NULL; - ad->hig = elm_gengrid_add(ad->win_main); - elm_layout_content_set(ad->ly_main, "historyitems", ad->hig); - elm_gengrid_item_size_set(ad->hig, GRID_ITEM_W+2, GRID_ITEM_H); - elm_gengrid_align_set(ad->hig, 0.5, 0.5); - elm_gengrid_horizontal_set(ad->hig, EINA_TRUE); - elm_gengrid_bounce_set(ad->hig, EINA_TRUE, EINA_FALSE); - elm_gengrid_multi_select_set(ad->hig, EINA_FALSE); - evas_object_smart_callback_add(ad->hig, "selected", _grid_click_paste, ad); -// evas_object_smart_callback_add(ad->hig, "longpressed", _grid_longpress, ad); - evas_object_size_hint_weight_set(ad->hig, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - - elm_gengrid_clear(ad->hig); - - gic.item_style = "default_grid"; - gic.func.label_get = NULL; - gic.func.content_get = _grid_icon_get; - gic.func.state_get = NULL; - gic.func.del = _grid_del; - -/* int i; - griditem_t *newgi; - - for (i = 0; i < N_IMAGES; i++) - { - clipdrawer_add_item(g_images_path[0], GI_IMAGE); - } - - clipdrawer_add_item("clipboard history", GI_TEXT);*/ - - evas_object_show (ad->hig); - -// for debugging, calc history pos -/* - Evas_Coord x, y, w, h; - Evas_Coord vx, vy, vw, vh; - - edje_object_part_geometry_get(elm_layout_edje_get(ad->ly_main),"imagehistory/list",&x,&y,&w,&h); - evas_object_geometry_get (ad->hig, &vx,&vy,&vw,&vh); - fprintf(stderr, "## x = %d, y = %d, w = %d, h = %d\n", x, y, w, h); - fprintf(stderr, "## vx = %d, vy = %d, vw = %d, vh = %d\n", vx, vy, vw, vh); -*/ - -// if (get_item_counts() != 0) -// clipdrawer_update_contents(ad); - - return 0; -} - -int clipdrawer_create_view(void *data) -{ - struct appdata *ad = data; - - clipdrawer_init(ad); - - // for debug - // at starting, showing app view - //clipdrawer_activate_view(ad); - - return 0; -} - -Eina_Bool _get_anim_pos(void *data, int *sp, int *ep) +static Eina_Bool _get_anim_pos(ClipdrawerData *cd, int *sp, int *ep) { if (!sp || !ep) return EINA_FALSE; - struct appdata *ad = data; - int angle = ad->o_degree; + int angle = cd->o_degree; int anim_start, anim_end; if (angle == 180) // reverse { - anim_start = -(ad->root_h - CLIPDRAWER_HEIGHT); + anim_start = -(cd->root_h - CLIPDRAWER_HEIGHT); anim_end = 0; } else if (angle == 90) // right rotate { - anim_start = ad->root_w; + anim_start = cd->root_w; anim_end = anim_start - CLIPDRAWER_HEIGHT_LANDSCAPE; } else if (angle == 270) // left rotate { - anim_start = -(ad->root_w - CLIPDRAWER_HEIGHT_LANDSCAPE); + anim_start = -(cd->root_w - CLIPDRAWER_HEIGHT_LANDSCAPE); anim_end = 0; } else // angle == 0 { - anim_start = ad->root_h; + anim_start = cd->root_h; anim_end = anim_start - CLIPDRAWER_HEIGHT; } @@ -689,13 +534,12 @@ Eina_Bool _get_anim_pos(void *data, int *sp, int *ep) return EINA_TRUE; } -Eina_Bool _do_anim_delta_pos(void *data, int sp, int ep, int ac, int *dp) +static Eina_Bool _do_anim_delta_pos(ClipdrawerData *cd, int sp, int ep, int ac, int *dp) { if (!dp) return EINA_FALSE; - struct appdata *ad = data; - int angle = ad->o_degree; + int angle = cd->o_degree; int delta; double posprop; posprop = 1.0*ac/ANIM_DURATION; @@ -703,22 +547,22 @@ Eina_Bool _do_anim_delta_pos(void *data, int sp, int ep, int ac, int *dp) if (angle == 180) // reverse { delta = (int)((ep-sp)*posprop); - evas_object_move(ad->win_main, 0, sp+delta); + evas_object_move(cd->main_win, 0, sp+delta); } else if (angle == 90) // right rotate { delta = (int)((ep-sp)*posprop); - evas_object_move(ad->win_main, sp+delta, 0); + evas_object_move(cd->main_win, sp+delta, 0); } else if (angle == 270) // left rotate { delta = (int)((ep-sp)*posprop); - evas_object_move(ad->win_main, sp+delta, 0); + evas_object_move(cd->main_win, sp+delta, 0); } else // angle == 0 { delta = (int)((sp-ep)*posprop); - evas_object_move(ad->win_main, 0, sp-delta); + evas_object_move(cd->main_win, 0, sp-delta); } *dp = delta; @@ -726,147 +570,110 @@ Eina_Bool _do_anim_delta_pos(void *data, int sp, int ep, int ac, int *dp) return EINA_TRUE; } -static void stop_animation(void *data) +static void stop_animation(AppData *ad) { - struct appdata *ad = data; - - ad->anim_status = STATUS_NONE; - if (anim_timer) + CALLED(); + ClipdrawerData *cd = ad->clipdrawer; + cd->anim_status = STATUS_NONE; + if (cd->anim_timer) { - ecore_timer_del(anim_timer); - anim_timer = NULL; + ecore_timer_del(cd->anim_timer); + cd->anim_timer = NULL; } - set_sliding_win_geometry(data); + set_sliding_win_geometry(cd); } -Eina_Bool anim_pos_calc_cb(void *data) +static Eina_Bool anim_pos_calc_cb(void *data) { - struct appdata *ad = data; - + AppData *ad = data; + ClipdrawerData *cd = ad->clipdrawer; int anim_start, anim_end, delta; - _get_anim_pos(ad, &anim_start, &anim_end); + _get_anim_pos(cd, &anim_start, &anim_end); - if (ad->anim_status == SHOW_ANIM) + if (cd->anim_status == SHOW_ANIM) { - if (ad->anim_count > ANIM_DURATION) + if (cd->anim_count > ANIM_DURATION) { - ad->anim_count = ANIM_DURATION; - stop_animation(data); + cd->anim_count = ANIM_DURATION; + stop_animation(ad); return EINA_FALSE; } - _do_anim_delta_pos(ad, anim_start, anim_end, ad->anim_count, &delta); - ad->anim_count++; + _do_anim_delta_pos(cd, anim_start, anim_end, cd->anim_count, &delta); + if (cd->anim_count == 1) + evas_object_show(cd->main_win); + cd->anim_count++; } - else if (ad->anim_status == HIDE_ANIM) + else if (cd->anim_status == HIDE_ANIM) { - if (ad->anim_count < 0) + if (cd->anim_count < 0) { - ad->anim_count = 0; - evas_object_hide(ad->win_main); - elm_win_lower(ad->win_main); - unset_transient_for(ad); - stop_animation(data); + cd->anim_count = 0; + evas_object_hide(cd->main_win); + elm_win_lower(cd->main_win); + unset_transient_for(cd->x_main_win, ad->x_active_win); + stop_animation(ad); return EINA_FALSE; } - _do_anim_delta_pos(ad, anim_start, anim_end, ad->anim_count, &delta); - ad->anim_count--; + _do_anim_delta_pos(cd, anim_start, anim_end, cd->anim_count, &delta); + cd->anim_count--; } else { - stop_animation(data); + stop_animation(ad); return EINA_FALSE; } return EINA_TRUE; } -Eina_Bool clipdrawer_anim_effect(void *data, anim_status_t atype) +static Eina_Bool clipdrawer_anim_effect(AppData *ad, AnimStatus atype) { - struct appdata *ad = data; - - if (atype == ad->anim_status) + CALLED(); + ClipdrawerData *cd = ad->clipdrawer; + if (atype == cd->anim_status) { DTRACE("Warning: Animation effect is already in progress. \n"); return EINA_FALSE; } - ad->anim_status = atype; - - if (anim_timer) - ecore_timer_del(anim_timer); + cd->anim_status = atype; - anim_timer = ecore_timer_add(ANIM_FLOPS, anim_pos_calc_cb, ad); + if (cd->anim_timer) + ecore_timer_del(cd->anim_timer); + cd->anim_timer = ecore_timer_add(ANIM_FLOPS, anim_pos_calc_cb, ad); return EINA_TRUE; } -void clipdrawer_activate_view(void *data) +void clipdrawer_activate_view(AppData* ad) { - struct appdata *ad = data; - - if (ad->win_main) - { - set_focus_for_app_window(ad->win_main, EINA_TRUE); - set_transient_for(ad); - ad->o_degree = get_active_window_degree(ad->active_win); - elm_win_rotation_set(ad->win_main, ad->o_degree); - set_rotation_to_clipdrawer(data); - evas_object_show(ad->win_main); - elm_win_activate(ad->win_main); - if (clipdrawer_anim_effect(ad, SHOW_ANIM)) - ad->windowshow = EINA_TRUE; + CALLED(); + ClipdrawerData *cd = ad->clipdrawer; + if (cd->main_win) + { + set_focus_for_app_window(cd->x_main_win, EINA_TRUE); + set_transient_for(cd->x_main_win, ad->x_active_win); + cd->o_degree = get_active_window_degree(ad->x_active_win); + elm_win_rotation_set(cd->main_win, cd->o_degree); + set_rotation_to_clipdrawer(cd); + // evas_object_show(cd->main_win); + elm_win_activate(cd->main_win); + // if (clipdrawer_anim_effect(ad, SHOW_ANIM)) + clipdrawer_anim_effect(ad, SHOW_ANIM); } } -void clipdrawer_lower_view(void *data) +void clipdrawer_lower_view(AppData* ad) { - struct appdata *ad = data; - - if (ad->win_main && ad->windowshow) - { - set_focus_for_app_window(ad->win_main, EINA_FALSE); - if (clipdrawer_anim_effect(ad, HIDE_ANIM)) - ad->windowshow = EINA_FALSE; - } -} - -void _change_gengrid_paste_textonly_mode(void *data) -{ - struct appdata *ad = data; - - griditem_t *ti = NULL; - - Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig); - - while (item) + CALLED(); + ClipdrawerData *cd = ad->clipdrawer; + if (cd->main_win && cd->anim_count) { - ti = elm_gengrid_item_data_get(item); - if ((ti->itype == GI_IMAGE) && (ti->ilayout)) - { - if (clipdrawer_paste_textonly_get(ad)) - edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,show,dim", "elm"); - else - edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,hide,dim", "elm"); - } - item = elm_gengrid_item_next_get(item); + set_focus_for_app_window(cd->x_main_win, EINA_FALSE); + // if (clipdrawer_anim_effect(ad, HIDE_ANIM)) + // ad->windowshow = EINA_FALSE; + clipdrawer_anim_effect(ad, HIDE_ANIM); } } - -void clipdrawer_paste_textonly_set(void *data, Eina_Bool textonly) -{ - struct appdata *ad = data; - textonly = !!textonly; - if (ad->pastetextonly != textonly) - ad->pastetextonly = textonly; - DTRACE("paste textonly mode = %d\n", textonly); - - _change_gengrid_paste_textonly_mode(ad); -} - -Eina_Bool clipdrawer_paste_textonly_get(void *data) -{ - struct appdata *ad = data; - return ad->pastetextonly; -} diff --git a/src/clipdrawer.h b/src/clipdrawer.h index 0135ffc..eb7fafd 100644 --- a/src/clipdrawer.h +++ b/src/clipdrawer.h @@ -15,34 +15,45 @@ * */ -#ifndef _clipdrawer_h_ -#define _clipdrawer_h_ +#ifndef _CLIPDRAWER_H_ +#define _CLIPDRAWER_H_ -#define CLIPDRAWER_HEIGHT 360 -#define CLIPDRAWER_HEIGHT_LANDSCAPE 228 +#include +#include -enum { - GI_TEXT = 0, - GI_IMAGE, - - GI_MAX_ITEMS, +typedef enum _AnimStatus AnimStatus; +enum _AnimStatus { + STATUS_NONE = 0, + SHOW_ANIM, + HIDE_ANIM }; -/* view maintains */ -int clipdrawer_init(void *data); -int clipdrawer_create_view(void *data); -void clipdrawer_activate_view(void *data); -//void clipdrawer_hide_view(void *data); -void clipdrawer_lower_view(void *data); +struct _ClipdrawerData { + Evas_Object *main_win; + Ecore_X_Window x_main_win; + Evas_Object *gengrid; + Evas_Object *main_layout; + Elm_Gengrid_Item_Class gic; + + int o_degree; -void set_rotation_to_clipdrawer(void *data); + int root_w; + int root_h; -const char* clipdrawer_get_plain_string_from_escaped(char *escstr); + Ecore_Event_Handler *keydown_handler; + Evas *evas; -char *clipdrawer_get_item_data(void *data, int pos); -int clipdrawer_add_item(char *idata, int type); + Ecore_Timer *anim_timer; + AnimStatus anim_status; + int anim_count; + Eina_Bool paste_text_only:1; +}; -void clipdrawer_paste_textonly_set(void *data, Eina_Bool textonly); -Eina_Bool clipdrawer_paste_textonly_get(void *data); +#include "cbhm.h" -#endif // _clipdrawer_h_ +void set_rotation_to_clipdrawer(ClipdrawerData *ad); +void clipdrawer_activate_view(AppData* ad); +void clipdrawer_lower_view(AppData* ad); +ClipdrawerData *init_clipdrawer(AppData *ad); +void depose_clipdrawer(ClipdrawerData *cd); +#endif // _CLIPDRAWER_H_ diff --git a/src/item_manager.c b/src/item_manager.c new file mode 100644 index 0000000..19c54df --- /dev/null +++ b/src/item_manager.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "item_manager.h" + +#define ITEM_CNT_MAX 12 + +static void item_free(CNP_ITEM *item) +{ + CALLED(); + if (!item) + { + DMSG("WRONG PARAMETER in %s\n", __func__); + return; + } + // remove gengrid + if (item->ad) + { + if (item->ad->draw_item_del) + item->ad->draw_item_del(item->ad, item); + if (item->ad->storage_item_del) + item->ad->storage_item_del(item->ad, item); + } + if (item->data) + FREE(item->data); + + if (item->ad->clip_selected_item == item) + item->ad->clip_selected_item = NULL; + FREE(item); +} + +CNP_ITEM *item_add_by_CNP_ITEM(AppData *ad, CNP_ITEM *item) +{ + if (!ad || !item) + { + DMSG("WRONG PARAMETER in %s, ad: 0x%x, item: 0x%x\n", __func__, ad, item); + return NULL; + } + item->ad = ad; + + ad->item_list = eina_list_prepend(ad->item_list, item); + if (ad && ad->draw_item_add) + ad->draw_item_add(ad, item); + if (ad && ad->storage_item_add) + ad->storage_item_add(ad, item); + + while (ITEM_CNT_MAX < eina_list_count(ad->item_list)) + { + CNP_ITEM *ditem = eina_list_nth(ad->item_list, ITEM_CNT_MAX); + + ad->item_list = eina_list_remove(ad->item_list, ditem); + item_free(ditem); + } + + return item; +} + +CNP_ITEM *item_add_by_data(AppData *ad, Ecore_X_Atom type, void *data, int len) +{ + if (!ad || !data) + { + DMSG("WRONG PARAMETER in %s\n", __func__); + return NULL; + } + CNP_ITEM *item; + item = CALLOC(1, sizeof(CNP_ITEM)); + if (!item) + return NULL; + item->type_index = atom_type_index_get(ad, type); + item->data = data; + item->len = len; + + item = item_add_by_CNP_ITEM(ad, item); + return item; +} + +CNP_ITEM *item_get_by_index(AppData *ad, int index) +{ + if (!ad || eina_list_count(ad->item_list) <= index || 0 > index) + { + DMSG("WRONG PARAMETER in %s\n", __func__); + return NULL; + } + CNP_ITEM *item; + item = eina_list_nth(ad->item_list, index); + return item; +} + +CNP_ITEM *item_get_by_data(AppData *ad, void *data) +{ + if (!ad || !data) + { + DMSG("WRONG PARAMETER in %s\n", __func__); + return NULL; + } + CNP_ITEM *item; + Eina_List *l; + EINA_LIST_FOREACH(ad->item_list, l, item) + { + if (item && item->data == data) + { + return item; + } + } + return NULL; +} + +CNP_ITEM *item_get_last(AppData *ad) +{ + if (!ad) + { + DMSG("WRONG PARAMETER in %s\n", __func__); + return NULL; + } + return eina_list_data_get(ad->item_list); +} + +void item_delete_by_CNP_ITEM(AppData *ad, CNP_ITEM *item) +{ + CALLED(); + if (!ad || !item) + { + DMSG("WRONG PARAMETER in %s\n", __func__); + return; + } + DMSG("item: 0x%x, item->gitem: 0x%x\n", item, item->gitem); + ad->item_list = eina_list_remove(ad->item_list, item); + item_free(item); +} + +void item_delete_by_data(AppData *ad, void *data) +{ + CALLED(); + if (!ad || !data) + { + DMSG("WRONG PARAMETER in %s\n", __func__); + return; + } + CNP_ITEM *item; + item = item_get_by_data(ad, data); + item_delete_by_CNP_ITEM(ad, item); +} + +void item_delete_by_index(AppData *ad, int index) +{ + CALLED(); + if (!ad || eina_list_count(ad->item_list) <= index || 0 > index) + { + DMSG("WRONG PARAMETER in %s\n", __func__); + return; + } + CNP_ITEM *item; + item = item_get_by_index(ad, index); + item_delete_by_CNP_ITEM(ad, item); +} + +void item_clear_all(AppData *ad) +{ + CALLED(); + while(ad->item_list) + { + CNP_ITEM *item = eina_list_data_get(ad->item_list); + ad->item_list = eina_list_remove(ad->item_list, item); + if (item) + item_free(item); + } +} + +int item_count_get(AppData *ad) +{ + return eina_list_count(ad->item_list); +} diff --git a/src/item_manager.h b/src/item_manager.h new file mode 100644 index 0000000..1c8210c --- /dev/null +++ b/src/item_manager.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _ITEM_MANAGER_H_ +#define _ITEM_MANAGER_H_ + +#include "cbhm.h" + +struct _CNP_ITEM { + int type_index; + void *data; + size_t len; + + Elm_Gengrid_Item *gitem; + Evas_Object *layout; + AppData *ad; +}; + +CNP_ITEM *item_add_by_CNP_ITEM(AppData *ad, CNP_ITEM *item); +CNP_ITEM *item_add_by_data(AppData *ad, Ecore_X_Atom type, void *data, int len); + +CNP_ITEM *item_get_by_index(AppData *ad, int index); +CNP_ITEM *item_get_by_data(AppData *ad, void *data); +CNP_ITEM *item_get_last(AppData *ad); + +void item_delete_by_CNP_ITEM(AppData *ad, CNP_ITEM *item); +void item_delete_by_data(AppData *ad, void *data); +void item_delete_by_index(AppData *ad, int index); +void item_clear_all(AppData *ad); +int item_count_get(AppData *ad); + +#endif /*_ITEM_MANAGER_H_*/ + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..d088d4a --- /dev/null +++ b/src/main.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#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); +} diff --git a/src/cbhm_main.c b/src/old/cbhm_main.c similarity index 100% rename from src/cbhm_main.c rename to src/old/cbhm_main.c diff --git a/src/cbhm_main.h b/src/old/cbhm_main.h similarity index 100% rename from src/cbhm_main.h rename to src/old/cbhm_main.h diff --git a/src/old/clipdrawer.c b/src/old/clipdrawer.c new file mode 100644 index 0000000..6da8a9b --- /dev/null +++ b/src/old/clipdrawer.c @@ -0,0 +1,872 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "common.h" +#include "cbhm_main.h" +#include "storage.h" +#include "xcnphandler.h" +#include "clipdrawer.h" + +#define DELETE_ICON_PATH "/usr/share/cbhm/icons/05_delete.png" +#define IM "/usr/share/cbhm/icons/" +static const char *g_images_path[] = { + IM"cbhm_default_img.png", +}; +#define N_IMAGES (1) + +#define GRID_ITEM_SPACE_W 6 +#define GRID_ITEM_SINGLE_W 185 +#define GRID_ITEM_SINGLE_H 161 +#define GRID_ITEM_W (GRID_ITEM_SINGLE_W+(GRID_ITEM_SPACE_W*2)) +#define GRID_ITEM_H (GRID_ITEM_SINGLE_H) +#define GRID_IMAGE_LIMIT_W 91 +#define GRID_IMAGE_LIMIT_H 113 + +#define ANIM_DURATION 30 // 1 seconds +#define ANIM_FLOPS (0.5/30) + +// gic should live at gengrid callback functions +Elm_Gengrid_Item_Class gic; +static Ecore_Timer *anim_timer = NULL; + +typedef struct tag_griditem +{ + int itype; + Elm_Gengrid_Item *item; + const char *ipathdata; + Eina_Strbuf *istrdata; + Evas_Object *delbtn; + Evas_Object *ilayout; +} griditem_t; + +const char * +remove_tags(const char *p) +{ + char *q,*ret; + int i; + if (!p) return NULL; + + q = malloc(strlen(p) + 1); + if (!q) return NULL; + ret = q; + + while (*p) + { + if ((*p != '<')) *q++ = *p++; + else if (*p == '<') + { + if ((p[1] == 'b') && (p[2] == 'r') && + ((p[3] == ' ') || (p[3] == '/') || (p[3] == '>'))) + *q++ = '\n'; + while ((*p) && (*p != '>')) p++; + p++; + } + } + *q = 0; + + return ret; +} + +const char* clipdrawer_get_plain_string_from_escaped(char *escstr) +{ + /* NOTE : return string should be freed */ + return remove_tags(escstr); +} + +static char* _get_string_for_entry(char *str) +{ + if (!str) + return NULL; + + Eina_Strbuf *strbuf = eina_strbuf_new(); + if (!strbuf) + return strdup(str); + eina_strbuf_prepend(strbuf, ""); + + 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, "
"); + 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, "", src); + DTRACE("src str: %s \n", src); + free(src); + } + trail = endtag + 1; + } + + char *ret = eina_strbuf_string_steal(strbuf); + eina_strbuf_free(strbuf); + DTRACE("result str: %s \n", ret); + return ret; +} + +static void _grid_del_response_cb(void *data, Evas_Object *obj, void *event_info) +{ + Elm_Gengrid_Item *it = (Elm_Gengrid_Item *)data; + evas_object_del(obj); + + if((int)event_info == ELM_POPUP_RESPONSE_OK) + { + struct appdata *ad = g_get_main_appdata(); + elm_gengrid_item_del(it); + ad->hicount--; + if (ad->hicount < 0) + { + int cnt = 0; + Elm_Gengrid_Item *trail = elm_gengrid_first_item_get(ad->hig); + while(trail) + { + cnt++; + elm_gengrid_item_next_get(trail); + } + ad->hicount = cnt; + DTRACE("ERR: cbhm history cnt < 0, gengrid item cnt: %d\n", cnt); + } + } +} + +static void _grid_click_delete(void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = data; +} + +static void +_grid_item_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + struct appdata *ad = g_get_main_appdata(); + + if (ad->anim_status != STATUS_NONE) + return; + + Elm_Gengrid_Item *sgobj = NULL; + sgobj = elm_gengrid_selected_item_get(ad->hig); + griditem_t *ti = NULL; + ti = elm_gengrid_item_data_get(sgobj); + + #define EDJE_DELBTN_PART_PREFIX "delbtn" + if (strncmp(source, EDJE_DELBTN_PART_PREFIX, strlen(EDJE_DELBTN_PART_PREFIX))) + { + if (!sgobj || !ti) + { + DTRACE("ERR: cbhm can't get the selected image\n"); + return; + } + + elm_gengrid_item_selected_set(sgobj, EINA_FALSE); + + if (ti->itype == GI_TEXT) + { + char *p = strdup(eina_strbuf_string_get(ti->istrdata)); + + elm_selection_set(1, ad->hig, /*ELM_SEL_FORMAT_HTML*/0x10, p); + } + else //if (ti->itype == GI_IMAGE) + { + if (!clipdrawer_paste_textonly_get(ad)) + { + int len = strlen(ti->ipathdata); + char *p = malloc(len + 10); + snprintf(p,len+10, "file:///%s", ti->ipathdata); + + elm_selection_set(/*secondary*/1, ad->hig,/*ELM_SEL_FORMAT_IMAGE*/4,p); + } + else + { + DTRACE("ERR: cbhm image paste mode is false\n"); + } + } + return; + } + + if (!sgobj) + { + DTRACE("ERR: cbhm can't get the selected item\n"); + return; + } + + elm_gengrid_item_selected_set(sgobj, EINA_FALSE); + + Evas_Object *popup = elm_popup_add(ad->win_main); + elm_popup_timeout_set(popup, 5); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_popup_desc_set(popup, "Are you sure delete this?"); + elm_popup_buttons_add(popup, 2, + "Yes", ELM_POPUP_RESPONSE_OK, + "No", ELM_POPUP_RESPONSE_CANCEL, + NULL); + evas_object_smart_callback_add(popup, "response", _grid_del_response_cb, sgobj); + evas_object_show(popup); +} + +Evas_Object* _grid_icon_get(const void *data, Evas_Object *obj, const char *part) +{ + griditem_t *ti = (griditem_t *)data; + + if (!strcmp(part, "elm.swallow.icon")) + { + if (ti->itype == GI_TEXT) + { + Evas_Object *layout = elm_layout_add (obj); + elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout"); + edje_object_signal_callback_add(elm_layout_edje_get(layout), + "mouse,up,1", "*", _grid_item_ly_clicked, data); + Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(obj)); + evas_object_resize(rect, GRID_ITEM_W, GRID_ITEM_H); + evas_object_color_set(rect, 242, 233, 183, 255); + evas_object_show(rect); + elm_layout_content_set(layout, "elm.swallow.icon", rect); + + // FIXME: add string length check + Evas_Object *ientry = elm_entry_add(obj); + evas_object_size_hint_weight_set(ientry, 0, 0); + Eina_Strbuf *strent = NULL; + char *strdata = eina_strbuf_string_get(ti->istrdata); + int i, skipflag, strcnt; + + strent = eina_strbuf_new(); + skipflag = 0; + strcnt = 0; + for (i = 0; i < eina_strbuf_length_get(ti->istrdata); i++) + { + switch (strdata[i]) + { + case '>': + skipflag = 0; + break; + case '<': + skipflag = 1; + break; + default: + if (!skipflag) + strcnt++; + break; + } + if (strcnt > 100) + break; + } + eina_strbuf_append_n(strent, strdata, i); + eina_strbuf_replace_all(strent, " absize=240x180 ", " absize=52x39 "); + if (strcnt > 100) + eina_strbuf_append(strent, "..."); + elm_entry_scrollable_set(ientry, EINA_TRUE); + char *entry_text = eina_strbuf_string_get(strent); + entry_text = _get_string_for_entry(entry_text); + if (entry_text) + { + elm_object_part_text_set(ientry, NULL, entry_text); + free(entry_text); + } + elm_entry_editable_set(ientry, EINA_FALSE); + elm_entry_context_menu_disabled_set(ientry, EINA_TRUE); + evas_object_show(ientry); + elm_layout_content_set(layout, "elm.swallow.inner", ientry); + + eina_strbuf_free(strent); + + return layout; + } + else// if (ti->itype == GI_IMAGE) + { + Evas_Object *layout = elm_layout_add (obj); + elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout"); + edje_object_signal_callback_add(elm_layout_edje_get(layout), + "mouse,up,1", "*", _grid_item_ly_clicked, data); + + Evas_Object *sicon; + sicon = evas_object_image_add(evas_object_evas_get(obj)); + evas_object_image_load_size_set(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H); + evas_object_image_file_set(sicon, ti->ipathdata, NULL); + evas_object_image_fill_set(sicon, 0, 0, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H); + evas_object_resize(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H); + elm_layout_content_set(layout, "elm.swallow.icon", sicon); + + struct appdata *ad = g_get_main_appdata(); + + if (clipdrawer_paste_textonly_get(ad)) + edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,show,dim", "elm"); + else + edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,hide,dim", "elm"); + + ti->ilayout = layout; + return layout; + } + } + + return NULL; +} + +static void _grid_longpress(void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = data; +} + +static void _grid_click_paste(void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = data; + if (ad->anim_status != STATUS_NONE) + return; + + Elm_Gengrid_Item *sgobj = NULL; + sgobj = elm_gengrid_selected_item_get(ad->hig); + griditem_t *ti = NULL; + ti = elm_gengrid_item_data_get(sgobj); +} + +void _grid_del(const void *data, Evas_Object *obj) +{ + griditem_t *ti = (griditem_t *)data; + if (ti->itype == GI_TEXT) + eina_strbuf_free(ti->istrdata); + else + eina_stringshare_del(ti->ipathdata); + free(ti); +} + +char* clipdrawer_get_item_data(void *data, int pos) +{ + struct appdata *ad = data; + griditem_t *ti = NULL; + griditem_t *newgi = NULL; + int count = 0; + + if (pos < 0 || pos > ad->hicount) + return NULL; + + Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig); + while (item) + { + ti = elm_gengrid_item_data_get(item); + if (count == pos) + { + if (!ti) + break; + if (ti->itype == GI_TEXT) + return (char*)eina_strbuf_string_get(ti->istrdata); + else + return ti->ipathdata; + } + count++; + item = elm_gengrid_item_next_get(item); + } + + return NULL; +} + +// FIXME: how to remove calling g_get_main_appdata()? +// it's mainly used at 'clipdrawer_image_item' +int clipdrawer_add_item(char *idata, int type) +{ + struct appdata *ad = g_get_main_appdata(); + griditem_t *newgi = NULL; + + newgi = malloc(sizeof(griditem_t)); + newgi->itype = type; + + fprintf(stderr, "## add - %d : %s\n", newgi->itype, idata); + if (type == GI_TEXT) + { + newgi->istrdata = eina_strbuf_new(); + eina_strbuf_append(newgi->istrdata, idata); + } + else //if (type == GI_IMAGE) + { + Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig); + griditem_t *ti = NULL; + + if (!check_regular_file(idata)) + { + DTRACE("Error : it isn't normal file = %s\n", idata); + return -1; + } + + while (item) + { + ti = elm_gengrid_item_data_get(item); + if ((ti->itype == type) && !strcmp(ti->ipathdata, idata)) + { + DTRACE("Error : duplicated file path = %s\n", idata); + return -1; + } + item = elm_gengrid_item_next_get(item); + } + newgi->ipathdata = eina_stringshare_add(idata); + } + + if (ad->hicount >= HISTORY_QUEUE_MAX_ITEMS) + { + ad->hicount--; + // FIXME: add routine that is removing its elements + elm_gengrid_item_del(elm_gengrid_last_item_get(ad->hig)); + } + + ad->hicount++; + newgi->item = elm_gengrid_item_prepend(ad->hig, &gic, newgi, NULL, NULL); + + return TRUE; +} + +static void +clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + struct appdata *ad = data; + + if (ad->anim_status != STATUS_NONE) + return; + + #define EDJE_CLOSE_PART_PREFIX "background/close" + if (!strncmp(source, EDJE_CLOSE_PART_PREFIX, strlen(EDJE_CLOSE_PART_PREFIX))) + { + clipdrawer_lower_view(ad); + } +} + +static void set_sliding_win_geometry(void *data) +{ + struct appdata *ad = data; + Ecore_X_Window zone, xwin; + Evas_Coord x, y, w, h; + xwin = elm_win_xwindow_get(ad->win_main); + zone = ecore_x_e_illume_zone_get(xwin); + DTRACE("[CBHM] xwin:%x, zone:%x\n", xwin, zone); + +// ecore_evas_geometry_get(ecore_evas_ecore_evas_get(evas_object_evas_get(ad->win_main)), &x, &y, &w, &h); + + if (ad->o_degree == 90 || ad->o_degree == 270) + { + h = ad->anim_count * CLIPDRAWER_HEIGHT_LANDSCAPE / ANIM_DURATION; + x = 0; + y = ad->root_w - h; + w = ad->root_h; + } + else + { + h = ad->anim_count * CLIPDRAWER_HEIGHT / ANIM_DURATION; + x = 0; + y = ad->root_h - h; + w = ad->root_w; + } + + if (!h) + w = 0; + + DTRACE("[CBHM] change degree geometry... (%d, %d, %d x %d)\n", x, y, w, h); + ecore_x_e_illume_sliding_win_geometry_set(zone, x, y, w, h); + ecore_x_e_illume_sliding_win_state_set(zone, ad->anim_count != 0); +} + +void set_rotation_to_clipdrawer(void *data) +{ + struct appdata *ad = data; + int angle = ad->o_degree; + int x, y, w, h; + + if (angle == 180) // reverse + { + h = CLIPDRAWER_HEIGHT; + x = 0; + y = 0; + w = ad->root_w; + } + else if (angle == 90) // right rotate + { + h = CLIPDRAWER_HEIGHT_LANDSCAPE; + x = ad->root_w - h; + y = 0; + w = ad->root_h; + } + else if (angle == 270) // left rotate + { + h = CLIPDRAWER_HEIGHT_LANDSCAPE; + x = 0; + y = 0; + w = ad->root_h; + } + else // angle == 0 + { + h = CLIPDRAWER_HEIGHT; + x = 0; + y = ad->root_h - h; + w = ad->root_w; + } + + evas_object_resize(ad->win_main, w, h); + evas_object_move(ad->win_main, x, y); + if (ad->anim_count == ANIM_DURATION) + set_sliding_win_geometry(data); +} + +int clipdrawer_init(void *data) +{ + struct appdata *ad = data; + double cdy, cdw; + + ad->windowshow = EINA_FALSE; + ad->hicount = 0; + ad->pastetextonly = EINA_TRUE; + ad->anim_status = STATUS_NONE; + ad->anim_count = 0; + + // for elm_check + elm_theme_extension_add(NULL, APP_EDJ_FILE); + + edje_object_signal_callback_add(elm_layout_edje_get(ad->ly_main), + "mouse,up,1", "*", clipdrawer_ly_clicked, ad); + + ad->hig = NULL; + ad->hig = elm_gengrid_add(ad->win_main); + elm_layout_content_set(ad->ly_main, "historyitems", ad->hig); + elm_gengrid_item_size_set(ad->hig, GRID_ITEM_W+2, GRID_ITEM_H); + elm_gengrid_align_set(ad->hig, 0.5, 0.5); + elm_gengrid_horizontal_set(ad->hig, EINA_TRUE); + elm_gengrid_bounce_set(ad->hig, EINA_TRUE, EINA_FALSE); + elm_gengrid_multi_select_set(ad->hig, EINA_FALSE); + evas_object_smart_callback_add(ad->hig, "selected", _grid_click_paste, ad); +// evas_object_smart_callback_add(ad->hig, "longpressed", _grid_longpress, ad); + evas_object_size_hint_weight_set(ad->hig, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + + elm_gengrid_clear(ad->hig); + + gic.item_style = "default_grid"; + gic.func.label_get = NULL; + gic.func.content_get = _grid_icon_get; + gic.func.state_get = NULL; + gic.func.del = _grid_del; + +/* int i; + griditem_t *newgi; + + for (i = 0; i < N_IMAGES; i++) + { + clipdrawer_add_item(g_images_path[0], GI_IMAGE); + } + + clipdrawer_add_item("clipboard history", GI_TEXT);*/ + + evas_object_show (ad->hig); + +// for debugging, calc history pos +/* + Evas_Coord x, y, w, h; + Evas_Coord vx, vy, vw, vh; + + edje_object_part_geometry_get(elm_layout_edje_get(ad->ly_main),"imagehistory/list",&x,&y,&w,&h); + evas_object_geometry_get (ad->hig, &vx,&vy,&vw,&vh); + fprintf(stderr, "## x = %d, y = %d, w = %d, h = %d\n", x, y, w, h); + fprintf(stderr, "## vx = %d, vy = %d, vw = %d, vh = %d\n", vx, vy, vw, vh); +*/ + +// if (get_item_counts() != 0) +// clipdrawer_update_contents(ad); + + return 0; +} + +int clipdrawer_create_view(void *data) +{ + struct appdata *ad = data; + + clipdrawer_init(ad); + + // for debug + // at starting, showing app view + //clipdrawer_activate_view(ad); + + return 0; +} + +Eina_Bool _get_anim_pos(void *data, int *sp, int *ep) +{ + if (!sp || !ep) + return EINA_FALSE; + + struct appdata *ad = data; + int angle = ad->o_degree; + int anim_start, anim_end; + + if (angle == 180) // reverse + { + anim_start = -(ad->root_h - CLIPDRAWER_HEIGHT); + anim_end = 0; + } + else if (angle == 90) // right rotate + { + anim_start = ad->root_w; + anim_end = anim_start - CLIPDRAWER_HEIGHT_LANDSCAPE; + } + else if (angle == 270) // left rotate + { + anim_start = -(ad->root_w - CLIPDRAWER_HEIGHT_LANDSCAPE); + anim_end = 0; + } + else // angle == 0 + { + anim_start = ad->root_h; + anim_end = anim_start - CLIPDRAWER_HEIGHT; + } + + *sp = anim_start; + *ep = anim_end; + return EINA_TRUE; +} + +Eina_Bool _do_anim_delta_pos(void *data, int sp, int ep, int ac, int *dp) +{ + if (!dp) + return EINA_FALSE; + + struct appdata *ad = data; + int angle = ad->o_degree; + int delta; + double posprop; + posprop = 1.0*ac/ANIM_DURATION; + + if (angle == 180) // reverse + { + delta = (int)((ep-sp)*posprop); + evas_object_move(ad->win_main, 0, sp+delta); + } + else if (angle == 90) // right rotate + { + delta = (int)((ep-sp)*posprop); + evas_object_move(ad->win_main, sp+delta, 0); + } + else if (angle == 270) // left rotate + { + delta = (int)((ep-sp)*posprop); + evas_object_move(ad->win_main, sp+delta, 0); + } + else // angle == 0 + { + delta = (int)((sp-ep)*posprop); + evas_object_move(ad->win_main, 0, sp-delta); + } + + *dp = delta; + + return EINA_TRUE; +} + +static void stop_animation(void *data) +{ + struct appdata *ad = data; + + ad->anim_status = STATUS_NONE; + if (anim_timer) + { + ecore_timer_del(anim_timer); + anim_timer = NULL; + } + + set_sliding_win_geometry(data); +} + +Eina_Bool anim_pos_calc_cb(void *data) +{ + struct appdata *ad = data; + + int anim_start, anim_end, delta; + + _get_anim_pos(ad, &anim_start, &anim_end); + + if (ad->anim_status == SHOW_ANIM) + { + if (ad->anim_count > ANIM_DURATION) + { + ad->anim_count = ANIM_DURATION; + stop_animation(data); + return EINA_FALSE; + } + _do_anim_delta_pos(ad, anim_start, anim_end, ad->anim_count, &delta); + ad->anim_count++; + } + else if (ad->anim_status == HIDE_ANIM) + { + if (ad->anim_count < 0) + { + ad->anim_count = 0; + evas_object_hide(ad->win_main); + elm_win_lower(ad->win_main); + unset_transient_for(ad); + stop_animation(data); + return EINA_FALSE; + } + _do_anim_delta_pos(ad, anim_start, anim_end, ad->anim_count, &delta); + ad->anim_count--; + } + else + { + stop_animation(data); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +Eina_Bool clipdrawer_anim_effect(void *data, anim_status_t atype) +{ + struct appdata *ad = data; + + if (atype == ad->anim_status) + { + DTRACE("Warning: Animation effect is already in progress. \n"); + return EINA_FALSE; + } + + ad->anim_status = atype; + + if (anim_timer) + ecore_timer_del(anim_timer); + + anim_timer = ecore_timer_add(ANIM_FLOPS, anim_pos_calc_cb, ad); + + return EINA_TRUE; +} + +void clipdrawer_activate_view(void *data) +{ + struct appdata *ad = data; + + if (ad->win_main) + { + set_focus_for_app_window(ad->win_main, EINA_TRUE); + set_transient_for(ad); + ad->o_degree = get_active_window_degree(ad->active_win); + elm_win_rotation_set(ad->win_main, ad->o_degree); + set_rotation_to_clipdrawer(data); + evas_object_show(ad->win_main); + elm_win_activate(ad->win_main); + if (clipdrawer_anim_effect(ad, SHOW_ANIM)) + ad->windowshow = EINA_TRUE; + } +} + +void clipdrawer_lower_view(void *data) +{ + struct appdata *ad = data; + + if (ad->win_main && ad->windowshow) + { + set_focus_for_app_window(ad->win_main, EINA_FALSE); + if (clipdrawer_anim_effect(ad, HIDE_ANIM)) + ad->windowshow = EINA_FALSE; + } +} + +void _change_gengrid_paste_textonly_mode(void *data) +{ + struct appdata *ad = data; + + griditem_t *ti = NULL; + + Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig); + + while (item) + { + ti = elm_gengrid_item_data_get(item); + if ((ti->itype == GI_IMAGE) && (ti->ilayout)) + { + if (clipdrawer_paste_textonly_get(ad)) + edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,show,dim", "elm"); + else + edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,hide,dim", "elm"); + } + item = elm_gengrid_item_next_get(item); + } +} + +void clipdrawer_paste_textonly_set(void *data, Eina_Bool textonly) +{ + struct appdata *ad = data; + textonly = !!textonly; + if (ad->pastetextonly != textonly) + ad->pastetextonly = textonly; + DTRACE("paste textonly mode = %d\n", textonly); + + _change_gengrid_paste_textonly_mode(ad); +} + +Eina_Bool clipdrawer_paste_textonly_get(void *data) +{ + struct appdata *ad = data; + return ad->pastetextonly; +} diff --git a/src/old/clipdrawer.h b/src/old/clipdrawer.h new file mode 100644 index 0000000..0135ffc --- /dev/null +++ b/src/old/clipdrawer.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _clipdrawer_h_ +#define _clipdrawer_h_ + +#define CLIPDRAWER_HEIGHT 360 +#define CLIPDRAWER_HEIGHT_LANDSCAPE 228 + +enum { + GI_TEXT = 0, + GI_IMAGE, + + GI_MAX_ITEMS, +}; + +/* view maintains */ +int clipdrawer_init(void *data); +int clipdrawer_create_view(void *data); +void clipdrawer_activate_view(void *data); +//void clipdrawer_hide_view(void *data); +void clipdrawer_lower_view(void *data); + +void set_rotation_to_clipdrawer(void *data); + +const char* clipdrawer_get_plain_string_from_escaped(char *escstr); + +char *clipdrawer_get_item_data(void *data, int pos); +int clipdrawer_add_item(char *idata, int type); + +void clipdrawer_paste_textonly_set(void *data, Eina_Bool textonly); +Eina_Bool clipdrawer_paste_textonly_get(void *data); + +#endif // _clipdrawer_h_ diff --git a/src/common.h b/src/old/common.h similarity index 100% rename from src/common.h rename to src/old/common.h diff --git a/src/old/scrcapture.c b/src/old/scrcapture.c new file mode 100644 index 0000000..d535200 --- /dev/null +++ b/src/old/scrcapture.c @@ -0,0 +1,768 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "common.h" +#include "cbhm_main.h" +#include "xcnphandler.h" +#include "scrcapture.h" +#include "clipdrawer.h" + +#include +#include + +#include +#include +#include +#include + +//#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 +#include +#include +#include + +#include +#include +#include +#include +#include + +static int svi_handle = -1; +static Eina_Bool g_shot = EINA_FALSE; +static XImage *ximage; +static XShmSegmentInfo x_shm_info; +static char *rot_buffer; + + +typedef struct tag_captureimginfo +{ + char filename[256]; + Evas_Object *eo; + char *imgdata; +} captureimginfo_t; + +static const char *createScreenShotSW(Display *d, int width, int height); +void releaseScreenShotSW(Display *d, const char * ss); +static Eina_Bool get_image_filename_with_date(char *dstr) +{ + time_t tim = time(NULL); + struct tm *now = localtime(&tim); + struct timeval tv; + gettimeofday(&tv, NULL); + sprintf(dstr, "%s/screen-%d%02d%02d%02d%02d%02d%0ld%s", + IMAGE_SAVE_DIR, + now->tm_year+1900, now->tm_mon+1, now->tm_mday, + now->tm_hour, now->tm_min, + now->tm_sec, tv.tv_usec, + IMAGE_SAVE_FILE_TYPE); + return EINA_TRUE; +} + + +static void _play_capture_sound() +{ + int ret = SVI_ERROR; + + if (svi_handle != -1) + ret = svi_play(svi_handle, SVI_VIB_OPERATION_SHUTTER, SVI_SND_OPERATION_SCRCAPTURE); + + if (ret != SVI_SUCCESS) + { + DTRACE("play file failed\n"); + } + else + { + DTRACE("play file success\n"); + } +} + +static Eina_Bool hide_small_popup(void *data) +{ + struct appdata *ad = data; + ad->popup_timer = NULL; + evas_object_hide(ad->small_popup); + return ECORE_CALLBACK_CANCEL; +} + +static void show_small_popup(struct appdata *ad, char* msg) +{ + if (!ad->small_popup) + ad->small_popup = elm_tickernoti_add(NULL); + if (!ad->small_win) + ad->small_win = elm_tickernoti_win_get(ad->small_popup); + + elm_object_style_set(ad->small_popup, "info"); + elm_tickernoti_label_set(ad->small_popup, msg); + elm_tickernoti_orientation_set(ad->small_popup, ELM_TICKERNOTI_ORIENT_BOTTOM); + evas_object_show(ad->small_popup); + ad->popup_timer = ecore_timer_add(2, hide_small_popup, ad); +} + +static void play_screen_capture_effect() +{ + struct appdata *ad = g_get_main_appdata(); + show_small_popup(ad, "Screen capture success"); + Ecore_X_Display *disp = ecore_x_display_get(); + Ecore_X_Window root_win = ecore_x_window_root_first_get(); + DTRACE("disp: 0x%x, root_win: 0x%x\n", disp, root_win); + utilx_show_capture_effect(disp, root_win); + _play_capture_sound(); +} + +static Eina_Bool _scrcapture_capture_postprocess(void* data) +{ + captureimginfo_t *capimginfo = data; + + DTIME("start capture postprocess - %s\n", capimginfo->filename); + + if (!evas_object_image_save(capimginfo->eo, capimginfo->filename, NULL, "compress=1")) + { + DTRACE("screen capture save fail\n"); + g_shot = EINA_FALSE; + return EINA_FALSE; + } + + DTIME("end capture postprocess - %s\n", capimginfo->filename); + + char *imgpath = NULL; + imgpath = malloc(strlen(capimginfo->filename)+strlen("file://")+2); + snprintf(imgpath, strlen(capimginfo->filename)+strlen("file://")+1, + "%s%s", "file://", capimginfo->filename); + DTRACE("add to image history = %s\n", imgpath+strlen("file://")); + clipdrawer_add_item(imgpath+strlen("file://"), GI_IMAGE); + free(imgpath); + + evas_object_del(capimginfo->eo); + free(capimginfo->imgdata); + free(capimginfo); + play_screen_capture_effect(); + DTIME("end current capture\n"); + + g_shot = EINA_FALSE; + + return EINA_FALSE; +} + +Eina_Bool capture_current_screen(void *data) +{ + struct appdata *ad = data; + if (!utilx_get_screen_capture(XOpenDisplay(NULL))) + { + show_small_popup(ad, "Screen capture disabled"); + DTRACE("utilx_get_screen_capture: disable\n"); + return EINA_FALSE; + } + else + DTRACE("utilx_get_screen_capture: enable\n"); + + if (g_shot) + { + DTRACE("too early to capture current screen\n"); + return EINA_FALSE; + } + g_shot = EINA_TRUE; + + DTIME("start current capture\n"); + + captureimginfo_t *capimginfo = NULL; + capimginfo = malloc(sizeof(captureimginfo_t) * 1); + get_image_filename_with_date(capimginfo->filename); + DTRACE("capture current screen\n"); + + int width, height; + width = ad->root_w; + height = ad->root_h; + capimginfo->imgdata = malloc(sizeof(char) * (width*height*4) + 1); + capimginfo->eo = evas_object_image_add(ad->evas); + + char *scrimage = NULL; + scrimage = createScreenShotSW(ecore_x_display_get(), width, height); + if (scrimage) + memcpy(capimginfo->imgdata, scrimage, width*height*4); + releaseScreenShotSW(ecore_x_display_get(), scrimage); + + if (scrimage == NULL || capimginfo->eo == NULL || capimginfo->imgdata == NULL) + { + DTRACE("screen capture fail\n"); + free(capimginfo->imgdata); + if (capimginfo->eo) + evas_object_del(capimginfo->eo); + free(capimginfo); + g_shot = EINA_FALSE; + return EINA_FALSE; + } + + DTRACE("screen capture prepared\n"); + + evas_object_image_data_set(capimginfo->eo, NULL); + evas_object_image_size_set(capimginfo->eo, width, height); + evas_object_image_data_set(capimginfo->eo, capimginfo->imgdata); + evas_object_image_data_update_add(capimginfo->eo, 0, 0, width, height); + evas_object_resize(capimginfo->eo, width, height); + + ecore_idler_add(_scrcapture_capture_postprocess, capimginfo); + + return EINA_TRUE; +} + +static Eina_Bool scrcapture_keydown_cb(void *data, int type, void *event) +{ + struct appdata *ad = data; + Ecore_Event_Key *ev = event; + + if (!strcmp(ev->keyname, KEY_END)) + clipdrawer_lower_view(ad); + + return ECORE_CALLBACK_PASS_ON; +} + +int init_scrcapture(void *data) +{ + struct appdata *ad = data; + + int result = 0; + + /* Key Grab */ +// Ecore_X_Display *xdisp = ecore_x_display_get(); +// Ecore_X_Window xwin = (Ecore_X_Window)ecore_evas_window_get(ecore_evas_ecore_evas_get(ad->evas)); + + ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, scrcapture_keydown_cb, ad); + + if (svi_init(&svi_handle) != SVI_SUCCESS) + { + DTRACE("svi init failed\n"); + svi_handle = -1; + return -1; + } + + return 0; +} + +void close_scrcapture(void *data) +{ + struct appdata *ad = data; + +// Ecore_X_Display *xdisp = ecore_x_display_get(); +// Ecore_X_Window xwin = (Ecore_X_Window)ecore_evas_window_get(ecore_evas_ecore_evas_get(ad->evas)); + + if (svi_handle != -1) + svi_fini(svi_handle); + if (ad->small_popup) + evas_object_del(ad->small_popup); + if (ad->small_win) + evas_object_del(ad->small_win); +} + +static int get_window_attribute(Window id, int *depth, Visual **visual, int *width, int *height) +{ +// assert(id); + XWindowAttributes attr; + + DTRACE("XGetWindowAttributes\n"); + if (!XGetWindowAttributes(ecore_x_display_get(), id, &attr)) + { + return -1; + } + + if (attr.map_state == IsViewable && attr.class == InputOutput) + { + *depth = attr.depth; + *width = attr.width; + *height= attr.height; + *visual= attr.visual; + } + + return 0; +} + +static Window _get_parent_window( Window id ) +{ + Window root; + Window parent; + Window* children; + unsigned int num; + + DTRACE("XQeuryTree\n"); + + if (!XQueryTree(ecore_x_display_get(), id, &root, &parent, &children, &num)) + { + return 0; + } + + if (children) + { + DTRACE("XFree\n"); + XFree(children); + } + + return parent; +} + +static Window find_capture_available_window( Window id, Visual** visual, int* depth, int* width, int* height) +{ + XWindowAttributes attr; + Window parent = id; + Window orig_id = id; + + if (id == 0) + { + return (Window) -1; + } + + do + { + id = parent; + DTRACE("find_capture - XGetWindowAttributes\n"); + + if (!XGetWindowAttributes(ecore_x_display_get(), id, &attr)) + { + return (Window) -1; + } + + parent = _get_parent_window( id ); + + if (attr.map_state == IsViewable + && attr.override_redirect == True + && attr.class == InputOutput && parent == attr.root ) + { + *depth = attr.depth; + *width = attr.width; + *height = attr.height; + *visual = attr.visual; + return id; + } + } while( parent != attr.root && parent != 0 ); //Failed finding a redirected window + + + DTRACE( "find_capture - cannot find id\n"); + XGetWindowAttributes (ecore_x_display_get(), orig_id, &attr); + *depth = attr.depth; + *width = attr.width; + *height = attr.height; + *visual = attr.visual; + + return (Window) 0; + +} + +char *scrcapture_screen_capture(Window oid, int *size) +{ + XImage *xim; + XShmSegmentInfo si; + Pixmap pix; + int depth; + int width; + int height; + Visual *visual; + char *captured_image; + Window id; + + id = find_capture_available_window(ecore_x_window_focus_get(), &visual, &depth, &width, &height); + + if (id == 0 || id == -1 || id == oid) + { + DTRACE("Window : 0x%lX\n", id); + if (get_window_attribute(id, &depth, &visual, &width, &height) < 0) + { + DTRACE("Failed to get the attributes from 0x%x\n", (unsigned int)id); + return NULL; + } + } + + DTRACE("WxH : %dx%d\n", width, height); + DTRACE("Depth : %d\n", depth >> 3); + + // NOTE: just add one more depth.... + si.shmid = shmget(IPC_PRIVATE, width * height * ((depth >> 3)+1), IPC_CREAT | 0666); + if (si.shmid < 0) + { + DTRACE("error at shmget\n"); + return NULL; + } + si.readOnly = False; + si.shmaddr = shmat(si.shmid, NULL, 0); + if (si.shmaddr == (char*)-1) + { + shmdt(si.shmaddr); + shmctl(si.shmid, IPC_RMID, 0); + DTRACE("can't get shmat\n"); + return NULL; + } + +/* + if (!need_redirecting) + { + Window border; + if (get_border_window(id, &border) < 0) + { + need_redirecting = 1; + printf("Failed to find a border, forcely do redirecting\n"); + } + else + { + id = border; + printf("Border window is found, use it : 0x%X\n", (unsigned int)id); + } + } + + if (need_redirecting) + { + printf("XCompositeRedirectWindow"); + XCompositeRedirectWindow(ecore_x_display_get(), id, CompositeRedirectManual); + } +*/ + + + DTRACE("XShmCreateImage\n"); + xim = XShmCreateImage(ecore_x_display_get(), visual, depth, ZPixmap, NULL, &si, width, height); + if (!xim) + { + shmdt(si.shmaddr); + shmctl(si.shmid, IPC_RMID, 0); + +/* + if (need_redirecting) + { + printf("XCompositeUnredirectWindow"); + XCompositeUnredirectWindow(ecore_x_display_get(), id, CompositeRedirectManual); + } +*/ + return NULL; + } + + *size = xim->bytes_per_line * xim->height; + xim->data = si.shmaddr; + + DTRACE("XCompositeNameWindowPixmap\n"); + pix = XCompositeNameWindowPixmap(ecore_x_display_get(), id); + + DTRACE("XShmAttach\n"); + XShmAttach(ecore_x_display_get(), &si); + + DTRACE("XShmGetImage\n"); + XShmGetImage(ecore_x_display_get(), pix, xim, 0, 0, 0xFFFFFFFF); + + //XUnmapWindow(disp, id); + //XMapWindow(disp, id); + DTRACE("XSync\n"); + XSync(ecore_x_display_get(), False); + + //sleep(1); + // We can optimize this! + captured_image = calloc(1, *size); + if (captured_image) + { + memcpy(captured_image, xim->data, *size); + } + else + { + DTRACE("calloc error"); + } + + DTRACE("XShmDetach"); + XShmDetach(ecore_x_display_get(), &si); + DTRACE("XFreePixmap\n"); + XFreePixmap(ecore_x_display_get(), pix); + DTRACE("XDestroyImage\n"); + XDestroyImage(xim); + +/* + if (need_redirecting) { + printf("XCompositeUnredirectWindow"); + XCompositeUnredirectWindow(ecore_x_display_get(), id, CompositeRedirectManual); + } +*/ + + shmdt(si.shmaddr); + shmctl(si.shmid, IPC_RMID, 0); + return captured_image; +} + +char *scrcapture_capture_screen_by_x11(Window xid, int *size) +{ + XImage *xim; + int depth; + int width; + int height; + Visual *visual; + char *captured_image; + + + DTRACE("Window : 0x%lX\n", xid); + if (get_window_attribute(xid, &depth, &visual, &width, &height) < 0) + { + DTRACE("Failed to get the attributes from 0x%x\n", (unsigned int)xid); + return NULL; + } + + DTRACE("WxH : %dx%d\n", width, height); + DTRACE("Depth : %d\n", depth >> 3); + + xim = XGetImage(ecore_x_display_get(), xid, 0, 0, + width, height, AllPlanes, ZPixmap); + + *size = xim->bytes_per_line * xim->height; + + captured_image = calloc(1, *size); + if (captured_image) + { + memcpy(captured_image, xim->data, *size); + } + else + { + DTRACE("calloc error"); + } + + return captured_image; +} + +#define return_if_fail(cond) {if (!(cond)) { printf ("%s : '%s' failed.\n", __FUNCTION__, #cond); return; }} +#define return_val_if_fail(cond, val) {if (!(cond)) { printf ("%s : '%s' failed.\n", __FUNCTION__, #cond); return val; }} +#define goto_if_fail(cond, dst) {if (!(cond)) { printf ("%s : '%s' failed.\n", __FUNCTION__, #cond); goto dst; }} + +int convert_image (uint32_t *srcbuf, + uint32_t *dstbuf, + pixman_format_code_t src_format, + pixman_format_code_t dst_format, + int src_width, int src_height, + int dst_width, int dst_height, + int rotate) +{ + pixman_image_t * src_img; + pixman_image_t * dst_img; + pixman_transform_t transform; + pixman_region16_t clip; + int src_stride, dst_stride; + int src_bpp; + int dst_bpp; + pixman_op_t op; + int rotate_step; + int ret = False; + + return_val_if_fail (srcbuf != NULL, False); + return_val_if_fail (dstbuf != NULL, False); + return_val_if_fail (rotate <= 360 && rotate >= -360, False); + + op = PIXMAN_OP_SRC; + + src_bpp = PIXMAN_FORMAT_BPP (src_format) / 8; + return_val_if_fail (src_bpp > 0, False); + + dst_bpp = PIXMAN_FORMAT_BPP (dst_format) / 8; + return_val_if_fail (dst_bpp > 0, False); + + rotate_step = (rotate + 360) / 90 % 4; + + src_stride = src_width * src_bpp; + dst_stride = dst_width * dst_bpp; + + src_img = pixman_image_create_bits (src_format, src_width, src_height, srcbuf, src_stride); + dst_img = pixman_image_create_bits (dst_format, dst_width, dst_height, dstbuf, dst_stride); + + goto_if_fail (src_img != NULL, CANT_CONVERT); + goto_if_fail (dst_img != NULL, CANT_CONVERT); + + pixman_transform_init_identity (&transform); + + if (rotate_step > 0) + { + int c, s, tx = 0, ty = 0; + switch (rotate_step) + { + case 1: + /* 270 degrees */ + c = 0; + s = -pixman_fixed_1; + ty = pixman_int_to_fixed (dst_width); + break; + case 2: + /* 180 degrees */ + c = -pixman_fixed_1; + s = 0; + tx = pixman_int_to_fixed (dst_width); + ty = pixman_int_to_fixed (dst_height); + break; + case 3: + /* 90 degrees */ + c = 0; + s = pixman_fixed_1; + tx = pixman_int_to_fixed (dst_height); + break; + default: + /* 0 degrees */ + c = 0; + s = 0; + break; + } + pixman_transform_rotate (&transform, NULL, c, s); + pixman_transform_translate (&transform, NULL, tx, ty); + } + + pixman_image_set_transform (src_img, &transform); + + pixman_image_composite (op, src_img, NULL, dst_img, + 0, 0, 0, 0, 0, 0, dst_width, dst_height); + + ret = True; + +CANT_CONVERT: + if (src_img) + pixman_image_unref (src_img); + if (dst_img) + pixman_image_unref (dst_img); + + return ret; +} + +int +getXwindowProperty (Display *d, Window xwindow, + Atom prop_atom, + Atom type_atom, + unsigned char *value, + int nvalues) +{ + int ret = 0; + Atom ret_type = None; + int ret_format; + unsigned long ret_nitems; + unsigned long ret_bytes_after; + unsigned char *data = NULL; + int result; + + result = XGetWindowProperty (d, xwindow, + prop_atom, 0, 0x7fffffff, False, type_atom, + &ret_type, &ret_format, &ret_nitems, &ret_bytes_after, + &data); + + if (result != Success) + { + DTRACE("Getting a property is failed!"); + ret = 0; + } + else if (type_atom != ret_type) + ret = 0; + else if (ret_format != 32) + { + DTRACE("Format is not matched! (%d)", ret_format); + ret = 0; + } + else if (ret_nitems == 0 || !data) + ret = 0; + else + { + if (ret_nitems < nvalues) + nvalues = ret_nitems; + + memcpy (value, data, nvalues*sizeof(int)); + ret = nvalues; + } + + if (data) + XFree(data); + + return ret; +} + +const char *createScreenShotSW(Display *d, int width, int height) +{ + Window root; + int rotate; + Atom atom_rotaion; + char *ret = NULL; + + if (ximage) + { + XDestroyImage (ximage); + ximage = NULL; + } + + root = RootWindow (d, DefaultScreen(d)); + + ximage = XShmCreateImage (d, DefaultVisualOfScreen (DefaultScreenOfDisplay (d)), 24, ZPixmap, NULL, + &x_shm_info, (unsigned int)width, (unsigned int)height); + if (!ximage) + { + DTRACE("XShmCreateImage failed !\n"); + return NULL; + } + + x_shm_info.shmid = shmget (IPC_PRIVATE, + ximage->bytes_per_line * ximage->height, + IPC_CREAT | 0777); + x_shm_info.shmaddr = ximage->data = shmat (x_shm_info.shmid, 0, 0); + x_shm_info.readOnly = False; + + if (!XShmAttach (d, &x_shm_info)) + { + DTRACE("XShmAttach failed !\n"); + return NULL; + } + + if (!XShmGetImage (d, root, ximage, 0, 0, AllPlanes)) + { + DTRACE("XShmGetImage failed !\n"); + return NULL; + } + + ret = ximage->data; + + atom_rotaion = XInternAtom (d, "X_SCREEN_ROTATION", True); + if (!atom_rotaion || + !getXwindowProperty (d, root, atom_rotaion, XA_CARDINAL, (unsigned char*)&rotate, 1)) + { + rotate = RR_Rotate_0; + } + + if (rotate == RR_Rotate_90 || rotate == RR_Rotate_270) + { + rot_buffer = calloc (ximage->bytes_per_line * ximage->height, 1); + + convert_image ((uint32_t*)ximage->data, + (uint32_t*)rot_buffer, + PIXMAN_x8b8g8r8, PIXMAN_x8b8g8r8, + height, width, width, height, + (rotate == RR_Rotate_90) ? 90 : 270); + + ret = rot_buffer; + } + + XSync (d, False); + + return ret; +} + +void releaseScreenShotSW(Display *d, const char * ss) +{ + if (ximage) + { + XShmDetach (d, &x_shm_info); + shmdt (x_shm_info.shmaddr); + shmctl (x_shm_info.shmid, IPC_RMID, NULL); + + XDestroyImage (ximage); + ximage = NULL; + + if (rot_buffer) + { + free (rot_buffer); + rot_buffer = NULL; + } + } +} diff --git a/src/old/scrcapture.h b/src/old/scrcapture.h new file mode 100644 index 0000000..f81f333 --- /dev/null +++ b/src/old/scrcapture.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _scrcapture_h_ +#define _scrcapture_h_ + +#include +#include +#include +#include +#include + +// XV extension API - start +const char* createScreenShot(int width, int height); +void releaseScreenShot(const char *ss); +// XV extension API - end + +Eina_Bool capture_current_screen(void *data); +char *scrcapture_capture_screen_by_x11(Window xid, int *size); +char *scrcapture_capture_screen_by_xv_ext(int width, int height); +void scrcapture_release_screen_by_xv_ext(const char *s); + +int init_scrcapture(void *data); +void close_scrcapture(void *data); + +#endif // _scrcapture_h_ diff --git a/src/old/storage.c b/src/old/storage.c new file mode 100644 index 0000000..b2acf88 --- /dev/null +++ b/src/old/storage.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "common.h" +#include "cbhm_main.h" +#include "storage.h" + +/* + file structure + + /--------------------------------------------------------------------------- + |header|current_position|total_count|item_header|item_body(512kib)|item...| + --------------------------------------------------------------------------/ + +*/ + +#define STORAGE_FILEPATH "/opt/var/.savecbh" +#define STORAGE_MAX_ITEMS HISTORY_QUEUE_MAX_ITEMS +#define HEADER_ITEM_SIZE (sizeof(int)) +#define BODY_ITEM_SIZE HISTORY_QUEUE_ITEM_SIZE +#define STORAGE_HEADER_SIZE (STORAGE_MAX_ITEMS * HEADER_ITEM_SIZE) +#define STORAGE_BODY_SIZE (STORAGE_MAX_ITEMS * BODY_ITEM_SIZE) +#define TOTAL_STORAGE_SIZE (STORAGE_HEADER_SIZE+STORAGE_BODY_SIZE) + +#define GET_HEADER_ADDR_BY_POSITION(pos) (STORAGE_HEADER_SIZE+pos*(HEADER_ITEM_SIZE+BODY_ITEM_SIZE)) +#define GET_BODY_ADDR_BY_POSITION(pos) (GET_HEADER_ADDR_BY_POSITION(pos)+HEADER_ITEM_SIZE) + +static FILE *g_storage_file = NULL; +static unsigned int g_storage_serial_number = 0; + +int init_storage(void *data) +{ + struct appdata *ad = data; + + int i; + int result = 0; + + if (g_storage_file) + return 1; + + g_storage_file = fopen(STORAGE_FILEPATH, "r+"); + if (!g_storage_file) + { // making data savefile + g_storage_file = fopen(STORAGE_FILEPATH, "w+"); + + if (!g_storage_file) + { + close_storage(ad); + DTRACE("Error : failed openning file for writing\n"); + return -1; + } + + result = fseek(g_storage_file, TOTAL_STORAGE_SIZE-1, SEEK_SET); + if (!result) + { + close_storage(ad); + DTRACE("Error : failed moving file position to file's end\n"); + return -1; + } + + result = fputc(0, g_storage_file); + if (result == EOF) + { + DTRACE("Error : failed writing to file's end\n"); + return -1; + } + } + + DTRACE("Success : storage init is done\n"); + + g_storage_serial_number = 0; + + return 0; +} + +int sync_storage(void *data) +{ +// struct appdata *ad = data; + + if (!g_storage_file) + { + DTRACE("g_storage_file is null\n"); + return -1; + } + fsync(g_storage_file); + + return 0; +} + +unsigned int get_storage_serial_code(void *data) +{ +// struct appdata *ad = data; + + return g_storage_serial_number; +} + +int adding_item_to_storage(void *data, int pos, char *idata) +{ +// struct appdata *ad = data; + if (!g_storage_file) + { + DTRACE("g_storage_file is null\n"); + return -1; + } + + int result; + result = fseek(g_storage_file, GET_HEADER_ADDR_BY_POSITION(pos), SEEK_SET); + // FIXME : replace from fprintf to fwrite + fprintf(g_storage_file, "%d", strlen(idata)); + fprintf(g_storage_file, "%s", idata); + + g_storage_serial_number++; + return 0; +} + +int get_item_counts(void *data) +{ + struct appdata *ad = data; + + return ad->hicount; +} + +int close_storage(void *data) +{ + struct appdata *ad = data; + + if (g_storage_file) + fclose(g_storage_file); + g_storage_file = NULL; + g_storage_serial_number = 0; + + return 0; +} + +int check_regular_file(char *path) +{ + struct stat fattr; + if (stat(path, &fattr)) + { + DTRACE("Cannot get file at path = %s\n", path); + return FALSE; + } + + return S_ISREG(fattr.st_mode); +} + diff --git a/src/old/storage.h b/src/old/storage.h new file mode 100644 index 0000000..e895ee4 --- /dev/null +++ b/src/old/storage.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _storage_h_ +#define _storage_h_ + +#include +#include +#include +#include + +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_ diff --git a/src/xcnphandler.c b/src/old/xcnphandler.c similarity index 100% rename from src/xcnphandler.c rename to src/old/xcnphandler.c diff --git a/src/xcnphandler.h b/src/old/xcnphandler.h similarity index 100% rename from src/xcnphandler.h rename to src/old/xcnphandler.h diff --git a/src/scrcapture.c b/src/scrcapture.c index 11b1296..92b5843 100644 --- a/src/scrcapture.c +++ b/src/scrcapture.c @@ -15,546 +15,299 @@ * */ -#include "common.h" -#include "cbhm_main.h" -#include "xcnphandler.h" -#include "scrcapture.h" -#include "clipdrawer.h" - +#include +#include +#include +#include #include -#include - -#include #include -#include -#include +#include +#include +#include + +#ifdef USE_SYSPOPUP +#include +#include +#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 -#include -#include -#include - -#include -#include -#include -#include -#include +#ifdef USE_SYSPOPUP +enum syspopup_type { + SCREEN_CAPTURE_SUCCESS = 0, + SCREEN_CAPTURE_DISABLED +}; +#define SYSPOPUP_PARAM_LEN 3 +#define SYSPOPUP_TYPE 0 +#define CBHM_SYSPOPUP "cbhm_syspopup" +#else +#define SCREEN_CAPTURE_SUCCESS "Screen capture success" +#define SCREEN_CAPTURE_DISABLED "Screen capture disabled" +#endif + +static char *createScreenShotSW(AppData *ad, int width, int height, XImage **ximage_ret, XShmSegmentInfo *x_shm_info); +static void releaseScreenShotSW(Ecore_X_Display *x_disp, char *ss, XImage *ximage, XShmSegmentInfo *x_shm_info); + +SCaptureData *init_screencapture(AppData *ad) +{ + SCaptureData *sd = CALLOC(1, sizeof(SCaptureData)); -static int svi_handle = -1; -static Eina_Bool g_shot = EINA_FALSE; -static XImage *ximage; -static XShmSegmentInfo x_shm_info; -static char *rot_buffer; + int ret; + ret = svi_init(&sd->svi_handle); + if(ret != SVI_SUCCESS) + { + DMSG("svi_init failed %d\n", ret); + sd->svi_init = EINA_FALSE; + } + else + sd->svi_init = EINA_TRUE; + return sd; +} -typedef struct tag_captureimginfo +void depose_screencapture(SCaptureData *sd) { - char filename[256]; - Evas_Object *eo; - char *imgdata; -} captureimginfo_t; - -static const char *createScreenShotSW(Display *d, int width, int height); -void releaseScreenShotSW(Display *d, const char * ss); -static Eina_Bool get_image_filename_with_date(char *dstr) + if (sd->svi_init) + svi_fini(sd->svi_handle); + if (sd->stimer) + ecore_timer_del(sd->stimer); + if (sd->spopup) + evas_object_del(sd->spopup); + if (sd->swin) + evas_object_del(sd->swin); + FREE(sd); +} + +static char *get_image_filename_with_date() { time_t tim = time(NULL); struct tm *now = localtime(&tim); struct timeval tv; gettimeofday(&tv, NULL); - sprintf(dstr, "%s/screen-%d%02d%02d%02d%02d%02d%0ld%s", + + size_t len = snprintf(NULL, 0, "%s/screen-%d%02d%02d%02d%02d%02d%0ld%s", IMAGE_SAVE_DIR, now->tm_year+1900, now->tm_mon+1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, tv.tv_usec, - IMAGE_SAVE_FILE_TYPE); - return EINA_TRUE; -} - - -static void _play_capture_sound() -{ - int ret = SVI_ERROR; - - if (svi_handle != -1) - ret = svi_play(svi_handle, SVI_VIB_OPERATION_SHUTTER, SVI_SND_OPERATION_SCRCAPTURE); - - if (ret != SVI_SUCCESS) + IMAGE_SAVE_FILE_TYPE) + 1; + char *filepath = MALLOC(sizeof(char) * len); + if (!filepath) { - DTRACE("play file failed\n"); - } - else - { - DTRACE("play file success\n"); + DTRACE("can't alloc filepath buffer\n"); + return NULL; } -} -static Eina_Bool hide_small_popup(void *data) -{ - struct appdata *ad = data; - ad->popup_timer = NULL; - evas_object_hide(ad->small_popup); - return ECORE_CALLBACK_CANCEL; + snprintf(filepath, len, "%s/screen-%d%02d%02d%02d%02d%02d%0ld%s", + IMAGE_SAVE_DIR, + now->tm_year+1900, now->tm_mon+1, now->tm_mday, + now->tm_hour, now->tm_min, + now->tm_sec, tv.tv_usec, + IMAGE_SAVE_FILE_TYPE); + return filepath; } -static void show_small_popup(struct appdata *ad, char* msg) -{ - if (!ad->small_popup) - ad->small_popup = elm_tickernoti_add(NULL); - if (!ad->small_win) - ad->small_win = elm_tickernoti_win_get(ad->small_popup); - - elm_object_style_set(ad->small_popup, "info"); - elm_tickernoti_label_set(ad->small_popup, msg); - elm_tickernoti_orientation_set(ad->small_popup, ELM_TICKERNOTI_ORIENT_BOTTOM); - evas_object_show(ad->small_popup); - ad->popup_timer = ecore_timer_add(2, hide_small_popup, ad); -} +#ifdef USE_SYSPOPUP +#define PRINT_CASE_WITH_FUNC(func, param) \ + case param: \ + DMSG(#func" fail: "#param"\n"); \ + break; -static void play_screen_capture_effect() -{ - struct appdata *ad = g_get_main_appdata(); - show_small_popup(ad, "Screen capture success"); - Ecore_X_Display *disp = ecore_x_display_get(); - Ecore_X_Window root_win = ecore_x_window_root_first_get(); - DTRACE("disp: 0x%x, root_win: 0x%x\n", disp, root_win); - utilx_show_capture_effect(disp, root_win); - _play_capture_sound(); -} +#define PRINT_ERROR(error) \ + print_bundle_error(__func__, error); -static Eina_Bool _scrcapture_capture_postprocess(void* data) +static void print_bundle_error(const char *func, int err) { - captureimginfo_t *capimginfo = data; - - DTIME("start capture postprocess - %s\n", capimginfo->filename); - - if (!evas_object_image_save(capimginfo->eo, capimginfo->filename, NULL, "compress=1")) + switch(errno) { - DTRACE("screen capture save fail\n"); - g_shot = EINA_FALSE; - return EINA_FALSE; + PRINT_CASE_WITH_FUNC(func, EKEYREJECTED); + PRINT_CASE_WITH_FUNC(func, EPERM); + PRINT_CASE_WITH_FUNC(func, EINVAL); + default: + DMSG("unknown errno in %s: %d", func, err); + break; } - - DTIME("end capture postprocess - %s\n", capimginfo->filename); - - char *imgpath = NULL; - imgpath = malloc(strlen(capimginfo->filename)+strlen("file://")+2); - snprintf(imgpath, strlen(capimginfo->filename)+strlen("file://")+1, - "%s%s", "file://", capimginfo->filename); - DTRACE("add to image history = %s\n", imgpath+strlen("file://")); - clipdrawer_add_item(imgpath+strlen("file://"), GI_IMAGE); - free(imgpath); - - evas_object_del(capimginfo->eo); - free(capimginfo->imgdata); - free(capimginfo); - play_screen_capture_effect(); - DTIME("end current capture\n"); - - g_shot = EINA_FALSE; - - return EINA_FALSE; } -Eina_Bool capture_current_screen(void *data) +#undef PRINT_ERROR +#undef PRINT_CASE_WITH_FUNC + +static void launch_cbhm_syspopup(SCaptureData *sd, int type) { - struct appdata *ad = data; - if (!utilx_get_screen_capture(XOpenDisplay(NULL))) - { - show_small_popup(ad, "Screen capture disabled"); - DTRACE("utilx_get_screen_capture: disable\n"); - return EINA_FALSE; - } - else - DTRACE("utilx_get_screen_capture: enable\n"); + char syspopup_type[SYSPOPUP_PARAM_LEN]; - if (g_shot) + bundle *b = bundle_create(); + if (!b) { - DTRACE("too early to capture current screen\n"); - return EINA_FALSE; + DMSG("bundle_create() fail\n"); + return; } - g_shot = EINA_TRUE; - - DTIME("start current capture\n"); - - captureimginfo_t *capimginfo = NULL; - capimginfo = malloc(sizeof(captureimginfo_t) * 1); - get_image_filename_with_date(capimginfo->filename); - DTRACE("capture current screen\n"); - int width, height; - width = ad->root_w; - height = ad->root_h; - capimginfo->imgdata = malloc(sizeof(char) * (width*height*4) + 1); - capimginfo->eo = evas_object_image_add(ad->evas); - - char *scrimage = NULL; - scrimage = createScreenShotSW(ecore_x_display_get(), width, height); - if (scrimage) - memcpy(capimginfo->imgdata, scrimage, width*height*4); - releaseScreenShotSW(ecore_x_display_get(), scrimage); - - if (scrimage == NULL || capimginfo->eo == NULL || capimginfo->imgdata == NULL) + snprintf(syspopup_type, SYSPOPUP_PARAM_LEN, "%d", type); + int ret = bundle_add(b, "CBHM_MSG_TYPE", syspopup_type); + if (ret == -1) { - DTRACE("screen capture fail\n"); - free(capimginfo->imgdata); - if (capimginfo->eo) - evas_object_del(capimginfo->eo); - free(capimginfo); - g_shot = EINA_FALSE; - return EINA_FALSE; + PRINT_ERROR(errno); } - - DTRACE("screen capture prepared\n"); - - evas_object_image_data_set(capimginfo->eo, NULL); - evas_object_image_size_set(capimginfo->eo, width, height); - evas_object_image_data_set(capimginfo->eo, capimginfo->imgdata); - evas_object_image_data_update_add(capimginfo->eo, 0, 0, width, height); - evas_object_resize(capimginfo->eo, width, height); - - ecore_idler_add(_scrcapture_capture_postprocess, capimginfo); - - return EINA_TRUE; -} - -static Eina_Bool scrcapture_keydown_cb(void *data, int type, void *event) -{ - struct appdata *ad = data; - Ecore_Event_Key *ev = event; - - if (!strcmp(ev->keyname, KEY_END)) - clipdrawer_lower_view(ad); - - return ECORE_CALLBACK_PASS_ON; -} - -int init_scrcapture(void *data) -{ - struct appdata *ad = data; - - int result = 0; - - /* Key Grab */ -// Ecore_X_Display *xdisp = ecore_x_display_get(); -// Ecore_X_Window xwin = (Ecore_X_Window)ecore_evas_window_get(ecore_evas_ecore_evas_get(ad->evas)); - - ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, scrcapture_keydown_cb, ad); - - if (svi_init(&svi_handle) != SVI_SUCCESS) + else { - DTRACE("svi init failed\n"); - svi_handle = -1; - return -1; + ret = syspopup_launch(CBHM_SYSPOPUP, b); + if (ret < 0) + DMSG("syspopup_launch() fail: %d, %d\n", ret, errno); } + ret = bundle_free(b); + if (ret == -1) + DMSG("bundle_free() fail: %d\n", errno); - return 0; + return; } - -void close_scrcapture(void *data) +#else +static Eina_Bool hide_spopup(void *data) { - struct appdata *ad = data; - -// Ecore_X_Display *xdisp = ecore_x_display_get(); -// Ecore_X_Window xwin = (Ecore_X_Window)ecore_evas_window_get(ecore_evas_ecore_evas_get(ad->evas)); - - if (svi_handle != -1) - svi_fini(svi_handle); - if (ad->small_popup) - evas_object_del(ad->small_popup); - if (ad->small_win) - evas_object_del(ad->small_win); + SCaptureData *sd = data; + ecore_timer_del(sd->stimer); + sd->stimer = NULL; + evas_object_hide(sd->spopup); + return ECORE_CALLBACK_CANCEL; } -static int get_window_attribute(Window id, int *depth, Visual **visual, int *width, int *height) +static void show_spopup(SCaptureData *sd, char *msg) { -// assert(id); - XWindowAttributes attr; - - DTRACE("XGetWindowAttributes\n"); - if (!XGetWindowAttributes(ecore_x_display_get(), id, &attr)) - { - return -1; - } - - if (attr.map_state == IsViewable && attr.class == InputOutput) - { - *depth = attr.depth; - *width = attr.width; - *height= attr.height; - *visual= attr.visual; - } - - return 0; + if (!sd->spopup) + sd->spopup = elm_tickernoti_add(NULL); + if (!sd->swin) + sd->swin = elm_tickernoti_win_get(sd->spopup); + + elm_object_style_set(sd->spopup, "info"); + elm_tickernoti_label_set(sd->spopup, msg); + elm_tickernoti_orientation_set(sd->spopup, ELM_TICKERNOTI_ORIENT_BOTTOM); + evas_object_show(sd->spopup); + sd->stimer = ecore_timer_add(2, hide_spopup, sd); } +#endif -static Window _get_parent_window( Window id ) +static void play_scrcapture_effect(AppData *ad) { - Window root; - Window parent; - Window* children; - unsigned int num; - - DTRACE("XQeuryTree\n"); + SCaptureData *sd = ad->screencapture; - if (!XQueryTree(ecore_x_display_get(), id, &root, &parent, &children, &num)) - { - return 0; - } +#ifdef USE_SYSPOPUP + launch_cbhm_syspopup(sd, SCREEN_CAPTURE_SUCCESS); +#else + show_spopup(sd, SCREEN_CAPTURE_SUCCESS); + utilx_show_capture_effect(ad->x_disp, ad->x_root_win); +#endif - if (children) + int ret = 0; + if (sd->svi_init) { - DTRACE("XFree\n"); - XFree(children); + ret = svi_play(sd->svi_handle, SVI_VIB_OPERATION_SHUTTER, SVI_SND_OPERATION_SCRCAPTURE); + DMSG("svi_play return: %d\n", ret); } - - return parent; } -static Window find_capture_available_window( Window id, Visual** visual, int* depth, int* width, int* height) +void capture_current_screen(AppData *ad) { - XWindowAttributes attr; - Window parent = id; - Window orig_id = id; - - if (id == 0) - { - return (Window) -1; - } - - do - { - id = parent; - DTRACE("find_capture - XGetWindowAttributes\n"); - - if (!XGetWindowAttributes(ecore_x_display_get(), id, &attr)) - { - return (Window) -1; - } - - parent = _get_parent_window( id ); - - if (attr.map_state == IsViewable - && attr.override_redirect == True - && attr.class == InputOutput && parent == attr.root ) - { - *depth = attr.depth; - *width = attr.width; - *height = attr.height; - *visual = attr.visual; - return id; - } - } while( parent != attr.root && parent != 0 ); //Failed finding a redirected window + SCaptureData *sd = ad->screencapture; + ClipdrawerData *cd = ad->clipdrawer; + Ecore_X_Display *disp = XOpenDisplay(NULL); + DMSG("ad->x_disp: 0x%x, disp: 0x%x\n", ad->x_disp, disp); - DTRACE( "find_capture - cannot find id\n"); - XGetWindowAttributes (ecore_x_display_get(), orig_id, &attr); - *depth = attr.depth; - *width = attr.width; - *height = attr.height; - *visual = attr.visual; - - return (Window) 0; - -} - -char *scrcapture_screen_capture(Window oid, int *size) -{ - XImage *xim; - XShmSegmentInfo si; - Pixmap pix; - int depth; - int width; - int height; - Visual *visual; - char *captured_image; - Window id; - - id = find_capture_available_window(ecore_x_window_focus_get(), &visual, &depth, &width, &height); - - if (id == 0 || id == -1 || id == oid) + if (!utilx_get_screen_capture(disp)) { - DTRACE("Window : 0x%lX\n", id); - if (get_window_attribute(id, &depth, &visual, &width, &height) < 0) - { - DTRACE("Failed to get the attributes from 0x%x\n", (unsigned int)id); - return NULL; - } +#ifdef USE_SYSPOPUP + launch_cbhm_syspopup(sd, SCREEN_CAPTURE_DISABLED); +#else + show_spopup(sd, SCREEN_CAPTURE_DISABLED); +#endif + DMSG("utilx_get_screen_capture: disable\n"); + return; } - DTRACE("WxH : %dx%d\n", width, height); - DTRACE("Depth : %d\n", depth >> 3); + DTIME("start current capture\n"); - // NOTE: just add one more depth.... - si.shmid = shmget(IPC_PRIVATE, width * height * ((depth >> 3)+1), IPC_CREAT | 0666); - if (si.shmid < 0) - { - DTRACE("error at shmget\n"); - return NULL; - } - si.readOnly = False; - si.shmaddr = shmat(si.shmid, NULL, 0); - if (si.shmaddr == (char*)-1) + int width, height; + width = cd->root_w; + height = cd->root_h; + + char *imgdata = MALLOC(sizeof(char) * (width*height*4) + 1); + if (!imgdata) { - shmdt(si.shmaddr); - shmctl(si.shmid, IPC_RMID, 0); - DTRACE("can't get shmat\n"); - return NULL; + DMSG("image buffer alloc fail\n"); + goto do_done; } -/* - if (!need_redirecting) + Evas_Object *image = evas_object_image_add(cd->evas); + if (!image) { - Window border; - if (get_border_window(id, &border) < 0) - { - need_redirecting = 1; - printf("Failed to find a border, forcely do redirecting\n"); - } - else - { - id = border; - printf("Border window is found, use it : 0x%X\n", (unsigned int)id); - } + DMSG("image add fail\n"); + goto do_done; } - if (need_redirecting) + XImage *ximage; + XShmSegmentInfo x_shm_info; + char *scrimage = createScreenShotSW(ad, width, height, &ximage, &x_shm_info); + if (!scrimage) { - printf("XCompositeRedirectWindow"); - XCompositeRedirectWindow(ecore_x_display_get(), id, CompositeRedirectManual); + DMSG("screen capture fail\n"); + goto do_done; } -*/ + memcpy(imgdata, scrimage, width*height*4); + releaseScreenShotSW(ad->x_disp, scrimage, ximage, &x_shm_info); - DTRACE("XShmCreateImage\n"); - xim = XShmCreateImage(ecore_x_display_get(), visual, depth, ZPixmap, NULL, &si, width, height); - if (!xim) + evas_object_image_data_set(image, NULL); + evas_object_image_size_set(image, width, height); + evas_object_image_data_set(image, imgdata); + evas_object_image_data_update_add(image, 0, 0, width, height); + evas_object_resize(image, width, height); + char *filepath = get_image_filename_with_date(); + if (filepath) { - shmdt(si.shmaddr); - shmctl(si.shmid, IPC_RMID, 0); - -/* - if (need_redirecting) + if (!evas_object_image_save(image, filepath, NULL, "compress=1")) { - printf("XCompositeUnredirectWindow"); - XCompositeUnredirectWindow(ecore_x_display_get(), id, CompositeRedirectManual); + DMSG("screen capture save fail\n"); + goto do_done; } -*/ - return NULL; - } - - *size = xim->bytes_per_line * xim->height; - xim->data = si.shmaddr; - - DTRACE("XCompositeNameWindowPixmap\n"); - pix = XCompositeNameWindowPixmap(ecore_x_display_get(), id); - - DTRACE("XShmAttach\n"); - XShmAttach(ecore_x_display_get(), &si); - - DTRACE("XShmGetImage\n"); - XShmGetImage(ecore_x_display_get(), pix, xim, 0, 0, 0xFFFFFFFF); - - //XUnmapWindow(disp, id); - //XMapWindow(disp, id); - DTRACE("XSync\n"); - XSync(ecore_x_display_get(), False); - - //sleep(1); - // We can optimize this! - captured_image = calloc(1, *size); - if (captured_image) - { - memcpy(captured_image, xim->data, *size); - } - else - { - DTRACE("calloc error"); - } - - DTRACE("XShmDetach"); - XShmDetach(ecore_x_display_get(), &si); - DTRACE("XFreePixmap\n"); - XFreePixmap(ecore_x_display_get(), pix); - DTRACE("XDestroyImage\n"); - XDestroyImage(xim); - -/* - if (need_redirecting) { - printf("XCompositeUnredirectWindow"); - XCompositeUnredirectWindow(ecore_x_display_get(), id, CompositeRedirectManual); - } -*/ - - shmdt(si.shmaddr); - shmctl(si.shmid, IPC_RMID, 0); - return captured_image; -} - -char *scrcapture_capture_screen_by_x11(Window xid, int *size) -{ - XImage *xim; - int depth; - int width; - int height; - Visual *visual; - char *captured_image; + item_add_by_data(ad, ad->targetAtoms[ATOM_INDEX_IMAGE].atom[0], filepath, strlen(filepath) + 1); - - DTRACE("Window : 0x%lX\n", xid); - if (get_window_attribute(xid, &depth, &visual, &width, &height) < 0) - { - DTRACE("Failed to get the attributes from 0x%x\n", (unsigned int)xid); - return NULL; - } - - DTRACE("WxH : %dx%d\n", width, height); - DTRACE("Depth : %d\n", depth >> 3); - - xim = XGetImage(ecore_x_display_get(), xid, 0, 0, - width, height, AllPlanes, ZPixmap); - - *size = xim->bytes_per_line * xim->height; - - captured_image = calloc(1, *size); - if (captured_image) - { - memcpy(captured_image, xim->data, *size); - } - else - { - DTRACE("calloc error"); + play_scrcapture_effect(ad); + DTIME("end current capture\n"); } - return captured_image; +do_done: + if (image) + evas_object_del(image); + if (imgdata) + FREE(imgdata); + return; } #define return_if_fail(cond) {if (!(cond)) { printf ("%s : '%s' failed.\n", __FUNCTION__, #cond); return; }} #define return_val_if_fail(cond, val) {if (!(cond)) { printf ("%s : '%s' failed.\n", __FUNCTION__, #cond); return val; }} #define goto_if_fail(cond, dst) {if (!(cond)) { printf ("%s : '%s' failed.\n", __FUNCTION__, #cond); goto dst; }} -int convert_image (uint32_t *srcbuf, - uint32_t *dstbuf, - pixman_format_code_t src_format, - pixman_format_code_t dst_format, - int src_width, int src_height, - int dst_width, int dst_height, +int convert_image(uint32_t *srcbuf, uint32_t *dstbuf, + pixman_format_code_t src_format, pixman_format_code_t dst_format, + int src_width, int src_height, int dst_width, int dst_height, int rotate) { - pixman_image_t * src_img; - pixman_image_t * dst_img; + pixman_image_t *src_img; + pixman_image_t *dst_img; pixman_transform_t transform; - pixman_region16_t clip; - int src_stride, dst_stride; - int src_bpp; - int dst_bpp; - pixman_op_t op; - int rotate_step; - int ret = False; + pixman_region16_t clip; + int src_stride, dst_stride; + int src_bpp; + int dst_bpp; + pixman_op_t op; + int rotate_step; + int ret = False; return_val_if_fail (srcbuf != NULL, False); return_val_if_fail (dstbuf != NULL, False); @@ -562,24 +315,24 @@ int convert_image (uint32_t *srcbuf, op = PIXMAN_OP_SRC; - src_bpp = PIXMAN_FORMAT_BPP (src_format) / 8; - return_val_if_fail (src_bpp > 0, False); + src_bpp = PIXMAN_FORMAT_BPP(src_format) / 8; + return_val_if_fail(src_bpp > 0, False); - dst_bpp = PIXMAN_FORMAT_BPP (dst_format) / 8; - return_val_if_fail (dst_bpp > 0, False); + dst_bpp = PIXMAN_FORMAT_BPP(dst_format) / 8; + return_val_if_fail(dst_bpp > 0, False); rotate_step = (rotate + 360) / 90 % 4; src_stride = src_width * src_bpp; dst_stride = dst_width * dst_bpp; - src_img = pixman_image_create_bits (src_format, src_width, src_height, srcbuf, src_stride); - dst_img = pixman_image_create_bits (dst_format, dst_width, dst_height, dstbuf, dst_stride); + src_img = pixman_image_create_bits(src_format, src_width, src_height, srcbuf, src_stride); + dst_img = pixman_image_create_bits(dst_format, dst_width, dst_height, dstbuf, dst_stride); goto_if_fail (src_img != NULL, CANT_CONVERT); goto_if_fail (dst_img != NULL, CANT_CONVERT); - pixman_transform_init_identity (&transform); + pixman_transform_init_identity(&transform); if (rotate_step > 0) { @@ -611,130 +364,83 @@ int convert_image (uint32_t *srcbuf, s = 0; break; } - pixman_transform_rotate (&transform, NULL, c, s); - pixman_transform_translate (&transform, NULL, tx, ty); + pixman_transform_rotate(&transform, NULL, c, s); + pixman_transform_translate(&transform, NULL, tx, ty); } - pixman_image_set_transform (src_img, &transform); + pixman_image_set_transform(src_img, &transform); - pixman_image_composite (op, src_img, NULL, dst_img, + pixman_image_composite(op, src_img, NULL, dst_img, 0, 0, 0, 0, 0, 0, dst_width, dst_height); ret = True; CANT_CONVERT: if (src_img) - pixman_image_unref (src_img); + pixman_image_unref(src_img); if (dst_img) - pixman_image_unref (dst_img); + pixman_image_unref(dst_img); return ret; } -int -getXwindowProperty (Display *d, Window xwindow, - Atom prop_atom, - Atom type_atom, - unsigned char *value, - int nvalues) +static char *createScreenShotSW(AppData *ad, int width, int height, XImage **ximage_ret, XShmSegmentInfo *x_shm_info) { - int ret = 0; - Atom ret_type = None; - int ret_format; - unsigned long ret_nitems; - unsigned long ret_bytes_after; - unsigned char *data = NULL; - int result; - - result = XGetWindowProperty (d, xwindow, - prop_atom, 0, 0x7fffffff, False, type_atom, - &ret_type, &ret_format, &ret_nitems, &ret_bytes_after, - &data); - - if (result != Success) - { - DTRACE("Getting a property is failed!"); - ret = 0; - } - else if (type_atom != ret_type) - ret = 0; - else if (ret_format != 32) - { - DTRACE("Format is not matched! (%d)", ret_format); - ret = 0; - } - else if (ret_nitems == 0 || !data) - ret = 0; - else - { - if (ret_nitems < nvalues) - nvalues = ret_nitems; + char *ret = NULL; - memcpy (value, data, nvalues*sizeof(int)); - ret = nvalues; - } - - if (data) - XFree(data); - - return ret; -} + XImage *ximage; -const char *createScreenShotSW(Display *d, int width, int height) -{ - Window root; - int rotate; - Atom atom_rotaion; - char *ret = NULL; - - if (ximage) - { - XDestroyImage (ximage); - ximage = NULL; - } - - root = RootWindow (d, DefaultScreen(d)); - - ximage = XShmCreateImage (d, DefaultVisualOfScreen (DefaultScreenOfDisplay (d)), 24, ZPixmap, NULL, - &x_shm_info, (unsigned int)width, (unsigned int)height); + ximage = XShmCreateImage(ad->x_disp, DefaultVisualOfScreen(DefaultScreenOfDisplay(ad->x_disp)), 24, ZPixmap, NULL, + x_shm_info, (unsigned int)width, (unsigned int)height); if (!ximage) { DTRACE("XShmCreateImage failed !\n"); return NULL; } - x_shm_info.shmid = shmget (IPC_PRIVATE, + x_shm_info->shmid = shmget(IPC_PRIVATE, ximage->bytes_per_line * ximage->height, IPC_CREAT | 0777); - x_shm_info.shmaddr = ximage->data = shmat (x_shm_info.shmid, 0, 0); - x_shm_info.readOnly = False; + ximage->data = (void *)shmat(x_shm_info->shmid, NULL, 0); + x_shm_info->shmaddr = ximage->data; + x_shm_info->readOnly = False; - if (!XShmAttach (d, &x_shm_info)) + if (!XShmAttach(ad->x_disp, x_shm_info)) { DTRACE("XShmAttach failed !\n"); + releaseScreenShotSW(ad->x_disp, NULL, ximage, x_shm_info); return NULL; } - if (!XShmGetImage (d, root, ximage, 0, 0, AllPlanes)) + if (!XShmGetImage(ad->x_disp, ad->x_root_win, ximage, 0, 0, AllPlanes)) { DTRACE("XShmGetImage failed !\n"); + releaseScreenShotSW(ad->x_disp, NULL, ximage, x_shm_info); return NULL; } ret = ximage->data; - atom_rotaion = XInternAtom (d, "X_SCREEN_ROTATION", True); - if (!atom_rotaion || - !getXwindowProperty (d, root, atom_rotaion, XA_CARDINAL, (unsigned char*)&rotate, 1)) + Ecore_X_Atom atom_rotation = ecore_x_atom_get("X_SCREEN_ROTATION"); + + int cnt; + unsigned char *prop_data = NULL; + int rotate = RR_Rotate_0; + if (ecore_x_window_prop_property_get(ad->x_root_win, atom_rotation, ECORE_X_ATOM_CARDINAL, 32, &prop_data, &cnt)) { - rotate = RR_Rotate_0; + if (prop_data) + { + memcpy(&rotate, prop_data, sizeof(int)); + FREE(prop_data); + } } if (rotate == RR_Rotate_90 || rotate == RR_Rotate_270) { - rot_buffer = calloc (ximage->bytes_per_line * ximage->height, 1); + char *rot_buffer; + rot_buffer = CALLOC(ximage->bytes_per_line * ximage->height, 1); - convert_image ((uint32_t*)ximage->data, + convert_image((uint32_t*)ximage->data, (uint32_t*)rot_buffer, PIXMAN_x8b8g8r8, PIXMAN_x8b8g8r8, height, width, width, height, @@ -743,26 +449,23 @@ const char *createScreenShotSW(Display *d, int width, int height) ret = rot_buffer; } - XSync (d, False); + ecore_x_sync(); + *ximage_ret = ximage; return ret; } -void releaseScreenShotSW(Display *d, const char * ss) +static void releaseScreenShotSW(Ecore_X_Display *x_disp, char *ss, XImage *ximage, XShmSegmentInfo *x_shm_info) { if (ximage) { - XShmDetach (d, &x_shm_info); - shmdt (x_shm_info.shmaddr); - shmctl (x_shm_info.shmid, IPC_RMID, NULL); + XShmDetach(x_disp, x_shm_info); + shmdt(x_shm_info->shmaddr); + shmctl(x_shm_info->shmid, IPC_RMID, NULL); - XDestroyImage (ximage); - ximage = NULL; + if (ss != ximage->data) + FREE(ss); - if (rot_buffer) - { - free (rot_buffer); - rot_buffer = NULL; - } + XDestroyImage(ximage); } } diff --git a/src/scrcapture.h b/src/scrcapture.h index 0a68206..b1fc5cf 100644 --- a/src/scrcapture.h +++ b/src/scrcapture.h @@ -15,26 +15,24 @@ * */ -#ifndef _scrcapture_h_ -#define _scrcapture_h_ +#ifndef _SCRCAPTURE_H_ +#define _SCRCAPTURE_H_ -#include -#include -#include -#include -#include +#include -// 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_ diff --git a/src/storage.c b/src/storage.c index 1fe56a9..6d44c0b 100644 --- a/src/storage.c +++ b/src/storage.c @@ -15,146 +15,292 @@ * */ -#include "common.h" -#include "cbhm_main.h" -#include "storage.h" - -/* - file structure +#include - /--------------------------------------------------------------------------- - |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; } - diff --git a/src/storage.h b/src/storage.h index e895ee4..6e06d9e 100644 --- a/src/storage.h +++ b/src/storage.h @@ -15,21 +15,24 @@ * */ -#ifndef _storage_h_ -#define _storage_h_ +#ifndef _STORAGE_H_ +#define _STORAGE_H_ -#include -#include -#include -#include +#include +#include +#include -int init_storage(void *data); -int sync_storage(void *data); -unsigned int get_storage_serial_code(void *data); -int adding_item_to_storage(void *data, int pos, char *idata); -int get_item_counts(void *data); -int close_storage(void *data); +#include "item_manager.h" -int check_regular_file(char *path); +typedef double indexType; /* Ecore_Time */ -#endif // _storage_h_ +#define STORAGE_ITEM_CNT 12 +struct _StorageData { + Eet_File *ef; + indexType indexTable[STORAGE_ITEM_CNT]; + CNP_ITEM *itemTable[STORAGE_ITEM_CNT]; +}; + +StorageData *init_storage(AppData *ad); +void depose_storage(StorageData *sd); +#endif diff --git a/src/xconverter.c b/src/xconverter.c new file mode 100644 index 0000000..55ef5ae --- /dev/null +++ b/src/xconverter.c @@ -0,0 +1,1476 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "xconverter.h" + +static char *html_to_entry(AppData *ad, int type_index, const char *str); +static char *efl_to_entry(AppData *ad, int type_index, const char *str); +static char *text_to_entry(AppData *ad, int type_index, const char *str); +static char *image_path_to_entry(AppData *ad, int type_index, const char *str); + +static char *make_close_tag(Eina_List* nodes); +static char *do_not_convert(AppData *ad, int type_index, const char *str); +static char *html_to_efl(AppData *ad, int type_index, const char *str); +static char *efl_to_html(AppData *ad, int type_index, const char *str); +static char *text_to_html(AppData *ad, int type_index, const char *str); +static char *text_to_efl(AppData *ad, int type_index, const char *str); +static char *to_text(AppData *ad, int type_index, const char *str); +static char *image_path_to_html(AppData *ad, int type_index, const char *str); +static char *image_path_to_efl(AppData *ad, int type_index, const char *str); +static char *image_path_to_text(AppData *ad, int type_index, const char *str); +//static char *efl_to_efl(AppData *ad, int type_index, const char *str); +//static char *html_to_html(AppData *ad, int type_index, const char *str); +static char *image_path_to_image_path(AppData *ad, int type_index, const char *str); + +int atom_type_index_get(AppData *ad, Ecore_X_Atom atom) +{ + int i, j; + for (i = 0; i < ATOM_INDEX_MAX; i++) + { + for (j = 0; j < ad->targetAtoms[i].atom_cnt; j++) + if (ad->targetAtoms[i].atom[j] == atom) + return i; + } + return -1; +} + +void init_target_atoms(AppData *ad) +{ + int atom_cnt[ATOM_INDEX_MAX] = { + 1, 5, 2, 1, 2 + }; + char *targetAtomNames[][5] = { + { "TARGETS" }, + { "UTF8-STRING", "STRING", "TEXT", "text/plain;charset=utf-8", "text/plain" }, + { "text/html;charset=utf-8", "text/html" }, + { "application/x-elementary-markup" }, + { "text/uri", "text/uri-list" } + }; + text_converter_func converts_for_entry[ATOM_INDEX_MAX] = { + NULL, text_to_entry, html_to_entry, efl_to_entry, image_path_to_entry + }; + + text_converter_func converts[ATOM_INDEX_MAX][ATOM_INDEX_MAX] = { + {NULL, NULL, NULL, NULL, NULL}, + {NULL, do_not_convert, text_to_html, text_to_efl, NULL}, + {NULL, to_text, do_not_convert, html_to_efl, NULL}, + {NULL, to_text, efl_to_html, do_not_convert, NULL}, + {NULL, image_path_to_text, image_path_to_html, image_path_to_efl, image_path_to_image_path} + }; + + int i, j; + for (i = 0; i < ATOM_INDEX_MAX; i++) + { + ad->targetAtoms[i].atom_cnt = atom_cnt[i]; + ad->targetAtoms[i].name = MALLOC(sizeof(char *) * atom_cnt[i]); + ad->targetAtoms[i].atom = MALLOC(sizeof(Ecore_X_Atom) * atom_cnt[i]); + for (j = 0; j < atom_cnt[i]; j++) + { + DMSG("atomName: %s\n", targetAtomNames[i][j]); + ad->targetAtoms[i].name[j] = strdup(targetAtomNames[i][j]); + ad->targetAtoms[i].atom[j] = ecore_x_atom_get(targetAtomNames[i][j]); + } + ad->targetAtoms[i].convert_for_entry = converts_for_entry[i]; + + for (j = 0; j < ATOM_INDEX_MAX; j++) + ad->targetAtoms[i].convert_to_target[j] = converts[i][j]; + //ecore_x_selection_converter_atom_add(ad->targetAtoms[i].atom, target_converters[i]); + //ecore_x_selection_converter_atom_add(ad->targetAtoms[i].atom, generic_converter); + } +} + +void depose_target_atoms(AppData *ad) +{ + int i, j; + for (i = 0; i < ATOM_INDEX_MAX; i++) + { + for (j = 0; j < ad->targetAtoms[i].atom_cnt; j++) + { + if (ad->targetAtoms[i].name[j]) + FREE(ad->targetAtoms[i].name[j]); + } + if (ad->targetAtoms[i].name) + FREE(ad->targetAtoms[i].name); + if (ad->targetAtoms[i].atom) + FREE(ad->targetAtoms[i].atom); + } +} + +static Eina_Bool targets_converter(AppData *ad, Ecore_X_Atom reqAtom, CNP_ITEM *item, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *tsize) +{ + CALLED(); + + int count; + int i, j; + + for (i = 0, count = 0; i < ATOM_INDEX_MAX; i++) + { + if (ad->targetAtoms[item->type_index].convert_to_target[i]) + count += ad->targetAtoms[i].atom_cnt; + } + + *data_ret = MALLOC(sizeof(Ecore_X_Atom) * count); + DMSG("item_type: %d, target Atom cnt: %d\n", item->type_index, count); + if (!*data_ret) + return EINA_FALSE; + + for (i = 0, count = 0; i < ATOM_INDEX_MAX; i++) + { + if (ad->targetAtoms[item->type_index].convert_to_target[i]) + { + for(j = 0; j < ad->targetAtoms[i].atom_cnt; j++) + { + ((Ecore_X_Atom *)*data_ret)[count++] = ad->targetAtoms[i].atom[j]; + DMSG("send target atom: %s\n", ad->targetAtoms[i].name[j]); + } + } + } + + if (size_ret) *size_ret = count; + if (ttype) *ttype = ECORE_X_ATOM_ATOM; + if (tsize) *tsize = 32; + return EINA_TRUE; +} + +Eina_Bool generic_converter(AppData *ad, Ecore_X_Atom reqAtom, CNP_ITEM *item, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *tsize) +{ + CALLED(); + + if (ad->targetAtoms[ATOM_INDEX_TARGET].atom[0] == reqAtom) + return targets_converter(ad, reqAtom, item, data_ret, size_ret, ttype, tsize); + + int req_index = atom_type_index_get(ad, reqAtom); + int type_index = item->type_index; + + if (ad->targetAtoms[type_index].convert_to_target[req_index]) + { + *data_ret = ad->targetAtoms[type_index].convert_to_target[req_index](ad, type_index, item->data); + if (!*data_ret) + return EINA_FALSE; + if (size_ret) *size_ret = strlen(*data_ret); + if (ttype) *ttype = ad->targetAtoms[item->type_index].atom[0]; + if (tsize) *tsize = 8; + return EINA_TRUE; + } + + return EINA_FALSE; +} + +/* For convert EFL to HTML */ + +#define TAGPOS_START 0x00000001 +#define TAGPOS_END 0x00000002 +#define TAGPOS_ALONE 0x00000003 + +/* TEXTBLOCK tag using stack but close tag word has no mean maybe bug... + * TEXTBLOCK boldfontbold + * HTML boldfont boldfont */ + +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, "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, "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, "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, "", data->color); + else + eina_strbuf_append_printf(edje, "", data->color); + + } + if (data->size) + eina_strbuf_append_printf(edje, "", 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>", 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, ""); + if (data->size) + eina_strbuf_append_printf(edje, ""); + 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[] = { + { "", _PARAGRAPH_SEPARATOR }, + { "
", "\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 = ""; + char *html_img_tag = ""; + + 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, ""); + + 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, "
"); + 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, "", 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); +} diff --git a/src/xconverter.h b/src/xconverter.h new file mode 100644 index 0000000..b4a81f3 --- /dev/null +++ b/src/xconverter.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _X_ATOM_H_ +#define _X_ATOM_H_ + +enum ATOM_INDEX { + ATOM_INDEX_TARGET = 0, + ATOM_INDEX_TEXT = 1, + ATOM_INDEX_HTML = 2, + ATOM_INDEX_EFL = 3, + ATOM_INDEX_IMAGE = 4, + ATOM_INDEX_MAX = 5 +}; + +#include "cbhm.h" + +void init_target_atoms(AppData *ad); +void depose_target_atoms(AppData *ad); +int atom_type_index_get(AppData *ad, Ecore_X_Atom atom); +char *string_for_entry_get(AppData *ad, int type_index, const char *str); +Eina_Bool generic_converter(AppData *ad, Ecore_X_Atom reqAtom, CNP_ITEM *item, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *tsize); + +#endif diff --git a/src/xhandler.c b/src/xhandler.c new file mode 100644 index 0000000..3c758ad --- /dev/null +++ b/src/xhandler.c @@ -0,0 +1,621 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "xhandler.h" +#include +#include + +Ecore_X_Window get_selection_owner(AppData *ad, Ecore_X_Selection selection) +{ + CALLED(); + if (!ad) return 0; + Ecore_X_Atom sel = 0; + switch(selection) + { + case ECORE_X_SELECTION_SECONDARY: + sel = ECORE_X_ATOM_SELECTION_SECONDARY; + break; + case ECORE_X_SELECTION_CLIPBOARD: + sel = ECORE_X_ATOM_SELECTION_CLIPBOARD; + break; + default: + return 0; + } + return XGetSelectionOwner(ad->x_disp, sel); +} + +Eina_Bool is_cbhm_selection_owner(AppData *ad, Ecore_X_Selection selection) +{ + CALLED(); + if (!ad) return EINA_FALSE; + Ecore_X_Window sel_owner = get_selection_owner(ad, selection); + DMSG("selection_owner: 0x%x, x_event_win: 0x%x \n", sel_owner, ad->x_event_win); + if (sel_owner == ad->x_event_win) + return EINA_TRUE; + return EINA_FALSE; +} + +Eina_Bool set_selection_owner(AppData *ad, Ecore_X_Selection selection, CNP_ITEM *item) +{ + CALLED(); + if (!ad) return EINA_FALSE; + + if (!item && is_cbhm_selection_owner(ad, selection)) + return EINA_TRUE; + + Ecore_X_Atom sel = 0; + Eina_Bool (*selection_func)(Ecore_X_Window win, const void *data, int size) = NULL; + + switch(selection) + { + case ECORE_X_SELECTION_SECONDARY: +// ecore_x_selection_secondary_clear(); + selection_func = ecore_x_selection_secondary_set; + ad->clip_selected_item = item; + break; + case ECORE_X_SELECTION_CLIPBOARD: +// ecore_x_selection_clipboard_clear(); + selection_func = ecore_x_selection_clipboard_set; + break; + default: + return EINA_FALSE; + } + + if (selection_func(ad->x_event_win, NULL, 0)) + return EINA_TRUE; + + DMSG("ERROR: set selection failed\n"); + return EINA_FALSE; +} + +static Eina_Bool selection_timer_cb(void *data) +{ + CALLED(); + AppData *ad = data; + XHandlerData *xd = ad->xhandler; + + set_selection_owner(ad, ECORE_X_SELECTION_CLIPBOARD, NULL); + if (is_cbhm_selection_owner(ad, ECORE_X_SELECTION_CLIPBOARD)) + { + ecore_timer_del(xd->selection_timer); + xd->selection_timer = NULL; + return ECORE_CALLBACK_CANCEL; + } + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool _xsel_clear_cb(void *data, int type, void *event) +{ + CALLED(); + if (!data || !event) return EINA_TRUE; + AppData *ad = data; + XHandlerData *xd = ad->xhandler; + Ecore_X_Event_Selection_Clear *ev = event; + + DMSG("in %s, ev->win: 0x%x\n", __func__, ev->win); + + if (is_cbhm_selection_owner(ad, ev->selection)) return EINA_TRUE; + if (ev->selection != ECORE_X_SELECTION_CLIPBOARD) + return ECORE_CALLBACK_PASS_ON; + + ecore_x_selection_clipboard_request(ad->x_event_win, ECORE_X_SELECTION_TARGET_TARGETS); + + if (xd->selection_timer) + { + ecore_timer_del(xd->selection_timer); + xd->selection_timer = NULL; + } + xd->selection_timer = ecore_timer_add(SELECTION_CHECK_TIME, selection_timer_cb, ad); + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool _xsel_request_cb(void *data, int type, void *event) +{ + CALLED(); + if (!data || !event) return ECORE_CALLBACK_PASS_ON; + AppData *ad = data; + Ecore_X_Event_Selection_Request *ev = event; + +#ifdef DEBUG + char *names[3]; + DMSG("selection_owner: 0x%x, ev->... owner: 0x%x, req: 0x%x, selection: %s, target: %s, property: %s\n", + get_selection_owner(ad, ECORE_X_SELECTION_CLIPBOARD), ev->owner, ev->requestor, + names[0] = ecore_x_atom_name_get(ev->selection), + names[1] = ecore_x_atom_name_get(ev->target), + names[2] = ecore_x_atom_name_get(ev->property)); + FREE(names[0]); + FREE(names[1]); + FREE(names[2]); +#endif + + CNP_ITEM *item; + if (ev->selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) + item = item_get_last(ad); + else if (ev->selection == ECORE_X_ATOM_SELECTION_SECONDARY) + item = ad->clip_selected_item; + else + return ECORE_CALLBACK_PASS_ON; + + if (!item) + return ECORE_CALLBACK_PASS_ON; + + + Ecore_X_Atom property = None; + void *data_ret = NULL; + int size_ret; + Ecore_X_Atom ttype; + int tsize; + + if (!generic_converter(ad, ev->target, item, &data_ret, &size_ret, &ttype, &tsize)) + /* if (!ecore_x_selection_convert(ev->selection, + ev->target, + &data_ret, &len, &typeAtom, &typesize))*/ + + { + /* Refuse selection, conversion to requested target failed */ + DMSG("converter return FALSE\n"); + } + else if (data_ret) + { + /* FIXME: This does not properly handle large data transfers */ + ecore_x_window_prop_property_set( + ev->requestor, + ev->property, + ttype, + tsize, + data_ret, + size_ret); + property = ev->property; + FREE(data_ret); + DMSG("change property\n"); + } + + ecore_x_selection_notify_send(ev->requestor, + ev->selection, + ev->target, + property, + CurrentTime); + DMSG("change property notify\n"); + ecore_x_flush(); + return ECORE_CALLBACK_DONE; +} + +static void send_convert_selection_target(AppData *ad, Ecore_X_Selection_Data_Targets *targets_data) +{ + CALLED(); + /* struct _Ecore_X_Selection_Data_Targets { + Ecore_X_Selection_Data data; + struct _Ecore_X_Selection_Data { + enum { + ECORE_X_SELECTION_CONTENT_NONE, + ECORE_X_SELECTION_CONTENT_TEXT, + ECORE_X_SELECTION_CONTENT_FILES, + ECORE_X_SELECTION_CONTENT_TARGETS, + ECORE_X_SELECTION_CONTENT_CUSTOM + } content; + unsigned char *data; + int length; + int format; + int (*FREE)(void *data); + }; + + char **targets; + int num_targets; + };*/ + if (!targets_data || !ad) + return; + Ecore_X_Atom *atomlist = (Ecore_X_Atom *)targets_data->data.data; + if (!atomlist) + return; + + DMSG("targets_data->num_targets: 0x%x\n", targets_data->num_targets); + int i, j, k; + for (i = 0; i < targets_data->num_targets; i++) + { + DMSG("get target: %s\n", targets_data->targets[i]); + for (j = 0; j < ATOM_INDEX_MAX; j++) + { + for (k = 0; k < ad->targetAtoms[j].atom_cnt; k++) + { + if (!strcmp(targets_data->targets[i], ad->targetAtoms[j].name[k])) + { + DMSG("find matched target: %s\n", ad->targetAtoms[j].name[k]); + ecore_x_selection_clipboard_request(ad->x_event_win, ad->targetAtoms[j].name[k]); + return; + } + } + } + } + DMSG("ERROR: get target atom failed\n"); +} + +static Eina_Bool _add_selection_imagepath(AppData* ad, char *str) +{ + if (!ad || !str) + return EINA_FALSE; + DMSG("get FILE: %s\n", str); + char *slash = strchr(str, '/'); + while (slash && slash[0] == '/') + { + if (slash[1] != '/') + { + char *filepath; + filepath = strdup(slash); + if (filepath) + { + if (ecore_file_exists(filepath)) + { + item_add_by_data(ad, ad->targetAtoms[ATOM_INDEX_IMAGE].atom[0], filepath, strlen(filepath) + 1); + return EINA_TRUE; + } + else + FREE(filepath); + } + break; + } + slash++; + } + DMSG("Error : it isn't normal file = %s\n", str); + return EINA_FALSE; +} + +static void _get_selection_data_files(AppData* ad, Ecore_X_Selection_Data_Files *files_data) +{ +/* struct _Ecore_X_Selection_Data_Files { + Ecore_X_Selection_Data data; + char **files; + int num_files; + }; */ + + int i; + for (i = 0; i < files_data->num_files; i++) + { + _add_selection_imagepath(ad, files_data->files[i]); + } +} + +static Eina_Bool _xsel_notify_cb(void *data, int type, void *event) +{ + CALLED(); + if (!data || !event) + return ECORE_CALLBACK_PASS_ON; + + AppData *ad = data; + XHandlerData *xd = ad->xhandler; + if (xd->selection_timer) + { + ecore_timer_del(xd->selection_timer); + xd->selection_timer = NULL; + } + +/* struct _Ecore_X_Event_Selection_Notify + { + Ecore_X_Window win; + Ecore_X_Time time; + Ecore_X_Selection selection; + Ecore_X_Atom atom; + char *target; + void *data; + };*/ + Ecore_X_Event_Selection_Notify *ev = event; + + switch (ev->selection) + { + case ECORE_X_SELECTION_CLIPBOARD: + break; + case ECORE_X_SELECTION_SECONDARY: + case ECORE_X_SELECTION_PRIMARY: + case ECORE_X_SELECTION_XDND: + default: + return ECORE_CALLBACK_PASS_ON; + } + if (!ev->data) + goto set_clipboard_selection_owner; + +/* struct _Ecore_X_Selection_Data { + enum { + ECORE_X_SELECTION_CONTENT_NONE, + ECORE_X_SELECTION_CONTENT_TEXT, + ECORE_X_SELECTION_CONTENT_FILES, + ECORE_X_SELECTION_CONTENT_TARGETS, + ECORE_X_SELECTION_CONTENT_CUSTOM + } content; + unsigned char *data; + int length; + int format; + int (*FREE)(void *data); + };*/ + Ecore_X_Selection_Data *sel_data = ev->data; + switch (sel_data->content) + { + case ECORE_X_SELECTION_CONTENT_NONE: + DMSG("ECORE_X_SELECTION_CONTENT_NONE\n"); + break; + case ECORE_X_SELECTION_CONTENT_TEXT: + DMSG("ECORE_X_SELECTION_CONTENT_TEXT\n"); + /* struct _Ecore_X_Selection_Data_Text { + Ecore_X_Selection_Data data; + char *text; + }; + Ecore_X_Selection_Data_Text *text_data = ev->data;*/ + // DMSG("sel_data->data: 0x%x, text_data->text: 0x%x\n", sel_data->data, text_data->text); + break; + case ECORE_X_SELECTION_CONTENT_FILES: + DMSG("ECORE_X_SELECTION_CONTENT_FILES\n"); + _get_selection_data_files(ad, ev->data); + goto set_clipboard_selection_owner; + break; + case ECORE_X_SELECTION_CONTENT_TARGETS: + DMSG("ECORE_X_SELECTION_CONTENT_TARGETS\n"); + send_convert_selection_target(ad, ev->data); + goto set_clipboard_selection_owner; + break; + case ECORE_X_SELECTION_CONTENT_CUSTOM: + DMSG("ECORE_X_SELECTION_CONTENT_CUSTOM\n"); + break; + } +#ifdef DEBUG + char *name; + DMSG("get atom: %d(%s), target: %s, length: %d, format: %d\n", + ev->atom, name = ecore_x_atom_name_get(ev->atom), ev->target, sel_data->length, sel_data->format); + FREE(name); +#endif + + Ecore_X_Atom targetAtom = ecore_x_atom_get(ev->target); + char *stripstr = strndup(sel_data->data, sel_data->length); + DMSG("get data: %s, len: %d\n", stripstr, strlen(stripstr)); + if (atom_type_index_get(ad, targetAtom) == ATOM_INDEX_IMAGE) + { + _add_selection_imagepath(ad, stripstr); + FREE(stripstr); + } + else + item_add_by_data(ad, targetAtom, stripstr, strlen(stripstr) + 1); + +// FREE(stripstr); + +set_clipboard_selection_owner: + set_selection_owner(ad, ECORE_X_SELECTION_CLIPBOARD, NULL); + if (!is_cbhm_selection_owner(ad, ECORE_X_SELECTION_CLIPBOARD)) + xd->selection_timer = ecore_timer_add(SELECTION_CHECK_TIME, selection_timer_cb, ad); + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool _xclient_msg_cb(void *data, int type, void *event) +{ + CALLED(); + AppData *ad = data; + XHandlerData *xd = ad->xhandler; + + /* struct _Ecore_X_Event_Client_Message { + Ecore_X_Window win; + Ecore_X_Atom message_type; + int format; + union + { + char b[20]; + short s[10]; + long l[5]; + } data; + Ecore_X_Time time; + };*/ + Ecore_X_Event_Client_Message *ev = event; + + if (ev->message_type == xd->atomXKey_MSG) + { + DTRACE("XE:ClientMessage for Screen capture\n"); + capture_current_screen(ad); + return TRUE; + } + + if (ev->message_type != xd->atomCBHM_MSG) + return -1; + + DTRACE("## %s\n", ev->data.b); + +/* Atom cbhm_atoms[ITEM_CNT_MAX]; + char atomname[10]; + Ecore_X_Window reqwin = ev->win;*/ + + if (strncmp("show", ev->data.b, 4) == 0) + { + ad->x_active_win = ev->win; + if (ev->data.b[4] == '1') + clipdrawer_paste_textonly_set(ad, EINA_FALSE); + else + clipdrawer_paste_textonly_set(ad, EINA_TRUE); + + clipdrawer_activate_view(ad); + } + else if (!strcmp("cbhm_hide", ev->data.b)) + { + clipdrawer_lower_view(ad); + } + else if (!strcmp("get count", ev->data.b)) + { + int icount = item_count_get(ad); + char countbuf[10]; + DMSG("## cbhm count : %d\n", icount); + snprintf(countbuf, 10, "%d", icount); + ecore_x_window_prop_property_set( + ev->win, + xd->atomCBHMCount, + xd->atomUTF8String, + 8, + countbuf, + strlen(countbuf)); + } +/* else if (strncmp("get #", ev->data.b, 5) == 0) + { + // FIXME : handle greater than 9 + int num = ev->data.b[5] - '0'; + int cur = get_current_history_position(); + num = cur + num - 1; + if (num > ITEMS_CNT_MAX-1) + num = num-ITEMS_CNT_MAX; + + if (num >= 0 && num < ITEMS_CNT_MAX) + { + DTRACE("## pos : #%d\n", num); + // FIXME : handle with correct atom + sprintf(atomname, "CBHM_c%d", num); + cbhm_atoms[0] = XInternAtom(g_disp, atomname, False); + + CNP_ITEM *item = clipdr; + + + if (clipdrawer_get_item_data(ad, num) != NULL) + { + XChangeProperty(g_disp, reqwin, cbhm_atoms[0], atomUTF8String, + 8, PropModeReplace, + (unsigned char *) clipdrawer_get_item_data(ad, num), + (int) strlen(clipdrawer_get_item_data(ad, num))); + } + } + } + else if (strcmp("get all", ev->data.b) == 0) + { +// print_history_buffer(); + pos = get_current_history_position(); + for (i = 0; i < 5; i++) + { + DTRACE("## %d -> %d\n", i, pos); + sprintf(atomname, "CBHM_c%d", i); + cbhm_atoms[i] = XInternAtom(g_disp, atomname, False); + if (clipdrawer_get_item_data(ad, pos) != NULL) + { + XChangeProperty(g_disp, reqwin, cbhm_atoms[i], atomUTF8String, + 8, PropModeReplace, + (unsigned char *) clipdrawer_get_item_data(ad, pos), + (int) strlen(clipdrawer_get_item_data(ad, pos))); + } + pos--; + if (pos < 0) + pos = ITEMS_CNT_MAX-1; + } + }*/ +/* else if (strcmp("get raw", ev->data.b) == 0) + { + + if (get_storage_start_addr != NULL) + { + XChangeProperty(g_disp, reqwin, atomCBHM_cRAW, atomUTF8String, + 8, PropModeReplace, + (unsigned char *) get_storage_start_addr(), + (int) get_total_storage_size()); + } + } + */ + XFlush(ad->x_disp); + + return EINA_TRUE; +} + +static Eina_Bool _xfocus_out_cb(void *data, int type, void *event) +{ + CALLED(); + AppData *ad = data; + DTRACE("XE:FOCUS OUT\n"); + clipdrawer_lower_view(ad); + return EINA_TRUE; +} + +static Eina_Bool _xproperty_notify_cb(void *data, int type, void *event) +{ +// CALLED(); + AppData *ad = data; + XHandlerData *xd = ad->xhandler; + ClipdrawerData *cd = ad->clipdrawer; + Ecore_X_Event_Window_Property *pevent = (Ecore_X_Event_Window_Property *)event; + + if (ad->x_active_win != pevent->win) + return EINA_TRUE; + + if (xd->atomWindowRotate == pevent->atom) + { + int angle = get_active_window_degree(ad->x_active_win); + if (angle != cd->o_degree) + { + cd->o_degree = angle; + elm_win_rotation_set(cd->main_win, angle); + set_rotation_to_clipdrawer(cd); + } + } + + return EINA_TRUE; +} + +static Eina_Bool _xwin_destroy_cb(void *data, int type, void *event) +{ + CALLED(); + AppData *ad = data; + Ecore_X_Event_Window_Destroy *pevent = event; + if (ad->x_active_win != pevent->win) + return EINA_TRUE; + clipdrawer_lower_view(ad); +} + +XHandlerData *init_xhandler(AppData *ad) +{ + XHandlerData *xd = CALLOC(1, sizeof(XHandlerData)); + if (!xd) + return NULL; + xd->xsel_clear_handler = ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR, _xsel_clear_cb, ad); + xd->xsel_request_handler = ecore_event_handler_add(ECORE_X_EVENT_SELECTION_REQUEST, _xsel_request_cb, ad); + xd->xsel_notify_handler = ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY, _xsel_notify_cb, ad); + xd->xclient_msg_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _xclient_msg_cb, ad); + xd->xfocus_out_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _xfocus_out_cb, ad); + xd->xproperty_notify_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _xproperty_notify_cb, ad); + xd->xwindow_destroy_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _xwin_destroy_cb, ad); + + xd->atomInc = ecore_x_atom_get("INCR"); + xd->atomWindowRotate = ecore_x_atom_get("_E_ILLUME_ROTATE_WINDOW_ANGLE"); + xd->atomCBHM_MSG = ecore_x_atom_get("CBHM_MSG"); + xd->atomXKey_MSG = ecore_x_atom_get("_XKEY_COMPOSITION"); + xd->atomCBHMCount = ecore_x_atom_get("CBHM_cCOUNT"); + xd->atomUTF8String = ecore_x_atom_get("UTF8_STRING"); + return xd; +} + +void depose_xhandler(XHandlerData *xd) +{ + ecore_event_handler_del(xd->xsel_clear_handler); + ecore_event_handler_del(xd->xsel_request_handler); + ecore_event_handler_del(xd->xsel_notify_handler); + ecore_event_handler_del(xd->xclient_msg_handler); + ecore_event_handler_del(xd->xfocus_out_handler); + ecore_event_handler_del(xd->xproperty_notify_handler); + ecore_event_handler_del(xd->xwindow_destroy_handler); + FREE(xd); +} + +int get_active_window_degree(Ecore_X_Window active) +{ + //ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE + + int rotation = 0; + unsigned char *prop_data = NULL; + int count; + int ret = ecore_x_window_prop_property_get( + active, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, + ECORE_X_ATOM_CARDINAL, 32, &prop_data, &count); + if (ret && prop_data) memcpy(&rotation, prop_data, sizeof(int)); + if (prop_data) FREE(prop_data); + return rotation; +} diff --git a/src/xhandler.h b/src/xhandler.h new file mode 100644 index 0000000..18a446a --- /dev/null +++ b/src/xhandler.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _XCNPHANDLER_H_ +#define _XCNPHANDLER_H_ + +#include +#include + +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 -- 2.7.4