init upload
authorHyoyoung Chang <hyoyoung.chang@samsung.com>
Tue, 14 Sep 2010 12:32:13 +0000 (21:32 +0900)
committerHyoyoung Chang <hyoyoung.chang@samsung.com>
Tue, 14 Sep 2010 12:32:13 +0000 (21:32 +0900)
19 files changed:
CMakeLists.txt [new file with mode: 0755]
data/themes/cbhmdrawer.edc [new file with mode: 0644]
debian/cbhm.install.in [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0755]
debian/copyright [new file with mode: 0644]
debian/dirs [new file with mode: 0644]
debian/docs [new file with mode: 0644]
debian/rules [new file with mode: 0755]
src/cbhm_main.c [new file with mode: 0644]
src/cbhm_main.h [new file with mode: 0755]
src/clipdrawer.c [new file with mode: 0644]
src/clipdrawer.h [new file with mode: 0644]
src/common.h [new file with mode: 0644]
src/storage.c [new file with mode: 0644]
src/storage.h [new file with mode: 0644]
src/xcnphandler.c [new file with mode: 0755]
src/xcnphandler.h [new file with mode: 0755]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..abafcc7
--- /dev/null
@@ -0,0 +1,38 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(cbhm C)
+
+SET(SRCS src/cbhm_main.c
+       src/clipdrawer.c
+       src/storage.c
+       src/xcnphandler.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED elementary appcore-efl appcore-common x11 ecore-x)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+#SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -finstrument-functions")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+ADD_DEFINITIONS("-DTARGET")
+ADD_DEFINITIONS("-DSLP_DEBUG")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+ADD_CUSTOM_TARGET(cbhmdrawer.edj 
+               COMMAND edje_cc 
+               ${CMAKE_SOURCE_DIR}/data/themes/cbhmdrawer.edc ${CMAKE_BINARY_DIR}/data/themes/cbhmdrawer.edj
+               DEPENDS ${CMAKE_SOURCE_DIR}/data/themes/cbhmdrawer.edc
+)
+ADD_DEPENDENCIES(${PROJECT_NAME} cbhmdrawer.edj)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/data/themes/cbhmdrawer.edj DESTINATION share/edje)
diff --git a/data/themes/cbhmdrawer.edc b/data/themes/cbhmdrawer.edc
new file mode 100644 (file)
index 0000000..4699775
--- /dev/null
@@ -0,0 +1,54 @@
+#define MAIN_W 480
+#define MAIN_H 400
+
+collections 
+{
+       group 
+       {
+               name: "cbhmdrawer";
+               //min: MAIN_W MAIN_H;
+               //max: MAIN_W MAIN_H;
+
+               parts 
+               {
+                       part 
+                       { 
+                               name: "background";
+                               type: RECT;
+                               mouse_events: 1;
+                               description 
+                               {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.0 0.0; }
+                                       rel2 { relative: 1.0 1.0; }
+                                       color: 100 100 100 255;
+                               }
+                       }
+
+                       part 
+                       {
+                               name: "cbhmdrawer/imglist";
+                               type: SWALLOW;
+                               mouse_events: 1;
+                               description
+                               {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.0 0.0; to: background; }
+                                       rel2 { relative: 1.0 0.4; to: background; }
+                               }
+                       }
+                       part 
+                       {
+                               name: "cbhmdrawer/txtlist";
+                               type: SWALLOW;
+                               mouse_events: 1;
+                               description
+                               {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.0 0.4; to: background; }
+                                       rel2 { relative: 1.0 1.0; to: background; }
+                               }
+                       }
+               }
+       }
+}
diff --git a/debian/cbhm.install.in b/debian/cbhm.install.in
new file mode 100644 (file)
index 0000000..cb17b09
--- /dev/null
@@ -0,0 +1,2 @@
+@PREFIX@/bin/*
+@PREFIX@/share/*
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..0dce12f
--- /dev/null
@@ -0,0 +1,6 @@
+cbhm (0.1.0-1) unstable; urgency=low
+
+  * init
+
+ -- Hyoyoung Chang <hyoyoung.chang@samsung.com>  Fri, 28 May 2010 10:40:00 +0900
+
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100755 (executable)
index 0000000..ed85b0a
--- /dev/null
@@ -0,0 +1,12 @@
+Source: cbhm
+Section: devel
+Priority: extra
+Maintainer: Hyoyoung Chang <hyoyoung.chang@samsung.com>
+Build-Depends: debhelper (>= 5), libelm-dev, libappcore-efl-dev
+Standards-Version: 0.1.1
+
+Package: cbhm
+Section: admin
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: cbhm application
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..dc32d87
--- /dev/null
@@ -0,0 +1,23 @@
+This is $PACKAGE_NAME, written and maintained by $NAME <$EMAIL>
+on Fri, 13 Nov 2009 14:08:22 +0900.
+
+The original source can always be found at:
+        ftp://slp.samsung.net/dists/unstable/main/source/
+
+Copyright Holder: $NAME
+
+License:
+        samsung
+
+/*
+ * SLP2.0
+ * Copyright (c) 2008 Samsung Electronics, Inc.
+ * All rights reserved.
+ *
+ * This software is a confidential and proprietary information
+ * of Samsung Electronics, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Samsung Electronics.
+ */
+
diff --git a/debian/dirs b/debian/dirs
new file mode 100644 (file)
index 0000000..ca882bb
--- /dev/null
@@ -0,0 +1,2 @@
+usr/bin
+usr/sbin
diff --git a/debian/docs b/debian/docs
new file mode 100644 (file)
index 0000000..a0f0008
--- /dev/null
@@ -0,0 +1 @@
+CMakeLists.txt
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..18bee42
--- /dev/null
@@ -0,0 +1,127 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+CFLAGS ?= -Wall -g
+CXXFLAGS ?=  -Wall -g
+LDFLAGS ?= 
+PREFIX ?= /usr
+DATADIR ?= /opt
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+       CFLAGS += -O0
+       CXXFLAGS += -O0
+else
+       CFLAGS += -O2
+       CXXFLAGS += -O2
+endif
+
+LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed
+
+configure: configure-stamp
+configure-stamp:
+       dh_testdir
+       # Add here commands to configure the package.
+       CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" cmake . -DCMAKE_INSTALL_PREFIX=$(PREFIX)
+
+       touch configure-stamp
+
+build: build-stamp
+
+build-stamp: configure-stamp 
+       dh_testdir
+
+       # Add here commands to compile the package.
+       $(MAKE)
+       #docbook-to-man debian/wavplayer.sgml > wavplayer.1
+
+       for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+               cat $$f > $${f%.in}; \
+               sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \
+               sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \
+       done
+
+
+       touch $@
+
+clean:
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp configure-stamp
+
+       # Add here commands to clean up after the build process.
+       -$(MAKE) clean
+       rm -rf CMakeCache.txt
+       rm -rf CMakeFiles
+       rm -rf cmake_install.cmake
+       rm -rf Makefile
+       rm -rf install_manifest.txt
+       rm -rf *.so
+       rm -rf *.edj
+
+       rm -rf po/CMakeCache.txt
+       rm -rf po/CMakeFiles
+       rm -rf po/cmake_install.cmake
+       rm -rf po/install_manifest.txt
+       rm -rf po/Makefile
+
+       for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+               rm -f $${f%.in}; \
+       done
+
+       dh_clean 
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k 
+       dh_installdirs
+
+       # Add here commands to install the package into debian/wavplayer.
+       $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+       dh_installchangelogs 
+       dh_installdocs
+       dh_installexamples
+       dh_install --sourcedir=debian/tmp
+#      dh_installmenu
+#      dh_installdebconf       
+#      dh_installlogrotate
+#      dh_installemacsen
+#      dh_installpam
+#      dh_installmime
+#      dh_python
+#      dh_installinit
+#      dh_installcron
+#      dh_installinfo
+       dh_installman
+       dh_link
+       dh_strip
+       dh_compress
+       dh_fixperms
+#      dh_perl
+       dh_makeshlibs
+       dh_installdeb
+       dh_shlibdeps
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/src/cbhm_main.c b/src/cbhm_main.c
new file mode 100644 (file)
index 0000000..5b63b10
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * SLP2
+ * Copyright (c) 2009 Samsung Electronics, Inc.
+ * All rights reserved.
+ *
+ * This software is a confidential and proprietary information
+ * of Samsung Electronics, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Samsung Electronics.
+ */
+
+#include <stdio.h>
+#include <Elementary.h>
+#include <Ecore_X.h>
+#include <utilX.h>
+//#include <appcore-efl.h>
+
+#include "common.h"
+#include "cbhm_main.h"
+#include "xcnphandler.h"
+#include "clipdrawer.h"
+
+#ifndef _EDJ
+#define _EDJ(ly) elm_layout_edje_get(ly)
+#endif
+
+static Evas_Object* create_win(const char *name);
+static Evas_Object* load_edj(Evas_Object *parent, const char *file, const char *group);
+
+static void win_del_cb(void *data, Evas_Object *obj, void *event)
+{
+       elm_exit();
+}
+
+static void main_quit_cb(void *data, Evas_Object* obj, void* event_info)
+{
+       elm_exit();
+}
+
+int init_appview(void *data)
+{
+       struct appdata *ad = (struct appdata *) data;
+       Evas_Object *win, *ly;
+
+       win = create_win(APPNAME);
+       if(win == NULL)
+               return -1;
+       ad->evas = evas_object_evas_get(win);
+       ad->win_main = win;
+
+       ly = load_edj(win, EDJ_FILE, GRP_MAIN);
+       if (ly == NULL)
+               return -1; 
+       elm_win_resize_object_add(win, ly);
+       edje_object_signal_callback_add(elm_layout_edje_get(ly), "EXIT", "*", main_quit_cb, NULL);
+       ad->ly_main = ly;
+
+       evas_object_show(ly);
+
+       clipdrawer_create_view(ad);
+
+       evas_object_show(win);
+
+       return 0;
+}
+
+static Evas_Object* create_win(const char *name)
+{
+       Evas_Object *eo;
+       int w, h;
+
+       eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
+       if (eo)
+    {
+               elm_win_title_set(eo, name);
+               elm_win_borderless_set(eo, EINA_TRUE);
+               evas_object_smart_callback_add(eo, "delete,request", win_del_cb, NULL);
+               ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
+               evas_object_resize(eo, w, h);
+       }
+
+       return eo;
+}
+
+static Evas_Object* load_edj(Evas_Object *parent, const char *file, const char *group)
+{       
+       Evas_Object *eo;
+       int r;
+
+       eo = elm_layout_add(parent);
+       if (eo) 
+       {
+               r = elm_layout_file_set(eo, file, group);
+               if (!r) 
+               {
+                       evas_object_del(eo);
+                       return NULL;
+               }
+
+               evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+               elm_win_resize_object_add(parent, eo);
+       }
+
+       return eo;
+}
+
+static int init(struct appdata *ad)
+{
+       xcnp_init(ad);
+       init_appview(ad);
+
+       return 0;
+}
+
+static void fini(struct appdata *ad)
+{
+       if (ad->ly_main)
+               evas_object_del(ad->ly_main);
+
+       if (ad->win_main)
+               evas_object_del(ad->win_main);
+}
+
+static void init_ad(struct appdata *ad)
+{
+       memset(ad, 0x0, sizeof(struct appdata));
+}
+
+EAPI int elm_main(int argc, char **argv)
+{
+       struct appdata ad;
+
+       init_ad(&ad);
+
+       if(!init(&ad))
+               elm_run();
+
+       fini(&ad);
+
+       elm_shutdown();
+
+       return EXIT_SUCCESS;
+}
+
+int main( int argc, char *argv[] )
+{
+       setenv("ELM_THEME", "beat", 1); // not recommended way
+
+       elm_init(argc, argv);
+
+       return elm_main(argc, argv);
+}
diff --git a/src/cbhm_main.h b/src/cbhm_main.h
new file mode 100755 (executable)
index 0000000..d3ae688
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _cbhm_main_h_
+#define _cbhm_main_h_
+
+#include <Elementary.h>
+
+#define APPNAME "cbhm"
+#define LOCALEDIR "/usr/share/locale"
+
+#define EDJ_PATH "/usr/share/edje"
+#define EDJ_FILE "/usr/share/edje/cbhmdrawer.edj"
+#define GRP_MAIN "cbhmdrawer"
+
+struct appdata
+{
+       Evas *evas;
+       Evas_Object *win_main;
+       Evas_Object *ly_main; /* layout widget based on EDJ */
+       /* add more variables here */
+       Evas_Object *scrl;
+       Evas_Object *imgbox; 
+       Evas_Object *txtlist; 
+};
+
+#endif /* _cbhm_main_h_ */
+
diff --git a/src/clipdrawer.c b/src/clipdrawer.c
new file mode 100644 (file)
index 0000000..5182c8a
--- /dev/null
@@ -0,0 +1,137 @@
+#include "common.h"
+#include "clipdrawer.h"
+#include "cbhm_main.h"
+#include "storage.h"
+
+#ifndef _EDJ
+#define _EDJ(ly) elm_layout_edje_get(ly)
+#endif
+
+#define IM     "/mnt/ums/Images/Wallpapers/"
+static const char *images[] = {
+       IM"TFT_01_480x800.jpg",
+       IM"TFT_02_480x800.jpg",
+       IM"TFT_03_480x800.jpg",
+       IM"TFT_04_480x800.jpg",
+       IM"TFT_05_480x800.jpg",
+       IM"OCTA_01_480x800.jpg",
+       IM"OCTA_02_480x800.jpg",
+       IM"OCTA_03_480x800.jpg",
+       IM"OCTA_04_480x800.jpg",
+       IM"OCTA_05_480x800.jpg",
+};
+#define N_IMAGES (10)
+
+static void _list_click( void *data, Evas_Object *obj, void *event_info )
+{
+    Elm_List_Item *it = (Elm_List_Item *) elm_list_selected_item_get( obj );
+       if (it == NULL)
+               return;
+
+    elm_list_item_selected_set(it, 0);
+
+       char *p = NULL;
+       char *cpdata = NULL;
+       int clen;
+
+       cpdata = elm_list_item_label_get(it);
+       if (cpdata == NULL)
+               return;
+       clen = strlen(cpdata);
+       p = malloc(clen + 1);
+       snprintf(p, clen, "%s", cpdata);
+       fprintf(stderr, "## cbhm : sel : %s\n", p);
+       elm_selection_set(1, obj, /*mark up*/1, p);
+}
+
+int clipdrawer_update_contents(void *data)
+{
+       struct appdata *ad = data;
+       int i, pos;
+
+       elm_list_clear(ad->txtlist);
+       for (i = 0; i < HISTORY_QUEUE_NUMBER; i++)
+       {
+               pos = get_current_history_position()+i;
+               if (pos > HISTORY_QUEUE_NUMBER-1)
+                       pos = pos-HISTORY_QUEUE_NUMBER;
+               if (get_item_contents_by_pos(pos) != NULL)
+                       elm_list_item_append(ad->txtlist, get_item_contents_by_pos(pos), NULL, NULL, NULL, ad);
+       }
+       elm_list_go(ad->txtlist);
+
+       return 0;
+}
+
+static int clipdrawer_init(void *data)
+{
+       struct appdata *ad = data;
+
+       evas_object_resize(ad->win_main, 480, 400);
+       evas_object_move(ad->win_main, 0, 400);
+       evas_object_resize(ad->ly_main, 480, 400);
+       evas_object_move(ad->ly_main, 0, 400);
+
+       ad->scrl = elm_scroller_add(ad->win_main);
+       edje_object_part_swallow(_EDJ(ad->ly_main), "cbhmdrawer/imglist", ad->scrl);
+       evas_object_size_hint_weight_set(ad->scrl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_scroller_bounce_set(ad->scrl, EINA_TRUE, EINA_FALSE);
+       elm_scroller_policy_set(ad->scrl, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
+       elm_win_resize_object_add(ad->win_main, ad->scrl);
+       evas_object_show(ad->scrl);
+
+       evas_object_resize(ad->scrl,480,95);
+       ad->imgbox = elm_box_add(ad->win_main);
+       elm_box_horizontal_set(ad->imgbox, TRUE);
+       evas_object_size_hint_weight_set(ad->imgbox, EVAS_HINT_EXPAND, 0);
+       evas_object_size_hint_align_set(ad->imgbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
+       elm_scroller_content_set(ad->scrl, ad->imgbox);
+       evas_object_show(ad->imgbox);
+
+       Evas_Object *pt;
+       int i;
+       for (i = 0 ; i < N_IMAGES ; i ++)
+       {
+               pt = elm_photo_add(ad->win_main);
+               elm_photo_file_set(pt, images[i]);
+               evas_object_size_hint_weight_set(pt, EVAS_HINT_EXPAND,
+                               EVAS_HINT_EXPAND);
+               evas_object_size_hint_align_set(pt, EVAS_HINT_FILL,
+                               EVAS_HINT_FILL);
+               elm_photo_size_set(pt, 145);
+               elm_box_pack_end(ad->imgbox, pt);
+               evas_object_show(pt);
+               evas_object_data_set(pt,"URI",images[i]);
+       }
+
+       ad->txtlist = elm_list_add(ad->win_main);
+       elm_layout_content_set(ad->ly_main, "cbhmdrawer/txtlist", ad->txtlist);
+       elm_list_horizontal_mode_set(ad->txtlist, ELM_LIST_COMPRESS);
+       evas_object_smart_callback_add(ad->txtlist, "selected", _list_click, ad);
+       elm_list_item_append(ad->txtlist, "default", NULL, NULL, NULL, ad);
+
+       elm_list_go(ad->txtlist);
+
+       if (get_item_counts() != 0)
+               clipdrawer_update_contents(ad);
+
+       return 0;
+}
+
+int clipdrawer_create_view(void *data)
+{
+       struct appdata *ad = data;
+
+       clipdrawer_init(ad);
+
+       return 0;
+}
+
+void clipdrawer_activate_view(void *data)
+{
+       struct appdata *ad = data;
+       
+       if (ad->win_main)
+               elm_win_activate(ad->win_main);
+}
diff --git a/src/clipdrawer.h b/src/clipdrawer.h
new file mode 100644 (file)
index 0000000..efd0e0c
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _clipdrawer_h_
+#define _clipdrawer_h_
+
+static int clipdrawer_init();
+int clipdrawer_update_contents(void *data);
+int clipdrawer_create_view();
+void clipdrawer_activate_view();
+
+#endif // _clipdrawer_h_
diff --git a/src/common.h b/src/common.h
new file mode 100644 (file)
index 0000000..f2fedee
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _common_h_
+#define _common_h_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define DEBUG 
+
+#ifdef DEBUG
+#define DTRACE(fmt, args...) \
+{do { fprintf(stderr, "[CBHM][%s:%04d] " fmt, __func__,__LINE__, ##args); } while (0); }
+#else
+#define DTRACE(fmt, args...) 
+#endif
+
+struct appdata;
+
+#define HISTORY_QUEUE_NUMBER 5
+
+#endif // _common_h_
diff --git a/src/storage.c b/src/storage.c
new file mode 100644 (file)
index 0000000..014fb90
--- /dev/null
@@ -0,0 +1,156 @@
+#include "common.h"
+#include "storage.h"
+
+#define STORAGE_FILEPATH "/tmp/.savecbh"
+#define STORAGE_MAX_ITEMS HISTORY_QUEUE_NUMBER
+#define HEADER_ITEM_SIZE (sizeof(int)) 
+#define BODY_ITEM_SIZE (4 * 1024) // 4Kilo 
+#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_ITEM_ADDR_BY_POSITION(map, pos) (map+STORAGE_HEADER_SIZE+pos*BODY_ITEM_SIZE)
+
+static int g_storage_fd = 0;
+static unsigned int g_storage_serial_number = 0;
+static char *g_map = NULL;
+
+int init_storage()
+{
+       int i;
+       int result = 0;
+
+       if (g_storage_fd != 0)
+               return 1;
+
+       g_storage_fd = open(STORAGE_FILEPATH, O_RDWR | O_CREAT, (mode_t)0600);
+       if (g_storage_fd == -1)
+       {
+               g_storage_fd = 0;
+               close_storage();
+               DTRACE("Error : failed openning file for writing\n");
+               return -1;
+       }
+
+    result = lseek(g_storage_fd, TOTAL_STORAGE_SIZE-1, SEEK_SET);
+    if (result == -1) 
+       {
+               close_storage();
+               DTRACE("Error : failed moving file position to file's end\n");
+               return -1;
+    }
+    
+    result = write(g_storage_fd, "", 1);
+    if (result != 1) 
+       {
+               close_storage();
+               DTRACE("Error : failed writing to file's end\n");
+               return -1;
+    }
+
+       g_map = mmap(0, TOTAL_STORAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_storage_fd, 0);
+       if (g_map == MAP_FAILED)
+       {
+               close_storage();
+               DTRACE("Error : failed mmapping the file\n");
+               return -1;
+       }
+
+       // FIXME : do not unconditionaly initialize, maybe old data can be
+       // at here
+       int *header = g_map;
+       for (i = 0; i < STORAGE_MAX_ITEMS; i++)
+       {
+               char d = 0;
+               header[i] = 0;
+               memcpy(GET_ITEM_ADDR_BY_POSITION(g_map, i), &d, 1);
+       }
+       DTRACE("Success : storage init is done\n");
+
+       g_storage_serial_number = 0;
+
+       return 0;
+}
+
+int sync_storage()
+{
+       if (g_map == NULL)
+       {
+               DTRACE("g_map is null\n");
+               return -1;
+       }
+       msync(g_map, TOTAL_STORAGE_SIZE, MS_ASYNC);
+
+       return 0;
+}
+
+int get_total_storage_size()
+{
+       return TOTAL_STORAGE_SIZE;
+}
+
+unsigned int get_storage_serial_code()
+{
+       return g_storage_serial_number;
+}
+
+int adding_item_to_storage(int pos, char *data)
+{
+       int *header = get_storage_start_addr();
+
+       if (g_map == NULL)
+       {
+               DTRACE("g_map is null");
+               return -1;
+       }
+       // saving relative addr at header
+       header[pos] = STORAGE_HEADER_SIZE+pos*BODY_ITEM_SIZE; 
+       memcpy(GET_ITEM_ADDR_BY_POSITION(g_map, pos), data, BODY_ITEM_SIZE);
+       g_storage_serial_number++;
+       return 0;
+}
+
+char *get_storage_start_addr()
+{
+       return g_map;
+}
+
+int get_item_counts()
+{
+       int i, count;
+       int *header = get_storage_start_addr();
+
+       count = 0;
+       for (i = 0; i < STORAGE_MAX_ITEMS; i++)
+       {
+               if (header[i] != 0)
+                       count++;
+       }
+       return count;
+}
+
+char *get_item_contents_by_pos(int pos)
+{
+       if (g_map == NULL)
+       {
+               DTRACE("g_map is null");
+               return NULL;
+       }
+       return GET_ITEM_ADDR_BY_POSITION(g_map, pos);
+}
+
+int close_storage()
+{
+       if (g_map)
+               munmap(g_map, TOTAL_STORAGE_SIZE);
+       g_map = NULL;
+
+       if (g_storage_fd)
+               close(g_storage_fd);
+       g_storage_fd = 0;
+       g_storage_serial_number = 0;
+
+       return 0;
+}
+
+
diff --git a/src/storage.h b/src/storage.h
new file mode 100644 (file)
index 0000000..352f701
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _storage_h_
+#define _storage_h_
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+int init_storage();
+int sync_storage();
+unsigned int get_storage_serial_code();
+int adding_item_to_storage(int pos, char *data);
+char *get_storage_start_addr();
+int get_item_counts();
+char *get_item_contents_by_pos(int pos);
+int close_storage();
+
+#endif // _storage_h_
diff --git a/src/xcnphandler.c b/src/xcnphandler.c
new file mode 100755 (executable)
index 0000000..ac64799
--- /dev/null
@@ -0,0 +1,482 @@
+#include "common.h"
+#include "cbhm_main.h"
+#include "xcnphandler.h"
+#include "storage.h"
+#include "clipdrawer.h"
+
+static Ecore_Event_Handler *xsel_clear_handler = NULL;
+static Ecore_Event_Handler *xsel_request_handler = NULL;
+static Ecore_Event_Handler *xsel_notify_handler = NULL;
+static Ecore_Event_Handler *xclient_msg_handler = NULL;
+
+char *g_lastest_content = NULL;
+int g_history_pos = 0;
+
+int xcnp_init(void *data)
+{
+       struct appdata *ad = data;
+       DTRACE("xcnp_init().. start!\n");
+
+       if(!_cbhm_init())
+       {
+               DTRACE("Failed - _cbhm_init()..!\n");
+               return NULL;
+       }
+
+       //Adding Event Handlers
+       xsel_clear_handler = ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR, _xsel_clear_cb, ad);
+       xsel_request_handler = ecore_event_handler_add(ECORE_X_EVENT_SELECTION_REQUEST, _xsel_request_cb, ad);
+       xsel_notify_handler = ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY, _xsel_notify_cb, ad);
+       xclient_msg_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _xclient_msg_cb, ad);
+
+       if(!xsel_clear_handler)
+               DTRACE("Failed to add ECORE_X_EVENT_SELECTION_CLEAR handler\n");
+       if(!xsel_request_handler)
+               DTRACE("Failed to add ECORE_X_EVENT_SELECTION_REQUEST handler\n");
+       if(!xsel_notify_handler)
+               DTRACE("Failed to add ECORE_X_EVENT_SELECTION_NOTIFY handler\n");
+       if(!xclient_msg_handler)
+               DTRACE("Failed to add ECORE_X_EVENT_CLIENT_MESSAGE handler\n");
+
+       return TRUE;
+}
+
+int xcnp_shutdown()
+{
+       //Removing Event Handlers
+       ecore_event_handler_del(xsel_clear_handler);
+       ecore_event_handler_del(xsel_request_handler);
+       ecore_event_handler_del(xsel_notify_handler);
+       ecore_event_handler_del(xclient_msg_handler);
+
+       xsel_clear_handler = NULL;
+       xsel_request_handler = NULL;
+       xsel_notify_handler = NULL;
+       xclient_msg_handler = NULL;
+
+       _cbhm_fini();
+
+       return TRUE;
+}
+
+static int _init_atoms()
+{
+       /* all atoms are global variables */
+       atomPrimary = XA_PRIMARY; 
+       atomTarget = XA_STRING;
+       atomClipboard = XInternAtom(g_disp, ATOM_CLIPBOARD_NAME, False);
+       atomCBHM = XInternAtom (g_disp, ATOM_CLIPBOARD_MANAGER_NAME, False);
+       atomCBOut = XInternAtom(g_disp, ATOM_CBHM_OUTBUF, False);
+       atomInc = XInternAtom(g_disp, "INCR", False);
+       atomTargets = XInternAtom(g_disp, "TARGETS", False);
+       atomUTF8String = XInternAtom(g_disp, "UTF8_STRING", False);
+
+       return TRUE;
+}
+
+static void _set_cbhmwin_prop()
+{
+       Atom atomCbhmWin = XInternAtom(g_disp, "CBHM_XWIN", False);
+       XChangeProperty(g_disp, g_rootwin, atomCbhmWin, XA_WINDOW, 
+                                       32, PropModeReplace,
+                                       (unsigned char *)&g_evtwin, (int) 1);
+}
+
+int increment_current_history_position()
+{
+       int pos = g_history_pos+1;
+       if (pos >= HISTORY_QUEUE_NUMBER)
+               pos = 0;
+       g_history_pos = pos;
+       return pos;
+}
+
+int get_current_history_position()
+{
+       int pos = g_history_pos-1;
+       if (pos < 0)
+               pos = HISTORY_QUEUE_NUMBER;
+       
+       return pos;
+}
+
+int add_to_storage_buffer(void *data, char *src, int len)
+{
+       struct appdata *ad = data;
+
+       if (len <= 0)
+               return -1;
+
+       if (g_lastest_content == NULL)
+               g_lastest_content = malloc(sizeof(char)*(4*1024));
+       if (g_history_pos >= HISTORY_QUEUE_NUMBER)
+               g_history_pos = 0;
+
+       // FIXME: remove g_lasteset_content
+       strcpy(g_lastest_content, src);
+       adding_item_to_storage(g_history_pos, g_lastest_content);
+       increment_current_history_position();
+
+       int nserial = 0;
+       nserial = get_storage_serial_code();
+       Atom atomCbhmSerial = XInternAtom(g_disp, "CBHM_SERIAL_NUMBER", False);
+       XChangeProperty(g_disp, g_evtwin, atomCbhmSerial, XA_INTEGER,
+                                       32, PropModeReplace,
+                                       (unsigned char *)&nserial, (int) 1);
+       XFlush(g_disp);
+
+       clipdrawer_update_contents(ad);
+
+       return 0;
+}
+
+int print_storage_buffer()
+{
+       int pos;
+       int i = 0;
+       for (i = 0; i < HISTORY_QUEUE_NUMBER; i++)
+       {
+               pos = get_current_history_position()+i;
+               if (pos > HISTORY_QUEUE_NUMBER-1)
+                       pos = pos-HISTORY_QUEUE_NUMBER;
+               DTRACE("%d: %s\n", i, get_item_contents_by_pos(pos) != NULL ? get_item_contents_by_pos(pos) : "NULL");
+       }
+}
+
+int send_convert_selection()
+{
+       XConvertSelection(g_disp, atomClipboard, atomTarget, atomCBOut, g_evtwin, CurrentTime);
+       DTRACE("sent convert selection\n");
+       return 0;
+}
+
+int set_clipboard_manager_owner()
+{
+       XSetSelectionOwner(g_disp, atomCBHM, g_evtwin, CurrentTime);
+       Ecore_X_Window selowner_window = XGetSelectionOwner(g_disp, atomCBHM);
+       DTRACE("g_evtwin = 0x%x, setted clipboard manager owner is = 0x%x\n", g_evtwin, selowner_window);
+       return 0;
+}
+
+int set_selection_owner()
+{
+       XSetSelectionOwner(g_disp, atomClipboard, g_evtwin, CurrentTime);
+       Ecore_X_Window selowner_window = XGetSelectionOwner(g_disp, atomClipboard);
+       DTRACE("evtwin = 0x%x, setted selection owner is = 0x%x\n", g_evtwin, selowner_window);
+       return 0;
+}
+
+int get_selection_content(void *data)
+{
+       Atom cbtype;
+       int cbformat;
+       unsigned long cbsize, cbitems;
+       unsigned char *cbbuf;
+       struct appdata *ad = data;
+
+       XGetWindowProperty(g_disp, g_evtwin, atomCBOut, 0, 0, False,
+                                          AnyPropertyType, &cbtype, &cbformat, &cbitems, &cbsize, &cbbuf);
+       XFree(cbbuf);
+
+       if (cbtype == atomInc)
+       {
+               XDeleteProperty(g_disp, g_evtwin, atomCBOut);
+               XFlush(g_disp);
+               DTRACE("INCR \n");
+               return -1;
+       }
+
+       DTRACE("cbsize = %d\n", cbsize);
+
+       if (cbformat != 8)
+       {
+               DTRACE("There're nothing to read = %d\n", cbformat);
+               return -2;
+       }
+
+       XGetWindowProperty(g_disp, g_evtwin, atomCBOut, 0, (long) cbsize, False,
+                                          AnyPropertyType, &cbtype, &cbformat, &cbitems, &cbsize, &cbbuf);
+       XDeleteProperty(g_disp, g_evtwin, atomCBOut);
+
+       add_to_storage_buffer(ad, cbbuf, cbitems);
+       DTRACE("len = %ld, data = %s\n", cbitems, cbbuf);
+
+       DTRACE("\n");
+       print_storage_buffer();
+       DTRACE("\n");
+
+       XFree(cbbuf);
+
+       return 0;
+}
+
+int processing_selection_request(Ecore_X_Event_Selection_Request *ev)
+{
+       XEvent req_evt;
+       int req_size;
+       Ecore_X_Window req_win;
+       Atom req_atom;
+
+       req_size = XExtendedMaxRequestSize(g_disp) / 4;
+       if (!req_size)
+       {
+               req_size = XMaxRequestSize(g_disp) / 4;
+       }
+
+    req_win = ev->requestor;
+       req_atom = ev->property;
+
+       /* TODO : if there are request which cbhm doesn't understand,
+          then reply None property to requestor */
+       if (ev->target == atomTargets) 
+       {
+        Atom types[2] = { atomTargets, atomTarget };
+
+        // send all (not using INCR) 
+        XChangeProperty(g_disp, req_win, req_atom, XA_ATOM,
+                                               32, PropModeReplace, (unsigned char *) types,
+                                               (int) (sizeof(types) / sizeof(Atom)));
+               DTRACE("target matched\n");
+    }
+    else
+       {
+               DTRACE("target mismatched. trying to txt\n");
+
+               int txt_len;
+               if (g_lastest_content != NULL)
+                       txt_len = strlen(g_lastest_content);
+               else
+                       txt_len = 0;
+
+               if (txt_len > req_size) 
+               {
+                       // INCR 
+               }
+               else 
+               {
+                       // send all (not using INCR) 
+                       XChangeProperty(g_disp, req_win, req_atom, atomTarget, 
+                                                       8, PropModeReplace, (unsigned char *) g_lastest_content, (int) txt_len);
+               }
+               DTRACE("txt target, len = %d\n", txt_len);
+               if (txt_len > 0 && g_lastest_content != NULL)
+                       DTRACE("txt target, content = %s\n", g_lastest_content);
+       }
+
+/*
+       DTRACE("wanted window = 0x%x\n", req_win);
+       DTRACE("wanted target = %s\n", XGetAtomName(g_disp, ev->target));
+*/
+       DTRACE("selection target = %s\n", XGetAtomName(g_disp, ev->selection));
+       DTRACE("getted atom name = %s\n", XGetAtomName(g_disp, req_atom));
+       DTRACE("req target atom name = %s\n", XGetAtomName(g_disp, ev->target));
+
+    req_evt.xselection.property = req_atom;
+    req_evt.xselection.type = SelectionNotify;
+    req_evt.xselection.display = g_disp;
+    req_evt.xselection.requestor = req_win;
+    req_evt.xselection.selection = ev->selection;
+    req_evt.xselection.target = ev->target;
+    req_evt.xselection.time = ev->time;
+
+    XSendEvent(g_disp, ev->requestor, 0, 0, &req_evt);
+    XFlush(g_disp);
+
+       return 0;
+}
+
+static int _cbhm_init()
+{
+       //Set default data structure
+       //Control that the libraries are properly initialized
+       if (!ecore_init()) return EXIT_FAILURE;
+       if (!ecore_evas_init()) return EXIT_FAILURE;
+       if (!edje_init()) return EXIT_FAILURE;
+
+       // do not x init in this module, it disconnect previous e17's X connection
+       //ecore_x_init(NULL);
+
+       g_disp = ecore_x_display_get();
+
+       if( !g_disp )
+       {
+               DTRACE("Failed to get display\n");
+               return -1;
+       }
+
+       g_rootwin = DefaultRootWindow(g_disp);
+       g_evtwin = ecore_x_window_new(g_rootwin, 0, 0, 19, 19);
+       ecore_x_netwm_name_set(g_evtwin, CLIPBOARD_MANAGER_WINDOW_TITLE_STRING);
+
+       XSelectInput(g_disp, g_evtwin, PropertyChangeMask);
+//     ecore_x_window_show(g_evtwin);
+       ecore_x_flush();
+
+       _set_cbhmwin_prop();
+    _init_atoms();
+       init_storage();
+
+       DTRACE("_cbhm_init ok\n");
+
+       set_clipboard_manager_owner();
+       send_convert_selection();
+       set_selection_owner();
+
+       return TRUE;
+}
+
+static void _cbhm_fini()
+{
+       close_storage();
+
+       return;
+}
+
+static int _xsel_clear_cb(void *data, int ev_type, void *event)
+{
+       struct appdata *ad = data;
+
+       Ecore_X_Event_Selection_Clear *ev = (Ecore_X_Event_Selection_Clear *)event;
+       
+       DTRACE("SelectionClear\n");
+
+       send_convert_selection();
+       ecore_x_flush();
+       /* TODO : set selection request is should after convert selection
+        * is done */
+       set_selection_owner();
+
+       return TRUE;
+}
+
+static int _xsel_request_cb(void *data, int ev_type, void *event)
+{
+       Ecore_X_Event_Selection_Request *ev = (Ecore_X_Event_Selection_Request *)event;
+       
+       DTRACE("SelectionRequest\n");
+
+       processing_selection_request(ev);
+
+       return TRUE;
+}
+
+static int _xsel_notify_cb(void *data, int ev_type, void *event)
+{
+       struct appdata *ad = data;
+
+       Ecore_X_Event_Selection_Notify *ev = (Ecore_X_Event_Selection_Notify *)event;
+       Ecore_X_Selection_Data_Text *text_data = NULL;
+       
+       DTRACE("SelectionNotify\n");
+
+       text_data = ev->data;
+       DTRACE("content type = %d\n", text_data->data.content);
+       get_selection_content(ad);
+
+       if (text_data->data.content != ECORE_X_SELECTION_CONTENT_TEXT)
+       {
+               DTRACE("content isn't text\n");
+       }
+
+       return TRUE;
+}
+
+static int _xclient_msg_cb(void *data, int ev_type, void *event)
+{
+       struct appdata *ad = data;
+
+       Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message*)event;
+
+       Atom atomCBHM_MSG = XInternAtom(g_disp, "CBHM_MSG", False);
+       Atom atomCBHM_cRAW = XInternAtom(g_disp, "CBHM_cRAW", False);
+       char atomname[10];
+       Atom cbhm_atoms[HISTORY_QUEUE_NUMBER];
+       Ecore_X_Window reqwin = ev->win;
+       int i, pos;
+
+       if (ev->message_type != atomCBHM_MSG)
+               return -1;
+
+       DTRACE("ClientMessage for CBHM\n");
+
+       DTRACE("## %s\n", ev->data.b);
+
+       if (strcmp("get count", ev->data.b) == 0)
+       {
+               int icount = get_item_counts();
+               char countbuf[10];
+               DTRACE("## cbhm count : %d\n", icount);
+               sprintf(countbuf, "%d", icount);
+               sprintf(atomname, "CBHM_cCOUNT");
+               cbhm_atoms[0] = XInternAtom(g_disp, atomname, False);
+               XChangeProperty(g_disp, reqwin, cbhm_atoms[0], atomUTF8String, 
+                                               8, PropModeReplace, 
+                                               (unsigned char *) countbuf, 
+                                               (int) 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 > HISTORY_QUEUE_NUMBER-1)
+                       num = num-HISTORY_QUEUE_NUMBER;
+
+               if (num >= 0 && num < HISTORY_QUEUE_NUMBER)
+               {
+                       DTRACE("## pos : #%d\n", num);
+                       // FIXME : handle with correct atom
+                       sprintf(atomname, "CBHM_c%d", num);
+                       cbhm_atoms[0] = XInternAtom(g_disp, atomname, False);
+                       if (get_item_contents_by_pos(num) != NULL)
+                       {
+                               XChangeProperty(g_disp, reqwin, cbhm_atoms[0], atomUTF8String, 
+                                                               8, PropModeReplace, 
+                                                               (unsigned char *) get_item_contents_by_pos(num), 
+                                                               (int) strlen(get_item_contents_by_pos(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 (get_item_contents_by_pos(pos) != NULL)
+                       {
+                               XChangeProperty(g_disp, reqwin, cbhm_atoms[i], atomUTF8String, 
+                                                               8, PropModeReplace, 
+                                                               (unsigned char *) get_item_contents_by_pos(pos) , 
+                                                               (int) strlen(get_item_contents_by_pos(pos)));
+                       }
+                       pos--;
+                       if (pos < 0)
+                               pos = HISTORY_QUEUE_NUMBER-1;
+               }
+       }
+       else if (strcmp("get raw", ev->data.b) == 0)
+       {
+               if (get_storage_start_addr != NULL)
+               {
+                       XChangeProperty(g_disp, reqwin, atomCBHM_cRAW, XA_STRING, 
+                                                       8, PropModeReplace, 
+                                                       (unsigned char *) get_storage_start_addr(),
+                                                       (int) get_total_storage_size());
+               }
+       }
+       else if (strcmp("show", ev->data.b) == 0)
+       {
+               clipdrawer_activate_view(ad);
+       }
+
+       XFlush(g_disp);
+
+       return TRUE;
+}
+
diff --git a/src/xcnphandler.h b/src/xcnphandler.h
new file mode 100755 (executable)
index 0000000..f039964
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef _xcnphandler_h_
+#define _xcnphandler_h_
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/XInput.h>
+#include <X11/extensions/XInput2.h>
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XIproto.h>
+
+#include <Ecore_X.h>
+#include <utilX.h>
+
+int xcnp_init(void *data);
+int xcnp_shutdown();
+
+static int _init_atoms();
+static void _set_cbhmwin_prop();
+
+int increment_current_history_position();
+int get_current_history_position();
+int add_to_storage_buffer(void *data, char *src, int len);
+int print_storage_buffer();
+
+int send_convert_selection();
+int set_clipboard_manager_owner();
+int set_selection_owner();
+int get_selection_content(void *data);
+int processing_selection_request(Ecore_X_Event_Selection_Request *ev);
+
+static int _cbhm_init();
+static void _cbhm_fini();
+static int _xsel_clear_cb(void *data, int ev_type, void *event);
+static int _xsel_request_cb(void *data, int ev_type, void *event);
+static int _xsel_notify_cb(void *data, int ev_type, void *event);
+static int _xclient_msg_cb(void *data, int ev_type, void *event);
+       
+#define ATOM_CLIPBOARD_NAME "CLIPBOARD"
+#define ATOM_CLIPBOARD_MANAGER_NAME "CLIPBOARD_MANAGER"
+#define ATOM_CBHM_OUTBUF "CBHM_BUF"
+#define CLIPBOARD_MANAGER_WINDOW_TITLE_STRING "X11_CLIPBOARD_HISTORY_MANAGER"
+
+static Ecore_X_Display* g_disp = NULL;
+static Ecore_X_Window g_rootwin = None;
+static Ecore_X_Window g_evtwin = None;
+
+/* all atoms are global variables */
+static Atom atomPrimary;
+static Atom atomTarget;
+static Atom atomClipboard;
+static Atom atomCBHM;
+static Atom atomCBOut;
+static Atom atomInc;
+static Atom atomTargets;
+static Atom atomUTF8String;
+
+#endif //_xcnphandler_h_
+