--- /dev/null
+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)
--- /dev/null
+#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; }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+@PREFIX@/bin/*
+@PREFIX@/share/*
--- /dev/null
+cbhm (0.1.0-1) unstable; urgency=low
+
+ * init
+
+ -- Hyoyoung Chang <hyoyoung.chang@samsung.com> Fri, 28 May 2010 10:40:00 +0900
+
--- /dev/null
+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
--- /dev/null
+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.
+ */
+
--- /dev/null
+usr/bin
+usr/sbin
--- /dev/null
+CMakeLists.txt
--- /dev/null
+#!/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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+#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_ */
+
--- /dev/null
+#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);
+}
--- /dev/null
+#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_
--- /dev/null
+#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_
--- /dev/null
+#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;
+}
+
+
--- /dev/null
+#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_
--- /dev/null
+#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;
+}
+
--- /dev/null
+#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_
+