summaryrefslogtreecommitdiff
path: root/ecore/src
diff options
context:
space:
mode:
authorpuppetmaster <puppetmaster>2005-07-25 17:06:37 +0000
committerpuppetmaster <puppetmaster>2005-07-25 17:06:37 +0000
commitf7314c870669f105d21814729b9fe2dd1160437d (patch)
treec5696f507133bb90ea3fef39fc4849c68f77fe2b /ecore/src
parentfix for struct usage ... -> and not "." (diff)
downloadelock-f7314c870669f105d21814729b9fe2dd1160437d.tar.xz
adding last snapshot of ecore for ecore_x_screensaver
Diffstat (limited to 'ecore/src')
-rw-r--r--ecore/src/.cvsignore2
-rw-r--r--ecore/src/CVS/Entries12
-rw-r--r--ecore/src/CVS/Repository1
-rw-r--r--ecore/src/CVS/Root1
-rw-r--r--ecore/src/CVS/Tag1
-rw-r--r--ecore/src/Ecore.h916
-rw-r--r--ecore/src/Makefile.am12
-rw-r--r--ecore/src/bin/.cvsignore6
-rw-r--r--ecore/src/bin/CVS/Entries10
-rw-r--r--ecore/src/bin/CVS/Repository1
-rw-r--r--ecore/src/bin/CVS/Root1
-rw-r--r--ecore/src/bin/CVS/Tag1
-rw-r--r--ecore/src/bin/Makefile.am148
-rw-r--r--ecore/src/bin/ecore_config.c229
-rw-r--r--ecore/src/bin/ecore_evas_test.c27
-rw-r--r--ecore/src/bin/ecore_evas_test.h36
-rw-r--r--ecore/src/bin/ecore_evas_test_app.c174
-rw-r--r--ecore/src/bin/ecore_evas_test_bg.c412
-rw-r--r--ecore/src/bin/ecore_evas_test_calibrate.c285
-rw-r--r--ecore/src/bin/ecore_test.c899
-rw-r--r--ecore/src/e_ev_filter.c132
-rw-r--r--ecore/src/e_ev_signal.c320
-rw-r--r--ecore/src/e_ev_x.c1234
-rw-r--r--ecore/src/e_events.c430
-rw-r--r--ecore/src/e_ipc.c187
-rw-r--r--ecore/src/e_util.c10
-rw-r--r--ecore/src/e_x.c3610
-rw-r--r--ecore/src/lib/.cvsignore2
-rw-r--r--ecore/src/lib/CVS/Entries13
-rw-r--r--ecore/src/lib/CVS/Repository1
-rw-r--r--ecore/src/lib/CVS/Root1
-rw-r--r--ecore/src/lib/CVS/Tag1
-rw-r--r--ecore/src/lib/Makefile.am13
-rw-r--r--ecore/src/lib/ecore/.cvsignore6
-rw-r--r--ecore/src/lib/ecore/CVS/Entries26
-rw-r--r--ecore/src/lib/ecore/CVS/Repository1
-rw-r--r--ecore/src/lib/ecore/CVS/Root1
-rw-r--r--ecore/src/lib/ecore/CVS/Tag1
-rw-r--r--ecore/src/lib/ecore/Ecore.h254
-rw-r--r--ecore/src/lib/ecore/Ecore_Data.h591
-rw-r--r--ecore/src/lib/ecore/Makefile.am34
-rw-r--r--ecore/src/lib/ecore/ecore.c236
-rw-r--r--ecore/src/lib/ecore/ecore_anim.c169
-rw-r--r--ecore/src/lib/ecore/ecore_app.c64
-rw-r--r--ecore/src/lib/ecore/ecore_events.c519
-rw-r--r--ecore/src/lib/ecore/ecore_exe.c263
-rw-r--r--ecore/src/lib/ecore/ecore_hash.c713
-rw-r--r--ecore/src/lib/ecore/ecore_idle_enterer.c105
-rw-r--r--ecore/src/lib/ecore/ecore_idle_exiter.c104
-rw-r--r--ecore/src/lib/ecore/ecore_idler.c106
-rw-r--r--ecore/src/lib/ecore/ecore_list.c1537
-rw-r--r--ecore/src/lib/ecore/ecore_main.c635
-rw-r--r--ecore/src/lib/ecore/ecore_path.c282
-rw-r--r--ecore/src/lib/ecore/ecore_plugin.c109
-rw-r--r--ecore/src/lib/ecore/ecore_private.h262
-rw-r--r--ecore/src/lib/ecore/ecore_sheap.c419
-rw-r--r--ecore/src/lib/ecore/ecore_signal.c455
-rw-r--r--ecore/src/lib/ecore/ecore_strings.c79
-rw-r--r--ecore/src/lib/ecore/ecore_time.c41
-rw-r--r--ecore/src/lib/ecore/ecore_timer.c223
-rw-r--r--ecore/src/lib/ecore/ecore_tree.c816
-rw-r--r--ecore/src/lib/ecore/ecore_value.c118
-rw-r--r--ecore/src/lib/ecore_con/.cvsignore7
-rw-r--r--ecore/src/lib/ecore_con/CVS/Entries7
-rw-r--r--ecore/src/lib/ecore_con/CVS/Repository1
-rw-r--r--ecore/src/lib/ecore_con/CVS/Root1
-rw-r--r--ecore/src/lib/ecore_con/CVS/Tag1
-rw-r--r--ecore/src/lib/ecore_con/Ecore_Con.h168
-rw-r--r--ecore/src/lib/ecore_con/Makefile.am36
-rw-r--r--ecore/src/lib/ecore_con/ecore_con.c1270
-rw-r--r--ecore/src/lib/ecore_con/ecore_con_private.h86
-rw-r--r--ecore/src/lib/ecore_con/ecore_con_url.c408
-rw-r--r--ecore/src/lib/ecore_config/.cvsignore8
-rw-r--r--ecore/src/lib/ecore_config/CVS/Entries14
-rw-r--r--ecore/src/lib/ecore_config/CVS/Entries.Log2
-rw-r--r--ecore/src/lib/ecore_config/CVS/Repository1
-rw-r--r--ecore/src/lib/ecore_config/CVS/Root1
-rw-r--r--ecore/src/lib/ecore_config/CVS/Tag1
-rw-r--r--ecore/src/lib/ecore_config/Ecore_Config.h308
-rw-r--r--ecore/src/lib/ecore_config/Makefile.am65
-rw-r--r--ecore/src/lib/ecore_config/ecore_config.c1623
-rw-r--r--ecore/src/lib/ecore_config/ecore_config_db.c286
-rw-r--r--ecore/src/lib/ecore_config/ecore_config_extra.c828
-rw-r--r--ecore/src/lib/ecore_config/ecore_config_ipc.h50
-rw-r--r--ecore/src/lib/ecore_config/ecore_config_ipc_ecore.c378
-rw-r--r--ecore/src/lib/ecore_config/ecore_config_ipc_main.c284
-rw-r--r--ecore/src/lib/ecore_config/ecore_config_private.h28
-rw-r--r--ecore/src/lib/ecore_config/ecore_config_storage.c172
-rw-r--r--ecore/src/lib/ecore_config/ecore_config_util.c781
-rw-r--r--ecore/src/lib/ecore_config/ecore_config_util.h63
-rw-r--r--ecore/src/lib/ecore_dbus/.cvsignore7
-rw-r--r--ecore/src/lib/ecore_dbus/CVS/Entries6
-rw-r--r--ecore/src/lib/ecore_dbus/CVS/Repository1
-rw-r--r--ecore/src/lib/ecore_dbus/CVS/Root1
-rw-r--r--ecore/src/lib/ecore_dbus/CVS/Tag1
-rw-r--r--ecore/src/lib/ecore_dbus/Ecore_DBus.h209
-rw-r--r--ecore/src/lib/ecore_dbus/Makefile.am39
-rw-r--r--ecore/src/lib/ecore_dbus/ecore_dbus.c1235
-rw-r--r--ecore/src/lib/ecore_dbus/ecore_dbus_private.h56
-rw-r--r--ecore/src/lib/ecore_evas/.cvsignore10
-rw-r--r--ecore/src/lib/ecore_evas/CVS/Entries9
-rw-r--r--ecore/src/lib/ecore_evas/CVS/Repository1
-rw-r--r--ecore/src/lib/ecore_evas/CVS/Root1
-rw-r--r--ecore/src/lib/ecore_evas/CVS/Tag1
-rw-r--r--ecore/src/lib/ecore_evas/Ecore_Evas.h165
-rw-r--r--ecore/src/lib/ecore_evas/Makefile.am69
-rw-r--r--ecore/src/lib/ecore_evas/ecore_evas.c1605
-rw-r--r--ecore/src/lib/ecore_evas/ecore_evas_buffer.c634
-rw-r--r--ecore/src/lib/ecore_evas/ecore_evas_fb.c542
-rw-r--r--ecore/src/lib/ecore_evas/ecore_evas_private.h216
-rw-r--r--ecore/src/lib/ecore_evas/ecore_evas_x.c1938
-rw-r--r--ecore/src/lib/ecore_fb/.cvsignore6
-rw-r--r--ecore/src/lib/ecore_fb/CVS/Entries7
-rw-r--r--ecore/src/lib/ecore_fb/CVS/Repository1
-rw-r--r--ecore/src/lib/ecore_fb/CVS/Root1
-rw-r--r--ecore/src/lib/ecore_fb/CVS/Tag1
-rw-r--r--ecore/src/lib/ecore_fb/Ecore_Fb.h116
-rw-r--r--ecore/src/lib/ecore_fb/Makefile.am32
-rw-r--r--ecore/src/lib/ecore_fb/ecore_fb.c1273
-rw-r--r--ecore/src/lib/ecore_fb/ecore_fb_keytab.h128
-rw-r--r--ecore/src/lib/ecore_fb/ecore_fb_private.h30
-rw-r--r--ecore/src/lib/ecore_file/.cvsignore6
-rw-r--r--ecore/src/lib/ecore_file/CVS/Entries13
-rw-r--r--ecore/src/lib/ecore_file/CVS/Repository1
-rw-r--r--ecore/src/lib/ecore_file/CVS/Root1
-rw-r--r--ecore/src/lib/ecore_file/CVS/Tag1
-rw-r--r--ecore/src/lib/ecore_file/Ecore_File.h91
-rw-r--r--ecore/src/lib/ecore_file/Makefile.am40
-rw-r--r--ecore/src/lib/ecore_file/ecore_file.c257
-rw-r--r--ecore/src/lib/ecore_file/ecore_file_download.c292
-rw-r--r--ecore/src/lib/ecore_file/ecore_file_monitor.c126
-rw-r--r--ecore/src/lib/ecore_file/ecore_file_monitor_fam.c305
-rw-r--r--ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c235
-rw-r--r--ecore/src/lib/ecore_file/ecore_file_monitor_poll.c357
-rw-r--r--ecore/src/lib/ecore_file/ecore_file_path.c84
-rw-r--r--ecore/src/lib/ecore_file/ecore_file_private.h75
-rw-r--r--ecore/src/lib/ecore_file/ecore_file_utils.c4
-rw-r--r--ecore/src/lib/ecore_ipc/.cvsignore7
-rw-r--r--ecore/src/lib/ecore_ipc/CVS/Entries6
-rw-r--r--ecore/src/lib/ecore_ipc/CVS/Repository1
-rw-r--r--ecore/src/lib/ecore_ipc/CVS/Root1
-rw-r--r--ecore/src/lib/ecore_ipc/CVS/Tag1
-rw-r--r--ecore/src/lib/ecore_ipc/Ecore_Ipc.h312
-rw-r--r--ecore/src/lib/ecore_ipc/Makefile.am39
-rw-r--r--ecore/src/lib/ecore_ipc/ecore_ipc.c1257
-rw-r--r--ecore/src/lib/ecore_ipc/ecore_ipc_private.h66
-rw-r--r--ecore/src/lib/ecore_job/.cvsignore6
-rw-r--r--ecore/src/lib/ecore_job/CVS/Entries6
-rw-r--r--ecore/src/lib/ecore_job/CVS/Repository1
-rw-r--r--ecore/src/lib/ecore_job/CVS/Root1
-rw-r--r--ecore/src/lib/ecore_job/CVS/Tag1
-rw-r--r--ecore/src/lib/ecore_job/Ecore_Job.h41
-rw-r--r--ecore/src/lib/ecore_job/Makefile.am31
-rw-r--r--ecore/src/lib/ecore_job/ecore_job.c86
-rw-r--r--ecore/src/lib/ecore_job/ecore_job_private.h16
-rw-r--r--ecore/src/lib/ecore_txt/.cvsignore6
-rw-r--r--ecore/src/lib/ecore_txt/CVS/Entries6
-rw-r--r--ecore/src/lib/ecore_txt/CVS/Repository1
-rw-r--r--ecore/src/lib/ecore_txt/CVS/Root1
-rw-r--r--ecore/src/lib/ecore_txt/CVS/Tag1
-rw-r--r--ecore/src/lib/ecore_txt/Ecore_Txt.h36
-rw-r--r--ecore/src/lib/ecore_txt/Makefile.am34
-rw-r--r--ecore/src/lib/ecore_txt/ecore_txt.c78
-rw-r--r--ecore/src/lib/ecore_txt/ecore_txt_private.h4
-rw-r--r--ecore/src/lib/ecore_x/.cvsignore6
-rw-r--r--ecore/src/lib/ecore_x/CVS/Entries23
-rw-r--r--ecore/src/lib/ecore_x/CVS/Repository1
-rw-r--r--ecore/src/lib/ecore_x/CVS/Root1
-rw-r--r--ecore/src/lib/ecore_x/CVS/Tag1
-rw-r--r--ecore/src/lib/ecore_x/Ecore_X.h1320
-rw-r--r--ecore/src/lib/ecore_x/Ecore_X_Atoms.h152
-rw-r--r--ecore/src/lib/ecore_x/Ecore_X_Cursor.h86
-rw-r--r--ecore/src/lib/ecore_x/Makefile.am81
-rw-r--r--ecore/src/lib/ecore_x/ecore_x.c1685
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_dnd.c405
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_e.c37
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_error.c95
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_events.c1565
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_gc.c29
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_icccm.c1082
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_mwm.c93
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_netwm.c1238
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_pixmap.c95
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_private.h210
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_selection.c773
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_sync.c48
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_window.c768
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_window_prop.c342
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_window_shape.c159
-rw-r--r--ecore/src/lib/ecore_x/ecore_x_xinerama.c54
190 files changed, 46799 insertions, 0 deletions
diff --git a/ecore/src/.cvsignore b/ecore/src/.cvsignore
new file mode 100644
index 0000000..282522d
--- /dev/null
+++ b/ecore/src/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/ecore/src/CVS/Entries b/ecore/src/CVS/Entries
new file mode 100644
index 0000000..8b75dcf
--- /dev/null
+++ b/ecore/src/CVS/Entries
@@ -0,0 +1,12 @@
+/.cvsignore/1.3/Thu Nov 13 12:30:47 2003//THEAD
+/Ecore.h/1.49/Tue Sep 23 08:09:28 2003//THEAD
+/Makefile.am/1.10/Thu Mar 10 15:19:35 2005//THEAD
+/e_ev_filter.c/1.8/Tue Sep 23 08:09:28 2003//THEAD
+/e_ev_signal.c/1.7/Tue Sep 23 08:09:28 2003//THEAD
+/e_ev_x.c/1.30/Tue Sep 23 08:09:28 2003//THEAD
+/e_events.c/1.16/Tue Sep 23 08:09:28 2003//THEAD
+/e_ipc.c/1.5/Tue Sep 23 08:09:28 2003//THEAD
+/e_util.c/1.7/Tue Sep 23 08:09:28 2003//THEAD
+/e_x.c/1.56/Tue Sep 23 08:09:28 2003//THEAD
+D/bin////
+D/lib////
diff --git a/ecore/src/CVS/Repository b/ecore/src/CVS/Repository
new file mode 100644
index 0000000..0014dc3
--- /dev/null
+++ b/ecore/src/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src
diff --git a/ecore/src/CVS/Root b/ecore/src/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/CVS/Tag b/ecore/src/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/Ecore.h b/ecore/src/Ecore.h
new file mode 100644
index 0000000..9bdd679
--- /dev/null
+++ b/ecore/src/Ecore.h
@@ -0,0 +1,916 @@
+#ifndef E_CORE_H
+#define E_CORE_H 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#define XK_MISCELLANY 1
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/Xresource.h>
+#include <X11/keysymdef.h>
+#include <X11/extensions/XShm.h>
+#include <X11/extensions/shape.h>
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#define XEV_NONE NoEventMask
+#define XEV_KEY KeyPressMask | KeyReleaseMask
+#define XEV_BUTTON ButtonPressMask | ButtonReleaseMask
+#define XEV_KEY_PRESS KeyPressMask
+#define XEV_KEY_RELEASE KeyReleaseMask
+#define XEV_BUTTON_PRESS ButtonPressMask
+#define XEV_BUTTON_RELEASE ButtonReleaseMask
+#define XEV_IN_OUT EnterWindowMask | LeaveWindowMask
+#define XEV_MOUSE_MOVE PointerMotionMask | ButtonMotionMask
+#define XEV_EXPOSE ExposureMask
+#define XEV_VISIBILITY VisibilityChangeMask
+#define XEV_CONFIGURE StructureNotifyMask
+#define XEV_CHILD_CHANGE SubstructureNotifyMask
+#define XEV_CHILD_REDIRECT SubstructureRedirectMask | ResizeRedirectMask
+#define XEV_FOCUS FocusChangeMask
+#define XEV_PROPERTY PropertyChangeMask
+#define XEV_COLORMAP ColormapChangeMask
+
+
+#define ECORE_ATOM(atom, name) \
+ if (!atom) (atom) = ecore_atom_get(name);
+#define MEMCPY(src, dst, type, num) \
+ memcpy(dst, src, sizeof(type) * (num))
+#define NEW(type, num) \
+ malloc(sizeof(type) * (num))
+#define ZERO(ptr, type, num) \
+ memset((ptr), 0, sizeof(type) * (num))
+#define NEW_PTR(num) \
+ malloc(sizeof(void *) * (num))
+#define FREE(ptr) \
+ { \
+ free(ptr); \
+ (ptr) = NULL; \
+ }
+#define IF_FREE(ptr) \
+ {if (ptr) FREE(ptr);}
+#define REALLOC(ptr, type, num) \
+ { \
+ if ((ptr) && (num == 0)) {free(ptr); ptr = NULL;} \
+ else if (ptr) ptr = realloc((ptr), sizeof(type) * (num)); \
+ else ptr = malloc(sizeof(type) * (num)); \
+ }
+#define REALLOC_PTR(ptr, num) \
+ { \
+ if ((ptr) && (num == 0)) {free(ptr); ptr = NULL;} \
+ else if (ptr) ptr = realloc(ptr, sizeof(void *) * (num)); \
+ else ptr = malloc(sizeof(void *) * (num)); \
+ }
+
+#define START_LIST_DEL(type, base, cmp) \
+ type *_p, *_pp; _pp = NULL; \
+ _p = (base); \
+ while(_p) \
+ { \
+ if (cmp) \
+ { \
+ if (_pp) _pp->next = _p->next; \
+ else (base) = _p->next;
+#define END_LIST_DEL \
+ return; \
+ } \
+ _pp = _p; \
+ _p = _p->next; \
+ }
+
+#define DND_TYPE_URI_LIST 0
+#define DND_TYPE_PLAIN_TEXT 1
+#define DND_TYPE_MOZ_URL 2
+#define DND_TYPE_NETSCAPE_URL 3
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ extern XContext xid_context;
+
+ typedef void (*Ecore_Error_Function) (Display * d, XErrorEvent * ev);
+
+ typedef struct _ecore_keygrab Ecore_KeyGrab;
+
+ typedef enum _ecore_ev_modifiers
+ {
+ ECORE_EVENT_KEY_MODIFIER_NONE = 0,
+ ECORE_EVENT_KEY_MODIFIER_SHIFT = (1 << 0),
+ ECORE_EVENT_KEY_MODIFIER_CTRL = (1 << 1),
+ ECORE_EVENT_KEY_MODIFIER_ALT = (1 << 2),
+ ECORE_EVENT_KEY_MODIFIER_WIN = (1 << 3)
+ } Ecore_Event_Key_Modifiers;
+
+ typedef enum _ecore_event_stack_detail
+ {
+ ECORE_EVENT_STACK_ABOVE = Above,
+ ECORE_EVENT_STACK_BELOW = Below,
+ ECORE_EVENT_STACK_TOP_IF = TopIf,
+ ECORE_EVENT_STACK_BOTTOM_IF = BottomIf,
+ ECORE_EVENT_STACK_OPPOSITE = Opposite
+ } Ecore_Event_Stack_Detail;
+
+ typedef enum _ecore_event_value_mask
+ {
+ ECORE_EVENT_VALUE_X = CWX,
+ ECORE_EVENT_VALUE_Y = CWY,
+ ECORE_EVENT_VALUE_W = CWWidth,
+ ECORE_EVENT_VALUE_H = CWHeight,
+ ECORE_EVENT_VALUE_BORDER = CWBorderWidth,
+ ECORE_EVENT_VALUE_SIBLING = CWSibling,
+ ECORE_EVENT_VALUE_STACKING = CWStackMode
+ } Ecore_Event_Value_Mask;
+
+ typedef enum _ecore_event_type
+ {
+ ECORE_EVENT_MOUSE_MOVE,
+ ECORE_EVENT_MOUSE_DOWN,
+ ECORE_EVENT_MOUSE_UP,
+ ECORE_EVENT_MOUSE_IN,
+ ECORE_EVENT_MOUSE_OUT,
+ ECORE_EVENT_MOUSE_WHEEL,
+ ECORE_EVENT_KEY_DOWN,
+ ECORE_EVENT_KEY_UP,
+ ECORE_EVENT_WINDOW_MAP,
+ ECORE_EVENT_WINDOW_UNMAP,
+ ECORE_EVENT_WINDOW_CREATE,
+ ECORE_EVENT_WINDOW_DESTROY,
+ ECORE_EVENT_WINDOW_CONFIGURE,
+ ECORE_EVENT_WINDOW_CONFIGURE_REQUEST,
+ ECORE_EVENT_WINDOW_MAP_REQUEST,
+ ECORE_EVENT_WINDOW_PROPERTY,
+ ECORE_EVENT_WINDOW_CIRCULATE,
+ ECORE_EVENT_WINDOW_CIRCULATE_REQUEST,
+ ECORE_EVENT_WINDOW_REPARENT,
+ ECORE_EVENT_WINDOW_EXPOSE,
+ ECORE_EVENT_WINDOW_VISIBILITY,
+ ECORE_EVENT_WINDOW_SHAPE,
+ ECORE_EVENT_WINDOW_FOCUS_IN,
+ ECORE_EVENT_WINDOW_FOCUS_OUT,
+ ECORE_EVENT_MESSAGE,
+ ECORE_EVENT_WINDOW_DELETE,
+ ECORE_EVENT_COLORMAP,
+
+ ECORE_EVENT_DND_DROP_REQUEST,
+ ECORE_EVENT_DND_DROP_END,
+ ECORE_EVENT_DND_DROP_POSITION,
+ ECORE_EVENT_DND_DROP,
+ ECORE_EVENT_DND_DROP_STATUS,
+ ECORE_EVENT_DND_DATA_REQUEST,
+ ECORE_EVENT_PASTE_REQUEST,
+ ECORE_EVENT_CLEAR_SELECTION,
+
+ ECORE_EVENT_CHILD,
+ ECORE_EVENT_USER,
+
+ ECORE_EVENT_MAX
+ } Ecore_Event_Type;
+
+ typedef struct _ecore_event
+ {
+ Ecore_Event_Type type;
+ char ignore;
+ void *event;
+ void (*ev_free) (void *evnt);
+ struct _ecore_event *next;
+ } Ecore_Event;
+
+ typedef struct _ecore_event_fd_handler
+ {
+ int fd;
+ void (*func) (int fd);
+ struct _ecore_event_fd_handler *next;
+ } Ecore_Event_Fd_Handler;
+
+ typedef struct _ecore_event_pid_handler
+ {
+ pid_t pid;
+ void (*func) (pid_t pid);
+ struct _ecore_event_pid_handler *next;
+ } Ecore_Event_Pid_Handler;
+
+ typedef struct _ecore_event_ipc_handler
+ {
+ int ipc;
+ void (*func) (int ipc);
+ struct _ecore_event_ipc_handler *next;
+ } Ecore_Event_Ipc_Handler;
+
+ typedef struct _ecore_event_timer
+ {
+ char *name;
+ void (*func) (int val, void *data);
+ int val;
+ void *data;
+ double in;
+ char just_added;
+ struct _ecore_event_timer *next;
+ } Ecore_Event_Timer;
+
+ typedef struct _ecore_event_key_down
+ {
+ Window win, root;
+ Ecore_Event_Key_Modifiers mods;
+ char *key;
+ char *compose;
+ Time time;
+ } Ecore_Event_Key_Down;
+
+ typedef struct _ecore_event_key_up
+ {
+ Window win, root;
+ Ecore_Event_Key_Modifiers mods;
+ char *key;
+ char *compose;
+ Time time;
+ } Ecore_Event_Key_Up;
+
+ typedef struct _ecore_event_mouse_down
+ {
+ Window win, root;
+ Ecore_Event_Key_Modifiers mods;
+ int button;
+ int x, y;
+ int rx, ry;
+ int double_click, triple_click;
+ Time time;
+ } Ecore_Event_Mouse_Down;
+
+ typedef struct _ecore_event_mouse_up
+ {
+ Window win, root;
+ Ecore_Event_Key_Modifiers mods;
+ int button;
+ int x, y;
+ int rx, ry;
+ Time time;
+ } Ecore_Event_Mouse_Up;
+
+ typedef struct _ecore_event_wheel
+ {
+ Window win, root;
+ Ecore_Event_Key_Modifiers mods;
+ int x, y, z;
+ int rx, ry;
+ Time time;
+ } Ecore_Event_Wheel;
+
+ typedef struct _ecore_event_mouse_move
+ {
+ Window win, root;
+ Ecore_Event_Key_Modifiers mods;
+ int x, y;
+ int rx, ry;
+ Time time;
+ } Ecore_Event_Mouse_Move;
+
+ typedef struct _ecore_event_window_enter
+ {
+ Window win, root;
+ int x, y;
+ int rx, ry;
+ Ecore_Event_Key_Modifiers mods;
+ Time time;
+ } Ecore_Event_Window_Enter;
+
+ typedef struct _ecore_event_window_leave
+ {
+ Window win, root;
+ int x, y;
+ int rx, ry;
+ Ecore_Event_Key_Modifiers mods;
+ Time time;
+ } Ecore_Event_Window_Leave;
+
+ typedef struct _ecore_event_window_focus_in
+ {
+ Window win, root;
+ int key_grab;
+ Time time;
+ } Ecore_Event_Window_Focus_In;
+
+ typedef struct _ecore_event_window_focus_out
+ {
+ Window win, root;
+ int key_grab;
+ Time time;
+ } Ecore_Event_Window_Focus_Out;
+
+ typedef struct _ecore_event_window_expose
+ {
+ Window win, root;
+ int x, y, w, h;
+ } Ecore_Event_Window_Expose;
+
+ typedef struct _ecore_event_window_visibility
+ {
+ Window win, root;
+ int fully_obscured;
+ } Ecore_Event_Window_Visibility;
+
+ typedef struct _ecore_event_window_create
+ {
+ Window win, root;
+ int override;
+ } Ecore_Event_Window_Create;
+
+ typedef struct _ecore_event_window_destroy
+ {
+ Window win, root;
+ } Ecore_Event_Window_Destroy;
+
+ typedef struct _ecore_event_window_map
+ {
+ Window win, root;
+ } Ecore_Event_Window_Map;
+
+ typedef struct _ecore_event_window_unmap
+ {
+ Window win, root;
+ } Ecore_Event_Window_Unmap;
+
+ typedef struct _ecore_event_window_map_request
+ {
+ Window win, root;
+ } Ecore_Event_Window_Map_Request;
+
+ typedef struct _ecore_event_window_reparent
+ {
+ Window win, root;
+ Window parent_from, parent;
+ } Ecore_Event_Window_Reparent;
+
+ typedef struct _ecore_event_window_configure
+ {
+ Window win, root;
+ int x, y, w, h;
+ int wm_generated;
+ } Ecore_Event_Window_Configure;
+
+ typedef struct _ecore_event_window_configure_request
+ {
+ Window win, root;
+ int x, y, w, h;
+ int border;
+ Window stack_win;
+ Ecore_Event_Stack_Detail detail;
+ Ecore_Event_Value_Mask mask;
+ } Ecore_Event_Window_Configure_Request;
+
+ typedef struct _ecore_event_window_circulate
+ {
+ Window win, root;
+ int lower;
+ } Ecore_Event_Window_Circulate;
+
+ typedef struct _ecore_event_window_circulate_request
+ {
+ Window win, root;
+ int lower;
+ } Ecore_Event_Window_Circulate_Request;
+
+ typedef struct _ecore_event_window_property
+ {
+ Window win, root;
+ Atom atom;
+ Time time;
+ } Ecore_Event_Window_Property;
+
+ typedef struct _ecore_event_window_shape
+ {
+ Window win, root;
+ Time time;
+ } Ecore_Event_Window_Shape;
+
+ typedef struct _ecore_event_message
+ {
+ Window win;
+ int format;
+ Atom atom;
+ union
+ {
+ char b[20];
+ short s[10];
+ long l[5];
+ }
+ data;
+ } Ecore_Event_Message;
+
+ typedef struct _ecore_event_colormap
+ {
+ Window win, root;
+ Colormap cmap;
+ int installed;
+ } Ecore_Event_Colormap;
+
+ typedef struct _ecore_event_window_delete
+ {
+ Window win, root;
+ } Ecore_Event_Window_Delete;
+
+ typedef struct _ecore_event_paste_request
+ {
+ Window win, root, source_win;
+ char *string;
+ } Ecore_Event_Paste_Request;
+
+ typedef struct _ecore_event_clear_selection
+ {
+ Window win, root;
+ Atom selection;
+ } Ecore_Event_Clear_Selection;
+
+ typedef struct _ecore_event_dnd_drop_request
+ {
+ Window win, root, source_win;
+ int num_files;
+ char **files;
+ int copy, link, move;
+ } Ecore_Event_Dnd_Drop_Request;
+
+ typedef struct _ecore_event_dnd_drop_end
+ {
+ Window win, root, source_win;
+ } Ecore_Event_Dnd_Drop_End;
+
+ typedef struct _ecore_event_dnd_drop_position
+ {
+ Window win, root, source_win;
+ int x, y;
+ } Ecore_Event_Dnd_Drop_Position;
+
+ typedef struct _ecore_event_dnd_drop
+ {
+ Window win, root, source_win;
+ } Ecore_Event_Dnd_Drop;
+
+ typedef struct _ecore_event_dnd_drop_status
+ {
+ Window win, root, source_win;
+ int x, y, w, h;
+ int copy, link, move, e_private;
+ int all_position_msgs;
+ int ok;
+ } Ecore_Event_Dnd_Drop_Status;
+
+ typedef struct _ecore_event_dnd_data_request
+ {
+ Window win, root, source_win;
+ Atom destination_atom;
+ int plain_text;
+ int uri_list;
+ int moz_url;
+ int netscape_url;
+ } Ecore_Event_Dnd_Data_Request;
+
+ typedef struct _ecore_event_child
+ {
+ pid_t pid;
+ int exit_code;
+ } Ecore_Event_Child;
+
+ typedef struct _ecore_event_user
+ {
+ int num;
+ int hup;
+ } Ecore_Event_User;
+
+ typedef struct _ecore_event_ipc_service
+ {
+ int service;
+ void (*func) (int fd);
+ struct _ecore_event_ipc_service *next;
+ } Ecore_Event_Ipc_Service;
+
+
+ typedef struct _ecore_xid
+ {
+ Window win;
+ Window parent;
+ Window root;
+ int children_num;
+ Window *children;
+ int x, y, w, h;
+ int mapped;
+ int mouse_in;
+ int depth;
+ int gravity;
+ int coords_invalid;
+ int bw;
+ int (*grab_button_auto_replay) (Ecore_Event_Mouse_Down *ev);
+ } Ecore_XID;
+
+
+ /* ---------------- API CALLS BELOW --------------------*/
+
+ /* ---------------- X WRAPPER CALLS */
+
+ int ecore_x_get_fd(void);
+ void ecore_set_error_handler(Ecore_Error_Function func);
+ void ecore_reset_error_handler(void);
+
+ /**
+ * ecore_display_init - Establishes a connection to the X server
+ * @display: The name of the display to connect to
+ *
+ * This function creates a connection to the X server. If
+ * @display is NULL, the name is taken from the $DISPLAY
+ * environment variable.
+ */
+ int ecore_display_init(char *display);
+
+ int ecore_events_pending(void);
+ void ecore_get_next_event(XEvent * event);
+ int ecore_event_shape_get_id(void);
+ void ecore_sync(void);
+ void ecore_flush(void);
+
+ /* ---------------- WINDOW CHILD HANDLING */
+
+ void ecore_del_child(Window win, Window child);
+ void ecore_add_child(Window win, Window child);
+ void ecore_raise_child(Window win, Window child);
+ void ecore_lower_child(Window win, Window child);
+ Ecore_XID *ecore_add_xid(Window win, int x, int y, int w, int h,
+ int depth, Window parent);
+ Ecore_XID *ecore_validate_xid(Window win);
+ void ecore_unvalidate_xid(Window win);
+
+ /* ---------------- WINDOWS-RELATED CALLS */
+
+ Window ecore_window_new(Window parent, int x, int y, int w,
+ int h);
+ Window ecore_window_override_new(Window parent, int x, int y,
+ int w, int h);
+ Window ecore_window_input_new(Window parent, int x, int y, int w,
+ int h);
+ void ecore_window_set_events_propagate(Window win,
+ int propagate);
+ void ecore_window_show(Window win);
+ void ecore_window_hide(Window win);
+ void ecore_window_set_background_pixmap(Window win,
+ Pixmap pmap);
+ void ecore_window_set_shape_mask(Window win, Pixmap mask);
+ void ecore_window_add_shape_mask(Window win, Pixmap mask);
+ void ecore_window_set_shape_window(Window win, Window src,
+ int x, int y);
+ void ecore_window_add_shape_window(Window win, Window src,
+ int x, int y);
+ void ecore_window_set_shape_rectangle(Window win, int x, int y,
+ int w, int h);
+ void ecore_window_add_shape_rectangle(Window win, int x, int y,
+ int w, int h);
+ void ecore_window_set_shape_rectangles(Window win,
+ XRectangle * rect,
+ int num);
+ void ecore_window_add_shape_rectangles(Window win,
+ XRectangle * rect,
+ int num);
+ void ecore_window_clip_shape_by_rectangle(Window win, int x,
+ int y, int w, int h);
+ XRectangle *ecore_window_get_shape_rectangles(Window win, int *num);
+ void ecore_window_select_shape_events(Window win);
+ void ecore_window_unselect_shape_events(Window win);
+ void ecore_window_clear(Window win);
+ void ecore_window_clear_area(Window win, int x, int y, int w,
+ int h);
+ void ecore_window_set_events(Window win, long mask);
+ void ecore_window_remove_events(Window win, long mask);
+ void ecore_window_add_events(Window win, long mask);
+ void ecore_window_move(Window win, int x, int y);
+ void ecore_window_resize(Window win, int w, int h);
+ void ecore_window_move_resize(Window win, int x, int y, int w,
+ int h);
+ void ecore_window_destroy(Window win);
+ void ecore_window_reparent(Window win, Window parent, int x,
+ int y);
+ void ecore_window_raise(Window win);
+ void ecore_window_lower(Window win);
+ void ecore_window_get_geometry(Window win, int *x, int *y,
+ int *w, int *h);
+ int ecore_window_get_depth(Window win);
+ int ecore_window_exists(Window win);
+ Window ecore_window_get_parent(Window win);
+ Window *ecore_window_get_children(Window win, int *num);
+ int ecore_window_mouse_in(Window win);
+ void ecore_window_mouse_set_in(Window win, int in);
+ Window ecore_window_get_root(Window win);
+ void ecore_window_set_delete_inform(Window win);
+ void ecore_window_property_set(Window win, Atom type,
+ Atom format, int size,
+ void *data, int number);
+ void *ecore_window_property_get(Window win, Atom type,
+ Atom format, int *size);
+ void ecore_window_dnd_advertise(Window win);
+ void ecore_window_ignore(Window win);
+ void ecore_window_no_ignore(Window win);
+ int ecore_window_is_ignored(Window win);
+ Window ecore_window_get_at_xy(int x, int y);
+
+ int ecore_window_dnd_capable(Window win);
+ void ecore_window_dnd_handle_motion(Window source_win, int x,
+ int y, int dragging);
+ void ecore_window_dnd_ok(int ok);
+ void ecore_window_dnd_finished(void);
+ void ecore_window_dnd_send_status_ok(Window source_win,
+ Window win, int x, int y,
+ int w, int h);
+ void ecore_window_dnd_send_finished(Window source_win,
+ Window win);
+ void ecore_window_set_title(Window win, char *title);
+ void ecore_window_set_name_class(Window win, char *name,
+ char *);
+ void ecore_window_get_name_class(Window win, char **name,
+ char **name_class);
+ char *ecore_window_get_machine(Window win);
+ char *ecore_window_get_command(Window win);
+ char *ecore_window_get_icon_name(Window win);
+ void ecore_window_get_hints(Window win, int *accepts_focus,
+ int *initial_state,
+ Pixmap * icon_pixmap,
+ Pixmap * icon_mask,
+ Window * icon_window,
+ Window * window_group);
+ void ecore_window_set_min_size(Window win, int w, int h);
+ void ecore_window_set_max_size(Window win, int w, int h);
+ void ecore_window_set_xy_hints(Window win, int x, int y);
+ void ecore_window_get_frame_size(Window win, int *l, int *r,
+ int *t, int *b);
+ int ecore_window_save_under(Window win);
+ void ecore_window_hint_set_layer(Window win, int layer);
+ void ecore_window_hint_set_sticky(Window win, int sticky);
+ void ecore_window_hint_set_borderless(Window win);
+ int ecore_window_get_gravity(Window win);
+ void ecore_window_gravity_reset(Window win);
+ void ecore_window_gravity_set(Window win, int gravity);
+ void ecore_window_bit_gravity_set(Window win, int gravity);
+ void ecore_window_get_root_relative_location(Window win,
+ int *x, int *y);
+ void ecore_window_send_event_move_resize(Window win, int x,
+ int y, int w, int h);
+ void ecore_window_send_client_message(Window win, Atom type,
+ int format, void *data);
+ void ecore_window_add_to_save_set(Window win);
+ void ecore_window_del_from_save_set(Window win);
+ void ecore_window_kill_client(Window win);
+ void ecore_window_set_border_width(Window win, int bw);
+ int ecore_window_get_border_width(Window win);
+ int ecore_window_get_wm_size_hints(Window win,
+ XSizeHints * hints,
+ int *mask);
+ int ecore_window_is_visible(Window win);
+ int ecore_window_is_normal(Window win);
+
+ /**
+ * ecore_window_is_manageable - Returns 1 if a window can be managed by the wm.
+ * @win: the window for which to query.
+ *
+ * This function returns 0 if the window is unmapped, should be ignored
+ * by the window manager or is of the InputOnly class, 1 otherwise.
+ */
+ int ecore_window_is_manageable(Window win);
+
+ void ecore_windows_restack(Window * wins, int num);
+ void ecore_window_stack_above(Window win, Window above);
+ void ecore_window_stack_below(Window win, Window below);
+ char *ecore_window_get_title(Window win);
+ void ecore_window_button_grab_auto_replay_set(Window win,
+ int (*func) (Ecore_Event_Mouse_Down *ev));
+ void *ecore_window_button_grab_auto_replay_get(Window win);
+ Window ecore_window_root(void);
+ void ecore_window_get_virtual_area(Window win, int *area_x,
+ int *area_y);
+
+ /* ---------------- PIXMAP CALLS */
+
+ Pixmap ecore_pixmap_new(Window win, int w, int h, int dep);
+ void ecore_pixmap_free(Pixmap pmap);
+
+ /* ---------------- POINTER CALLS */
+
+ void ecore_pointer_xy(Window win, int *x, int *y);
+ void ecore_pointer_xy_set(int x, int y);
+ void ecore_pointer_xy_get(int *x, int *y);
+ void ecore_pointer_warp_by(int dx, int dy);
+ void ecore_pointer_warp_to(int x, int y);
+ void ecore_pointer_replay(Time t);
+ void ecore_pointer_grab(Window win, Time t);
+ void ecore_pointer_ungrab(Time t);
+
+ /* ---------------- KEYBOARD-RELATED CALLS */
+
+ KeySym ecore_key_get_keysym_from_keycode(KeyCode keycode);
+ char *ecore_key_get_string_from_keycode(KeyCode keycode);
+ void ecore_key_grab(char *key, Ecore_Event_Key_Modifiers mods,
+ int anymod, int sync);
+ void ecore_key_ungrab(char *key,
+ Ecore_Event_Key_Modifiers mods,
+ int anymod);
+ KeyCode ecore_key_get_keycode(char *key);
+ char *ecore_keypress_translate_into_typeable(Ecore_Event_Key_Down * e);
+
+ void ecore_event_allow(int mode, Time t);
+
+ /* ---------------- LOCKS AND MODIFIER CALLS */
+
+ int ecore_lock_mask_scroll_get(void);
+ int ecore_lock_mask_num_get(void);
+ int ecore_lock_mask_caps_get(void);
+ void ecore_lock_scroll_set(int onoff);
+ int ecore_lock_scroll_get(void);
+ void ecore_lock_num_set(int onoff);
+ int ecore_lock_num_get(void);
+ void ecore_lock_caps_set(int onoff);
+ int ecore_lock_caps_get(void);
+
+ int ecore_mod_mask_shift_get(void);
+ int ecore_mod_mask_ctrl_get(void);
+ int ecore_mod_mask_alt_get(void);
+ int ecore_mod_mask_win_get(void);
+ void ecore_mod_shift_set(int onoff);
+ int ecore_mod_shift_get(void);
+ void ecore_mod_ctrl_set(int onoff);
+ int ecore_mod_ctrl_get(void);
+ void ecore_mod_alt_set(int onoff);
+ int ecore_mod_alt_get(void);
+ void ecore_mod_win_set(int onoff);
+ int ecore_mod_win_get(void);
+
+ int ecore_lock_mask_get(void);
+ int ecore_modifier_mask_get(void);
+ Window ecore_get_key_grab_win(void);
+ Display *ecore_display_get(void);
+ void ecore_focus_window_set(Window win);
+ Window ecore_focus_window_get(void);
+ void ecore_focus_to_window(Window win);
+ void ecore_focus_mode_reset(void);
+ Atom ecore_atom_get(char *name);
+
+
+ /* ---------------- GRABBING/UNGRABBING CALLS */
+
+ /**
+ * ecore_grab - Grabs the X server connection
+ *
+ * This function wraps XGrabServer, which prevents all other
+ * clients from receiving events. Calls are reference-counted.
+ */
+ void ecore_grab(void);
+
+ /**
+ * ecore_ungrab - Ungrabs the X server connection
+ *
+ * This function releases the server, provided that ecore_grab()
+ * has been called the same number of times as ecore_ungrab().
+ */
+ void ecore_ungrab(void);
+
+ void ecore_grab_mouse(Window win, int confine, Cursor cursor);
+ void ecore_ungrab_mouse(void);
+ Window ecore_grab_window_get(void);
+
+ void ecore_button_grab(Window win, int button, int events,
+ Ecore_Event_Key_Modifiers mod,
+ int any_mod);
+ void ecore_button_ungrab(Window win, int button,
+ Ecore_Event_Key_Modifiers mod,
+ int any_mod);
+ void ecore_keyboard_grab(Window win);
+ void ecore_keyboard_ungrab(void);
+ Window ecore_keyboard_grab_window_get(void);
+
+
+ /* ----------------- GRAPHICS CONTEXT AND DRAWING CALLS */
+
+ GC ecore_gc_new(Drawable d);
+ void ecore_gc_free(GC gc);
+ void ecore_gc_set_fg(GC gc, int val);
+ void ecore_gc_set_include_inferiors(GC gc);
+ void ecore_fill_rectangle(Drawable d, GC gc, int x, int y,
+ int w, int h);
+ void ecore_draw_rectangle(Drawable d, GC gc, int x, int y,
+ int w, int h);
+ void ecore_draw_line(Drawable d, GC gc, int x1, int y1, int x2,
+ int y2);
+ void ecore_draw_point(Drawable d, GC gc, int x, int y);
+ void ecore_area_copy(Drawable src, Drawable dest, GC gc,
+ int sx, int sy, int sw, int sh, int dx,
+ int dy);
+
+
+ /* ---------------- DRAG AND DROP CALLS */
+
+
+ int ecore_dnd_selection_convert(Window win, Window req,
+ Atom type);
+ void *ecore_dnd_selection_get(Window win, Window req, Atom type,
+ int *size);
+ void ecore_dnd_set_data(Window win);
+ void ecore_dnd_set_action(Window win);
+
+ void ecore_dnd_send_data(Window win, Window source_win,
+ void *data, int size, Atom dest_atom,
+ int type);
+ void ecore_dnd_set_mode_copy(void);
+ void ecore_dnd_set_mode_link(void);
+ void ecore_dnd_set_mode_move(void);
+ void ecore_dnd_set_mode_ask(void);
+ void ecore_dnd_own_selection(Window win);
+ void ecore_dnd_send_drop(Window win, Window source_win);
+ void ecore_get_virtual_area(int *area_x, int *area_y);
+ void ecore_clear_target_status(void);
+
+
+ /* ---------------- IPC CALLS */
+
+ void ecore_event_ipc_init(char *path);
+ void ecore_event_ipc_cleanup(void);
+ void ecore_add_ipc_service(int service, void (*func) (int fd));
+ void ecore_del_ipc_service(int service);
+
+ /* ---------------- SELECTION CALLS */
+
+ char *ecore_selection_get_data(Window win, Atom prop);
+ Window ecore_selection_request(void);
+ Window ecore_selection_set(char *string);
+
+ /* ---------------- CURSOR LOOK CALLS */
+
+ void ecore_set_blank_pointer(Window w);
+ Cursor ecore_cursor_new(Pixmap pmap, Pixmap mask, int x, int y,
+ int fr, int fg, int fb, int br, int bg,
+ int bb);
+ void ecore_cursor_free(Cursor c);
+ void ecore_cursor_set(Window win, Cursor c);
+
+ /* ---------------- EVENT-HANDLING CALLS */
+
+ void ecore_add_event(Ecore_Event_Type type, void *event,
+ void (*ev_free) (void *event));
+ void ecore_del_event(void *event);
+ void ecore_del_all_events(void);
+ Ecore_Event *ecore_get_last_event(void);
+ void ecore_add_event_fd(int fd, void (*func) (int fd));
+ void ecore_del_event_fd(int fd);
+ void ecore_add_event_pid(pid_t pid, void (*func) (pid_t pid));
+ void ecore_del_event_pid(pid_t pid);
+ void ecore_add_event_ipc(int ipc, void (*func) (int ipc));
+ void ecore_del_event_ipc(int ipc);
+ void ecore_event_loop(void);
+ void ecore_event_loop_quit(void);
+ void ecore_add_event_timer(char *name, double in,
+ void (*func) (int val, void *data),
+ int val, void *data);
+ void *ecore_del_event_timer(char *name);
+ void ecore_event_filter(Ecore_Event * ev);
+ void ecore_event_filter_events_handle(Ecore_Event * ev);
+ void ecore_event_filter_idle_handle(void);
+
+ /**
+ * ecore_event_filter_init - Setup event handlers
+ *
+ * This function initializes all ECORE_EVENT_MAX
+ * event handler to be empty.
+ */
+ void ecore_event_filter_init(void);
+
+ void ecore_event_filter_handler_add(Ecore_Event_Type type,
+ void (*func) (Ecore_Event *ev));
+ void ecore_event_filter_idle_handler_add(void (*func) (void *data), void *data);
+
+ /**
+ * ecore_event_signal_init - Setup for default signal handlers
+ *
+ * This function initializes signal handlers for various
+ * signals via sigaction().
+ */
+ void ecore_event_signal_init(void);
+
+ int ecore_event_signal_events_pending(void);
+
+ /**
+ * ecore_event_x_init - Ecore X initialization
+ *
+ * This function initializes Ecore's X event handling
+ * callbacks.
+ */
+ void ecore_event_x_init(void);
+
+ /* ---------------- MISCELLANEOUS CALLS */
+
+ double ecore_get_time(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ecore/src/Makefile.am b/ecore/src/Makefile.am
new file mode 100644
index 0000000..f8d2f8c
--- /dev/null
+++ b/ecore/src/Makefile.am
@@ -0,0 +1,12 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+SUBDIRS = lib bin
+
+EXTRA_DIST = \
+ e_ev_filter.c \
+ e_ev_signal.c \
+ e_ev_x.c \
+ e_events.c \
+ e_ipc.c \
+ e_util.c \
+ e_x.c
diff --git a/ecore/src/bin/.cvsignore b/ecore/src/bin/.cvsignore
new file mode 100644
index 0000000..67aa34d
--- /dev/null
+++ b/ecore/src/bin/.cvsignore
@@ -0,0 +1,6 @@
+.deps
+.libs
+Makefile
+Makefile.in
+ecore_evas_test
+ecore_test
diff --git a/ecore/src/bin/CVS/Entries b/ecore/src/bin/CVS/Entries
new file mode 100644
index 0000000..c8c44fb
--- /dev/null
+++ b/ecore/src/bin/CVS/Entries
@@ -0,0 +1,10 @@
+/.cvsignore/1.1/Thu Nov 13 12:30:47 2003//THEAD
+/Makefile.am/1.16/Thu Jun 23 03:33:43 2005//THEAD
+/ecore_config.c/1.1/Thu Jun 23 03:33:43 2005//THEAD
+/ecore_evas_test.c/1.2/Tue Sep 23 08:09:28 2003//THEAD
+/ecore_evas_test.h/1.3/Wed Feb 23 20:55:18 2005//THEAD
+/ecore_evas_test_app.c/1.7/Sun May 22 03:01:59 2005//THEAD
+/ecore_evas_test_bg.c/1.5/Thu Jul 7 03:31:34 2005//THEAD
+/ecore_evas_test_calibrate.c/1.5/Sat Jan 8 18:40:31 2005//THEAD
+/ecore_test.c/1.18/Mon Jun 20 09:18:01 2005//THEAD
+D
diff --git a/ecore/src/bin/CVS/Repository b/ecore/src/bin/CVS/Repository
new file mode 100644
index 0000000..5c94258
--- /dev/null
+++ b/ecore/src/bin/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/bin
diff --git a/ecore/src/bin/CVS/Root b/ecore/src/bin/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/bin/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/bin/CVS/Tag b/ecore/src/bin/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/bin/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/bin/Makefile.am b/ecore/src/bin/Makefile.am
new file mode 100644
index 0000000..67e6a17
--- /dev/null
+++ b/ecore/src/bin/Makefile.am
@@ -0,0 +1,148 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+if BUILD_ECORE_EVAS
+ECORE_EVAS_LIB = $(top_builddir)/src/lib/ecore_evas/libecore_evas.la
+else
+ECORE_EVAS_LIB =
+endif
+
+if BUILD_ECORE_X
+ECORE_X_LIB = $(top_builddir)/src/lib/ecore_x/libecore_x.la
+else
+ECORE_X_LIB =
+endif
+
+if BUILD_ECORE_FB
+ECORE_FB_LIB = $(top_builddir)/src/lib/ecore_fb/libecore_fb.la
+else
+ECORE_FB_LIB =
+endif
+
+if BUILD_ECORE_JOB
+ECORE_JOB_LIB = $(top_builddir)/src/lib/ecore_job/libecore_job.la
+else
+ECORE_JOB_LIB =
+endif
+
+if BUILD_ECORE_CON
+ECORE_CON_LIB = $(top_builddir)/src/lib/ecore_con/libecore_con.la
+else
+ECORE_CON_LIB =
+endif
+
+if BUILD_ECORE_IPC
+ECORE_IPC_LIB = $(top_builddir)/src/lib/ecore_ipc/libecore_ipc.la
+else
+ECORE_IPC_LIB =
+endif
+
+if BUILD_ECORE_TXT
+ECORE_TXT_LIB = $(top_builddir)/src/lib/ecore_txt/libecore_txt.la
+else
+ECORE_TXT_LIB =
+endif
+
+if BUILD_ECORE_CONFIG
+ECORE_CONFIG_LIB = $(top_builddir)/src/lib/ecore_config/libecore_config.la
+else
+ECORE_CONFIG_LIB =
+endif
+
+INCLUDES = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_evas \
+-I$(top_srcdir)/src/lib/ecore_x \
+-I$(top_srcdir)/src/lib/ecore_fb \
+-I$(top_srcdir)/src/lib/ecore_job \
+-I$(top_srcdir)/src/lib/ecore_con \
+-I$(top_srcdir)/src/lib/ecore_ipc \
+-I$(top_srcdir)/src/lib/ecore_txt @iconv_cflags@ \
+-I$(top_srcdir)/src/lib/ecore_config \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_evas \
+-I$(top_builddir)/src/lib/ecore_x \
+-I$(top_builddir)/src/lib/ecore_fb \
+-I$(top_builddir)/src/lib/ecore_job \
+-I$(top_builddir)/src/lib/ecore_con \
+-I$(top_builddir)/src/lib/ecore_ipc \
+-I$(top_builddir)/src/lib/ecore_txt @iconv_cflags@ \
+-I$(top_builddir)/src/lib/ecore_config \
+@evas_cflags@ \
+@x_cflags@ \
+@eet_cflags@
+
+bin_PROGRAMS = \
+ecore_test \
+ecore_evas_test \
+ecore_config
+
+ecore_test_SOURCES = \
+ecore_test.c
+
+ecore_test_LDADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(ECORE_X_LIB) \
+$(ECORE_TXT_LIB) \
+$(ECORE_JOB_LIB) \
+$(ECORE_FB_LIB) \
+$(ECORE_EVAS_LIB) \
+$(ECORE_CON_LIB) \
+$(ECORE_IPC_LIB) \
+-lm @iconv_libs@
+
+ecore_test_CFLAGS = \
+$(CFLAGS) \
+$(INCLUDES)
+
+ecore_test_DEPENDENCIES = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(ECORE_X_LIB) \
+$(ECORE_TXT_LIB) \
+$(ECORE_JOB_LIB) \
+$(ECORE_FB_LIB) \
+$(ECORE_EVAS_LIB) \
+$(ECORE_CON_LIB) \
+$(ECORE_IPC_LIB)
+
+ecore_evas_test_SOURCES = \
+ecore_evas_test.c \
+ecore_evas_test_app.c \
+ecore_evas_test_bg.c \
+ecore_evas_test_calibrate.c \
+ecore_evas_test.h
+
+ecore_evas_test_LDADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(ECORE_X_LIB) \
+$(ECORE_TXT_LIB) \
+$(ECORE_JOB_LIB) \
+$(ECORE_FB_LIB) \
+$(ECORE_EVAS_LIB) \
+$(ECORE_CON_LIB) \
+$(ECORE_IPC_LIB) \
+-lm @iconv_libs@
+
+ecore_evas_test_CFLAGS = \
+$(CFLAGS) \
+$(INCLUDES)
+
+ecore_evas_test_DEPENDENCIES = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(ECORE_JOB_LIB) \
+$(ECORE_FB_LIB) \
+$(ECORE_X_LIB) \
+$(ECORE_EVAS_LIB) \
+$(ECORE_CON_LIB) \
+$(ECORE_IPC_LIB) \
+$(ECORE_TXT_LIB)
+
+ecore_config_SOURCES = \
+ecore_config.c
+
+ecore_config_LDADD = \
+$(ECORE_CONFIG_LIB)
+
+ecore_config_DEPENDENCIES = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(ECORE_CONFIG_LIB)
+
diff --git a/ecore/src/bin/ecore_config.c b/ecore/src/bin/ecore_config.c
new file mode 100644
index 0000000..690d9fd
--- /dev/null
+++ b/ecore/src/bin/ecore_config.c
@@ -0,0 +1,229 @@
+#include "config.h"
+#include "Ecore.h"
+
+#ifdef BUILD_ECORE_CONFIG
+#include "Ecore_Config.h"
+
+int
+set(const char *key, int ec_type, const char *value)
+{
+ int i;
+ float f;
+
+ switch (ec_type) {
+ case PT_INT:
+ case PT_BLN:
+ i = atoi(value);
+ if (ecore_config_typed_set(key, &i, ec_type) != ECORE_CONFIG_ERR_SUCC) return -1;
+ break;
+ case PT_FLT:
+ f = atof(value);
+ if (ecore_config_typed_set(key, &f, ec_type) != ECORE_CONFIG_ERR_SUCC) return -1;
+ break;
+ case PT_STR:
+ case PT_RGB:
+ case PT_THM:
+ case PT_NIL:
+ if (ecore_config_typed_set(key, value, ec_type) != ECORE_CONFIG_ERR_SUCC) return -1;
+ break;
+ }
+ return 0;
+}
+
+int
+get(const char *key)
+{
+ Ecore_Config_Prop *e;
+
+ if (!(e = ecore_config_get(key))) {
+ fprintf(stderr, "No such property\n");
+ return -1;
+ }
+
+ switch (e->type) {
+ case PT_NIL:
+ printf("\n");
+ break;
+ case PT_INT:
+ printf("%ld\n", ecore_config_int_get(key));
+ break;
+ case PT_BLN:
+ printf("%d\n", ecore_config_boolean_get(key));
+ break;
+ case PT_FLT:
+ printf("%lf\n", ecore_config_float_get(key));
+ break;
+ case PT_STR:
+ printf("%s\n", ecore_config_string_get(key));
+ break;
+ case PT_RGB:
+ printf("%s\n", ecore_config_argbstr_get(key));
+ break;
+ case PT_THM:
+ printf("%s\n", ecore_config_theme_get(key));
+ break;
+ default:
+ fprintf(stderr, "Property has unrecognised type");
+ return -1;
+ }
+ return 0;
+}
+
+int
+list(const char *file)
+{
+ fprintf(stderr, "Command not yet supported\n");
+ return -1;
+}
+
+int
+get_type(const char *key)
+{
+ Ecore_Config_Prop *e;
+ if (!(e = ecore_config_get(key))) {
+ fprintf(stderr, "No such property\n");
+ return -1;
+ }
+
+ switch (e->type) {
+ case PT_NIL:
+ printf("nil\n");
+ break;
+ case PT_INT:
+ printf("int\n");
+ break;
+ case PT_BLN:
+ printf("bool\n");
+ break;
+ case PT_FLT:
+ printf("float\n");
+ break;
+ case PT_STR:
+ printf("string\n");
+ break;
+ case PT_RGB:
+ printf("rgb\n");
+ break;
+ case PT_THM:
+ printf("theme\n");
+ break;
+ default:
+ fprintf(stderr, "Property has unrecognised type");
+ return -1;
+ }
+ return 0;
+}
+
+int
+parse_type(const char *type)
+{
+ if (!strcmp("nil", type)) {
+ return PT_NIL;
+ } else if (!strcmp("int", type)) {
+ return PT_INT;
+ } else if (!strcmp("float", type)) {
+ return PT_FLT;
+ } else if (!strcmp("bool", type)) {
+ return PT_BLN;
+ } else if (!strcmp("str", type)) {
+ return PT_STR;
+ } else if (!strcmp("rgb", type)) {
+ return PT_RGB;
+ } else if (!strcmp("theme", type)) {
+ return PT_THM;
+ }
+ return -1;
+}
+
+void
+usage_and_exit(const char *prog, int ret, const char *msg)
+{
+ if (msg) fprintf(stderr, msg);
+ fprintf(stderr, "Usage: %s <config-file> {get|set|type|list} [args...]\n", prog);
+ fprintf(stderr, "LIST: %s <config-file> list\n", prog);
+ fprintf(stderr, "GET: %s <config-file> get <key>\n", prog);
+ fprintf(stderr, "GET TYPE: %s <config-file> type <key>\n", prog);
+ fprintf(stderr, "SET: %s <config-file> set <key> {nil|int|float|bool|str|rgb|theme} <value>\n", prog);
+ exit(ret);
+}
+
+int
+main(int argc, const char **argv)
+{
+ const char *prog, *file, *cmd, *key, *type, *value;
+ int ec_type = -1;
+ int ret = 0;
+ prog = file = cmd = key = type = value = NULL;
+
+ prog = argv[0];
+ if (argc < 3) usage_and_exit(prog, 2, "Not enough arguments\n");
+
+ file = argv[1];
+ cmd = argv[2];
+
+ // Check for valid command
+ if (strcmp("get", cmd) &&
+ strcmp("type", cmd) &&
+ strcmp("set", cmd) &&
+ strcmp("list", cmd))
+ {
+ usage_and_exit(prog, 2, "Unrecognised command\n");
+ }
+
+ // Check for enough arguments
+ if ((*cmd == 's') || (*cmd == 'g') || (*cmd == 't')) {
+ if (argc < 3) usage_and_exit(prog, 2, "Not enough arguments\n");
+ key = argv[3];
+ }
+
+ if (*cmd == 's') {
+ if (argc < 5) usage_and_exit(prog, 2, "No type and value specified\n");
+ type = argv[4];
+
+ if ((ec_type = parse_type(type)) < 0)
+ usage_and_exit(prog, 3, "Unsupported type\n");
+
+ if (strcmp(type, "nil")) {
+ if (argc < 6)
+ usage_and_exit(prog, 2, "No value specified\n");
+ value = argv[5];
+ }
+ }
+
+ // Load configuration from file
+ ecore_config_init("econfig");
+ ecore_config_file_load(file);
+
+ // Execute command
+ switch (*cmd) {
+ case 's':
+ if (set(key, ec_type, value)) {
+ fprintf(stderr, "Set failed\n");
+ ret = 4;
+ } else {
+ ecore_config_file_save(file);
+ }
+ break;
+ case 'g':
+ if (get(key)) ret = 4;
+ break;
+ case 't':
+ if (get_type(key)) ret = 4;
+ break;
+ case 'l':
+ if (list(file)) ret = 4;
+ break;
+ }
+
+ ecore_config_shutdown();
+
+ return ret;
+}
+#else
+int
+main(int argc, const char **argv)
+{
+ printf("Ecore_config module not compiled. This program is empty.\n");
+ return -1;
+}
+#endif
diff --git a/ecore/src/bin/ecore_evas_test.c b/ecore/src/bin/ecore_evas_test.c
new file mode 100644
index 0000000..91536e5
--- /dev/null
+++ b/ecore/src/bin/ecore_evas_test.c
@@ -0,0 +1,27 @@
+#include "ecore_evas_test.h"
+
+#ifdef BUILD_ECORE_EVAS
+
+int
+main(int argc, const char **argv)
+{
+ if (app_start(argc, argv) < 1) return -1;
+
+ bg_start();
+
+ calibrate_start();
+
+ ecore_main_loop_begin();
+
+ app_finish();
+
+ return 0;
+}
+#else
+int
+main(int argc, const char **argv)
+{
+ printf("Ecore_evas module not compiled. This program is empty.\n");
+ return -1;
+}
+#endif
diff --git a/ecore/src/bin/ecore_evas_test.h b/ecore/src/bin/ecore_evas_test.h
new file mode 100644
index 0000000..f0b9962
--- /dev/null
+++ b/ecore/src/bin/ecore_evas_test.h
@@ -0,0 +1,36 @@
+#ifndef _ECORE_EVAS_TEST_H
+#define _ECORE_EVAS_TEST_H
+
+#include "config.h"
+#include "Ecore.h"
+#include <math.h>
+
+#ifdef BUILD_ECORE_EVAS
+#include "Ecore_Evas.h"
+#include "Ecore_Fb.h"
+
+#define IM PACKAGE_DATA_DIR"/images/"
+#define PT PACKAGE_DATA_DIR"/pointers/"
+#define FN PACKAGE_DATA_DIR"/fonts/"
+
+extern double start_time;
+extern Ecore_Evas *ee;
+extern Evas *evas;
+
+
+
+void calibrate_pos_set(int pos);
+int calibrate_pos_get(void);
+void calibrate_finish(void);
+void calibrate_start(void);
+
+void bg_resize(double w, double h);
+void bg_start(void);
+void bg_go(void);
+
+int app_start(int argc, const char **argv);
+void app_finish(void);
+
+#endif
+
+#endif
diff --git a/ecore/src/bin/ecore_evas_test_app.c b/ecore/src/bin/ecore_evas_test_app.c
new file mode 100644
index 0000000..e1d58d2
--- /dev/null
+++ b/ecore/src/bin/ecore_evas_test_app.c
@@ -0,0 +1,174 @@
+#include "ecore_evas_test.h"
+
+#ifdef BUILD_ECORE_EVAS
+
+double start_time = 0.0;
+Ecore_Evas *ee = NULL;
+Evas *evas = NULL;
+
+Ecore_Idle_Enterer *getpix_handler = NULL;
+
+static void app_resize(Ecore_Evas *ee);
+static int app_signal_exit(void *data, int ev_type, void *ev);
+static void app_delete_request(Ecore_Evas *ee);
+
+static int
+getpix_cb(void *data)
+{
+ const int *pix;
+ int p;
+ int w, h;
+ FILE *f;
+ int x, y;
+ static int count = 0;
+ char buf[256];
+ unsigned char *line;
+
+ pix = ecore_evas_buffer_pixels_get(ee);
+ ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+ snprintf(buf, sizeof(buf), "out%04i.ppm", count);
+ count++;
+ f = fopen(buf, "wb");
+ if (f)
+ {
+ line = malloc(w * 4);
+ fprintf(f, "P6\n%i %i\n255\n", w, h);
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ p = pix[(y * w) + x];
+ line[(x * 3) + 0] = ((p >> 16) & 0xff);
+ line[(x * 3) + 1] = ((p >> 8 ) & 0xff);
+ line[(x * 3) + 2] = ((p ) & 0xff);
+/* line[(x * 3) + 3] = ((p >> 24) & 0xff);*/
+ }
+ fwrite(line, w * 3, 1, f);
+ }
+ free(line);
+ fclose(f);
+ }
+ return 1;
+}
+
+int
+app_start(int argc, const char **argv)
+{
+ /* init the app */
+ start_time = ecore_time_get();
+ ecore_init();
+ ecore_app_args_set(argc, argv);
+ ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, app_signal_exit, NULL);
+
+ /* create an evas */
+ if (!ecore_evas_init()) return -1;
+ if ((argc > 1) && (!strcmp(argv[1], "-fb")))
+ {
+ ee = ecore_evas_fb_new(NULL, 0, 240, 320);
+ evas = ecore_evas_get(ee);
+ }
+ else if ((argc > 1) && (!strcmp(argv[1], "-x")))
+ {
+ ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 240, 320);
+ evas = ecore_evas_get(ee);
+ }
+#if HAVE_ECORE_EVAS_GL
+ else if ((argc > 1) && (!strcmp(argv[1], "-gl")))
+ {
+ ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 240, 320);
+ evas = ecore_evas_get(ee);
+ }
+#endif
+ else if ((argc > 1) && (!strcmp(argv[1], "-buf")))
+ {
+ ee = ecore_evas_buffer_new(240, 320);
+ evas = ecore_evas_get(ee);
+ getpix_handler = ecore_idle_enterer_add(getpix_cb, NULL);
+ }
+ else if ((argc > 1) && (!strcmp(argv[1], "-buf2")))
+ {
+ Evas_Object *o;
+
+ ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 240, 320);
+
+ o = evas_object_rectangle_add(ecore_evas_get(ee));
+ evas_object_move(o, 0, 0);
+ evas_object_resize(o, 240, 320);
+ evas_object_color_set(o, 150, 200, 250, 255);
+ evas_object_show(o);
+
+ o = ecore_evas_object_image_new(ee);
+ evas = ecore_evas_get(evas_object_data_get(o, "Ecore_Evas"));
+ evas_object_move(o, 50, 50);
+ evas_object_resize(o, 120, 160);
+ evas_object_image_fill_set(o, 0, 0, 120, 160);
+ evas_object_image_size_set(o, 240, 320);
+ ecore_evas_resize(evas_object_data_get(o, "Ecore_Evas"), 240, 320);
+ evas_object_color_set(o, 255, 255, 255, 200);
+ evas_object_show(o);
+ }
+ else if ((argc > 1) && (!strcmp(argv[1], "-h")))
+ {
+ printf("%s -x Test ecore_evas in X (default)\n"
+ "%s -gl Test ecore_evas in X GL\n"
+ "%s -fb Test ecore_evas in the Framebuffer\n"
+ "%s -buf Test ecore_evas in the Buffer\n"
+ "%s -buf2 Test ecore_evas in the Image Buffer\n"
+ "%s -h Display this help\n",
+ argv[0], argv[0], argv[0], argv[0], argv[0], argv[0]);
+ ecore_evas_shutdown();
+ ecore_shutdown();
+ return 0;
+ }
+ else {
+#ifdef BUILD_ECORE_X
+ ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 240, 320);
+#else
+#ifdef BUILD_ECORE_FB
+ ee = ecore_evas_fb_new(NULL, 270, 240, 320);
+#endif
+#endif
+ evas = ecore_evas_get(ee);
+ }
+ if (!ee) return -1;
+ ecore_evas_callback_delete_request_set(ee, app_delete_request);
+ ecore_evas_callback_resize_set(ee, app_resize);
+ ecore_evas_title_set(ee, "Ecore Evas Test");
+ ecore_evas_name_class_set(ee, "ecore_test", "test_evas");
+ ecore_evas_show(ee);
+ evas_image_cache_set(evas, 8192 * 1024);
+ evas_font_cache_set(evas, 512 * 1024);
+ evas_font_path_append(evas, FN);
+ return 1;
+}
+
+void
+app_finish(void)
+{
+ ecore_evas_shutdown();
+ ecore_shutdown();
+}
+
+static void
+app_resize(Ecore_Evas *ee)
+{
+ Evas_Coord w, h;
+
+ evas_output_viewport_get(evas, NULL, NULL, &w, &h);
+ bg_resize(w, h);
+}
+
+static int
+app_signal_exit(void *data, int ev_type, void *ev)
+{
+ ecore_main_loop_quit();
+ return 1;
+}
+
+static void
+app_delete_request(Ecore_Evas *ee)
+{
+ ecore_main_loop_quit();
+}
+
+#endif
diff --git a/ecore/src/bin/ecore_evas_test_bg.c b/ecore/src/bin/ecore_evas_test_bg.c
new file mode 100644
index 0000000..397e5f5
--- /dev/null
+++ b/ecore/src/bin/ecore_evas_test_bg.c
@@ -0,0 +1,412 @@
+#include "ecore_evas_test.h"
+
+#ifdef BUILD_ECORE_EVAS
+
+Evas_Object *o_bg_rect = NULL;
+Evas_Object *o_logo = NULL;
+Ecore_Timer *anim_timer = NULL;
+
+#define NUM 32
+#define SIZE 32
+#define SLIDE 80
+
+Evas_Object *o_ball[NUM];
+Evas_Object *o_shad[NUM];
+
+Evas_Object *o_clip = NULL;
+Evas_Object *o_bar[2];
+Evas_Object *o_bar_shad_1[3];
+Evas_Object *o_bar_shad_2[2];
+Evas_Object *o_bg = NULL;
+
+static int bg_animate_obj_timer(void *data);
+static void bg_cb_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+void
+bg_resize(double w, double h)
+{
+ evas_object_resize(o_bg_rect, w, h);
+ evas_object_move(o_logo, (w - 240) / 2, (h - 280) / 2);
+ bg_animate_obj_timer(NULL);
+}
+
+void
+bg_start(void)
+{
+ Evas_Object *o;
+
+ /* set up a big white rectangle on the bg */
+ o = evas_object_rectangle_add(evas);
+ evas_object_color_set(o, 255, 255, 255, 255);
+ evas_object_move(o, 0, 0);
+ evas_object_resize(o, 240, 320);
+ evas_object_layer_set(o, -1000000);
+ evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, bg_cb_key_down, ee);
+ evas_object_focus_set(o, 1);
+ evas_object_show(o);
+ o_bg_rect = o;
+
+ o = evas_object_image_add(evas);
+ evas_object_image_file_set(o, IM"e_logo.png", NULL);
+ evas_object_resize(o, 240, 280);
+ evas_object_image_fill_set(o, 0, 0, 240, 280);
+ evas_object_move(o, (240 - 240) / 2, (320 - 280) / 2);
+ evas_object_layer_set(o, -999);
+ evas_object_pass_events_set(o, 1);
+ evas_object_show(o);
+ o_logo = o;
+
+ o = evas_object_rectangle_add(evas);
+ evas_object_color_set(o, 255, 255, 255, 255);
+ evas_object_resize(o, 240, 0);
+ evas_object_pass_events_set(o, 1);
+ evas_object_show(o);
+ o_clip = o;
+
+ o = evas_object_image_add(evas);
+ evas_object_image_file_set(o, IM"bg.png", NULL);
+ evas_object_resize(o, 240, 320);
+ evas_object_image_fill_set(o, 0, 0, 240, 320);
+ evas_object_layer_set(o, -9999);
+ evas_object_move(o, 0, 0);
+ evas_object_clip_set(o, o_clip);
+ evas_object_pass_events_set(o, 1);
+ evas_object_show(o);
+ o_bg = o;
+
+ o = evas_object_image_add(evas);
+ evas_object_image_file_set(o, IM"bar.png", NULL);
+ evas_object_image_border_set(o, 5, 5, 5, 5);
+ evas_object_resize(o, 240, 32);
+ evas_object_image_fill_set(o, 0, 0, 240, 32);
+ evas_object_layer_set(o, 100);
+ evas_object_pass_events_set(o, 1);
+ o_bar[0] = o;
+
+ o = evas_object_image_add(evas);
+ evas_object_image_file_set(o, IM"bar.png", NULL);
+ evas_object_image_border_set(o, 5, 5, 5, 5);
+ evas_object_resize(o, 240, 32);
+ evas_object_image_fill_set(o, 0, 0, 240, 32);
+ evas_object_layer_set(o, 100);
+ evas_object_pass_events_set(o, 1);
+ o_bar[1] = o;
+
+ o = evas_object_image_add(evas);
+ evas_object_image_file_set(o, IM"bar_shad_above.png", NULL);
+ evas_object_resize(o, 240, 8);
+ evas_object_image_fill_set(o, 0, 0, 240, 8);
+ evas_object_image_smooth_scale_set(o, 0);
+ evas_object_layer_set(o, 100);
+ evas_object_pass_events_set(o, 1);
+ o_bar_shad_1[0] = o;
+
+ o = evas_object_image_add(evas);
+ evas_object_image_file_set(o, IM"bar_shad_below.png", NULL);
+ evas_object_resize(o, 240, 32);
+ evas_object_image_fill_set(o, 0, 0, 240, 32);
+ evas_object_image_smooth_scale_set(o, 0);
+ evas_object_layer_set(o, -100);
+ evas_object_pass_events_set(o, 1);
+ evas_object_clip_set(o, o_clip);
+ o_bar_shad_1[1] = o;
+
+ o = evas_object_image_add(evas);
+ evas_object_image_file_set(o, IM"bar_shad_below.png", NULL);
+ evas_object_resize(o, 240, 16);
+ evas_object_image_fill_set(o, 0, 0, 240, 16);
+ evas_object_image_smooth_scale_set(o, 0);
+ evas_object_layer_set(o, 100);
+ evas_object_pass_events_set(o, 1);
+ evas_object_clip_set(o, o_clip);
+ o_bar_shad_1[2] = o;
+
+ o = evas_object_image_add(evas);
+ evas_object_image_file_set(o, IM"bar_shad_above.png", NULL);
+ evas_object_resize(o, 240, 8);
+ evas_object_image_fill_set(o, 0, 0, 240, 8);
+ evas_object_image_smooth_scale_set(o, 0);
+ evas_object_layer_set(o, 100);
+ evas_object_pass_events_set(o, 1);
+ evas_object_clip_set(o, o_clip);
+ o_bar_shad_2[0] = o;
+
+ o = evas_object_image_add(evas);
+ evas_object_image_file_set(o, IM"bar_shad_below.png", NULL);
+ evas_object_resize(o, 240, 8);
+ evas_object_image_fill_set(o, 0, 0, 240, 8);
+ evas_object_image_smooth_scale_set(o, 0);
+ evas_object_layer_set(o, 100);
+ evas_object_pass_events_set(o, 1);
+ o_bar_shad_2[1] = o;
+
+ {
+ int i;
+
+ for (i = 0; i < NUM; i++)
+ {
+ o = evas_object_image_add(evas);
+ evas_object_image_file_set(o, IM"ball.png", NULL);
+ evas_object_resize(o, SIZE, SIZE);
+ evas_object_image_fill_set(o, 0, 0, SIZE, SIZE);
+ evas_object_move(o, 0, 0);
+ evas_object_pass_events_set(o, 1);
+ evas_object_clip_set(o, o_clip);
+ o_ball[i] = o;
+ o = evas_object_image_add(evas);
+ evas_object_image_file_set(o, IM"shadow.png", NULL);
+ evas_object_resize(o, SIZE, SIZE);
+ evas_object_image_fill_set(o, 0, 0, SIZE, SIZE);
+ evas_object_move(o, 0, 0);
+ evas_object_pass_events_set(o, 1);
+ evas_object_clip_set(o, o_clip);
+ evas_object_lower(o);
+ o_shad[i] = o;
+ }
+ }
+}
+
+void
+bg_go(void)
+{
+ /* add a timer to animate them */
+ anim_timer = ecore_timer_add(0.01, bg_animate_obj_timer, NULL);
+}
+
+static int
+bg_animate_obj_timer(void *data)
+{
+ Evas_Object *o;
+ Evas_Coord x, y, sx, sy;
+ Evas_Coord w, h;
+ double v;
+ int ow, oh;
+ double t;
+ int l, m, n;
+ int i;
+ static double t_first = 0;
+ static int done = 0;
+
+ t = ecore_time_get() - start_time;
+ if (t_first == 0) t_first = t;
+ if (t - t_first > 2.0) done = 1;
+ evas_output_viewport_get(evas_object_evas_get(o_clip), NULL, NULL, &w, &h);
+ if (!done)
+ {
+ v = ((cos(((t - t_first) / 2) * 3.14159) - 1.0) / -2);
+ l = (SLIDE) * v;
+ }
+ else
+ {
+ l = SLIDE;
+ }
+ evas_object_move(o_bar[0], 0, (h / 2) - 32 - l);
+ evas_object_move(o_bar[1], 0, (h / 2) + l);
+ evas_object_move(o_bar_shad_1[0], 0, (h / 2) - 32 - l - 8);
+ evas_object_move(o_bar_shad_1[1], 0, (h / 2) - l);
+ evas_object_move(o_bar_shad_1[2], 0, (h / 2) - l);
+ evas_object_move(o_bar_shad_2[0], 0, (h / 2) + l - 8);
+ evas_object_move(o_bar_shad_2[1], 0, (h / 2) + 32 + l);
+
+ evas_object_resize(o_bar[0], w, 32);
+ evas_object_image_fill_set(o_bar[0], 0, 0, w, 32);
+
+ evas_object_resize(o_bar[1], w, 32);
+ evas_object_image_fill_set(o_bar[1], 0, 0, w, 32);
+
+ evas_object_resize(o_bar_shad_1[0], w, 8);
+ evas_object_image_fill_set(o_bar_shad_1[0], 0, 0, w, 8);
+
+ evas_object_resize(o_bar_shad_1[1], w, 32);
+ evas_object_image_fill_set(o_bar_shad_1[1], 0, 0, w, 32);
+
+ evas_object_resize(o_bar_shad_1[2], w, 16);
+ evas_object_image_fill_set(o_bar_shad_1[2], 0, 0, w, 16);
+
+ evas_object_resize(o_bar_shad_2[0], w, 8);
+ evas_object_image_fill_set(o_bar_shad_2[0], 0, 0, w, 8);
+
+ evas_object_resize(o_bar_shad_2[1], w, 8);
+ evas_object_image_fill_set(o_bar_shad_2[1], 0, 0, w, 8);
+
+ evas_object_move(o_clip, 0, (h / 2) - l);
+ evas_object_resize(o_clip, w, l * 2);
+
+ evas_object_resize(o_bg, w, h);
+ evas_object_image_fill_set(o_bg, 0, 0, w, h);
+
+ evas_object_show(o_bar[0]);
+ evas_object_show(o_bar[1]);
+ evas_object_show(o_bar_shad_1[0]);
+ evas_object_show(o_bar_shad_1[1]);
+ evas_object_show(o_bar_shad_1[2]);
+ evas_object_show(o_bar_shad_2[0]);
+ evas_object_show(o_bar_shad_2[1]);
+ for (i = 0; i < NUM; i++)
+ {
+ o = o_ball[i];
+ evas_output_viewport_get(evas_object_evas_get(o), NULL, NULL, &w, &h);
+ l = ((int)o / 179) & 0x0f;
+ v = (sin(t * (double)l / 12) + 1.0) / 2;
+ v = 0.25 + (0.75 * v);
+ m = 1 + (((int)o / 36) & 0x0f);
+ n = 1 + (((int)o / 763) & 0x0f);
+ ow = SIZE * v;
+ oh = SIZE * v;
+ evas_object_resize(o, ow, oh);
+ evas_object_image_fill_set(o, 0, 0, ow, oh);
+ x = sin(t * (double)m / 12) * ((w - ow) / 2);
+ y = sin(t * (double)n / 12) * ((h - oh) / 2);
+ evas_object_move(o, (w / 2) - (ow / 2) + x, (h / 2) - (oh / 2) + y);
+ evas_object_show(o);
+ o = o_shad[i];
+ evas_object_resize(o, ow, oh);
+ evas_object_image_fill_set(o, 0, 0, ow, oh);
+ sx = v * (((w - ow) / 2) + x) / 8;
+ sy = v * (((h - oh) / 2) + y) / 8;
+ evas_object_move(o,
+ (w / 2) - (ow / 2) + x + sx,
+ (h / 2) - (oh / 2) + y + sy);
+ evas_object_show(o);
+ }
+ return 1;
+}
+
+/* NB: on ipaq
+ *
+ * "F1" "F2" "F3" "F4"
+ * "Up"
+ * "Left" "Return" "Right"
+ * "Down"
+ *
+ */
+static void
+bg_cb_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Key_Down *ev;
+
+ ev = event_info;
+ if (!strcmp(ev->keyname, "Escape")) ecore_main_loop_quit();
+ if (!strcmp(ev->keyname, "q")) ecore_main_loop_quit();
+ if (!strcmp(ev->keyname, "Q")) ecore_main_loop_quit();
+ if ((!strcmp(ev->keyname, "f")) ||
+ (!strcmp(ev->keyname, "F1")))
+ {
+ if (!ecore_evas_fullscreen_get(ee))
+ ecore_evas_fullscreen_set(ee, 1);
+ else
+ ecore_evas_fullscreen_set(ee, 0);
+ }
+ if (!strcmp(ev->keyname, "o"))
+ {
+ if (!ecore_evas_override_get(ee))
+ ecore_evas_override_set(ee, 1);
+ else
+ ecore_evas_override_set(ee, 0);
+ }
+ if ((!strcmp(ev->keyname, "r")) ||
+ (!strcmp(ev->keyname, "F4")))
+ {
+ int r;
+
+ r = ecore_evas_rotation_get(ee);
+ if (r == 0) r = 90;
+ else if (r == 90) r = 270;
+ else if (r == 270) r = 0;
+ ecore_evas_rotation_set(ee, r);
+ }
+ if (!strcmp(ev->keyname, "b"))
+ {
+ if (!ecore_evas_borderless_get(ee))
+ ecore_evas_borderless_set(ee, 1);
+ else
+ ecore_evas_borderless_set(ee, 0);
+ }
+ if (!strcmp(ev->keyname, "d"))
+ {
+ if (!ecore_evas_avoid_damage_get(ee))
+ ecore_evas_avoid_damage_set(ee, 1);
+ else
+ ecore_evas_avoid_damage_set(ee, 0);
+ }
+ if (!strcmp(ev->keyname, "s"))
+ {
+ if (!ecore_evas_shaped_get(ee))
+ {
+ evas_object_hide(o_bg_rect);
+// evas_object_hide(o_bg);
+ ecore_evas_shaped_set(ee, 1);
+ }
+ else
+ {
+ evas_object_show(o_bg_rect);
+// evas_object_show(o_bg);
+ ecore_evas_shaped_set(ee, 0);
+ }
+ }
+ if (!strcmp(ev->keyname, "Up"))
+ {
+#ifdef BUILD_ECORE_FB
+ double br;
+
+ br = ecore_fb_backlight_brightness_get();
+ ecore_fb_backlight_brightness_set(br + 0.1);
+#endif
+ }
+ if (!strcmp(ev->keyname, "Down"))
+ {
+#ifdef BUILD_ECORE_FB
+ double br;
+
+ br = ecore_fb_backlight_brightness_get();
+ ecore_fb_backlight_brightness_set(br - 0.1);
+#endif
+ }
+ if (!strcmp(ev->keyname, "F2"))
+ {
+#ifdef BUILD_ECORE_FB
+ if (ecore_fb_backlight_get())
+ ecore_fb_backlight_set(0);
+ else
+ ecore_fb_backlight_set(1);
+#endif
+ }
+ if (!strcmp(ev->keyname, "F3"))
+ {
+#ifdef BUILD_ECORE_FB
+ static int v = 0;
+
+ if (v) ecore_fb_led_set(0);
+ else ecore_fb_led_set(1);
+ if (!v) v = 1;
+ else v = 0;
+#endif
+ }
+ if (!strcmp(ev->keyname, "Left"))
+ {
+#ifdef BUILD_ECORE_FB
+ ecore_fb_led_blink_set(0.1);
+#endif
+ }
+ if (!strcmp(ev->keyname, "Right"))
+ {
+#ifdef BUILD_ECORE_FB
+ ecore_fb_led_blink_set(0.5);
+#endif
+ }
+ if ((!strcmp(ev->keyname, "p")) ||
+ (!strcmp(ev->keyname, "Return")))
+ {
+ char *fl;
+
+ ecore_evas_cursor_get(ee, &fl, NULL, NULL, NULL);
+ if (!fl)
+ ecore_evas_cursor_set(ee, PT"mouse_pointer.png", 1000000, 2, 2);
+ else
+ ecore_evas_cursor_set(ee, NULL, 0, 0, 0);
+#ifdef BUILD_ECORE_FB
+ printf("%3.3f\n", ecore_fb_light_sensor_get());
+#endif
+ }
+}
+#endif
diff --git a/ecore/src/bin/ecore_evas_test_calibrate.c b/ecore/src/bin/ecore_evas_test_calibrate.c
new file mode 100644
index 0000000..22b2424
--- /dev/null
+++ b/ecore/src/bin/ecore_evas_test_calibrate.c
@@ -0,0 +1,285 @@
+#include "ecore_evas_test.h"
+
+#ifdef BUILD_ECORE_EVAS
+
+static Evas_Object *o_events = NULL;
+static Evas_Object *o_crosshair = NULL;
+static Evas_Object *o_text = NULL;
+static int cal_pos = 0;
+static int down = 0;
+
+static int cal_coords[] = {15, 15, -15, 15, 15, -15, -15, -15};
+static char *cal_lines[] =
+{
+ "Please click on the crosshair",
+ "Again please",
+ "And again",
+ "Last one, then calibration is complete"
+};
+static int cal_input[8];
+
+static int tmp_input_count = 0;
+static int tmp_input[16];
+
+static void calibrate_cb_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void calibrate_cb_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void calibrate_cb_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+void
+calibrate_pos_set(int pos)
+{
+ Evas_Coord w, h, ow, oh;
+ int x, y;
+
+ cal_pos = pos;
+ evas_object_geometry_get(o_crosshair, NULL, NULL, &w, &h);
+ x = cal_coords[(cal_pos * 2) + 0];
+ y = cal_coords[(cal_pos * 2) + 1];
+ evas_output_viewport_get(evas, NULL, NULL, &ow, &oh);
+ if (x < 0) x = ow + x - 1;
+ if (y < 0) y = oh + y - 1;
+ cal_coords[(cal_pos * 2) + 0] = x;
+ cal_coords[(cal_pos * 2) + 1] = y;
+ evas_object_move(o_crosshair, x - (((int)w - 1) / 2), y - (((int)h - 1) / 2));
+ evas_object_text_text_set(o_text, cal_lines[cal_pos]);
+ evas_object_geometry_get(o_text, NULL, NULL, &w, &h);
+ evas_object_move(o_text, (ow - w) / 2, (oh - h) / 2);
+}
+
+int
+calibrate_pos_get(void)
+{
+ return cal_pos;
+}
+
+void
+calibrate_finish(void)
+{
+ int m0, m1;
+ int y0, y1;
+ int x[4], y[4], xi[4], yi[4];
+ int i, rot;
+
+ int xscale, xtrans, yscale, ytrans, xyswap;
+
+ rot = ecore_evas_rotation_get(ee);
+ for (i = 0; i < 4; i++)
+ {
+ x[i] = cal_coords[(i * 2) + 0];
+ y[i] = cal_coords[(i * 2) + 1];
+ xi[i] = cal_input[(i * 2) + 0];
+ yi[i] = cal_input[(i * 2) + 1];
+ }
+ xyswap = 0;
+
+ m0 = ((x[1] - x[0]) * 256) / (xi[1] - xi[0]);
+ y0 = ((x[1] - ((xi[1] * m0) / 256)) + (x[0] - ((xi[0] * m0) >> 8)) ) / 2;
+
+ m1 = ((x[3] - x[2]) * 256) / (xi[3] - xi[2]);
+ y1 = ((x[3] - ((xi[3] * m1) / 256)) + (x[2] - ((xi[2] * m1) >> 8)) ) / 2;
+
+ xscale = (m0 + m1) / 2;
+ xtrans = (y0 + y1) / 2;
+
+ m0 = ((y[2] - y[0]) * 256) / (yi[2] - yi[0]);
+ y0 = ((y[2] - ((yi[2] * m0) / 256)) + (y[0] - ((yi[0] * m0) >> 8)) ) / 2;
+
+ m1 = ((y[3] - y[1]) * 256) / (yi[3] - yi[1]);
+ y1 = ((y[3] - ((yi[3] * m1) / 256)) + (y[1] - ((yi[1] * m1) >> 8)) ) / 2;
+
+ yscale = (m0 + m1) / 2;
+ ytrans = (y0 + y1) / 2;
+
+ if (rot == 0)
+ {
+#ifdef BUILD_ECORE_FB
+ ecore_fb_touch_screen_calibrate_set(xscale, xtrans, yscale, ytrans, xyswap);
+#endif
+ }
+ else if (rot == 270)
+ {
+ int ow, oh;
+
+ evas_output_size_get(evas, &ow, &oh);
+ ytrans = oh - (ytrans + ((oh * yscale) / 256));
+#ifdef BUILD_ECORE_FB
+ ecore_fb_touch_screen_calibrate_set(yscale, ytrans, xscale, xtrans, xyswap);
+#endif
+ }
+
+ evas_object_del(o_crosshair);
+ evas_object_del(o_events);
+ evas_object_del(o_text);
+ o_crosshair = NULL;
+ o_events = NULL;
+ o_text = NULL;
+ cal_pos = 0;
+ bg_go();
+}
+
+void
+calibrate_start(void)
+{
+ Evas_Object *o;
+
+#ifdef BUILD_ECORE_FB
+ ecore_fb_touch_screen_calibrate_set(256, 0, 256, 0, 0);
+#endif
+
+ o = evas_object_rectangle_add(evas);
+ evas_object_layer_set(o, 1000000);
+ evas_object_color_set(o, 255, 255, 255, 120);
+ evas_object_move(o, -12000, -16000);
+ evas_object_resize(o, 24000, 32000);
+ evas_object_show(o);
+ evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, calibrate_cb_down, ee);
+ evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, calibrate_cb_up, ee);
+ evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, calibrate_cb_move, ee);
+ o_events = o;
+
+ o = evas_object_image_add(evas);
+ evas_object_layer_set(o, 1000001);
+ evas_object_image_file_set(o, IM"crosshair.png", NULL);
+ evas_object_resize(o, 31, 31);
+ evas_object_image_fill_set(o, 0, 0, 31, 31);
+ evas_object_pass_events_set(o, 1);
+ evas_object_show(o);
+ o_crosshair = o;
+
+ o = evas_object_text_add(evas);
+ evas_object_layer_set(o, 1000002);
+ evas_object_color_set(o, 0, 0, 0, 255);
+ evas_object_text_font_set(o, "Vera", 10);
+ evas_object_pass_events_set(o, 1);
+ evas_object_show(o);
+ o_text = o;
+
+ calibrate_pos_set(0);
+}
+
+
+static void
+calibrate_cb_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Down *ev;
+
+ ev = event_info;
+
+ evas_object_move(o_crosshair, ev->output.x - 15, ev->output.y - 15);
+ tmp_input_count = 0;
+ tmp_input[((tmp_input_count & 0x7) * 2) + 0] = ev->output.x;
+ tmp_input[((tmp_input_count & 0x7) * 2) + 1] = ev->output.y;
+ tmp_input_count++;
+ down = 1;
+}
+
+static void
+calibrate_cb_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Up *ev;
+ int n, i, avx, avy, c, mx, my;
+ int dists[8];
+ int indexes[8];
+ int sorted;
+
+ ev = event_info;
+ down = 0;
+ tmp_input[((tmp_input_count & 0x7) * 2) + 0] = ev->output.x;
+ tmp_input[((tmp_input_count & 0x7) * 2) + 1] = ev->output.y;
+ tmp_input_count++;
+ n = 8;
+ if (tmp_input_count < 8) n = tmp_input_count;
+ avx = 0; avy = 0; c = 0;
+ for (i = 0; i < n; i++)
+ {
+ dists[i] = tmp_input[(i * 2) + 0];
+ indexes[i] = i;
+ }
+ sorted = 0;
+ while (!sorted)
+ {
+ sorted = 1;
+ for (i = 0; i < n - 1; i++)
+ {
+ if (dists[i + 1] < dists[i])
+ {
+ int tmp;
+
+ sorted = 0;
+ tmp = dists[i];
+ dists[i] = dists[i + 1];
+ dists[i + 1] = tmp;
+ tmp = indexes[i];
+ indexes[i] = indexes[i + 1];
+ indexes[i + 1] = tmp;
+ }
+ }
+ }
+ mx = dists[(n + 1) / 2];
+ for (i = 0; i < n; i++)
+ {
+ dists[i] = tmp_input[(i * 2) + 1];
+ indexes[i] = i;
+ }
+ sorted = 0;
+ while (!sorted)
+ {
+ sorted = 1;
+ for (i = 0; i < n - 1; i++)
+ {
+ if (dists[i + 1] < dists[i])
+ {
+ int tmp;
+
+ sorted = 0;
+ tmp = dists[i];
+ dists[i] = dists[i + 1];
+ dists[i + 1] = tmp;
+ tmp = indexes[i];
+ indexes[i] = indexes[i + 1];
+ indexes[i + 1] = tmp;
+ }
+ }
+ }
+ my = dists[(n + 1) / 2];
+
+ for (i = 0; i < n; i++)
+ {
+ int x, y, dx, dy;
+
+ x = tmp_input[(i * 2) + 0];
+ y = tmp_input[(i * 2) + 1];
+ dx = x - mx;
+ dy = y - my;
+ if (dx < 0) dx = -dx;
+ if (dy < 0) dy = -dy;
+ if ((dx <= 8) && (dy <= 8))
+ {
+ avx += tmp_input[(i * 2) + 0];
+ avy += tmp_input[(i * 2) + 1];
+ c++;
+ }
+ }
+ cal_input[(cal_pos * 2) + 0] = avx / c;
+ cal_input[(cal_pos * 2) + 1] = avy / c;
+ n = calibrate_pos_get();
+ if (n < 3)
+ {
+ calibrate_pos_set(n + 1);
+ return;
+ }
+ calibrate_finish();
+}
+
+static void
+calibrate_cb_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Move *ev;
+
+ ev = event_info;
+ if (!down) return;
+ tmp_input[((tmp_input_count & 0x7) * 2) + 0] = ev->cur.output.x;
+ tmp_input[((tmp_input_count & 0x7) * 2) + 1] = ev->cur.output.y;
+ tmp_input_count++;
+}
+#endif
diff --git a/ecore/src/bin/ecore_test.c b/ecore/src/bin/ecore_test.c
new file mode 100644
index 0000000..c32aef8
--- /dev/null
+++ b/ecore/src/bin/ecore_test.c
@@ -0,0 +1,899 @@
+#include "config.h"
+#include "Ecore.h"
+#ifdef BUILD_ECORE_JOB
+#include "Ecore_Job.h"
+#endif
+#ifdef BUILD_ECORE_X
+#include "Ecore_X.h"
+#endif
+#ifdef BUILD_ECORE_FB
+#include "Ecore_Fb.h"
+#endif
+#ifdef BUILD_ECORE_EVAS
+#include "Ecore_Evas.h"
+#endif
+#ifdef BUILD_ECORE_CON
+#include "Ecore_Con.h"
+#endif
+#ifdef BUILD_ECORE_IPC
+#include "Ecore_Ipc.h"
+#endif
+
+#include <math.h>
+
+/* APP GLOBALS */
+double start_time = 0;
+
+int
+handler_signal_exit(void *data, int ev_type, void *ev)
+{
+ Ecore_Event_Signal_Exit *e;
+
+ e = ev;
+ if (e->interrupt) printf("exit: interrupt\n");
+ if (e->quit) printf("exit: quit\n");
+ if (e->terminate) printf("exit: terminate\n");
+ ecore_main_loop_quit();
+ return 1;
+}
+
+
+
+
+
+
+int
+handler_ipc_client_add(void *data, int type, void *event)
+{
+#ifdef BUILD_ECORE_IPC
+ Ecore_Ipc_Event_Client_Add *e;
+
+ e = event;
+ printf("!!! client %p connected to server!\n", e->client);
+ return 1;
+#endif
+}
+
+int
+handler_ipc_client_del(void *data, int type, void *event)
+{
+#ifdef BUILD_ECORE_IPC
+ Ecore_Ipc_Event_Client_Del *e;
+
+ e = event;
+ printf("!!! client %p disconnected from server!\n", e->client);
+ return 1;
+#endif
+}
+
+
+int
+handler_ipc_client_data(void *data, int type, void *event)
+{
+#ifdef BUILD_ECORE_IPC
+ Ecore_Ipc_Event_Client_Data *e;
+
+ e = event;
+ printf("!!! client sent: [%i] [%i] (%i) \"%s\"\n", e->major, e->minor, e->size, (char*)e->data);
+ ecore_ipc_client_send(e->client, 1, 2, 0, 0, 0, "ABC", 4);
+ /* we can disconnect a client like this: */
+ /* ecore_ipc_client_del(e->client); */
+ /* or we can end a server by: */
+ /* ecore_ipc_server_del(ecore_ipc_client_server_get(e->client)); */
+ return 1;
+#endif
+}
+
+
+int
+handler_ipc_server_add(void *data, int type, void *event)
+{
+#ifdef BUILD_ECORE_IPC
+ Ecore_Ipc_Event_Server_Add *e;
+
+ e = event;
+ printf("!!! client made successful connect to server %p!\n", e->server);
+ return 1;
+#endif
+}
+
+int
+handler_ipc_server_del(void *data, int type, void *event)
+{
+#ifdef BUILD_ECORE_IPC
+ Ecore_Ipc_Event_Server_Del *e;
+
+ e = event;
+ printf("!!! server went away!\n");
+ /* clean up our server connection since it went away */
+ ecore_ipc_server_del(e->server);
+ return 1;
+#endif
+}
+
+int
+handler_ipc_server_data(void *data, int type, void *event)
+{
+#ifdef BUILD_ECORE_IPC
+ Ecore_Ipc_Event_Server_Data *e;
+ static int count = 0;
+
+ e = event;
+ printf("!!! server sent: [%i] [%i] (%i) \"%s\"\n", e->major, e->minor, e->size, (char*)e->data);
+ ecore_ipc_server_send(e->server, 3, 4, 0, 0, 0, "EFG", 4);
+ count++;
+ if (count > 4)
+ {
+ printf("!!! go & disconnect from server!\n");
+ ecore_ipc_server_del(e->server);
+ }
+ return 1;
+#endif
+}
+
+/**** ECORE_CON TEST CODE */
+int
+handler_client_add(void *data, int type, void *event)
+{
+#ifdef BUILD_ECORE_CON
+ Ecore_Con_Event_Client_Add *e;
+
+ e = event;
+ printf("!!! client %p connected to server!\n", e->client);
+ return 1;
+#endif
+}
+
+int
+handler_client_del(void *data, int type, void *event)
+{
+#ifdef BUILD_ECORE_CON
+ Ecore_Con_Event_Client_Del *e;
+
+ e = event;
+ printf("!!! client %p disconnected from server!\n", e->client);
+ return 1;
+#endif
+}
+
+
+int
+handler_client_data(void *data, int type, void *event)
+{
+#ifdef BUILD_ECORE_CON
+ Ecore_Con_Event_Client_Data *e;
+
+ e = event;
+ printf("!!! client sent: \"%s\"\n", (char*)e->data);
+ ecore_con_client_send(e->client, "ABC", 4);
+ /* we can disconnect a client like this: */
+ /* ecore_con_client_del(e->client); */
+ /* or we can end a server by: */
+ /* ecore_con_server_del(ecore_con_client_server_get(e->client)); */
+ return 1;
+#endif
+}
+
+
+int
+handler_server_add(void *data, int type, void *event)
+{
+#ifdef BUILD_ECORE_CON
+ Ecore_Con_Event_Server_Add *e;
+
+ e = event;
+ printf("!!! client made successful connect to server %p!\n", e->server);
+ return 1;
+#endif
+}
+
+int
+handler_server_del(void *data, int type, void *event)
+{
+#ifdef BUILD_ECORE_CON
+ Ecore_Con_Event_Server_Del *e;
+
+ e = event;
+ printf("!!! server went away!\n");
+ /* clean up our server connection since it went away */
+ ecore_con_server_del(e->server);
+ return 1;
+#endif
+}
+
+int
+handler_server_data(void *data, int type, void *event)
+{
+#ifdef BUILD_ECORE_CON
+ Ecore_Con_Event_Server_Data *e;
+ static int count = 0;
+
+ e = event;
+ printf("!!! server sent: \"%s\"\n", (char*)e->data);
+ ecore_con_server_send(e->server, "EFG", 4);
+ count++;
+ if (count > 4)
+ {
+ printf("!!! go & disconnect from server!\n");
+ ecore_con_server_del(e->server);
+ }
+ return 1;
+#endif
+}
+
+
+/* NB: also tests ECORE_JOB */
+#ifdef BUILD_ECORE_JOB
+void
+job_call(void *data)
+{
+ printf("!! Job done \"%s\"!\n", (char *)data);
+}
+#endif
+
+int
+idle_enterer(void *data)
+{
+ printf("-------> Entering idle %3.3f\n", ecore_time_get() - start_time);
+ return 1;
+}
+
+int
+idler(void *data)
+{
+ printf("oo Idler %3.3f\n", ecore_time_get() - start_time);
+ return 1;
+}
+
+int
+timer(void *data)
+{
+ printf("Q- Timer tick %3.8f\n", ecore_time_get() - start_time);
+ /* test ecore_job */
+#ifdef BUILD_ECORE_JOB
+ ecore_job_add(job_call, "1");
+ ecore_job_add(job_call, "2");
+ ecore_job_add(job_call, "3");
+#endif
+ return 1;
+}
+
+void
+setup_ecore_test(void)
+{
+ ecore_idle_enterer_add(idle_enterer, NULL);
+/* ecore_idler_add(idler, NULL); */
+ ecore_timer_add(2.0, timer, NULL);
+}
+
+#ifdef BUILD_ECORE_X
+/**** ECORE_X TEST CODE */
+
+Ecore_X_Window win = 0;
+
+int
+handler_x_key_down(void *data, int type, void *event)
+{
+ Ecore_X_Event_Key_Down *e;
+
+ e = event;
+ printf("Key down %s\n", e->keyname);
+ return 1;
+}
+
+int
+handler_x_key_up(void *data, int type, void *event)
+{
+ Ecore_X_Event_Key_Up *e;
+
+ e = event;
+ printf("Key up %s\n", e->keyname);
+ return 1;
+}
+
+int
+handler_x_mouse_button_down(void *data, int type, void *event)
+{
+ Ecore_X_Event_Mouse_Button_Down *e;
+
+ e = event;
+ printf("Mouse down %i [%i][%i]\n", e->button, e->double_click, e->triple_click);
+ return 1;
+}
+
+int
+handler_x_mouse_button_up(void *data, int type, void *event)
+{
+ Ecore_X_Event_Mouse_Button_Up *e;
+
+ e = event;
+ printf("Mouse up %i\n", e->button);
+ return 1;
+}
+
+int
+handler_x_mouse_move(void *data, int type, void *event)
+{
+ Ecore_X_Event_Mouse_Move *e;
+
+ e = event;
+ printf("Mouse move to %i %i\n", e->x, e->y);
+ return 1;
+}
+
+int
+handler_x_mouse_in(void *data, int type, void *event)
+{
+ Ecore_X_Event_Mouse_In *e;
+
+ e = event;
+ printf("Mouse in\n");
+ return 1;
+}
+
+int
+handler_x_mouse_out(void *data, int type, void *event)
+{
+ Ecore_X_Event_Mouse_Out *e;
+
+ e = event;
+ printf("Mouse out\n");
+ return 1;
+}
+
+int
+handler_x_window_focus_in(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Focus_In *e;
+
+ e = event;
+ printf("Focus in\n");
+ return 1;
+}
+
+int
+handler_x_window_focus_out(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Focus_Out *e;
+
+ e = event;
+ printf("Focus out\n");
+ return 1;
+}
+
+int
+handler_x_window_damage(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Damage *e;
+
+ e = event;
+ printf("Damage %i %i, %ix%i\n", e->x, e->y, e->w, e->h);
+ return 1;
+}
+
+int
+handler_x_window_destroy(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Destroy *e;
+
+ e = event;
+ printf("Destroy\n");
+ ecore_main_loop_quit();
+ return 1;
+}
+
+int
+handler_x_window_configure(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Configure *e;
+ const int desktop = 0;
+
+ e = event;
+ printf("Configure %i %i, %ix%i\n", e->x, e->y, e->w, e->h);
+ printf("Switching desktops to %d\n", desktop);
+ ecore_x_netwm_desktop_request_send(e->win, 0, desktop);
+ return 1;
+}
+
+int
+handler_x_window_delete_request(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Delete_Request *e;
+
+ e = event;
+ printf("Delete Request\n");
+ ecore_main_loop_quit();
+ return 1;
+}
+
+int
+handler_x_window_prop_title_change(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Prop_Title_Change *e;
+
+ e = event;
+ if (e->title)
+ printf("Title change to \"%s\"\n", e->title);
+ else
+ printf("Title deleted\n");
+ return 1;
+}
+
+int
+handler_x_window_prop_visible_title_change(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
+
+ e = event;
+ if (e->title)
+ printf("Visible title change to \"%s\"\n", e->title);
+ else
+ printf("Visible title deleted\n");
+ return 1;
+}
+
+int
+handler_x_window_prop_icon_name_change(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
+
+ e = event;
+ if (e->name)
+ printf("Icon name change to \"%s\"\n", e->name);
+ else
+ printf("Icon name deleted\n");
+ return 1;
+}
+
+int
+handler_x_window_prop_visible_icon_name_change(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
+
+ e = event;
+ if (e->name)
+ printf("Visible icon name change to \"%s\"\n", e->name);
+ else
+ printf("Visible icon name deleted\n");
+ return 1;
+}
+
+int
+handler_x_window_prop_client_machine_change(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
+
+ e = event;
+ if (e->name)
+ printf("Client machine change to \"%s\"\n", e->name);
+ else
+ printf("Client machine deleted\n");
+ return 1;
+}
+
+int
+handler_x_window_prop_pid_change(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Prop_Pid_Change *e;
+
+ e = event;
+ if (e->pid)
+ {
+ printf("Pid change to \"%d\" ", e->pid);
+ if (e->pid == getpid())
+ printf("correct.\n");
+ else
+ printf("INCORRECT!\n");
+ }
+ else
+ printf("Pid deleted\n");
+ return 1;
+}
+
+int
+handler_x_window_prop_name_class_change(void *data, int type, void *event)
+{
+ Ecore_X_Event_Window_Prop_Name_Class_Change *e;
+
+ e = event;
+ if ((e->name) && (e->clas))
+ printf("Name & Class change to \"%s\".\"%s\"\n", e->name, e->clas);
+ else
+ printf("Name & Class deleted\n");
+ return 1;
+}
+
+void
+setup_ecore_x_test(void)
+{
+ char *tmp;
+ int pid;
+ unsigned int desktop;
+
+ win = ecore_x_window_new(0, 0, 0, 120, 60);
+ ecore_x_netwm_name_set(win, "Ecore Test Program");
+ ecore_x_icccm_title_set(win, "Ecore Test Program");
+ //printf("Title currently: %s\n", tmp);
+ free(tmp);
+#if 0
+ /* Visibile title should be set by the wm */
+ tmp = ecore_x_netwm_visible_name_get(win);
+ if (!tmp)
+ {
+ printf("No visible title, setting it to Ecore ... Program\n");
+ ecore_x_window_prop_visible_title_set(win, "Ecore ... Program");
+ tmp = ecore_x_window_prop_visible_title_get(win);
+ }
+ printf("Visible title: %s\n", tmp);
+ free(tmp);
+#endif
+ ecore_x_netwm_icon_name_get(win, &tmp);
+ if (!tmp)
+ {
+ printf("No icon name, setting it to Ecore_Test\n");
+ ecore_x_netwm_icon_name_set(win, "Ecore_Test");
+ ecore_x_netwm_icon_name_get(win, &tmp);
+ }
+ printf("Icon Name: %s\n", tmp);
+ free(tmp);
+#if 0
+ /* Visibile icon should be set by the wm */
+ tmp = ecore_x_window_prop_visible_icon_name_get(win);
+ if (!tmp)
+ {
+ printf("No visible icon name, setting it to Ecore\n");
+ ecore_x_window_prop_visible_icon_name_set(win, "Ecore");
+ tmp = ecore_x_window_prop_visible_icon_name_get(win);
+ }
+ printf("Visible icon Name: %s\n", tmp);
+ free(tmp);
+#endif
+ tmp = ecore_x_icccm_client_machine_get(win);
+ if (tmp)
+ {
+ printf("Client machine: %s\n", tmp);
+ free(tmp);
+ }
+ ecore_x_netwm_pid_get(win, &pid);
+ printf("Pid: %d\n", pid);
+ ecore_x_icccm_name_class_set(win, "ecore_test", "main");
+ ecore_x_netwm_desktop_set(win, 1);
+ ecore_x_netwm_desktop_get(win, &desktop);
+ printf("Window on desktop %u\n", desktop);
+ ecore_x_netwm_window_type_set(win, ECORE_X_WINDOW_TYPE_DIALOG);
+ ecore_x_icccm_protocol_set(win, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, 1);
+ ecore_x_window_show(win);
+ ecore_x_flush();
+
+ ecore_event_handler_add(ECORE_X_EVENT_KEY_DOWN, handler_x_key_down, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_KEY_UP, handler_x_key_up, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, handler_x_mouse_button_down, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, handler_x_mouse_button_up, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_MOUSE_MOVE, handler_x_mouse_move, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, handler_x_mouse_in, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, handler_x_mouse_out, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, handler_x_window_focus_in, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, handler_x_window_focus_out, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DAMAGE, handler_x_window_damage, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, handler_x_window_destroy, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, handler_x_window_configure, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, handler_x_window_delete_request, NULL);
+ /*
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE, handler_x_window_prop_title_change, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE, handler_x_window_prop_visible_title_change, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE, handler_x_window_prop_icon_name_change, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE, handler_x_window_prop_visible_icon_name_change, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE, handler_x_window_prop_name_class_change, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE, handler_x_window_prop_client_machine_change, NULL);
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, handler_x_window_prop_pid_change, NULL);
+ */
+
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS
+/* choose: TEST_X, TEST_FB */
+#define TEST_X
+
+/**** ECORE_EVAS TEST CODE */
+
+Ecore_Timer *anim_timer = NULL;
+Ecore_Evas *ee = NULL;
+Evas *evas = NULL;
+Evas_Object *objects[64];
+
+int
+obj_timer(void *data)
+{
+ Evas_Object *o;
+ Evas_Coord x, y;
+ Evas_Coord w, h;
+ Evas_Coord ow, oh;
+ double t;
+ int m, n;
+ int i;
+
+ t = ecore_time_get() - start_time;
+ for (i = 0; i < (sizeof(objects) / sizeof(Evas_Object *)); i++)
+ {
+ o = objects[i];
+ evas_output_viewport_get(evas_object_evas_get(o), NULL, NULL, &w, &h);
+ evas_object_geometry_get(o, NULL, NULL, &ow, &oh);
+ m = ((int)o / 36) & 0x3f;
+ n = ((int)o / 763) & 0x3f;
+ x = sin(t * (double)m / 12) * ((w - ow) / 2);
+ y = sin(t * (double)n / 12) * ((h - oh) / 2);
+ evas_object_move(o, (w / 2) - (ow / 2) + x, (h / 2) - (oh / 2) + y);
+ }
+ return 1;
+}
+
+void
+del_req(Ecore_Evas *ee)
+{
+ int i;
+
+ printf("request to go away... nice exit\n");
+ for (i = 0; i < (sizeof(objects) / sizeof(Evas_Object *)); i++)
+ objects[i] = NULL;
+ ecore_timer_del(anim_timer);
+ anim_timer = NULL;
+ ecore_main_loop_quit();
+}
+
+static void
+cb_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Key_Down *ev;
+
+ ev = event_info;
+ if (!strcmp(ev->keyname, "Escape")) ecore_main_loop_quit();
+ if (!strcmp(ev->keyname, "q")) ecore_main_loop_quit();
+ if (!strcmp(ev->keyname, "Q")) ecore_main_loop_quit();
+ if (!strcmp(ev->keyname, "f"))
+ {
+ if (!ecore_evas_fullscreen_get(ee))
+ ecore_evas_fullscreen_set(ee, 1);
+ else
+ ecore_evas_fullscreen_set(ee, 0);
+ }
+ if (!strcmp(ev->keyname, "o"))
+ {
+ if (!ecore_evas_override_get(ee))
+ ecore_evas_override_set(ee, 1);
+ else
+ ecore_evas_override_set(ee, 0);
+ }
+ if (!strcmp(ev->keyname, "r"))
+ {
+ int r;
+
+ r = ecore_evas_rotation_get(ee);
+ if (r == 0) r = 90;
+ else if (r == 90) r = 270;
+ else if (r == 270) r = 0;
+ ecore_evas_rotation_set(ee, r);
+ }
+ if (!strcmp(ev->keyname, "b"))
+ {
+ if (!ecore_evas_borderless_get(ee))
+ ecore_evas_borderless_set(ee, 1);
+ else
+ ecore_evas_borderless_set(ee, 0);
+ }
+ if (!strcmp(ev->keyname, "d"))
+ {
+ if (!ecore_evas_avoid_damage_get(ee))
+ ecore_evas_avoid_damage_set(ee, 1);
+ else
+ ecore_evas_avoid_damage_set(ee, 0);
+ }
+ if (!strcmp(ev->keyname, "s"))
+ {
+ if (!ecore_evas_shaped_get(ee))
+ ecore_evas_shaped_set(ee, 1);
+ else
+ ecore_evas_shaped_set(ee, 0);
+ }
+#if 1 /* no data files shipped yet to test this */
+ if (!strcmp(ev->keyname, "p"))
+ {
+ char *fl;
+
+ ecore_evas_cursor_get(ee, &fl, NULL, NULL, NULL);
+ if (!fl)
+ ecore_evas_cursor_set(ee, "data/pointers/mouse_pointer.png", 1000000, 2, 2);
+ else
+ ecore_evas_cursor_set(ee, NULL, 0, 0, 0);
+ }
+#endif
+}
+
+int
+setup_ecore_evas_test(void)
+{
+ Evas_Object *o;
+ int i;
+
+ /* create a new ecore wrapped evas canvas in X */
+#ifdef TEST_X
+ ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 240, 320);
+#endif
+#ifdef TEST_FB
+ ee = ecore_evas_fb_new(NULL, 270, 240, 320);
+#endif
+ if (!ee) return 0;
+ ecore_evas_title_set(ee, "Ecore Evas Test");
+ ecore_evas_name_class_set(ee, "ecore_test", "test_evas");
+ /* callback if clsoe button is pressed and win is asked to be deleted */
+ ecore_evas_callback_delete_request_set(ee, del_req);
+
+ /* get the actual evas ecore created for us */
+ evas = ecore_evas_get(ee);
+
+ /* image cache set (in bytes) */
+ evas_image_cache_set(evas, 0 * 1024);
+ /* font cache set (in bytes) */
+ evas_font_cache_set(evas, 0 * 1024);
+ /* add a directory to look in for fonts */
+ evas_font_path_append(evas, "./");
+
+ /* set up a big white rectangle on the bg */
+ o = evas_object_rectangle_add(evas);
+ evas_object_color_set(o, 255, 255, 255, 255);
+ evas_object_move(o, 0, 0);
+ evas_object_resize(o, 100000, 100000);
+ evas_object_layer_set(o, -1000000);
+ evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, cb_key_down, ee);
+ evas_object_focus_set(o, 1);
+ evas_object_show(o);
+
+ /* make a bunch of rectangles */
+ for (i = 0; i < (sizeof(objects) / sizeof(Evas_Object *)); i++)
+ {
+ o = evas_object_rectangle_add(evas);
+ evas_object_move(o, 10, 10);
+ evas_object_pass_events_set(o, 1);
+ evas_object_color_set(o,
+ ((int)o) & 0xff,
+ ((int)o / 30) & 0xff,
+ ((int)o / 65) & 0xff,
+ ((int)o / 156) & 0xff);
+ evas_object_resize(o, 4 + (((int)o) % 100), 4 + (((int)o / 50) % 100));
+ evas_object_show(o);
+ objects[i] = o;
+ }
+ /* add a timer to animate them */
+ anim_timer = ecore_timer_add(0.01, obj_timer, NULL);
+
+ ecore_evas_show(ee);
+ return 1;
+}
+#endif
+
+/**** MAIN */
+int
+main(int argc, const char **argv)
+{
+ /* get the time the program started at */
+ start_time = ecore_time_get();
+
+ /* init ecore */
+ ecore_init();
+ /* tell ecore what our arguments are */
+ ecore_app_args_set(argc, argv);
+
+#if 1
+ /* setup to test ecore module basics */
+ setup_ecore_test();
+#endif
+
+#ifdef BUILD_ECORE_CON
+#if 0
+ /* init ecore_con */
+ ecore_con_init();
+ {
+ Ecore_Con_Server *server;
+
+/* server = ecore_con_server_add(ECORE_CON_LOCAL_USER, "ecore_test", 0, NULL);*/
+ server = ecore_con_server_add(ECORE_CON_LOCAL_SYSTEM, "ecore_test", 0, NULL);
+/* server = ecore_con_server_add(ECORE_CON_REMOTE_SYSTEM, "localhost", 7654, NULL); */
+ ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, handler_client_add, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, handler_client_del, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, handler_client_data, NULL);
+ printf("create server %p\n", server);
+ }
+ {
+ Ecore_Con_Server *server;
+
+/* server = ecore_con_server_connect(ECORE_CON_LOCAL_USER, "ecore_test", 0, NULL);*/
+ server = ecore_con_server_connect(ECORE_CON_LOCAL_SYSTEM, "ecore_test", 0, NULL);
+/* server = ecore_con_server_connect(ECORE_CON_REMOTE_SYSTEM, "localhost", 7654, NULL); */
+/* server = ecore_con_server_connect(ECORE_CON_REMOTE_SYSTEM, "www.rasterman.com", 80, NULL); */
+ ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, handler_server_add, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, handler_server_del, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, handler_server_data, NULL);
+ printf("connect to server: %p\n", server);
+ if (server)
+ {
+ char data[160 * 1024];
+
+ strcpy(data, "BLAHPANTS!");
+ ecore_con_server_send(server, data, 160 * 1024);
+ }
+ }
+#endif
+#endif
+
+#ifdef BUILD_ECORE_IPC
+#if 1
+ /* init ecore_ipc */
+ ecore_ipc_init();
+ {
+ Ecore_Ipc_Server *server;
+
+ server = ecore_ipc_server_add(ECORE_IPC_LOCAL_SYSTEM, "ecore_ipc_test", 0, NULL);
+/* server = ecore_ipc_server_add(ECORE_IPC_REMOTE_SYSTEM, "localhost", 4567, NULL); */
+ ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, handler_ipc_client_add, NULL);
+ ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, handler_ipc_client_del, NULL);
+ ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, handler_ipc_client_data, NULL);
+ printf("create ipc server %p\n", server);
+ }
+ {
+ Ecore_Ipc_Server *server;
+
+ server = ecore_ipc_server_connect(ECORE_IPC_LOCAL_SYSTEM, "ecore_ipc_test", 0, NULL);
+/* server = ecore_ipc_server_connect(ECORE_IPC_REMOTE_SYSTEM, "localhost", 4567, NULL); */
+ ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, handler_ipc_server_add, NULL);
+ ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, handler_ipc_server_del, NULL);
+ ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, handler_ipc_server_data, NULL);
+ printf("connect to ipc server: %p\n", server);
+ if (server)
+ {
+ char data[160 * 1024];
+
+ strcpy(data, "BLAHPANTS!");
+ ecore_ipc_server_send(server, 5, 6, 0, 0, 0, data, 160 * 1024);
+ }
+ }
+#endif
+#endif
+
+#ifdef BUILD_ECORE_EVAS
+ /* init ecore_evas */
+/* if (!ecore_evas_init()) return -1; */
+#endif
+
+ /* setup a callback to handle a systsme signal to quit */
+ ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, handler_signal_exit, NULL);
+
+#ifdef BUILD_ECORE_X
+ /* setup to test ecore_x module things */
+ if (!ecore_x_init(NULL)) return -1;
+ setup_ecore_x_test();
+#endif
+
+#ifdef BUILD_ECORE_EVAS
+ /* setup to test ecore_evas module */
+/* if (!setup_ecore_evas_test()) return -1; */
+#endif
+
+ /* run the main loop */
+ ecore_main_loop_begin();
+
+#ifdef BUILD_ECORE_EVAS
+ /* shut down ecore_evas */
+ ecore_evas_shutdown();
+#endif
+#ifdef BUILD_ECORE_IPC
+ /* shut down ecore_ipc */
+ ecore_ipc_shutdown();
+#endif
+#ifdef BUILD_ECORE_CON
+ /* shut down ecore_con */
+ ecore_con_shutdown();
+#endif
+ /* shut down ecore */
+ ecore_shutdown();
+ return 0;
+}
diff --git a/ecore/src/e_ev_filter.c b/ecore/src/e_ev_filter.c
new file mode 100644
index 0000000..58c7e0f
--- /dev/null
+++ b/ecore/src/e_ev_filter.c
@@ -0,0 +1,132 @@
+#include "Ecore.h"
+
+typedef struct _ecore_event_handler Ecore_Event_Handler;
+typedef struct _ecore_event_idle_handler Ecore_Event_Idle_Handler;
+
+struct _ecore_event_handler
+{
+ void (*func) (Ecore_Event * ev);
+ Ecore_Event_Handler *next;
+};
+
+struct _ecore_event_idle_handler
+{
+ void (*func) (void *data);
+ void *data;
+ Ecore_Event_Idle_Handler *next;
+};
+
+static Ecore_Event_Handler *handler[ECORE_EVENT_MAX];
+static Ecore_Event_Idle_Handler *idle_handlers = NULL;
+
+void
+ecore_event_filter(Ecore_Event * ev)
+{
+ Ecore_Event *evp;
+ int motion_events = 0;
+ int dnd_pos_events = 0;
+ int dnd_status_events = 0;
+
+ /* count events to only use last events of some types */
+ for (evp = ev; evp; evp = evp->next)
+ {
+ if (evp->type == ECORE_EVENT_MOUSE_MOVE)
+ motion_events++;
+ if (evp->type == ECORE_EVENT_DND_DROP_POSITION)
+ dnd_pos_events++;
+ if (evp->type == ECORE_EVENT_DND_DROP_STATUS)
+ dnd_status_events++;
+ }
+ for (evp = ev; evp; evp = evp->next)
+ {
+ if (evp->type == ECORE_EVENT_MOUSE_MOVE)
+ {
+ if (motion_events > 1)
+ {
+ evp->ignore = 1;
+ motion_events--;
+ }
+ }
+ else if (evp->type == ECORE_EVENT_DND_DROP_POSITION)
+ {
+ if (dnd_pos_events > 1)
+ {
+ evp->ignore = 1;
+ dnd_pos_events--;
+ }
+ }
+ else if (evp->type == ECORE_EVENT_DND_DROP_STATUS)
+ {
+ if (dnd_status_events > 1)
+ {
+ evp->ignore = 1;
+ dnd_status_events--;
+ }
+ }
+ }
+}
+
+void
+ecore_event_filter_events_handle(Ecore_Event * ev)
+{
+ Ecore_Event *evp;
+
+ for (evp = ev; evp; evp = evp->next)
+ {
+ Ecore_Event_Handler *h;
+
+ if (!evp->ignore)
+ {
+ for (h = handler[evp->type]; h; h = h->next)
+ {
+ if (h->func)
+ h->func(evp);
+ }
+ }
+ }
+}
+
+void
+ecore_event_filter_idle_handle(void)
+{
+ Ecore_Event_Idle_Handler *h;
+
+ for (h = idle_handlers; h; h = h->next)
+ h->func(h->data);
+}
+
+extern int __quit_ev_loop;
+
+void
+ecore_event_filter_init(void)
+{
+ int i;
+
+ __quit_ev_loop = 0;
+ for (i = 0; i < ECORE_EVENT_MAX; i++)
+ handler[i] = NULL;
+}
+
+void
+ecore_event_filter_handler_add(Ecore_Event_Type type,
+ void (*func) (Ecore_Event * ev))
+{
+ Ecore_Event_Handler *h;
+
+ h = NEW(Ecore_Event_Handler, 1);
+ h->func = func;
+ h->next = handler[type];
+ handler[type] = h;
+}
+
+void
+ecore_event_filter_idle_handler_add(void (*func) (void *data), void *data)
+{
+ Ecore_Event_Idle_Handler *h;
+
+ h = NEW(Ecore_Event_Idle_Handler, 1);
+ h->func = func;
+ h->data = data;
+ h->next = idle_handlers;
+ idle_handlers = h;
+}
diff --git a/ecore/src/e_ev_signal.c b/ecore/src/e_ev_signal.c
new file mode 100644
index 0000000..b0e34cb
--- /dev/null
+++ b/ecore/src/e_ev_signal.c
@@ -0,0 +1,320 @@
+#include "Ecore.h"
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <errno.h>
+
+static void ecore_event_signal_free(void *event);
+static void ecore_event_signal_handle_sigchld(int num);
+static void ecore_event_signal_handle_sigusr1(int num);
+static void ecore_event_signal_handle_sigusr2(int num);
+static void ecore_event_signal_handle_sighup(int num);
+static void ecore_event_signal_handle_sigpipe(int num);
+static void ecore_event_signal_handle_sigsegv(int num);
+static void ecore_event_signal_handle_sigfpe(int num);
+static void ecore_event_signal_handle_sigill(int num);
+static void ecore_event_signal_handle_sigbus(int num);
+
+#ifdef HAVE_SIGSTKFLT
+static void ecore_event_signal_handle_sigstkflt(int num);
+#endif
+#ifdef HAVE_SIGPWR
+static void ecore_event_signal_handle_sigpwr(int num);
+#endif
+static void ecore_event_signal_handle_sigchld(int num);
+static void ecore_event_signal_handle_all(pid_t pid);
+
+static int signal_chld_count = 0;
+static int signal_usr1_count = 0;
+static int signal_usr2_count = 0;
+static int signal_hup_count = 0;
+
+/* freeing stuff */
+static void
+ecore_event_signal_free(void *event)
+{
+ FREE(event);
+}
+
+/* signal handlers we can return from and add to signal recieved counts */
+static void
+ecore_event_signal_handle_sigchld(int num)
+{
+ signal_chld_count++;
+ return;
+ num = 0;
+}
+
+static void
+ecore_event_signal_handle_sigusr1(int num)
+{
+ signal_usr1_count++;
+ return;
+ num = 0;
+}
+
+static void
+ecore_event_signal_handle_sigusr2(int num)
+{
+ signal_usr2_count++;
+ return;
+ num = 0;
+}
+
+static void
+ecore_event_signal_handle_sighup(int num)
+{
+ signal_hup_count++;
+ return;
+ num = 0;
+}
+
+/* signals to ignore */
+static void
+ecore_event_signal_handle_sigpipe(int num)
+{
+ return;
+ num = 0;
+}
+
+/* signal handlers we cant return from - so handle here */
+static void
+ecore_event_signal_handle_sigsegv(int num)
+{
+ for (;;)
+ {
+ fprintf(stderr, "EEEEEEEEK SEGV - waiting 10 seconds\n");
+ sleep(10);
+ }
+ /* EEK - can't return - bad */
+ abort();
+ num = 0;
+}
+
+static void
+ecore_event_signal_handle_sigfpe(int num)
+{
+ /* EEK - can't return - bad */
+ abort();
+ num = 0;
+}
+
+static void
+ecore_event_signal_handle_sigill(int num)
+{
+ /* EEK - can't return - bad */
+ abort();
+ num = 0;
+}
+
+static void
+ecore_event_signal_handle_sigbus(int num)
+{
+ /* EEK - can't return - bad */
+ abort();
+ num = 0;
+}
+
+#ifdef HAVE_SIGSTKFLT
+static void
+ecore_event_signal_handle_sigstkflt(int num)
+{
+ /* EEK - can't return - bad */
+ abort();
+ return;
+ num = 0;
+}
+#endif
+
+static void
+ecore_event_signal_handle_sigint(int num)
+{
+ exit(0);
+ return;
+ num = 0;
+}
+
+static void
+ecore_event_signal_handle_sigquit(int num)
+{
+ exit(0);
+ return;
+ num = 0;
+}
+
+static void
+ecore_event_signal_handle_sigabrt(int num)
+{
+ abort();
+ return;
+ num = 0;
+}
+
+static void
+ecore_event_signal_handle_sigalrm(int num)
+{
+ return;
+ num = 0;
+}
+
+static void
+ecore_event_signal_handle_sigterm(int num)
+{
+ exit(0);
+ return;
+ num = 0;
+}
+
+#ifdef HAVE_SIGPWR
+static void
+ecore_event_signal_handle_sigpwr(int num)
+{
+ exit(0);
+ return;
+ num = 0;
+}
+#endif
+
+static void
+ecore_event_signal_handle_all(pid_t pid_pass)
+{
+ int status;
+ pid_t pid;
+
+ if (signal_chld_count > 0)
+ {
+ while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
+ {
+ if (WIFEXITED(status))
+ {
+ Ecore_Event_Child *e;
+ int code;
+
+ code = WEXITSTATUS(status);
+ e = NEW(Ecore_Event_Child, 1);
+ e->pid = pid;
+ e->exit_code = code;
+ ecore_add_event(ECORE_EVENT_CHILD, e, ecore_event_signal_free);
+ }
+ }
+ signal_chld_count = 0;
+ }
+ while (signal_usr1_count > 0)
+ {
+ Ecore_Event_User *e;
+
+ e = NEW(Ecore_Event_User, 1);
+ e->num = 0;
+ e->hup = 0;
+ ecore_add_event(ECORE_EVENT_USER, e, ecore_event_signal_free);
+ signal_usr1_count--;
+ }
+ while (signal_hup_count > 0)
+ {
+ Ecore_Event_User *e;
+
+ e = NEW(Ecore_Event_User, 1);
+ e->num = 0;
+ e->hup = 1;
+ ecore_add_event(ECORE_EVENT_USER, e, ecore_event_signal_free);
+ signal_hup_count--;
+ }
+ return;
+ pid_pass = 0;
+}
+
+int
+ecore_event_signal_events_pending(void)
+{
+ return (signal_chld_count + signal_usr1_count + signal_hup_count);
+}
+
+void
+ecore_event_signal_init(void)
+{
+ struct sigaction sa;
+
+ ecore_add_event_pid(0, ecore_event_signal_handle_all);
+
+ sa.sa_handler = ecore_event_signal_handle_sigchld;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGCHLD, &sa, (struct sigaction *)0);
+
+ sa.sa_handler = ecore_event_signal_handle_sigusr1;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGUSR1, &sa, (struct sigaction *)0);
+
+ sa.sa_handler = ecore_event_signal_handle_sigusr2;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGUSR2, &sa, (struct sigaction *)0);
+
+ sa.sa_handler = ecore_event_signal_handle_sighup;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGHUP, &sa, (struct sigaction *)0);
+
+ sa.sa_handler = ecore_event_signal_handle_sigpipe;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGPIPE, &sa, (struct sigaction *)0);
+/*
+ sa.sa_handler = ecore_event_signal_handle_sigsegv;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGSEGV, &sa, (struct sigaction *)0);
+*/
+ sa.sa_handler = ecore_event_signal_handle_sigfpe;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGFPE, &sa, (struct sigaction *)0);
+
+ sa.sa_handler = ecore_event_signal_handle_sigill;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGILL, &sa, (struct sigaction *)0);
+
+ sa.sa_handler = ecore_event_signal_handle_sigbus;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGBUS, &sa, (struct sigaction *)0);
+#ifdef HAVE_SIGSTKFLT
+ sa.sa_handler = ecore_event_signal_handle_sigstkflt;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGSTKFLT, &sa, (struct sigaction *)0);
+#endif
+ sa.sa_handler = ecore_event_signal_handle_sigint;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGINT, &sa, (struct sigaction *)0);
+
+ sa.sa_handler = ecore_event_signal_handle_sigquit;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGQUIT, &sa, (struct sigaction *)0);
+
+ sa.sa_handler = ecore_event_signal_handle_sigabrt;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGABRT, &sa, (struct sigaction *)0);
+
+ sa.sa_handler = ecore_event_signal_handle_sigalrm;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGALRM, &sa, (struct sigaction *)0);
+
+ sa.sa_handler = ecore_event_signal_handle_sigterm;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGTERM, &sa, (struct sigaction *)0);
+#ifdef HAVE_SIGPWR
+ sa.sa_handler = ecore_event_signal_handle_sigpwr;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGPWR, &sa, (struct sigaction *)0);
+#endif
+}
diff --git a/ecore/src/e_ev_x.c b/ecore/src/e_ev_x.c
new file mode 100644
index 0000000..a3ea7bd
--- /dev/null
+++ b/ecore/src/e_ev_x.c
@@ -0,0 +1,1234 @@
+#include "Ecore.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* private funtion prototypes */
+static void ecore_event_x_handle_events(int fd);
+static void ecore_event_x_translate_events(XEvent * events,
+ int num_events);
+
+static void ecore_event_key_down_free(void *event);
+static void ecore_event_key_up_free(void *event);
+static void ecore_event_generic_free(void *event);
+static void ecore_event_dnd_drop_request_free(void *event);
+static void ecore_event_paste_request_free(void *event);
+
+static void ecore_event_x_handle_keypress(XEvent * xevent);
+static void ecore_event_x_handle_keyrelease(XEvent * xevent);
+static void ecore_event_x_handle_button_press(XEvent * xevent);
+static void ecore_event_x_handle_button_release(XEvent * xevent);
+static void ecore_event_x_handle_motion_notify(XEvent * xevent);
+static void ecore_event_x_handle_enter_notify(XEvent * xevent);
+static void ecore_event_x_handle_leave_notify(XEvent * xevent);
+static void ecore_event_x_handle_focus_in(XEvent * xevent);
+static void ecore_event_x_handle_focus_out(XEvent * xevent);
+static void ecore_event_x_handle_expose(XEvent * xevent);
+static void ecore_event_x_handle_visibility_notify(XEvent * xevent);
+static void ecore_event_x_handle_create_notify(XEvent * xevent);
+static void ecore_event_x_handle_destroy_notify(XEvent * xevent);
+static void ecore_event_x_handle_unmap_notify(XEvent * xevent);
+static void ecore_event_x_handle_map_notify(XEvent * xevent);
+static void ecore_event_x_handle_map_request(XEvent * xevent);
+static void ecore_event_x_handle_reparent_notify(XEvent * xevent);
+static void ecore_event_x_handle_configure_notify(XEvent * xevent);
+static void ecore_event_x_handle_configure_request(XEvent * xevent);
+static void ecore_event_x_handle_circulate_notify(XEvent * xevent);
+static void ecore_event_x_handle_circulate_request(XEvent * xevent);
+static void ecore_event_x_handle_property_notify(XEvent * xevent);
+static void ecore_event_x_handle_colormap_notify(XEvent * xevent);
+static void ecore_event_x_handle_selection_notify(XEvent * xevent);
+static void ecore_event_x_handle_selection_clear(XEvent * xevent);
+static void ecore_event_x_handle_selection_request(XEvent * xevent);
+static void ecore_event_x_handle_client_message(XEvent * xevent);
+static void ecore_event_x_handle_shape_change(XEvent * xevent);
+
+static int max_event_id = 0;
+static void (**event_translator) (XEvent * event) = NULL;
+
+static int lock_mask_scroll = 0, lock_mask_num = 0, lock_mask_caps = 0;
+static int mod_mask_shift = 0, mod_mask_ctrl = 0, mod_mask_alt =
+ 0, mod_mask_win = 0;
+
+/* convenience macros */
+#define GETSET_MODS(state, mods) \
+(mods) = ECORE_EVENT_KEY_MODIFIER_NONE;\
+if ((state) & mod_mask_shift) { ecore_mod_shift_set(1); (mods) |= ECORE_EVENT_KEY_MODIFIER_SHIFT; }\
+else ecore_mod_shift_set(0);\
+if ((state) & mod_mask_ctrl) { ecore_mod_ctrl_set(1); (mods) |= ECORE_EVENT_KEY_MODIFIER_CTRL; }\
+else ecore_mod_ctrl_set(0);\
+if ((state) & mod_mask_alt) { ecore_mod_alt_set(1); (mods) |= ECORE_EVENT_KEY_MODIFIER_ALT; }\
+else ecore_mod_alt_set(0);\
+if ((state) & mod_mask_win) { ecore_mod_win_set(1); (mods) |= ECORE_EVENT_KEY_MODIFIER_WIN; }\
+else ecore_mod_win_set(0);
+
+/* public functions */
+
+/* initialise event handling for the fd X is on */
+void
+ecore_event_x_init(void)
+{
+ int i, shape_event_id, current_lock;
+
+ shape_event_id = max_event_id = ecore_event_shape_get_id();
+ if (shape_event_id < LASTEvent)
+ {
+ max_event_id = LASTEvent;
+ fprintf(stderr, "ERROR: No shape extension! This is BAD!\n");
+ }
+ event_translator = NEW_PTR(max_event_id + 1);
+ for (i = 0; i < max_event_id + 1; i++)
+ event_translator[i] = NULL;
+ event_translator[KeyPress] = ecore_event_x_handle_keypress;
+ event_translator[KeyRelease] = ecore_event_x_handle_keyrelease;
+ event_translator[ButtonPress] = ecore_event_x_handle_button_press;
+ event_translator[ButtonRelease] = ecore_event_x_handle_button_release;
+ event_translator[MotionNotify] = ecore_event_x_handle_motion_notify;
+ event_translator[EnterNotify] = ecore_event_x_handle_enter_notify;
+ event_translator[LeaveNotify] = ecore_event_x_handle_leave_notify;
+ event_translator[FocusIn] = ecore_event_x_handle_focus_in;
+ event_translator[FocusOut] = ecore_event_x_handle_focus_out;
+ event_translator[Expose] = ecore_event_x_handle_expose;
+ event_translator[VisibilityNotify] = ecore_event_x_handle_visibility_notify;
+ event_translator[CreateNotify] = ecore_event_x_handle_create_notify;
+ event_translator[DestroyNotify] = ecore_event_x_handle_destroy_notify;
+ event_translator[UnmapNotify] = ecore_event_x_handle_unmap_notify;
+ event_translator[MapNotify] = ecore_event_x_handle_map_notify;
+ event_translator[MapRequest] = ecore_event_x_handle_map_request;
+ event_translator[ReparentNotify] = ecore_event_x_handle_reparent_notify;
+ event_translator[ConfigureNotify] = ecore_event_x_handle_configure_notify;
+ event_translator[ConfigureRequest] = ecore_event_x_handle_configure_request;
+ event_translator[CirculateNotify] = ecore_event_x_handle_circulate_notify;
+ event_translator[CirculateRequest] = ecore_event_x_handle_circulate_request;
+ event_translator[PropertyNotify] = ecore_event_x_handle_property_notify;
+ event_translator[ColormapNotify] = ecore_event_x_handle_colormap_notify;
+ event_translator[ClientMessage] = ecore_event_x_handle_client_message;
+ event_translator[SelectionNotify] = ecore_event_x_handle_selection_notify;
+ event_translator[SelectionClear] = ecore_event_x_handle_selection_clear;
+ event_translator[SelectionRequest] = ecore_event_x_handle_selection_request;
+ if (shape_event_id > SelectionRequest)
+ event_translator[shape_event_id] = ecore_event_x_handle_shape_change;
+
+ lock_mask_scroll = ecore_lock_mask_scroll_get();
+ lock_mask_num = ecore_lock_mask_num_get();
+ lock_mask_caps = ecore_lock_mask_caps_get();
+
+ mod_mask_shift = ecore_mod_mask_shift_get();
+ mod_mask_ctrl = ecore_mod_mask_ctrl_get();
+ mod_mask_alt = ecore_mod_mask_alt_get();
+ mod_mask_win = ecore_mod_mask_win_get();
+
+/* HRRRMMM lets not do this
+ ecorecore_keygrab("Num_Lock", ECORE_EVENT_KEY_MODIFIER_NONE, 1, 1);
+ ecorecore_keygrab("Scroll_Lock", ECORE_EVENT_KEY_MODIFIER_NONE, 1, 1);
+ ecorecore_keygrab("Caps_Lock", ECORE_EVENT_KEY_MODIFIER_NONE, 1, 1);
+ */
+ current_lock = ecore_modifier_mask_get();
+ if (current_lock & lock_mask_scroll)
+ ecore_lock_scroll_set(1);
+ if (current_lock & lock_mask_num)
+ ecore_lock_num_set(1);
+ if (current_lock & lock_mask_caps)
+ ecore_lock_caps_set(1);
+ if (current_lock & mod_mask_shift)
+ ecore_mod_shift_set(1);
+ if (current_lock & mod_mask_ctrl)
+ ecore_mod_ctrl_set(1);
+ if (current_lock & mod_mask_alt)
+ ecore_mod_alt_set(1);
+ if (current_lock & mod_mask_win)
+ ecore_mod_win_set(1);
+ ecore_add_event_fd(ecore_x_get_fd(), ecore_event_x_handle_events);
+}
+
+/* private functions */
+/* get all events onthe event queue and translate them */
+static void
+ecore_event_x_handle_events(int fd)
+{
+ int num_events = 0, size_events = 0;
+ XEvent *events = NULL;
+
+ /* while there are events in the queue */
+ while (ecore_events_pending())
+ {
+ /* incriment our event count */
+ num_events++;
+ /* if the numebr fo events is > than our buffer size then */
+ if (num_events > size_events)
+ {
+ /* increase the buffer size by 64 events */
+ size_events += 64;
+ if (events)
+ {
+ REALLOC(events, XEvent, size_events)}
+ else
+ events = NEW(XEvent, size_events);
+ }
+ /* get the next event into the event buffer */
+ ecore_get_next_event(&(events[num_events - 1]));
+ }
+ /* call the XEvent -> Eevent translator */
+ if (events)
+ {
+ ecore_event_x_translate_events(events, num_events);
+ /* if theres an event buffer - free it */
+ FREE(events);
+ }
+ return;
+ fd = 0;
+}
+
+/* take an array of events and translate them into E events */
+static void
+ecore_event_x_translate_events(XEvent * events, int num_events)
+{
+ int i;
+
+ for (i = 0; i < num_events; i++)
+ {
+ if ((events[i].type <= max_event_id) &&
+ (event_translator[events[i].type]))
+ (*(event_translator[events[i].type])) (&(events[i]));
+ }
+}
+
+static void
+ecore_event_key_down_free(void *event)
+{
+ Ecore_Event_Key_Down *e;
+
+ e = (Ecore_Event_Key_Down *) event;
+ IF_FREE(e->key);
+ IF_FREE(e->compose);
+ FREE(e);
+}
+
+static void
+ecore_event_key_up_free(void *event)
+{
+ Ecore_Event_Key_Up *e;
+
+ e = (Ecore_Event_Key_Up *) event;
+ IF_FREE(e->key);
+ IF_FREE(e->compose);
+ FREE(e);
+}
+
+static void
+ecore_event_generic_free(void *event)
+{
+ FREE(event);
+}
+
+static void
+ecore_event_dnd_drop_request_free(void *event)
+{
+ Ecore_Event_Dnd_Drop_Request *e;
+
+ e = (Ecore_Event_Dnd_Drop_Request *) event;
+ if (e->files)
+ {
+ int i;
+
+ for (i = 0; i < e->num_files; i++)
+ FREE(e->files[i]);
+ }
+ FREE(event);
+}
+
+static void
+ecore_event_paste_request_free(void *event)
+{
+ Ecore_Event_Paste_Request *e;
+
+ e = (Ecore_Event_Paste_Request *) event;
+ IF_FREE(e->string);
+ FREE(event);
+}
+
+static void
+ecore_event_x_handle_keypress(XEvent * xevent)
+{
+ Ecore_Event_Key_Down *e;
+ static KeyCode previous_code = 0;
+ static Time previous_time = 0;
+
+ /* avoid doubling events up from passive grabs */
+ if ((xevent->xkey.keycode == previous_code) &&
+ xevent->xkey.time == previous_time)
+ return;
+ previous_code = xevent->xkey.keycode;
+ previous_time = xevent->xkey.time;
+/*
+ if (ecore_keyget_keysym_from_keycode(xevent->xkey.keycode) == XK_Scroll_Lock)
+ {
+ if (ecore_lock_scroll_get())
+ ecore_lock_scroll_set(0);
+ else
+ ecore_lock_scroll_set(1);
+ e_event_allow(ReplayKeyboard, xevent->xkey.time);
+ ecore_flush();
+ }
+ else if (ecore_keyget_keysym_from_keycode(xevent->xkey.keycode) == XK_Num_Lock)
+ {
+ if (ecore_lock_num_get())
+ ecore_lock_num_set(0);
+ else
+ ecore_lock_num_set(1);
+ e_event_allow(ReplayKeyboard, xevent->xkey.time);
+ ecore_flush();
+ }
+ else if (ecore_keyget_keysym_from_keycode(xevent->xkey.keycode) == XK_Caps_Lock)
+ {
+ if (ecore_lock_caps_get())
+ ecore_lock_caps_set(0);
+ else
+ ecore_lock_caps_set(1);
+ e_event_allow(ReplayKeyboard, xevent->xkey.time);
+ ecore_flush();
+ }
+ */
+ e = NEW(Ecore_Event_Key_Down, 1);
+ e->win = xevent->xkey.window;
+ e->root = xevent->xkey.root;
+ GETSET_MODS(xevent->xkey.state, e->mods);
+ e->time = xevent->xkey.time;
+ e->key = ecore_key_get_string_from_keycode(xevent->xkey.keycode);
+ {
+ int val;
+ char buf[256];
+ KeySym sym;
+ XComposeStatus stat;
+
+ val = XLookupString((XKeyEvent *) xevent, buf, sizeof(buf), &sym, &stat);
+ if (val > 0)
+ {
+ buf[val] = 0;
+ e->compose = strdup(buf);
+ }
+ else
+ e->compose = NULL;
+ }
+ ecore_add_event(ECORE_EVENT_KEY_DOWN, e, ecore_event_key_down_free);
+}
+
+static void
+ecore_event_x_handle_keyrelease(XEvent * xevent)
+{
+ Ecore_Event_Key_Up *e;
+ static KeyCode previous_code = 0;
+ static Time previous_time = 0;
+
+ /* avoid doubling events up from passive grabs */
+ if ((xevent->xkey.keycode == previous_code) &&
+ xevent->xkey.time == previous_time)
+ return;
+ previous_code = xevent->xkey.keycode;
+ previous_time = xevent->xkey.time;
+
+ e = NEW(Ecore_Event_Key_Up, 1);
+ e->win = xevent->xkey.window;
+ e->root = xevent->xkey.root;
+ GETSET_MODS(xevent->xkey.state, e->mods);
+ e->time = xevent->xkey.time;
+ e->key = ecore_key_get_string_from_keycode(xevent->xkey.keycode);
+ {
+ int val;
+ char buf[256];
+ KeySym sym;
+ XComposeStatus stat;
+
+ val = XLookupString((XKeyEvent *) xevent, buf, sizeof(buf), &sym, &stat);
+ if (val > 0)
+ {
+ buf[val] = 0;
+ e->compose = strdup(buf);
+ }
+ else
+ e->compose = NULL;
+ }
+ ecore_add_event(ECORE_EVENT_KEY_UP, e, ecore_event_key_up_free);
+}
+
+static void
+ecore_event_x_handle_button_press(XEvent * xevent)
+{
+ static Time last_time = 0, last_last_time = 0;
+ static int last_button = 0, last_last_button = 0;
+ static Window last_window = 0, last_last_window = 0;
+
+ ecore_pointer_xy_set(xevent->xbutton.x_root, xevent->xbutton.y_root);
+ if ((xevent->xbutton.button == 4) || (xevent->xbutton.button == 5))
+ {
+ Ecore_Event_Wheel *e;
+
+ e = NEW(Ecore_Event_Wheel, 1);
+ e->win = xevent->xbutton.window;
+ e->root = xevent->xbutton.root;
+ e->x = xevent->xbutton.x;
+ e->y = xevent->xbutton.y;
+ e->rx = xevent->xbutton.x_root;
+ e->ry = xevent->xbutton.y_root;
+ e->time = xevent->xbutton.time;
+ if (xevent->xbutton.button == 5)
+ e->z = 1;
+ else
+ e->z = -1;
+ if (xevent->xbutton.time - last_time < 15)
+ e->z *= 16;
+ else if (xevent->xbutton.time - last_time < 30)
+ e->z *= 4;
+ GETSET_MODS(xevent->xbutton.state, e->mods);
+ ecore_add_event(ECORE_EVENT_MOUSE_WHEEL, e, ecore_event_generic_free);
+ }
+ else
+ {
+ Ecore_Event_Mouse_Down *e;
+
+ e = NEW(Ecore_Event_Mouse_Down, 1);
+ e->win = xevent->xbutton.window;
+ e->root = xevent->xbutton.root;
+ e->button = xevent->xbutton.button;
+ e->x = xevent->xbutton.x;
+ e->y = xevent->xbutton.y;
+ e->rx = xevent->xbutton.x_root;
+ e->ry = xevent->xbutton.y_root;
+ e->time = xevent->xbutton.time;
+ e->double_click = 0;
+ e->triple_click = 0;
+ GETSET_MODS(xevent->xbutton.state, e->mods);
+ if (xevent->xbutton.time - last_last_time < 500)
+ {
+ if ((xevent->xbutton.window == (unsigned int)last_window) &&
+ (last_window == last_last_window) &&
+ (xevent->xbutton.button == (unsigned int)last_button) &&
+ (last_button == last_button))
+ e->triple_click = 1;
+ }
+ else if (xevent->xbutton.time - last_time < 250)
+ {
+ if ((xevent->xbutton.window == (unsigned int)last_window) &&
+ (xevent->xbutton.button == (unsigned int)last_button))
+ e->double_click = 1;
+ }
+ ecore_add_event(ECORE_EVENT_MOUSE_DOWN, e, ecore_event_generic_free);
+ {
+ Ecore_XID *xid = NULL;
+
+ if (XFindContext(xevent->xbutton.display, e->win,
+ xid_context, (XPointer *) & xid) != XCNOENT)
+ {
+ if ((xid->grab_button_auto_replay) &&
+ (xid->grab_button_auto_replay(e)))
+ {
+ ecore_pointer_replay(e->time);
+ }
+ }
+ }
+ }
+ last_last_window = last_window;
+ last_window = xevent->xbutton.window;
+ last_last_button = last_button;
+ last_button = xevent->xbutton.button;
+ last_last_time = last_time;
+ last_time = xevent->xbutton.time;
+}
+
+static void
+ecore_event_x_handle_button_release(XEvent * xevent)
+{
+ Ecore_Event_Mouse_Up *e;
+
+ if (xevent->xbutton.button > 3)
+ return;
+
+ e = NEW(Ecore_Event_Mouse_Up, 1);
+ e->win = xevent->xbutton.window;
+ e->root = xevent->xbutton.root;
+ e->button = xevent->xbutton.button;
+ e->x = xevent->xbutton.x;
+ e->y = xevent->xbutton.y;
+ e->rx = xevent->xbutton.x_root;
+ e->ry = xevent->xbutton.y_root;
+ e->time = xevent->xbutton.time;
+ GETSET_MODS(xevent->xbutton.state, e->mods);
+ ecore_add_event(ECORE_EVENT_MOUSE_UP, e, ecore_event_generic_free);
+}
+
+static void
+ecore_event_x_handle_motion_notify(XEvent * xevent)
+{
+ Ecore_Event_Mouse_Move *e;
+
+ ecore_pointer_xy_set(xevent->xmotion.x_root, xevent->xmotion.y_root);
+ e = NEW(Ecore_Event_Mouse_Move, 1);
+ e->win = xevent->xmotion.window;
+ e->root = xevent->xmotion.root;
+ e->x = xevent->xmotion.x;
+ e->y = xevent->xmotion.y;
+ e->rx = xevent->xmotion.x_root;
+ e->ry = xevent->xmotion.y_root;
+ e->time = xevent->xmotion.time;
+ GETSET_MODS(xevent->xmotion.state, e->mods);
+ ecore_add_event(ECORE_EVENT_MOUSE_MOVE, e, ecore_event_generic_free);
+}
+
+static void
+ecore_event_x_handle_enter_notify(XEvent * xevent)
+{
+ Ecore_Event_Window_Enter *e;
+
+/* if ((xevent->xcrossing.mode == NotifyGrab) || (xevent->xcrossing.mode == NotifyUngrab)) return;*/
+ ecore_pointer_xy_set(xevent->xcrossing.x_root, xevent->xcrossing.y_root);
+ e = NEW(Ecore_Event_Window_Enter, 1);
+ e->win = xevent->xcrossing.window;
+ e->root = xevent->xcrossing.root;
+ e->x = xevent->xcrossing.x;
+ e->y = xevent->xcrossing.y;
+ e->rx = xevent->xcrossing.x_root;
+ e->ry = xevent->xcrossing.y_root;
+ e->time = xevent->xcrossing.time;
+ GETSET_MODS(xevent->xcrossing.state, e->mods);
+ ecore_add_event(ECORE_EVENT_MOUSE_IN, e, ecore_event_generic_free);
+ ecore_window_mouse_set_in(e->win, 1);
+ {
+ Ecore_Event_Mouse_Move *e;
+
+ e = NEW(Ecore_Event_Mouse_Move, 1);
+ e->win = xevent->xcrossing.window;
+ e->root = xevent->xcrossing.root;
+ e->x = xevent->xcrossing.x;
+ e->y = xevent->xcrossing.y;
+ e->rx = xevent->xcrossing.x_root;
+ e->ry = xevent->xcrossing.y_root;
+ e->time = xevent->xcrossing.time;
+ GETSET_MODS(xevent->xcrossing.state, e->mods);
+ ecore_add_event(ECORE_EVENT_MOUSE_MOVE, e, ecore_event_generic_free);
+ }
+}
+
+static void
+ecore_event_x_handle_leave_notify(XEvent * xevent)
+{
+ Ecore_Event_Window_Leave *e;
+
+/* if ((xevent->xcrossing.mode == NotifyGrab) || (xevent->xcrossing.mode == NotifyUngrab)) return;*/
+ ecore_pointer_xy_set(xevent->xcrossing.x_root, xevent->xcrossing.y_root);
+ {
+ Ecore_Event_Mouse_Move *e;
+
+ e = NEW(Ecore_Event_Mouse_Move, 1);
+ e->win = xevent->xcrossing.window;
+ e->root = xevent->xcrossing.root;
+ e->x = xevent->xcrossing.x;
+ e->y = xevent->xcrossing.y;
+ e->rx = xevent->xcrossing.x_root;
+ e->ry = xevent->xcrossing.y_root;
+ e->time = xevent->xcrossing.time;
+ GETSET_MODS(xevent->xcrossing.state, e->mods);
+ ecore_add_event(ECORE_EVENT_MOUSE_MOVE, e, ecore_event_generic_free);
+ }
+ e = NEW(Ecore_Event_Window_Leave, 1);
+ e->win = xevent->xcrossing.window;
+ e->root = xevent->xcrossing.root;
+ e->x = xevent->xcrossing.x;
+ e->y = xevent->xcrossing.y;
+ e->rx = xevent->xcrossing.x_root;
+ e->ry = xevent->xcrossing.y_root;
+ e->time = xevent->xcrossing.time;
+ GETSET_MODS(xevent->xcrossing.state, e->mods);
+ ecore_add_event(ECORE_EVENT_MOUSE_OUT, e, ecore_event_generic_free);
+ ecore_window_mouse_set_in(e->win, 0);
+}
+
+static void
+ecore_event_x_handle_focus_in(XEvent * xevent)
+{
+ Ecore_Event_Window_Focus_In *e;
+
+ e = NEW(Ecore_Event_Window_Focus_In, 1);
+ e->win = xevent->xfocus.window;
+ e->root = ecore_window_get_root(e->win);
+ if (xevent->xfocus.mode != NotifyNormal)
+ e->key_grab = 1;
+ else
+ e->key_grab = 0;
+ ecore_add_event(ECORE_EVENT_WINDOW_FOCUS_IN, e, ecore_event_generic_free);
+ ecore_focus_window_set(e->win);
+}
+
+static void
+ecore_event_x_handle_focus_out(XEvent * xevent)
+{
+ Ecore_Event_Window_Focus_Out *e;
+
+ e = NEW(Ecore_Event_Window_Focus_Out, 1);
+ e->win = xevent->xfocus.window;
+ e->root = ecore_window_get_root(e->win);
+ if (xevent->xfocus.mode != NotifyNormal)
+ e->key_grab = 1;
+ else
+ e->key_grab = 0;
+ ecore_add_event(ECORE_EVENT_WINDOW_FOCUS_OUT, e, ecore_event_generic_free);
+ ecore_focus_window_set(0);
+}
+
+static void
+ecore_event_x_handle_expose(XEvent * xevent)
+{
+ Ecore_Event_Window_Expose *e;
+
+ e = NEW(Ecore_Event_Window_Expose, 1);
+ e->win = xevent->xexpose.window;
+ e->root = ecore_window_get_root(e->win);
+ e->x = xevent->xexpose.x;
+ e->y = xevent->xexpose.y;
+ e->w = xevent->xexpose.width;
+ e->h = xevent->xexpose.height;
+ ecore_add_event(ECORE_EVENT_WINDOW_EXPOSE, e, ecore_event_generic_free);
+}
+
+static void
+ecore_event_x_handle_visibility_notify(XEvent * xevent)
+{
+ if (xevent->xvisibility.state != VisibilityPartiallyObscured)
+ {
+ Ecore_Event_Window_Visibility *e;
+
+ e = NEW(Ecore_Event_Window_Visibility, 1);
+ e->win = xevent->xvisibility.window;
+ e->root = ecore_window_get_root(e->win);
+ if (xevent->xvisibility.state == VisibilityFullyObscured)
+ e->fully_obscured = 1;
+ else
+ e->fully_obscured = 0;
+ ecore_add_event(ECORE_EVENT_WINDOW_VISIBILITY, e,
+ ecore_event_generic_free);
+ }
+}
+
+static void
+ecore_event_x_handle_create_notify(XEvent * xevent)
+{
+ Ecore_Event_Window_Create *e;
+
+ e = NEW(Ecore_Event_Window_Create, 1);
+ e->win = xevent->xcreatewindow.window;
+ ecore_validate_xid(e->win);
+ e->root = ecore_window_get_root(e->win);
+ if (xevent->xcreatewindow.override_redirect)
+ e->override = 1;
+ else
+ e->override = 0;
+ ecore_add_event(ECORE_EVENT_WINDOW_CREATE, e, ecore_event_generic_free);
+}
+
+static void
+ecore_event_x_handle_destroy_notify(XEvent * xevent)
+{
+ Ecore_Event_Window_Destroy *e;
+
+ e = NEW(Ecore_Event_Window_Destroy, 1);
+ e->win = xevent->xdestroywindow.window;
+ e->root = ecore_window_get_root(e->win);
+ ecore_add_event(ECORE_EVENT_WINDOW_DESTROY, e, ecore_event_generic_free);
+ ecore_unvalidate_xid(e->win);
+}
+
+static void
+ecore_event_x_handle_unmap_notify(XEvent * xevent)
+{
+ Ecore_Event_Window_Unmap *e;
+ Ecore_XID *xid = NULL;
+
+ e = NEW(Ecore_Event_Window_Unmap, 1);
+ e->win = xevent->xunmap.window;
+ e->root = ecore_window_get_root(e->win);
+ ecore_add_event(ECORE_EVENT_WINDOW_UNMAP, e, ecore_event_generic_free);
+ xid = ecore_validate_xid(e->win);
+ if (xid)
+ xid->mapped = 0;
+}
+
+static void
+ecore_event_x_handle_map_notify(XEvent * xevent)
+{
+ Ecore_Event_Window_Map *e;
+ Ecore_XID *xid = NULL;
+
+ e = NEW(Ecore_Event_Window_Map, 1);
+ e->win = xevent->xmap.window;
+ e->root = ecore_window_get_root(e->win);
+ ecore_add_event(ECORE_EVENT_WINDOW_MAP, e, ecore_event_generic_free);
+ xid = ecore_validate_xid(e->win);
+ if (xid)
+ xid->mapped = 1;
+}
+
+static void
+ecore_event_x_handle_map_request(XEvent * xevent)
+{
+ Ecore_Event_Window_Map_Request *e;
+
+ e = NEW(Ecore_Event_Window_Map_Request, 1);
+ e->win = xevent->xmaprequest.window;
+ e->root = ecore_window_get_root(e->win);
+ ecore_add_event(ECORE_EVENT_WINDOW_MAP_REQUEST, e, ecore_event_generic_free);
+ ecore_validate_xid(e->win);
+}
+
+static void
+ecore_event_x_handle_reparent_notify(XEvent * xevent)
+{
+ Ecore_Event_Window_Reparent *e;
+ Window parent;
+ Ecore_XID *xid = NULL;
+
+ e = NEW(Ecore_Event_Window_Reparent, 1);
+ e->win = xevent->xreparent.window;
+ xid = ecore_validate_xid(e->win);
+ e->root = ecore_window_get_root(e->win);
+ parent = ecore_window_get_parent(e->win);
+ e->parent_from = parent;
+ e->parent = xevent->xreparent.parent;
+ ecore_validate_xid(e->parent);
+ ecore_del_child(parent, e->win);
+ ecore_add_child(xevent->xreparent.parent, xevent->xreparent.window);
+ if (xid)
+ xid->parent = e->parent;
+ ecore_add_event(ECORE_EVENT_WINDOW_REPARENT, e, ecore_event_generic_free);
+}
+
+static void
+ecore_event_x_handle_configure_notify(XEvent * xevent)
+{
+ Ecore_Event_Window_Configure *e;
+ Ecore_XID *xid;
+
+ e = NEW(Ecore_Event_Window_Configure, 1);
+ e->win = xevent->xconfigure.window;
+ e->root = ecore_window_get_root(e->win);
+ e->x = xevent->xconfigure.x;
+ e->y = xevent->xconfigure.y;
+ e->w = xevent->xconfigure.width;
+ e->h = xevent->xconfigure.height;
+ if (!xevent->xconfigure.send_event)
+ {
+ xid = ecore_validate_xid(e->win);
+ if (xid)
+ {
+ xid->x = e->x;
+ xid->y = e->y;
+ xid->w = e->w;
+ xid->h = e->h;
+ }
+ e->wm_generated = 0;
+ /* FIXME: don't handle redoing stack for xevent->xconfigure.above */
+ /* member (the window is stacked immediately in stack above this) */
+ }
+ else
+ e->wm_generated = 1;
+ ecore_add_event(ECORE_EVENT_WINDOW_CONFIGURE, e, ecore_event_generic_free);
+}
+
+static void
+ecore_event_x_handle_configure_request(XEvent * xevent)
+{
+ Ecore_Event_Window_Configure_Request *e;
+
+ e = NEW(Ecore_Event_Window_Configure_Request, 1);
+ e->win = xevent->xconfigurerequest.window;
+ e->root = ecore_window_get_root(e->win);
+ e->x = xevent->xconfigurerequest.x;
+ e->y = xevent->xconfigurerequest.y;
+ e->w = xevent->xconfigurerequest.width;
+ e->h = xevent->xconfigurerequest.height;
+ e->stack_win = xevent->xconfigurerequest.above;
+ e->detail = xevent->xconfigurerequest.detail;
+ e->mask = xevent->xconfigurerequest.value_mask;
+ ecore_add_event(ECORE_EVENT_WINDOW_CONFIGURE_REQUEST, e,
+ ecore_event_generic_free);
+}
+
+static void
+ecore_event_x_handle_circulate_notify(XEvent * xevent)
+{
+ Ecore_Event_Window_Circulate *e;
+
+ e = NEW(Ecore_Event_Window_Circulate, 1);
+ e->win = xevent->xcirculate.window;
+ e->root = ecore_window_get_root(e->win);
+ if (xevent->xcirculate.place == PlaceOnBottom)
+ e->lower = 1;
+ else
+ e->lower = 0;
+ ecore_add_event(ECORE_EVENT_WINDOW_CIRCULATE, e, ecore_event_generic_free);
+}
+
+static void
+ecore_event_x_handle_circulate_request(XEvent * xevent)
+{
+ Ecore_Event_Window_Circulate_Request *e;
+
+ e = NEW(Ecore_Event_Window_Circulate_Request, 1);
+ e->win = xevent->xcirculaterequest.window;
+ e->root = ecore_window_get_root(e->win);
+ if (xevent->xcirculaterequest.place == PlaceOnBottom)
+ e->lower = 1;
+ else
+ e->lower = 0;
+ ecore_add_event(ECORE_EVENT_WINDOW_CIRCULATE_REQUEST, e,
+ ecore_event_generic_free);
+}
+
+static void
+ecore_event_x_handle_property_notify(XEvent * xevent)
+{
+ Ecore_Event_Window_Property *e;
+
+ e = NEW(Ecore_Event_Window_Property, 1);
+ e->win = xevent->xproperty.window;
+ e->root = ecore_window_get_root(e->win);
+ e->atom = xevent->xproperty.atom;
+ e->time = xevent->xproperty.time;
+ ecore_add_event(ECORE_EVENT_WINDOW_PROPERTY, e, ecore_event_generic_free);
+}
+
+static void
+ecore_event_x_handle_colormap_notify(XEvent * xevent)
+{
+ Ecore_Event_Colormap *e;
+
+ e = NEW(Ecore_Event_Colormap, 1);
+ e->win = xevent->xcolormap.window;
+ e->root = ecore_window_get_root(e->win);
+ e->cmap = xevent->xcolormap.colormap;
+ if (xevent->xcolormap.state == ColormapInstalled)
+ e->installed = 1;
+ else
+ e->installed = 0;
+ ecore_add_event(ECORE_EVENT_COLORMAP, e, ecore_event_generic_free);
+}
+
+Ecore_Event_Dnd_Drop_Request *ev_drop_request_pending = NULL;
+
+static void
+ecore_event_x_handle_selection_notify(XEvent * xevent)
+{
+ Ecore_Event_Dnd_Drop_Request *e;
+ char *data;
+ int size;
+ static Atom atom_xdndactioncopy = 0;
+ static Atom atom_xdndactionmove = 0;
+ static Atom atom_xdndactionlink = 0;
+ static Atom atom_xdndactionask = 0;
+ static Atom atom_xdndactionlist = 0;
+
+ e = ev_drop_request_pending;
+ if (!e)
+ {
+ Ecore_Event_Paste_Request *e2;
+
+ e2 = NEW(Ecore_Event_Paste_Request, 1);
+ e2->string = ecore_selection_get_data(xevent->xselection.requestor,
+ xevent->xselection.property);
+ if (e2->string)
+ {
+ e2->win = xevent->xselection.requestor;
+ e2->root = ecore_window_get_root(e2->win);
+ e2->source_win = xevent->xselection.requestor;
+ ecore_add_event(ECORE_EVENT_PASTE_REQUEST, e2,
+ ecore_event_paste_request_free);
+ }
+ else
+ {
+ FREE(e2);
+ }
+ return;
+ }
+
+ ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy");
+ ECORE_ATOM(atom_xdndactionmove, "XdndActionMove");
+ ECORE_ATOM(atom_xdndactionlink, "XdndActionLink");
+ ECORE_ATOM(atom_xdndactionask, "XdndActionAsk");
+ ECORE_ATOM(atom_xdndactionlist, "XdndActionList");
+ data = ecore_dnd_selection_get(xevent->xany.window, e->source_win,
+ xevent->xselection.property, &size);
+ if (data)
+ {
+ char *s, *buf;
+ int i, is;
+ Atom *method = NULL;
+
+ method = ecore_window_property_get(e->source_win,
+ atom_xdndactionlist, XA_ATOM, &is);
+ if (method)
+ {
+ e->copy = 0;
+ e->link = 0;
+ e->move = 0;
+ if (*method == atom_xdndactioncopy)
+ e->copy = 1;
+ else if (*method == atom_xdndactionmove)
+ e->move = 1;
+ else if (*method == atom_xdndactionlink)
+ e->link = 1;
+ FREE(method);
+ }
+ else
+ {
+ e->copy = 0;
+ e->link = 0;
+ e->move = 0;
+ }
+ s = data;
+ buf = NEW(char, size);
+
+ i = 0;
+ is = 0;
+ e->files = NULL;
+ while ((s[is]) && (is < size))
+ {
+ if ((i == 0) && (s[is] == '#'))
+ {
+ for (; ((s[is] != 0) && (s[is] != '\n')); is++);
+ }
+ else
+ {
+ if (s[is] != '\r')
+ {
+ buf[i++] = s[is];
+ }
+ else
+ {
+ buf[i] = 0;
+ e->num_files++;
+ REALLOC_PTR(e->files, e->num_files);
+ e->files[e->num_files - 1] = strdup(buf);
+ buf[0] = 0;
+ i = 0;
+ is++;
+ }
+ is++;
+ }
+ }
+ if (i > 0)
+ {
+ buf[i] = 0;
+ e->num_files++;
+ REALLOC_PTR(e->files, e->num_files);
+ e->files[e->num_files - 1] = strdup(buf);
+ }
+ FREE(buf);
+ FREE(data);
+ }
+ ecore_add_event(ECORE_EVENT_DND_DROP_REQUEST, e,
+ ecore_event_dnd_drop_request_free);
+ ev_drop_request_pending = NULL;
+}
+
+static void
+ecore_event_x_handle_selection_clear(XEvent * xevent)
+{
+ Ecore_Event_Clear_Selection *e;
+
+ e = NEW(Ecore_Event_Clear_Selection, 1);
+ e->win = xevent->xselectionclear.window;
+ e->root = ecore_window_get_root(e->win);
+ e->selection = xevent->xselectionclear.selection;
+ ecore_add_event(ECORE_EVENT_CLEAR_SELECTION, e, ecore_event_generic_free);
+}
+
+static void
+ecore_event_x_handle_selection_request(XEvent * xevent)
+{
+ static Atom atom_xdndselection = 0;
+ static Atom atom_text_plain = 0;
+ static Atom atom_text_uri_list = 0;
+ static Atom atom_text_moz_url = 0;
+ static Atom atom_netscape_url = 0;
+ static Atom atom_text_selection = 0;
+ Ecore_Event_Dnd_Data_Request *e;
+
+ ECORE_ATOM(atom_xdndselection, "XdndSelection");
+ ECORE_ATOM(atom_text_plain, "text/plain");
+ ECORE_ATOM(atom_text_uri_list, "text/uri-list");
+ ECORE_ATOM(atom_text_moz_url, "text/x-moz-url");
+ ECORE_ATOM(atom_netscape_url, "_NETSCAPE_URL");
+ ECORE_ATOM(atom_text_selection, "TEXT_SELECTION");
+ if (xevent->xselectionrequest.selection == atom_xdndselection)
+ {
+ e = NEW(Ecore_Event_Dnd_Data_Request, 1);
+ e->win = xevent->xselectionrequest.owner;
+ e->root = ecore_window_get_root(e->win);
+ e->source_win = xevent->xselectionrequest.requestor;
+ e->plain_text =0;
+ e->uri_list = 0;
+ e->moz_url = 0;
+ e->netscape_url = 0;
+
+ if (xevent->xselectionrequest.target == atom_text_plain) e->plain_text = 1;
+ if (xevent->xselectionrequest.target == atom_text_uri_list) e->uri_list = 1;
+ if (xevent->xselectionrequest.target == atom_text_moz_url) e->moz_url = 1;
+ if (xevent->xselectionrequest.target == atom_netscape_url) e->netscape_url = 1;
+ e->destination_atom = xevent->xselectionrequest.property;
+ ecore_add_event(ECORE_EVENT_DND_DATA_REQUEST, e,
+ ecore_event_generic_free);
+ }
+ else
+ {
+ XEvent ev;
+ Atom target_list[2];
+ static Atom xa_targets = None;
+
+ if (xa_targets == None)
+ xa_targets = XInternAtom(xevent->xselectionrequest.display,
+ "TARGETS", False);
+ ev.xselection.type = SelectionNotify;
+ ev.xselection.property = None;
+ ev.xselection.display = xevent->xselectionrequest.display;
+ ev.xselection.requestor = xevent->xselectionrequest.requestor;
+ ev.xselection.selection = xevent->xselectionrequest.selection;
+ ev.xselection.target = xevent->xselectionrequest.target;
+ ev.xselection.time = xevent->xselectionrequest.time;
+ if (xevent->xselectionrequest.target == xa_targets)
+ {
+ target_list[0] = (Atom) xa_targets;
+ target_list[1] = (Atom) XA_STRING;
+ XChangeProperty(xevent->xselectionrequest.display,
+ xevent->xselectionrequest.requestor,
+ xevent->xselectionrequest.property,
+ xevent->xselectionrequest.target,
+ (8 * sizeof(target_list[0])),
+ PropModeReplace,
+ (unsigned char *)target_list,
+ (sizeof(target_list) / sizeof(target_list[0])));
+ ev.xselection.property = xevent->xselectionrequest.property;
+ }
+ else if (xevent->xselectionrequest.target == XA_STRING)
+ {
+ void *data;
+ int size;
+
+ data = ecore_window_property_get(xevent->xselectionrequest.owner,
+ atom_text_selection, XA_STRING,
+ &size);
+ if (data)
+ {
+ XChangeProperty(xevent->xselectionrequest.display,
+ xevent->xselectionrequest.requestor,
+ xevent->xselectionrequest.property,
+ xevent->xselectionrequest.target,
+ 8, PropModeReplace, data, size);
+ FREE(data);
+ }
+ ev.xselection.property = xevent->xselectionrequest.property;
+ }
+ XSendEvent(xevent->xselectionrequest.display,
+ xevent->xselectionrequest.requestor, False, 0, &ev);
+ }
+}
+
+static void
+ecore_event_x_handle_client_message(XEvent * xevent)
+{
+ static Atom atom_wm_delete_window = 0;
+ static Atom atom_wm_protocols = 0;
+ static Atom atom_xdndstatus = 0;
+ static Atom atom_xdndenter = 0;
+ static Atom atom_xdndleave = 0;
+ static Atom atom_xdndfinished = 0;
+ static Atom atom_xdndposition = 0;
+ static Atom atom_xdnddrop = 0;
+ static Atom atom_text_uri_list = 0;
+ static Atom atom_xdndactioncopy = 0;
+ static Atom atom_xdndactionlink = 0;
+ static Atom atom_xdndactionmove = 0;
+ static Atom atom_xdndactionprivate = 0;
+
+ /* setup some known atoms to translate this message into a sensible event */
+ ECORE_ATOM(atom_wm_delete_window, "WM_DELETE_WINDOW");
+ ECORE_ATOM(atom_wm_protocols, "WM_PROTOCOLS");
+ ECORE_ATOM(atom_xdndstatus, "XdndStatus");
+ ECORE_ATOM(atom_xdndfinished, "XdndFinished");
+ ECORE_ATOM(atom_xdndenter, "XdndEnter");
+ ECORE_ATOM(atom_xdndleave, "XdndLeave");
+ ECORE_ATOM(atom_xdnddrop, "XdndDrop");
+ ECORE_ATOM(atom_xdndposition, "XdndPosition");
+ ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy");
+ ECORE_ATOM(atom_xdndactionlink, "XdndActionLink");
+ ECORE_ATOM(atom_xdndactionmove, "XdndActionMove");
+ ECORE_ATOM(atom_xdndactionprivate, "XdndActionPrivate");
+ ECORE_ATOM(atom_text_uri_list, "text/uri-list");
+
+ /* first type = delete event sent to client */
+ if ((xevent->xclient.message_type == atom_wm_protocols) &&
+ (xevent->xclient.format == 32) &&
+ (xevent->xclient.data.l[0] == (long)atom_wm_delete_window))
+ {
+ Ecore_Event_Window_Delete *e;
+
+ e = NEW(Ecore_Event_Window_Delete, 1);
+ e->win = xevent->xclient.window;
+ e->root = ecore_window_get_root(e->win);
+ ecore_add_event(ECORE_EVENT_WINDOW_DELETE, e, ecore_event_generic_free);
+ }
+ else if ((xevent->xclient.message_type == atom_xdndenter) &&
+ (xevent->xclient.format == 32))
+ {
+/* if ((xevent->xclient.data.l[2] == (long)atom_text_uri_list) ||
+ * (xevent->xclient.data.l[3] == (long)atom_text_uri_list) ||
+ * (xevent->xclient.data.l[4] == (long)atom_text_uri_list))
+ */ {
+ Ecore_Event_Dnd_Drop_Request *e;
+
+
+ if (ev_drop_request_pending)
+ {
+ ecore_event_dnd_drop_request_free(ev_drop_request_pending);
+ ev_drop_request_pending = NULL;
+ }
+ e = NEW(Ecore_Event_Dnd_Drop_Request, 1);
+ e->win = xevent->xclient.window;
+ e->root = ecore_window_get_root(e->win);
+ e->source_win = (Window) xevent->xclient.data.l[0];
+ if (!ecore_dnd_selection_convert
+ (e->source_win, e->win, atom_text_uri_list))
+ {
+ FREE(e);
+ return;
+ }
+ e->files = NULL;
+ e->num_files = 0;
+ ev_drop_request_pending = e;
+ }
+ }
+ else if ((xevent->xclient.message_type == atom_xdndleave) &&
+ (xevent->xclient.format == 32))
+ {
+ Ecore_Event_Dnd_Drop_End *e;
+
+ e = NEW(Ecore_Event_Dnd_Drop_End, 1);
+ e->win = xevent->xclient.window;
+ e->root = ecore_window_get_root(e->win);
+ e->source_win = (Window) xevent->xclient.data.l[0];
+ ecore_add_event(ECORE_EVENT_DND_DROP_END, e, ecore_event_generic_free);
+ }
+ else if ((xevent->xclient.message_type == atom_xdndposition) &&
+ (xevent->xclient.format == 32))
+ {
+ Ecore_Event_Dnd_Drop_Position *e;
+
+ e = NEW(Ecore_Event_Dnd_Drop_Position, 1);
+ e->win = xevent->xclient.window;
+ e->root = ecore_window_get_root(e->win);
+ e->source_win = (Window) xevent->xclient.data.l[0];
+ e->x = (xevent->xclient.data.l[2] >> 16) & 0xffff;
+ e->y = xevent->xclient.data.l[2] & 0xffff;
+ ecore_add_event(ECORE_EVENT_DND_DROP_POSITION, e,
+ ecore_event_generic_free);
+ }
+ else if ((xevent->xclient.message_type == atom_xdndstatus) &&
+ (xevent->xclient.format == 32))
+ {
+ Ecore_Event_Dnd_Drop_Status *e;
+
+ ecore_clear_target_status();
+ e = NEW(Ecore_Event_Dnd_Drop_Status, 1);
+ e->win = xevent->xclient.window;
+ e->root = ecore_window_get_root(e->win);
+ e->source_win = (Window) xevent->xclient.data.l[0];
+ e->x = (xevent->xclient.data.l[2] >> 16) & 0xffff;
+ e->y = xevent->xclient.data.l[2] & 0xffff;
+ e->w = (xevent->xclient.data.l[3] >> 16) & 0xffff;
+ e->h = xevent->xclient.data.l[3] & 0xffff;
+
+ e->copy = e->link = e->move = e->e_private = 0;
+ if( xevent->xclient.data.l[4] == atom_xdndactioncopy )
+ e->copy = 1;
+ else if( xevent->xclient.data.l[4] == atom_xdndactionlink )
+ e->link = 1;
+ else if( xevent->xclient.data.l[4] == atom_xdndactionmove )
+ e->move = 1;
+ else if( xevent->xclient.data.l[4] == atom_xdndactionprivate )
+ e->e_private = 1;
+
+ if (xevent->xclient.data.l[1] & 0x1)
+ e->ok = 1;
+ else
+ e->ok = 0;
+ if (xevent->xclient.data.l[1] & 0x2)
+ e->all_position_msgs = 1;
+ else
+ e->all_position_msgs = 0;
+ ecore_add_event(ECORE_EVENT_DND_DROP_STATUS, e, ecore_event_generic_free);
+ }
+ else if ((xevent->xclient.message_type == atom_xdndfinished) &&
+ (xevent->xclient.format == 32))
+ {
+ Ecore_Event_Dnd_Drop_End *e;
+
+ e = NEW(Ecore_Event_Dnd_Drop_End, 1);
+ e->win = xevent->xclient.window;
+ e->root = ecore_window_get_root(e->win);
+ e->source_win = (Window) xevent->xclient.data.l[0];
+ ecore_add_event(ECORE_EVENT_DND_DROP_END, e, ecore_event_generic_free);
+ }
+ else if ((xevent->xclient.message_type == atom_xdnddrop) &&
+ (xevent->xclient.format == 32))
+ {
+ Ecore_Event_Dnd_Drop *e;
+
+ e = NEW(Ecore_Event_Dnd_Drop, 1);
+ e->win = xevent->xclient.window;
+ e->root = ecore_window_get_root(e->win);
+ e->source_win = (Window) xevent->xclient.data.l[0];
+ ecore_add_event(ECORE_EVENT_DND_DROP, e, ecore_event_generic_free);
+ }
+ else
+ {
+ Ecore_Event_Message *e;
+
+ e = NEW(Ecore_Event_Message, 1);
+ e->win = xevent->xclient.window;
+ e->format = xevent->xclient.format;
+ e->atom = xevent->xclient.message_type;
+ MEMCPY(xevent->xclient.data.b, e->data.b, char, 20);
+
+ ecore_add_event(ECORE_EVENT_MESSAGE, e, ecore_event_generic_free);
+ }
+}
+
+static void
+ecore_event_x_handle_shape_change(XEvent * xevent)
+{
+ Ecore_Event_Window_Shape *e;
+ XShapeEvent *shape_event;
+
+ shape_event = (XShapeEvent *) xevent;
+ e = NEW(Ecore_Event_Window_Shape, 1);
+ e->win = shape_event->window;
+ e->root = ecore_window_get_root(e->win);
+ e->time = shape_event->time;
+ ecore_add_event(ECORE_EVENT_WINDOW_SHAPE, e, ecore_event_generic_free);
+}
+
+char *
+ecore_keypress_translate_into_typeable(Ecore_Event_Key_Down * e)
+{
+ /* exceptions */
+ if ((!strcmp(e->key, "Delete")) ||
+ (!strcmp(e->key, "BackSpace")) ||
+ (!strcmp(e->key, "Tab")) ||
+ (!strcmp(e->key, "Escape")) ||
+ (!strcmp(e->key, "Return")) ||
+ (!strcmp(e->key, "KP_Enter")) ||
+ (!strcmp(e->key, "Enter")) ||
+ (!strcmp(e->key, "KP_Divide")) ||
+ (!strcmp(e->key, "KP_Multiply")) ||
+ (!strcmp(e->key, "KP_Subtract")) ||
+ (!strcmp(e->key, "KP_Add")) || (!strcmp(e->key, "Enter")))
+ return NULL;
+ return e->compose;
+}
diff --git a/ecore/src/e_events.c b/ecore/src/e_events.c
new file mode 100644
index 0000000..0a8f442
--- /dev/null
+++ b/ecore/src/e_events.c
@@ -0,0 +1,430 @@
+#include "Ecore.h"
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* glocal (yes global/local) variabels for events */
+Ecore_Event_Fd_Handler *fd_handlers = NULL;
+Ecore_Event_Ipc_Handler *ipc_handlers = NULL;
+Ecore_Event_Pid_Handler *pid_handlers = NULL;
+Ecore_Event_Timer *timers = NULL;
+
+Ecore_Event *events = NULL;
+Ecore_Event *last_event = NULL;
+
+int __quit_ev_loop = 0;
+
+/* local functions for event handling */
+static void ecore_handle_event_timer(void);
+static void ecore_handle_zero_event_timer(void);
+
+/* public functions */
+
+/* add an event to the end of the event queue */
+void
+ecore_add_event(Ecore_Event_Type type, void *event,
+ void (*ev_free) (void *event))
+{
+ Ecore_Event *ev;
+
+ ev = NEW(Ecore_Event, 1);
+ ev->type = type;
+ ev->ignore = 0;
+ ev->event = event;
+ ev->next = NULL;
+ ev->ev_free = ev_free;
+ if (!events)
+ events = ev;
+ else
+ last_event->next = ev;
+ last_event = ev;
+}
+
+/* delete an event from the event queue */
+void
+ecore_del_event(void *event)
+{
+ Ecore_Event *ev, *pev;
+
+ pev = NULL;
+ ev = events;
+ while (ev)
+ {
+ if (ev->event == event)
+ {
+ if (pev)
+ pev->next = ev->next;
+ else
+ events = ev->next;
+ if (!ev->next)
+ last_event = pev;
+ if ((ev->event) && (ev->ev_free))
+ (*ev->ev_free) (ev->event);
+ FREE(ev);
+ return;
+ }
+ pev = ev;
+ ev = ev->next;
+ }
+}
+
+void
+ecore_del_all_events(void)
+{
+ Ecore_Event *ev, *pev;
+
+ ev = events;
+ while (ev)
+ {
+ pev = ev;
+ ev = ev->next;
+ if ((pev->event) && (pev->ev_free))
+ pev->ev_free(pev->event);
+ FREE(pev);
+ }
+ events = NULL;
+ last_event = NULL;
+}
+
+Ecore_Event *
+ecore_get_last_event(void)
+{
+ return last_event;
+}
+
+/* add a callback handler if fd is active for reading */
+void
+ecore_add_event_fd(int fd, void (*func) (int fd))
+{
+ Ecore_Event_Fd_Handler *fd_h;
+
+ /* new handler struct */
+ fd_h = NEW(Ecore_Event_Fd_Handler, 1);
+ fd_h->next = fd_handlers;
+ fd_h->fd = fd;
+ fd_h->func = func;
+ fd_handlers = fd_h;
+}
+
+/* delete handler for fd */
+void
+ecore_del_event_fd(int fd)
+{
+ START_LIST_DEL(Ecore_Event_Fd_Handler, fd_handlers, (_p->fd == fd));
+ FREE(_p);
+ END_LIST_DEL;
+}
+
+void
+ecore_add_event_pid(pid_t pid, void (*func) (pid_t pid))
+{
+ Ecore_Event_Pid_Handler *pid_h;
+
+ /* delete the old handler */
+ ecore_del_event_pid(pid);
+ /* new handler struct */
+ pid_h = NEW(Ecore_Event_Pid_Handler, 1);
+ pid_h->next = pid_handlers;
+ pid_h->pid = pid;
+ pid_h->func = func;
+ pid_handlers = pid_h;
+}
+
+void
+ecore_del_event_pid(pid_t pid)
+{
+ START_LIST_DEL(Ecore_Event_Pid_Handler, pid_handlers, (_p->pid == pid));
+ FREE(_p);
+ END_LIST_DEL;
+}
+
+void
+ecore_add_event_ipc(int ipc, void (*func) (int ipc))
+{
+ Ecore_Event_Ipc_Handler *ipc_h;
+
+ /* delete the old handler */
+ ecore_del_event_ipc(ipc);
+ /* new handler struct */
+ ipc_h = NEW(Ecore_Event_Ipc_Handler, 1);
+ ipc_h->next = ipc_handlers;
+ ipc_h->ipc = ipc;
+ ipc_h->func = func;
+ ipc_handlers = ipc_h;
+}
+
+void
+ecore_del_event_ipc(int ipc)
+{
+ START_LIST_DEL(Ecore_Event_Ipc_Handler, ipc_handlers, (_p->ipc == ipc));
+ FREE(_p);
+ END_LIST_DEL;
+}
+
+/* sit in this loop forever and process events */
+void
+ecore_event_loop(void)
+{
+ int fdcount, fdsize, ipccount, ipcsize;
+ int timed_out, were_events;
+ double time1, time2, prev_time = 0.0;
+ struct timeval tval;
+ fd_set fdset, ipcset;
+ Ecore_Event_Fd_Handler *fd_h;
+ Ecore_Event_Pid_Handler *pid_h;
+ Ecore_Event_Ipc_Handler *ipc_h;
+
+ /* init some of the time variables */
+ time1 = ecore_get_time();
+ time2 = time1 - prev_time;
+ prev_time = time1;
+ while (__quit_ev_loop == 0)
+ {
+ /* state setup */
+ timed_out = 0;
+ were_events = 0;
+
+ /* setup fd array from list of listening fd's */
+ fdsize = 0;
+ FD_ZERO(&fdset);
+ /* for ever fd handler add the fd to the array and incriment fdsize */
+ for (fd_h = fd_handlers; fd_h; fd_h = fd_h->next)
+ {
+ FD_SET(fd_h->fd, &fdset);
+ if (fd_h->fd > fdsize)
+ fdsize = fd_h->fd;
+ }
+ fdcount = 1;
+ ipcsize = 0;
+ FD_ZERO(&ipcset);
+ /* for ever fd handler add the fd to the array and incriment fdsize */
+ for (ipc_h = ipc_handlers; ipc_h; ipc_h = ipc_h->next)
+ {
+ FD_SET(ipc_h->ipc, &ipcset);
+ if (ipc_h->ipc > ipcsize)
+ ipcsize = ipc_h->ipc;
+ }
+ ipccount = 1;
+ /* if there are timers setup adjust timeout value and select */
+ if (timers)
+ {
+ if (timers->just_added)
+ {
+ timers->just_added = 0;
+ time1 = timers->in;
+ }
+ else
+ {
+ time1 = timers->in - time2;
+ if (time1 < 0.0)
+ time1 = 0.0;
+ timers->in = time1;
+ }
+ tval.tv_sec = (long)time1;
+ tval.tv_usec = (long)((time1 - ((double)tval.tv_sec)) * 1000000);
+ if (tval.tv_sec < 0)
+ tval.tv_sec = 0;
+ if (tval.tv_usec <= 1000)
+ tval.tv_usec = 1000;
+ ecore_handle_zero_event_timer();
+ if ((!ecore_events_pending()) && (!ecore_event_signal_events_pending()))
+ fdcount = select(fdsize + 1, &fdset, NULL, NULL, &tval);
+ }
+ /* no timers - just sit and block */
+ else
+ {
+ if ((!ecore_events_pending()) && (!ecore_event_signal_events_pending()))
+ fdcount = select(fdsize + 1, &fdset, NULL, NULL, NULL);
+ }
+ for (pid_h = pid_handlers; pid_h; pid_h = pid_h->next)
+ pid_h->func(pid_h->pid);
+
+ /* see if we have any new ipc connections */
+ tval.tv_sec = 0;
+ tval.tv_usec = 0;
+ ipccount += select(ipcsize + 1, &ipcset, NULL, NULL, &tval);
+
+ /* return < 0 - error or signal interrupt */
+ if (fdcount < 0)
+ {
+ /* error */
+ if ((errno == ENOMEM) || (errno == EINVAL) || (errno == EBADF))
+ {
+ fprintf(stderr, "Lost connection to X display.\n");
+ exit(1);
+ }
+ }
+ /* timers are available and its a timeout */
+ if ((timers) && (fdcount == 0))
+ {
+ ecore_handle_event_timer();
+ timed_out = 1;
+ }
+ if (fdcount < 0)
+ fdcount = 0;
+ if (ecore_events_pending())
+ {
+ fdcount++;
+ FD_SET(ecore_x_get_fd(), &fdset);
+ }
+ /* fd's are active */
+ if (fdcount > 0)
+ {
+ /* for every fd handler - if its fd is set - call the func */
+ for (fd_h = fd_handlers; fd_h;)
+ {
+ Ecore_Event_Fd_Handler *fdh;
+
+ fdh = fd_h;
+ fd_h = fd_h->next;
+ if (FD_ISSET(fdh->fd, &fdset))
+ fdh->func(fdh->fd);
+ }
+ }
+
+ /* ipc clients are active */
+ if (ipccount > 0)
+ {
+ for (ipc_h = ipc_handlers; ipc_h;)
+ {
+ Ecore_Event_Ipc_Handler *ipch;
+
+ ipch = ipc_h;
+ ipc_h = ipc_h->next;
+ if (FD_ISSET(ipch->ipc, &ipcset))
+ ipch->func(ipch->ipc);
+ }
+ }
+ if (events)
+ ecore_event_filter(events);
+ if (events)
+ {
+ ecore_event_filter_events_handle(events);
+ were_events = 1;
+ }
+ ecore_del_all_events();
+ if ((timed_out) || (were_events))
+ ecore_event_filter_idle_handle();
+ ecore_flush();
+ time1 = ecore_get_time();
+ time2 = time1 - prev_time;
+ prev_time = time1;
+ }
+ __quit_ev_loop = 0;
+}
+
+/* set a flag to 0 so that we can quit the event loop and shutdown
+ * properly */
+void
+ecore_event_loop_quit(void)
+{
+ __quit_ev_loop = 1;
+}
+
+/* add a timeout funcitont o be called in "in" seconds with name name */
+void
+ecore_add_event_timer(char *name, double in, void (*func) (int val, void *data),
+ int val, void *data)
+{
+ Ecore_Event_Timer *timer, *ptr, *pptr;
+ double tally;
+
+ if (name)
+ ecore_del_event_timer(name);
+ timer = NEW(Ecore_Event_Timer, 1);
+ timer->next = NULL;
+ timer->func = func;
+ timer->data = data;
+ timer->val = val;
+ timer->just_added = 1;
+ timer->in = in;
+ timer->name = strdup(name);
+ if (!timers)
+ timers = timer;
+ else
+ {
+ pptr = NULL;
+ ptr = timers;
+ tally = 0.0;
+ while (ptr)
+ {
+ tally += ptr->in;
+ if (tally > in)
+ {
+ tally -= ptr->in;
+ timer->next = ptr;
+ if (pptr)
+ pptr->next = timer;
+ else
+ timers = timer;
+ timer->in -= tally;
+ if (timer->next)
+ timer->next->in -= timer->in;
+ return;
+ }
+ pptr = ptr;
+ ptr = ptr->next;
+ }
+ if (pptr)
+ pptr->next = timer;
+ else
+ timers = timer;
+ timer->in -= tally;
+ }
+}
+
+/* delete a timer timeout entry named "name" */
+void *
+ecore_del_event_timer(char *name)
+{
+ Ecore_Event_Timer *timer, *ptr, *pptr;
+
+ pptr = NULL;
+ ptr = timers;
+ while (ptr)
+ {
+ timer = ptr;
+ if (!strcmp(timer->name, name))
+ {
+ void *data;
+
+ if (pptr)
+ pptr->next = timer->next;
+ else
+ timers = timer->next;
+ if (timer->next)
+ timer->next->in += timer->in;
+ IF_FREE(timer->name);
+ data = timer->data;
+ FREE(timer);
+ return data;
+ }
+ pptr = ptr;
+ ptr = ptr->next;
+ }
+ return NULL;
+}
+
+/* private functions */
+static void
+ecore_handle_event_timer(void)
+{
+ Ecore_Event_Timer *timer;
+
+ if (!timers)
+ return;
+ timer = timers;
+ timers = timer->next;
+ (*(timer->func)) (timer->val, timer->data);
+ IF_FREE(timer->name);
+ FREE(timer);
+}
+
+static void
+ecore_handle_zero_event_timer(void)
+{
+ while ((timers) && (timers->in == 0.0))
+ ecore_handle_event_timer();
+}
diff --git a/ecore/src/e_ipc.c b/ecore/src/e_ipc.c
new file mode 100644
index 0000000..2a6de2b
--- /dev/null
+++ b/ecore/src/e_ipc.c
@@ -0,0 +1,187 @@
+#include "Ecore.h"
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+void ecore_ipc_init(char *path);
+void ecore_ipc_cleanup(void);
+static void ecore_ipc_connect_handler(int fd);
+static void ecore_ipc_client_handler(int fd);
+void ecore_ipc_get_data(int fd, void *buf);
+void ecore_ipc_send_data(int fd, void *buf, int size);
+void ecore_add_ipc_service(int service, void (*func) (int fd));
+void ecore_del_ipc_service(int service);
+
+Ecore_Event_Ipc_Service *ipc_services = NULL;
+
+void
+ecore_ev_ipc_init(char *path)
+{
+ int fd, len;
+ struct sockaddr_un saun;
+
+ if (path == NULL)
+ return;
+
+ /* a UNIX domain, stream socket */
+ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ {
+ printf("Cannot create ipc socket... disabling ipc.\n");
+ return;
+ }
+
+ /* create the address we will be binding to */
+ saun.sun_family = AF_UNIX;
+ strcpy(saun.sun_path, path);
+
+ /* unlink the address so the bind won't fail */
+ unlink(path);
+ len = sizeof(saun.sun_family) + strlen(saun.sun_path);
+
+ if (bind(fd, (struct sockaddr *)&saun, len) < 0)
+ {
+ printf("Cannot bind ipc socket... disabling ipc.\n");
+ return;
+ }
+
+ /* listen on the socket */
+ if (listen(fd, 5) < 0)
+ {
+ printf("Cannot listen on ipc socket... disabling ipc.\n");
+ return;
+ }
+
+ /* add ipc listener */
+ ecore_add_event_ipc(fd, ecore_ipc_connect_handler);
+}
+
+void
+ecore_ev_ipc_cleanup(void)
+{
+ Ecore_Event_Ipc_Service *ipc_s;
+
+ /* cleanup services list */
+ for (ipc_s = ipc_services; ipc_s; ipc_s = ipc_s->next)
+ {
+ ecore_del_ipc_service(ipc_s->service);
+ }
+}
+
+static void
+ecore_ipc_connect_handler(int fd)
+{
+ struct sockaddr_un fsaun;
+ int fromlen, nfd;
+
+ /* accept ipc connection */
+ fromlen = sizeof(fsaun);
+
+ if ((nfd = accept(fd, (struct sockaddr *)&fsaun, &fromlen)) < 0)
+ {
+ printf("Cannot accept ipc connection... ignoring connection attempt.\n");
+ return;
+ }
+
+ /* add ipc client */
+ ecore_add_event_ipc(nfd, ecore_ipc_client_handler);
+}
+
+static void
+ecore_ipc_client_handler(int fd)
+{
+ int nread, service;
+ Ecore_Event_Ipc_Service *ipc_s;
+
+ if ((nread = read(fd, &service, sizeof(service))) == 0)
+ {
+ close(fd);
+ ecore_del_event_ipc(fd);
+ }
+ else if (nread > 0)
+ {
+ /* call the service function */
+ for (ipc_s = ipc_services; ipc_s; ipc_s = ipc_s->next)
+ {
+ if (ipc_s->service == service)
+ {
+ ipc_s->func(fd);
+ break;
+ }
+ }
+ }
+ else
+ {
+ printf("ipc error in read service.\n");
+ fflush(stdout);
+ }
+}
+
+void
+ecore_ipc_get_data(int fd, void *buf)
+{
+ int readn, nread;
+
+ /* read number of bytes being sent */
+ if ((nread = read(fd, &readn, sizeof(readn))) == -1)
+ {
+ printf("ipc error in get data.\n");
+ fflush(stdout);
+ return;
+ }
+
+ /* get data structure */
+ if ((nread = read(fd, buf, readn)) == -1)
+ {
+ printf("ipc error in get data.\n");
+ fflush(stdout);
+ return;
+ }
+}
+
+void
+ecore_ipc_send_data(int fd, void *buf, int size)
+{
+ int n;
+
+ /* send length of data being sent */
+ if ((n = write(fd, &size, sizeof(size))) == -1)
+ {
+ printf("ipc error in send data length.\n");
+ fflush(stdout);
+ return;
+ }
+
+ /* send data */
+ if ((n = write(fd, buf, size)) == -1)
+ {
+ printf("ipc error in send data.\n");
+ fflush(stdout);
+ return;
+ }
+}
+
+void
+ecore_add_ipc_service(int service, void (*func) (int fd))
+{
+ Ecore_Event_Ipc_Service *ipc_s;
+
+ /* delete the old service */
+ ecore_del_ipc_service(service);
+ /* new service struct */
+ ipc_s = NEW(Ecore_Event_Ipc_Service, 1);
+ ipc_s->next = ipc_services;
+ ipc_s->service = service;
+ ipc_s->func = func;
+ ipc_services = ipc_s;
+}
+
+void
+ecore_del_ipc_service(int service)
+{
+ START_LIST_DEL(Ecore_Event_Ipc_Service, ipc_services,
+ (_p->service == service));
+ FREE(_p);
+ END_LIST_DEL;
+}
diff --git a/ecore/src/e_util.c b/ecore/src/e_util.c
new file mode 100644
index 0000000..fc4a2ae
--- /dev/null
+++ b/ecore/src/e_util.c
@@ -0,0 +1,10 @@
+#include "Ecore.h"
+
+double
+ecore_get_time(void)
+{
+ struct timeval timev;
+
+ gettimeofday(&timev, NULL);
+ return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
+}
diff --git a/ecore/src/e_x.c b/ecore/src/e_x.c
new file mode 100644
index 0000000..b3d8069
--- /dev/null
+++ b/ecore/src/e_x.c
@@ -0,0 +1,3610 @@
+#include "Ecore.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef XA_CLIPBOARD
+#define X_CLIPBOARD_SELECTION XA_CLIPBOARD(disp)
+#define X_CLIPBOARD_PROP XA_CLIPBOARD(disp)
+#else
+#define X_CLIPBOARD_SELECTION XA_PRIMARY
+#define X_CLIPBOARD_PROP XA_CUT_BUFFER0
+#endif
+
+typedef struct _window_list Window_List;
+
+struct _window_list
+{
+ Window win;
+ Window_List *next;
+};
+
+XContext xid_context = 0;
+
+static Display *disp;
+static Visual *default_vis;
+static Colormap default_cm;
+static int default_depth;
+static Window default_win;
+static Window default_root;
+
+static int lock_scroll = 0;
+static int lock_num = 0;
+static int lock_caps = 0;
+
+static Window focused_win = 0;
+
+static int mod_shift = 0;
+static int mod_ctrl = 0;
+static int mod_alt = 0;
+static int mod_win = 0;
+
+static Window grabkey_win = 0;
+
+static int mouse_x = 0, mouse_y = 0;
+
+static Window current_dnd_win = 0;
+static int current_dnd_target_ok = 0;
+static int dnd_await_target_status = 0;
+
+static int x_grabs = 0;
+
+static Window_List *ignore_wins = NULL;
+
+static Window grab_pointer_win = 0;
+
+static Window keyboard_grab_win = 0;
+
+static int dnd_copy = 0;
+static int dnd_link = 0;
+static int dnd_move = 1;
+
+static void ecore_handle_x_error(Display * d, XErrorEvent * ev);
+static void ecore_handle_x_io_error(Display * d);
+static Window ecore_window_at_xy_0(Window base, int bx, int by, int x,
+ int y);
+
+static void
+ecore_handle_x_error(Display * d, XErrorEvent * ev)
+{
+/*
+ char err[16384];
+
+ XGetErrorText(d, ev->error_code, err, 16000);
+ printf("X Error:\n"
+ "Error: %s\nrequest: %i\nminor: %i\n", err, ev->request_code, ev->minor_code);
+ */
+ /* ignore all X errors */
+ return;
+ d = NULL;
+ ev = NULL;
+}
+
+static void
+ecore_handle_x_io_error(Display * d)
+{
+ /* FIXME: call clean exit handler */
+ exit(1);
+ d = NULL;
+}
+
+void
+ecore_del_child(Window win, Window child)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
+ return;
+ if (xid)
+ {
+ int i;
+
+ for (i = 0; i < xid->children_num; i++)
+ {
+ if (xid->children[i] == child)
+ {
+ int j;
+
+ for (j = i; j < xid->children_num - 1; j++)
+ xid->children[j] = xid->children[j + 1];
+ xid->children_num--;
+ REALLOC(xid->children, Window, xid->children_num);
+ return;
+ }
+ }
+ }
+}
+
+void
+ecore_add_child(Window win, Window child)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
+ return;
+ if (xid)
+ {
+ int i;
+
+ for (i = 0; i < xid->children_num; i++)
+ {
+ if (xid->children[i] == child)
+ return;
+ }
+ xid->children_num++;
+ REALLOC(xid->children, Window, xid->children_num);
+ xid->children[xid->children_num - 1] = child;
+ }
+ xid = ecore_validate_xid(child);
+}
+
+void
+ecore_raise_child(Window win, Window child)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
+ return;
+ if (xid)
+ {
+ int i;
+
+ for (i = 0; i < xid->children_num; i++)
+ {
+ if (xid->children[i] == child)
+ {
+ int j;
+
+ for (j = i; j < xid->children_num - 1; j++)
+ xid->children[j] = xid->children[j + 1];
+ xid->children[xid->children_num - 1] = child;
+ return;
+ }
+ }
+ }
+}
+
+void
+ecore_lower_child(Window win, Window child)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
+ return;
+ if (xid)
+ {
+ int i;
+
+ for (i = 0; i < xid->children_num; i++)
+ {
+ if (xid->children[i] == child)
+ {
+ int j;
+
+ for (j = i; j > 0; j--)
+ xid->children[j] = xid->children[j - 1];
+ xid->children[0] = child;
+ return;
+ }
+ }
+ }
+}
+
+Ecore_XID *
+ecore_add_xid(Window win, int x, int y, int w, int h, int depth, Window parent)
+{
+ Ecore_XID *xid = NULL;
+
+ ecore_window_add_events(win, XEV_IN_OUT | XEV_CONFIGURE | XEV_VISIBILITY);
+ xid = NEW(Ecore_XID, 1);
+ xid->win = win;
+ xid->x = x;
+ xid->y = y;
+ xid->w = w;
+ xid->h = h;
+ xid->mapped = 0;
+ xid->depth = depth;
+ xid->mouse_in = 0;
+ xid->parent = parent;
+ xid->root = ecore_window_get_root(parent);
+ xid->children_num = 0;
+ xid->children = NULL;
+ xid->gravity = ecore_window_get_gravity(win);
+ xid->coords_invalid = 0;
+ xid->bw = 0;
+ xid->grab_button_auto_replay = NULL;
+ XSaveContext(disp, xid->win, xid_context, (XPointer) xid);
+ ecore_add_child(parent, win);
+ return xid;
+}
+
+Ecore_XID *
+ecore_validate_xid(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return NULL;
+ if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
+ {
+ XWindowAttributes att;
+ Window root_ret = 0, parent_ret = 0, *children_ret = NULL;
+ unsigned int children_ret_num = 0;
+
+ ecore_window_add_events(win, XEV_IN_OUT | XEV_CONFIGURE |
+ XEV_VISIBILITY | XEV_CHILD_CHANGE);
+ xid = NEW(Ecore_XID, 1);
+ xid->win = win;
+ if (!XGetWindowAttributes(disp, win, &att))
+ {
+ FREE(xid);
+ return NULL;
+ }
+ if (!XQueryTree(disp, win, &root_ret, &parent_ret, &children_ret,
+ &children_ret_num))
+ {
+ FREE(xid);
+ return NULL;
+ }
+ xid->parent = parent_ret;
+ if (xid->parent)
+ ecore_validate_xid(xid->parent);
+ if (children_ret)
+ {
+ xid->children_num = children_ret_num;
+ xid->children = NEW(Window, children_ret_num);
+ MEMCPY(children_ret, xid->children, Window, children_ret_num);
+ XFree(children_ret);
+ }
+ else
+ {
+ xid->children_num = 0;
+ xid->children = NULL;
+ }
+ xid->root = root_ret;
+ xid->x = att.x;
+ xid->y = att.y;
+ xid->w = att.width;
+ xid->h = att.height;
+ if (att.map_state == IsUnmapped)
+ xid->mapped = 0;
+ else
+ xid->mapped = 1;
+ xid->depth = att.depth;
+ xid->mouse_in = 0;
+ xid->gravity = att.win_gravity;
+ xid->bw = att.border_width;
+ xid->coords_invalid = 0;
+ xid->grab_button_auto_replay = NULL;
+ XSaveContext(disp, xid->win, xid_context, (XPointer) xid);
+ ecore_add_child(xid->parent, win);
+ }
+ return xid;
+}
+
+void
+ecore_unvalidate_xid(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
+ return;
+ if (xid)
+ {
+ int i;
+
+ for (i = 0; i < xid->children_num; i++)
+ ecore_unvalidate_xid(xid->children[i]);
+ ecore_del_child(xid->parent, win);
+ IF_FREE(xid->children);
+ FREE(xid);
+ XDeleteContext(disp, win, xid_context);
+ }
+}
+
+void
+ecore_sync(void)
+{
+ if (!disp)
+ return;
+
+ XSync(disp, False);
+}
+
+void
+ecore_flush(void)
+{
+ if (!disp)
+ return;
+ XFlush(disp);
+}
+
+Window
+ecore_window_new(Window parent, int x, int y, int w, int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ if (!disp)
+ return 0;
+ if (!parent)
+ parent = default_root;
+ attr.backing_store = NotUseful;
+ attr.override_redirect = False;
+ attr.colormap = default_cm;
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.save_under = False;
+ attr.do_not_propagate_mask = True;
+ win = XCreateWindow(disp, parent,
+ x, y, w, h, 0,
+ default_depth, InputOutput, default_vis,
+ CWOverrideRedirect | CWSaveUnder | CWBackingStore |
+ CWColormap | CWBackPixmap | CWBorderPixel |
+ CWDontPropagate, &attr);
+ ecore_add_xid(win, x, y, w, h, default_depth, parent);
+ ecore_add_child(parent, win);
+ ecore_validate_xid(parent);
+ return win;
+}
+
+Window
+ecore_window_override_new(Window parent, int x, int y, int w, int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ if (!disp)
+ return 0;
+ if (!parent)
+ parent = default_root;
+ attr.backing_store = NotUseful;
+ attr.override_redirect = True;
+ attr.colormap = default_cm;
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.save_under = False;
+ attr.do_not_propagate_mask = True;
+ win = XCreateWindow(disp, parent,
+ x, y, w, h, 0,
+ default_depth, InputOutput, default_vis,
+ CWOverrideRedirect | CWSaveUnder | CWBackingStore |
+ CWColormap | CWBackPixmap | CWBorderPixel |
+ CWDontPropagate, &attr);
+ ecore_add_xid(win, x, y, w, h, default_depth, parent);
+ ecore_add_child(parent, win);
+ ecore_validate_xid(parent);
+ return win;
+}
+
+Window
+ecore_window_input_new(Window parent, int x, int y, int w, int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ if (!disp)
+ return 0;
+ if (!parent)
+ parent = default_root;
+ attr.override_redirect = True;
+ attr.do_not_propagate_mask = True;
+ win = XCreateWindow(disp, parent,
+ x, y, w, h, 0,
+ 0, InputOnly, default_vis,
+ CWOverrideRedirect | CWDontPropagate, &attr);
+ ecore_add_xid(win, x, y, w, h, 0, parent);
+ ecore_add_child(parent, win);
+ ecore_validate_xid(parent);
+ return win;
+}
+
+void
+ecore_window_set_events_propagate(Window win, int propagate)
+{
+ XSetWindowAttributes attr;
+
+ if (!disp)
+ return;
+ if (!win)
+ win = default_root;
+ if (!propagate)
+ attr.do_not_propagate_mask = True;
+ else
+ attr.do_not_propagate_mask = False;
+ XChangeWindowAttributes(disp, win, CWDontPropagate, &attr);
+}
+
+void
+ecore_window_show(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ if (xid->mapped)
+ return;
+ xid->mapped = 1;
+ XMapWindow(disp, win);
+ }
+}
+
+void
+ecore_window_hide(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp)
+ return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ if (!xid->mapped)
+ return;
+ xid->mapped = 0;
+ XUnmapWindow(disp, win);
+ }
+}
+
+Pixmap
+ecore_pixmap_new(Window win, int w, int h, int dep)
+{
+ if (!disp)
+ return 0;
+ if (!win)
+ win = default_win;
+ if (dep == 0)
+ dep = default_depth;
+ return XCreatePixmap(disp, win, w, h, dep);
+}
+
+void
+ecore_pixmap_free(Pixmap pmap)
+{
+ if (!disp)
+ return;
+ if (!pmap)
+ return;
+ XFreePixmap(disp, pmap);
+}
+
+void
+ecore_window_set_background_pixmap(Window win, Pixmap pmap)
+{
+ if (!disp)
+ return;
+ if (win == 0)
+ win = default_root;
+ XSetWindowBackgroundPixmap(disp, win, pmap);
+}
+
+void
+ecore_window_set_shape_mask(Window win, Pixmap mask)
+{
+ if (!disp)
+ return;
+ XShapeCombineMask(disp, win, ShapeBounding, 0, 0, mask, ShapeSet);
+}
+
+void
+ecore_window_add_shape_mask(Window win, Pixmap mask)
+{
+ if (!disp)
+ return;
+ XShapeCombineMask(disp, win, ShapeBounding, 0, 0, mask, ShapeUnion);
+}
+
+void
+ecore_window_set_shape_window(Window win, Window src, int x, int y)
+{
+ if (!disp)
+ return;
+ XShapeCombineShape(disp, win, ShapeBounding, x, y, src, ShapeBounding,
+ ShapeSet);
+}
+
+void
+ecore_window_add_shape_window(Window win, Window src, int x, int y)
+{
+ if (!disp)
+ return;
+ XShapeCombineShape(disp, win, ShapeBounding, x, y, src, ShapeBounding,
+ ShapeUnion);
+}
+
+void
+ecore_window_set_shape_rectangle(Window win, int x, int y, int w, int h)
+{
+ XRectangle rect;
+
+ if (!disp)
+ return;
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeSet,
+ Unsorted);
+}
+
+void
+ecore_window_add_shape_rectangle(Window win, int x, int y, int w, int h)
+{
+ XRectangle rect;
+
+ if (!disp)
+ return;
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeUnion,
+ Unsorted);
+}
+
+void
+ecore_window_set_shape_rectangles(Window win, XRectangle * rect, int num)
+{
+ if (!disp)
+ return;
+ XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rect, num, ShapeSet,
+ Unsorted);
+}
+
+void
+ecore_window_add_shape_rectangles(Window win, XRectangle * rect, int num)
+{
+ if (!disp)
+ return;
+ XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rect, num, ShapeUnion,
+ Unsorted);
+}
+
+void
+ecore_window_clip_shape_by_rectangle(Window win, int x, int y, int w, int h)
+{
+ XRectangle rect;
+
+ if (!disp)
+ return;
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &rect, 1,
+ ShapeIntersect, Unsorted);
+}
+
+XRectangle *
+ecore_window_get_shape_rectangles(Window win, int *num)
+{
+ int ord;
+
+ if (!disp)
+ return NULL;
+ return XShapeGetRectangles(disp, win, ShapeBounding, num, &ord);
+}
+
+void
+ecore_window_select_shape_events(Window win)
+{
+ if (!disp)
+ return;
+
+ XShapeSelectInput(disp, win, ShapeNotifyMask);
+}
+
+void
+ecore_window_unselect_shape_events(Window win)
+{
+ if (!disp)
+ return;
+
+ XShapeSelectInput(disp, win, 0);
+}
+
+void
+ecore_window_clear(Window win)
+{
+ if (!disp)
+ return;
+ if (win == 0)
+ win = default_root;
+ XClearWindow(disp, win);
+}
+
+void
+ecore_window_clear_area(Window win, int x, int y, int w, int h)
+{
+ if (!disp)
+ return;
+ if (win == 0)
+ win = default_root;
+ XClearArea(disp, win, x, y, w, h, False);
+}
+
+void
+ecore_pointer_xy(Window win, int *x, int *y)
+{
+ Window dw;
+ unsigned int dm;
+ int wx, wy;
+
+ if (!disp)
+ return;
+
+ if (win == 0)
+ win = default_root;
+
+ XQueryPointer(disp, win, &dw, &dw, &mouse_x, &mouse_y, &wx, &wy, &dm);
+
+ if (x)
+ *x = wx;
+ if (y)
+ *y = wy;
+}
+
+void
+ecore_pointer_xy_set(int x, int y)
+{
+ if (!disp) return;
+ mouse_x = x;
+ mouse_y = y;
+}
+
+void
+ecore_pointer_xy_get(int *x, int *y)
+{
+ if (!disp) return;
+ if (x)
+ *x = mouse_x;
+ if (y)
+ *y = mouse_y;
+}
+
+void
+ecore_window_set_events(Window win, long mask)
+{
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ XSelectInput(disp, win, mask);
+}
+
+void
+ecore_window_remove_events(Window win, long mask)
+{
+ XWindowAttributes att;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ if (XGetWindowAttributes(disp, win, &att) == True)
+ {
+ mask = att.your_event_mask & (~mask);
+ ecore_window_set_events(win, mask);
+ }
+}
+
+void
+ecore_window_add_events(Window win, long mask)
+{
+ XWindowAttributes att;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ if (XGetWindowAttributes(disp, win, &att) == True)
+ {
+ mask = att.your_event_mask | mask;
+ ecore_window_set_events(win, mask);
+ }
+}
+
+void
+ecore_window_move(Window win, int x, int y)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ if (!xid->coords_invalid)
+ {
+ if ((xid->x == x) && (xid->y == y))
+ return;
+ }
+ xid->x = x;
+ xid->y = y;
+ xid->coords_invalid = 0;
+ XMoveWindow(disp, win, x, y);
+ }
+}
+
+#define REGRAVITATE \
+if (xid->children) \
+{ \
+ int j; \
+\
+ for (j = 0; j < xid->children_num; j++) \
+ { \
+ Ecore_XID *xid2; \
+\
+ xid2 = ecore_validate_xid(xid->children[j]); \
+ if (xid2) \
+ { \
+ xid2->coords_invalid = 1; \
+ } \
+ } \
+}
+
+#if 0
+switch (xid2->gravity)
+ {
+ case UnmapGravity:
+ xid2->mapped = 0;
+ break;
+ case NorthWestGravity:
+ break;
+ case NorthGravity:
+ xid2->x += (w - xid->w) / 2;
+ break;
+ case NorthEastGravity:
+ xid2->x += (w - xid->w);
+ break;
+ case WestGravity:
+ xid2->h += (h - xid->h) / 2;
+ break;
+ case CenterGravity:
+ xid2->x += (w - xid->w) / 2;
+ xid2->h += (h - xid->h) / 2;
+ break;
+ case EastGravity:
+ xid2->x += (w - xid->w);
+ break;
+ case SouthWestGravity:
+ xid2->y += (h - xid->h);
+ break;
+ case SouthGravity:
+ xid2->x += (w - xid->w) / 2;
+ xid2->y += (h - xid->h);
+ break;
+ case SouthEastGravity:
+ xid2->x += (w - xid->w);
+ xid2->y += (h - xid->h);
+ break;
+ case StaticGravity:
+ xid2->coords_invalid = 1;
+ break;
+ default:
+ break;
+ }
+}
+}
+}
+#endif
+
+void
+ecore_window_resize(Window win, int w, int h)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ if (!xid->coords_invalid)
+ {
+ if ((xid->w == w) && (xid->h == h))
+ return;
+ }
+ REGRAVITATE;
+ xid->w = w;
+ xid->h = h;
+ xid->coords_invalid = 0;
+ XResizeWindow(disp, win, w, h);
+ }
+}
+
+void
+ecore_window_move_resize(Window win, int x, int y, int w, int h)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ if (!xid->coords_invalid)
+ {
+ if ((xid->x == x) && (xid->y == y) && (xid->w == w) && (xid->h == h))
+ return;
+ }
+ REGRAVITATE;
+ xid->x = x;
+ xid->y = y;
+ xid->w = w;
+ xid->h = h;
+ xid->coords_invalid = 0;
+ XMoveResizeWindow(disp, win, x, y, w, h);
+ }
+}
+
+int
+ecore_x_get_fd(void)
+{
+ if (!disp) return 0;
+ return ConnectionNumber(disp);
+}
+
+void
+ecore_set_error_handler(Ecore_Error_Function func)
+{
+ if (!disp) return;
+ XSetErrorHandler((XErrorHandler) func);
+}
+
+void
+ecore_reset_error_handler(void)
+{
+ if (!disp) return;
+ XSetErrorHandler((XErrorHandler) ecore_handle_x_error);
+}
+
+int
+ecore_display_init(char *display)
+{
+ int revert;
+
+ xid_context = XUniqueContext();
+ disp = XOpenDisplay(display);
+ if (!disp)
+ {
+ char *d;
+
+ d = getenv("DISPLAY");
+/* no need for this anymore
+ if (d)
+ fprintf(stderr,
+ "Fatal Error:\n"
+ "Cannot connect to the display nominated by your DISPLAY variable:\n"
+ "%s\n"
+ "Try changing your DISPLAY variable like:\n"
+ "DISPLAY=host:0 application_name\n", d);
+ else
+ fprintf(stderr,
+ "Fatal Error:\n"
+ "No DISPLAY variable set so cannot determine display to connect to.\n"
+ "Try setting your DISPLAY variable like:\n"
+ "DISPLAY=host:0 appication_name\n");
+*/
+ return 0;
+ }
+ XSetErrorHandler((XErrorHandler) ecore_handle_x_error);
+ XSetIOErrorHandler((XIOErrorHandler) ecore_handle_x_io_error);
+ default_vis = DefaultVisual(disp, DefaultScreen(disp));
+ default_depth = DefaultDepth(disp, DefaultScreen(disp));
+ default_cm = DefaultColormap(disp, DefaultScreen(disp));
+ default_win = DefaultRootWindow(disp);
+ default_root = DefaultRootWindow(disp);
+ mod_shift = ecore_mod_mask_shift_get();
+ mod_ctrl = ecore_mod_mask_ctrl_get();
+ mod_alt = ecore_mod_mask_alt_get();
+ mod_win = ecore_mod_mask_win_get();
+ XGetInputFocus(disp, &focused_win, &revert);
+ ecore_window_set_events(default_root, XEV_KEY | XEV_IN_OUT | XEV_MOUSE_MOVE |
+ XEV_CONFIGURE | XEV_CHILD_CHANGE | XEV_PROPERTY |
+ XEV_COLORMAP | XEV_VISIBILITY);
+ ecore_pointer_xy(0, NULL, NULL);
+ return 1;
+}
+
+int
+ecore_events_pending(void)
+{
+ if (!disp) return 0;
+ return XPending(disp);
+}
+
+void
+ecore_get_next_event(XEvent * event)
+{
+ if (!disp) return;
+ XNextEvent(disp, event);
+}
+
+int
+ecore_event_shape_get_id(void)
+{
+ int base = -1, err_base;
+
+ if (!disp) return 0;
+ XShapeQueryExtension(disp, &base, &err_base);
+ base += ShapeNotify;
+ return base;
+}
+
+KeySym
+ecore_key_get_keysym_from_keycode(KeyCode keycode)
+{
+ if (!disp) return 0;
+ return XKeycodeToKeysym(disp, keycode, 0);
+}
+
+char *
+ecore_key_get_string_from_keycode(KeyCode keycode)
+{
+ char *str;
+
+ if (!disp) return strdup("");
+ str = XKeysymToString(ecore_key_get_keysym_from_keycode(keycode));
+ if (!str)
+ return strdup("");
+ return strdup(str);
+}
+
+void
+ecore_event_allow(int mode, Time t)
+{
+ if (!disp) return;
+ XAllowEvents(disp, mode, t);
+}
+
+int
+ecore_lock_mask_scroll_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Scroll_Lock);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_lock_mask_num_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Num_Lock);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_lock_mask_caps_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Caps_Lock);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_mod_mask_shift_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Shift_L);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_mod_mask_ctrl_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Control_L);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_mod_mask_alt_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Alt_L);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_mod_mask_win_get(void)
+{
+ static int have_mask = 0;
+ static int mask = 0;
+ XModifierKeymap *mod;
+ KeyCode nl;
+ int i;
+ int masks[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask,
+ Mod4Mask, Mod5Mask
+ };
+
+ if (!disp) return 0;
+ if (have_mask)
+ return mask;
+ mod = XGetModifierMapping(disp);
+ nl = XKeysymToKeycode(disp, XK_Meta_L);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ if ((nl) && (mod->modifiermap[i] == nl))
+ {
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ if (mask == ecore_mod_mask_alt_get())
+ mask = 0;
+ if (mask == ecore_mod_mask_ctrl_get())
+ mask = 0;
+ have_mask = 1;
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap)
+ XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+int
+ecore_lock_mask_get(void)
+{
+ static int mask = 0;
+ Window root_ret, child_ret;
+ int root_x_ret, root_y_ret, win_x_ret, win_y_ret;
+ unsigned int mask_ret;
+
+ if (!disp) return 0;
+ if (!mask)
+ mask = ecore_lock_mask_scroll_get() | ecore_lock_mask_num_get() |
+ ecore_lock_mask_caps_get();
+ XQueryPointer(disp, default_root, &root_ret, &child_ret, &root_x_ret,
+ &root_y_ret, &win_x_ret, &win_y_ret, &mask_ret);
+ return (mask_ret & mask);
+}
+
+int
+ecore_modifier_mask_get(void)
+{
+ Window root_ret, child_ret;
+ int root_x_ret, root_y_ret, win_x_ret, win_y_ret;
+ unsigned int mask_ret;
+
+ if (!disp) return 0;
+ XQueryPointer(disp, default_root, &root_ret, &child_ret, &root_x_ret,
+ &root_y_ret, &win_x_ret, &win_y_ret, &mask_ret);
+ return (mask_ret);
+}
+
+Window
+ecore_get_key_grab_win(void)
+{
+ if (!disp) return 0;
+ return grabkey_win;
+}
+
+void
+ecore_key_grab(char *key, Ecore_Event_Key_Modifiers mods, int anymod, int sync)
+{
+ KeyCode keycode;
+ int i, mod, mask_scroll, mask_num, mask_caps, masks[8], mode;
+
+ if (!disp) return;
+ keycode = ecore_key_get_keycode(key);
+ mod = 0;
+ mode = GrabModeAsync;
+ if (sync)
+ mode = GrabModeSync;
+ if (!grabkey_win)
+ grabkey_win = default_root;
+ if (mods & ECORE_EVENT_KEY_MODIFIER_SHIFT)
+ mod |= ecore_mod_mask_shift_get();
+ if (mods & ECORE_EVENT_KEY_MODIFIER_CTRL)
+ mod |= ecore_mod_mask_ctrl_get();
+ if (mods & ECORE_EVENT_KEY_MODIFIER_ALT)
+ mod |= ecore_mod_mask_alt_get();
+ if (mods & ECORE_EVENT_KEY_MODIFIER_WIN)
+ mod |= ecore_mod_mask_win_get();
+ mask_scroll = ecore_lock_mask_scroll_get();
+ mask_num = ecore_lock_mask_num_get();
+ mask_caps = ecore_lock_mask_caps_get();
+ masks[0] = 0;
+ masks[1] = mask_scroll;
+ masks[2] = mask_num;
+ masks[3] = mask_caps;
+ masks[4] = mask_scroll | mask_num;
+ masks[5] = mask_scroll | mask_caps;
+ masks[6] = mask_num | mask_caps;
+ masks[7] = mask_scroll | mask_num | mask_caps;
+ if (anymod)
+ XGrabKey(disp, keycode, AnyModifier, grabkey_win, False, mode, mode);
+ else
+ {
+ for (i = 0; i < 8; i++)
+ XGrabKey(disp, keycode, masks[i] | mod, grabkey_win, False, mode, mode);
+ }
+}
+
+void
+ecore_key_ungrab(char *key, Ecore_Event_Key_Modifiers mods, int anymod)
+{
+ KeyCode keycode;
+
+ if (!disp) return;
+ keycode = ecore_key_get_keycode(key);
+ if (anymod)
+ XUngrabKey(disp, keycode, AnyModifier, default_root);
+ else
+ {
+ int i, mod, mask_scroll, mask_num, mask_caps, masks[8];
+
+ mod = 0;
+ if (mods & ECORE_EVENT_KEY_MODIFIER_SHIFT)
+ mod |= ecore_mod_mask_shift_get();
+ if (mods & ECORE_EVENT_KEY_MODIFIER_CTRL)
+ mod |= ecore_mod_mask_ctrl_get();
+ if (mods & ECORE_EVENT_KEY_MODIFIER_ALT)
+ mod |= ecore_mod_mask_alt_get();
+ if (mods & ECORE_EVENT_KEY_MODIFIER_WIN)
+ mod |= ecore_mod_mask_win_get();
+ mask_scroll = ecore_lock_mask_scroll_get();
+ mask_num = ecore_lock_mask_num_get();
+ mask_caps = ecore_lock_mask_caps_get();
+ masks[0] = 0;
+ masks[1] = mask_scroll;
+ masks[2] = mask_num;
+ masks[3] = mask_caps;
+ masks[4] = mask_scroll | mask_num;
+ masks[5] = mask_scroll | mask_caps;
+ masks[6] = mask_num | mask_caps;
+ masks[7] = mask_scroll | mask_num | mask_caps;
+ for (i = 0; i < 8; i++)
+ XUngrabKey(disp, keycode, masks[i] | mod, grabkey_win);
+ }
+}
+
+KeyCode
+ecore_key_get_keycode(char *key)
+{
+ if (!disp) return 0;
+ return XKeysymToKeycode(disp, XStringToKeysym(key));
+}
+
+void
+ecore_window_destroy(Window win)
+{
+ if (!disp) return;
+ ecore_unvalidate_xid(win);
+ XDestroyWindow(disp, win);
+}
+
+void
+ecore_window_reparent(Window win, Window parent, int x, int y)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ if (parent == 0)
+ parent = default_root;
+ XReparentWindow(disp, win, parent, x, y);
+ ecore_del_child(xid->parent, win);
+ ecore_add_child(parent, win);
+ xid->parent = parent;
+ xid->x = x;
+ xid->y = y;
+ }
+}
+
+void
+ecore_window_raise(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ XRaiseWindow(disp, win);
+ ecore_raise_child(xid->parent, win);
+ }
+}
+
+void
+ecore_window_lower(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ XLowerWindow(disp, win);
+ ecore_lower_child(xid->parent, win);
+ }
+}
+
+void
+ecore_window_get_geometry(Window win, int *x, int *y, int *w, int *h)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ xid = ecore_validate_xid(win);
+ if ((xid) && (xid->coords_invalid))
+ {
+ Window dw;
+ int rx, ry;
+ unsigned int rw, rh, di;
+
+ XGetGeometry(disp, win, &dw, &rx, &ry, &rw, &rh, &di, &di);
+ xid->x = rx;
+ xid->y = ry;
+ xid->w = (int)rw;
+ xid->h = (int)rh;
+ xid->coords_invalid = 0;
+ }
+ if (xid)
+ {
+ if (x)
+ *x = xid->x;
+ if (y)
+ *y = xid->y;
+ if (w)
+ *w = xid->w;
+ if (h)
+ *h = xid->h;
+ }
+ else
+ {
+ if (x)
+ *x = 0;
+ if (y)
+ *y = 0;
+ if (w)
+ *w = 0;
+ if (h)
+ *h = 0;
+ }
+}
+
+int
+ecore_window_get_depth(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return 0;
+ if (win == 0)
+ win = default_root;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ return xid->depth;
+ return -1;
+}
+
+int
+ecore_window_exists(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return 0;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ return 1;
+ return 0;
+}
+
+Window
+ecore_window_get_parent(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return 0;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ return xid->parent;
+ return 0;
+}
+
+Window *
+ecore_window_get_children(Window win, int *num)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return NULL;
+ if (win == 0)
+ win = default_root;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ Window *wlist = NULL;
+
+ *num = xid->children_num;
+ if (xid->children)
+ {
+ wlist = NEW(Window, xid->children_num);
+ MEMCPY(xid->children, wlist, Window, xid->children_num);
+ }
+ return wlist;
+ }
+ *num = 0;
+ return NULL;
+}
+
+int
+ecore_window_mouse_in(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return 0;
+ if (win == 0)
+ win = default_root;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ return xid->mouse_in;
+ return 0;
+}
+
+void
+ecore_window_mouse_set_in(Window win, int in)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ xid->mouse_in = in;
+}
+
+Display *
+ecore_display_get(void)
+{
+ return disp;
+}
+
+Window
+ecore_window_get_root(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return 0;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ return xid->root;
+ return 0;
+}
+
+void
+ecore_lock_scroll_set(int onoff)
+{
+ lock_scroll = onoff;
+}
+
+int
+ecore_lock_scroll_get(void)
+{
+ return lock_scroll;
+}
+
+void
+ecore_lock_num_set(int onoff)
+{
+ lock_num = onoff;
+}
+
+int
+ecore_lock_num_get(void)
+{
+ return lock_num;
+}
+
+void
+ecore_lock_caps_set(int onoff)
+{
+ lock_caps = onoff;
+}
+
+int
+ecore_lock_caps_get(void)
+{
+ return lock_caps;
+}
+
+void
+ecore_mod_shift_set(int onoff)
+{
+ mod_shift = onoff;
+}
+
+int
+ecore_mod_shift_get(void)
+{
+ return mod_shift;
+}
+
+void
+ecore_mod_ctrl_set(int onoff)
+{
+ mod_ctrl = onoff;
+}
+
+int
+ecore_mod_ctrl_get(void)
+{
+ return mod_ctrl;
+}
+
+void
+ecore_mod_alt_set(int onoff)
+{
+ mod_alt = onoff;
+}
+
+int
+ecore_mod_alt_get(void)
+{
+ return mod_alt;
+}
+
+void
+ecore_mod_win_set(int onoff)
+{
+ mod_win = onoff;
+}
+
+int
+ecore_mod_win_get(void)
+{
+ return mod_win;
+}
+
+void
+ecore_focus_window_set(Window win)
+{
+ focused_win = win;
+}
+
+Window
+ecore_focus_window_get(void)
+{
+ return focused_win;
+}
+
+void
+ecore_focus_to_window(Window win)
+{
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ XSetInputFocus(disp, win, RevertToNone, CurrentTime);
+}
+
+void
+ecore_focus_mode_reset(void)
+{
+ if (!disp) return;
+ XSetInputFocus(disp, default_root, RevertToPointerRoot, CurrentTime);
+}
+
+Atom
+ecore_atom_get(char *name)
+{
+ if (!disp) return 0;
+ return XInternAtom(disp, name, False);
+}
+
+void
+ecore_window_set_delete_inform(Window win)
+{
+ static Atom protocols[1] = { 0 };
+
+ if (!disp) return;
+ ECORE_ATOM(protocols[0], "WM_DELETE_WINDOW");
+ XSetWMProtocols(disp, win, protocols, 1);
+}
+
+void
+ecore_window_property_set(Window win, Atom type, Atom format, int size,
+ void *data, int number)
+{
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ if (size != 32)
+ XChangeProperty(disp, win, type, format, size, PropModeReplace,
+ (unsigned char *)data, number);
+ else
+ {
+ long *dat;
+ int i, *ptr;
+
+ dat = NEW(long, number);
+
+ for (ptr = (int *)data, i = 0; i < number; i++)
+ dat[i] = ptr[i];
+ XChangeProperty(disp, win, type, format, size, PropModeReplace,
+ (unsigned char *)dat, number);
+ FREE(dat);
+ }
+}
+
+void *
+ecore_window_property_get(Window win, Atom type, Atom format, int *size)
+{
+ unsigned char *retval;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ void *data = NULL;
+
+ if (!disp)
+ return NULL;
+
+ retval = NULL;
+ if (win == 0)
+ win = default_root;
+ XGetWindowProperty(disp, win, type, 0, 0x7fffffffL, False, format,
+ &type_ret, &format_ret, &num_ret, &bytes_after, &retval);
+ if (retval)
+ {
+ if (format_ret == 32)
+ {
+ int i;
+
+ *size = num_ret * sizeof(unsigned int);
+
+ data = NEW(unsigned int, num_ret);
+
+ for (i = 0; i < (int)num_ret; i++)
+ ((unsigned int *)data)[i] = ((unsigned long *)retval)[i];
+ }
+ else if (format_ret == 16)
+ {
+ int i;
+
+ *size = num_ret * sizeof(unsigned short);
+
+ data = NEW(unsigned short, *size);
+
+ for (i = 0; i < (int)num_ret; i++)
+ ((unsigned short *)data)[i] = ((unsigned short *)retval)[i];
+ }
+ else if (format_ret == 8)
+ {
+ /* format_ret == 8 */
+ *size = num_ret;
+ data = NEW(char, num_ret);
+
+ if (data)
+ memcpy(data, retval, num_ret);
+ }
+ XFree(retval);
+ return data;
+ }
+ *size = 0;
+ return NULL;
+}
+
+void
+ecore_window_dnd_advertise(Window win)
+{
+ static Atom atom_xdndaware = 0;
+ int dnd_version = 3;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndaware, "XdndAware");
+ ecore_window_property_set(win, atom_xdndaware, XA_ATOM, 32, &dnd_version, 1);
+}
+
+void
+ecore_grab(void)
+{
+ if (!disp)
+ return;
+
+ x_grabs++;
+
+ if (x_grabs == 1)
+ XGrabServer(disp);
+}
+
+void
+ecore_ungrab(void)
+{
+ if (!disp)
+ return;
+
+ x_grabs--;
+
+ if (x_grabs == 0)
+ {
+ XUngrabServer(disp);
+ ecore_sync();
+ }
+}
+
+void
+ecore_window_ignore(Window win)
+{
+ Window_List *w;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ w = NEW(Window_List, 1);
+ w->win = win;
+ w->next = ignore_wins;
+ ignore_wins = w;
+}
+
+void
+ecore_window_no_ignore(Window win)
+{
+ Window_List *w, *pw;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ for (pw = NULL, w = ignore_wins; w; pw = w, w = w->next)
+ {
+ if (w->win == win)
+ {
+ if (pw)
+ pw->next = w->next;
+ else
+ ignore_wins = w->next;
+ FREE(w);
+ return;
+ }
+ }
+}
+
+int
+ecore_window_is_ignored(Window win)
+{
+ Window_List *w;
+
+ if (!disp) return 0;
+ if (win == 0)
+ win = default_root;
+ for (w = ignore_wins; w; w = w->next)
+ {
+ if (w->win == win)
+ return 1;
+ }
+ return 0;
+}
+
+static Window
+ecore_window_at_xy_0(Window base, int bx, int by, int x, int y)
+{
+ Window *list = NULL;
+ XWindowAttributes att;
+ Window child = 0, parent_win = 0, root_win = 0;
+ int i;
+ unsigned int ww, wh, num;
+ int wx, wy;
+
+ if (!disp) return 0;
+ if ((!XGetWindowAttributes(disp, base, &att)) ||
+ (att.map_state != IsViewable))
+ return 0;
+
+ wx = att.x;
+ wy = att.y;
+ ww = att.width;
+ wh = att.height;
+
+ wx += bx;
+ wy += by;
+
+ if (!((x >= wx) && (y >= wy) && (x < (int)(wx + ww)) && (y < (int)(wy + wh))))
+ return 0;
+
+ if (!XQueryTree(disp, base, &root_win, &parent_win, &list, &num))
+ return base;
+ if (list)
+ {
+ for (i = num - 1;; i--)
+ {
+ if (!ecore_window_is_ignored(list[i]))
+ {
+ if ((child = ecore_window_at_xy_0(list[i], wx, wy, x, y)) != 0)
+ {
+ XFree(list);
+ return child;
+ }
+ }
+ if (!i)
+ break;
+ }
+ XFree(list);
+ }
+ return base;
+}
+
+Window
+ecore_window_get_at_xy(int x, int y)
+{
+ Window child;
+
+ if (!disp) return 0;
+ ecore_grab();
+ child = ecore_window_at_xy_0(default_root, 0, 0, x, y);
+ if (child)
+ {
+ ecore_ungrab();
+ return child;
+ }
+ ecore_ungrab();
+ return default_root;
+}
+
+int
+ecore_window_dnd_capable(Window win)
+{
+ static Atom atom_xdndaware = 0;
+ int dnd_version = 3;
+ int *atom_ret;
+ int size = 0;
+
+ if (!disp) return 0;
+ ECORE_ATOM(atom_xdndaware, "XdndAware");
+ atom_ret = ecore_window_property_get(win, atom_xdndaware, XA_ATOM, &size);
+ if ((atom_ret) && (size >= (int)sizeof(int)))
+ {
+ if (atom_ret[0] == dnd_version)
+ {
+ FREE(atom_ret);
+ return 1;
+ }
+ FREE(atom_ret);
+ }
+ return 0;
+}
+
+void
+ecore_window_dnd_handle_motion(Window source_win, int x, int y, int dragging)
+{
+ static Atom atom_xdndenter = 0;
+ static Atom atom_xdndleave = 0;
+ static Atom atom_xdnddrop = 0;
+ static Atom atom_xdndposition = 0;
+ static Atom atom_xdndactioncopy = 0;
+ static Atom atom_xdndactionmove = 0;
+ static Atom atom_xdndactionlink = 0;
+ static Atom atom_xdndactionask = 0;
+ static Atom atom_text_uri_list = 0;
+ static Atom atom_text_plain = 0;
+ static Atom atom_text_moz_url = 0;
+ static Atom atom_netscape_url = 0;
+ Window win;
+ XEvent xevent;
+
+ if (!disp) return;
+ win = ecore_window_get_at_xy(x, y);
+ while ((win) && (!ecore_window_dnd_capable(win)))
+ win = ecore_window_get_parent(win);
+ ECORE_ATOM(atom_xdndenter, "XdndEnter");
+ ECORE_ATOM(atom_xdndleave, "XdndLeave");
+ ECORE_ATOM(atom_xdnddrop, "XdndDrop");
+ ECORE_ATOM(atom_xdndposition, "XdndPosition");
+ ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy");
+ ECORE_ATOM(atom_xdndactionmove, "XdndActionMove");
+ ECORE_ATOM(atom_xdndactionlink, "XdndActionLink");
+ ECORE_ATOM(atom_xdndactionask, "XdndActionAsk");
+ ECORE_ATOM(atom_text_uri_list, "text/uri-list");
+ ECORE_ATOM(atom_text_plain, "text/plain");
+ ECORE_ATOM(atom_text_moz_url, "text/x-moz-url");
+ ECORE_ATOM(atom_netscape_url, "_NETSCAPE_URL");
+ if ((win != current_dnd_win) && (current_dnd_win))
+ {
+ /* send leave to old dnd win */
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.format = 32;
+ xevent.xclient.window = current_dnd_win;
+ xevent.xclient.message_type = atom_xdndleave;
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = 0;
+ xevent.xclient.data.l[2] = 0;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+ XSendEvent(disp, current_dnd_win, False, 0, &xevent);
+ }
+ if (win)
+ {
+ if (win != current_dnd_win)
+ {
+ /* send enter on new win */
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdndenter;
+ xevent.xclient.format = 32;
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = (3 << 24);
+ xevent.xclient.data.l[2] = atom_text_uri_list;
+ xevent.xclient.data.l[3] = atom_text_plain;
+ xevent.xclient.data.l[4] = atom_text_moz_url;
+ XSendEvent(disp, win, False, 0, &xevent);
+ ecore_clear_target_status();
+ }
+ /* kjb cep */
+ if(!dnd_await_target_status)
+ {
+ /* send position information */
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdndposition;
+ xevent.xclient.format = 32;
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = (3 << 24);
+ xevent.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
+ xevent.xclient.data.l[3] = CurrentTime;
+ if (dnd_copy)
+ xevent.xclient.data.l[4] = atom_xdndactioncopy;
+ else if (dnd_link)
+ xevent.xclient.data.l[4] = atom_xdndactionlink;
+ else if (dnd_move)
+ xevent.xclient.data.l[4] = atom_xdndactionmove;
+ else
+ xevent.xclient.data.l[4] = atom_xdndactionask;
+ XSendEvent(disp, win, False, 0, &xevent);
+ dnd_await_target_status = 1;
+ }
+ }
+ if (!dragging)
+ {
+ if (win)
+ {
+ if (current_dnd_target_ok)
+ {
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdnddrop;
+ xevent.xclient.format = 32;
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = 0;
+ xevent.xclient.data.l[2] = CurrentTime;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+ XSendEvent(disp, win, False, 0, &xevent);
+ }
+ else
+ {
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdndleave;
+ xevent.xclient.format = 32;
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = 0;
+ xevent.xclient.data.l[2] = 0;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+ XSendEvent(disp, win, False, 0, &xevent);
+ }
+ }
+ current_dnd_target_ok = 0;
+ }
+ current_dnd_win = win;
+}
+
+
+void
+ecore_clear_target_status(void)
+{
+ dnd_await_target_status = 0;
+}
+
+
+int
+ecore_dnd_selection_convert(Window win, Window req, Atom type)
+{
+ static Atom atom_xdndselection = 0;
+ static Atom atom_jxselectionwindowproperty = 0;
+
+ if (!disp) return 0;
+ ECORE_ATOM(atom_xdndselection, "XdndSelection");
+ ECORE_ATOM(atom_jxselectionwindowproperty, "JXSelectionWindowProperty");
+ if (win == XGetSelectionOwner(disp, atom_xdndselection))
+ {
+ XConvertSelection(disp, atom_xdndselection, type,
+ atom_jxselectionwindowproperty, req, CurrentTime);
+ return 1;
+ }
+ return 0;
+}
+
+void *
+ecore_dnd_selection_get(Window win, Window req, Atom type, int *size)
+{
+ unsigned char *data = NULL;
+ long bytes_read;
+ unsigned long remaining = 1;
+
+ if (!disp) return NULL;
+ *size = 0;
+ bytes_read = 0;
+ while (remaining)
+ {
+ unsigned char *s;
+ Atom actual;
+ int format;
+ unsigned long count;
+
+ s = NULL;
+ if (XGetWindowProperty(disp, win, type, bytes_read / 4, 0x10000, 1,
+ AnyPropertyType, &actual, &format, &count,
+ &remaining, &s) != Success)
+ {
+ /* error occured */
+ XFree(s);
+ IF_FREE(data);
+ *size = 0;
+ return NULL;
+ }
+ if (s)
+ {
+ /* got some mroe data - append it */
+ bytes_read += count;
+ if (!data)
+ data = NEW(char, bytes_read);
+
+ else
+ REALLOC(data, char, bytes_read);
+ MEMCPY(s, data + (bytes_read - count), char, count);
+
+ XFree(s);
+ }
+ }
+ *size = bytes_read;
+ return data;
+ req = 0;
+}
+
+void
+ecore_dnd_set_data(Window win)
+{
+ static Atom atom_xdndselection = 0;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndselection, "XdndSelection");
+ ecore_dnd_set_action(win);
+ XSetSelectionOwner(disp, atom_xdndselection, win, CurrentTime);
+}
+
+void
+ecore_dnd_set_action(Window win)
+{
+ static int atom_xdndactioncopy = 0;
+ static int atom_xdndactionmove = 0;
+ static int atom_xdndactionlink = 0;
+ static int atom_xdndactionask = 0;
+ static Atom atom_xdndactionlist = 0;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy");
+ ECORE_ATOM(atom_xdndactionmove, "XdndActionMove");
+ ECORE_ATOM(atom_xdndactionlink, "XdndActionLink");
+ ECORE_ATOM(atom_xdndactionask, "XdndActionAsk");
+ ECORE_ATOM(atom_xdndactionlist, "XdndActionList");
+ if (dnd_copy)
+ ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32,
+ &atom_xdndactioncopy, 1);
+ else if (dnd_link)
+ ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32,
+ &atom_xdndactionlink, 1);
+ else if (dnd_move)
+ ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32,
+ &atom_xdndactionmove, 1);
+ else
+ ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32,
+ &atom_xdndactionask, 1);
+}
+
+void
+ecore_dnd_send_data(Window win, Window source_win, void *data, int size,
+ Atom dest_atom, int type)
+{
+ XEvent xevent;
+ static Atom atom_text_plain = 0;
+ static Atom atom_text_uri_list = 0;
+ static Atom atom_text_moz_url = 0;
+ static Atom atom_netscape_url = 0;
+ static Atom atom_xdndselection = 0;
+ Atom target;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndselection, "XdndSelection");
+ ECORE_ATOM(atom_text_uri_list, "text/uri-list");
+ ECORE_ATOM(atom_text_plain, "text/plain");
+ ECORE_ATOM(atom_text_moz_url, "text/x-moz-url");
+ ECORE_ATOM(atom_text_moz_url, "_NETSCAPE_URL");
+ ECORE_ATOM(atom_text_plain, "text/plain");
+ if (type == DND_TYPE_URI_LIST) target = atom_text_uri_list;
+ else if (type == DND_TYPE_PLAIN_TEXT) target = atom_text_plain;
+ else if (type == DND_TYPE_MOZ_URL) target = atom_text_moz_url;
+ else if (type == DND_TYPE_NETSCAPE_URL) target = atom_netscape_url;
+ else target = 0;
+ ecore_window_property_set(win, dest_atom, target, 8, data, size);
+ xevent.xselection.type = SelectionNotify;
+ xevent.xselection.property = dest_atom;
+ xevent.xselection.display = disp;
+ xevent.xselection.requestor = win;
+ xevent.xselection.selection = atom_xdndselection;
+ xevent.xselection.target = target;
+ xevent.xselection.time = CurrentTime;
+ XSendEvent(disp, win, False, 0, &xevent);
+ return;
+ source_win = 0;
+}
+
+void
+ecore_dnd_set_mode_copy(void)
+{
+ dnd_copy = 1;
+ dnd_link = 0;
+ dnd_move = 0;
+}
+
+void
+ecore_dnd_set_mode_link(void)
+{
+ dnd_copy = 0;
+ dnd_link = 1;
+ dnd_move = 0;
+}
+
+void
+ecore_dnd_set_mode_move(void)
+{
+ dnd_copy = 0;
+ dnd_link = 0;
+ dnd_move = 1;
+}
+
+void
+ecore_dnd_set_mode_ask(void)
+{
+ dnd_copy = 0;
+ dnd_link = 0;
+ dnd_move = 0;
+}
+
+void
+ecore_dnd_own_selection(Window win)
+{
+ static Atom atom_xdndselection = 0;
+ static Atom atom_jxselectionwindowproperty = 0;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndselection, "XdndSelection");
+ ECORE_ATOM(atom_jxselectionwindowproperty, "JXSelectionWindowProperty");
+
+ if (!XSetSelectionOwner(disp, atom_xdndselection, win, CurrentTime))
+ return;
+}
+
+void
+ecore_dnd_send_drop(Window win, Window source_win)
+{
+ static Atom atom_xdnddrop = 0;
+ XEvent xevent;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdnddrop, "XdndDrop");
+
+ ecore_dnd_own_selection(source_win);
+
+ memset(&xevent, 0, sizeof(xevent));
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdnddrop;
+ xevent.xclient.format = 32;
+
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = CurrentTime;
+ xevent.xclient.data.l[2] = 0;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+ XSendEvent(disp, win, False, 0, &xevent);
+}
+
+void
+ecore_window_dnd_send_status_ok(Window source_win, Window win, int x, int y,
+ int w, int h)
+{
+ static Atom atom_xdndstatus = 0;
+ static Atom atom_xdndactioncopy = 0;
+ static Atom atom_xdndactionmove = 0;
+ static Atom atom_xdndactionlink = 0;
+ static Atom atom_xdndactionask = 0;
+ XEvent xevent;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndstatus, "XdndStatus");
+ ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy");
+ ECORE_ATOM(atom_xdndactionmove, "XdndActionMove");
+ ECORE_ATOM(atom_xdndactionlink, "XdndActionLink");
+ ECORE_ATOM(atom_xdndactionask, "XdndActionAsk");
+ memset(&xevent, 0, sizeof(xevent));
+
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdndstatus;
+ xevent.xclient.format = 32;
+
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = 3;
+ xevent.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
+ xevent.xclient.data.l[3] = ((h << 16) & 0xffff0000) | (w & 0xffff);
+ if (dnd_copy)
+ xevent.xclient.data.l[4] = atom_xdndactioncopy;
+ else if (dnd_link)
+ xevent.xclient.data.l[4] = atom_xdndactionlink;
+ else if (dnd_move)
+ xevent.xclient.data.l[4] = atom_xdndactionmove;
+ else
+ xevent.xclient.data.l[4] = atom_xdndactionask;
+ XSendEvent(disp, win, False, 0, &xevent);
+}
+
+void
+ecore_window_dnd_send_finished(Window source_win, Window win)
+{
+ static Atom atom_xdndfinished = 0;
+ XEvent xevent;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_xdndfinished, "XdndFinished");
+ memset(&xevent, 0, sizeof(xevent));
+
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = disp;
+ xevent.xclient.window = win;
+ xevent.xclient.message_type = atom_xdndfinished;
+ xevent.xclient.format = 32;
+
+ xevent.xclient.data.l[0] = source_win;
+ xevent.xclient.data.l[1] = 0;
+ xevent.xclient.data.l[2] = 0;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+ XSendEvent(disp, win, False, 0, &xevent);
+}
+
+void
+ecore_window_dnd_ok(int ok)
+{
+ current_dnd_target_ok = ok;
+}
+
+void
+ecore_window_dnd_finished(void)
+{
+ current_dnd_win = 0;
+}
+
+void
+ecore_window_set_title(Window win, char *title)
+{
+ if (!disp) return;
+ XStoreName(disp, win, title);
+}
+
+void
+ecore_window_set_name_class(Window win, char *name, char *class)
+{
+ XClassHint hint;
+
+ if (!disp) return;
+ hint.res_name = name;
+ hint.res_class = class;
+ XSetClassHint(disp, win, &hint);
+}
+
+void
+ecore_window_get_name_class(Window win, char **name, char **class)
+{
+ XClassHint xch;
+
+ if (!disp) return;
+ if (name)
+ *name = NULL;
+ if (class)
+ *class = NULL;
+ if (XGetClassHint(disp, win, &xch))
+ {
+ if (name)
+ {
+ if (xch.res_name)
+ *name = strdup(xch.res_name);
+ }
+ if (class)
+ {
+ if (xch.res_class)
+ *class = strdup(xch.res_class);
+ }
+ XFree(xch.res_name);
+ XFree(xch.res_class);
+ }
+}
+
+void
+ecore_window_get_hints(Window win, int *accepts_focus, int *initial_state,
+ Pixmap * icon_pixmap, Pixmap * icon_mask,
+ Window * icon_window, Window * window_group)
+{
+ XWMHints *hints;
+
+ if (!disp) return;
+ hints = XGetWMHints(disp, win);
+ if (hints)
+ {
+ if ((hints->flags & InputHint) && (accepts_focus))
+ {
+ if (hints->input)
+ *accepts_focus = 1;
+ else
+ *accepts_focus = 0;
+ }
+ if ((hints->flags & StateHint) && (initial_state))
+ {
+ *initial_state = hints->initial_state;
+ }
+ if ((hints->flags & IconPixmapHint) && (icon_pixmap))
+ {
+ *icon_pixmap = hints->icon_pixmap;
+ }
+ if ((hints->flags & IconMaskHint) && (icon_mask))
+ {
+ *icon_mask = hints->icon_pixmap;
+ }
+ if ((hints->flags & IconWindowHint) && (icon_window))
+ {
+ *icon_window = hints->icon_window;
+ }
+ if ((hints->flags & WindowGroupHint) && (window_group))
+ {
+ *window_group = hints->window_group;
+ }
+ XFree(hints);
+ }
+}
+
+char *
+ecore_window_get_machine(Window win)
+{
+ XTextProperty xtp;
+
+ if (!disp) return NULL;
+ if (XGetWMClientMachine(disp, win, &xtp))
+ {
+ char *s;
+
+ if (!xtp.value)
+ return NULL;
+ s = strdup(xtp.value);
+ XFree(xtp.value);
+ return s;
+ }
+ return NULL;
+}
+
+char *
+ecore_window_get_command(Window win)
+{
+ int cargc;
+ char **cargv;
+
+ if (!disp) return NULL;
+ if (XGetCommand(disp, win, &cargv, &cargc))
+ {
+ if (cargc > 0)
+ {
+ char *s;
+ int size, i;
+
+ size = 0;
+ for (i = 0; i < cargc; i++)
+ size += strlen(cargv[i]);
+ size += cargc - 1;
+ s = NEW(char, size + 1);
+ s[0] = 0;
+
+ strcpy(s, cargv[0]);
+ for (i = 1; i < cargc; i++)
+ {
+ strcat(s, " ");
+ strcat(s, cargv[i]);
+ }
+ XFreeStringList(cargv);
+ return s;
+ }
+ else
+ return NULL;
+ }
+ return NULL;
+}
+
+char *
+ecore_window_get_icon_name(Window win)
+{
+ XTextProperty xtp;
+
+ if (!disp) return NULL;
+ if (XGetWMIconName(disp, win, &xtp))
+ {
+ char *s;
+
+ if (!xtp.value)
+ return NULL;
+ s = strdup(xtp.value);
+ XFree(xtp.value);
+ return s;
+ }
+ return NULL;
+}
+
+void
+ecore_window_set_min_size(Window win, int w, int h)
+{
+ XSizeHints hints;
+ long ret;
+
+ if (!disp) return;
+ memset(&hints, 0, sizeof(XSizeHints));
+ XGetWMNormalHints(disp, win, &hints, &ret);
+ hints.flags |= PMinSize | PSize | USSize;
+ hints.min_width = w;
+ hints.min_height = h;
+ XSetWMNormalHints(disp, win, &hints);
+}
+
+void
+ecore_window_set_max_size(Window win, int w, int h)
+{
+ XSizeHints hints;
+ long ret;
+
+ if (!disp) return;
+ memset(&hints, 0, sizeof(XSizeHints));
+ XGetWMNormalHints(disp, win, &hints, &ret);
+ hints.flags |= PMaxSize | PSize | USSize;
+ hints.max_width = w;
+ hints.max_height = h;
+ XSetWMNormalHints(disp, win, &hints);
+}
+
+void
+ecore_window_set_xy_hints(Window win, int x, int y)
+{
+ XSizeHints hints;
+ long ret;
+
+ if (!disp) return;
+ memset(&hints, 0, sizeof(XSizeHints));
+ XGetWMNormalHints(disp, win, &hints, &ret);
+ hints.flags |= PPosition | USPosition | PSize | USSize;
+ hints.x = x;
+ hints.y = y;
+ XSetWMNormalHints(disp, win, &hints);
+}
+
+void
+ecore_window_get_frame_size(Window win, int *l, int *r, int *t, int *b)
+{
+ static Atom atom_e_frame_size = 0;
+ int *data, size;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_e_frame_size, "_E_FRAME_SIZE");
+ data = ecore_window_property_get(win, atom_e_frame_size, XA_CARDINAL, &size);
+ if (data)
+ {
+ if (size == (4 * sizeof(int)))
+ {
+ if (l)
+ *l = data[0];
+ if (r)
+ *r = data[1];
+ if (t)
+ *t = data[2];
+ if (b)
+ *b = data[3];
+ }
+ else
+ {
+ if (l)
+ *l = 0;
+ if (r)
+ *r = 0;
+ if (t)
+ *t = 0;
+ if (b)
+ *b = 0;
+ }
+ FREE(data);
+ }
+ else
+ {
+ if (l)
+ *l = 0;
+ if (r)
+ *r = 0;
+ if (t)
+ *t = 0;
+ if (b)
+ *b = 0;
+ }
+}
+
+int
+ecore_window_save_under(Window win)
+{
+ XSetWindowAttributes att;
+ XWindowAttributes gatt;
+
+ if (!disp) return 0;
+ att.save_under = True;
+ XChangeWindowAttributes(disp, win, CWSaveUnder, &att);
+ XGetWindowAttributes(disp, win, &gatt);
+ return (gatt.save_under == True) ? 1 : 0;
+}
+
+GC
+ecore_gc_new(Drawable d)
+{
+ XGCValues gcv;
+
+ if (!disp) return 0;
+ if (d == 0)
+ d = default_root;
+ return XCreateGC(disp, d, 0, &gcv);
+}
+
+void
+ecore_gc_free(GC gc)
+{
+ if (!disp) return;
+ XFreeGC(disp, gc);
+}
+
+void
+ecore_gc_set_fg(GC gc, int val)
+{
+ if (!disp) return;
+ XSetForeground(disp, gc, val);
+}
+
+void
+ecore_fill_rectangle(Drawable d, GC gc, int x, int y, int w, int h)
+{
+ if (!disp) return;
+ XFillRectangle(disp, d, gc, x, y, w, h);
+}
+
+void
+ecore_draw_rectangle(Drawable d, GC gc, int x, int y, int w, int h)
+{
+ if (!disp) return;
+ XDrawRectangle(disp, d, gc, x, y, w - 1, h - 1);
+}
+
+void
+ecore_draw_line(Drawable d, GC gc, int x1, int y1, int x2, int y2)
+{
+ if (!disp) return;
+ XDrawLine(disp, d, gc, x1, y1, x2, y2);
+}
+
+void
+ecore_draw_point(Drawable d, GC gc, int x, int y)
+{
+ if (!disp) return;
+ XDrawPoint(disp, d, gc, x, y);
+}
+
+void
+ecore_window_hint_set_layer(Window win, int layer)
+{
+ static Atom atom_win_layer = 0;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_win_layer, "_WIN_LAYER");
+ ecore_window_property_set(win, atom_win_layer, XA_CARDINAL, 32, &layer, 1);
+}
+
+void
+ecore_window_hint_set_sticky(Window win, int sticky)
+{
+ static Atom atom_win_state = 0;
+ static Atom atom_win_hints = 0;
+ int data;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_win_state, "_WIN_STATE");
+ ECORE_ATOM(atom_win_hints, "_WIN_HINTS");
+ if (sticky)
+ {
+ data = ((1 << 0) | (1 << 8) | (1 << 9));
+ ecore_window_property_set(win, atom_win_state, XA_CARDINAL, 32, &data, 1);
+ data = ((1 << 0) | (1 << 1) | (1 << 2));
+ ecore_window_property_set(win, atom_win_hints, XA_CARDINAL, 32, &data, 1);
+ }
+ else
+ {
+ data = 0;
+ ecore_window_property_set(win, atom_win_state, XA_CARDINAL, 32, &data, 1);
+ ecore_window_property_set(win, atom_win_hints, XA_CARDINAL, 32, &data, 1);
+ }
+}
+
+void
+ecore_window_hint_set_borderless(Window win)
+{
+ static Atom atom_motif_wm_hints = 0;
+ int data[5];
+
+ if (!disp) return;
+ ECORE_ATOM(atom_motif_wm_hints, "_MOTIF_WM_HINTS");
+ data[0] = 0x3;
+ data[1] = 0x0;
+ data[2] = 0x0;
+ data[3] = 0x2ada27b0;
+ data[4] = 0x2aabd6b0;
+ ecore_window_property_set(win, atom_motif_wm_hints, atom_motif_wm_hints, 32,
+ data, 5);
+}
+
+void
+ecore_grab_mouse(Window win, int confine, Cursor cursor)
+{
+ int ret;
+
+ if (!disp)
+ return;
+ if (confine)
+ ret = XGrabPointer(disp, win, False,
+ XEV_BUTTON | XEV_MOUSE_MOVE | XEV_IN_OUT,
+ GrabModeAsync, GrabModeAsync, win, cursor, CurrentTime);
+ else
+ ret = XGrabPointer(disp, win, False,
+ XEV_BUTTON | XEV_MOUSE_MOVE | XEV_IN_OUT,
+ GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime);
+ if (ret == GrabSuccess)
+ grab_pointer_win = win;
+}
+
+void
+ecore_ungrab_mouse(void)
+{
+ if (!disp) return;
+ XUngrabPointer(disp, CurrentTime);
+ grab_pointer_win = 0;
+}
+
+Window
+ecore_grab_window_get(void)
+{
+ return grab_pointer_win;
+}
+
+int
+ecore_window_get_gravity(Window win)
+{
+ XWindowAttributes att;
+
+ if (!disp)
+ return 0;
+
+ XGetWindowAttributes(disp, win, &att);
+ return att.win_gravity;
+}
+
+void
+ecore_window_gravity_reset(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ XSetWindowAttributes att;
+
+/* if (xid->gravity != NorthWestGravity)*/
+ {
+ att.win_gravity = NorthWestGravity;
+ XChangeWindowAttributes(disp, win, CWWinGravity, &att);
+ xid->gravity = NorthWestGravity;
+ xid->coords_invalid = 1;
+ }
+ }
+}
+
+void
+ecore_window_gravity_set(Window win, int gravity)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+/* if (xid->gravity != gravity)*/
+ {
+ XSetWindowAttributes att;
+
+ att.win_gravity = gravity;
+ XChangeWindowAttributes(disp, win, CWWinGravity, &att);
+ xid->gravity = gravity;
+ xid->coords_invalid = 1;
+ }
+ }
+}
+
+void
+ecore_window_bit_gravity_set(Window win, int gravity)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ XSetWindowAttributes att;
+
+ att.bit_gravity = gravity;
+ XChangeWindowAttributes(disp, win, CWBitGravity, &att);
+ }
+}
+
+void
+ecore_pointer_warp_by(int dx, int dy)
+{
+ if (!disp) return;
+ XWarpPointer(disp, None, None, 0, 0, 0, 0, dx, dy);
+}
+
+void
+ecore_pointer_warp_to(int x, int y)
+{
+ if (!disp) return;
+ XWarpPointer(disp, None, default_root, 0, 0, 0, 0, x, y);
+}
+
+void
+ecore_gc_set_include_inferiors(GC gc)
+{
+ XGCValues gcv;
+
+ if (!disp) return;
+ gcv.subwindow_mode = IncludeInferiors;
+ XChangeGC(disp, gc, GCSubwindowMode, &gcv);
+}
+
+void
+ecore_area_copy(Drawable src, Drawable dest, GC gc,
+ int sx, int sy, int sw, int sh, int dx, int dy)
+{
+ if (!disp) return;
+ if (src == 0)
+ src = default_root;
+ if (dest == 0)
+ dest = default_root;
+ XCopyArea(disp, src, dest, gc, sx, sy, sw, sh, dx, dy);
+}
+
+Window
+ecore_window_root(void)
+{
+ return default_root;
+}
+
+void
+ecore_window_get_virtual_area(Window win, int *area_x, int *area_y)
+{
+ static Atom atom_win_area = 0;
+ int *data, size;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_win_area, "_WIN_AREA");
+ data = ecore_window_property_get(win, atom_win_area, XA_CARDINAL, &size);
+ if (data)
+ {
+ if (size == (sizeof(int) * 2))
+ {
+ if (area_x)
+ *area_x = data[0];
+ if (area_y)
+ *area_y = data[1];
+ }
+ FREE(data);
+ }
+}
+
+void
+ecore_get_virtual_area(int *area_x, int *area_y)
+{
+ static Atom atom_win_area = 0;
+ int *data, size;
+
+ if (!disp) return;
+ ECORE_ATOM(atom_win_area, "_WIN_AREA");
+ data = ecore_window_property_get(default_root, atom_win_area, XA_CARDINAL, &size);
+ if (data)
+ {
+ if (size == (sizeof(int) * 2))
+ {
+ if (area_x)
+ *area_x = data[0];
+ if (area_y)
+ *area_y = data[1];
+ }
+ FREE(data);
+ }
+}
+
+void
+ecore_window_get_root_relative_location(Window win, int *x, int *y)
+{
+ int dx, dy;
+ Window parent;
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ if (win == default_root)
+ {
+ if (x)
+ *x = 0;
+ if (y)
+ *y = 0;
+ return;
+ }
+ xid = ecore_validate_xid(win);
+ if (!xid)
+ {
+ if (x)
+ *x = 0;
+ if (y)
+ *y = 0;
+ return;
+ }
+ dx = 0;
+ dy = 0;
+ do
+ {
+ parent = xid->parent;
+ dx += xid->x;
+ dy += xid->y;
+ if (parent != default_root)
+ {
+ xid = ecore_validate_xid(parent);
+ if (!xid)
+ {
+ if (x)
+ *x = dx;
+ if (y)
+ *y = dy;
+ return;
+ }
+ }
+ }
+ while (parent != default_root);
+ if (x)
+ *x = dx;
+ if (y)
+ *y = dy;
+}
+
+void
+ecore_window_button_grab_auto_replay_set(Window win, int (*func) (Ecore_Event_Mouse_Down *ev))
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (!xid) return;
+ xid->grab_button_auto_replay = func;
+}
+
+void *
+ecore_window_button_grab_auto_replay_get(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return NULL;
+ xid = ecore_validate_xid(win);
+ if (!xid) return NULL;
+ return xid->grab_button_auto_replay;
+}
+
+void
+ecore_button_grab(Window win, int button, int events,
+ Ecore_Event_Key_Modifiers mod, int any_mod)
+{
+ unsigned int b;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+
+ if (!disp) return;
+ b = button;
+ if (b == 0)
+ b = AnyButton;
+ m = 0;
+ if (any_mod)
+ m = AnyModifier;
+ else
+ {
+ if (mod & ECORE_EVENT_KEY_MODIFIER_SHIFT)
+ m |= ecore_mod_mask_shift_get();
+ if (mod & ECORE_EVENT_KEY_MODIFIER_CTRL)
+ m |= ecore_mod_mask_ctrl_get();
+ if (mod & ECORE_EVENT_KEY_MODIFIER_ALT)
+ m |= ecore_mod_mask_alt_get();
+ if (mod & ECORE_EVENT_KEY_MODIFIER_WIN)
+ m |= ecore_mod_mask_win_get();
+ }
+ locks[0] = 0;
+ locks[1] = ecore_lock_mask_caps_get();
+ locks[2] = ecore_lock_mask_num_get();
+ locks[3] = ecore_lock_mask_scroll_get();
+ locks[4] = ecore_lock_mask_caps_get() | ecore_lock_mask_num_get();
+ locks[5] = ecore_lock_mask_caps_get() | ecore_lock_mask_scroll_get();
+ locks[6] = ecore_lock_mask_num_get() | ecore_lock_mask_scroll_get();
+ locks[7] =
+ ecore_lock_mask_caps_get() | ecore_lock_mask_num_get() |
+ ecore_lock_mask_scroll_get();
+ for (i = 0; i < 8; i++)
+ XGrabButton(disp, b, m | locks[i],
+ win, False, events, GrabModeSync, GrabModeAsync, None, None);
+}
+
+void
+ecore_button_ungrab(Window win, int button, Ecore_Event_Key_Modifiers mod,
+ int any_mod)
+{
+ unsigned int b;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+
+ if (!disp) return;
+ b = button;
+ if (b == 0)
+ b = AnyButton;
+ m = 0;
+ if (any_mod)
+ m = AnyModifier;
+ else
+ {
+ if (mod & ECORE_EVENT_KEY_MODIFIER_SHIFT)
+ m |= ecore_mod_mask_shift_get();
+ if (mod & ECORE_EVENT_KEY_MODIFIER_CTRL)
+ m |= ecore_mod_mask_ctrl_get();
+ if (mod & ECORE_EVENT_KEY_MODIFIER_ALT)
+ m |= ecore_mod_mask_alt_get();
+ if (mod & ECORE_EVENT_KEY_MODIFIER_WIN)
+ m |= ecore_mod_mask_win_get();
+ }
+ locks[0] = 0;
+ locks[1] = ecore_lock_mask_caps_get();
+ locks[2] = ecore_lock_mask_num_get();
+ locks[3] = ecore_lock_mask_scroll_get();
+ locks[4] = ecore_lock_mask_caps_get() | ecore_lock_mask_num_get();
+ locks[5] = ecore_lock_mask_caps_get() | ecore_lock_mask_scroll_get();
+ locks[6] = ecore_lock_mask_num_get() | ecore_lock_mask_scroll_get();
+ locks[7] =
+ ecore_lock_mask_caps_get() | ecore_lock_mask_num_get() |
+ ecore_lock_mask_scroll_get();
+ for (i = 0; i < 8; i++)
+ XUngrabButton(disp, b, m | locks[i], win);
+}
+
+void
+ecore_pointer_replay(Time t)
+{
+ if (!disp) return;
+ XSync(disp, False);
+ XAllowEvents(disp, ReplayPointer, t);
+ XSync(disp, False);
+}
+
+void
+ecore_pointer_grab(Window win, Time t)
+{
+ if (!disp) return;
+ XGrabPointer(disp, win, False, XEV_BUTTON | XEV_MOUSE_MOVE | XEV_IN_OUT,
+ GrabModeAsync, GrabModeAsync, None, None, t);
+}
+
+void
+ecore_pointer_ungrab(Time t)
+{
+ if (!disp) return;
+ XUngrabPointer(disp, t);
+}
+
+void
+ecore_window_send_event_move_resize(Window win, int x, int y, int w, int h)
+{
+ XEvent ev;
+
+ if (!disp) return;
+ ev.type = ConfigureNotify;
+ ev.xconfigure.display = disp;
+ ev.xconfigure.event = win;
+ ev.xconfigure.window = win;
+ ev.xconfigure.x = x;
+ ev.xconfigure.y = y;
+ ev.xconfigure.width = w;
+ ev.xconfigure.height = h;
+ ev.xconfigure.border_width = 0;
+ ev.xconfigure.above = win;
+ ev.xconfigure.override_redirect = False;
+ XSendEvent(disp, win, False, StructureNotifyMask, &ev);
+}
+
+void
+ecore_window_send_client_message(Window win, Atom type, int format, void *data)
+{
+ XClientMessageEvent ev;
+ int i;
+
+ if (!disp) return;
+ ev.type = ClientMessage;
+ ev.window = win;
+ ev.message_type = type;
+ ev.format = format;
+ if (format == 32)
+ {
+ for (i = 0; i < 5; i++)
+ ev.data.l[i] = ((unsigned int *)data)[i];
+ }
+ else if (format == 16)
+ {
+ for (i = 0; i < 10; i++)
+ ev.data.s[i] = ((unsigned short *)data)[i];
+ }
+ else if (format == 8)
+ {
+ for (i = 0; i < 20; i++)
+ ev.data.b[i] = ((unsigned char *)data)[i];
+ }
+ XSendEvent(disp, win, False, 0, (XEvent *) & ev);
+}
+
+void
+ecore_window_add_to_save_set(Window win)
+{
+ if (!disp) return;
+ XAddToSaveSet(disp, win);
+}
+
+void
+ecore_window_del_from_save_set(Window win)
+{
+ if (!disp) return;
+ XRemoveFromSaveSet(disp, win);
+}
+
+void
+ecore_window_kill_client(Window win)
+{
+ if (!disp) return;
+ XKillClient(disp, (XID) win);
+}
+
+void
+ecore_window_set_border_width(Window win, int bw)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return;
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ xid->bw = bw;
+ }
+ XSetWindowBorderWidth(disp, win, bw);
+}
+
+int
+ecore_window_get_border_width(Window win)
+{
+ Ecore_XID *xid = NULL;
+
+ if (!disp) return 0;
+
+ xid = ecore_validate_xid(win);
+ if (xid)
+ {
+ return xid->bw;
+ }
+
+ return 0;
+}
+
+int
+ecore_window_get_wm_size_hints(Window win, XSizeHints * hints, int *mask)
+{
+ long sup_ret;
+ Status ok;
+
+ if (!disp) return 0;
+
+ ok = XGetWMNormalHints(disp, win, hints, &sup_ret);
+ *mask = (int)sup_ret;
+ return ok;
+}
+
+int
+ecore_window_is_visible(Window win)
+{
+ XWindowAttributes att;
+
+ if (!disp) return 0;
+ if (win == 0)
+ win = default_root;
+ if (XGetWindowAttributes(disp, win, &att) == True)
+ {
+ if (att.map_state == IsUnmapped)
+ return 0;
+ return 1;
+ }
+ return 0;
+}
+
+int
+ecore_window_is_normal(Window win)
+{
+ XWindowAttributes att;
+
+ if (!disp) return 0;
+ if (win == 0)
+ win = default_root;
+ if (XGetWindowAttributes(disp, win, &att) == True)
+ {
+ if ((att.override_redirect) || (att.class == InputOnly))
+ return 0;
+ return 1;
+ }
+ return 0;
+}
+
+int
+ecore_window_is_manageable(Window win)
+{
+ XWindowAttributes att;
+
+ if (!disp) return 0;
+ if (win == 0)
+ win = default_root;
+ if (XGetWindowAttributes(disp, win, &att) == True)
+ {
+ if ((att.map_state == IsUnmapped) || (att.override_redirect)
+ || (att.class == InputOnly))
+ return 0;
+ return 1;
+ }
+ return 0;
+}
+
+void
+ecore_windows_restack(Window * wins, int num)
+{
+ if (!disp) return;
+ XRestackWindows(disp, wins, num);
+}
+
+void
+ecore_window_stack_above(Window win, Window above)
+{
+ XWindowChanges xwc;
+
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ xwc.sibling = above;
+ xwc.stack_mode = Above;
+ XConfigureWindow(disp, win, CWSibling | CWStackMode, &xwc);
+}
+
+void
+ecore_window_stack_below(Window win, Window below)
+{
+ XWindowChanges xwc;
+
+ if (!disp) return;
+
+ if (win == 0)
+ win = default_root;
+ xwc.sibling = below;
+ xwc.stack_mode = Below;
+ XConfigureWindow(disp, win, CWSibling | CWStackMode, &xwc);
+}
+
+char *
+ecore_window_get_title(Window win)
+{
+ XTextProperty xtp;
+
+ if (!disp) return 0;
+
+ if (win == 0)
+ win = default_root;
+ if (XGetWMName(disp, win, &xtp))
+ {
+ int items;
+ char **list;
+ Status s;
+ char *title = NULL;
+
+ if (xtp.format == 8)
+ {
+ s = XmbTextPropertyToTextList(disp, &xtp, &list, &items);
+ if ((s == Success) && (items > 0))
+ {
+ title = strdup(*list);
+ XFreeStringList(list);
+ }
+ else
+ title = strdup((char *)xtp.value);
+ }
+ else
+ title = strdup((char *)xtp.value);
+ XFree(xtp.value);
+ return title;
+ }
+ return NULL;
+}
+
+void
+ecore_keyboard_grab(Window win)
+{
+ int status;
+
+ if (!disp) return;
+ if (keyboard_grab_win)
+ return;
+ if (win == 0)
+ win = default_root;
+ keyboard_grab_win = win;
+ status =
+ XGrabKeyboard(disp, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
+ if ((status == AlreadyGrabbed) || (status == GrabNotViewable)
+ || (status == GrabFrozen) || (status == GrabInvalidTime))
+ keyboard_grab_win = 0;
+}
+
+void
+ecore_keyboard_ungrab(void)
+{
+ if (!disp) return;
+ if (!keyboard_grab_win)
+ return;
+ keyboard_grab_win = 0;
+ XUngrabKeyboard(disp, CurrentTime);
+}
+
+Window
+ecore_keyboard_grab_window_get(void)
+{
+ if (!disp) return 0;
+ return keyboard_grab_win;
+}
+
+Window
+ecore_selection_set(char *string)
+{
+ Window target = 0;
+ static Atom dest = 0;
+ Atom selection;
+
+ if (!disp) return 0;
+ selection = X_CLIPBOARD_SELECTION;
+ ECORE_ATOM(dest, "TEXT_SELECTION");
+ target = ecore_window_new(0, 0, 0, 77, 7);
+ ecore_window_add_events(target, XEV_CONFIGURE | XEV_PROPERTY);
+ XSetSelectionOwner(disp, selection, target, CurrentTime);
+ if (XGetSelectionOwner(disp, XA_PRIMARY) != target)
+ {
+ ecore_window_destroy(target);
+ return 0;
+ }
+ XChangeProperty(disp, target, dest,
+ XA_STRING, 8, PropModeReplace, string, strlen(string));
+ return target;
+}
+
+Window
+ecore_selection_request(void)
+{
+ static Atom dest = 0;
+ Atom selection;
+ Window target = 0;
+
+ if (!disp) return 0;
+ selection = X_CLIPBOARD_SELECTION;
+ ECORE_ATOM(dest, "TEXT_SELECTION");
+ target = ecore_window_new(0, 0, 0, 7, 77);
+ ecore_window_add_events(target, XEV_CONFIGURE | XEV_PROPERTY);
+ XConvertSelection(disp, XA_PRIMARY, XA_STRING, dest, target, CurrentTime);
+ return target;
+}
+
+char *
+ecore_selection_get_data(Window win, Atom prop)
+{
+ char *string = NULL;
+ long nread;
+ unsigned long bytes_after, nitems;
+ unsigned char *data;
+ Atom actual_type;
+ int actual_fmt;
+
+ if (!disp) return NULL;
+ if (prop == None)
+ return NULL;
+ for (nread = 0, bytes_after = 1; bytes_after > 0;)
+ {
+ if ((XGetWindowProperty(disp, win, prop, nread / 4,
+ 0x10000, True, AnyPropertyType,
+ &actual_type, &actual_fmt, &nitems,
+ &bytes_after, &data) != Success))
+ {
+ IF_FREE(string);
+ if (data)
+ {
+ XFree(data);
+ }
+ return NULL;
+ }
+ nread += nitems;
+
+ if (actual_type == XA_STRING)
+ {
+ if (string)
+ string = realloc(string, strlen(string) + nitems + 1);
+ else
+ {
+ string = malloc(nitems + 1);
+ string[0] = 0;
+ }
+ string[strlen(string) + nitems] = 0;
+ strncat(string, data, nitems);
+ }
+ else
+ {
+ int size, i;
+ XTextProperty xtextp;
+ char **cl = NULL;
+
+ xtextp.value = data;
+ xtextp.encoding = actual_type;
+ xtextp.format = actual_fmt;
+ xtextp.nitems = nitems;
+ XmbTextPropertyToTextList(disp, &xtextp, &cl, &size);
+
+ if (cl)
+ {
+ for (i = 0; i < size; i++)
+ {
+ if (cl[i])
+ {
+ if (string)
+ string =
+ realloc(string, strlen(string) + strlen(cl[i]) + 1);
+ else
+ {
+ string = malloc(strlen(cl[i]) + 1);
+ string[0] = 0;
+ }
+ string[strlen(string) + strlen(cl[i])] = 0;
+ strcat(string, cl[i]);
+ }
+ }
+ XFreeStringList(cl);
+ }
+ }
+ if (data)
+ {
+ XFree(data);
+ }
+ }
+ return string;
+}
+
+void
+ecore_set_blank_pointer(Window w)
+{
+ Cursor c;
+ XColor cl;
+ Pixmap p, m;
+ GC gc;
+ XGCValues gcv;
+
+ if (!disp) return;
+ if (w == 0)
+ w = default_root;
+ p = XCreatePixmap(disp, w, 1, 1, 1);
+ m = XCreatePixmap(disp, w, 1, 1, 1);
+ gc = XCreateGC(disp, m, 0, &gcv);
+ XSetForeground(disp, gc, 0);
+ XDrawPoint(disp, m, gc, 0, 0);
+ XFreeGC(disp, gc);
+ c = XCreatePixmapCursor(disp, p, m, &cl, &cl, 0, 0);
+ XDefineCursor(disp, w, c);
+ XFreeCursor(disp, c);
+ XFreePixmap(disp, p);
+ XFreePixmap(disp, m);
+}
+
+Cursor
+ecore_cursor_new(Pixmap pmap, Pixmap mask, int x, int y, int fr, int fg, int fb,
+ int br, int bg, int bb)
+{
+ XColor cl1, cl2;
+
+ if (!disp) return 0;
+ cl1.pixel = 0;
+ cl1.red = fr << 8 | fr;
+ cl1.green = fg << 8 | fg;
+ cl1.blue = fb << 8 | fb;
+ cl1.flags = DoRed | DoGreen | DoBlue;
+ cl2.pixel = 0;
+ cl2.red = br << 8 | br;
+ cl2.green = bg << 8 | bg;
+ cl2.blue = bb << 8 | bb;
+ cl2.flags = DoRed | DoGreen | DoBlue;
+ return XCreatePixmapCursor(disp, pmap, mask, &cl1, &cl2, x, y);
+}
+
+void
+ecore_cursor_free(Cursor c)
+{
+ if (!disp) return;
+ XFreeCursor(disp, c);
+}
+
+void
+ecore_cursor_set(Window win, Cursor c)
+{
+ if (!disp) return;
+ if (win == 0)
+ win = default_root;
+ XDefineCursor(disp, win, c);
+}
diff --git a/ecore/src/lib/.cvsignore b/ecore/src/lib/.cvsignore
new file mode 100644
index 0000000..282522d
--- /dev/null
+++ b/ecore/src/lib/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/ecore/src/lib/CVS/Entries b/ecore/src/lib/CVS/Entries
new file mode 100644
index 0000000..78afff1
--- /dev/null
+++ b/ecore/src/lib/CVS/Entries
@@ -0,0 +1,13 @@
+/.cvsignore/1.1/Thu Nov 13 12:30:47 2003//THEAD
+/Makefile.am/1.8/Fri Apr 29 05:29:13 2005//THEAD
+D/ecore////
+D/ecore_con////
+D/ecore_config////
+D/ecore_dbus////
+D/ecore_evas////
+D/ecore_fb////
+D/ecore_file////
+D/ecore_ipc////
+D/ecore_job////
+D/ecore_txt////
+D/ecore_x////
diff --git a/ecore/src/lib/CVS/Repository b/ecore/src/lib/CVS/Repository
new file mode 100644
index 0000000..9ce7be3
--- /dev/null
+++ b/ecore/src/lib/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/lib
diff --git a/ecore/src/lib/CVS/Root b/ecore/src/lib/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/lib/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/lib/CVS/Tag b/ecore/src/lib/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/lib/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/lib/Makefile.am b/ecore/src/lib/Makefile.am
new file mode 100644
index 0000000..8bfccd9
--- /dev/null
+++ b/ecore/src/lib/Makefile.am
@@ -0,0 +1,13 @@
+## Process this file with automake to produce Makefile.in
+SUBDIRS = \
+ecore \
+ecore_job \
+ecore_txt \
+ecore_fb \
+ecore_con \
+ecore_x \
+ecore_ipc \
+ecore_evas \
+ecore_config \
+ecore_file \
+ecore_dbus
diff --git a/ecore/src/lib/ecore/.cvsignore b/ecore/src/lib/ecore/.cvsignore
new file mode 100644
index 0000000..78de274
--- /dev/null
+++ b/ecore/src/lib/ecore/.cvsignore
@@ -0,0 +1,6 @@
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+libecore.la
diff --git a/ecore/src/lib/ecore/CVS/Entries b/ecore/src/lib/ecore/CVS/Entries
new file mode 100644
index 0000000..0d13af0
--- /dev/null
+++ b/ecore/src/lib/ecore/CVS/Entries
@@ -0,0 +1,26 @@
+/.cvsignore/1.2/Mon Mar 29 21:11:30 2004//THEAD
+/Ecore.h/1.23/Fri Apr 15 01:22:45 2005//THEAD
+/Ecore_Data.h/1.14/Sat Apr 2 15:59:55 2005//THEAD
+/Makefile.am/1.9/Thu Mar 10 15:19:36 2005//THEAD
+/ecore.c/1.11/Mon Apr 11 15:43:44 2005//THEAD
+/ecore_anim.c/1.3/Wed Mar 2 07:06:32 2005//THEAD
+/ecore_app.c/1.5/Thu Nov 25 04:07:54 2004//THEAD
+/ecore_events.c/1.18/Mon Jun 13 02:30:37 2005//THEAD
+/ecore_exe.c/1.8/Thu Jul 7 03:31:34 2005//THEAD
+/ecore_hash.c/1.11/Wed Mar 2 07:06:32 2005//THEAD
+/ecore_idle_enterer.c/1.5/Sat May 8 04:44:03 2004//THEAD
+/ecore_idle_exiter.c/1.3/Sat May 8 04:44:03 2004//THEAD
+/ecore_idler.c/1.5/Sat May 8 04:44:03 2004//THEAD
+/ecore_main.c/1.18/Mon Mar 28 09:00:08 2005//THEAD
+/ecore_path.c/1.6/Tue Jan 4 22:45:05 2005//THEAD
+/ecore_plugin.c/1.4/Wed Oct 20 17:51:27 2004//THEAD
+/ecore_private.h/1.14/Sat May 28 03:57:17 2005//THEAD
+/ecore_sheap.c/1.5/Sat Jan 29 02:13:12 2005//THEAD
+/ecore_signal.c/1.16/Wed Mar 2 07:06:33 2005//THEAD
+/ecore_time.c/1.5/Wed Oct 20 17:51:28 2004//THEAD
+/ecore_timer.c/1.12/Mon Apr 4 16:01:39 2005//THEAD
+/ecore_tree.c/1.4/Tue Jan 4 22:45:06 2005//THEAD
+/ecore_value.c/1.5/Wed Mar 2 07:06:33 2005//THEAD
+/ecore_list.c/1.16/Sat Jul 23 17:35:06 2005//THEAD
+/ecore_strings.c/1.7/Sat Jul 23 17:35:06 2005//THEAD
+D
diff --git a/ecore/src/lib/ecore/CVS/Repository b/ecore/src/lib/ecore/CVS/Repository
new file mode 100644
index 0000000..69e64ae
--- /dev/null
+++ b/ecore/src/lib/ecore/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/lib/ecore
diff --git a/ecore/src/lib/ecore/CVS/Root b/ecore/src/lib/ecore/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/lib/ecore/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/lib/ecore/CVS/Tag b/ecore/src/lib/ecore/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/lib/ecore/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/lib/ecore/Ecore.h b/ecore/src/lib/ecore/Ecore.h
new file mode 100644
index 0000000..308262d
--- /dev/null
+++ b/ecore/src/lib/ecore/Ecore.h
@@ -0,0 +1,254 @@
+#ifndef _ECORE_H
+#define _ECORE_H
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef WIN32
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef GCC_HASCLASSVISIBILITY
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file Ecore.h
+ * @brief The file that provides the program utility, main loop and timer
+ * functions.
+ *
+ * This header provides the Ecore event handling loop. For more
+ * details, see @ref Ecore_Main_Loop_Group.
+ *
+ * For the main loop to be of any use, you need to be able to add events
+ * and event handlers. Events for file descriptor events are covered in
+ * @ref Ecore_FD_Handler_Group.
+ *
+ * Time functions are covered in @ref Ecore_Time_Group.
+ *
+ * There is also provision for callbacks for when the loop enters or
+ * exits an idle state. See @ref Idle_Group for more information.
+ *
+ * Functions are also provided for spawning child processes using fork.
+ * See @ref Ecore_Exe_Basic_Group and @ref Ecore_Exe_Signal_Group for
+ * more details.
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <limits.h>
+#include <signal.h>
+
+#include <Ecore_Data.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
+#ifndef MIN
+#define MIN(x, y) (((x) > (y)) ? (y) : (x))
+#endif
+
+#ifndef MAX
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+#endif
+
+#ifndef ABS
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+#endif
+
+#ifndef CLAMP
+#define CLAMP(x, min, max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x)))
+#endif
+
+#define ECORE_EVENT_NONE 0
+#define ECORE_EVENT_EXE_EXIT 1 /**< Spawned Exe has exit event */
+#define ECORE_EVENT_SIGNAL_USER 2 /**< User signal event */
+#define ECORE_EVENT_SIGNAL_HUP 3 /**< Hup signal event */
+#define ECORE_EVENT_SIGNAL_EXIT 4 /**< Exit signal event */
+#define ECORE_EVENT_SIGNAL_POWER 5 /**< Power signal event */
+#define ECORE_EVENT_SIGNAL_REALTIME 6 /**< Realtime signal event */
+#define ECORE_EVENT_COUNT 7
+
+#ifndef _ECORE_PRIVATE_H
+ enum _Ecore_Fd_Handler_Flags
+ {
+ ECORE_FD_READ = 1, /**< Fd Read mask */
+ ECORE_FD_WRITE = 2, /**< Fd Write mask */
+ ECORE_FD_ERROR = 4 /**< Fd Error mask */
+ };
+ typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags;
+
+#ifndef WIN32
+ typedef void Ecore_Exe; /**< A handle for spawned processes */
+#endif
+ typedef void Ecore_Timer; /**< A handle for timers */
+ typedef void Ecore_Idler; /**< A handle for idlers */
+ typedef void Ecore_Idle_Enterer; /**< A handle for idle enterers */
+ typedef void Ecore_Idle_Exiter; /**< A handle for idle exiters */
+ typedef void Ecore_Fd_Handler; /**< A handle for Fd hanlders */
+ typedef void Ecore_Event_Handler; /**< A handle for an event handler */
+ typedef void Ecore_Event_Filter; /**< A handle for an event filter */
+ typedef void Ecore_Event; /**< A handle for an event */
+ typedef void Ecore_Animator; /**< A handle for animators */
+#endif
+ typedef struct _Ecore_Event_Exe_Exit Ecore_Event_Exe_Exit; /**< Spawned Exe exit event */
+ typedef struct _Ecore_Event_Signal_User Ecore_Event_Signal_User; /**< User signal event */
+ typedef struct _Ecore_Event_Signal_Hup Ecore_Event_Signal_Hup; /**< Hup signal event */
+ typedef struct _Ecore_Event_Signal_Exit Ecore_Event_Signal_Exit; /**< Exit signal event */
+ typedef struct _Ecore_Event_Signal_Power Ecore_Event_Signal_Power; /**< Power signal event */
+ typedef struct _Ecore_Event_Signal_Realtime Ecore_Event_Signal_Realtime; /**< Realtime signal event */
+
+#ifndef WIN32
+ struct _Ecore_Event_Exe_Exit /** Process exit event */
+ {
+ pid_t pid; /**< The process ID of the process that exited */
+ int exit_code; /**< The exit code of the process */
+ Ecore_Exe *exe; /**< The handle to the exited process, or NULL if not found */
+ int exit_signal; /** < The signal that caused the process to exit */
+ char exited : 1; /** < set to 1 if the process exited of its own accord */
+ char signalled : 1; /** < set to 1 id the process exited due to uncaught signal */
+ void *ext_data; /**< Extension data - not used */
+ siginfo_t data; /**< Signal info */
+ };
+#endif
+
+ struct _Ecore_Event_Signal_User /** User signal event */
+ {
+ int number; /**< The signal number. Either 1 or 2 */
+ void *ext_data; /**< Extension data - not used */
+
+#ifndef WIN32
+ siginfo_t data; /**< Signal info */
+#endif
+ };
+
+ struct _Ecore_Event_Signal_Hup /** Hup signal event */
+ {
+ void *ext_data; /**< Extension data - not used */
+
+#ifndef WIN32
+ siginfo_t data; /**< Signal info */
+#endif
+ };
+
+ struct _Ecore_Event_Signal_Exit /** Exit request event */
+ {
+ int interrupt : 1; /**< Set if the exit request was an interrupt signal*/
+ int quit : 1; /**< set if the exit request was a quit signal */
+ int terminate : 1; /**< Set if the exit request was a terminate singal */
+ void *ext_data; /**< Extension data - not used */
+
+#ifndef WIN32
+ siginfo_t data; /**< Signal info */
+#endif
+ };
+
+ struct _Ecore_Event_Signal_Power /** Power event */
+ {
+ void *ext_data; /**< Extension data - not used */
+
+#ifndef WIN32
+ siginfo_t data; /**< Signal info */
+#endif
+ };
+
+ struct _Ecore_Event_Signal_Realtime /** Realtime event */
+ {
+ int num; /**< The realtime signal's number */
+
+#ifndef WIN32
+ siginfo_t data; /**< Signal info */
+#endif
+ };
+
+ EAPI int ecore_init(void);
+ EAPI int ecore_shutdown(void);
+
+ EAPI void ecore_app_args_set(int argc, const char **argv);
+ EAPI void ecore_app_args_get(int *argc, char ***argv);
+ EAPI void ecore_app_restart(void);
+
+ EAPI Ecore_Event_Handler *ecore_event_handler_add(int type, int (*func) (void *data, int type, void *event), const void *data);
+ EAPI void *ecore_event_handler_del(Ecore_Event_Handler *event_handler);
+ EAPI Ecore_Event *ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data);
+ EAPI void *ecore_event_del(Ecore_Event *event);
+ EAPI int ecore_event_type_new(void);
+ EAPI Ecore_Event_Filter *ecore_event_filter_add(void * (*func_start) (void *data), int (*func_filter) (void *data, void *loop_data, int type, void *event), void (*func_end) (void *data, void *loop_data), const void *data);
+ EAPI void *ecore_event_filter_del(Ecore_Event_Filter *ef);
+ EAPI int ecore_event_current_type_get(void);
+ EAPI void *ecore_event_current_event_get(void);
+
+
+#ifndef WIN32
+ EAPI Ecore_Exe *ecore_exe_run(const char *exe_cmd, const void *data);
+ EAPI void *ecore_exe_free(Ecore_Exe *exe);
+ EAPI pid_t ecore_exe_pid_get(Ecore_Exe *exe);
+ EAPI void *ecore_exe_data_get(Ecore_Exe *exe);
+ EAPI void ecore_exe_pause(Ecore_Exe *exe);
+ EAPI void ecore_exe_continue(Ecore_Exe *exe);
+ EAPI void ecore_exe_terminate(Ecore_Exe *exe);
+ EAPI void ecore_exe_kill(Ecore_Exe *exe);
+ EAPI void ecore_exe_signal(Ecore_Exe *exe, int num);
+ EAPI void ecore_exe_hup(Ecore_Exe *exe);
+#endif
+
+ EAPI Ecore_Idler *ecore_idler_add(int (*func) (void *data), const void *data);
+ EAPI void *ecore_idler_del(Ecore_Idler *idler);
+
+ EAPI Ecore_Idle_Enterer *ecore_idle_enterer_add(int (*func) (void *data), const void *data);
+ EAPI void *ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer);
+
+ EAPI Ecore_Idle_Exiter *ecore_idle_exiter_add(int (*func) (void *data), const void *data);
+ EAPI void *ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter);
+
+ EAPI void ecore_main_loop_iterate(void);
+ EAPI void ecore_main_loop_begin(void);
+ EAPI void ecore_main_loop_quit(void);
+ EAPI Ecore_Fd_Handler *ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, int (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data, int (*buf_func) (void *buf_data, Ecore_Fd_Handler *fd_handler), const void *buf_data);
+ EAPI void ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, void (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data);
+ EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler);
+ EAPI int ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler);
+ EAPI int ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags);
+ EAPI void ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags);
+
+ EAPI double ecore_time_get(void);
+
+ EAPI Ecore_Timer *ecore_timer_add(double in, int (*func) (void *data), const void *data);
+ EAPI void *ecore_timer_del(Ecore_Timer *timer);
+ EAPI void ecore_timer_interval_set(Ecore_Timer *timer, double in);
+
+ EAPI Ecore_Animator *ecore_animator_add(int (*func) (void *data), const void *data);
+ EAPI void *ecore_animator_del(Ecore_Animator *animator);
+ EAPI void ecore_animator_frametime_set(double frametime);
+ EAPI double ecore_animator_frametime_get(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ecore/src/lib/ecore/Ecore_Data.h b/ecore/src/lib/ecore/Ecore_Data.h
new file mode 100644
index 0000000..117f96c
--- /dev/null
+++ b/ecore/src/lib/ecore/Ecore_Data.h
@@ -0,0 +1,591 @@
+#ifndef _ECORE_DATA_H
+# define _ECORE_DATA_H
+
+/**
+ * @file Ecore_Data.h
+ * @brief Contains threading, list, hash, debugging and tree functions.
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+#ifdef __sgi
+#define __FUNCTION__ "unknown"
+#ifndef __cplusplus
+#define inline
+#endif
+#endif
+
+# define PRIME_TABLE_MAX 21
+# define PRIME_MIN 17
+# define PRIME_MAX 16777213
+
+ extern const unsigned int ecore_prime_table[];
+
+ typedef void (*Ecore_For_Each) (void *value, void *user_data);
+# define ECORE_FOR_EACH(function) ((Ecore_For_Each)function)
+
+ typedef void (*Ecore_Free_Cb) (void *data);
+# define ECORE_FREE_CB(func) ((Ecore_Free_Cb)func)
+
+ typedef unsigned int (*Ecore_Hash_Cb) (void *key);
+# define ECORE_HASH_CB(function) ((Ecore_Hash_Cb)function)
+
+ typedef int (*Ecore_Compare_Cb) (void *data1, void *data2);
+# define ECORE_COMPARE_CB(function) ((Ecore_Compare_Cb)function)
+
+ int ecore_direct_compare(void *key1, void *key2);
+ int ecore_str_compare(void *key1, void *key2);
+
+ unsigned int ecore_direct_hash(void *key);
+ unsigned int ecore_str_hash(void *key);
+
+
+# ifdef HAVE_PTHREADS /* pthreads are installed */
+
+# include <pthread.h>
+
+# define ECORE_DECLARE_LOCKS \
+ struct { \
+ int readers; \
+ pthread_mutex_t readers_mutex; \
+ pthread_mutex_t writers_mutex; \
+ pthread_cond_t readers_cond; \
+ } locks
+
+# define ECORE_INIT_LOCKS(structure) \
+ if (structure) { \
+ structure->readers = 0; \
+ pthread_mutex_init(&structure->locks.readers_mutex, NULL); \
+ pthread_mutex_init(&structure->locks.writers_mutex, NULL); \
+ pthread_cond_init(&structure->locks.readers_cond, NULL); \
+ }
+
+# define ECORE_DESTROY_LOCKS(structure) \
+ if (structure) { \
+ pthread_mutex_destroy(&structure->locks.readers_mutex); \
+ pthread_mutex_destroy(&structure->locks.writers_mutex); \
+ pthread_cond_destroy(&structure->readers_cond); \
+ }
+
+# define ECORE_READ_LOCK(structure) \
+ if (structure) { \
+ pthread_mutex_lock(&structure->locks.readers_mutex); \
+ structure->locks.readers++; \
+ pthread_mutex_unlock(&structure->locks.readers_mutex); \
+ }
+
+# define ECORE_READ_UNLOCK(structure) \
+ if (structure) { \
+ pthread_mutex_lock(&structure->locks.readers_mutex); \
+ if (--structure->locks.readers == 0) \
+ pthread_cond_broadcast(&structure->locks.readers_cond); \
+ pthread_mutex_unlock(&structure->locks.readers_mutex); \
+ }
+
+# define ECORE_WRITE_LOCK(structure) \
+ if (structure) { \
+ pthread_mutex_lock(&structure->locks.readers_mutex); \
+ pthread_mutex_lock(&structure->locks.writers_mutex); \
+ while (structure->locks.readers > 0) \
+ pthread_cond_wait(&structure->locks.readers_cond, \
+ &structure->locks.readers_mutex); \
+ pthread_mutex_unlock(&structure->locks.readers_mutex); \
+ }
+
+# define ECORE_WRITE_UNLOCK(structure) \
+ if (structure) \
+ pthread_mutex_unlock(&structure->locks.writers_mutex); \
+
+# define ECORE_THREAD_CREATE(function, arg) \
+ if (function) { \
+ pthread_t thread; \
+ pthread_create(&thread, NULL, function, arg); \
+ pthread_detach(thread); \
+ }
+
+# define ECORE_NO_THREADS(function, arg)
+
+# else /* No pthreads available */
+
+# define ECORE_DECLARE_LOCKS
+# define ECORE_INIT_LOCKS(structure)
+# define ECORE_READ_LOCK(structure)
+# define ECORE_READ_UNLOCK(structure)
+# define ECORE_WRITE_LOCK(structure)
+# define ECORE_WRITE_UNLOCK(structure)
+# define ECORE_THREAD_CREATE(function, args)
+# define ECORE_DESTROY_LOCKS(structure)
+
+# define ECORE_NO_THREADS(function, arg) if (function) function(arg);
+
+# endif /* HAVE_PTHREADS */
+
+ typedef struct _ecore_list Ecore_List;
+# define ECORE_LIST(list) ((Ecore_List *)list)
+
+ typedef struct _ecore_list_node Ecore_List_Node;
+# define ECORE_LIST_NODE(node) ((Ecore_List_Node *)node)
+
+ struct _ecore_list_node {
+ void *data;
+ struct _ecore_list_node *next;
+
+ ECORE_DECLARE_LOCKS;
+ };
+
+ struct _ecore_list {
+ Ecore_List_Node *first; /* The first node in the list */
+ Ecore_List_Node *last; /* The last node in the list */
+ Ecore_List_Node *current; /* The current node in the list */
+
+ Ecore_Free_Cb free_func; /* The callback to free data in nodes */
+
+ int nodes; /* The number of nodes in the list */
+ int index; /* The position from the front of the
+ list of current node */
+ ECORE_DECLARE_LOCKS;
+ };
+
+
+ /* Creating and initializing new list structures */
+ Ecore_List *ecore_list_new(void);
+ int ecore_list_init(Ecore_List *list);
+
+ /* Adding items to the list */
+ inline int ecore_list_append(Ecore_List * list, void *_data);
+ inline int ecore_list_prepend(Ecore_List * list, void *_data);
+ inline int ecore_list_insert(Ecore_List * list, void *_data);
+
+ /* Removing items from the list */
+ inline int ecore_list_remove_destroy(Ecore_List *list);
+ inline void *ecore_list_remove(Ecore_List * list);
+ inline void *ecore_list_remove_first(Ecore_List * list);
+ inline void *ecore_list_remove_last(Ecore_List * list);
+
+ /* Retrieve the current position in the list */
+ inline void *ecore_list_current(Ecore_List * list);
+ int ecore_list_index(Ecore_List * list);
+ int ecore_list_nodes(Ecore_List * list);
+
+ /* Traversing the list */
+ int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function,
+ void *user_data);
+ inline void *ecore_list_goto_first(Ecore_List * list);
+ inline void *ecore_list_goto_last(Ecore_List * list);
+ inline void *ecore_list_goto_index(Ecore_List * list, int index);
+ inline void *ecore_list_goto(Ecore_List * list, void *_data);
+
+ /* Traversing the list and returning data */
+ inline void *ecore_list_next(Ecore_List * list);
+
+ /* Check to see if there is any data in the list */
+ int ecore_list_is_empty(Ecore_List * list);
+
+ /* Remove every node in the list without freeing the list itself */
+ int ecore_list_clear(Ecore_List * list);
+ /* Free the list and it's contents */
+ void ecore_list_destroy(Ecore_List *list);
+
+ /* Creating and initializing list nodes */
+ Ecore_List_Node *ecore_list_node_new(void);
+ int ecore_list_node_init(Ecore_List_Node *newNode);
+
+ /* Destroying nodes */
+ int ecore_list_node_destroy(Ecore_List_Node * _e_node, Ecore_Free_Cb free_func);
+
+ int ecore_list_set_free_cb(Ecore_List * list, Ecore_Free_Cb free_func);
+
+ typedef Ecore_List Ecore_DList;
+# define ECORE_DLIST(dlist) ((Ecore_DList *)dlist)
+
+ typedef struct _ecore_dlist_node Ecore_DList_Node;
+# define ECORE_DLIST_NODE(dlist) ((Ecore_DList_Node *)dlist)
+
+ struct _ecore_dlist_node {
+ Ecore_List_Node single;
+ Ecore_DList_Node *previous;
+ };
+
+ /* Creating and initializing new list structures */
+ Ecore_DList *ecore_dlist_new(void);
+ int ecore_dlist_init(Ecore_DList *list);
+ void ecore_dlist_destroy(Ecore_DList *list);
+
+ /* Adding items to the list */
+ int ecore_dlist_append(Ecore_DList * _e_dlist, void *_data);
+ int ecore_dlist_prepend(Ecore_DList * _e_dlist, void *_data);
+ int ecore_dlist_insert(Ecore_DList * _e_dlist, void *_data);
+
+ /* Info about list's state */
+ void *ecore_dlist_current(Ecore_DList *list);
+ int ecore_dlist_index(Ecore_DList *list);
+# define ecore_dlist_nodes(list) ecore_list_nodes(ECORE_LIST(list))
+
+ /* Removing items from the list */
+ void *ecore_dlist_remove(Ecore_DList * _e_dlist);
+ void *ecore_dlist_remove_first(Ecore_DList * _e_dlist);
+ int ecore_dlist_remove_destroy(Ecore_DList *list);
+ void *ecore_dlist_remove_last(Ecore_DList * _e_dlist);
+
+ /* Traversing the list */
+# define ecore_dlist_for_each(list, function, user_data) \
+ ecore_list_for_each(ECORE_LIST(list), function, user_data)
+ inline void *ecore_dlist_goto_first(Ecore_DList * _e_dlist);
+ inline void *ecore_dlist_goto_last(Ecore_DList * _e_dlist);
+ inline void *ecore_dlist_goto_index(Ecore_DList * _e_dlist, int index);
+ inline void *ecore_dlist_goto(Ecore_DList * _e_dlist, void *_data);
+
+ /* Traversing the list and returning data */
+ inline void *ecore_dlist_next(Ecore_DList * list);
+ inline void *ecore_dlist_previous(Ecore_DList * list);
+
+ /* Check to see if there is any data in the list */
+ int ecore_dlist_is_empty(Ecore_DList * _e_dlist);
+
+ /* Remove every node in the list without free'ing it */
+ int ecore_dlist_clear(Ecore_DList * _e_dlist);
+
+ /* Creating and initializing list nodes */
+ int ecore_dlist_node_init(Ecore_DList_Node * node);
+ Ecore_DList_Node *ecore_dlist_node_new(void);
+
+ /* Destroying nodes */
+ int ecore_dlist_node_destroy(Ecore_DList_Node * node, Ecore_Free_Cb free_func);
+
+ int ecore_dlist_set_free_cb(Ecore_DList * dlist, Ecore_Free_Cb free_func);
+
+
+
+ /*
+ * Hash Table Implementation:
+ *
+ * Traditional hash table implementation. I had tried a list of tables
+ * approach to save on the realloc's but it ended up being much slower than
+ * the traditional approach.
+ */
+
+ typedef struct _ecore_hash_node Ecore_Hash_Node;
+# define ECORE_HASH_NODE(hash) ((Ecore_Hash_Node *)hash)
+
+ struct _ecore_hash_node {
+ void *key; /* The key for the data node */
+ void *value; /* The value associated with this node */
+
+ ECORE_DECLARE_LOCKS;
+ };
+
+ typedef struct _ecore_hash Ecore_Hash;
+# define ECORE_HASH(hash) ((Ecore_Hash *)hash)
+
+ struct _ecore_hash {
+ Ecore_List **buckets;
+ int size; /* An index into the table of primes to
+ determine size */
+ int nodes; /* The number of nodes currently in the hash */
+
+ int index; /* The current index into the bucket table */
+
+ Ecore_Compare_Cb compare; /* The function used to compare node values */
+ Ecore_Hash_Cb hash_func; /* The function used to compare node values */
+
+ Ecore_Free_Cb free_key; /* The callback function to free key */
+ Ecore_Free_Cb free_value; /* The callback function to determine hash */
+
+ ECORE_DECLARE_LOCKS;
+ };
+
+ /* Create and initialize a hash */
+ Ecore_Hash *ecore_hash_new(Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare);
+ int ecore_hash_init(Ecore_Hash *hash, Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare);
+
+ /* Functions related to freeing the data in the hash table */
+ int ecore_hash_set_free_key(Ecore_Hash *hash, Ecore_Free_Cb function);
+ int ecore_hash_set_free_value(Ecore_Hash *hash, Ecore_Free_Cb function);
+ void ecore_hash_destroy(Ecore_Hash *hash);
+
+ int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func,
+ void *user_data);
+ Ecore_List *ecore_hash_keys(Ecore_Hash *hash);
+
+ /* Retrieve and store data into the hash */
+ void *ecore_hash_get(Ecore_Hash *hash, void *key);
+ int ecore_hash_set(Ecore_Hash *hash, void *key, void *value);
+ void *ecore_hash_remove(Ecore_Hash *hash, void *key);
+ void ecore_hash_dump_graph(Ecore_Hash *hash);
+
+
+ inline void ecore_print_warning(const char *function, const char *sparam);
+
+ /* Wrappers around free() that helps debug free() bugs such as freeing NULL
+ * or accessing a pointer that has already been freed */
+# ifndef IF_FREE
+# define IF_FREE(ptr) if (ptr) free(ptr); ptr = NULL;
+# endif
+
+# ifndef FREE
+# define FREE(ptr) free(ptr); ptr = NULL;
+# endif
+
+ /* Debugging printf, basically a wrapper to fprintf that checks the level
+ * of the message and checks that it is to be printed at the current debugging
+ * level */
+# ifndef DPRINTF
+# ifdef __sgi
+# define DPRINTF(debug, format, args) \
+ if (debug >= DEBUG_LEVEL) \
+ fprintf(stderr, format, args);
+# else
+# define DPRINTF(debug, format, args...) \
+ if (debug >= DEBUG_LEVEL) \
+ fprintf(stderr, format, args);
+# endif
+# endif
+
+
+ /* convenience macros for checking pointer parameters for non-NULL */
+# ifndef CHECK_PARAM_POINTER_RETURN
+# define CHECK_PARAM_POINTER_RETURN(sparam, param, ret) \
+ if (!(param)) \
+ { \
+ ecore_print_warning(__FUNCTION__, sparam); \
+ return ret; \
+ }
+# endif
+
+# ifndef CHECK_PARAM_POINTER
+# define CHECK_PARAM_POINTER(sparam, param) \
+ if (!(param)) \
+ { \
+ ecore_print_warning(__FUNCTION__, sparam); \
+ return; \
+ }
+# endif
+
+ /* Use the larger of a and b */
+# ifndef MAX
+# define MAX(a, b) (((a) > (b)) ? (a) : (b))
+# endif
+
+ /* Use the smaller of a and b */
+# ifndef MIN
+# define MIN(a, b) (((a) < (b)) ? (a) : (b))
+# endif
+
+
+ typedef struct _ecore_path_group Ecore_Path_Group;
+ struct _ecore_path_group
+ {
+ int id;
+ char *name;
+ Ecore_List *paths;
+ };
+
+ /*
+ * Create a new path group
+ */
+ int ecore_path_group_new(char *group_name);
+
+ /*
+ * Destroy a previous path group
+ */
+ void ecore_path_group_del(int group_id);
+
+ /*
+ * Add a directory to be searched for files
+ */
+ void ecore_path_group_add(int group_id, char *path);
+
+ /*
+ * Remove a directory to be searched for files
+ */
+ void ecore_path_group_remove(int group_id, char *path);
+
+ /*
+ * Find the absolute path if it exists in the group of paths
+ */
+ char * ecore_path_group_find(int group_id, char *name);
+
+ /*
+ * Get a list of all the available files in a path set
+ */
+ Ecore_List * ecore_path_group_available(int group_id);
+
+
+ typedef struct _ecore_plugin Ecore_Plugin;
+ struct _ecore_plugin
+ {
+ int group;
+ char *name;
+ void *handle;
+ };
+
+ /*
+ * Load the specified plugin
+ */
+ Ecore_Plugin *ecore_plugin_load(int group_id, char *plugin);
+
+ /*
+ * Unload the specified plugin
+ */
+ void ecore_plugin_unload(Ecore_Plugin * plugin);
+
+ /*
+ * Lookup the specified symbol for the plugin
+ */
+ void *ecore_plugin_call(Ecore_Plugin * plugin, char *symbol_name);
+
+ Ecore_List *ecore_plugin_get_available(int group_id);
+
+
+# define ECORE_SHEAP_MIN 0
+# define ECORE_SHEAP_MAX 1
+
+# define HEAP_INCREMENT 4096
+
+# define PARENT(i) (i / 2)
+# define LEFT(i) (2 * i)
+# define RIGHT(i) (2 * i + 1)
+
+ typedef struct _ecore_heap Ecore_Sheap;
+# define ECORE_HEAP(heap) ((Ecore_Sheap *)heap)
+
+ struct _ecore_heap {
+ void **data;
+ int size;
+ int space;
+
+ char order, sorted;
+
+ /* Callback for comparing node values, default is direct comparison */
+ Ecore_Compare_Cb compare;
+
+ /* Callback for freeing node data, default is NULL */
+ Ecore_Free_Cb free_func;
+ };
+
+ Ecore_Sheap *ecore_sheap_new(Ecore_Compare_Cb compare, int size);
+ void ecore_sheap_destroy(Ecore_Sheap *heap);
+ int ecore_sheap_init(Ecore_Sheap *heap, Ecore_Compare_Cb compare, int size);
+ int ecore_sheap_set_free_cb(Ecore_Sheap *heap, Ecore_Free_Cb free_func);
+ int ecore_sheap_insert(Ecore_Sheap *heap, void *data);
+ void *ecore_sheap_extract(Ecore_Sheap *heap);
+ void *ecore_sheap_extreme(Ecore_Sheap *heap);
+ int ecore_sheap_change(Ecore_Sheap *heap, void *item, void *newval);
+ int ecore_sheap_set_compare(Ecore_Sheap *heap, Ecore_Compare_Cb compare);
+ void ecore_sheap_set_order(Ecore_Sheap *heap, char order);
+ void ecore_sheap_sort(Ecore_Sheap *heap);
+
+ inline void *ecore_sheap_item(Ecore_Sheap *heap, int i);
+
+
+ typedef struct _ecore_string Ecore_String;
+ struct _ecore_string {
+ char *string;
+ int references;
+ };
+
+ char *ecore_string_instance(char *string);
+ void ecore_string_release(char *string);
+
+
+ typedef struct _Ecore_Tree_Node Ecore_Tree_Node;
+# define ECORE_TREE_NODE(object) ((Ecore_Tree_Node *)object)
+ struct _Ecore_Tree_Node {
+
+ /* The actual data for each node */
+ void *key;
+ void *value;
+
+ /* Pointers to surrounding nodes */
+ Ecore_Tree_Node *parent;
+ Ecore_Tree_Node *left_child;
+ Ecore_Tree_Node *right_child;
+
+ /* Book keeping information for quicker balancing of the tree */
+ int max_right;
+ int max_left;
+
+ ECORE_DECLARE_LOCKS;
+ };
+
+ typedef struct _Ecore_Tree Ecore_Tree;
+# define ECORE_TREE(object) ((Ecore_Tree *)object)
+ struct _Ecore_Tree {
+ /* Nodes of the tree */
+ Ecore_Tree_Node *tree;
+
+ /* Callback for comparing node values, default is direct comparison */
+ Ecore_Compare_Cb compare_func;
+
+ /* Callback for freeing node data, default is NULL */
+ Ecore_Free_Cb free_func;
+
+ ECORE_DECLARE_LOCKS;
+ };
+
+ /* Some basic tree functions */
+ /* Allocate and initialize a new tree */
+ Ecore_Tree *ecore_tree_new(Ecore_Compare_Cb compare_func);
+ /* Initialize a new tree */
+ int ecore_tree_init(Ecore_Tree * tree, Ecore_Compare_Cb compare_func);
+
+ /* Free the tree */
+ int ecore_tree_destroy(Ecore_Tree * tree);
+ /* Check to see if the tree has any nodes in it */
+ int ecore_tree_is_empty(Ecore_Tree * tree);
+
+ /* Retrieve the value associated with key */
+ void *ecore_tree_get(Ecore_Tree * tree, void *key);
+ Ecore_Tree_Node *ecore_tree_get_node(Ecore_Tree * tree, void *key);
+ /* Retrieve the value of node with key greater than or equal to key */
+ void *ecore_tree_get_closest_larger(Ecore_Tree * tree, void *key);
+ /* Retrieve the value of node with key less than or equal to key */
+ void *ecore_tree_get_closest_smaller(Ecore_Tree * tree, void *key);
+
+ /* Set the value associated with key to value */
+ int ecore_tree_set(Ecore_Tree * tree, void *key, void *value);
+ /* Remove the key from the tree */
+ int ecore_tree_remove(Ecore_Tree * tree, void *key);
+
+ /* Add a node to the tree */
+ int ecore_tree_add_node(Ecore_Tree * tree, Ecore_Tree_Node * node);
+ /* Remove a node from the tree */
+ int ecore_tree_remove_node(Ecore_Tree * tree, Ecore_Tree_Node * node);
+
+ /* For each node in the tree perform the for_each_func function */
+ /* For this one pass in the node */
+ int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func,
+ void *user_data);
+ /* And here pass in the node's value */
+ int ecore_tree_for_each_node_value(Ecore_Tree * tree,
+ Ecore_For_Each for_each_func,
+ void *user_data);
+
+ /* Some basic node functions */
+ /* Initialize a node */
+ int ecore_tree_node_init(Ecore_Tree_Node * new_node);
+ /* Allocate and initialize a new node */
+ Ecore_Tree_Node *ecore_tree_node_new(void);
+ /* Free the desired node */
+ int ecore_tree_node_destroy(Ecore_Tree_Node * node, Ecore_Free_Cb free_data);
+
+ /* Set the node's key to key */
+ int ecore_tree_node_key_set(Ecore_Tree_Node * node, void *key);
+ /* Retrieve the key in node */
+ void *ecore_tree_node_key_get(Ecore_Tree_Node * node);
+
+ /* Set the node's value to value */
+ int ecore_tree_node_value_set(Ecore_Tree_Node * node, void *value);
+ /* Retrieve the value in node */
+ void *ecore_tree_node_value_get(Ecore_Tree_Node * node);
+
+ /* Add a function to free the data stored in nodes */
+ int ecore_tree_set_free_cb(Ecore_Tree * tree, Ecore_Free_Cb free_func);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _ECORE_DATA_H */
+
diff --git a/ecore/src/lib/ecore/Makefile.am b/ecore/src/lib/ecore/Makefile.am
new file mode 100644
index 0000000..c0bdd3a
--- /dev/null
+++ b/ecore/src/lib/ecore/Makefile.am
@@ -0,0 +1,34 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES =
+
+lib_LTLIBRARIES = libecore.la
+include_HEADERS = \
+Ecore.h \
+Ecore_Data.h
+
+libecore_la_SOURCES = \
+ecore.c \
+ecore_app.c \
+ecore_anim.c \
+ecore_events.c \
+ecore_exe.c \
+ecore_hash.c \
+ecore_idle_enterer.c \
+ecore_idle_exiter.c \
+ecore_idler.c \
+ecore_list.c \
+ecore_main.c \
+ecore_path.c \
+ecore_plugin.c \
+ecore_sheap.c \
+ecore_signal.c \
+ecore_strings.c \
+ecore_time.c \
+ecore_timer.c \
+ecore_tree.c \
+ecore_value.c \
+ecore_private.h
+
+libecore_la_LIBADD = -lm @dlopen_libs@ @winsock_libs@
+libecore_la_LDFLAGS = -version-info 1:0:0
diff --git a/ecore/src/lib/ecore/ecore.c b/ecore/src/lib/ecore/ecore.c
new file mode 100644
index 0000000..3e6b2a8
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore.c
@@ -0,0 +1,236 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+#include <locale.h>
+#include <langinfo.h>
+
+static const char *_ecore_magic_string_get(Ecore_Magic m);
+static int _ecore_init_count = 0;
+
+#ifndef WIN32
+int _ecore_fps_debug = 0;
+#endif
+
+/** OpenBSD does not define CODESET
+ * FIXME ??
+ */
+
+#ifndef CODESET
+#define CODESET "INVALID"
+#endif
+
+/**
+ * Set up connections, signal handlers, sockets etc.
+ * @return 1 or greater on success, 0 otherwise
+ *
+ * This function sets up all singal handlers and the basic event loop. If it
+ * succeeds, 1 will be returned, otherwise 0 will be returned.
+ *
+ * @code
+ * #include <Ecore.h>
+ *
+ * int main(int argc, char **argv)
+ * {
+ * if (!ecore_init())
+ * {
+ * printf("ERROR: Cannot init Ecore!\n");
+ * return -1;
+ * }
+ * ecore_main_loop_begin();
+ * ecore_shutdown();
+ * }
+ * @endcode
+ */
+int
+ecore_init(void)
+{
+ if (++_ecore_init_count == 1)
+ {
+ setlocale(LC_CTYPE, "");
+ if (strcmp(nl_langinfo(CODESET), "UTF-8"))
+ {
+// printf("WARNING: not a utf8 locale!\n");
+ }
+#ifndef WIN32
+ if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1;
+ if (_ecore_fps_debug) _ecore_fps_debug_init();
+ _ecore_signal_init();
+#endif
+ }
+
+ return _ecore_init_count;
+}
+
+/**
+ * Shut down connections, signal handlers sockets etc.
+ *
+ * This function shuts down all things set up in ecore_init() and cleans up all
+ * event queues, handlers, filters, timers, idlers, idle enterers/exiters
+ * etc. set up after ecore_init() was called.
+ *
+ * Do not call this function from any callback that may be called from the main
+ * loop, as the main loop will then fall over and not function properly.
+ */
+int
+ecore_shutdown(void)
+{
+ if (--_ecore_init_count)
+ return _ecore_init_count;
+
+#ifndef WIN32
+ if (_ecore_fps_debug) _ecore_fps_debug_shutdown();
+#endif
+ _ecore_animator_shutdown();
+#ifndef WIN32
+ _ecore_exe_shutdown();
+#endif
+ _ecore_idle_enterer_shutdown();
+ _ecore_idle_exiter_shutdown();
+ _ecore_idler_shutdown();
+ _ecore_timer_shutdown();
+ _ecore_event_shutdown();
+ _ecore_main_shutdown();
+#ifndef WIN32
+ _ecore_signal_shutdown();
+#endif
+
+ return _ecore_init_count;
+}
+
+void
+_ecore_magic_fail(void *d, Ecore_Magic m, Ecore_Magic req_m, const char *fname)
+{
+ fprintf(stderr,
+ "\n"
+ "*** ECORE ERROR: Ecore Magic Check Failed!!!\n"
+ "*** IN FUNCTION: %s()\n", fname);
+ if (!d)
+ fprintf(stderr, " Input handle pointer is NULL!\n");
+ else if (m == ECORE_MAGIC_NONE)
+ fprintf(stderr, " Input handle has already been freed!\n");
+ else if (m != req_m)
+ fprintf(stderr, " Input handle is wrong type\n"
+ " Expected: %08x - %s\n"
+ " Supplied: %08x - %s\n",
+ (unsigned int)req_m, _ecore_magic_string_get(req_m),
+ (unsigned int)m, _ecore_magic_string_get(m));
+ fprintf(stderr,
+ "*** NAUGHTY PROGRAMMER!!!\n"
+ "*** SPANK SPANK SPANK!!!\n"
+ "*** Now go fix your code. Tut tut tut!\n"
+ "\n");
+ if (getenv("ECORE_ERROR_ABORT")) abort();
+}
+
+static const char *
+_ecore_magic_string_get(Ecore_Magic m)
+{
+ switch (m)
+ {
+ case ECORE_MAGIC_NONE:
+ return "None (Freed Object)";
+ break;
+ case ECORE_MAGIC_EXE:
+ return "Ecore_Exe (Executable)";
+ break;
+ case ECORE_MAGIC_TIMER:
+ return "Ecore_Timer (Timer)";
+ break;
+ case ECORE_MAGIC_IDLER:
+ return "Ecore_Idler (Idler)";
+ break;
+ case ECORE_MAGIC_IDLE_ENTERER:
+ return "Ecore_Idle_Enterer (Idler Enterer)";
+ break;
+ case ECORE_MAGIC_IDLE_EXITER:
+ return "Ecore_Idle_Exiter (Idler Exiter)";
+ break;
+ case ECORE_MAGIC_FD_HANDLER:
+ return "Ecore_Fd_Handler (Fd Handler)";
+ break;
+ case ECORE_MAGIC_EVENT_HANDLER:
+ return "Ecore_Event_Handler (Event Handler)";
+ break;
+ case ECORE_MAGIC_EVENT:
+ return "Ecore_Event (Event)";
+ break;
+ default:
+ return "<UNKNOWN>";
+ };
+ return "<UNKNOWN>";
+}
+
+#ifndef WIN32
+/* fps debug calls - for debugging how much time your app actually spends */
+/* "running" (and the inverse being time spent running)... this does not */
+/* account for other apps and multitasking... */
+
+static int _ecore_fps_debug_init_count = 0;
+static int _ecore_fps_debug_fd = -1;
+unsigned int *_ecore_fps_runtime_mmap = NULL;
+
+void
+_ecore_fps_debug_init(void)
+{
+ char buf[4096];
+
+ _ecore_fps_debug_init_count++;
+ if (_ecore_fps_debug_init_count > 1) return;
+ snprintf(buf, sizeof(buf), "/tmp/.ecore_fps_debug-%i", (int)getpid());
+ _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR);
+ if (_ecore_fps_debug_fd < 0)
+ {
+ unlink(buf);
+ _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR);
+ }
+ if (_ecore_fps_debug_fd >= 0)
+ {
+ unsigned int zero = 0;
+
+ write(_ecore_fps_debug_fd, &zero, sizeof(unsigned int));
+ _ecore_fps_runtime_mmap = mmap(NULL, sizeof(unsigned int),
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ _ecore_fps_debug_fd, 0);
+ }
+}
+
+void
+_ecore_fps_debug_shutdown(void)
+{
+ _ecore_fps_debug_init_count--;
+ if (_ecore_fps_debug_init_count > 0) return;
+ if (_ecore_fps_debug_fd >= 0)
+ {
+ char buf[4096];
+
+ snprintf(buf, sizeof(buf), "/tmp/.ecore_fps_debug-%i", (int)getpid());
+ unlink(buf);
+ if (_ecore_fps_runtime_mmap)
+ {
+ munmap(_ecore_fps_runtime_mmap, sizeof(int));
+ _ecore_fps_runtime_mmap = NULL;
+ }
+ close(_ecore_fps_debug_fd);
+ _ecore_fps_debug_fd = -1;
+ }
+}
+
+void
+_ecore_fps_debug_runtime_add(double t)
+{
+ if ((_ecore_fps_debug_fd >= 0) &&
+ (_ecore_fps_runtime_mmap))
+ {
+ unsigned int tm;
+
+ tm = (unsigned int)(t * 1000000.0);
+ /* i know its not 100% theoretically guaranteed, but i'd say a write */
+ /* of an int could be considered atomic for all practical purposes */
+ /* oh and since this is cumulative, 1 second = 1,000,000 ticks, so */
+ /* this can run for about 4294 seconds becore looping. if you are */
+ /* doing performance testing in one run for over an hour... well */
+ /* time to restart or handle a loop condition :) */
+ *(_ecore_fps_runtime_mmap) += tm;
+ }
+}
+#endif
diff --git a/ecore/src/lib/ecore/ecore_anim.c b/ecore/src/lib/ecore/ecore_anim.c
new file mode 100644
index 0000000..476fa20
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_anim.c
@@ -0,0 +1,169 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+
+static int _ecore_animator(void *data);
+
+static Ecore_Timer *timer = NULL;
+static int animators_delete_me = 0;
+static Ecore_Animator *animators = NULL;
+static double animators_frametime = 1.0 / 30.0;
+
+/**
+ * Add a animator to tick off at every animaton tick during main loop execution.
+ * @param func The function to call when it ticks off
+ * @param data The data to pass to the function
+ * @return A handle to the new animator
+ * @ingroup Ecore_Animator_Group
+ *
+ * This function adds a animator and returns its handle on success and NULL on
+ * failure. The function @p func will be called every N seconds where N is the
+ * frametime interval set by ecore_animator_frametime_set(). The function will
+ * be passed the @p data pointer as its parameter.
+ *
+ * When the animator @p func is called, it must return a value of either 1 or 0.
+ * If it returns 1, it will be called again at the next tick, or if it returns
+ * 0 it will be deleted automatically making any references/handles for it
+ * invalid.
+ */
+Ecore_Animator *
+ecore_animator_add(int (*func) (void *data), const void *data)
+{
+ Ecore_Animator *animator;
+
+ if (!func) return NULL;
+ animator = calloc(1, sizeof(Ecore_Animator));
+ if (!animator) return NULL;
+ ECORE_MAGIC_SET(animator, ECORE_MAGIC_ANIMATOR);
+ animator->func = func;
+ animator->data = (void *)data;
+ animators = _ecore_list_append(animators, animator);
+ if (!timer)
+ timer = ecore_timer_add(animators_frametime, _ecore_animator, NULL);
+ return animator;
+}
+
+/**
+ * Delete the specified animator from the animator list.
+ * @param animator The animator to delete
+ * @return The data pointer set for the animator
+ * @ingroup Ecore_Animator_Group
+ *
+ * Delete the specified @p aqnimator from the set of animators that are executed
+ * during main loop execution. This function returns the data parameter that
+ * was being passed to the callback on success, or NULL on failure. After this
+ * call returns the specified animator object @p animator is invalid and should not
+ * be used again. It will not get called again after deletion.
+ */
+void *
+ecore_animator_del(Ecore_Animator *animator)
+{
+ if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR))
+ {
+ ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR,
+ "ecore_animator_del");
+ return NULL;
+ }
+ if (animator->delete_me) return animator->data;
+ animator->delete_me = 1;
+ animators_delete_me++;
+ return animator->data;
+}
+
+/**
+ * Set the animator call interval in seconds.
+ * @param frametime The time in seconds in between animator ticks.
+ *
+ * This function sets the time interval (in seconds) inbetween animator ticks.
+ */
+void
+ecore_animator_frametime_set(double frametime)
+{
+ if (frametime < 0.0) frametime = 0.0;
+ if (animators_frametime == frametime) return;
+ animators_frametime = frametime;
+ if (timer)
+ {
+ ecore_timer_del(timer);
+ timer = NULL;
+ }
+ if (animators)
+ timer = ecore_timer_add(animators_frametime, _ecore_animator, NULL);
+}
+
+/**
+ * Get the animator call interval in seconds.
+ * @return The time in second in between animator ticks.
+ *
+ * this function retrieves the time inbetween animator ticks, in seconds.
+ */
+double
+ecore_animator_frametime_get(void)
+{
+ return animators_frametime;
+}
+
+void
+_ecore_animator_shutdown(void)
+{
+ if (timer)
+ {
+ ecore_timer_del(timer);
+ timer = NULL;
+ }
+ while (animators)
+ {
+ Ecore_Animator *animator;
+
+ animator = animators;
+ animators = _ecore_list_remove(animators, animator);
+ ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
+ free(animator);
+ }
+}
+
+static int
+_ecore_animator(void *data __UNUSED__)
+{
+ Ecore_Oldlist *l;
+
+ for (l = (Ecore_Oldlist *)animators; l;)
+ {
+ Ecore_Animator *animator;
+
+ animator = (Ecore_Animator *)l;
+ l = l->next;
+ if (!animator->delete_me)
+ {
+ if (!animator->func(animator->data))
+ {
+ animator->delete_me = 1;
+ animators_delete_me = 1;
+ }
+ }
+ }
+ if (animators_delete_me)
+ {
+
+ for (l = (Ecore_Oldlist *)animators; l;)
+ {
+ Ecore_Animator *animator;
+
+ animator = (Ecore_Animator *)l;
+ l = l->next;
+ if (animator->delete_me)
+ {
+ animators = _ecore_list_remove(animators, animator);
+ ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
+ free(animator);
+ animators_delete_me--;
+ if (animators_delete_me == 0) break;
+ }
+ }
+ }
+ if (!animators)
+ {
+ timer = NULL;
+ return 0;
+ }
+ return 1;
+}
diff --git a/ecore/src/lib/ecore/ecore_app.c b/ecore/src/lib/ecore/ecore_app.c
new file mode 100644
index 0000000..ecf36bf
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_app.c
@@ -0,0 +1,64 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+
+static int app_argc = 0;
+static char **app_argv = NULL;
+
+/**
+ * Set up the programs command-line arguments.
+ * @param argc The same as passed as argc to the programs main() function
+ * @param argv The same as passed as argv to the programs main() function
+ *
+ * A call to this function will store the programs command-line arguments
+ * for later use by ecore_app_restart() or ecore_app_args_get().
+ */
+void
+ecore_app_args_set(int argc, const char **argv)
+{
+ if ((argc < 1) ||
+ (!argv)) return;
+ app_argc = argc;
+ app_argv = (char **)argv;
+}
+
+/**
+ * Return the programs stored command-line arguments.
+ * @param argc A pointer to the return value to hold argc
+ * @param argv A pointer to the return value to hold argv
+ *
+ * When called, this funciton returns the arguments for the program stored by
+ * ecore_app_args_set(). The integer pointed to by @p argc will be filled, if
+ * the pointer is not NULL, and the string array pointer @p argv will be filled
+ * also if the pointer is not NULL. The values they are filled with will be the
+ * same set by ecore_app_args_set().
+ */
+void
+ecore_app_args_get(int *argc, char ***argv)
+{
+ if (argc) *argc = app_argc;
+ if (argv) *argv = app_argv;
+}
+
+/**
+ * Restart the program executable with the command-line arguments stored.
+ *
+ * This function will restart & re-execute this program in place of itself
+ * using the command-line arguments stored by ecore_app_args_set(). This is
+ * an easy way for a program to restart itself for cleanup purposes,
+ * configuration reasons or in the event of a crash.
+ *
+ * FIXME: Currently not implimented.
+ */
+void
+ecore_app_restart(void)
+{
+ char **args;
+ int i;
+
+ if ((app_argc < 1) || (!app_argv)) return;
+ args = malloc((app_argc + 1) * sizeof(char *));
+ if (!args) return;
+ for (i = 0; i < app_argc; i++) args[i] = app_argv[i];
+ args[i] = NULL;
+ execvp(app_argv[0], args);
+}
diff --git a/ecore/src/lib/ecore/ecore_events.c b/ecore/src/lib/ecore/ecore_events.c
new file mode 100644
index 0000000..45e2ac9
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_events.c
@@ -0,0 +1,519 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+
+static int events_num = 0;
+static Ecore_Event *events = NULL;
+
+static Ecore_Event_Handler **event_handlers = NULL;
+static int event_handlers_num = 0;
+static int event_handlers_alloc_num = 0;
+static Ecore_Oldlist_Data *event_handlers_delete_list = NULL;
+
+static Ecore_Event_Filter *event_filters = NULL;
+static int event_filters_delete_me = 0;
+
+static int event_id_max = ECORE_EVENT_COUNT;
+
+static int ecore_raw_event_type = ECORE_EVENT_NONE;
+static void *ecore_raw_event_event = NULL;
+
+
+/**
+ * Add an event handler.
+ * @param type The type of the event this handler will get called for
+ * @param func The function to call when the event is found in the queue
+ * @param data A data pointer to pass to the called function @p func
+ * @return A new Event handler, or NULL on failure
+ *
+ * Add an event handler to the list of handlers. This will, on success, return
+ * a handle to the event handler object that was created, that can be used
+ * later to remove the handler using ecore_event_handler_del(). The @p type
+ * parameter is the iteger of the event type that will trigger this callback
+ * to be called. The callback @p func is called when this event is processed
+ * and will be passed the event type, a pointer to the private event
+ * structure that is specific to that event type, and a data pointer that is
+ * provided in this call as the @p data parameter.
+ *
+ * When the callback @p func is called, it must return 1 or 0. If it returns
+ * 1, It will keep being called as per normal, for each handler set up for that
+ * event type. If it returns 0, it will cease processing handlers for that
+ * particular event, so all handler set to handle that event type that have not
+ * already been called, will not be.
+ */
+Ecore_Event_Handler *
+ecore_event_handler_add(int type, int (*func) (void *data, int type, void *event), const void *data)
+{
+ Ecore_Event_Handler *eh;
+
+ if (!func) return NULL;
+ if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) return NULL;
+ eh = calloc(1, sizeof(Ecore_Event_Handler));
+ if (!eh) return NULL;
+ ECORE_MAGIC_SET(eh, ECORE_MAGIC_EVENT_HANDLER);
+ eh->type = type;
+ eh->func = func;
+ eh->data = (void *)data;
+ if (type >= (event_handlers_num - 1))
+ {
+ int p_alloc_num;
+
+ p_alloc_num = event_handlers_alloc_num;
+ event_handlers_num = type + 1;
+ if (event_handlers_num > event_handlers_alloc_num)
+ {
+ Ecore_Event_Handler **new_handlers;
+ int i;
+
+ event_handlers_alloc_num = ((event_handlers_num + 16) / 16) * 16;
+ new_handlers = realloc(event_handlers, event_handlers_alloc_num * sizeof(Ecore_Event_Handler *));
+ if (!new_handlers)
+ {
+ free(eh);
+ return NULL;
+ }
+ event_handlers = new_handlers;
+ for (i = p_alloc_num; i < event_handlers_alloc_num; i++)
+ event_handlers[i] = NULL;
+ }
+ }
+ event_handlers[type] = _ecore_list_append(event_handlers[type], eh);
+ return eh;
+}
+
+/**
+ * Delete an event handler.
+ * @param event_handler Event handler handle to delete
+ * @return Data passed to handler
+ *
+ * Delete a specified event handler from the handler list. On success this will
+ * delete the event handler and return the pointer passed as @p data when the
+ * handler was added by ecore_event_handler_add(). On failure NULL will be
+ * returned. Once a handler is deleted it will no longer be called.
+ */
+void *
+ecore_event_handler_del(Ecore_Event_Handler *event_handler)
+{
+ Ecore_Oldlist_Data *node;
+
+ if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER,
+ "ecore_event_handler_del");
+ return NULL;
+ }
+ event_handler->delete_me = 1;
+ node = calloc(1, sizeof(Ecore_Oldlist_Data));
+ node->data = event_handler;
+ event_handlers_delete_list = _ecore_list_append(event_handlers_delete_list, node);
+ return event_handler->data;
+}
+
+static void _ecore_event_generic_free (void *data __UNUSED__, void *event)
+{
+ free (event);
+}
+
+/**
+ * Add an event to the event queue.
+ * @param type The event type to add to the end of the event queue
+ * @param ev The private data structure for this event type
+ * @param func_free The function to be called to free this private structure
+ * @param data The data pointer to be passed to the free function
+ * @return A Handle for that event
+ *
+ * On success this function returns a handle to an event on the event queue, or
+ * NULL if it fails. If it succeeds, an event of type @p type will be added
+ * to the queue for processing by event handlers added by
+ * ecore_event_handler_add(). The @p ev parameter will be a pointer to the event
+ * private data that is specific to that event type. When the event is no
+ * longer needed, @p func_free will be called and passed the private sructure
+ * pointer for cleaning up. If @p func_free is NULL, free() will be called
+ * with the private structure pointer.
+ * func_free is passed @p data as its data parameter.
+ */
+Ecore_Event *
+ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data)
+{
+ if (!ev) return NULL;
+ if (type <= ECORE_EVENT_NONE) return NULL;
+ if (type >= event_id_max) return NULL;
+ if (!func_free) func_free = _ecore_event_generic_free;
+ return _ecore_event_add(type, ev, func_free, data);
+}
+
+/**
+ * Delete an event from the queue.
+ * @param event The event handle to delete
+ * @return The data pointer originally set for the event free function
+ *
+ * This deletes the event @p event from the event queue, and returns the
+ * @p data parameer originally set when adding it with ecore_event_add(). This
+ * does not immediately call the free function, and it may be called later on
+ * cleanup, and so if the free function depends on the data pointer to work,
+ * you should defer cleaning of this till the free function is called later.
+ */
+void *
+ecore_event_del(Ecore_Event *event)
+{
+ if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT))
+ {
+ ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT,
+ "ecore_event_del");
+ return NULL;
+ }
+ event->delete_me = 1;
+ return event->data;
+}
+
+/**
+ * Allocate a new event type id sensibly and return the new id.
+ * @return A new event type id.
+ *
+ * This function allocates a new event type id and returns it. Once an event
+ * type has been allocated it can never be de-allocated during the life of
+ * the program. There is no guarantee of the contents of this event ID, or how
+ * it is calculated, except that the ID will be unique to the current instance
+ * of the process.
+ */
+int
+ecore_event_type_new(void)
+{
+ event_id_max++;
+ return event_id_max - 1;
+}
+
+/**
+ * Add a filter the current event queue.
+ * @param func_start Function to call just before filtering and return data
+ * @param func_filter Function to call on each event
+ * @param func_end Function to call after the queu has been filtered
+ * @param data Data to pass to the filter functions
+ * @return A filter handle
+ *
+ * This adds a filter to call callbacks to loop through the event queue and
+ * filter events out of the queue. On failure NULL is returned. On success a
+ * Filter handle is returned. Filters are called on the queue just before
+ * Event handler processing to try and remove redundant events. Just as
+ * processing starts @p func_start is called and passed the @p data pointer.
+ * This function returns a pointer that is used as loop_data that is now passed to
+ * @p func_filter as loop_data. @p func_filter is also passed @p data and the
+ * event type and private event structure. If this callback returns 0, the
+ * event is removed from the queue. If it returns 1, the event is kept. When
+ * processing is finished @p func_end is called and is passed the loop_data
+ * and @p data pointer to clean up.
+ */
+Ecore_Event_Filter *
+ecore_event_filter_add(void * (*func_start) (void *data), int (*func_filter) (void *data, void *loop_data, int type, void *event), void (*func_end) (void *data, void *loop_data), const void *data)
+{
+ Ecore_Event_Filter *ef;
+
+ if (!func_filter) return NULL;
+ ef = calloc(1, sizeof(Ecore_Event_Filter));
+ if (!ef) return NULL;
+ ECORE_MAGIC_SET(ef, ECORE_MAGIC_EVENT_FILTER);
+ ef->func_start = func_start;
+ ef->func_filter = func_filter;
+ ef->func_end = func_end;
+ ef->data = (void *)data;
+ event_filters = _ecore_list_append(event_filters, ef);
+ return ef;
+}
+
+/**
+ * Delete an event filter.
+ * @param ef The event filter handle
+ * @return The data set for the filter
+ *
+ * Delete a filter that has been added by its @p ef handle. On success this
+ * will return the data pointer set when this filter was added. On failure
+ * NULL is returned.
+ */
+void *
+ecore_event_filter_del(Ecore_Event_Filter *ef)
+{
+ if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER))
+ {
+ ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER,
+ "ecore_event_filter_del");
+ return NULL;
+ }
+ ef->delete_me = 1;
+ event_filters_delete_me = 1;
+ return ef->data;
+}
+
+/**
+ * Return the current event type being handled.
+ * @return The current event type being handled if inside a handler callback
+ *
+ * If the program is currently inside an Ecore event handler callback this
+ * will return the type of the current event being processed. If Ecore is
+ * not inside an event handler, ECORE_EVENT_NONE is returned.
+ *
+ * This is useful when certain Ecore modules such as Ecore_Evas "swallow"
+ * events and not all the original information is passed on. In special cases
+ * this extra information may be useful or needed and using this call can let
+ * the program know if the event type being handled is one it wants to get more
+ * information about.
+ */
+int
+ecore_event_current_type_get(void)
+{
+ return ecore_raw_event_type;
+}
+
+/**
+ * Return the current event type pointer handled.
+ * @return The current event pointer being handled if inside a handler callback
+ *
+ * If the program is currently inside an Ecore event handler callback this
+ * will return the pointer of the current event being processed. If Ecore is
+ * not inside an event handler, NULL will be returned.
+ *
+ * This is useful when certain Ecore modules such as Ecore_Evas "swallow"
+ * events and not all the original information is passed on. In special cases
+ * this extra information may be useful or needed and using this call can let
+ * the program access the event data if the type of the event is handled by
+ * the program.
+ */
+void *
+ecore_event_current_event_get(void)
+{
+ return ecore_raw_event_event;
+}
+
+void
+_ecore_event_shutdown(void)
+{
+ int i;
+
+ while (events) _ecore_event_del(events);
+ for (i = 0; i < event_handlers_num; i++)
+ {
+ while (event_handlers[i])
+ {
+ Ecore_Event_Handler *eh;
+
+ eh = event_handlers[i];
+ event_handlers[i] = _ecore_list_remove(event_handlers[i], eh);
+ ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
+ free(eh);
+ }
+ }
+ while (event_handlers_delete_list)
+ {
+ Ecore_Oldlist_Data *ehd;
+
+ ehd = event_handlers_delete_list;
+ event_handlers_delete_list = _ecore_list_remove(event_handlers_delete_list, ehd);
+ free(ehd);
+ }
+ if (event_handlers) free(event_handlers);
+ event_handlers = NULL;
+ event_handlers_num = 0;
+ event_handlers_alloc_num = 0;
+ while (event_filters)
+ {
+ Ecore_Event_Filter *ef;
+
+ ef = event_filters;
+ event_filters = _ecore_list_remove(event_filters, ef);
+ ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
+ free(ef);
+ }
+ event_filters_delete_me = 0;
+}
+
+int
+_ecore_event_exist(void)
+{
+ if (events) return 1;
+ return 0;
+}
+
+Ecore_Event *
+_ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data)
+{
+ Ecore_Event *e;
+
+ e = calloc(1, sizeof(Ecore_Event));
+ if (!e) return NULL;
+ ECORE_MAGIC_SET(e, ECORE_MAGIC_EVENT);
+ e->type = type;
+ e->event = ev;
+ e->func_free = func_free;
+ e->data = data;
+ events = _ecore_list_append(events, e);
+ events_num++;
+ return e;
+}
+
+void *
+_ecore_event_del(Ecore_Event *event)
+{
+ void *data;
+
+ data = event->data;
+ event->func_free(event->data, event->event);
+ events = _ecore_list_remove(events, event);
+ ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE);
+ free(event);
+ events_num--;
+ return data;
+}
+
+void
+_ecore_event_call(void)
+{
+ Ecore_Oldlist *l, *ll;
+ Ecore_Event *e;
+ Ecore_Event_Filter *ef;
+ Ecore_Event_Handler *eh;
+ Ecore_Oldlist_Data *ehd;
+ int handle_count;
+
+ for (l = (Ecore_Oldlist *)event_filters; l; l = l->next)
+ {
+ ef = (Ecore_Event_Filter *)l;
+ if (!ef->delete_me)
+ {
+ if (ef->func_start)
+ ef->loop_data = ef->func_start(ef->data);
+ for (ll = (Ecore_Oldlist *)events; ll; ll = ll->next)
+ {
+ Ecore_Event *e;
+
+ e = (Ecore_Event *)ll;
+ if (!ef->func_filter(ef->loop_data, ef->data,
+ e->type, e->event))
+ {
+// printf("FILTER SAID TO DEL ev %p\n", e->event);
+ ecore_event_del(e);
+ }
+ }
+ if (ef->func_end)
+ ef->func_end(ef->data, ef->loop_data);
+ }
+ }
+ if (event_filters_delete_me)
+ {
+ for (l = (Ecore_Oldlist *)event_filters; l;)
+ {
+ ef = (Ecore_Event_Filter *)l;
+ l = l->next;
+ if (ef->delete_me)
+ {
+ event_filters = _ecore_list_remove(event_filters, ef);
+ ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
+ free(ef);
+ }
+ }
+ event_filters_delete_me = 0;
+ }
+// printf("EVENT BATCH...\n");
+ for (l = (Ecore_Oldlist *)events; l; l = l->next)
+ {
+ e = (Ecore_Event *)l;
+ if (!e->delete_me)
+ {
+ handle_count = 0;
+ ecore_raw_event_type = e->type;
+ ecore_raw_event_event = e->event;
+// printf("HANDLE ev type %i, %p\n", e->type, e->event);
+ if ((e->type >= 0) && (e->type < event_handlers_num))
+ {
+ for (ll = (Ecore_Oldlist *)event_handlers[e->type]; ll; ll = ll->next)
+ {
+ eh = (Ecore_Event_Handler *)ll;
+ if (!eh->delete_me)
+ {
+ handle_count++;
+ if (!eh->func(eh->data, e->type, e->event))
+ break; /* 0 == "call no further handlers" */
+ }
+ }
+ }
+ /* if no handlers were set for EXIT signal - then default is */
+ /* to quit the main loop */
+ if ((e->type == ECORE_EVENT_SIGNAL_EXIT) && (handle_count == 0))
+ ecore_main_loop_quit();
+ }
+ }
+ ecore_raw_event_type = ECORE_EVENT_NONE;
+ ecore_raw_event_event = NULL;
+
+ while (events) _ecore_event_del(events);
+ while (event_handlers_delete_list)
+ {
+ ehd = event_handlers_delete_list;
+ eh = ehd->data;
+ event_handlers[eh->type] = _ecore_list_remove(event_handlers[eh->type], eh);
+ event_handlers_delete_list = _ecore_list_remove(event_handlers_delete_list, ehd);
+ ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
+ free(eh);
+ free(ehd);
+ }
+}
+
+#ifndef WIN32
+void *
+_ecore_event_exe_exit_new(void)
+{
+ Ecore_Event_Exe_Exit *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Exe_Exit));
+ return e;
+}
+
+void
+_ecore_event_exe_exit_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Event_Exe_Exit *e;
+
+ e = ev;
+ if (e->exe) _ecore_exe_free(e->exe);
+ free(e);
+}
+#endif
+
+void *
+_ecore_event_signal_user_new(void)
+{
+ Ecore_Event_Signal_User *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Signal_User));
+ return e;
+}
+
+void *
+_ecore_event_signal_hup_new(void)
+{
+ Ecore_Event_Signal_Hup *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Signal_Hup));
+ return e;
+}
+
+void *
+_ecore_event_signal_exit_new(void)
+{
+ Ecore_Event_Signal_Exit *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Signal_Exit));
+ return e;
+}
+
+void *
+_ecore_event_signal_power_new(void)
+{
+ Ecore_Event_Signal_Power *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Signal_Power));
+ return e;
+}
+
+void *
+_ecore_event_signal_realtime_new(void)
+{
+ return calloc(1, sizeof(Ecore_Event_Signal_Realtime));
+}
diff --git a/ecore/src/lib/ecore/ecore_exe.c b/ecore/src/lib/ecore/ecore_exe.c
new file mode 100644
index 0000000..a91b35b
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_exe.c
@@ -0,0 +1,263 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+
+#include <sys/types.h>
+#include <signal.h>
+#include <unistd.h>
+
+#ifndef WIN32
+static Ecore_Exe *exes = NULL;
+
+/**
+ * @defgroup Ecore_Exe_Basic_Group Process Spawning Functions
+ *
+ * Functions that deal with spawned processes.
+ */
+
+/**
+ * Spawns a child process.
+ *
+ * This function forks and runs the given command using @c /bin/sh.
+ *
+ * Note that the process handle is only valid until a child process
+ * terminated event is received. After all handlers for the child process
+ * terminated event have been called, the handle will be freed by Ecore.
+ *
+ * @param exe_cmd The command to run with @c /bin/sh.
+ * @param data Data to attach to the returned process handle.
+ * @return A process handle to the spawned process.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+Ecore_Exe *
+ecore_exe_run(const char *exe_cmd, const void *data)
+{
+ Ecore_Exe *exe;
+ pid_t pid;
+
+ if (!exe_cmd) return NULL;
+ pid = fork();
+ if (pid)
+ {
+ exe = calloc(1, sizeof(Ecore_Exe));
+ if (!exe)
+ {
+ kill(pid, SIGKILL);
+ return NULL;
+ }
+ ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE);
+ exe->pid = pid;
+ exe->data = (void *)data;
+ exes = _ecore_list_append(exes, exe);
+ return exe;
+ }
+ setsid();
+ execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL);
+ exit(127);
+ return NULL;
+}
+
+/**
+ * Frees the given process handle.
+ *
+ * Note that the process that the handle represents is unaffected by this
+ * function.
+ *
+ * @param exe The given process handle.
+ * @return The data attached to the handle when @ref ecore_exe_run was
+ * called.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+void *
+ecore_exe_free(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
+ "ecore_exe_free");
+ return NULL;
+ }
+ return _ecore_exe_free(exe);
+}
+
+/**
+ * Retrieves the process ID of the given spawned process.
+ * @param exe Handle to the given spawned process.
+ * @return The process ID on success. @c -1 otherwise.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+pid_t
+ecore_exe_pid_get(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
+ "ecore_exe_pid_get");
+ return -1;
+ }
+ return exe->pid;
+}
+
+/**
+ * Retrieves the data attached to the given process handle.
+ * @param exe The given process handle.
+ * @return The data pointer attached to @p exe.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+void *
+ecore_exe_data_get(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
+ "ecore_exe_data_get");
+ return NULL;
+ }
+ return exe->data;
+}
+
+/**
+ * @defgroup Ecore_Exe_Signal_Group Spawned Process Signal Functions
+ *
+ * Functions that send signals to spawned processes.
+ */
+
+/**
+ * Pauses the given process by sending it a @c SIGSTOP signal.
+ * @param exe Process handle to the given process.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+void
+ecore_exe_pause(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
+ "ecore_exe_pause");
+ return;
+ }
+ kill(exe->pid, SIGSTOP);
+}
+
+/**
+ * Continues the given paused process by sending it a @c SIGCONT signal.
+ * @param exe Process handle to the given process.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+void
+ecore_exe_continue(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
+ "ecore_exe_continue");
+ return;
+ }
+ kill(exe->pid, SIGCONT);
+}
+
+/**
+ * Sends the given spawned process a terminate (@c SIGTERM) signal.
+ * @param exe Process handle to the given process.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+void
+ecore_exe_terminate(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
+ "ecore_exe_terminate");
+ return;
+ }
+ kill(exe->pid, SIGTERM);
+}
+
+/**
+ * Kills the given spawned process by sending it a @c SIGKILL signal.
+ * @param exe Process handle to the given process.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+void
+ecore_exe_kill(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
+ "ecore_exe_kill");
+ return;
+ }
+ kill(exe->pid, SIGKILL);
+}
+
+/**
+ * Sends a @c SIGUSR signal to the given spawned process.
+ * @param exe Process handle to the given process.
+ * @param num The number user signal to send. Must be either 1 or 2, or
+ * the signal will be ignored.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+void
+ecore_exe_signal(Ecore_Exe *exe, int num)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
+ "ecore_exe_signal");
+ return;
+ }
+ if (num == 1)
+ kill(exe->pid, SIGUSR1);
+ else if (num == 2)
+ kill(exe->pid, SIGUSR2);
+}
+
+/**
+ * Sends a @c SIGHUP signal to the given spawned process.
+ * @param exe Process handle to the given process.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+void
+ecore_exe_hup(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
+ "ecore_exe_hup");
+ return;
+ }
+ kill(exe->pid, SIGHUP);
+}
+
+void
+_ecore_exe_shutdown(void)
+{
+ while (exes) _ecore_exe_free(exes);
+}
+
+Ecore_Exe *
+_ecore_exe_find(pid_t pid)
+{
+ Ecore_Oldlist *l;
+
+ for (l = (Ecore_Oldlist *)exes; l; l = l->next)
+ {
+ Ecore_Exe *exe;
+
+ exe = (Ecore_Exe *)l;
+ if (exe->pid == pid) return exe;
+ }
+ return NULL;
+}
+
+void *
+_ecore_exe_free(Ecore_Exe *exe)
+{
+ void *data;
+
+ data = exe->data;
+ exes = _ecore_list_remove(exes, exe);
+ ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE);
+ free(exe);
+ return data;
+}
+#endif
diff --git a/ecore/src/lib/ecore/ecore_hash.c b/ecore/src/lib/ecore/ecore_hash.c
new file mode 100644
index 0000000..0fde533
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_hash.c
@@ -0,0 +1,713 @@
+#include <Ecore.h>
+
+#define ECORE_HASH_CHAIN_MAX 3
+
+#define ECORE_COMPUTE_HASH(hash, key) hash->hash_func(key) % \
+ ecore_prime_table[hash->size];
+
+#define ECORE_HASH_INCREASE(hash) ((hash && hash->size < PRIME_MAX) ? \
+ (hash->nodes / ecore_prime_table[hash->size]) > \
+ ECORE_HASH_CHAIN_MAX : FALSE)
+#define ECORE_HASH_REDUCE(hash) ((hash && hash->size > PRIME_MIN) ? \
+ (double)hash->nodes / (double)ecore_prime_table[hash->size-1] \
+ < ((double)ECORE_HASH_CHAIN_MAX * 0.375) : FALSE)
+
+
+/* Private hash manipulation functions */
+static int _ecore_hash_add_node(Ecore_Hash *hash, Ecore_Hash_Node *node);
+static Ecore_Hash_Node * _ecore_hash_get_node(Ecore_Hash *hash, void *key);
+static int _ecore_hash_increase(Ecore_Hash *hash);
+static int _ecore_hash_decrease(Ecore_Hash *hash);
+inline int _ecore_hash_rehash(Ecore_Hash *hash, Ecore_List **old_table, int old_size);
+static int _ecore_hash_bucket_destroy(Ecore_List *list, Ecore_Free_Cb keyd,
+ Ecore_Free_Cb valued);
+inline Ecore_Hash_Node * _ecore_hash_get_bucket(Ecore_Hash *hash, Ecore_List *bucket,
+ void *key);
+
+static Ecore_Hash_Node *_ecore_hash_node_new(void *key, void *value);
+static int _ecore_hash_node_init(Ecore_Hash_Node *node, void *key, void *value);
+static int _ecore_hash_node_destroy(Ecore_Hash_Node *node, Ecore_Free_Cb keyd,
+ Ecore_Free_Cb valued);
+
+/**
+ * @defgroup Ecore_Data_Hash_ADT_Creation_Group Hash Creation Functions
+ *
+ * Functions that create hash tables.
+ */
+
+/**
+ * Creates and initializes a new hash
+ * @param hash_func The function for determining hash position.
+ * @param compare The function for comparing node keys.
+ * @return @c NULL on error, a new hash on success.
+ * @ingroup Ecore_Data_Hash_ADT_Creation_Group
+ */
+Ecore_Hash *ecore_hash_new(Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare)
+{
+ Ecore_Hash *new_hash = (Ecore_Hash *)malloc(sizeof(Ecore_Hash));
+ if (!new_hash)
+ return NULL;
+
+ if (!ecore_hash_init(new_hash, hash_func, compare)) {
+ FREE(new_hash);
+ return NULL;
+ }
+
+ return new_hash;
+}
+
+/**
+ * Initializes the given hash.
+ * @param hash The given hash.
+ * @param hash_func The function used for hashing node keys.
+ * @param compare The function used for comparing node keys.
+ * @return @c TRUE on success, @c FALSE on an error.
+ * @ingroup Ecore_Data_Hash_ADT_Creation_Group
+ */
+int ecore_hash_init(Ecore_Hash *hash, Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare)
+{
+ CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
+
+ memset(hash, 0, sizeof(Ecore_Hash));
+
+ hash->hash_func = hash_func;
+ hash->compare = compare;
+
+ hash->buckets = (Ecore_List **)malloc(ecore_prime_table[0] *
+ sizeof(Ecore_List *));
+ memset(hash->buckets, 0, ecore_prime_table[0] * sizeof(Ecore_List *));
+
+ ECORE_INIT_LOCKS(hash);
+
+ return TRUE;
+}
+
+/**
+ * @defgroup Ecore_Data_Hash_ADT_Destruction_Group Hash Destruction Functions
+ *
+ * Functions that destroy hash tables and their contents.
+ */
+
+/**
+ * Sets the function to destroy the keys of the given hash.
+ * @param hash The given hash.
+ * @param function The function used to free the node keys.
+ * @return @c TRUE on success, @c FALSE on error.
+ * @ingroup Ecore_Data_Hash_ADT_Destruction_Group
+ */
+int ecore_hash_set_free_key(Ecore_Hash *hash, Ecore_Free_Cb function)
+{
+ CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
+ CHECK_PARAM_POINTER_RETURN("function", function, FALSE);
+
+ ECORE_WRITE_LOCK(hash);
+ hash->free_key = function;
+ ECORE_WRITE_UNLOCK(hash);
+
+ return TRUE;
+}
+
+/**
+ * Sets the function to destroy the values in the given hash.
+ * @param hash The given hash.
+ * @param function The function that will free the node values.
+ * @return @c TRUE on success, @c FALSE on error
+ * @ingroup Ecore_Data_Hash_ADT_Destruction_Group
+ */
+int ecore_hash_set_free_value(Ecore_Hash *hash, Ecore_Free_Cb function)
+{
+ CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
+ CHECK_PARAM_POINTER_RETURN("function", function, FALSE);
+
+ ECORE_WRITE_LOCK(hash);
+ hash->free_value = function;
+ ECORE_WRITE_UNLOCK(hash);
+
+ return TRUE;
+}
+
+/**
+ * @defgroup Ecore_Data_Hash_ADT_Data_Group Hash Data Functions
+ *
+ * Functions that set, access and delete values from the hash tables.
+ */
+
+/**
+ * Sets a key-value pair in the given hash table.
+ * @param hash The given hash table.
+ * @param key The key.
+ * @param value The value.
+ * @return @c TRUE if successful, @c FALSE if not.
+ * @ingroup Ecore_Data_Hash_ADT_Data_Group
+ */
+int ecore_hash_set(Ecore_Hash *hash, void *key, void *value)
+{
+ int ret = FALSE;
+ Ecore_Hash_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
+
+ ECORE_WRITE_LOCK(hash);
+ node = _ecore_hash_get_node(hash, key);
+ if (node)
+ node->value = value;
+ else {
+ node = _ecore_hash_node_new(key, value);
+ if (node)
+ ret = _ecore_hash_add_node(hash, node);
+ }
+ ECORE_WRITE_UNLOCK(hash);
+
+ return ret;
+}
+
+/**
+ * Frees the hash table and the data contained inside it.
+ * @param hash The hash table to destroy.
+ * @return @c TRUE on success, @c FALSE on error.
+ * @ingroup Ecore_Data_Hash_ADT_Destruction_Group
+ */
+void ecore_hash_destroy(Ecore_Hash *hash)
+{
+ unsigned int i = 0;
+
+ CHECK_PARAM_POINTER("hash", hash);
+
+ ECORE_WRITE_LOCK(hash);
+
+ while (i < ecore_prime_table[hash->size]) {
+ if (hash->buckets[i])
+ _ecore_hash_bucket_destroy(hash->buckets[i],
+ hash->free_key, hash->free_value);
+ i++;
+ }
+
+ FREE(hash->buckets);
+
+ ECORE_WRITE_UNLOCK(hash);
+ ECORE_DESTROY_LOCKS(hash);
+
+ FREE(hash);
+
+ return;
+}
+
+/**
+ * @defgroup Ecore_Data_Hash_ADT_Traverse_Group Hash Traverse Functions
+ *
+ * Functions that iterate through hash tables.
+ */
+
+/**
+ * Runs the @p for_each_func function on each entry in the given hash.
+ * @param hash The given hash.
+ * @param for_each_func The function that each entry is passed to.
+ * @param user_data a pointer passed to calls of for_each_func
+ * @return TRUE on success, FALSE otherwise.
+ * @ingroup Ecore_Data_Hash_ADT_Traverse_Group
+ */
+int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func,
+ void *user_data)
+{
+ unsigned int i = 0;
+
+ CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
+ CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE);
+
+ ECORE_READ_LOCK(hash);
+
+ while (i < ecore_prime_table[hash->size]) {
+ if (hash->buckets[i]) {
+ Ecore_Hash_Node *node;
+
+ ecore_list_goto_first(hash->buckets[i]);
+ while ((node = ecore_list_next(hash->buckets[i]))) {
+ for_each_func(node, user_data);
+ }
+ }
+ i++;
+ }
+
+ ECORE_READ_UNLOCK(hash);
+
+ return TRUE;
+}
+
+/**
+ * Retrieves an ecore_list of all keys in the given hash.
+ * @param hash The given hash.
+ * @return new ecore_list on success, NULL otherwise
+ * @ingroup Ecore_Data_Hash_ADT_Traverse_Group
+ */
+Ecore_List *ecore_hash_keys(Ecore_Hash *hash)
+{
+ unsigned int i = 0;
+ Ecore_List *keys;
+
+ CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
+
+ ECORE_READ_LOCK(hash);
+
+ keys = ecore_list_new();
+
+ while (i < ecore_prime_table[hash->size]) {
+ if (hash->buckets[i]) {
+ Ecore_Hash_Node *node;
+
+ ecore_list_goto_first(hash->buckets[i]);
+ while ((node = ecore_list_next(hash->buckets[i]))) {
+ ecore_list_append(keys, node->key);
+ }
+ }
+ i++;
+ }
+
+ ECORE_READ_UNLOCK(hash);
+
+ return keys;
+}
+
+/**
+ * Prints the distribution of the given hash table for graphing.
+ * @param hash The given hash table.
+ */
+void
+ecore_hash_dump_graph(Ecore_Hash *hash)
+{
+ unsigned int i;
+
+ for (i = 0; i < ecore_prime_table[hash->size]; i++)
+ if (hash->buckets[i])
+ printf("%d\t%u\n", i, ecore_list_nodes(hash->buckets[i]));
+ else
+ printf("%d\t0\n", i);
+}
+
+static int
+_ecore_hash_bucket_destroy(Ecore_List *list, Ecore_Free_Cb keyd, Ecore_Free_Cb valued)
+{
+ Ecore_Hash_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ while ((node = ecore_list_remove_first(list)) != NULL)
+ _ecore_hash_node_destroy(node, keyd, valued);
+
+ ecore_list_destroy(list);
+
+ return TRUE;
+}
+
+/*
+ * @brief Add the node to the hash table
+ * @param hash: the hash table to add the key
+ * @param node: the node to add to the hash table
+ * @return Returns FALSE on error, TRUE on success
+ */
+static int
+_ecore_hash_add_node(Ecore_Hash *hash, Ecore_Hash_Node *node)
+{
+ unsigned int hash_val;
+
+ CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ /* Check to see if the hash needs to be resized */
+ if (ECORE_HASH_INCREASE(hash))
+ _ecore_hash_increase(hash);
+
+ /* Compute the position in the table */
+ if (!hash->hash_func)
+ hash_val = (unsigned int)node->key %
+ ecore_prime_table[hash->size];
+ else
+ hash_val = ECORE_COMPUTE_HASH(hash, node->key);
+
+ /* Create the list if it's not already present */
+ if (!hash->buckets[hash_val])
+ hash->buckets[hash_val] = ecore_list_new();
+
+ /* Append the node to the list at the index position */
+ if (!ecore_list_prepend(hash->buckets[hash_val], node))
+ return FALSE;
+ hash->nodes++;
+
+ return TRUE;
+}
+
+/**
+ * Retrieves the value associated with the given key from the given hash
+ * table.
+ * @param hash The given hash table.
+ * @param key The key to search for.
+ * @return The value corresponding to key on success, @c NULL otherwise.
+ * @ingroup Ecore_Data_Hash_ADT_Data_Group
+ */
+void *ecore_hash_get(Ecore_Hash *hash, void *key)
+{
+ void *data;
+ Ecore_Hash_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
+
+ node = _ecore_hash_get_node(hash, key);
+ if (!node)
+ return NULL;
+
+ ECORE_READ_LOCK(node);
+ data = node->value;
+ ECORE_READ_UNLOCK(node);
+
+ return data;
+}
+
+
+/**
+ * Removes the value associated with the given key in the given hash
+ * table.
+ * @param hash The given hash table.
+ * @param key The key to search for.
+ * @return The value corresponding to the key on success. @c NULL is
+ * returned if there is an error.
+ * @ingroup Ecore_Data_Hash_ADT_Data_Group
+ */
+void *ecore_hash_remove(Ecore_Hash *hash, void *key)
+{
+ Ecore_Hash_Node *node = NULL;
+ Ecore_List *list;
+ unsigned int hash_val;
+ void *ret = NULL;
+
+ CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
+
+ ECORE_WRITE_LOCK(hash);
+
+ /* Compute the position in the table */
+ if (!hash->hash_func)
+ hash_val = (unsigned int)key % ecore_prime_table[hash->size];
+ else
+ hash_val = ECORE_COMPUTE_HASH(hash, key);
+
+ /*
+ * If their is a list that could possibly hold the key/value pair
+ * traverse it and remove the hash node.
+ */
+ if (hash->buckets[hash_val]) {
+ list = hash->buckets[hash_val];
+ ecore_list_goto_first(list);
+
+ /*
+ * Traverse the list to find the specified key
+ */
+ if (hash->compare) {
+ while ((node = ecore_list_current(list)) &&
+ hash->compare(node->key, key) != 0)
+ ecore_list_next(list);
+ }
+ else {
+ while ((node = ecore_list_current(list)) &&
+ node->key != key)
+ ecore_list_next(list);
+ }
+
+ if (node) {
+ ecore_list_remove(list);
+ ret = node->value;
+ node->value = NULL;
+ _ecore_hash_node_destroy(node, hash->free_key,
+ hash->free_value);
+ }
+ }
+
+ if (ECORE_HASH_REDUCE(hash))
+ _ecore_hash_decrease(hash);
+
+ ECORE_WRITE_UNLOCK(hash);
+
+ return ret;
+}
+
+/*
+ * @brief Retrieve the node associated with key
+ * @param hash: the hash table to search for the key
+ * @param key: the key to search for in the hash table
+ * @return Returns NULL on error, node corresponding to key on success
+ */
+static Ecore_Hash_Node *
+_ecore_hash_get_node(Ecore_Hash *hash, void *key)
+{
+ unsigned int hash_val;
+ Ecore_Hash_Node *node = NULL;
+
+ CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
+
+ ECORE_READ_LOCK(hash);
+
+ /* Compute the position in the table */
+ if (!hash->hash_func)
+ hash_val = (unsigned int)key % ecore_prime_table[hash->size];
+ else
+ hash_val = ECORE_COMPUTE_HASH(hash, key);
+
+ /* Grab the bucket at the specified position */
+ if (hash->buckets[hash_val])
+ node = _ecore_hash_get_bucket(hash, hash->buckets[hash_val], key);
+
+ ECORE_READ_UNLOCK(hash);
+
+ return node;
+}
+
+/*
+ * @brief Search the hash bucket for a specified key
+ * @param hash: the hash table to retrieve the comparison function
+ * @param bucket: the list to search for the key
+ * @param key: the key to search for in the list
+ * @return Returns NULL on error or not found, the found node on success
+ */
+inline Ecore_Hash_Node *
+_ecore_hash_get_bucket(Ecore_Hash *hash, Ecore_List *bucket, void *key)
+{
+ Ecore_Hash_Node *node = NULL;
+
+ ECORE_READ_LOCK(hash);
+ ecore_list_goto_first(bucket);
+
+ /*
+ * Traverse the list to find the desired node, if the node is in the
+ * list, then return the node.
+ */
+ if (hash->compare) {
+ while ((node = ecore_list_next(bucket)) != NULL) {
+ ECORE_READ_LOCK(node);
+ if (hash->compare(node->key, key) == 0) {
+ ECORE_READ_UNLOCK(node);
+ ECORE_READ_UNLOCK(hash);
+ return node;
+ }
+ ECORE_READ_UNLOCK(node);
+ }
+ }
+ else {
+ while ((node = ecore_list_next(bucket)) != NULL) {
+ ECORE_READ_LOCK(node);
+ if (node->key == key) {
+ ECORE_READ_UNLOCK(node);
+ ECORE_READ_UNLOCK(hash);
+ return node;
+ }
+ ECORE_READ_UNLOCK(node);
+ }
+ }
+ ECORE_READ_UNLOCK(hash);
+
+ return NULL;
+}
+
+/*
+ * @brief Increase the size of the hash table by approx. 2 * current size
+ * @param hash: the hash table to increase the size of
+ * @return Returns TRUE on success, FALSE on error
+ */
+static int
+_ecore_hash_increase(Ecore_Hash *hash)
+{
+ void *old;
+
+ CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
+
+ /* Max size reached so return FALSE */
+ if (hash->size == PRIME_TABLE_MAX)
+ return FALSE;
+
+ /*
+ * Increase the size of the hash and save a pointer to the old data
+ */
+ hash->size++;
+ old = hash->buckets;
+
+ /*
+ * Allocate a new bucket area, of the new larger size
+ */
+ hash->buckets = (Ecore_List **)calloc(ecore_prime_table[hash->size],
+ sizeof(Ecore_List *));
+
+ /*
+ * Make sure the allocation succeeded, if not replace the old data and
+ * return a failure.
+ */
+ if (!hash->buckets) {
+ hash->buckets = old;
+ hash->size--;
+ return FALSE;
+ }
+ hash->nodes = 0;
+
+ /*
+ * Now move all of the old data into the new bucket area
+ */
+ if (_ecore_hash_rehash(hash, old, hash->size - 1)) {
+ FREE(old);
+ return TRUE;
+ }
+
+ /*
+ * Free the old buckets regardless of success.
+ */
+ FREE(old);
+
+ return FALSE;
+}
+
+/*
+ * @brief Decrease the size of the hash table by < 1/2 * current size
+ * @param hash: the hash table to decrease the size of
+ * @return Returns TRUE on success, FALSE on error
+ */
+static int
+_ecore_hash_decrease(Ecore_Hash *hash)
+{
+ Ecore_List **old;
+
+ CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
+
+ if (ecore_prime_table[hash->size] == PRIME_MIN)
+ return FALSE;
+
+ /*
+ * Decrease the hash size and store a pointer to the old data
+ */
+ hash->size--;
+ old = hash->buckets;
+
+ /*
+ * Allocate a new area to store the data
+ */
+ hash->buckets = (Ecore_List **)malloc(ecore_prime_table[hash->size] *
+ sizeof(Ecore_List *));
+
+ /*
+ * Make sure allocation succeeded otherwise rreturn to the previous
+ * state
+ */
+ if (!hash->buckets) {
+ hash->buckets = old;
+ hash->size++;
+ return FALSE;
+ }
+
+ /*
+ * Zero out the new area
+ */
+ memset(hash->buckets, 0, ecore_prime_table[hash->size]
+ * sizeof(Ecore_List *));
+ hash->nodes = 0;
+
+ if (_ecore_hash_rehash(hash, old, hash->size - 1)) {
+ FREE(old);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * @brief Rehash the nodes of a table into the hash table
+ * @param hash: the hash to place the nodes of the table
+ * @param table: the table to remove the nodes from and place in hash
+ * @return Returns TRUE on success, FALSE on success
+ */
+inline int
+_ecore_hash_rehash(Ecore_Hash *hash, Ecore_List **old_table, int old_size)
+{
+ unsigned int i;
+ Ecore_Hash_Node *node;
+ Ecore_List *old;
+
+ CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
+ CHECK_PARAM_POINTER_RETURN("old_table", old_table, FALSE);
+
+ for (i = 0; i < ecore_prime_table[old_size]; i++) {
+ /* Hash into a new list to avoid loops of rehashing the same
+ * nodes */
+ old = old_table[i];
+ old_table[i] = NULL;
+
+ /* Loop through re-adding each node to the hash table */
+ while (old && (node = ecore_list_remove_last(old))) {
+ _ecore_hash_add_node(hash, node);
+ }
+
+ /* Now free up the old list space */
+ if (old)
+ ecore_list_destroy(old);
+ }
+
+ return TRUE;
+}
+
+/*
+ * @brief Create a new hash node for key and value storage
+ * @param key: the key for this node
+ * @param value: the value that the key references
+ * @return Returns NULL on error, a new hash node on success
+ */
+static Ecore_Hash_Node *
+_ecore_hash_node_new(void *key, void *value)
+{
+ Ecore_Hash_Node *node;
+
+ node = (Ecore_Hash_Node *)malloc(sizeof(Ecore_Hash_Node));
+ if (!node)
+ return NULL;
+
+ if (!_ecore_hash_node_init(node, key, value)) {
+ FREE(node);
+ return NULL;
+ }
+
+ return node;
+}
+
+/*
+ * @brief Initialize a hash node to some sane default values
+ * @param node: the node to set the values
+ * @param key: the key to reference this node
+ * @param value: the value that key refers to
+ * @return Returns TRUE on success, FALSE on error
+ */
+static int
+_ecore_hash_node_init(Ecore_Hash_Node *node, void *key, void *value)
+{
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ ECORE_INIT_LOCKS(node);
+ node->key = key;
+ node->value = value;
+
+ return TRUE;
+}
+
+/*
+ * @brief Destroy a node and call the specified callbacks to free data
+ * @param node: the node to be destroyed
+ * @param keyd: the function to free the key
+ * @param valued: the function to free the value
+ * @return Returns TRUE on success, FALSE on error
+ */
+static int
+_ecore_hash_node_destroy(Ecore_Hash_Node *node, Ecore_Free_Cb keyd,
+ Ecore_Free_Cb valued)
+{
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ if (keyd)
+ keyd(node->key);
+
+ if (valued)
+ valued(node->value);
+
+ FREE(node);
+
+ return TRUE;
+}
diff --git a/ecore/src/lib/ecore/ecore_idle_enterer.c b/ecore/src/lib/ecore/ecore_idle_enterer.c
new file mode 100644
index 0000000..7b8c967
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_idle_enterer.c
@@ -0,0 +1,105 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+
+static Ecore_Idle_Enterer *idle_enterers = NULL;
+static int idle_enterers_delete_me = 0;
+
+/**
+ * Add an idle enterer handler.
+ * @param func The function to call when entering an idle state.
+ * @param data The data to be passed to the @p func call
+ * @return A handle to the idle enterer callback if successful. Otherwise,
+ * NULL is returned.
+ * @ingroup Idle_Group
+ */
+Ecore_Idle_Enterer *
+ecore_idle_enterer_add(int (*func) (void *data), const void *data)
+{
+ Ecore_Idle_Enterer *ie;
+
+ if (!func) return NULL;
+ ie = calloc(1, sizeof(Ecore_Idle_Enterer));
+ if (!ie) return NULL;
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
+ ie->func = func;
+ ie->data = (void *)data;
+ idle_enterers = _ecore_list_append(idle_enterers, ie);
+ return ie;
+}
+
+/**
+ * Delete an idle enterer callback.
+ * @param idle_enterer The idle enterer to delete
+ * @return The data pointer passed to the idler enterer callback on success.
+ * NULL otherwise.
+ * @ingroup Idle_Group
+ */
+void *
+ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer)
+{
+ if (!ECORE_MAGIC_CHECK(idle_enterer, ECORE_MAGIC_IDLE_ENTERER))
+ {
+ ECORE_MAGIC_FAIL(idle_enterer, ECORE_MAGIC_IDLE_ENTERER,
+ "ecore_idle_enterer_del");
+ return NULL;
+ }
+ idle_enterer->delete_me = 1;
+ idle_enterers_delete_me = 1;
+ return idle_enterer->data;
+}
+
+void
+_ecore_idle_enterer_shutdown(void)
+{
+ while (idle_enterers)
+ {
+ Ecore_Idle_Enterer *ie;
+
+ ie = idle_enterers;
+ idle_enterers = _ecore_list_remove(idle_enterers, ie);
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
+ free(ie);
+ }
+ idle_enterers_delete_me = 0;
+}
+
+void
+_ecore_idle_enterer_call(void)
+{
+ Ecore_Oldlist *l;
+
+ for (l = (Ecore_Oldlist *)idle_enterers; l; l = l->next)
+ {
+ Ecore_Idle_Enterer *ie;
+
+ ie = (Ecore_Idle_Enterer *)l;
+ if (!ie->delete_me)
+ {
+ if (!ie->func(ie->data)) ecore_idle_enterer_del(ie);
+ }
+ }
+ if (idle_enterers_delete_me)
+ {
+ for (l = (Ecore_Oldlist *)idle_enterers; l;)
+ {
+ Ecore_Idle_Enterer *ie;
+
+ ie = (Ecore_Idle_Enterer *)l;
+ l = l->next;
+ if (ie->delete_me)
+ {
+ idle_enterers = _ecore_list_remove(idle_enterers, ie);
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
+ free(ie);
+ }
+ }
+ idle_enterers_delete_me = 0;
+ }
+}
+
+int
+_ecore_idle_enterer_exist(void)
+{
+ if (idle_enterers) return 1;
+ return 0;
+}
diff --git a/ecore/src/lib/ecore/ecore_idle_exiter.c b/ecore/src/lib/ecore/ecore_idle_exiter.c
new file mode 100644
index 0000000..1b8a6ae
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_idle_exiter.c
@@ -0,0 +1,104 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+
+static Ecore_Idle_Exiter *idle_exiters = NULL;
+static int idle_exiters_delete_me = 0;
+
+/**
+ * Add an idle exiter handler.
+ * @param func The function to call when exiting an idle state.
+ * @param data The data to be passed to the @p func call
+ * @return A handle to the idle exiter callback on success. NULL otherwise.
+ * @ingroup Idle_Group
+ */
+Ecore_Idle_Exiter *
+ecore_idle_exiter_add(int (*func) (void *data), const void *data)
+{
+ Ecore_Idle_Exiter *ie;
+
+ if (!func) return NULL;
+ ie = calloc(1, sizeof(Ecore_Idle_Exiter));
+ if (!ie) return NULL;
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_EXITER);
+ ie->func = func;
+ ie->data = (void *)data;
+ idle_exiters = _ecore_list_append(idle_exiters, ie);
+ return ie;
+}
+
+/**
+ * Delete an idle exiter handler from the list to be run on exiting idle state.
+ * @param idle_exiter The idle exiter to delete
+ * @return The data pointer that was being being passed to the handler if
+ * successful. NULL otherwise.
+ * @ingroup Idle_Group
+ */
+void *
+ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter)
+{
+ if (!ECORE_MAGIC_CHECK(idle_exiter, ECORE_MAGIC_IDLE_EXITER))
+ {
+ ECORE_MAGIC_FAIL(idle_exiter, ECORE_MAGIC_IDLE_EXITER,
+ "ecore_idle_exiter_del");
+ return NULL;
+ }
+ idle_exiter->delete_me = 1;
+ idle_exiters_delete_me = 1;
+ return idle_exiter->data;
+}
+
+void
+_ecore_idle_exiter_shutdown(void)
+{
+ while (idle_exiters)
+ {
+ Ecore_Idle_Exiter *ie;
+
+ ie = idle_exiters;
+ idle_exiters = _ecore_list_remove(idle_exiters, ie);
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
+ free(ie);
+ }
+ idle_exiters_delete_me = 0;
+}
+
+void
+_ecore_idle_exiter_call(void)
+{
+ Ecore_Oldlist *l;
+
+ for (l = (Ecore_Oldlist *)idle_exiters; l; l = l->next)
+ {
+ Ecore_Idle_Exiter *ie;
+
+ ie = (Ecore_Idle_Exiter *)l;
+ if (!ie->delete_me)
+ {
+ if (!ie->func(ie->data)) ecore_idle_exiter_del(ie);
+ }
+ }
+ if (idle_exiters_delete_me)
+ {
+ for (l = (Ecore_Oldlist *)idle_exiters; l;)
+ {
+ Ecore_Idle_Exiter *ie;
+
+ ie = (Ecore_Idle_Exiter *)l;
+ l = l->next;
+ if (ie->delete_me)
+ {
+ idle_exiters = _ecore_list_remove(idle_exiters, ie);
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
+ free(ie);
+ }
+ }
+ idle_exiters_delete_me = 0;
+ }
+}
+
+int
+_ecore_idle_exiter_exist(void)
+{
+ if (idle_exiters) return 1;
+ return 0;
+}
diff --git a/ecore/src/lib/ecore/ecore_idler.c b/ecore/src/lib/ecore/ecore_idler.c
new file mode 100644
index 0000000..4332439
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_idler.c
@@ -0,0 +1,106 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+
+static Ecore_Idler *idlers = NULL;
+static int idlers_delete_me = 0;
+
+/**
+ * Add an idler handler.
+ * @param func The function to call when idling.
+ * @param data The data to be passed to this @p func call.
+ * @return A idler handle if successfully added. NULL otherwise.
+ * @ingroup Idle_Group
+ */
+Ecore_Idler *
+ecore_idler_add(int (*func) (void *data), const void *data)
+{
+ Ecore_Idler *ie;
+
+ if (!func) return NULL;
+ ie = calloc(1, sizeof(Ecore_Idler));
+ if (!ie) return NULL;
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLER);
+ ie->func = func;
+ ie->data = (void *)data;
+ idlers = _ecore_list_append(idlers, ie);
+ return ie;
+}
+
+/**
+ * Delete an idler callback from the list to be executed.
+ * @param idler The handle of the idler callback to delete
+ * @return The data pointer passed to the idler callback on success. NULL
+ * otherwise.
+ * @ingroup Idle_Group
+ */
+void *
+ecore_idler_del(Ecore_Idler *idler)
+{
+ if (!ECORE_MAGIC_CHECK(idler, ECORE_MAGIC_IDLER))
+ {
+ ECORE_MAGIC_FAIL(idler, ECORE_MAGIC_IDLER,
+ "ecore_idler_del");
+ return NULL;
+ }
+ idler->delete_me = 1;
+ idlers_delete_me = 1;
+ return idler->data;
+}
+
+void
+_ecore_idler_shutdown(void)
+{
+ while (idlers)
+ {
+ Ecore_Idler *ie;
+
+ ie = idlers;
+ idlers = _ecore_list_remove(idlers, ie);
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
+ free(ie);
+ }
+ idlers_delete_me = 0;
+}
+
+int
+_ecore_idler_call(void)
+{
+ Ecore_Oldlist *l;
+
+ for (l = (Ecore_Oldlist *)idlers; l; l = l->next)
+ {
+ Ecore_Idler *ie;
+
+ ie = (Ecore_Idler *)l;
+ if (!ie->delete_me)
+ {
+ if (!ie->func(ie->data)) ecore_idler_del(ie);
+ }
+ }
+ if (idlers_delete_me)
+ {
+ for (l = (Ecore_Oldlist *)idlers; l;)
+ {
+ Ecore_Idler *ie;
+
+ ie = (Ecore_Idler *)l;
+ l = l->next;
+ if (ie->delete_me)
+ {
+ idlers = _ecore_list_remove(idlers, ie);
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
+ free(ie);
+ }
+ }
+ idlers_delete_me = 0;
+ }
+ if (idlers) return 1;
+ return 0;
+}
+
+int
+_ecore_idler_exist(void)
+{
+ if (idlers) return 1;
+ return 0;
+}
diff --git a/ecore/src/lib/ecore/ecore_list.c b/ecore/src/lib/ecore/ecore_list.c
new file mode 100644
index 0000000..82562b9
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_list.c
@@ -0,0 +1,1537 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+
+/* Return information about the list */
+static void *_ecore_list_current(Ecore_List * list);
+
+/* Adding functions */
+static int _ecore_list_insert(Ecore_List * list, Ecore_List_Node *node);
+static int _ecore_list_append_0(Ecore_List * list, Ecore_List_Node *node);
+static int _ecore_list_prepend_0(Ecore_List * list, Ecore_List_Node *node);
+
+/* Remove functions */
+static void *_ecore_list_remove_0(Ecore_List * list);
+static void *_ecore_list_remove_first(Ecore_List * list);
+static void *_ecore_list_remove_last(Ecore_List * list);
+
+/* Basic traversal functions */
+static void *_ecore_list_next(Ecore_List * list);
+static void *_ecore_list_goto_last(Ecore_List * list);
+static void *_ecore_list_goto_first(Ecore_List * list);
+static void *_ecore_list_goto(Ecore_List * list, void *data);
+static void *_ecore_list_goto_index(Ecore_List *list, int index);
+
+/* Iterative function */
+static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function,
+ void *user_data);
+
+/* Private double linked list functions */
+static void *_ecore_dlist_previous(Ecore_DList * list);
+static void *_ecore_dlist_remove_first(Ecore_DList *list);
+static void *_ecore_dlist_goto_index(Ecore_DList *list, int index);
+
+/* XXX: Begin deprecated code */
+void *
+_ecore_list_append(void *in_list, void *in_item)
+{
+ Ecore_Oldlist *l, *new_l;
+ Ecore_Oldlist *list, *item;
+
+ list = in_list;
+ item = in_item;
+ new_l = item;
+ new_l->next = NULL;
+ if (!list)
+ {
+ new_l->prev = NULL;
+ new_l->last = new_l;
+ return new_l;
+ }
+ if (list->last) l = list->last;
+ else for (l = list; l; l = l->next);
+ l->next = new_l;
+ new_l->prev = l;
+ list->last = new_l;
+ return list;
+}
+
+void *
+_ecore_list_prepend(void *in_list, void *in_item)
+{
+ Ecore_Oldlist *new_l;
+ Ecore_Oldlist *list, *item;
+
+ list = in_list;
+ item = in_item;
+ new_l = item;
+ new_l->prev = NULL;
+ if (!list)
+ {
+ new_l->next = NULL;
+ new_l->last = new_l;
+ return new_l;
+ }
+ new_l->next = list;
+ list->prev = new_l;
+ new_l->last = list->last;
+ list->last = NULL;
+ return new_l;
+}
+
+void *
+_ecore_list_append_relative(void *in_list, void *in_item, void *in_relative)
+{
+ Ecore_Oldlist *l;
+ Ecore_Oldlist *list, *item, *relative;
+
+ list = in_list;
+ item = in_item;
+ relative = in_relative;
+ for (l = list; l; l = l->next)
+ {
+ if (l == relative)
+ {
+ Ecore_Oldlist *new_l;
+
+ new_l = item;
+ if (l->next)
+ {
+ new_l->next = l->next;
+ l->next->prev = new_l;
+ }
+
+ else new_l->next = NULL;
+ l->next = new_l;
+ new_l->prev = l;
+ if (!new_l->next)
+ list->last = new_l;
+ return list;
+ }
+ }
+ return _ecore_list_append(list, item);
+}
+
+void *
+_ecore_list_prepend_relative(void *in_list, void *in_item, void *in_relative)
+{
+ Ecore_Oldlist *l;
+ Ecore_Oldlist *list, *item, *relative;
+
+ list = in_list;
+ item = in_item;
+ relative = in_relative;
+ for (l = list; l; l = l->next)
+ {
+ if (l == relative)
+ {
+ Ecore_Oldlist *new_l;
+
+ new_l = item;
+ new_l->prev = l->prev;
+ new_l->next = l;
+ l->prev = new_l;
+ if (new_l->prev)
+ {
+ new_l->prev->next = new_l;
+ if (!new_l->next)
+ list->last = new_l;
+ return list;
+ }
+ else
+ {
+ if (!new_l->next)
+ new_l->last = new_l;
+ else
+ {
+ new_l->last = list->last;
+ list->last = NULL;
+ }
+ return new_l;
+ }
+ }
+ }
+ return _ecore_list_prepend(list, item);
+}
+
+void *
+_ecore_list_remove(void *in_list, void *in_item)
+{
+ Ecore_Oldlist *return_l;
+ Ecore_Oldlist *list, *item;
+
+ /* checkme */
+ if(!in_list)
+ return in_list;
+
+ list = in_list;
+ item = in_item;
+ if (!item) return list;
+ if (item->next)
+ item->next->prev = item->prev;
+ if (item->prev)
+ {
+ item->prev->next = item->next;
+ return_l = list;
+ }
+ else
+ {
+ return_l = item->next;
+ if (return_l)
+ return_l->last = list->last;
+ }
+ if (item == list->last)
+ list->last = item->prev;
+ item->next = NULL;
+ item->prev = NULL;
+ return return_l;
+}
+
+void *
+_ecore_list_find(void *in_list, void *in_item)
+{
+ Ecore_Oldlist *l;
+ Ecore_Oldlist *list, *item;
+
+ list = in_list;
+ item = in_item;
+ for (l = list; l; l = l->next)
+ {
+ if (l == item) return item;
+ }
+ return NULL;
+}
+/* XXX: End deprecated code */
+
+/**
+@defgroup Ecore_Data_List_Creation_Group List Creation/Destruction Functions
+
+Functions that create, initialize and destroy Ecore_Lists.
+*/
+
+/**
+ * Create and initialize a new list.
+ * @return A new initialized list on success, @c NULL on failure.
+ * @ingroup Ecore_Data_List_Creation_Group
+ */
+Ecore_List *ecore_list_new()
+{
+ Ecore_List *list;
+
+ list = (Ecore_List *)malloc(sizeof(Ecore_List));
+ if (!list)
+ return NULL;
+
+ if (!ecore_list_init(list)) {
+ FREE(list);
+ return NULL;
+ }
+
+ return list;
+}
+
+/**
+ * Initialize a list to some sane starting values.
+ * @param list The list to initialize.
+ * @return @c TRUE if successful, @c FALSE if an error occurs.
+ * @ingroup Ecore_Data_List_Creation_Group
+ */
+int ecore_list_init(Ecore_List *list)
+{
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ memset(list, 0, sizeof(Ecore_List));
+
+ return TRUE;
+}
+
+/**
+ * Free a list and all of it's nodes.
+ * @param list The list to be freed.
+ * @ingroup Ecore_Data_List_Creation_Group
+ */
+void ecore_list_destroy(Ecore_List * list)
+{
+ void *data;
+
+ CHECK_PARAM_POINTER("list", list);
+
+ while (list->first) {
+ data = _ecore_list_remove_first(list);
+ if (list->free_func)
+ list->free_func(data);
+ }
+
+ FREE(list);
+}
+
+/**
+ * Set the function for freeing data.
+ * @param list The list that will use this function when nodes are
+ * destroyed.
+ * @param free_func The function that will free the key data.
+ * @return @c TRUE on successful set, @c FALSE otherwise.
+ */
+int ecore_list_set_free_cb(Ecore_List * list, Ecore_Free_Cb free_func)
+{
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ list->free_func = free_func;
+
+ return TRUE;
+}
+
+/**
+ * Checks the list for any nodes.
+ * @param list The list to check for nodes
+ * @return @c TRUE if no nodes in list, @c FALSE if the list contains nodes
+ */
+int ecore_list_is_empty(Ecore_List * list)
+{
+ int ret = TRUE;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ if (list->nodes)
+ ret = FALSE;
+
+ return ret;
+}
+
+/**
+ * Returns the number of the current node.
+ * @param list The list to return the number of the current node.
+ * @return The number of the current node in the list.
+ */
+int ecore_list_index(Ecore_List * list)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = list->index;
+
+ return ret;
+}
+
+/**
+ * Find the number of nodes in the list.
+ * @param list The list to find the number of nodes
+ * @return The number of nodes in the list.
+ */
+int ecore_list_nodes(Ecore_List * list)
+{
+ int ret = 0;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = list->nodes;
+
+ return ret;
+}
+
+/**
+@defgroup Ecore_Data_List_Add_Item_Group List Item Adding Functions
+
+Functions that are used to add nodes to an Ecore_List.
+*/
+
+/**
+ * Append data to the list.
+ * @param list The list.
+ * @param data The data to append.
+ * @return @c FALSE if an error occurs, @c TRUE if appended successfully
+ * @ingroup Ecore_Data_List_Add_Item_Group
+ */
+inline int ecore_list_append(Ecore_List * list, void *data)
+{
+ int ret;
+ Ecore_List_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ node = ecore_list_node_new();
+ node->data = data;
+
+ ret = _ecore_list_append_0(list, node);
+
+ return ret;
+}
+
+/* For adding items to the end of the list */
+static int _ecore_list_append_0(Ecore_List * list, Ecore_List_Node *end)
+{
+ if (list->last) {
+ list->last->next = end;
+ }
+
+ list->last = end;
+
+ if (list->first == NULL) {
+ list->first = end;
+ list->index = 0;
+ list->current = NULL;
+ }
+
+ if (list->index >= list->nodes)
+ list->index++;
+
+ list->nodes++;
+
+ return TRUE;
+}
+
+/**
+ * Prepend data to the beginning of the list.
+ * @param list The list.
+ * @param data The data to prepend.
+ * @return @c FALSE if an error occurs, @c TRUE if prepended successfully.
+ * @ingroup Ecore_Data_List_Add_Item_Group
+ */
+inline int ecore_list_prepend(Ecore_List * list, void *data)
+{
+ int ret;
+ Ecore_List_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ node = ecore_list_node_new();
+ node->data = data;
+
+ ret = _ecore_list_prepend_0(list, node);
+
+ return ret;
+}
+
+/* For adding items to the beginning of the list */
+static int _ecore_list_prepend_0(Ecore_List * list, Ecore_List_Node *start)
+{
+ /* Put it at the beginning of the list */
+ start->next = list->first;
+
+ list->first = start;
+
+ /* If no last node, then the first node is the last node */
+ if (list->last == NULL)
+ list->last = list->first;
+
+ list->nodes++;
+ list->index++;
+
+ return TRUE;
+}
+
+/**
+ * Insert data in front of the current point in the list.
+ * @param list The list to hold the inserted @p data.
+ * @param data The data to insert into @p list.
+ * @return @c FALSE if there is an error, @c TRUE on success
+ * @ingroup Ecore_Data_List_Add_Item_Group
+ */
+inline int ecore_list_insert(Ecore_List * list, void *data)
+{
+ int ret;
+ Ecore_List_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ node = ecore_list_node_new();
+ node->data = data;
+
+ ret = _ecore_list_insert(list, node);
+
+ return ret;
+}
+
+/* For adding items in front of the current position in the list */
+static int _ecore_list_insert(Ecore_List * list, Ecore_List_Node *new_node)
+{
+ /*
+ * If the current point is at the beginning of the list, then it's the
+ * same as prepending it to the list.
+ */
+ if (list->current == list->first)
+ return _ecore_list_prepend_0(list, new_node);
+
+ if (list->current == NULL) {
+ int ret_value;
+
+ ret_value = _ecore_list_append_0(list, new_node);
+ list->current = list->last;
+
+ return ret_value;
+ }
+
+ /* Setup the fields of the new node */
+ new_node->next = list->current;
+
+ /* And hook the node into the list */
+ _ecore_list_goto_index(list, ecore_list_index(list) - 1);
+
+ list->current->next = new_node;
+
+ /* Now move the current item to the inserted item */
+ list->current = new_node;
+ list->index++;
+ list->nodes++;
+
+ return TRUE;
+}
+
+/**
+@defgroup Ecore_Data_List_Remove_Item_Group List Item Removing Functions
+
+Functions that remove nodes from an Ecore_List.
+*/
+
+/**
+ * Remove the current item from the list.
+ * @param list The list to remove the current item
+ * @return A pointer to the removed data on success, @c NULL on failure.
+ * @ingroup Ecore_Data_List_Remove_Item_Group
+ */
+inline void *ecore_list_remove(Ecore_List * list)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_list_remove_0(list);
+
+ return ret;
+}
+
+/* Remove the current item from the list */
+static void *_ecore_list_remove_0(Ecore_List * list)
+{
+ void *ret = NULL;
+ Ecore_List_Node *old;
+
+ if (!list)
+ return FALSE;
+
+ if (ecore_list_is_empty(list))
+ return FALSE;
+
+ if (!list->current)
+ return FALSE;
+
+ if (list->current == list->first)
+ return _ecore_list_remove_first(list);
+
+ if (list->current == list->last)
+ return _ecore_list_remove_last(list);
+
+ old = list->current;
+
+ _ecore_list_goto_index(list, list->index - 1);
+
+ list->current->next = old->next;
+ old->next = NULL;
+ ret = old->data;
+ old->data = NULL;
+
+ _ecore_list_next(list);
+
+ ecore_list_node_destroy(old, NULL);
+ list->nodes--;
+
+ return ret;
+}
+
+/**
+ * Remove and free the data in lists current position.
+ * @param list The list to remove and free the current item.
+ * @return @c TRUE on success, @c FALSE on error
+ * @ingroup Ecore_Data_List_Remove_Item_Group
+ */
+int ecore_list_remove_destroy(Ecore_List *list)
+{
+ void *data;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ data = _ecore_list_remove_0(list);
+ if (list->free_func)
+ list->free_func(data);
+
+ return TRUE;
+}
+
+/**
+ * Remove the first item from the list.
+ * @param list The list to remove the current item
+ * @return Returns a pointer to the removed data on success, @c NULL on
+ * failure.
+ * @ingroup Ecore_Data_List_Remove_Item_Group
+ */
+inline void *ecore_list_remove_first(Ecore_List * list)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_list_remove_first(list);
+
+ return ret;
+}
+
+/* Remove the first item from the list */
+static void *_ecore_list_remove_first(Ecore_List * list)
+{
+ void *ret = NULL;
+ Ecore_List_Node *old;
+
+ if (!list)
+ return FALSE;
+
+ if (ecore_list_is_empty(list))
+ return FALSE;
+
+ if (!list->first)
+ return FALSE;
+
+ old = list->first;
+
+ list->first = list->first->next;
+
+ if (list->current == old)
+ list->current = list->first;
+ else
+ (list->index ? list->index-- : 0);
+
+ if (list->last == old)
+ list->last = list->first;
+
+ ret = old->data;
+ old->data = NULL;
+
+ ecore_list_node_destroy(old, NULL);
+ list->nodes--;
+
+ return ret;
+}
+
+/**
+ * Remove the last item from the list.
+ * @param list The list to remove the last node from
+ * @return A pointer to the removed data on success, @c NULL on failure.
+ * @ingroup Ecore_Data_List_Remove_Item_Group
+ */
+inline void *ecore_list_remove_last(Ecore_List * list)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_list_remove_last(list);
+
+ return ret;
+}
+
+/* Remove the last item from the list */
+static void *_ecore_list_remove_last(Ecore_List * list)
+{
+ void *ret = NULL;
+ Ecore_List_Node *old, *prev;
+
+ if (!list)
+ return FALSE;
+
+ if (ecore_list_is_empty(list))
+ return FALSE;
+
+ if (!list->last)
+ return FALSE;
+
+ old = list->last;
+ if (list->current == old)
+ list->current = NULL;
+
+ if (list->first == old)
+ list->first = NULL;
+ for (prev = list->first; prev && prev->next != old; prev = prev->next);
+ list->last = prev;
+ if (prev) {
+ prev->next = NULL;
+ if (list->current == old) {
+ list->current = NULL;
+ }
+ }
+
+
+ if (old) {
+ old->next = NULL;
+ ret = old->data;
+ old->data = NULL;
+ }
+
+ ecore_list_node_destroy(old, NULL);
+ list->nodes--;
+
+ return ret;
+}
+
+/**
+@defgroup Ecore_Data_List_Traverse_Group List Traversal Functions
+
+Functions that can be used to traverse an Ecore_List.
+*/
+
+/**
+ * Make the current item the item with the given index number.
+ * @param list The list.
+ * @param index The position to move the current item.
+ * @return A pointer to new current item on success, @c NULL on failure.
+ * @ingroup Ecore_Data_List_Traverse_Group
+ */
+inline void *ecore_list_goto_index(Ecore_List * list, int index)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_list_goto_index(list, index);
+
+ return ret;
+}
+
+/* This is the non-threadsafe version, use this inside internal functions that
+ * already lock the list */
+static void *_ecore_list_goto_index(Ecore_List *list, int index)
+{
+ int i;
+
+ if (!list)
+ return FALSE;
+
+ if (ecore_list_is_empty(list))
+ return FALSE;
+
+ if (index > ecore_list_nodes(list) || index < 0)
+ return FALSE;
+
+ _ecore_list_goto_first(list);
+
+ for (i = 0; i < index && _ecore_list_next(list); i++);
+
+ if (i >= list->nodes)
+ return FALSE;
+
+ list->index = i;
+
+ return list->current->data;
+}
+
+/**
+ * Make the current item the node that contains @p data.
+ * @param list The list.
+ * @param data The data to find.
+ * @return A pointer to @p data on success, @c NULL on failure.
+ * @ingroup Ecore_Data_List_Traverse_Group
+ */
+inline void *ecore_list_goto(Ecore_List * list, void *data)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_list_goto(list, data);
+
+ return ret;
+}
+
+/* Set the current position to the node containing data */
+static void *_ecore_list_goto(Ecore_List * list, void *data)
+{
+ int index;
+ Ecore_List_Node *node;
+
+ if (!list)
+ return NULL;
+
+ index = 0;
+
+ node = list->first;
+ while (node && node->data) {
+ Ecore_List_Node *next;
+
+ if (node->data == data)
+ break;
+
+ next = node->next;
+
+ node = next;
+
+ index++;
+ }
+
+ if (!node)
+ return NULL;
+
+ list->current = node;
+ list->index = index;
+
+ return list->current->data;
+}
+
+/**
+ * Make the current item the first item in the list
+ * @param list The list.
+ * @return A pointer to the first item on success, @c NULL on failure
+ * @ingroup Ecore_Data_List_Traverse_Group
+ */
+inline void *ecore_list_goto_first(Ecore_List *list)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_list_goto_first(list);
+
+ return ret;
+}
+
+/* Set the current position to the start of the list */
+static void *_ecore_list_goto_first(Ecore_List * list)
+{
+ if (!list || !list->first)
+ return NULL;
+
+ list->current = list->first;
+ list->index = 0;
+
+ return list->current->data;
+}
+
+/**
+ * Make the current item the last item in the list.
+ * @param list The list.
+ * @return A pointer to the last item on success, @c NULL on failure.
+ * @ingroup Ecore_Data_List_Traverse_Group
+ */
+inline void *ecore_list_goto_last(Ecore_List * list)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_list_goto_last(list);
+
+ return ret;
+}
+
+/* Set the current position to the end of the list */
+static void *_ecore_list_goto_last(Ecore_List * list)
+{
+ if (!list || !list->last)
+ return NULL;
+
+ list->current = list->last;
+ list->index = (list->nodes - 1);
+
+ return list->current->data;
+}
+
+/**
+ * Retrieve the data pointed to by the current item in @p list.
+ * @param list The list.
+ * @return Returns the data at current position, can be @c NULL.
+ */
+inline void *ecore_list_current(Ecore_List * list)
+{
+ void *ret;
+
+ ret = _ecore_list_current(list);
+
+ return ret;
+}
+
+/* Return the data of the current node without incrementing */
+static void *_ecore_list_current(Ecore_List * list)
+{
+ void *ret;
+
+ if (!list->current)
+ return NULL;
+
+ ret = list->current->data;
+
+ return ret;
+}
+
+/**
+ * Retrieve the data pointed to by the current item, and make the next item
+ * the current item.
+ * @param list The list to retrieve data from.
+ * @return The current item in the list on success, @c NULL on failure.
+ */
+inline void *ecore_list_next(Ecore_List * list)
+{
+ void *data;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ data = _ecore_list_next(list);
+
+ return data;
+}
+
+/* Return the data contained in the current node and go to the next node */
+static void *_ecore_list_next(Ecore_List * list)
+{
+ void *data;
+ Ecore_List_Node *ret;
+ Ecore_List_Node *next;
+
+ if (!list->current)
+ return NULL;
+
+ ret = list->current;
+ next = list->current->next;
+
+ list->current = next;
+ list->index++;
+
+ data = ret->data;
+
+ return data;
+}
+
+/**
+ * Remove all nodes from @p list.
+ * @param list The list.
+ * @return Returns @c TRUE on success, @c FALSE on error.
+ * @note The data for each item on the list is not freed by
+ * @c ecore_list_clear().
+ */
+int ecore_list_clear(Ecore_List * list)
+{
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ while (!ecore_list_is_empty(list))
+ _ecore_list_remove_first(list);
+
+ return TRUE;
+}
+
+/**
+ * Execute function for each node in @p list.
+ * @param list The list.
+ * @param function The function to pass each node from @p list to.
+ * @return Returns @c TRUE on success, @c FALSE on failure.
+ * @ingroup Ecore_Data_List_Traverse_Group
+ */
+int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function,
+ void *user_data)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_list_for_each(list, function, user_data);
+
+ return ret;
+}
+
+/* The real meat of executing the function for each data node */
+static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function,
+ void *user_data)
+{
+ void *value;
+
+ if (!list || !function)
+ return FALSE;
+
+ _ecore_list_goto_first(list);
+ while ((value = _ecore_list_next(list)) != NULL)
+ function(value, user_data);
+
+ return TRUE;
+}
+
+/* Initialize a node to starting values */
+int ecore_list_node_init(Ecore_List_Node * node)
+{
+
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ node->next = NULL;
+ node->data = NULL;
+
+ return TRUE;
+}
+
+/**
+@defgroup Ecore_Data_List_Node_Group List Node Functions
+
+Functions that are used in the creation, maintenance and destruction of
+Ecore_List nodes.
+*/
+
+/**
+ * Allocates and initializes a new list node.
+ * @return A new Ecore_List_Node on success, @c NULL otherwise.
+ * @ingroup Ecore_Data_List_Node_Group
+ */
+Ecore_List_Node *ecore_list_node_new()
+{
+ Ecore_List_Node *new_node;
+
+ new_node = malloc(sizeof(Ecore_List_Node));
+
+ if (!ecore_list_node_init(new_node)) {
+ FREE(new_node);
+ return NULL;
+ }
+
+ return new_node;
+}
+
+/**
+ * Calls the function to free the data and the node.
+ * @param node Node to destroy.
+ * @param free_func Function to call if @p node points to data to free.
+ * @return @c TRUE.
+ * @ingroup Ecore_Data_List_Node_Group
+ */
+int ecore_list_node_destroy(Ecore_List_Node * node, Ecore_Free_Cb free_func)
+{
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ if (free_func && node->data)
+ free_func(node->data);
+
+ FREE(node);
+
+ return TRUE;
+}
+
+/**
+ * @defgroup Ecore_Data_DList_Creation_Group Doubly Linked List Creation/Destruction Functions
+ *
+ * Functions used to create, initialize and destroy @c Ecore_DLists.
+ */
+
+/**
+ * Creates and initialises a new doubly linked list.
+ * @return A new initialised doubly linked list on success, @c NULL
+ * on failure.
+ * @ingroup Ecore_Data_DList_Creation_Group
+ */
+Ecore_DList *ecore_dlist_new()
+{
+ Ecore_DList *list = NULL;
+
+ list = (Ecore_DList *)malloc(sizeof(Ecore_DList));
+ if (!list)
+ return NULL;
+
+ if (!ecore_dlist_init(list)) {
+ IF_FREE(list);
+ return NULL;
+ }
+
+ return list;
+}
+
+/**
+ * Initialises a list to some sane starting values.
+ * @param list The doubly linked list to initialise.
+ * @return @c TRUE if successful, @c FALSE if an error occurs.
+ * @ingroup Ecore_Data_DList_Creation_Group
+ */
+int ecore_dlist_init(Ecore_DList *list)
+{
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ memset(list, 0, sizeof(Ecore_DList));
+
+ return TRUE;
+}
+
+/**
+ * Frees a doubly linked list and all of its nodes.
+ * @param list The doubly linked list to be freed.
+ * @ingroup Ecore_Data_DList_Creation_Group
+ */
+void ecore_dlist_destroy(Ecore_DList * list)
+{
+ void *data;
+ CHECK_PARAM_POINTER("list", list);
+
+ while (list->first) {
+ data = _ecore_dlist_remove_first(list);
+ if (list->free_func)
+ list->free_func(data);
+ }
+
+ FREE(list);
+}
+
+/**
+ * Sets the function used for freeing data stored in a doubly linked list.
+ * @param list The doubly linked list that will use this function when
+ * nodes are destroyed.
+ * @param free_func The function that will free the key data
+ * @return @c TRUE on success, @c FALSE on failure.
+ * @ingroup Ecore_Data_DList_Creation_Group
+ */
+int ecore_dlist_set_free_cb(Ecore_DList * list, Ecore_Free_Cb free_func)
+{
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ return ecore_list_set_free_cb(ECORE_LIST(list), free_func);
+}
+
+/**
+ * Returns whether there is anything in the given doubly linked list.
+ * @param list The given doubly linked list.
+ * @return @c TRUE if there are nodes, @c FALSE otherwise.
+ */
+int ecore_dlist_is_empty(Ecore_DList * list)
+{
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ return ecore_list_is_empty(ECORE_LIST(list));
+}
+
+/**
+ * Retrieves the index of the current node of the given doubly linked list.
+ * @param list The given doubly linked list.
+ * @return The index of the current node.
+ */
+inline int ecore_dlist_index(Ecore_DList * list)
+{
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ return ecore_list_index(ECORE_LIST(list));
+}
+
+/**
+ * @defgroup Ecore_Data_DList_Add_Item_Group Doubly Linked List Adding Functions
+ *
+ * Functions that are used to add nodes to an Ecore_DList.
+ */
+
+/**
+ * Appends data to the given doubly linked list.
+ * @param list The given doubly linked list.
+ * @param data The data to append.
+ * @return @c TRUE if the data is successfully appended, @c FALSE otherwise.
+ * @ingroup Ecore_Data_DList_Add_Item_Group
+ */
+int ecore_dlist_append(Ecore_DList * list, void *data)
+{
+ int ret;
+ Ecore_DList_Node *prev;
+ Ecore_DList_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ node = ecore_dlist_node_new();
+ ECORE_LIST_NODE(node)->data = data;
+
+ prev = ECORE_DLIST_NODE(ECORE_LIST(list)->last);
+ ret = _ecore_list_append_0(ECORE_LIST(list), ECORE_LIST_NODE(node));
+ if (ret) {
+ node->previous = prev;
+ }
+
+ return ret;
+}
+
+/**
+ * Adds data to the very beginning of the given doubly linked list.
+ * @param list The given doubly linked list.
+ * @param data The data to prepend.
+ * @return @c TRUE if the data is successfully prepended, @c FALSE otherwise.
+ * @ingroup Ecore_Data_DList_Add_Item_Group
+ */
+int ecore_dlist_prepend(Ecore_DList * list, void *data)
+{
+ int ret;
+ Ecore_DList_Node *prev;
+ Ecore_DList_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ node = ecore_dlist_node_new();
+ ECORE_LIST_NODE(node)->data = data;
+
+ prev = ECORE_DLIST_NODE(ECORE_LIST(list)->first);
+ ret = _ecore_list_prepend_0(ECORE_LIST(list), ECORE_LIST_NODE(node));
+ if (ret && prev)
+ prev->previous = node;
+
+ return ret;
+}
+
+/**
+ * Inserts data at the current point in the given doubly linked list.
+ * @param list The given doubly linked list.
+ * @param data The data to be inserted.
+ * @return @c TRUE on success, @c FALSE otherwise.
+ * @ingroup Ecore_Data_DList_Add_Item_Group
+ */
+int ecore_dlist_insert(Ecore_DList * list, void *data)
+{
+ int ret;
+ Ecore_DList_Node *prev;
+ Ecore_DList_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ prev = ECORE_DLIST_NODE(ECORE_LIST(list)->current);
+ if (!prev)
+ prev = ECORE_DLIST_NODE(ECORE_LIST(list)->last);
+
+ if (prev)
+ prev = prev->previous;
+
+ node = ecore_dlist_node_new();
+ ECORE_LIST_NODE(node)->data = data;
+
+ ret = _ecore_list_insert(list, ECORE_LIST_NODE(node));
+ if (!ret) {
+ return ret;
+ }
+
+ if (ECORE_LIST_NODE(node)->next)
+ ECORE_DLIST_NODE(ECORE_LIST_NODE(node)->next)->previous = node;
+
+ if (prev)
+ node->previous = prev;
+
+ return ret;
+}
+
+/**
+ * @defgroup Ecore_Data_DList_Remove_Item_Group Doubly Linked List Removing Functions
+ *
+ * Functions that remove nodes from an @c Ecore_DList.
+ */
+
+/**
+ * Removes the current item from the given doubly linked list.
+ * @param list The given doubly linked list.
+ * @return A pointer to the removed data on success, @c NULL otherwise.
+ * @ingroup Ecore_Data_DList_Remove_Item_Group
+ */
+void *ecore_dlist_remove(Ecore_DList * list)
+{
+ void *ret;
+ Ecore_List *l2 = ECORE_LIST(list);
+ Ecore_DList_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ if (l2->current) {
+ node = ECORE_DLIST_NODE(list->current->next);
+ if (node)
+ node->previous = ECORE_DLIST_NODE(l2->current)->previous;
+ }
+ ret = _ecore_list_remove_0(list);
+
+ return ret;
+}
+
+/**
+ * Removes the first item from the given doubly linked list.
+ * @param list The given doubly linked list.
+ * @return A pointer to the removed data on success, @c NULL on failure.
+ * @ingroup Ecore_Data_DList_Remove_Item_Group
+ */
+void *ecore_dlist_remove_first(Ecore_DList * list)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_dlist_remove_first(list);
+
+ return ret;
+}
+
+/**
+ * Removes and frees the data at the current position in the given doubly
+ * linked list.
+ * @param list The given doubly linked list.
+ * @return @c TRUE on success, @c FALSE otherwise.
+ * @ingroup Ecore_Data_DList_Remove_Item_Group
+ */
+int ecore_dlist_remove_destroy(Ecore_DList *list)
+{
+ void *data;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ data = ecore_dlist_remove(list);
+ if (!data)
+ return FALSE;
+
+ if (list->free_func)
+ list->free_func(data);
+
+ return TRUE;
+}
+
+static void *_ecore_dlist_remove_first(Ecore_DList *list)
+{
+ void *ret;
+
+ if (!list)
+ return FALSE;
+
+ ret = _ecore_list_remove_first(list);
+ if (ret && ECORE_LIST(list)->first)
+ ECORE_DLIST_NODE(ECORE_LIST(list)->first)->previous = NULL;
+
+ return ret;
+}
+
+/**
+ * Removes the last item from the given doubly linked list.
+ * @param list The given doubly linked list.
+ * @return A pointer to the removed data on success, @c NULL otherwise.
+ * @ingroup Ecore_Data_DList_Remove_Item_Group
+ */
+void *ecore_dlist_remove_last(Ecore_DList * list)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_list_remove_last(list);
+
+ return ret;
+}
+
+/**
+ * Moves the current item to the index number in the given doubly linked list.
+ * @param list The given doubly linked list.
+ * @param index The position to move the current item
+ * @return The node at specified index on success, @c NULL on error.
+ */
+void *ecore_dlist_goto_index(Ecore_DList * list, int index)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_dlist_goto_index(list, index);
+
+ return ret;
+}
+
+/* This is the non-threadsafe version, use this inside internal functions that
+ * already lock the list */
+static void *_ecore_dlist_goto_index(Ecore_DList *list, int index)
+{
+ int i, increment;
+
+ if (!list)
+ return FALSE;
+
+ if (ecore_list_is_empty(ECORE_LIST(list)))
+ return FALSE;
+
+ if (index > ecore_list_nodes(ECORE_LIST(list)) || index < 0)
+ return FALSE;
+
+ if (ECORE_LIST(list)->index >= ECORE_LIST(list)->nodes)
+ _ecore_list_goto_last(ECORE_LIST(list));
+
+ if (index < ECORE_LIST(list)->index)
+ increment = -1;
+ else
+ increment = 1;
+
+ for (i = ECORE_LIST(list)->index; i != index; i += increment) {
+ if (increment > 0)
+ _ecore_list_next(list);
+ else
+ _ecore_dlist_previous(list);
+ }
+
+ return _ecore_list_current(list);
+}
+
+/**
+ * @brief Move the current item to the node that contains data
+ * @param list: the list to move the current item in
+ * @param data: the data to find and set the current item to
+ *
+ * @return Returns specified data on success, NULL on error
+ */
+void *ecore_dlist_goto(Ecore_DList * list, void *data)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_list_goto(ECORE_LIST(list), data);
+
+ return ret;
+}
+
+/**
+ * @brief Move the current pointer to the first item in the list
+ * @param list: the list to change the current to the first item
+ *
+ * @return Returns a pointer to the first item on success, NULL on failure.
+ */
+void *ecore_dlist_goto_first(Ecore_DList *list)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_list_goto_first(list);
+
+ return ret;
+}
+
+/**
+ * @brief Move the pointer to the current item to the last item
+ * @param list: the list to move the current item pointer to the last
+ * @return Returns a pointer to the last item in the list , NULL if empty.
+ */
+void *ecore_dlist_goto_last(Ecore_DList * list)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ret = _ecore_list_goto_last(ECORE_LIST(list));
+
+ return ret;
+}
+
+/**
+ * @brief Return the data in the current list item
+ * @param list: the list to the return the current data
+ * @return Returns value of the current data item, NULL if no current item
+ */
+void *ecore_dlist_current(Ecore_DList * list)
+{
+ void *ret;
+
+ ret = _ecore_list_current(ECORE_LIST(list));
+
+ return ret;
+}
+
+/**
+ * @brief Move to the next item in the list and return current item
+ * @param list: the list to move to the next item in.
+ * @return Returns data in the current list node, or NULL on error
+ */
+void *ecore_dlist_next(Ecore_DList * list)
+{
+ void *data;
+
+ data = _ecore_list_next(list);
+
+ return data;
+}
+
+/**
+ * @brief Move to the previous item and return current item
+ * @param list: the list to move to the previous item in.
+ * @return Returns data in the current list node, or NULL on error
+ */
+void *ecore_dlist_previous(Ecore_DList * list)
+{
+ void *data;
+
+ data = _ecore_dlist_previous(list);
+
+ return data;
+}
+
+static void *_ecore_dlist_previous(Ecore_DList * list)
+{
+ void *data = NULL;
+
+ if (!list)
+ return NULL;
+
+ if (ECORE_LIST(list)->current) {
+ data = ECORE_LIST(list)->current->data;
+ ECORE_LIST(list)->current = ECORE_LIST_NODE(ECORE_DLIST_NODE(
+ ECORE_LIST(list)->current)->previous);
+ ECORE_LIST(list)->index--;
+ }
+ else
+ _ecore_list_goto_last(ECORE_LIST(list));
+
+ return data;
+}
+
+/**
+ * @brief Remove all nodes from the list.
+ * @param list: the list to remove all nodes from
+ *
+ * @return Returns TRUE on success, FALSE on errors
+ */
+int ecore_dlist_clear(Ecore_DList * list)
+{
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ ecore_list_clear(ECORE_LIST(list));
+
+ return TRUE;
+}
+
+/*
+ * @brief Initialize a node to sane starting values
+ * @param node: the node to initialize
+ * @return Returns TRUE on success, FALSE on errors
+ */
+int ecore_dlist_node_init(Ecore_DList_Node * node)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ ret = ecore_list_node_init(ECORE_LIST_NODE(node));
+ if (ret)
+ node->previous = NULL;
+
+ return ret;
+}
+
+/*
+ * @brief Allocate and initialize a new list node
+ * @return Returns NULL on error, new list node on success
+ */
+Ecore_DList_Node *ecore_dlist_node_new()
+{
+ Ecore_DList_Node *new_node;
+
+ new_node = malloc(sizeof(Ecore_DList_Node));
+
+ if (!new_node)
+ return NULL;
+
+ if (!ecore_dlist_node_init(new_node)) {
+ FREE(new_node);
+ return NULL;
+ }
+
+ return new_node;
+}
+
+/*
+ * @brief Call the data's free callback function, then free the node
+ * @param node: the node to be freed
+ * @param free_func: the callback function to execute on the data
+ * @return Returns TRUE on success, FALSE on error
+ */
+int ecore_dlist_node_destroy(Ecore_DList_Node * node, Ecore_Free_Cb free_func)
+{
+ CHECK_PARAM_POINTER_RETURN("node", node,
+ FALSE);
+
+ return ecore_list_node_destroy(ECORE_LIST_NODE(node), free_func);
+}
diff --git a/ecore/src/lib/ecore/ecore_main.c b/ecore/src/lib/ecore/ecore_main.c
new file mode 100644
index 0000000..6944db4
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_main.c
@@ -0,0 +1,635 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+
+#ifdef WIN32
+#include <winsock.h>
+#endif
+
+#define FIX_HZ 1
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#ifdef FIX_HZ
+#include <sys/param.h>
+#ifndef HZ
+#define HZ 100
+#endif
+#endif
+
+
+static int _ecore_main_select(double timeout);
+static void _ecore_main_fd_handlers_cleanup(void);
+static void _ecore_main_fd_handlers_call(void);
+static int _ecore_main_fd_handlers_buf_call(void);
+static void _ecore_main_loop_iterate_internal(int once_only);
+
+static int in_main_loop = 0;
+static int do_quit = 0;
+static Ecore_Fd_Handler *fd_handlers = NULL;
+static int fd_handlers_delete_me = 0;
+
+static double t1 = 0.0;
+static double t2 = 0.0;
+
+/**
+ * @defgroup Ecore_Main_Loop_Group Main Loop Functions
+ *
+ * These functions control the Ecore event handling loop. This loop is
+ * designed to work on embedded systems all the way to large and
+ * powerful mutli-cpu workstations.
+ *
+ * It serialises all system signals and events into a single event
+ * queue, that can be easily processed without needing to worry about
+ * concurrency. A properly written, event-driven program using this
+ * kind of programming does not need threads. It makes the program very
+ * robust and easy to follow.
+ *
+ * Here is an example of simple program and its basic event loop flow:
+ * @image html prog_flow.png
+ *
+ * For examples of setting up and using a main loop, see
+ * @ref event_handler_example.c and @ref timer_example.c.
+ */
+
+/**
+ * Runs a single iteration of the main loop to process everything on the
+ * queue.
+ * @ingroup Ecore_Main_Loop_Group
+ */
+void
+ecore_main_loop_iterate(void)
+{
+ _ecore_main_loop_iterate_internal(1);
+}
+
+/**
+ * Runs the application main loop.
+ *
+ * This function will not return until @ref ecore_main_loop_quit is called.
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ */
+void
+ecore_main_loop_begin(void)
+{
+ in_main_loop++;
+ for (;do_quit == 0;) _ecore_main_loop_iterate_internal(0);
+ do_quit = 0;
+ in_main_loop--;
+}
+
+/**
+ * Quits the main loop once all the events currently on the queue have
+ * been processed.
+ * @ingroup Ecore_Main_Loop_Group
+ */
+void
+ecore_main_loop_quit(void)
+{
+ do_quit = 1;
+}
+
+/**
+ * @defgroup Ecore_FD_Handler_Group File Event Handling Functions
+ *
+ * Functions that deal with file descriptor handlers.
+ */
+
+/**
+ * Adds a callback for activity on the given file descriptor.
+ *
+ * @p func will be called during the execution of @ref ecore_main_loop_begin
+ * when the file descriptor is available for reading, or writing, or both.
+ * @p buf_func is called during event loop handling to check if data that has
+ * been read from the file descriptor is in a buffer and is available to
+ * read.
+ *
+ * @param fd The file descriptor to watch.
+ * @param flags To watch it for read (@c ECORE_FD_READ) and/or
+ * (@c ECORE_FD_WRITE) write ability. @c ECORE_FD_ERROR
+ *
+ * @param func The callback function.
+ * @param data The data to pass to the callback.
+ * @param buf_func The function to call to check if any data has been
+ * buffered and already read from the fd. Can be @c NULL.
+ * @param buf_data The data to pass to the @p buf_func function.
+ * @return A fd handler handle if successful. @c NULL otherwise.
+ * @ingroup Ecore_FD_Handler_Group
+ */
+Ecore_Fd_Handler *
+ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, int (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data, int (*buf_func) (void *buf_data, Ecore_Fd_Handler *fd_handler), const void *buf_data)
+{
+ Ecore_Fd_Handler *fdh;
+
+ if ((fd < 0) ||
+ (flags == 0) ||
+ (!func)) return NULL;
+ fdh = calloc(1, sizeof(Ecore_Fd_Handler));
+ if (!fdh) return NULL;
+ ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
+ fdh->fd = fd;
+ fdh->flags = flags;
+ fdh->read_active = 0;
+ fdh->write_active = 0;
+ fdh->error_active = 0;
+ fdh->delete_me = 0;
+ fdh->func = func;
+ fdh->data = (void *)data;
+ fdh->buf_func = buf_func;
+ fdh->buf_data = (void *)buf_data;
+ fd_handlers = _ecore_list_append(fd_handlers, fdh);
+ return fdh;
+}
+
+/**
+ * Deletes the given FD handler.
+ * @param fd_handler The given FD handler.
+ * @return The data pointer set using @ref ecore_main_fd_handler_add,
+ * for @p fd_handler on success. @c NULL otherwise.
+ * @ingroup Ecore_FD_Handler_Group
+ */
+void *
+ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
+{
+ if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
+ "ecore_main_fd_handler_del");
+ return NULL;
+ }
+ fd_handler->delete_me = 1;
+ fd_handlers_delete_me = 1;
+ return fd_handler->data;
+}
+
+void
+ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, void (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data)
+{
+ if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
+ "ecore_main_fd_handler_prepare_callback_set");
+ return;
+ }
+ fd_handler->prep_func = func;
+ fd_handler->prep_data = (void *) data;
+}
+
+/**
+ * Retrieves the file descriptor that the given handler is handling.
+ * @param fd_handler The given FD handler.
+ * @return The file descriptor the handler is watching.
+ * @ingroup Ecore_FD_Handler_Group
+ */
+int
+ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler)
+{
+ if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
+ "ecore_main_fd_handler_fd_get");
+ return -1;
+ }
+ return fd_handler->fd;
+}
+
+/**
+ * Return if read, write or error, or a combination thereof, is active on the
+ * file descriptor of the given FD handler.
+ * @param fd_handler The given FD handler.
+ * @param flags The flags, @c ECORE_FD_READ, @c ECORE_FD_WRITE or
+ * @c ECORE_FD_ERROR to query.
+ * @return @c 1 if any of the given flags are active. @c 0 otherwise.
+ * @ingroup Ecore_FD_Handler_Group
+ */
+int
+ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags)
+{
+ int ret;
+
+ if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
+ "ecore_main_fd_handler_active_get");
+ return 0;
+ }
+ ret = 0;
+ if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = 1;
+ if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = 1;
+ if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = 1;
+ return ret;
+}
+
+/**
+ * Set what active streams the given FD handler should be monitoring.
+ * @param fd_handler The given FD handler.
+ * @param flags The flags to be watching.
+ * @ingroup Ecore_FD_Handler_Group
+ */
+void
+ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags)
+{
+ if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
+ "ecore_main_fd_handler_active_set");
+ return;
+ }
+ fd_handler->flags = flags;
+}
+
+void
+_ecore_main_shutdown(void)
+{
+ if (in_main_loop)
+ {
+ fprintf(stderr,
+ "\n"
+ "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n"
+ "*** Program may crash or behave strangely now.\n");
+ return;
+ }
+ while (fd_handlers)
+ {
+ Ecore_Fd_Handler *fdh;
+
+ fdh = fd_handlers;
+ fd_handlers = _ecore_list_remove(fd_handlers, fdh);
+ ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
+ free(fdh);
+ }
+ fd_handlers_delete_me = 0;
+}
+
+static int
+_ecore_main_select(double timeout)
+{
+ struct timeval tv, *t;
+ fd_set rfds, wfds, exfds;
+ int max_fd;
+ int ret;
+ Ecore_Oldlist *l;
+
+ t = NULL;
+ if (timeout > 0.0)
+ {
+ int sec, usec;
+
+#ifdef FIX_HZ
+ timeout += (0.5 / HZ);
+ sec = (int)timeout;
+ usec = (int)((timeout - (double)sec) * 1000000);
+#else
+ sec = (int)timeout;
+ usec = (int)((timeout - (double)sec) * 1000000);
+#endif
+ tv.tv_sec = sec;
+ tv.tv_usec = usec;
+ t = &tv;
+ }
+ else if (timeout == 0.0)
+ {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ t = &tv;
+ }
+ max_fd = 0;
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ FD_ZERO(&exfds);
+
+ /* call the prepare callback for all handlers */
+ for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next)
+ {
+ Ecore_Fd_Handler *fdh;
+
+ fdh = (Ecore_Fd_Handler *)l;
+
+ if (fdh->prep_func)
+ fdh->prep_func (fdh->prep_data, fdh);
+ }
+ for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next)
+ {
+ Ecore_Fd_Handler *fdh;
+
+ fdh = (Ecore_Fd_Handler *)l;
+ if (fdh->flags & ECORE_FD_READ)
+ {
+ FD_SET(fdh->fd, &rfds);
+ if (fdh->fd > max_fd) max_fd = fdh->fd;
+ }
+ if (fdh->flags & ECORE_FD_WRITE)
+ {
+ FD_SET(fdh->fd, &wfds);
+ if (fdh->fd > max_fd) max_fd = fdh->fd;
+ }
+ if (fdh->flags & ECORE_FD_ERROR)
+ {
+ FD_SET(fdh->fd, &exfds);
+ if (fdh->fd > max_fd) max_fd = fdh->fd;
+ }
+ }
+#ifndef WIN32
+ if (_ecore_signal_count_get()) return -1;
+#endif
+ ret = select(max_fd + 1, &rfds, &wfds, &exfds, t);
+ if (ret < 0)
+ {
+ if (errno == EINTR) return -1;
+ }
+ if (ret > 0)
+ {
+ for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next)
+ {
+ Ecore_Fd_Handler *fdh;
+
+ fdh = (Ecore_Fd_Handler *)l;
+ if (!fdh->delete_me)
+ {
+ if (FD_ISSET(fdh->fd, &rfds))
+ fdh->read_active = 1;
+ if (FD_ISSET(fdh->fd, &wfds))
+ fdh->write_active = 1;
+ if (FD_ISSET(fdh->fd, &exfds))
+ fdh->error_active = 1;
+ }
+ }
+ _ecore_main_fd_handlers_cleanup();
+ return 1;
+ }
+ return 0;
+}
+
+static void
+_ecore_main_fd_handlers_cleanup(void)
+{
+ Ecore_Oldlist *l;
+
+ if (!fd_handlers_delete_me) return;
+ for (l = (Ecore_Oldlist *)fd_handlers; l;)
+ {
+ Ecore_Fd_Handler *fdh;
+
+ fdh = (Ecore_Fd_Handler *)l;
+ l = l->next;
+ if (fdh->delete_me)
+ {
+ fd_handlers = _ecore_list_remove(fd_handlers, fdh);
+ ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
+ free(fdh);
+ }
+ }
+ fd_handlers_delete_me = 0;
+}
+
+static void
+_ecore_main_fd_handlers_call(void)
+{
+ Ecore_Oldlist *l;
+
+ for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next)
+ {
+ Ecore_Fd_Handler *fdh;
+
+ fdh = (Ecore_Fd_Handler *)l;
+ if (!fdh->delete_me)
+ {
+ if ((fdh->read_active) ||
+ (fdh->write_active) ||
+ (fdh->error_active))
+ {
+ if (!fdh->func(fdh->data, fdh))
+ {
+ fdh->delete_me = 1;
+ fd_handlers_delete_me = 1;
+ }
+ fdh->read_active = 0;
+ fdh->write_active = 0;
+ fdh->error_active = 0;
+ }
+ }
+ }
+}
+
+static int
+_ecore_main_fd_handlers_buf_call(void)
+{
+ Ecore_Oldlist *l;
+ int ret;
+
+ ret = 0;
+ for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next)
+ {
+ Ecore_Fd_Handler *fdh;
+
+ fdh = (Ecore_Fd_Handler *)l;
+ if (!fdh->delete_me)
+ {
+ if (fdh->buf_func)
+ {
+ if (fdh->buf_func(fdh->buf_data, fdh))
+ {
+ ret |= fdh->func(fdh->data, fdh);
+ fdh->read_active = 1;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+static void
+_ecore_main_loop_iterate_internal(int once_only)
+{
+ double next_time;
+ int have_event = 0;
+ int have_signal;
+
+ in_main_loop++;
+ /* expire any timers */
+ {
+ double now;
+
+ now = ecore_time_get();
+ while (_ecore_timer_call(now));
+ _ecore_timer_cleanup();
+ }
+ /* any timers re-added as a result of these are allowed to go */
+ _ecore_timer_enable_new();
+#ifndef WIN32
+ /* process signals into events .... */
+ while (_ecore_signal_count_get()) _ecore_signal_call();
+#endif
+ if (_ecore_event_exist())
+ {
+ int ret;
+
+ have_event = 1;
+ have_signal = 1;
+ ret = _ecore_main_select(0);
+ goto process_events;
+ }
+ /* call idle enterers ... */
+ if (!once_only)
+ _ecore_idle_enterer_call();
+ else
+ {
+ int ret;
+
+ have_event = have_signal = 0;
+ ret = _ecore_main_select(0);
+
+ if (ret > 0) have_event = 1;
+#ifndef WIN32
+ if (_ecore_signal_count_get() > 0) have_signal = 1;
+#endif
+
+ if (have_signal || have_event)
+ goto process_events;
+ }
+
+ /* if these calls caused any biuffered events to appear - deal with them */
+ while (_ecore_main_fd_handlers_buf_call());
+ /* if ther are any - jump to processing them */
+ if (_ecore_event_exist())
+ {
+ int ret;
+
+ have_event = 1;
+ have_signal = 1;
+ ret = _ecore_main_select(0);
+ goto process_events;
+ }
+ if (once_only)
+ {
+ _ecore_idle_enterer_call();
+ in_main_loop--;
+ return;
+ }
+
+#ifndef WIN32
+ if (_ecore_fps_debug)
+ {
+ t2 = ecore_time_get();
+ if ((t1 > 0.0) && (t2 > 0.0))
+ _ecore_fps_debug_runtime_add(t2 - t1);
+ }
+#endif
+ start_loop:
+ if (do_quit)
+ {
+ in_main_loop--;
+ return;
+ }
+ if (!_ecore_event_exist())
+ {
+ /* init flags */
+ have_event = have_signal = 0;
+ next_time = _ecore_timer_next_get();
+ /* no timers */
+ if (next_time < 0)
+ {
+ /* no idlers */
+ if (!_ecore_idler_exist())
+ {
+ int ret;
+
+ ret = _ecore_main_select(-1);
+ if (ret > 0) have_event = 1;
+#ifndef WIN32
+ if (_ecore_signal_count_get() > 0) have_signal = 1;
+#endif
+ }
+ /* idlers */
+ else
+ {
+ for (;;)
+ {
+ int ret;
+
+ if (!_ecore_idler_call()) goto start_loop;
+ if (_ecore_event_exist()) break;
+ ret = _ecore_main_select(0);
+ if (ret > 0) have_event = 1;
+#ifndef WIN32
+ if (_ecore_signal_count_get() > 0) have_signal = 1;
+#endif
+ if (have_event || have_signal) break;
+ next_time = _ecore_timer_next_get();
+ if (next_time >= 0) goto start_loop;
+ if (do_quit) break;
+ }
+ }
+ }
+ /* timers */
+ else
+ {
+ /* no idlers */
+ if (!_ecore_idler_exist())
+ {
+ int ret;
+
+ ret = _ecore_main_select(next_time);
+ if (ret > 0) have_event = 1;
+#ifndef WIN32
+ if (_ecore_signal_count_get() > 0) have_signal = 1;
+#endif
+ }
+ /* idlers */
+ else
+ {
+ for (;;)
+ {
+ double cur_time, t;
+ int ret;
+
+ if (!_ecore_idler_call()) goto start_loop;
+ if (_ecore_event_exist()) break;
+ ret = _ecore_main_select(0);
+ if (ret > 0) have_event = 1;
+#ifndef WIN32
+ if (_ecore_signal_count_get() > 0) have_signal = 1;
+#endif
+ if ((have_event) || (have_signal)) break;
+ cur_time = ecore_time_get();
+ t = ecore_time_get() - cur_time;
+ if (t >= next_time) break;
+ next_time = _ecore_timer_next_get();
+ if (next_time < 0) goto start_loop;
+ if (do_quit) break;
+ }
+ }
+ }
+ }
+#ifndef WIN32
+ if (_ecore_fps_debug)
+ {
+ t1 = ecore_time_get();
+ }
+#endif
+ /* we came out of our "wait state" so idle has exited */
+ if (!once_only)
+ _ecore_idle_exiter_call();
+ /* call the fd handler per fd that became alive... */
+ /* this should read or write any data to the monitored fd and then */
+ /* post events onto the ecore event pipe if necessary */
+ process_events:
+ if (have_event) _ecore_main_fd_handlers_call();
+ do
+ {
+#ifndef WIN32
+ /* process signals into events .... */
+ while (_ecore_signal_count_get()) _ecore_signal_call();
+#endif
+
+ /* handle events ... */
+ _ecore_event_call();
+ _ecore_main_fd_handlers_cleanup();
+ }
+ while (_ecore_main_fd_handlers_buf_call());
+ if (once_only) _ecore_idle_enterer_call();
+ in_main_loop--;
+}
diff --git a/ecore/src/lib/ecore/ecore_path.c b/ecore/src/lib/ecore/ecore_path.c
new file mode 100644
index 0000000..9202eea
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_path.c
@@ -0,0 +1,282 @@
+#include <Ecore.h>
+
+static Ecore_List *group_list = NULL;
+
+Ecore_Path_Group *__ecore_path_group_find(char *name);
+Ecore_Path_Group *__ecore_path_group_find_id(int id);
+
+/**
+ * @defgroup Ecore_Path_Group Path Group Functions
+ *
+ * Functions that make it easier to find a file in a set of search paths.
+ *
+ * @todo Give this a better description.
+ */
+
+/**
+ * Creates a new path group.
+ * @param group_name The name of the new group.
+ * @return @c 0 on error, the integer id of the new group on success.
+ * @ingroup Ecore_Path_Group
+ */
+int
+ecore_path_group_new(char *group_name)
+{
+ Ecore_Path_Group *last;
+ Ecore_Path_Group *group;
+
+ CHECK_PARAM_POINTER_RETURN("group_name", group_name, -1);
+
+ if (!group_list) {
+ group_list = ecore_list_new();
+ }
+ else {
+ group = __ecore_path_group_find(group_name);
+ if (group)
+ return -1;
+ }
+
+ group = (Ecore_Path_Group *)malloc(sizeof(Ecore_Path_Group));
+ memset(group, 0, sizeof(Ecore_Path_Group));
+
+ group->name = strdup(group_name);
+ ecore_list_append(group_list, group);
+
+ last = ecore_list_goto_last(group_list);
+ group->id = last->id + 1;
+
+ return group->id;
+}
+
+/**
+ * Destroys a previously created path group
+ * @param group_id The unique identifier for the group.
+ * @ingroup Ecore_Path_Group
+ */
+void
+ecore_path_group_del(int group_id)
+{
+ Ecore_Path_Group *group;
+
+ group = __ecore_path_group_find_id(group_id);
+
+ if (!group)
+ return;
+
+ if (group->paths) {
+ ecore_list_for_each(group->paths,
+ ECORE_FOR_EACH(free), NULL);
+ ecore_list_destroy(group->paths);
+ }
+
+ free(group->name);
+ free(group);
+}
+
+/**
+ * Adds a directory to be searched for files.
+ * @param group_id The unique identifier for the group to add the path.
+ * @param path The new path to be added to the group.
+ * @ingroup Ecore_Path_Group
+ */
+void
+ecore_path_group_add(int group_id, char *path)
+{
+ Ecore_Path_Group *group;
+
+ CHECK_PARAM_POINTER("path", path);
+
+ group = __ecore_path_group_find_id(group_id);
+
+ if (!group)
+ return;
+
+ if (!group->paths)
+ group->paths = ecore_list_new();
+
+ ecore_list_append(group->paths, strdup(path));
+}
+
+/**
+ * Removes the given directory from the given group.
+ * @param group_id The identifier for the given group.
+ * @param path The path of the directory to be removed.
+ * @ingroup Ecore_Path_Group
+ */
+void
+ecore_path_group_remove(int group_id, char *path)
+{
+ char *found;
+ Ecore_Path_Group *group;
+
+ CHECK_PARAM_POINTER("path", path);
+
+ group = __ecore_path_group_find_id(group_id);
+
+ if (!group || !group->paths)
+ return;
+
+ /*
+ * Find the path in the list of available paths
+ */
+ ecore_list_goto_first(group->paths);
+
+ while ((found = ecore_list_current(group->paths))
+ && strcmp(found, path))
+ ecore_list_next(group->paths);
+
+ /*
+ * If the path is found, remove and free it
+ */
+ if (found) {
+ ecore_list_remove(group->paths);
+ free(found);
+ }
+}
+
+/**
+ * Finds a file in a group of paths.
+ * @param group_id The path group id to search.
+ * @param name The name of the file to find.
+ * @return A pointer to a newly allocated path location of the found file
+ * on success. @c NULL on failure.
+ * @ingroup Ecore_Path_Group
+ */
+char *
+ecore_path_group_find(int group_id, char *name)
+{
+ int r;
+ char *p;
+ struct stat st;
+ char path[PATH_MAX];
+ Ecore_Path_Group *group;
+
+ CHECK_PARAM_POINTER_RETURN("name", name, NULL);
+
+ group = __ecore_path_group_find_id(group_id);
+
+ /*
+ * Search the paths of the path group for the specified file name
+ */
+ ecore_list_goto_first(group->paths);
+ p = ecore_list_next(group->paths);
+ do {
+ snprintf(path, PATH_MAX, "%s/%s", p, name);
+ r = stat(path, &st);
+ } while (((r < 0) || !S_ISREG(st.st_mode)) &&
+ (p = ecore_list_next(group->paths)));
+
+ if (p)
+ p = strdup(path);
+
+ return p;
+}
+
+/**
+ * Retrieves a list of all available files in the given path.
+ * @param group_id The identifier for the given path.
+ * @return A pointer to a newly allocated list of all files found in the paths
+ * identified by @p group_id. @c NULL otherwise.
+ * @ingroup Ecore_Path_Group
+ */
+Ecore_List *
+ecore_path_group_available(int group_id)
+{
+ Ecore_List *avail = NULL;
+ Ecore_Path_Group *group;
+ char *path;
+
+ group = __ecore_path_group_find_id(group_id);
+
+ if (!group || !group->paths || ecore_list_is_empty(group->paths))
+ return NULL;
+
+ ecore_list_goto_first(group->paths);
+
+ while ((path = ecore_list_next(group->paths)) != NULL)
+ {
+ DIR *dir;
+ struct stat st;
+ struct dirent *d;
+
+ stat(path, &st);
+
+ if (!S_ISDIR(st.st_mode))
+ continue;
+
+ dir = opendir(path);
+
+ if (!dir)
+ continue;
+
+ while ((d = readdir(dir)) != NULL)
+ {
+ char ppath[PATH_MAX];
+ char *ext;
+ char n[PATH_MAX];
+ int l;
+
+ if (!strncmp(d->d_name, ".", 1))
+ continue;
+
+ ext = strrchr(d->d_name, '.');
+
+ if (!ext || strncmp(ext, ".so", 3))
+ continue;
+
+ snprintf(ppath, PATH_MAX, "%s/%s", path, d->d_name);
+
+ stat(ppath, &st);
+
+ if (!S_ISREG(st.st_mode))
+ continue;
+
+ l = strlen(d->d_name);
+
+ strncpy(n, d->d_name, l - 2);
+
+ if (!avail)
+ avail = ecore_list_new();
+
+ ecore_list_append(avail, strdup(n));
+ }
+ }
+
+ return avail;
+}
+
+/*
+ * Find the specified group name
+ */
+Ecore_Path_Group *
+__ecore_path_group_find(char *name)
+{
+ Ecore_Path_Group *group;
+
+ CHECK_PARAM_POINTER_RETURN("name", name, NULL);
+
+ ecore_list_goto_first(group_list);
+
+ while ((group = ecore_list_next(group_list)) != NULL)
+ if (!strcmp(group->name, name))
+ return group;
+
+ return NULL;
+}
+
+/*
+ * Find the specified group id
+ */
+Ecore_Path_Group *
+__ecore_path_group_find_id(int id)
+{
+ Ecore_Path_Group *group;
+
+ ecore_list_goto_first(group_list);
+
+ while ((group = ecore_list_next(group_list)) != NULL)
+ if (group->id == id)
+ return group;
+
+ return NULL;
+}
diff --git a/ecore/src/lib/ecore/ecore_plugin.c b/ecore/src/lib/ecore/ecore_plugin.c
new file mode 100644
index 0000000..42d6203
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_plugin.c
@@ -0,0 +1,109 @@
+#include <Ecore.h>
+
+#ifndef WIN32
+#include <dlfcn.h>
+
+static Ecore_List *loaded_plugins = NULL;
+
+/**
+ * @defgroup Ecore_Plugin Plugin Functions
+ *
+ * Functions that load modules of compiled code into memory.
+ */
+
+/**
+ * Loads the specified plugin from the specified path group.
+ * @param group_id The path group to search for the plugin to load
+ * @param plugin_name The name of the plugin to load.
+ * @return A pointer to the newly loaded plugin on success, @c NULL on
+ * failure.
+ * @ingroup Ecore_Plugin
+ */
+Ecore_Plugin *
+ecore_plugin_load(int group_id, char *plugin_name)
+{
+ char *path;
+ char temp[PATH_MAX];
+
+ Ecore_Plugin *plugin;
+ void *handle = NULL;
+
+ CHECK_PARAM_POINTER_RETURN("plugin_name", plugin_name, NULL);
+
+ snprintf(temp, PATH_MAX, "%s.so", plugin_name);
+ path = ecore_path_group_find(group_id, temp);
+ if (!path)
+ return NULL;
+
+ handle = dlopen(path, RTLD_LAZY);
+ if (!handle)
+ return NULL;
+
+ /*
+ * Allocate the new plugin and initialize it's fields
+ */
+ plugin = malloc(sizeof(Ecore_Plugin));
+ memset(plugin, 0, sizeof(Ecore_Plugin));
+
+ plugin->group = group_id;
+ plugin->name = strdup(plugin_name);
+ plugin->handle = handle;
+
+ /*
+ * Now add it to the list of the groups loaded plugins
+ */
+ if (!loaded_plugins)
+ loaded_plugins = ecore_list_new();
+
+ ecore_list_append(loaded_plugins, plugin);
+
+ FREE(path);
+
+ return plugin;
+}
+
+/**
+ * Unloads the given plugin from memory.
+ * @param plugin The given plugin.
+ * @ingroup Ecore_Plugin
+ */
+void
+ecore_plugin_unload(Ecore_Plugin * plugin)
+{
+ CHECK_PARAM_POINTER("plugin", plugin);
+
+ if (!plugin->handle)
+ return;
+
+ if (ecore_list_goto(loaded_plugins, plugin))
+ ecore_list_remove(loaded_plugins);
+
+ dlclose(plugin->handle);
+
+ FREE(plugin->name);
+ FREE(plugin);
+}
+
+/*
+ * Searches for the specified symbol in the given plugin.
+ * @param plugin The given plugin.
+ * @param symbol_name The symbol to search for.
+ * @return Address of the given symbol if successful. Otherwise, @c NULL.
+ * @ingroup Ecore_Plugin
+ */
+void *
+ecore_plugin_call(Ecore_Plugin * plugin, char *symbol_name)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("plugin", plugin, NULL);
+ CHECK_PARAM_POINTER_RETURN("symbol_name", symbol_name, NULL);
+
+ if (!plugin->handle)
+ return NULL;
+
+ ret = dlsym(plugin->handle, symbol_name);
+
+ return ret;
+}
+#endif
diff --git a/ecore/src/lib/ecore/ecore_private.h b/ecore/src/lib/ecore/ecore_private.h
new file mode 100644
index 0000000..89a7328
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_private.h
@@ -0,0 +1,262 @@
+#ifndef _ECORE_PRIVATE_H
+#define _ECORE_PRIVATE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifndef WIN32
+#include <sys/mman.h>
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if HAVE___ATTRIBUTE__
+#define __UNUSED__ __attribute__((unused))
+#else
+#define __UNUSED__
+#endif
+
+#define ECORE_MAGIC_NONE 0x1234fedc
+#define ECORE_MAGIC_EXE 0xf7e812f5
+#define ECORE_MAGIC_TIMER 0xf7d713f4
+#define ECORE_MAGIC_IDLER 0xf7c614f3
+#define ECORE_MAGIC_IDLE_ENTERER 0xf7b515f2
+#define ECORE_MAGIC_IDLE_EXITER 0xf7601afd
+#define ECORE_MAGIC_FD_HANDLER 0xf7a416f1
+#define ECORE_MAGIC_EVENT_HANDLER 0xf79317f0
+#define ECORE_MAGIC_EVENT_FILTER 0xf78218ff
+#define ECORE_MAGIC_EVENT 0xf77119fe
+#define ECORE_MAGIC_ANIMATOR 0xf7643ea5
+
+#define ECORE_MAGIC Ecore_Magic __magic
+
+#define ECORE_MAGIC_SET(d, m) (d)->__magic = (m)
+#define ECORE_MAGIC_CHECK(d, m) ((d) && ((d)->__magic == (m)))
+#define ECORE_MAGIC_FAIL(d, m, fn) _ecore_magic_fail((d), (d) ? (d)->__magic : 0, (m), (fn));
+
+typedef unsigned int Ecore_Magic;
+
+typedef struct _Ecore_Oldlist Ecore_Oldlist;
+typedef struct _Ecore_Oldlist_Data Ecore_Oldlist_Data;
+
+struct _Ecore_Oldlist
+{
+ Ecore_Oldlist *next, *prev;
+ Ecore_Oldlist *last;
+};
+
+struct _Ecore_Oldlist_Data
+{
+ Ecore_Oldlist __list_data;
+ void *data;
+};
+
+#ifndef _ECORE_H
+enum _Ecore_Fd_Handler_Flags
+{
+ ECORE_FD_READ = 1,
+ ECORE_FD_WRITE = 2,
+ ECORE_FD_ERROR = 4
+};
+typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags;
+
+#ifndef WIN32
+typedef struct _Ecore_Exe Ecore_Exe;
+#endif
+typedef struct _Ecore_Timer Ecore_Timer;
+typedef struct _Ecore_Idler Ecore_Idler;
+typedef struct _Ecore_Idle_Enterer Ecore_Idle_Enterer;
+typedef struct _Ecore_Idle_Exiter Ecore_Idle_Exiter;
+typedef struct _Ecore_Fd_Handler Ecore_Fd_Handler;
+typedef struct _Ecore_Event_Handler Ecore_Event_Handler;
+typedef struct _Ecore_Event_Filter Ecore_Event_Filter;
+typedef struct _Ecore_Event Ecore_Event;
+typedef struct _Ecore_Animator Ecore_Animator;
+
+#ifndef WIN32
+struct _Ecore_Exe
+{
+ Ecore_Oldlist __list_data;
+ ECORE_MAGIC;
+ pid_t pid;
+ void *data;
+};
+#endif
+
+struct _Ecore_Timer
+{
+ Ecore_Oldlist __list_data;
+ ECORE_MAGIC;
+ double in;
+ double at;
+ signed char delete_me : 1;
+ signed char just_added : 1;
+ int (*func) (void *data);
+ void *data;
+};
+
+struct _Ecore_Idler
+{
+ Ecore_Oldlist __list_data;
+ ECORE_MAGIC;
+ int delete_me : 1;
+ int (*func) (void *data);
+ void *data;
+};
+
+struct _Ecore_Idle_Enterer
+{
+ Ecore_Oldlist __list_data;
+ ECORE_MAGIC;
+ int delete_me : 1;
+ int (*func) (void *data);
+ void *data;
+};
+
+struct _Ecore_Idle_Exiter
+{
+ Ecore_Oldlist __list_data;
+ ECORE_MAGIC;
+ int delete_me : 1;
+ int (*func) (void *data);
+ void *data;
+};
+
+struct _Ecore_Fd_Handler
+{
+ Ecore_Oldlist __list_data;
+ ECORE_MAGIC;
+ int fd;
+ Ecore_Fd_Handler_Flags flags;
+ int read_active : 1;
+ int write_active : 1;
+ int error_active : 1;
+ int delete_me : 1;
+ int (*func) (void *data, Ecore_Fd_Handler *fd_handler);
+ void *data;
+ int (*buf_func) (void *data, Ecore_Fd_Handler *fd_handler);
+ void *buf_data;
+ void (*prep_func) (void *data, Ecore_Fd_Handler *fd_handler);
+ void *prep_data;
+};
+
+struct _Ecore_Event_Handler
+{
+ Ecore_Oldlist __list_data;
+ ECORE_MAGIC;
+ int type;
+ int delete_me : 1;
+ int (*func) (void *data, int type, void *event);
+ void *data;
+};
+
+struct _Ecore_Event_Filter
+{
+ Ecore_Oldlist __list_data;
+ ECORE_MAGIC;
+ int delete_me : 1;
+ void * (*func_start) (void *data);
+ int (*func_filter) (void *data, void *loop_data, int type, void *event);
+ void (*func_end) (void *data, void *loop_data);
+ void *loop_data;
+ void *data;
+};
+
+struct _Ecore_Event
+{
+ Ecore_Oldlist __list_data;
+ ECORE_MAGIC;
+ int type;
+ void *event;
+ int delete_me : 1;
+ void (*func_free) (void *data, void *ev);
+ void *data;
+};
+
+struct _Ecore_Animator
+{
+ Ecore_Oldlist __list_data;
+ ECORE_MAGIC;
+ signed char delete_me : 1;
+ int (*func) (void *data);
+ void *data;
+};
+
+#endif
+
+void _ecore_magic_fail(void *d, Ecore_Magic m, Ecore_Magic req_m, const char *fname);
+
+void _ecore_timer_shutdown(void);
+void _ecore_timer_cleanup(void);
+void _ecore_timer_enable_new(void);
+double _ecore_timer_next_get(void);
+int _ecore_timer_call(double when);
+
+void _ecore_idler_shutdown(void);
+int _ecore_idler_call(void);
+int _ecore_idler_exist(void);
+
+void _ecore_idle_enterer_shutdown(void);
+void _ecore_idle_enterer_call(void);
+int _ecore_idle_enterer_exist(void);
+
+void _ecore_idle_exiter_shutdown(void);
+void _ecore_idle_exiter_call(void);
+int _ecore_idle_exiter_exist(void);
+
+void _ecore_event_shutdown(void);
+int _ecore_event_exist(void);
+Ecore_Event *_ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data);
+void *_ecore_event_del(Ecore_Event *event);
+void _ecore_event_call(void);
+
+#ifndef WIN32
+void *_ecore_event_exe_exit_new(void);
+void _ecore_event_exe_exit_free(void *data, void *ev);
+#endif
+void *_ecore_event_signal_user_new(void);
+void *_ecore_event_signal_hup_new(void);
+void *_ecore_event_signal_exit_new(void);
+void *_ecore_event_signal_power_new(void);
+void *_ecore_event_signal_realtime_new(void);
+
+void _ecore_main_shutdown(void);
+
+void _ecore_signal_shutdown(void);
+void _ecore_signal_init(void);
+int _ecore_signal_count_get(void);
+void _ecore_signal_call(void);
+
+#ifndef WIN32
+void _ecore_exe_shutdown(void);
+Ecore_Exe *_ecore_exe_find(pid_t pid);
+void *_ecore_exe_free(Ecore_Exe *exe);
+#endif
+
+void _ecore_animator_shutdown(void);
+
+
+void *_ecore_list_append (void *in_list, void *in_item);
+void *_ecore_list_prepend (void *in_list, void *in_item);
+void *_ecore_list_append_relative (void *in_list, void *in_item, void *in_relative);
+void *_ecore_list_prepend_relative (void *in_list, void *in_item, void *in_relative);
+void *_ecore_list_remove (void *in_list, void *in_item);
+void *_ecore_list_find (void *in_list, void *in_item);
+
+void _ecore_fps_debug_init(void);
+void _ecore_fps_debug_shutdown(void);
+void _ecore_fps_debug_runtime_add(double t);
+
+
+
+extern int _ecore_fps_debug;
+
+#endif
diff --git a/ecore/src/lib/ecore/ecore_sheap.c b/ecore/src/lib/ecore/ecore_sheap.c
new file mode 100644
index 0000000..b630608
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_sheap.c
@@ -0,0 +1,419 @@
+#include <Ecore.h>
+
+static void _ecore_sheap_heapify(Ecore_Sheap *heap, int i);
+static void _ecore_sheap_update_data(Ecore_Sheap *heap);
+
+/**
+ * Allocate and initialize a new binary heap
+ * @param compare The function for comparing keys, NULL for direct comparison
+ * @param size The number of elements to allow in the heap
+ * @return A pointer to the newly allocated binary heap on success, NULL on
+ * failure.
+ */
+Ecore_Sheap *ecore_sheap_new(Ecore_Compare_Cb compare, int size)
+{
+ Ecore_Sheap *heap = NULL;
+
+ heap = (Ecore_Sheap *)malloc(sizeof(Ecore_Sheap));
+ if (!heap)
+ return NULL;
+ memset(heap, 0, sizeof(Ecore_Sheap));
+
+ if (!ecore_sheap_init(heap, compare, size)) {
+ FREE(heap);
+ return NULL;
+ }
+
+ return heap;
+}
+
+/**
+ * Initialize a binary heap to default values
+ * @param heap The heap to initialize
+ * @param compare The function for comparing keys, NULL for direct comparison
+ * @param size The number of elements to allow in the heap
+ * @return TRUE on success, FALSE on failure
+ */
+int ecore_sheap_init(Ecore_Sheap *heap, Ecore_Compare_Cb compare, int size)
+{
+ CHECK_PARAM_POINTER_RETURN("heap", heap, FALSE);
+
+ heap->space = size;
+ if (!compare)
+ heap->compare = ecore_direct_compare;
+ else
+ heap->compare = compare;
+ heap->order = ECORE_SHEAP_MIN;
+
+ heap->data = (void **)malloc(heap->space * sizeof(void *));
+ if (!heap->data)
+ return FALSE;
+ memset(heap->data, 0, heap->space * sizeof(void *));
+
+ return TRUE;
+}
+
+/**
+ * Free up the memory used by the heap
+ *
+ * Frees the memory used by @a heap, calls the destroy function on each data
+ * item if necessary.
+ *
+ * @param heap The heap to be freed
+ */
+void ecore_sheap_destroy(Ecore_Sheap *heap)
+{
+ int i;
+
+ CHECK_PARAM_POINTER("heap", heap);
+
+ /*
+ * Free data in heap
+ */
+ if (heap->free_func)
+ for (i = 0; i < heap->size; i++)
+ heap->free_func(heap->data[i]);
+
+ FREE(heap->data);
+
+ FREE(heap);
+}
+
+/**
+ * Set the function for freeing data.
+ * @param heap The heap that will use this function when nodes are
+ * destroyed.
+ * @param free_func The function that will free the key data.
+ * @return @c TRUE on successful set, @c FALSE otherwise.
+ */
+int ecore_sheap_set_free_cb(Ecore_Sheap *heap, Ecore_Free_Cb free_func)
+{
+ CHECK_PARAM_POINTER_RETURN("heap", heap, FALSE);
+
+ heap->free_func = free_func;
+
+ return TRUE;
+}
+
+/**
+ * Insert new data into the heap.
+ * @param heap The heap to insert @a data.
+ * @param data The data to add to @a heap.
+ * @return TRUE on success, NULL on failure. Increases the size of the heap if
+ * it becomes larger than available space.
+ */
+int ecore_sheap_insert(Ecore_Sheap *heap, void *data)
+{
+ int i;
+ void *temp;
+ int parent;
+ int position;
+
+ CHECK_PARAM_POINTER_RETURN("heap", heap, FALSE);
+
+ /*
+ * Increase the size of the allocated data area if there isn't enough
+ * space available to add this data
+ */
+ if (heap->size >= heap->space)
+ return FALSE;
+
+ heap->sorted = FALSE;
+
+ /*
+ * Place the data at the end of the heap initially. Then determine the
+ * parent and position in the array of it's parent.
+ */
+ heap->data[heap->size] = data;
+ position = heap->size;
+ heap->size++;
+ i = heap->size;
+ parent = PARENT(i) - 1;
+
+ /*
+ * Check the order of the heap to decide where to place the inserted
+ * data. The loop is placed inside the if statement to reduce the
+ * number of branching decisions that must be predicted.
+ */
+ if (heap->order == ECORE_SHEAP_MIN) {
+ while ((position > 0) && heap->compare(heap->data[parent],
+ heap->data[position]) > 0) {
+
+ /*
+ * Swap the data with it's parents to move it up in
+ * the heap.
+ */
+ temp = heap->data[position];
+ heap->data[position] = heap->data[parent];
+ heap->data[parent] = temp;
+
+ /*
+ * Now determine the new position for the next
+ * iteration of the loop, as well as it's parents
+ * position.
+ */
+ i = PARENT(i);
+ position = i - 1;
+ parent = PARENT(i) - 1;
+ }
+ }
+ else {
+ while ((position > 0) && heap->compare(heap->data[parent],
+ heap->data[position]) < 0) {
+
+ /*
+ * Swap the data with it's parents to move it up in
+ * the heap.
+ */
+ temp = heap->data[position];
+ heap->data[position] = heap->data[PARENT(i) - 1];
+ heap->data[PARENT(i) - 1] = temp;
+
+ /*
+ * Now determine the new position for the next
+ * iteration of the loop, as well as it's parents
+ * position.
+ */
+ i = PARENT(i);
+ position = i - 1;
+ parent = PARENT(i) - 1;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * Extract the item at the top of the heap
+ * @param heap The heap to remove the top item
+ * @return The top item of the heap on success, NULL on failure.
+ * @note The extract function maintains the heap properties after the
+ * extract.
+ */
+void *ecore_sheap_extract(Ecore_Sheap *heap)
+{
+ void *extreme;
+
+ if (heap->size < 1)
+ return NULL;
+
+ heap->sorted = FALSE;
+
+ extreme = heap->data[0];
+ heap->size--;
+ heap->data[0] = heap->data[heap->size];
+
+ _ecore_sheap_heapify(heap, 1);
+
+ return extreme;
+}
+
+/**
+ * Examine the item at the top of the heap
+ * @param heap The heap to examine the top item
+ * @return The top item of the heap on success, NULL on failure.
+ * @note The function does not alter the heap.
+ */
+void *ecore_sheap_extreme(Ecore_Sheap *heap)
+{
+ if (heap->size < 1)
+ return NULL;
+
+ return heap->data[0];
+}
+
+/**
+ * Change the value of the specified item in the heap
+ * @param heap The heap to search for the item to change
+ * @param item The item in the heap to change
+ * @param newval The new value assigned to the item in the heap
+ * @return TRUE on success, FALSE on failure.
+ * @note The heap does not free the old data since it must be passed
+ * in, so the caller can perform the free if desired.
+ */
+int ecore_sheap_change(Ecore_Sheap *heap, void *item, void *newval)
+{
+ int i;
+
+ CHECK_PARAM_POINTER_RETURN("heap", heap, FALSE);
+
+ for (i = 0; i < heap->size && heap->compare(heap->data[i], item); i++);
+
+ if (i < heap->size)
+ heap->data[i] = newval;
+ else
+ return FALSE;
+
+ /*
+ * FIXME: This is not the correct procedure when a change occurs.
+ */
+ _ecore_sheap_heapify(heap, 1);
+
+ return TRUE;
+}
+
+/**
+ * Change the comparison function for the heap
+ * @param heap The heap to change comparison function
+ * @param compare The new function for comparing nodes
+ * @return TRUE on success, FALSE on failure.
+ *
+ * The comparison function is changed to @compare and the heap is heapified
+ * by the new comparison.
+ */
+int ecore_sheap_set_compare(Ecore_Sheap *heap, Ecore_Compare_Cb compare)
+{
+ CHECK_PARAM_POINTER_RETURN("heap", heap, FALSE);
+
+ if (!compare)
+ heap->compare = ecore_direct_compare;
+ else
+ heap->compare = compare;
+
+ _ecore_sheap_update_data(heap);
+
+ return TRUE;
+}
+
+/**
+ * Change the order of the heap
+ * @param heap The heap to change the order
+ * @param order The new order of the heap
+ *
+ * Changes the heap order of @heap and re-heapifies the data to this new
+ * order. The default order is a min heap.
+ */
+void ecore_sheap_set_order(Ecore_Sheap *heap, char order)
+{
+ CHECK_PARAM_POINTER("heap", heap);
+
+ heap->order = order;
+
+ _ecore_sheap_update_data(heap);
+}
+
+/**
+ * Sort the data in the heap
+ * @param heap The heap to be sorted
+ *
+ * Sorts the data in the heap into the order that is used for the heap's
+ * data.
+ */
+void ecore_sheap_sort(Ecore_Sheap *heap)
+{
+ int i = 0;
+ void **new_data;
+
+ CHECK_PARAM_POINTER("heap", heap);
+
+ new_data = (void **)malloc(heap->size * sizeof(void *));
+
+ /*
+ * Extract the heap and insert into the new data array in order.
+ */
+ while (heap->size > 0)
+ new_data[i++] = ecore_sheap_extract(heap);
+
+ /*
+ * Free the old data array and update the heap with the new data, also
+ * mark as sorted.
+ */
+ FREE(heap->data);
+ heap->data = new_data;
+ heap->size = i;
+ heap->sorted = TRUE;
+}
+
+/*
+ * Access the item at the ith position in the heap
+ * @param heap The heap to access the internal data
+ * @param i The index of the data within the heap
+ * @return The data located at the ith position within @heap on success,
+ * NULL on failure.
+ * @note The data is guaranteed to be in sorted order.
+ */
+inline void *ecore_sheap_item(Ecore_Sheap *heap, int i)
+{
+ if (i >= heap->size)
+ return NULL;
+
+ /*
+ * Make sure the data is sorted so we return the correct value.
+ */
+ if (!heap->sorted)
+ ecore_sheap_sort(heap);
+
+ return heap->data[i];
+}
+
+/*
+ * Regain the heap properties starting at position i
+ * @param heap The heap to regain heap properties
+ * @param i The position to start heapifying
+ */
+static void _ecore_sheap_heapify(Ecore_Sheap *heap, int i)
+{
+ int extreme;
+ int left = LEFT(i);
+ int right = RIGHT(i);
+
+ if (heap->order == ECORE_SHEAP_MIN) {
+ if (left <= heap->size && heap->compare(heap->data[left - 1],
+ heap->data[i - 1]) < 0)
+ extreme = left;
+ else
+ extreme = i;
+
+ if (right <= heap->size && heap->compare(heap->data[right - 1],
+ heap->data[extreme - 1]) < 0)
+ extreme = right;
+ }
+ else {
+ if (left <= heap->size && heap->compare(heap->data[left - 1],
+ heap->data[i - 1]) > 0)
+ extreme = left;
+ else
+ extreme = i;
+
+ if (right <= heap->size && heap->compare(heap->data[right - 1],
+ heap->data[extreme - 1]) > 0)
+ extreme = right;
+ }
+
+ /*
+ * If the data needs to be swapped down the heap, recurse on
+ * heapifying it's new placement.
+ */
+ if (extreme != i) {
+ void *temp;
+
+ temp = heap->data[extreme - 1];
+ heap->data[extreme - 1] = heap->data[i - 1];
+ heap->data[i - 1] = temp;
+
+ _ecore_sheap_heapify(heap, extreme);
+ }
+}
+
+static void _ecore_sheap_update_data(Ecore_Sheap *heap)
+{
+ int i, old_size;
+ void **data;
+
+ /*
+ * Track the old values from the heap
+ */
+ old_size = heap->size;
+ data = heap->data;
+
+ /*
+ *
+ */
+ heap->size = 0;
+ heap->data = malloc(heap->space * sizeof(void *));
+
+ for (i = 0; i < old_size; i++)
+ ecore_sheap_insert(heap, data[i]);
+
+ FREE(data);
+}
diff --git a/ecore/src/lib/ecore/ecore_signal.c b/ecore/src/lib/ecore/ecore_signal.c
new file mode 100644
index 0000000..fb45b1b
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_signal.c
@@ -0,0 +1,455 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+
+#ifndef WIN32
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <assert.h>
+
+/* make mono happy - this is evil though... */
+#undef SIGPWR
+/* valgrind in some versions/setups uses SIGRT's... hmmm */
+/* #undef SIGRTMIN */
+
+typedef void (*Signal_Handler)(int sig, siginfo_t *si, void *foo);
+
+static void _ecore_signal_callback_set(int sig, Signal_Handler func);
+static void _ecore_signal_callback_ignore(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigchld(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigusr1(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigusr2(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sighup(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigquit(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigint(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigterm(int sig, siginfo_t *si, void *foo);
+#ifdef SIGPWR
+static void _ecore_signal_callback_sigpwr(int sig, siginfo_t *si, void *foo);
+#endif
+
+#ifdef SIGRTMIN
+static void _ecore_signal_callback_sigrt(int sig, siginfo_t *si, void *foo);
+#endif
+
+static volatile sig_atomic_t sig_count = 0;
+static volatile sig_atomic_t sigchld_count = 0;
+static volatile sig_atomic_t sigusr1_count = 0;
+static volatile sig_atomic_t sigusr2_count = 0;
+static volatile sig_atomic_t sighup_count = 0;
+static volatile sig_atomic_t sigquit_count = 0;
+static volatile sig_atomic_t sigint_count = 0;
+static volatile sig_atomic_t sigterm_count = 0;
+
+static volatile siginfo_t sigchld_info;
+static volatile siginfo_t sigusr1_info;
+static volatile siginfo_t sigusr2_info;
+static volatile siginfo_t sighup_info;
+static volatile siginfo_t sigquit_info;
+static volatile siginfo_t sigint_info;
+static volatile siginfo_t sigterm_info;
+
+#ifdef SIGPWR
+static volatile sig_atomic_t sigpwr_count = 0;
+static volatile siginfo_t sigpwr_info = {0};
+#endif
+
+#ifdef SIGRTMIN
+static volatile sig_atomic_t *sigrt_count = NULL;
+static volatile siginfo_t *sigrt_info = NULL;
+#endif
+
+void
+_ecore_signal_shutdown(void)
+{
+#ifdef SIGRTMIN
+ int i, num = SIGRTMAX - SIGRTMIN;
+#endif
+
+ _ecore_signal_callback_set(SIGPIPE, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGALRM, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGCHLD, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGUSR1, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGUSR2, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGHUP, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGQUIT, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGINT, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGTERM, (Signal_Handler) SIG_DFL);
+#ifdef SIGPWR
+ _ecore_signal_callback_set(SIGPWR, (Signal_Handler) SIG_DFL);
+ sigpwr_count = 0;
+#endif
+ sigchld_count = 0;
+ sigusr1_count = 0;
+ sigusr2_count = 0;
+ sighup_count = 0;
+ sigquit_count = 0;
+ sigint_count = 0;
+ sigterm_count = 0;
+ sig_count = 0;
+
+#ifdef SIGRTMIN
+ for (i = 0; i < num; i++) {
+ _ecore_signal_callback_set(SIGRTMIN + i, (Signal_Handler) SIG_DFL);
+ sigrt_count[i] = 0;
+ }
+
+ if (sigrt_count) {
+ free((sig_atomic_t *) sigrt_count);
+ sigrt_count = NULL;
+ }
+
+ if (sigrt_info) {
+ free((siginfo_t *) sigrt_info);
+ sigrt_info = NULL;
+ }
+#endif
+}
+
+void
+_ecore_signal_init(void)
+{
+#ifdef SIGRTMIN
+ int i, num = SIGRTMAX - SIGRTMIN;
+#endif
+
+ _ecore_signal_callback_set(SIGPIPE, _ecore_signal_callback_ignore);
+ _ecore_signal_callback_set(SIGALRM, _ecore_signal_callback_ignore);
+ _ecore_signal_callback_set(SIGCHLD, _ecore_signal_callback_sigchld);
+ _ecore_signal_callback_set(SIGUSR1, _ecore_signal_callback_sigusr1);
+ _ecore_signal_callback_set(SIGUSR2, _ecore_signal_callback_sigusr2);
+ _ecore_signal_callback_set(SIGHUP, _ecore_signal_callback_sighup);
+ _ecore_signal_callback_set(SIGQUIT, _ecore_signal_callback_sigquit);
+ _ecore_signal_callback_set(SIGINT, _ecore_signal_callback_sigint);
+ _ecore_signal_callback_set(SIGTERM, _ecore_signal_callback_sigterm);
+#ifdef SIGPWR
+ _ecore_signal_callback_set(SIGPWR, _ecore_signal_callback_sigpwr);
+#endif
+
+#ifdef SIGRTMIN
+ sigrt_count = calloc(1, sizeof(sig_atomic_t) * num);
+ assert(sigrt_count);
+
+ sigrt_info = calloc(1, sizeof(siginfo_t) * num);
+ assert(sigrt_info);
+
+ for (i = 0; i < num; i++)
+ _ecore_signal_callback_set(SIGRTMIN + i, _ecore_signal_callback_sigrt);
+#endif
+}
+
+int
+_ecore_signal_count_get(void)
+{
+ return sig_count;
+}
+
+void
+_ecore_signal_call(void)
+{
+#ifdef SIGRTMIN
+ int i, num = SIGRTMAX - SIGRTMIN;
+#endif
+
+ while (sigchld_count > 0)
+ {
+ pid_t pid;
+ int status;
+
+ while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
+ {
+ Ecore_Event_Exe_Exit *e;
+
+ e = _ecore_event_exe_exit_new();
+ if (e)
+ {
+ if (WIFEXITED(status))
+ {
+ e->exit_code = WEXITSTATUS(status);
+ e->exited = 1;
+ }
+ else if (WIFSIGNALED(status))
+ {
+ e->exit_signal = WTERMSIG(status);
+ e->signalled = 1;
+ }
+ e->pid = pid;
+ e->exe = _ecore_exe_find(pid);
+
+ if (sigchld_info.si_signo)
+ e->data = sigchld_info;
+
+ _ecore_event_add(ECORE_EVENT_EXE_EXIT, e,
+ _ecore_event_exe_exit_free, NULL);
+ }
+ }
+ sigchld_count--;
+ sig_count--;
+ }
+ while (sigusr1_count > 0)
+ {
+ Ecore_Event_Signal_User *e;
+
+ e = _ecore_event_signal_user_new();
+ if (e)
+ {
+ e->number = 1;
+
+ if (sigusr1_info.si_signo)
+ e->data = sigusr1_info;
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL);
+ }
+ sigusr1_count--;
+ sig_count--;
+ }
+ while (sigusr2_count > 0)
+ {
+ Ecore_Event_Signal_User *e;
+
+ e = _ecore_event_signal_user_new();
+ if (e)
+ {
+ e->number = 2;
+
+ if (sigusr2_info.si_signo)
+ e->data = sigusr2_info;
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL);
+ }
+ sigusr2_count--;
+ sig_count--;
+ }
+ while (sighup_count > 0)
+ {
+ Ecore_Event_Signal_Hup *e;
+
+ e = _ecore_event_signal_hup_new();
+ if (e)
+ {
+ if (sighup_info.si_signo)
+ e->data = sighup_info;
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_HUP, e, NULL, NULL);
+ }
+ sighup_count--;
+ sig_count--;
+ }
+ while (sigquit_count > 0)
+ {
+ Ecore_Event_Signal_Exit *e;
+
+ e = _ecore_event_signal_exit_new();
+ if (e)
+ {
+ e->quit = 1;
+
+ if (sigquit_info.si_signo)
+ e->data = sigquit_info;
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
+ }
+ sigquit_count--;
+ sig_count--;
+ }
+ while (sigint_count > 0)
+ {
+ Ecore_Event_Signal_Exit *e;
+
+ e = _ecore_event_signal_exit_new();
+ if (e)
+ {
+ e->interrupt = 1;
+
+ if (sigint_info.si_signo)
+ e->data = sigint_info;
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
+ }
+ sigint_count--;
+ sig_count--;
+ }
+ while (sigterm_count > 0)
+ {
+ Ecore_Event_Signal_Exit *e;
+
+ e = _ecore_event_signal_exit_new();
+ if (e)
+ {
+ e->terminate = 1;
+
+ if (sigterm_info.si_signo)
+ e->data = sigterm_info;
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
+ }
+ sigterm_count--;
+ sig_count--;
+ }
+#ifdef SIGPWR
+ while (sigpwr_count > 0)
+ {
+ Ecore_Event_Signal_Power *e;
+
+ e = _ecore_event_signal_power_new();
+ if (e)
+ {
+ if (sigpwr_info.si_signo)
+ e->data = sigpwr_info;
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_POWER, e, NULL, NULL);
+ }
+ sigpwr_count--;
+ sig_count--;
+ }
+#endif
+
+#ifdef SIGRTMIN
+ for (i = 0; i < num; i++)
+ while (sigrt_count[i] > 0) {
+ Ecore_Event_Signal_Realtime *e;
+
+ if ((e = _ecore_event_signal_realtime_new())) {
+ e->num = i;
+
+ if (sigrt_info[i].si_signo)
+ e->data = sigrt_info[i];
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_REALTIME, e, NULL, NULL);
+ }
+
+ sigrt_count[i]--;
+ sig_count--;
+ }
+#endif
+}
+
+static void
+_ecore_signal_callback_set(int sig, Signal_Handler func)
+{
+ struct sigaction sa;
+
+ sa.sa_sigaction = func;
+ sa.sa_flags = SA_RESTART | SA_SIGINFO;
+ sigemptyset(&sa.sa_mask);
+ sigaction(sig, &sa, NULL);
+}
+
+static void
+_ecore_signal_callback_ignore(int sig __UNUSED__, siginfo_t *si __UNUSED__, void *foo __UNUSED__)
+{
+}
+
+static void
+_ecore_signal_callback_sigchld(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ if (si)
+ sigchld_info = *si;
+ else
+ sigchld_info.si_signo = 0;
+
+ sigchld_count++;
+ sig_count++;
+}
+
+static void
+_ecore_signal_callback_sigusr1(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ if (si)
+ sigusr1_info = *si;
+ else
+ sigusr1_info.si_signo = 0;
+
+ sigusr1_count++;
+ sig_count++;
+}
+
+static void
+_ecore_signal_callback_sigusr2(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ if (si)
+ sigusr2_info = *si;
+ else
+ sigusr2_info.si_signo = 0;
+
+ sigusr2_count++;
+ sig_count++;
+}
+
+static void
+_ecore_signal_callback_sighup(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ if (si)
+ sighup_info = *si;
+ else
+ sighup_info.si_signo = 0;
+
+ sighup_count++;
+ sig_count++;
+}
+
+static void
+_ecore_signal_callback_sigquit(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ if (si)
+ sigquit_info = *si;
+ else
+ sigquit_info.si_signo = 0;
+
+ sigquit_count++;
+ sig_count++;
+}
+
+static void
+_ecore_signal_callback_sigint(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ if (si)
+ sigint_info = *si;
+ else
+ sigint_info.si_signo = 0;
+
+ sigint_count++;
+ sig_count++;
+}
+
+static void
+_ecore_signal_callback_sigterm(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ if (si)
+ sigterm_info = *si;
+ else
+ sigterm_info.si_signo = 0;
+
+ sigterm_count++;
+ sig_count++;
+}
+
+#ifdef SIGPWR
+static void
+_ecore_signal_callback_sigpwr(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ if (si)
+ sigpwr_info = *si;
+ else
+ sigpwr_info.si_signo = 0;
+
+ sigpwr_count++;
+ sig_count++;
+}
+#endif
+
+#ifdef SIGRTMIN
+static void
+_ecore_signal_callback_sigrt(int sig, siginfo_t *si, void *foo __UNUSED__)
+{
+ if (si)
+ sigrt_info[sig - SIGRTMIN] = *si;
+ else
+ sigrt_info[sig - SIGRTMIN].si_signo = 0;
+
+ sigrt_count[sig - SIGRTMIN]++;
+ sig_count++;
+}
+#endif
+#endif
diff --git a/ecore/src/lib/ecore/ecore_strings.c b/ecore/src/lib/ecore/ecore_strings.c
new file mode 100644
index 0000000..032d2a5
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_strings.c
@@ -0,0 +1,79 @@
+#include <Ecore.h>
+
+static Ecore_Hash *ecore_strings = NULL;
+
+/**
+ * @defgroup Ecore_String_Group String Instance Functions
+ *
+ * These functions allow you to store one copy of a string, and use it
+ * throughout your program.
+ */
+
+/**
+ * Retrieves an instance of a string for use in an ecore program.
+ * @param string The string to retrieve an instance of.
+ * @return A pointer to an instance of the string on success.
+ * @c NULL on failure.
+ * @ingroup Ecore_String_Group
+ */
+char *ecore_string_instance(char *string)
+{
+ Ecore_String *str;
+
+ CHECK_PARAM_POINTER_RETURN("string", string, NULL);
+
+ /*
+ * No strings have been loaded at this point, so create the hash
+ * table for storing string info for later.
+ */
+ if (!ecore_strings)
+ ecore_strings = ecore_hash_new(ecore_str_hash, ecore_str_compare);
+
+ /*
+ * Check for a previous instance of the string, if not found, create
+ * it.
+ */
+ str = ecore_hash_get(ecore_strings, string);
+ if (!str) {
+
+ /*
+ * Allocate and initialize a new string reference.
+ */
+ str = (Ecore_String *)malloc(sizeof(Ecore_String));
+
+ str->string = strdup(string);
+ str->references = 0;
+
+ ecore_hash_set(ecore_strings, str->string, str);
+ }
+
+ str->references++;
+
+ return str->string;
+}
+
+/**
+ * Notes that the given string has lost an instance.
+ *
+ * It will free the string if no other instances are left.
+ *
+ * @param string The given string.
+ * @ingroup Ecore_String_Group
+ */
+void ecore_string_release(char *string)
+{
+ Ecore_String *str;
+
+ CHECK_PARAM_POINTER("string", string);
+
+ str = ecore_hash_get(ecore_strings, string);
+ if (!str)
+ return;
+
+ str->references--;
+ if (str->references < 1) {
+ ecore_hash_remove(ecore_strings, string);
+ FREE(str->string);
+ FREE(str);
+ }
+}
diff --git a/ecore/src/lib/ecore/ecore_time.c b/ecore/src/lib/ecore/ecore_time.c
new file mode 100644
index 0000000..969f508
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_time.c
@@ -0,0 +1,41 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+
+#include <sys/time.h>
+
+#ifndef HAVE_GETTIMEOFDAY
+#ifdef WIN32
+#include <sys/timeb.h>
+
+static int gettimeofday (struct timeval *tv, void *unused)
+{
+ struct _timeb t;
+
+ if (!tv)
+ return -1;
+
+ _ftime (&t);
+
+ tv->tv_sec = t.time;
+ tv->tv_usec = t.millitm * 1000;
+
+ return 0;
+}
+#else
+#error "Your platform isn't supported yet"
+#endif
+#endif
+
+/**
+ * Retrieves the current system time as a floating point value in seconds.
+ * @return The number of seconds since 12.00AM 1st January 1970.
+ * @ingroup Ecore_Time_Group
+ */
+double
+ecore_time_get(void)
+{
+ struct timeval timev;
+
+ gettimeofday(&timev, NULL);
+ return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
+}
diff --git a/ecore/src/lib/ecore/ecore_timer.c b/ecore/src/lib/ecore/ecore_timer.c
new file mode 100644
index 0000000..3c24291
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_timer.c
@@ -0,0 +1,223 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+
+static void _ecore_timer_set(Ecore_Timer *timer, double at, double in, int (*func) (void *data), void *data);
+
+static int timers_added = 0;
+static int timers_delete_me = 0;
+static Ecore_Timer *timers = NULL;
+static double last_check = 0.0;
+
+/**
+ * @defgroup Ecore_Time_Group Ecore Time Functions
+ *
+ * Functions that deal with time. These functions include those that simply
+ * retrieve it in a given format, and those that create events based on it.
+ */
+
+/**
+ * Creates a timer to call the given function in the given period of time.
+ * @param in The interval in seconds.
+ * @param func The given function. If @p func returns 1, the timer is
+ * rescheduled for the next interval @p in.
+ * @param data Data to pass to @p func when it is called.
+ * @return A timer object on success. @c NULL on failure.
+ * @ingroup Ecore_Time_Group
+ */
+Ecore_Timer *
+ecore_timer_add(double in, int (*func) (void *data), const void *data)
+{
+ double now;
+ Ecore_Timer *timer;
+
+ if (!func) return NULL;
+ if (in < 0.0) in = 0.0;
+ timer = calloc(1, sizeof(Ecore_Timer));
+ if (!timer) return NULL;
+ ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER);
+ now = ecore_time_get();
+ _ecore_timer_set(timer, now + in, in, func, (void *)data);
+ return timer;
+}
+
+/**
+ * Delete the specified timer from the timer list.
+ * @param timer The timer to delete.
+ * @return The data pointer set for the timer when @ref ecore_timer_add was
+ * called. @c NULL is returned if the function is unsuccessful.
+ * @ingroup Ecore_Time_Group
+ */
+void *
+ecore_timer_del(Ecore_Timer *timer)
+{
+ if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
+ {
+ ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
+ "ecore_timer_del");
+ return NULL;
+ }
+ if (timer->delete_me) return timer->data;
+ timers_delete_me++;
+ timer->delete_me = 1;
+ return timer->data;
+}
+
+/**
+ * Change the interval the timer ticks of. If set during
+ * a timer call, this will affect the next interval.
+ *
+ * @param timer The timer to change.
+ * @param in The interval in seconds.
+ * @ingroup Ecore_Time_Group
+ */
+void
+ecore_timer_interval_set(Ecore_Timer *timer, double in)
+{
+ if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
+ {
+ ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
+ "ecore_timer_interval_set");
+ return;
+ }
+ timer->in = in;
+}
+
+void
+_ecore_timer_shutdown(void)
+{
+ while (timers)
+ {
+ Ecore_Timer *timer;
+
+ timer = timers;
+ timers = _ecore_list_remove(timers, timer);
+ ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
+ free(timer);
+ }
+}
+
+void
+_ecore_timer_cleanup(void)
+{
+ Ecore_Oldlist *l;
+
+ if (!timers_delete_me) return;
+ for (l = (Ecore_Oldlist *)timers; l;)
+ {
+ Ecore_Timer *timer;
+
+ timer = (Ecore_Timer *)l;
+ l = l->next;
+ if (timer->delete_me)
+ {
+ timers = _ecore_list_remove(timers, timer);
+ ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
+ free(timer);
+ timers_delete_me--;
+ if (timers_delete_me == 0) return;
+ }
+ }
+ timers_delete_me = 0;
+}
+
+void
+_ecore_timer_enable_new(void)
+{
+ Ecore_Oldlist *l;
+
+ if (!timers_added) return;
+ timers_added = 0;
+ for (l = (Ecore_Oldlist *)timers; l; l = l->next)
+ {
+ Ecore_Timer *timer;
+
+ timer = (Ecore_Timer *)l;
+ timer->just_added = 0;
+ }
+}
+
+double
+_ecore_timer_next_get(void)
+{
+ double now;
+ double in;
+
+ if (!timers) return -1;
+ now = ecore_time_get();
+ in = timers->at - now;
+ if (in < 0) in = 0;
+ return in;
+}
+
+int
+_ecore_timer_call(double when)
+{
+ Ecore_Oldlist *l;
+ Ecore_Timer *timer;
+
+ if (!timers) return 0;
+ if (last_check > when)
+ {
+ /* User set time backwards */
+ for (l = (Ecore_Oldlist *)timers; l; l = l->next)
+ {
+ timer = (Ecore_Timer *)l;
+ timer->at -= (last_check - when);
+ }
+ }
+ last_check = when;
+ for (l = (Ecore_Oldlist *)timers; l; l = l->next)
+ {
+ timer = (Ecore_Timer *)l;
+ if ((timer->at <= when) &&
+ (!timer->just_added) &&
+ (!timer->delete_me))
+ {
+ timers = _ecore_list_remove(timers, timer);
+ _ecore_timer_call(when);
+ if ((!timer->delete_me) && (timer->func(timer->data)))
+ {
+ /* if the timer would have gone off more than 30 seconds ago,
+ * assume that the system hung and set the timer to go off
+ * timer->in from now.
+ */
+ if ((timer->at + timer->in) < (when - 30.0))
+ _ecore_timer_set(timer, when + timer->in, timer->in, timer->func, timer->data);
+ else
+ _ecore_timer_set(timer, timer->at + timer->in, timer->in, timer->func, timer->data);
+ }
+ else
+ free(timer);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+_ecore_timer_set(Ecore_Timer *timer, double at, double in, int (*func) (void *data), void *data)
+{
+ Ecore_Oldlist *l;
+
+ timers_added = 1;
+ timer->at = at;
+ timer->in = in;
+ timer->func = func;
+ timer->data = data;
+ timer->just_added = 1;
+ if (timers)
+ {
+ for (l = ((Ecore_Oldlist *)(timers))->last; l; l = l->prev)
+ {
+ Ecore_Timer *t2;
+
+ t2 = (Ecore_Timer *)l;
+ if (timer->at > t2->at)
+ {
+ timers = _ecore_list_append_relative(timers, timer, t2);
+ return;
+ }
+ }
+ }
+ timers = _ecore_list_prepend(timers, timer);
+}
diff --git a/ecore/src/lib/ecore/ecore_tree.c b/ecore/src/lib/ecore/ecore_tree.c
new file mode 100644
index 0000000..55322dd
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_tree.c
@@ -0,0 +1,816 @@
+#include <Ecore.h>
+
+/* A macro for determining the highest node at given branch */
+#define MAX_HEIGHT(node) (node ? MAX(node->max_left, node->max_right) : 0)
+
+/* Utility functions for searching the tree and returning a node, or its
+ * parent */
+Ecore_Tree_Node *tree_node_find(Ecore_Tree * tree, void *key);
+Ecore_Tree_Node *tree_node_find_parent(Ecore_Tree * tree, void *key);
+
+/* Balancing functions, keep the tree balanced within a one node height
+ * difference */
+int tree_node_balance(Ecore_Tree * Tree, Ecore_Tree_Node * top_node);
+int tree_node_rotate_right(Ecore_Tree * tree, Ecore_Tree_Node * top_node);
+int tree_node_rotate_left(Ecore_Tree * tree, Ecore_Tree_Node * top_node);
+
+/* Fucntions for executing a specified function on each node of a tree */
+int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func,
+ void *user_data);
+int tree_for_each_node_value(Ecore_Tree_Node * node,
+ Ecore_For_Each for_each_func, void *user_data);
+
+/**
+ * @brief Allocate a new tree structure.
+ * @param compare_func: function used to compare the two values
+ * @return Returns NULL if the operation fails, otherwise the new tree
+ */
+Ecore_Tree *ecore_tree_new(Ecore_Compare_Cb compare_func)
+{
+ Ecore_Tree *new_tree;
+
+ new_tree = ECORE_TREE(malloc(sizeof(Ecore_Tree)));
+ if (!new_tree)
+ return NULL;
+
+ if (!ecore_tree_init(new_tree, compare_func)) {
+ IF_FREE(new_tree);
+ return NULL;
+ }
+
+ return new_tree;
+}
+
+/**
+ * @brief Initialize a tree structure to some sane initial values
+ * @param new_tree: the new tree structure to be initialized
+ * @param compare_func: the function used to compare node keys
+ * @return Returns TRUE on successful initialization, FALSE on an error
+ */
+int ecore_tree_init(Ecore_Tree * new_tree, Ecore_Compare_Cb compare_func)
+{
+ CHECK_PARAM_POINTER_RETURN("new_tree", new_tree, FALSE);
+
+ memset(new_tree, 0, sizeof(Ecore_Tree));
+
+ if (!compare_func)
+ new_tree->compare_func = ecore_direct_compare;
+ else
+ new_tree->compare_func = compare_func;
+
+ ECORE_INIT_LOCKS(new_tree);
+
+ return TRUE;
+}
+
+/*
+ * @brief Add a function to be called at node destroy time
+ * @param tree: the tree that will use this function when nodes are destroyed
+ * @param free_func: the function that will be passed the node being freed
+ * @return Returns TRUE on successful set, FALSE otherwise.
+ */
+int ecore_tree_set_free_cb(Ecore_Tree * tree, Ecore_Free_Cb free_func)
+{
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+
+ ECORE_WRITE_LOCK(tree);
+ tree->free_func = free_func;
+ ECORE_WRITE_UNLOCK(tree);
+
+ return TRUE;
+}
+
+/*
+ * @brief Initialize a new tree node
+ * @return Returns FALSE if the operation fails, otherwise TRUE
+ */
+int ecore_tree_node_init(Ecore_Tree_Node * new_node)
+{
+ CHECK_PARAM_POINTER_RETURN("new_node", new_node, FALSE);
+
+ new_node->key = NULL;
+ new_node->value = NULL;
+
+ new_node->parent = NULL;
+ new_node->right_child = NULL;
+ new_node->left_child = NULL;
+
+ new_node->max_left = new_node->max_right = 0;
+
+ ECORE_INIT_LOCKS(new_node);
+
+ return TRUE;
+}
+
+/*
+ * @brief Allocate a new tree node
+ * @return Returns NULL if the operation fails, otherwise the new node.
+ */
+Ecore_Tree_Node *ecore_tree_node_new()
+{
+ Ecore_Tree_Node *new_node;
+
+ new_node = ECORE_TREE_NODE(malloc(sizeof(Ecore_Tree_Node)));
+ if (!new_node)
+ return NULL;
+
+ if (!ecore_tree_node_init(new_node)) {
+ IF_FREE(new_node);
+ return NULL;
+ }
+
+ return new_node;
+}
+
+/*
+ * @brief Free a tree node and it's children.
+ * @param node: tree node to be free()'d
+ * @param data_free: callback for destroying the data held in node
+ * @return Returns TRUE if the node is destroyed successfully, FALSE if not.
+ *
+ * If you don't want the children free'd then you need to remove the node first.
+ */
+int ecore_tree_node_destroy(Ecore_Tree_Node * node, Ecore_Free_Cb data_free)
+{
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ ECORE_WRITE_LOCK(node);
+ if (data_free)
+ data_free(node->value);
+ ECORE_WRITE_UNLOCK(node);
+
+ ECORE_DESTROY_LOCKS(node);
+
+ FREE(node);
+
+ return TRUE;
+}
+
+/*
+ * @brief Set the value of the node to value
+ * @param node: the node to be set
+ * @param value: the value to set the node to.
+ * @return Returns TRUE if the node is set successfully, FALSE if not.
+ */
+int ecore_tree_node_value_set(Ecore_Tree_Node * node, void *value)
+{
+ CHECK_PARAM_POINTER_RETURN("node", node,
+ FALSE);
+
+ ECORE_WRITE_LOCK(node);
+ node->value = value;
+ ECORE_WRITE_UNLOCK(node);
+
+ return TRUE;
+}
+
+/*
+ * @brief Get the value of the node
+ * @param node: the node that contains the desired value
+ * @return Returns NULL if an error, otherwise the value associated with node
+ */
+void *ecore_tree_node_value_get(Ecore_Tree_Node * node)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+ ECORE_READ_LOCK(node);
+ ret = node->value;
+ ECORE_READ_UNLOCK(node);
+
+ return ret;
+}
+
+/*
+ * @brief Set the value of the node's key to key
+ * @param node: the node to be set
+ * @param key: the value to set it's key to.
+ * @return Returns TRUE if the node is set successfully, FALSE if not.
+ */
+int ecore_tree_node_key_set(Ecore_Tree_Node * node, void *key)
+{
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ ECORE_WRITE_LOCK(node);
+ node->key = key;
+ ECORE_WRITE_UNLOCK(node);
+
+ return TRUE;
+}
+
+/*
+ * @brief Get the value of the node's key
+ * @param node: the node that contains the desired key
+ *
+ * @return Returns NULL if an error occurs, otherwise the key is returned
+ */
+void *ecore_tree_node_key_get(Ecore_Tree_Node * node)
+{
+ void *ret;
+
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+ ECORE_READ_LOCK(node);
+ ret = node->key;
+ ECORE_READ_UNLOCK(node);
+
+ return ret;
+}
+
+/**
+ * @brief Free the tree and it's stored data
+ * @param tree: the tree to destroy
+ *
+ * @return Returns TRUE if tree destroyed successfully, FALSE if not.
+ */
+int ecore_tree_destroy(Ecore_Tree * tree)
+{
+ Ecore_Tree_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+
+ ECORE_WRITE_LOCK(tree);
+ while ((node = tree->tree)) {
+ ecore_tree_remove_node(tree, node);
+ ecore_tree_node_destroy(node, tree->free_func);
+ }
+ ECORE_WRITE_UNLOCK(tree);
+ ECORE_DESTROY_LOCKS(tree);
+
+ FREE(tree);
+
+ return TRUE;
+}
+
+/**
+ * @brief Return the node corresponding to key
+ * @param tree: the tree to search
+ * @param key: the key to search for in the tree
+ *
+ * @return Returns the node corresponding to the key if found, otherwise NULL.
+ */
+Ecore_Tree_Node *ecore_tree_get_node(Ecore_Tree * tree, void *key)
+{
+ Ecore_Tree_Node *ret;
+
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+
+ ECORE_READ_LOCK(tree);
+ ret = tree_node_find(tree, key);
+ ECORE_READ_UNLOCK(tree);
+
+ return ret;
+}
+
+/**
+ * @brief Return the value corresponding to key
+ * @param tree: the tree to search
+ * @param key: the key to search for in @a tree
+ * @return Returns the value corresponding to the key if found, otherwise NULL.
+ */
+void *ecore_tree_get(Ecore_Tree * tree, void *key)
+{
+ void *ret;
+ Ecore_Tree_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+
+ ECORE_READ_LOCK(tree);
+ node = tree_node_find(tree, key);
+ ECORE_READ_UNLOCK(tree);
+
+ ECORE_READ_LOCK(node);
+ ret = (node ? node->value : NULL);
+ ECORE_READ_UNLOCK(node);
+
+ return ret;
+}
+
+/**
+ * @brief Find the closest value greater than or equal to the key.
+ * @param tree The tree to search.
+ * @param key The key to search for in @a tree.
+ * @return NULL if no valid nodes, otherwise the node greater than or
+ * equal to the key
+ */
+void *ecore_tree_get_closest_larger(Ecore_Tree * tree, void *key)
+{
+ Ecore_Tree_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+
+ ECORE_READ_LOCK(tree);
+ node = tree_node_find(tree, key);
+ ECORE_READ_UNLOCK(tree);
+
+ if (node)
+ return node;
+
+ ECORE_READ_LOCK(tree);
+ node = tree_node_find_parent(tree, key);
+
+ if (!node) {
+ ECORE_READ_UNLOCK(tree);
+ return NULL;
+ }
+
+ ECORE_READ_LOCK(node);
+ if (tree->compare_func(node->key, key) < 0)
+ return NULL;
+ ECORE_READ_UNLOCK(node);
+ ECORE_READ_UNLOCK(tree);
+
+ return node;
+}
+
+/**
+ * @brief Find the closest value <= key
+ * @param tree the tree to search
+ * @param key the key to search for in tree
+ * @return Returns NULL if no valid nodes, otherwise the node <= key
+ */
+void *ecore_tree_get_closest_smaller(Ecore_Tree * tree, void *key)
+{
+ Ecore_Tree_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+
+ ECORE_READ_LOCK(tree);
+ node = tree_node_find(tree, key);
+ ECORE_READ_UNLOCK(tree);
+
+ if (node)
+ return node;
+
+ ECORE_READ_LOCK(tree);
+ node = tree_node_find_parent(tree, key);
+ ECORE_READ_LOCK(tree);
+
+ if (node)
+ node = node->right_child;
+
+ return node;
+}
+
+/**
+ * Set the value associated with key to @a value.
+ * @param tree The tree that contains the key/value pair.
+ * @param key The key to identify which node to set a value.
+ * @param value Value to set the found node.
+ * @return TRUE if successful, FALSE if not.
+ */
+int ecore_tree_set(Ecore_Tree * tree, void *key, void *value)
+{
+ Ecore_Tree_Node *node = NULL;
+
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+
+ ECORE_READ_LOCK(tree);
+ node = tree_node_find(tree, key);
+ ECORE_READ_UNLOCK(tree);
+
+ if (!node) {
+ node = ecore_tree_node_new();
+ ecore_tree_node_key_set(node, key);
+ if (!ecore_tree_add_node(tree, node))
+ return FALSE;
+ }
+ ecore_tree_node_value_set(node, value);
+
+ ECORE_WRITE_LOCK(tree);
+ for (; node; node = node->parent)
+ tree_node_balance(tree, node);
+ ECORE_WRITE_UNLOCK(tree);
+
+ return TRUE;
+}
+
+/**
+ * Place a node in the tree.
+ * @param tree The tree to add @a node.
+ * @param node The node to add to @a tree.
+ * @return TRUE on a successful add, FALSE otherwise.
+ */
+int ecore_tree_add_node(Ecore_Tree * tree, Ecore_Tree_Node * node)
+{
+ Ecore_Tree_Node *travel = NULL;
+
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ /* Find where to put this new node. */
+ if (!tree->tree) {
+ tree->tree = node;
+ } else {
+ travel = tree_node_find_parent(tree, node->key);
+ node->parent = travel;
+
+ /* The node is less than travel */
+ if (tree->compare_func(node->key, travel->key) < 0) {
+ travel->right_child = node;
+ travel->max_left = 1;
+ /* The node is greater than travel */
+ } else {
+ travel->left_child = node;
+ travel->max_right = 1;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/**
+ * Remove the node from the tree.
+ * @param tree The tree to remove @a node from.
+ * @param node The node to remove from @a tree.
+ * @return TRUE on a successful remove, FALSE otherwise.
+ */
+int ecore_tree_remove_node(Ecore_Tree * tree, Ecore_Tree_Node * node)
+{
+ Ecore_Tree_Node *traverse;
+
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ /*
+ * Find the nearest value to the balanced one.
+ */
+ if (node->left_child) {
+ traverse = node->left_child;
+
+ /* Now work our way down right side of the traverse node.
+ * This will give us the node with the next closest value
+ * to the current node. If traverse had no right node, then
+ * this will stop at node's left node. */
+ while (traverse->right_child) {
+ traverse = traverse->right_child;
+ }
+
+ /*
+ * Hook any dropped leaves into the moved nodes spot
+ */
+ if (traverse->parent)
+ traverse->parent->left_child = traverse->left_child;
+ }
+ else if (node->right_child) {
+ traverse = node->right_child;
+
+ /* Now work our way down left side of the traverse node.
+ * This will give us the node with the next closest value
+ * to the current node. If traverse had no left node, then
+ * this will stop at node's right node. */
+ while (traverse->left_child) {
+ traverse = traverse->left_child;
+ }
+
+ /*
+ * Hook any dropped leaves into the moved nodes spot
+ */
+ if (traverse->right_child)
+ traverse->right_child->parent = traverse->parent;
+
+ if (traverse->parent)
+ traverse->parent->right_child = traverse->right_child;
+ else
+ tree->tree = traverse->right_child;
+ }
+ else
+ traverse = NULL;
+
+ if (traverse) {
+
+ /*
+ * Ensure that we don't get a recursive reference.
+ */
+ if (node->right_child && node->right_child != traverse) {
+ node->right_child->parent = traverse;
+ traverse->right_child = node->right_child;
+ }
+
+ if (node->left_child && node->left_child != traverse) {
+ node->left_child->parent = traverse;
+ traverse->left_child = node->left_child;
+ }
+
+ /*
+ * Unlink the node to be moved from it's parent.
+ */
+ if (traverse->parent) {
+ if (traverse->parent->left_child == traverse)
+ traverse->parent->left_child = NULL;
+ else
+ traverse->parent->right_child = NULL;
+ }
+ traverse->parent = node->parent;
+ }
+
+ if (node->parent) {
+ if (node == node->parent->left_child)
+ node->parent->left_child = traverse;
+ else
+ node->parent->right_child = traverse;
+ }
+
+ if (tree->tree == node)
+ tree->tree = traverse;
+
+ node->parent = node->left_child = node->right_child = NULL;
+
+ /*
+ * Rebalance the tree to ensure short search paths.
+ */
+ while (traverse) {
+ tree_node_balance(tree, traverse);
+ traverse = traverse->parent;
+ }
+
+ return TRUE;
+}
+
+/**
+ * Remove the key from the tree.
+ * @param tree The tree to remove @a key.
+ * @param key The key to remove from @a tree.
+ * @return TRUE on a successful remove, FALSE otherwise.
+ */
+int ecore_tree_remove(Ecore_Tree * tree, void *key)
+{
+ Ecore_Tree_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+ if (!tree->tree)
+ return FALSE;
+
+ /* Find the node we need to remove */
+ node = tree_node_find(tree, key);
+ if (!node)
+ return FALSE;
+
+ if (!ecore_tree_remove_node(tree, node))
+ return FALSE;
+
+ ecore_tree_node_destroy(node, tree->free_func);
+
+ return TRUE;
+}
+
+/**
+ * @brief Test to see if the tree has any nodes
+ * @param tree: the tree to check for nodes
+ * @return Returns TRUE if no nodes exist, FALSE otherwise
+ */
+int ecore_tree_is_empty(Ecore_Tree * tree)
+{
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+
+ if (!tree->tree)
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
+ * @brief Execute function for each value in the tree
+ * @param tree: the tree to traverse
+ * @param for_each_func: the function to execute for each value in the tree
+ * @param user_data: data passed to each for_each_func call
+ * @return Returns TRUE on success, FALSE on failure.
+ */
+int ecore_tree_for_each_node_value(Ecore_Tree * tree,
+ Ecore_For_Each for_each_func, void *user_data)
+{
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+ CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE);
+
+ if (!tree->tree)
+ return FALSE;
+
+ return tree_for_each_node_value(tree->tree, for_each_func, user_data);
+}
+
+/**
+ * @brief Execute the function for each node in the tree
+ * @param tree: the tree to traverse
+ * @param for_each_func: the function to execute for each node
+ * @param user_data: data passed to each for_each_func call
+ * @return Returns TRUE on success, FALSE on failure.
+ */
+int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func,
+ void *user_data)
+{
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+ CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE);
+
+ if (!tree->tree)
+ return FALSE;
+
+ return tree_for_each_node(tree->tree, for_each_func, user_data);
+}
+
+/* Find the parent for the key */
+Ecore_Tree_Node *tree_node_find_parent(Ecore_Tree * tree, void *key)
+{
+ Ecore_Tree_Node *parent, *travel;
+
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+
+ parent = tree_node_find(tree, key);
+ if (parent)
+ parent = parent->parent;
+
+ travel = tree->tree;
+ if (!travel)
+ return NULL;
+
+ while (!parent) {
+ int compare;
+
+ if ((compare = tree->compare_func(key, travel->key)) < 0) {
+ if (!travel->right_child)
+ parent = travel;
+ travel = travel->right_child;
+ } else {
+ if (!travel->left_child)
+ parent = travel;
+ travel = travel->left_child;
+ }
+ }
+
+ return parent;
+}
+
+/* Search for the node with a specified key */
+Ecore_Tree_Node *tree_node_find(Ecore_Tree * tree, void *key)
+{
+ int compare;
+ Ecore_Tree_Node *node;
+
+ CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
+
+ node = tree->tree;
+ while (node && (compare = tree->compare_func(key, node->key)) != 0) {
+
+ if (compare < 0) {
+ if (!node->right_child) {
+ return NULL;
+ }
+
+ node = node->right_child;
+ } else {
+ if (!node->left_child) {
+ return NULL;
+ }
+
+ node = node->left_child;
+ }
+ }
+
+ return node;
+}
+
+/* Balance the tree with respect to node */
+int tree_node_balance(Ecore_Tree * tree, Ecore_Tree_Node * top_node)
+{
+ int balance;
+
+ CHECK_PARAM_POINTER_RETURN("top_node", top_node, FALSE);
+
+ /* Get the height of the left branch. */
+ if (top_node->right_child) {
+ top_node->max_left = MAX_HEIGHT(top_node->right_child) + 1;
+ } else
+ top_node->max_left = 0;
+
+ /* Get the height of the right branch. */
+ if (top_node->left_child) {
+ top_node->max_right = MAX_HEIGHT(top_node->left_child) + 1;
+ } else
+ top_node->max_right = 0;
+
+ /* Determine which side has a larger height. */
+ balance = top_node->max_right - top_node->max_left;
+
+ /* if the left side has a height advantage >1 rotate right */
+ if (balance < -1)
+ tree_node_rotate_right(tree, top_node);
+ /* else if the left side has a height advantage >1 rotate left */
+ else if (balance > 1)
+ tree_node_rotate_left(tree, top_node);
+
+ return TRUE;
+}
+
+/* Tree is overbalanced to the left, so rotate nodes to the right. */
+int tree_node_rotate_right(Ecore_Tree * tree, Ecore_Tree_Node * top_node)
+{
+ Ecore_Tree_Node *temp;
+
+ CHECK_PARAM_POINTER_RETURN("top_node", top_node, FALSE);
+
+ /* The left branch's right branch becomes the nodes left branch,
+ * the left branch becomes the top node, and the node becomes the
+ * right branch. */
+ temp = top_node->right_child;
+ top_node->right_child = temp->left_child;
+ temp->left_child = top_node;
+
+ /* Make sure the nodes know who their new parents are and the tree
+ * structure knows the start of the tree. */
+ temp->parent = top_node->parent;
+ if (temp->parent == NULL)
+ tree->tree = temp;
+ else {
+ if (temp->parent->left_child == top_node)
+ temp->parent->left_child = temp;
+ else
+ temp->parent->right_child = temp;
+ }
+ top_node->parent = temp;
+
+ /* And recalculate node heights */
+ tree_node_balance(tree, top_node);
+ tree_node_balance(tree, temp);
+
+ return TRUE;
+}
+
+/* The tree is overbalanced to the right, so we rotate nodes to the left */
+int tree_node_rotate_left(Ecore_Tree * tree, Ecore_Tree_Node * top_node)
+{
+ Ecore_Tree_Node *temp;
+
+ CHECK_PARAM_POINTER_RETURN("top_node", top_node, FALSE);
+
+ /*
+ * The right branch's left branch becomes the nodes right branch,
+ * the right branch becomes the top node, and the node becomes the
+ * left branch.
+ */
+ temp = top_node->left_child;
+ top_node->left_child = temp->right_child;
+ temp->right_child = top_node;
+
+ /* Make sure the nodes know who their new parents are. */
+ temp->parent = top_node->parent;
+ if (temp->parent == NULL)
+ tree->tree = temp;
+ else {
+ if (temp->parent->left_child == top_node)
+ temp->parent->left_child = temp;
+ else
+ temp->parent->right_child = temp;
+ }
+ top_node->parent = temp;
+
+ /* And recalculate node heights */
+ tree_node_balance(tree, top_node);
+ tree_node_balance(tree, temp);
+
+ return TRUE;
+}
+
+/*
+ * @brief Execute a function for each node below this point in the tree.
+ * @param node: the highest node in the tree the function will be executed for
+ * @param for_each_func: the function to pass the nodes as data into
+ * @param user_data: data passed to each for_each_func call
+ * @return Returns FALSE if an error condition occurs, otherwise TRUE
+ */
+int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func,
+ void *user_data)
+{
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ if (node->right_child)
+ tree_for_each_node(node->right_child, for_each_func, user_data);
+
+ if (node->left_child)
+ tree_for_each_node(node->left_child, for_each_func, user_data);
+
+ for_each_func(node, user_data);
+
+ return TRUE;
+}
+
+
+/*
+ * @brief Execute a function for each node below this point in the tree.
+ * @param node: the highest node in the tree the function will be executed for
+ * @param for_each_func: the function to pass the nodes values as data
+ * @return Returns FALSE if an error condition occurs, otherwise TRUE
+ */
+int tree_for_each_node_value(Ecore_Tree_Node * node,
+ Ecore_For_Each for_each_func, void *user_data)
+{
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ if (node->right_child)
+ tree_for_each_node_value(node->right_child, for_each_func, user_data);
+
+ if (node->left_child)
+ tree_for_each_node_value(node->left_child, for_each_func, user_data);
+
+ for_each_func(node->value, user_data);
+
+ return TRUE;
+}
diff --git a/ecore/src/lib/ecore/ecore_value.c b/ecore/src/lib/ecore/ecore_value.c
new file mode 100644
index 0000000..d893809
--- /dev/null
+++ b/ecore/src/lib/ecore/ecore_value.c
@@ -0,0 +1,118 @@
+/* ecore_value.c
+
+Copyright (C) 2001 Christopher Rosendahl <smugg@fatelabs.com>
+ Nathan Ingersoll <ningerso@d.umn.edu>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies of the Software and its documentation and acknowledgment shall be
+given in the documentation and software packages that this Software was
+used.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <Ecore.h>
+
+const unsigned int ecore_prime_table[] = { 17, 31, 61, 127, 257, 509, 1021,
+ 2053, 4093, 8191, 16381, 32771, 65537, 131071, 262147, 524287, 1048573,
+ 2097143, 4194301, 8388617, 16777213
+};
+
+inline void ecore_print_warning(const char *function, const char *sparam)
+{
+ fprintf(stderr, "***** Developer Warning ***** :\n"
+ "\tThis program is calling:\n\n"
+ "\t%s();\n\n"
+ "\tWith the parameter:\n\n"
+ "\t%s\n\n"
+ "\tbeing NULL. Please fix your program.\n", function, sparam);
+ fflush(stderr);
+}
+
+/**
+ * Just casts the key to an unsigned int
+ * @param key The key to return compute a hash value
+ * @return The key cast to an unsigned int.
+ */
+unsigned int ecore_direct_hash(void *key)
+{
+ return ((unsigned int) key);
+}
+
+/**
+ * Compute the hash value of a string
+ * @param key A pointer to the string to compute a hash value
+ * @return A computed hash value for @a key.
+ */
+unsigned int ecore_str_hash(void *key)
+{
+ int i;
+ unsigned int value = 0;
+ char *k = (char *) key;
+
+ if (!k)
+ return 0;
+
+ for (i = 0; k[i] != '\0'; i++) {
+ value ^= ((unsigned int) k[i] << ((i * 5) %
+ (sizeof(unsigned int) * 8)));
+ }
+
+ return value;
+}
+
+/**
+ * Perform a direct comparison of two keys' values
+ * @param key1 The first key to compare
+ * @param key2 The second key to compare
+ * @return A strcmp style value to indicate the larger key
+ */
+int ecore_direct_compare(void *key1, void *key2)
+{
+ unsigned int k1, k2;
+
+ k1 = (unsigned int) key1;
+ k2 = (unsigned int) key2;
+
+ if (k1 > k2)
+ return 1;
+
+ if (k1 < k2)
+ return -1;
+
+ return 0;
+}
+
+/**
+ * Perform a string comparison of two keys values
+ * @param key1 The first key to compare
+ * @param key2 The second key to compare
+ * @return A strcmp style value to indicate the larger key
+ */
+int ecore_str_compare(void *key1, void *key2)
+{
+ char *k1, *k2;
+
+ if (!key1 || !key2)
+ return ecore_direct_compare(key1, key2);
+ else if (key1 == key2)
+ return 0;
+
+ k1 = (char *) key1;
+ k2 = (char *) key2;
+
+ return strcmp(k1, k2);
+}
diff --git a/ecore/src/lib/ecore_con/.cvsignore b/ecore/src/lib/ecore_con/.cvsignore
new file mode 100644
index 0000000..c9eb519
--- /dev/null
+++ b/ecore/src/lib/ecore_con/.cvsignore
@@ -0,0 +1,7 @@
+.deps
+.libs
+Ecore_Con.h
+Makefile
+Makefile.in
+ecore_con.lo
+libecore_con.la
diff --git a/ecore/src/lib/ecore_con/CVS/Entries b/ecore/src/lib/ecore_con/CVS/Entries
new file mode 100644
index 0000000..1740d38
--- /dev/null
+++ b/ecore/src/lib/ecore_con/CVS/Entries
@@ -0,0 +1,7 @@
+/.cvsignore/1.2/Wed Mar 31 16:47:45 2004//THEAD
+/Ecore_Con.h/1.9/Fri Jun 24 13:38:27 2005//THEAD
+/Makefile.am/1.10/Fri Jun 24 13:38:27 2005//THEAD
+/ecore_con.c/1.41/Fri Apr 29 04:51:31 2005//THEAD
+/ecore_con_private.h/1.8/Fri Jun 24 13:38:27 2005//THEAD
+/ecore_con_url.c/1.6/Fri Jun 24 15:01:59 2005//THEAD
+D
diff --git a/ecore/src/lib/ecore_con/CVS/Repository b/ecore/src/lib/ecore_con/CVS/Repository
new file mode 100644
index 0000000..282cc26
--- /dev/null
+++ b/ecore/src/lib/ecore_con/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/lib/ecore_con
diff --git a/ecore/src/lib/ecore_con/CVS/Root b/ecore/src/lib/ecore_con/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/lib/ecore_con/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/lib/ecore_con/CVS/Tag b/ecore/src/lib/ecore_con/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/lib/ecore_con/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/lib/ecore_con/Ecore_Con.h b/ecore/src/lib/ecore_con/Ecore_Con.h
new file mode 100644
index 0000000..fd022b3
--- /dev/null
+++ b/ecore/src/lib/ecore_con/Ecore_Con.h
@@ -0,0 +1,168 @@
+#ifndef _ECORE_CON_H
+#define _ECORE_CON_H
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef WIN32
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef GCC_HASCLASSVISIBILITY
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file Ecore_Con.h
+ * @brief Sockets functions.
+ *
+ * The Ecore Connection Library ( @c Ecore_Con ) provides simple mechanisms
+ * for communications between programs using reliable sockets. It saves
+ * the programmer from having to worry about file descripters and waiting
+ * for incoming connections.
+ *
+ * There are two main objects in the @c Ecore_Con library: the @c
+ * Ecore_Con_Server and the @c Ecore_Con_Client.
+ *
+ * The @c Ecore_Con_Server represents a server to connect to. It is
+ * represents a server that can be connected to. It is used regardless
+ * of whether the program is acting as a server or client itself.
+ *
+ * To create a listening server, call @c ecore_con_server_add().
+ *
+ * To connect to a server, call @c ecore_con_server_connect(). Data can
+ * then be sent to the server using the @c ecore_con_server_send().
+ *
+ * Whenever a client connection is made to an @c Ecore_Con_Server, a
+ * @c ECORE_CON_CLIENT_ADD event is emitted. Any event callbacks that are
+ * called receive a @c Ecore_Con_Client object, which represents a
+ * connection that that particular client.
+ *
+ * Functions are described in the following groupings:
+ * @li @ref Ecore_Con_Lib_Group
+ * @li @ref Ecore_Con_Server_Group
+ * @li @ref Ecore_Con_Client_Group
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ECORE_CON_PRIVATE_H
+ typedef void Ecore_Con_Server; /**< A connection handle */
+ typedef void Ecore_Con_Client; /**< A connection handle */
+ typedef void Ecore_Con_Url;
+
+ typedef enum _Ecore_Con_Type
+ {
+ ECORE_CON_LOCAL_USER,
+ ECORE_CON_LOCAL_SYSTEM,
+ ECORE_CON_REMOTE_SYSTEM,
+ ECORE_CON_USE_SSL = 16
+ } Ecore_Con_Type;
+
+#endif
+
+ typedef struct _Ecore_Con_Event_Client_Add Ecore_Con_Event_Client_Add;
+ typedef struct _Ecore_Con_Event_Client_Del Ecore_Con_Event_Client_Del;
+ typedef struct _Ecore_Con_Event_Server_Add Ecore_Con_Event_Server_Add;
+ typedef struct _Ecore_Con_Event_Server_Del Ecore_Con_Event_Server_Del;
+ typedef struct _Ecore_Con_Event_Client_Data Ecore_Con_Event_Client_Data;
+ typedef struct _Ecore_Con_Event_Server_Data Ecore_Con_Event_Server_Data;
+ typedef struct _Ecore_Con_Event_Url_Data Ecore_Con_Event_Url_Data;
+ typedef struct _Ecore_Con_Event_Url_Complete Ecore_Con_Event_Url_Complete;
+
+ struct _Ecore_Con_Event_Client_Add
+ {
+ Ecore_Con_Client *client;
+ };
+
+ struct _Ecore_Con_Event_Client_Del
+ {
+ Ecore_Con_Client *client;
+ };
+
+ struct _Ecore_Con_Event_Server_Add
+ {
+ Ecore_Con_Server *server;
+ };
+
+ struct _Ecore_Con_Event_Server_Del
+ {
+ Ecore_Con_Server *server;
+ };
+
+ struct _Ecore_Con_Event_Client_Data
+ {
+ Ecore_Con_Client *client;
+ void *data;
+ int size;
+ };
+
+ struct _Ecore_Con_Event_Server_Data
+ {
+ Ecore_Con_Server *server;
+ void *data;
+ int size;
+ };
+
+ struct _Ecore_Con_Event_Url_Data
+ {
+ Ecore_Con_Url *url_con;
+ void *data;
+ int size;
+ };
+
+ struct _Ecore_Con_Event_Url_Complete
+ {
+ Ecore_Con_Url *url_con;
+ int status;
+ };
+
+ extern int ECORE_CON_EVENT_CLIENT_ADD;
+ extern int ECORE_CON_EVENT_CLIENT_DEL;
+ extern int ECORE_CON_EVENT_SERVER_ADD;
+ extern int ECORE_CON_EVENT_SERVER_DEL;
+ extern int ECORE_CON_EVENT_CLIENT_DATA;
+ extern int ECORE_CON_EVENT_SERVER_DATA;
+ extern int ECORE_CON_EVENT_URL_DATA;
+ extern int ECORE_CON_EVENT_URL_COMPLETE;
+
+ EAPI int ecore_con_init(void);
+ EAPI int ecore_con_shutdown(void);
+
+ EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type, const char *name, int port, const void *data);
+
+ EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type, const char *name, int port, const void *data);
+ EAPI void *ecore_con_server_del(Ecore_Con_Server *svr);
+ EAPI void *ecore_con_server_data_get(Ecore_Con_Server *svr);
+ EAPI int ecore_con_server_connected_get(Ecore_Con_Server *svr);
+ EAPI int ecore_con_server_send(Ecore_Con_Server *svr, void *data, int size);
+ EAPI void ecore_con_server_client_limit_set(Ecore_Con_Server *svr, int client_limit, char reject_excess_clients);
+
+ EAPI int ecore_con_client_send(Ecore_Con_Client *cl, void *data, int size);
+ EAPI Ecore_Con_Server *ecore_con_client_server_get(Ecore_Con_Client *cl);
+ EAPI void *ecore_con_client_del(Ecore_Con_Client *cl);
+ EAPI void ecore_con_client_data_set(Ecore_Con_Client *cl, const void *data);
+ EAPI void *ecore_con_client_data_get(Ecore_Con_Client *cl);
+
+ EAPI int ecore_con_ssl_available_get(void);
+
+ EAPI int ecore_con_url_init(void);
+ EAPI int ecore_con_url_shutdown(void);
+ EAPI Ecore_Con_Url *ecore_con_url_new(const char *url);
+ EAPI void ecore_con_url_destroy(Ecore_Con_Url *url_con);
+ EAPI int ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url);
+ EAPI int ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *content_type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ecore/src/lib/ecore_con/Makefile.am b/ecore/src/lib/ecore_con/Makefile.am
new file mode 100644
index 0000000..e40be6e
--- /dev/null
+++ b/ecore/src/lib/ecore_con/Makefile.am
@@ -0,0 +1,36 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_con \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_con \
+@SSL_CFLAGS@ @curl_cflags@
+
+libecore_con_la_LDFLAGS = -version-info 1:0:0 \
+-L$(top_builddir)/src/lib/ecore/.libs
+
+if BUILD_ECORE_CON
+
+lib_LTLIBRARIES = libecore_con.la
+include_HEADERS = \
+Ecore_Con.h
+
+libecore_con_la_SOURCES = \
+ecore_con.c \
+ecore_con_url.c \
+ecore_con_private.h
+
+libecore_con_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+@SSL_LIBS@ @winsock_libs@ @curl_libs@
+
+libecore_con_la_DEPENDENCIES = \
+$(top_builddir)/src/lib/ecore/libecore.la
+
+endif
+
+EXTRA_DIST = \
+ecore_con.c \
+ecore_con_url.c \
+ecore_con_private.h
diff --git a/ecore/src/lib/ecore_con/ecore_con.c b/ecore/src/lib/ecore_con/ecore_con.c
new file mode 100644
index 0000000..b394ae2
--- /dev/null
+++ b/ecore/src/lib/ecore_con/ecore_con.c
@@ -0,0 +1,1270 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "Ecore.h"
+#include "config.h"
+#include "ecore_private.h"
+#include "ecore_con_private.h"
+#include "Ecore_Con.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#elif WIN32
+#include <winsock.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <netdb.h>
+
+#if USE_OPENSSL
+#include <time.h>
+#endif
+
+static void _ecore_con_server_free(Ecore_Con_Server *svr);
+static void _ecore_con_client_free(Ecore_Con_Client *cl);
+static int _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static void _ecore_con_server_flush(Ecore_Con_Server *svr);
+static void _ecore_con_client_flush(Ecore_Con_Client *cl);
+static void _ecore_con_event_client_data_free(void *data, void *ev);
+static void _ecore_con_event_server_data_free(void *data, void *ev);
+
+int ECORE_CON_EVENT_CLIENT_ADD = 0;
+int ECORE_CON_EVENT_CLIENT_DEL = 0;
+int ECORE_CON_EVENT_SERVER_ADD = 0;
+int ECORE_CON_EVENT_SERVER_DEL = 0;
+int ECORE_CON_EVENT_CLIENT_DATA = 0;
+int ECORE_CON_EVENT_SERVER_DATA = 0;
+
+static Ecore_List *servers = NULL;
+static int init_count = 0;
+
+#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
+
+/**
+ * @defgroup Ecore_Con_Lib_Group Ecore Connection Library Functions
+ *
+ * Utility functions that set up and shut down the Ecore Connection
+ * library.
+ */
+
+/**
+ * Initialises the Ecore_Con library.
+ * @return Number of times the library has been initialised without being
+ * shut down.
+ * @ingroup Ecore_Con_Lib_Group
+ */
+int
+ecore_con_init(void)
+{
+ init_count++;
+ if (!ECORE_CON_EVENT_CLIENT_ADD)
+ {
+ ECORE_CON_EVENT_CLIENT_ADD = ecore_event_type_new();
+ ECORE_CON_EVENT_CLIENT_DEL = ecore_event_type_new();
+ ECORE_CON_EVENT_SERVER_ADD = ecore_event_type_new();
+ ECORE_CON_EVENT_SERVER_DEL = ecore_event_type_new();
+ ECORE_CON_EVENT_CLIENT_DATA = ecore_event_type_new();
+ ECORE_CON_EVENT_SERVER_DATA = ecore_event_type_new();
+
+#if USE_OPENSSL
+ SSL_library_init();
+ SSL_load_error_strings();
+#endif
+ }
+ if (!servers)
+ servers = ecore_list_new();
+ return init_count;
+}
+
+/**
+ * Shuts down the Ecore_Con library.
+ * @return Number of times the library has been initialised without being
+ * shut down.
+ * @ingroup Ecore_Con_Lib_Group
+ */
+int
+ecore_con_shutdown(void)
+{
+ if (init_count > 0)
+ {
+ init_count--;
+ if (init_count > 0) return init_count;
+ while (!ecore_list_is_empty(servers))
+ _ecore_con_server_free(ecore_list_remove_first(servers));
+ ecore_list_destroy(servers);
+ servers = NULL;
+ }
+ return 0;
+}
+
+/**
+ * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions
+ *
+ * Functions that operate on Ecore server objects.
+ */
+
+/**
+ * Creates a server to listen for connections.
+ *
+ * The socket on which the server listens depends on the connection
+ * type:
+ * @li If @a compl_type is @c ECORE_CON_LOCAL_USER, the server will listen on
+ * the Unix socket "~/.ecore/[name]/[port]".
+ * @li If @a compl_type is @c ECORE_CON_LOCAL_SYSTEM, the server will listen
+ * on Unix socket "/tmp/.ecore_service|[name]|[port]".
+ * @li If @a compl_type is @c ECORE_CON_REMOTE_SYSTEM, the server will listen
+ * on TCP port @c port.
+ *
+ * @param compl_type The connection type.
+ * @param name Name to associate with the socket. It is used when
+ * generating the socket name of a Unix socket. Though
+ * it is not used for the TCP socket, it still needs to
+ * be a valid character array. @c NULL will not be
+ * accepted.
+ * @param port Number to identify socket. When a Unix socket is used,
+ * it becomes part of the socket name. When a TCP socket
+ * is used, it is used as the TCP port.
+ * @param data Data to associate with the created Ecore_Con_Server
+ * object.
+ * @return A new Ecore_Con_Server.
+ * @ingroup Ecore_Con_Server_Group
+ */
+Ecore_Con_Server *
+ecore_con_server_add(Ecore_Con_Type compl_type,
+ const char *name,
+ int port,
+ const void *data)
+{
+ Ecore_Con_Server *svr;
+ Ecore_Con_Type type;
+ struct sockaddr_in socket_addr;
+ struct sockaddr_un socket_unix;
+ struct linger lin;
+ char buf[4096];
+
+ if (port < 0) return NULL;
+ /* local user socket: FILE: ~/.ecore/[name]/[port] */
+ /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */
+ /* remote system socket: TCP/IP: [name]:[port] */
+ svr = calloc(1, sizeof(Ecore_Con_Server));
+ if (!svr) return NULL;
+
+ type = compl_type;
+#if USE_OPENSSL
+ /* unset the SSL flag for the following checks */
+ type &= ~ECORE_CON_USE_SSL;
+#endif
+
+ if ((type == ECORE_CON_LOCAL_USER) ||
+ (type == ECORE_CON_LOCAL_SYSTEM))
+ {
+ const char *homedir;
+ struct stat st;
+ mode_t pmode, mask;
+
+ if (!name) goto error;
+ mask =
+ S_IRGRP | S_IWGRP | S_IXGRP |
+ S_IROTH | S_IWOTH | S_IXOTH;
+ if (type == ECORE_CON_LOCAL_USER)
+ {
+ homedir = getenv("HOME");
+ if (!homedir) homedir = getenv("TMP");
+ if (!homedir) homedir = "/tmp";
+ mask = S_IRUSR | S_IWUSR | S_IXUSR;
+ snprintf(buf, sizeof(buf), "%s/.ecore", homedir);
+ if (stat(buf, &st) < 0) mkdir(buf, mask);
+ snprintf(buf, sizeof(buf), "%s/.ecore/%s", homedir, name);
+ if (stat(buf, &st) < 0) mkdir(buf, mask);
+ snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, name, port);
+ mask =
+ S_IRGRP | S_IWGRP | S_IXGRP |
+ S_IROTH | S_IWOTH | S_IXOTH;
+ }
+ else if (type == ECORE_CON_LOCAL_SYSTEM)
+ {
+ mask = 0;
+ if (name[0] == '/')
+ snprintf(buf, sizeof(buf), "%s|%i", name, port);
+ else
+ snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i", name, port);
+ }
+ pmode = umask(mask);
+ start:
+ svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (svr->fd < 0)
+ {
+ umask(pmode);
+ goto error;
+ }
+ if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
+ {
+ umask(pmode);
+ goto error;
+ }
+ if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
+ {
+ umask(pmode);
+ goto error;
+ }
+ lin.l_onoff = 1;
+ lin.l_linger = 100;
+ if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0)
+ {
+ umask(pmode);
+ goto error;
+ }
+ socket_unix.sun_family = AF_UNIX;
+ strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
+ if (bind(svr->fd, (struct sockaddr *)&socket_unix, LENGTH_OF_SOCKADDR_UN(&socket_unix)) < 0)
+ {
+ if (connect(svr->fd, (struct sockaddr *)&socket_unix,
+ LENGTH_OF_SOCKADDR_UN(&socket_unix)) < 0)
+ {
+ if ((type == ECORE_CON_LOCAL_USER) ||
+ (type == ECORE_CON_LOCAL_SYSTEM))
+ {
+ if (unlink(buf) < 0)
+ {
+ umask(pmode);
+ goto error;
+ }
+ else
+ goto start;
+ }
+ else
+ {
+ umask(pmode);
+ goto error;
+ }
+ }
+ else
+ {
+ umask(pmode);
+ goto error;
+ }
+ }
+ if (listen(svr->fd, 4096) < 0)
+ {
+ umask(pmode);
+ goto error;
+ }
+ svr->path = strdup(buf);
+ if (!svr->path)
+ {
+ umask(pmode);
+ goto error;
+ }
+ svr->fd_handler = ecore_main_fd_handler_add(svr->fd,
+ ECORE_FD_READ,
+ _ecore_con_svr_handler, svr,
+ NULL, NULL);
+ umask(pmode);
+ if (!svr->fd_handler) goto error;
+ }
+ else if (type == ECORE_CON_REMOTE_SYSTEM)
+ {
+ svr->fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (svr->fd < 0) goto error;
+ if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
+ if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
+ lin.l_onoff = 1;
+ lin.l_linger = 100;
+ if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0) goto error;
+ socket_addr.sin_family = AF_INET;
+ socket_addr.sin_port = htons(port);
+ socket_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ if (bind(svr->fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) < 0) goto error;
+ if (listen(svr->fd, 4096) < 0) goto error;
+ svr->fd_handler = ecore_main_fd_handler_add(svr->fd,
+ ECORE_FD_READ,
+ _ecore_con_svr_handler, svr,
+ NULL, NULL);
+ if (!svr->fd_handler) goto error;
+ }
+
+#if USE_OPENSSL
+ if (compl_type & ECORE_CON_USE_SSL)
+ {
+ /* SSLv3 gives *weird* results on my box, don't use it yet */
+ if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
+ goto error;
+
+ if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
+ goto error;
+
+ SSL_set_fd(svr->ssl, svr->fd);
+ }
+#endif
+
+ svr->name = strdup(name);
+ if (!svr->name) goto error;
+ svr->type = type;
+ svr->port = port;
+ svr->data = (void *)data;
+ svr->created = 1;
+ svr->reject_excess_clients = 0;
+ svr->client_limit = -1;
+ svr->clients = ecore_list_new();
+ ecore_list_append(servers, svr);
+ ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER);
+ return svr;
+
+ error:
+ if (svr->name) free(svr->name);
+ if (svr->path) free(svr->path);
+ if (svr->fd >= 0) close(svr->fd);
+ if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
+ if (svr->write_buf) free(svr->write_buf);
+#if USE_OPENSSL
+ if (svr->ssl) SSL_free(svr->ssl);
+ if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
+#endif
+ free(svr);
+ return NULL;
+}
+
+/**
+ * Creates a server object to represent the server listening at the
+ * given port.
+ *
+ * The socket to which the server connects depends on the connection type:
+ * @li If @a compl_type is @c ECORE_CON_LOCAL_USER, the function will
+ * connect to the server listening on the Unix socket
+ * "~/.ecore/[name]/[port]".
+ * @li If @a compl_type is @c ECORE_CON_LOCAL_SYSTEM, the function will
+ * connect to the server listening on the Unix socket
+ * "/tmp/.ecore_service|[name]|[port]".
+ * @li If @a compl_type is @c ECORE_CON_REMOTE_SYSTEM, the function will
+ * connect to the server listening on the TCP port "[name]:[port]".
+ *
+ * @param compl_type The connection type.
+ * @param name Name used when determining what socket to connect to.
+ * It is used to generate the socket name when the socket
+ * is a Unix socket. It is used as the hostname when
+ * connecting with a TCP socket.
+ * @param port Number to identify the socket to connect to. Used when
+ * generating the socket name for a Unix socket, or as the
+ * TCP port when connecting to a TCP socket.
+ * @param data Data to associate with the created Ecore_Con_Server
+ * object.
+ * @return A new Ecore_Con_Server.
+ * @ingroup Ecore_Con_Server_Group
+ */
+Ecore_Con_Server *
+ecore_con_server_connect(Ecore_Con_Type compl_type,
+ const char *name,
+ int port,
+ const void *data)
+{
+ Ecore_Con_Server *svr;
+ Ecore_Con_Type type;
+ struct sockaddr_un socket_unix;
+ struct sockaddr_in socket_addr;
+ int curstate = 0;
+ char buf[4096];
+
+ if (!name) return NULL;
+ if (port < 0) return NULL;
+ /* local user socket: FILE: ~/.ecore/[name]/[port] */
+ /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */
+ /* remote system socket: TCP/IP: [name]:[port] */
+ svr = calloc(1, sizeof(Ecore_Con_Server));
+ if (!svr) return NULL;
+
+ type = compl_type;
+#if USE_OPENSSL
+ /* unset the SSL flag for the following checks */
+ type &= ~ECORE_CON_USE_SSL;
+#endif
+
+ if ((type == ECORE_CON_LOCAL_USER) ||
+ (type == ECORE_CON_LOCAL_SYSTEM))
+ {
+ const char *homedir;
+
+ if (type == ECORE_CON_LOCAL_USER)
+ {
+ homedir = getenv("HOME");
+ if (!homedir) homedir = getenv("TMP");
+ if (!homedir) homedir = "/tmp";
+ snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, name, port);
+ }
+ else if (type == ECORE_CON_LOCAL_SYSTEM)
+ {
+ if (name[0] == '/')
+ snprintf(buf, sizeof(buf), "%s|%i", name, port);
+ else
+ snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i", name, port);
+ }
+ svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (svr->fd < 0) goto error;
+ if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
+ if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
+ if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) goto error;
+ socket_unix.sun_family = AF_UNIX;
+ strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
+ if (connect(svr->fd, (struct sockaddr *)&socket_unix, LENGTH_OF_SOCKADDR_UN(&socket_unix)) < 0) goto error;
+ svr->path = strdup(buf);
+ if (!svr->path) goto error;
+ svr->fd_handler = ecore_main_fd_handler_add(svr->fd,
+ ECORE_FD_READ,
+ _ecore_con_cl_handler, svr,
+ NULL, NULL);
+ if (!svr->fd_handler) goto error;
+ {
+ /* we got our server! */
+ Ecore_Con_Event_Server_Add *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Server_Add));
+ if (e)
+ {
+ e->server = svr;
+ ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e, NULL, NULL);
+ }
+ }
+ }
+ else if (type == ECORE_CON_REMOTE_SYSTEM)
+ {
+ struct hostent *he;
+
+ /* FIXME: gethostbyname is blocking... */
+ if (!(he = gethostbyname(name))) goto error;
+ svr->fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (svr->fd < 0) goto error;
+ if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
+ if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
+ if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) goto error;
+ socket_addr.sin_family = AF_INET;
+ socket_addr.sin_port = htons(port);
+ memcpy((struct in_addr *)&socket_addr.sin_addr,
+ he->h_addr, sizeof(struct in_addr));
+ if (connect(svr->fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) < 0)
+ {
+ if (errno != EINPROGRESS)
+ goto error;
+ svr->connecting = 1;
+ svr->fd_handler = ecore_main_fd_handler_add(svr->fd,
+ ECORE_FD_READ | ECORE_FD_WRITE,
+ _ecore_con_cl_handler, svr,
+ NULL, NULL);
+ }
+ else
+ svr->fd_handler = ecore_main_fd_handler_add(svr->fd,
+ ECORE_FD_READ,
+ _ecore_con_cl_handler, svr,
+ NULL, NULL);
+
+ if (!svr->fd_handler) goto error;
+ }
+
+#if USE_OPENSSL
+ if (compl_type & ECORE_CON_USE_SSL)
+ {
+ /* SSLv3 gives *weird* results on my box, don't use it yet */
+ if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
+ goto error;
+
+ if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
+ goto error;
+
+ SSL_set_fd(svr->ssl, svr->fd);
+ }
+#endif
+
+ svr->name = strdup(name);
+ if (!svr->name) goto error;
+ svr->type = type;
+ svr->port = port;
+ svr->data = (void *)data;
+ svr->created = 0;
+ svr->reject_excess_clients = 0;
+ svr->client_limit = -1;
+ svr->clients = ecore_list_new();
+ ecore_list_append(servers, svr);
+ ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER);
+ return svr;
+
+ error:
+ if (svr->name) free(svr->name);
+ if (svr->path) free(svr->path);
+ if (svr->fd >= 0) close(svr->fd);
+ if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
+#if USE_OPENSSL
+ if (svr->ssl) SSL_free(svr->ssl);
+ if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
+#endif
+ free(svr);
+ return NULL;
+}
+
+/**
+ * Closes the connection and frees the given server.
+ * @param svr The given server.
+ * @return Data associated with the server when it was created.
+ * @ingroup Ecore_Con_Server_Group
+ */
+void *
+ecore_con_server_del(Ecore_Con_Server *svr)
+{
+ void *data;
+
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER,
+ "ecore_con_server_del");
+ return NULL;
+ }
+ data = svr->data;
+ _ecore_con_server_free(svr);
+ if (ecore_list_goto(servers, svr)) ecore_list_remove(servers);
+ return data;
+}
+
+/**
+ * Retrieves the data associated with the given server.
+ * @param svr The given server.
+ * @return The associated data.
+ * @ingroup Ecore_Con_Server_Group
+ */
+void *
+ecore_con_server_data_get(Ecore_Con_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER,
+ "ecore_con_server_data_get");
+ return NULL;
+ }
+ return svr->data;
+}
+
+/**
+ * Retrieves whether the given server is currently connected.
+ * @todo Check that this function does what the documenter believes it does.
+ * @param svr The given server.
+ * @return @c 1 if the server is connected. @c 0 otherwise.
+ * @ingroup Ecore_Con_Server_Group
+ */
+int
+ecore_con_server_connected_get(Ecore_Con_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER,
+ "ecore_con_server_connected_get");
+ return 0;
+ }
+ if (svr->connecting) return 0;
+ return 1;
+}
+
+/**
+ * Sends the given data to the given server.
+ * @param svr The given server.
+ * @param data The given data.
+ * @param size Length of the data, in bytes, to send.
+ * @return The number of bytes sent. @c 0 will be returned if there is an
+ * error.
+ * @ingroup Ecore_Con_Server_Group
+ */
+int
+ecore_con_server_send(Ecore_Con_Server *svr, void *data, int size)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER,
+ "ecore_con_server_send");
+ return 0;
+ }
+ if (svr->dead) return 0;
+ if (!data) return 0;
+ if (size < 1) return 0;
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
+ if (svr->write_buf)
+ {
+ unsigned char *newbuf;
+
+ newbuf = realloc(svr->write_buf, svr->write_buf_size + size);
+ if (newbuf) svr->write_buf = newbuf;
+ else return 0;
+ memcpy(svr->write_buf + svr->write_buf_size, data, size);
+ svr->write_buf_size += size;
+ }
+ else
+ {
+ svr->write_buf = malloc(size);
+ if (!svr->write_buf) return 0;
+ svr->write_buf_size = size;
+ memcpy(svr->write_buf, data, size);
+ }
+ return size;
+}
+
+/**
+ * Sets a limit on the number of clients that can be handled concurrently
+ * by the given server, and a policy on what to do if excess clients try to
+ * connect.
+ * Beware that if you set this once ecore is already running, you may
+ * already have pending CLIENT_ADD events in your event queue. Those
+ * clients have already connected and will not be affected by this call.
+ * Only clients subsequently trying to connect will be affected.
+ * @param svr The given server.
+ * @param client_limit The maximum number of clients to handle
+ * concurrently. -1 means unlimited (default). 0
+ * effectively disables the server.
+ * @param reject_excess_clients Set to 1 to automatically disconnect
+ * excess clients as soon as they connect if you are
+ * already handling client_limit clients. Set to 0
+ * (default) to just hold off on the "accept()"
+ * system call until the number of active clients
+ * drops. This causes the kernel to queue up to 4096
+ * connections (or your kernel's limit, whichever is
+ * lower).
+ * @ingroup Ecore_Con_Server_Group
+ */
+void
+ecore_con_server_client_limit_set(Ecore_Con_Server *svr, int client_limit, char reject_excess_clients)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER,
+ "ecore_con_server_client_limit_set");
+ return;
+ }
+ svr->client_limit = client_limit;
+ svr->reject_excess_clients = reject_excess_clients;
+}
+
+/**
+ * @defgroup Ecore_Con_Client_Group Ecore Connection Client Functions
+ *
+ * Functions that operate on Ecore connection client objects.
+ */
+
+/**
+ * Sends the given data to the given client.
+ * @param cl The given client.
+ * @param data The given data.
+ * @param size Length of the data, in bytes, to send.
+ * @return The number of bytes sent. @c 0 will be returned if there is an
+ * error.
+ * @ingroup Ecore_Con_Client_Group
+ */
+int
+ecore_con_client_send(Ecore_Con_Client *cl, void *data, int size)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT,
+ "ecore_con_client_send");
+ return 0;
+ }
+ if (cl->dead) return 0;
+ if (!data) return 0;
+ if (size < 1) return 0;
+ ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
+ if (cl->buf)
+ {
+ unsigned char *newbuf;
+
+ newbuf = realloc(cl->buf, cl->buf_size + size);
+ if (newbuf) cl->buf = newbuf;
+ else return 0;
+ memcpy(cl->buf + cl->buf_size, data, size);
+ cl->buf_size += size;
+ }
+ else
+ {
+ cl->buf = malloc(size);
+ if (!cl->buf) return 0;
+ cl->buf_size = size;
+ memcpy(cl->buf, data, size);
+ }
+ return size;
+}
+
+/**
+ * Retrieves the server representing the socket the client has
+ * connected to.
+ * @param cl The given client.
+ * @return The server that the client connected to.
+ * @ingroup Ecore_Con_Client_Group
+ */
+Ecore_Con_Server *
+ecore_con_client_server_get(Ecore_Con_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT,
+ "ecore_con_client_server_get");
+ return NULL;
+ }
+ return cl->server;
+}
+
+/**
+ * Closes the connection and frees memory allocated to the given client.
+ * @param cl The given client.
+ * @return Data associated with the client.
+ * @ingroup Ecore_Con_Client_Group
+ */
+void *
+ecore_con_client_del(Ecore_Con_Client *cl)
+{
+ void *data;
+
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT,
+ "ecore_con_client_del");
+ return NULL;
+ }
+ data = cl->data;
+ _ecore_con_client_free(cl);
+ if (ecore_list_goto(cl->server->clients, cl)) ecore_list_remove(cl->server->clients);
+ return data;
+}
+
+/**
+ * Sets the data associated with the given client to @p data.
+ * @param cl The given client.
+ * @param data What to set the data to.
+ * @ingroup Ecore_Con_Client_Group
+ */
+void
+ecore_con_client_data_set(Ecore_Con_Client *cl, const void *data)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT,
+ "ecore_con_client_data_set");
+ return;
+ }
+ cl->data = (void *)data;
+}
+
+/**
+ * Retrieves the data associated with the given client.
+ * @param cl The given client.
+ * @return The data associated with @p cl.
+ * @ingroup Ecore_Con_Client_Group
+ */
+void *
+ecore_con_client_data_get(Ecore_Con_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT,
+ "ecore_con_client_data_get");
+ return NULL;
+ }
+ return cl->data;
+}
+
+/**
+ * Returns if SSL support is available
+ * @return 1 if SSL is available, 0 if it is not.
+ * @ingroup Ecore_Con_Client_Group
+ */
+int
+ecore_con_ssl_available_get(void)
+{
+#if USE_OPENSSL
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+static void
+_ecore_con_server_free(Ecore_Con_Server *svr)
+{
+ ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE);
+ while ((svr->write_buf) && (!svr->dead)) _ecore_con_server_flush(svr);
+ if (svr->write_buf) free(svr->write_buf);
+ while (!ecore_list_is_empty(svr->clients))
+ _ecore_con_client_free(ecore_list_remove_first(svr->clients));
+ ecore_list_destroy(svr->clients);
+ if ((svr->created) && (svr->path)) unlink(svr->path);
+ if (svr->fd >= 0) close(svr->fd);
+#if USE_OPENSSL
+ if (svr->ssl)
+ {
+ SSL_shutdown(svr->ssl);
+ SSL_free(svr->ssl);
+ }
+ if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
+#endif
+ if (svr->name) free(svr->name);
+ if (svr->path) free(svr->path);
+ if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
+ free(svr);
+}
+
+static void
+_ecore_con_client_free(Ecore_Con_Client *cl)
+{
+ ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE);
+ while ((cl->buf) && (!cl->dead)) _ecore_con_client_flush(cl);
+ if (cl->buf) free(cl->buf);
+ if (cl->fd >= 0) close(cl->fd);
+ if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler);
+ free(cl);
+}
+
+static int
+_ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ Ecore_Con_Server *svr;
+ int new_fd;
+ struct sockaddr_in incoming;
+ size_t size_in;
+
+ svr = data;
+ if (svr->dead) return 1;
+ if ((svr->client_limit >= 0) && (!svr->reject_excess_clients))
+ {
+ if (ecore_list_nodes(svr->clients) >= svr->client_limit) return 1;
+ }
+ /* a new client */
+ size_in = sizeof(struct sockaddr_in);
+ new_fd = accept(svr->fd, (struct sockaddr *)&incoming, &size_in);
+ if (new_fd >= 0)
+ {
+ Ecore_Con_Client *cl;
+
+ if ((svr->client_limit >= 0) && (svr->reject_excess_clients))
+ {
+ close(new_fd);
+ return 1;
+ }
+
+ cl = calloc(1, sizeof(Ecore_Con_Client));
+ if (!cl)
+ {
+ close(new_fd);
+ return 1;
+ }
+ fcntl(new_fd, F_SETFL, O_NONBLOCK);
+ fcntl(new_fd, F_SETFD, FD_CLOEXEC);
+ cl->fd = new_fd;
+ cl->server = svr;
+ cl->fd_handler = ecore_main_fd_handler_add(cl->fd,
+ ECORE_FD_READ,
+ _ecore_con_svr_cl_handler,
+ cl, NULL, NULL);
+ ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
+ ecore_list_append(svr->clients, cl);
+ {
+ Ecore_Con_Event_Client_Add *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Client_Add));
+ if (e)
+ {
+ e->client = cl;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, e, NULL, NULL);
+ }
+ }
+ }
+ return 1;
+}
+
+#if USE_OPENSSL
+/* Tries to connect an Ecore_Con_Server to an SSL host.
+ * Returns 1 on success, -1 on fatal errors and 0 if the caller
+ * should try again later.
+ */
+static int
+svr_try_connect_ssl(Ecore_Con_Server *svr)
+{
+ int res, ssl_err, flag = 0;
+
+ res = SSL_connect(svr->ssl);
+ if (res == 1) return 1;
+ ssl_err = SSL_get_error(svr->ssl, res);
+
+ if (ssl_err == SSL_ERROR_NONE) return 1;
+ if (ssl_err == SSL_ERROR_WANT_READ) flag = ECORE_FD_READ;
+ else if (ssl_err == SSL_ERROR_WANT_WRITE) flag = ECORE_FD_WRITE;
+ else return -1;
+ if (flag) ecore_main_fd_handler_active_set(svr->fd_handler, flag);
+ return 0;
+}
+#endif
+
+static void
+kill_server(Ecore_Con_Server *svr)
+{
+ Ecore_Con_Event_Server_Del *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Server_Del));
+ if (e)
+ {
+ e->server = svr;
+ ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e, NULL, NULL);
+ }
+
+ svr->dead = 1;
+ ecore_main_fd_handler_del(svr->fd_handler);
+ svr->fd_handler = NULL;
+}
+
+static int
+svr_try_connect_plain(Ecore_Con_Server *svr)
+{
+ int so_err = 0, size = sizeof(int);
+
+ if (getsockopt(svr->fd, SOL_SOCKET, SO_ERROR, &so_err, &size) < 0)
+ so_err = -1;
+
+ if (so_err != 0)
+ {
+ /* we lost our server! */
+ kill_server(svr);
+ }
+ else
+ {
+ /* we got our server! */
+ Ecore_Con_Event_Server_Add *e;
+
+ svr->connecting = 0;
+ e = calloc(1, sizeof(Ecore_Con_Event_Server_Add));
+ if (e)
+ {
+ e->server = svr;
+ ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e, NULL, NULL);
+ }
+ if (!svr->write_buf)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
+ }
+ return (!svr->dead);
+}
+
+/* returns 1 on success, 0 on failure */
+static int svr_try_connect (Ecore_Con_Server *svr)
+{
+#if USE_OPENSSL
+ if (!svr->ssl)
+ {
+#endif
+ return svr_try_connect_plain(svr);
+#if USE_OPENSSL
+ }
+ else
+ switch (svr_try_connect_ssl(svr)) {
+ case 1:
+ return svr_try_connect_plain(svr);
+ case -1:
+ kill_server(svr);
+ return 0;
+ default:
+ return 0;
+ }
+#endif
+}
+
+
+static int
+_ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ Ecore_Con_Server *svr;
+#if USE_OPENSSL
+ int ssl_err = SSL_ERROR_NONE;
+#endif
+
+ svr = data;
+ if (svr->dead) return 1;
+ if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
+ {
+ unsigned char *inbuf = NULL;
+ int inbuf_num = 0;
+
+ if (svr->connecting && !svr_try_connect(svr))
+ return 1;
+
+ for (;;)
+ {
+ int num, lost_server = 0;
+ char buf[READBUFSIZ];
+
+#if USE_OPENSSL
+ if (!svr->ssl)
+ {
+#endif
+ if ((num = read(svr->fd, buf, READBUFSIZ)) < 1)
+ lost_server = (errno == EIO || errno == EBADF ||
+ errno == EPIPE || errno == EINVAL ||
+ errno == ENOSPC || num == 0); /* is num == 0 right? */
+#if USE_OPENSSL
+ }
+ else
+ {
+ num = SSL_read(svr->ssl, buf, READBUFSIZ);
+ if (num < 1)
+ {
+ ssl_err = SSL_get_error(svr->ssl, num);
+ lost_server = (ssl_err == SSL_ERROR_ZERO_RETURN);
+ }
+ else
+ ssl_err = SSL_ERROR_NONE;
+ }
+#endif
+ if (num < 1)
+ {
+ if (inbuf)
+ {
+ Ecore_Con_Event_Server_Data *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Server_Data));
+ if (e)
+ {
+ e->server = svr;
+ e->data = inbuf;
+ e->size = inbuf_num;
+ ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
+ _ecore_con_event_server_data_free, NULL);
+ }
+ }
+ if (lost_server)
+ {
+ /* we lost our server! */
+ kill_server(svr);
+ return 1;
+ }
+ break;
+ }
+ else
+ {
+ inbuf = realloc(inbuf, inbuf_num + num);
+ memcpy(inbuf + inbuf_num, buf, num);
+ inbuf_num += num;
+ }
+ }
+
+#if USE_OPENSSL
+ if (svr->ssl && ssl_err == SSL_ERROR_WANT_READ)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
+ else if (svr->ssl && ssl_err == SSL_ERROR_WANT_WRITE)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
+#endif
+ }
+ else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
+ {
+ if (svr->connecting && !svr_try_connect (svr))
+ return 1;
+
+ _ecore_con_server_flush(svr);
+ }
+
+ return 1;
+}
+
+static int
+_ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ Ecore_Con_Client *cl;
+
+ cl = data;
+ if (cl->dead) return 1;
+ if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
+ {
+ unsigned char *inbuf = NULL;
+ int inbuf_num = 0;
+
+ for (;;)
+ {
+ char buf[65536];
+ int num;
+
+ errno = 0;
+ num = read(cl->fd, buf, 65536);
+ if (num < 1)
+ {
+ if (inbuf)
+ {
+ Ecore_Con_Event_Client_Data *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Client_Data));
+ if (e)
+ {
+ e->client = cl;
+ e->data = inbuf;
+ e->size = inbuf_num;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
+ _ecore_con_event_client_data_free, NULL);
+ }
+ }
+ if ((errno == EIO) || (errno == EBADF) ||
+ (errno == EPIPE) || (errno == EINVAL) ||
+ (errno == ENOSPC) || (num == 0)/* is num == 0 right? */)
+ {
+ /* we lost our client! */
+ Ecore_Con_Event_Client_Del *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
+ if (e)
+ {
+ e->client = cl;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e, NULL, NULL);
+ }
+ cl->dead = 1;
+ ecore_main_fd_handler_del(cl->fd_handler);
+ cl->fd_handler = NULL;
+ }
+ break;
+ }
+ else
+ {
+ inbuf = realloc(inbuf, inbuf_num + num);
+ memcpy(inbuf + inbuf_num, buf, num);
+ inbuf_num += num;
+ }
+ }
+ }
+ else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
+ _ecore_con_client_flush(cl);
+ return 1;
+}
+
+static void
+_ecore_con_server_flush(Ecore_Con_Server *svr)
+{
+ int count, num, lost_server = 0;
+#if USE_OPENSSL
+ int ssl_err = SSL_ERROR_NONE;
+#endif
+
+ if (!svr->write_buf) return;
+
+ /* check whether we need to write anything at all.
+ * we must not write zero bytes with SSL_write() since it
+ * causes undefined behaviour
+ */
+ if (svr->write_buf_size == svr->write_buf_offset)
+ return;
+
+ num = svr->write_buf_size - svr->write_buf_offset;
+#if USE_OPENSSL
+ if (!svr->ssl)
+ {
+#endif
+ count = write(svr->fd, svr->write_buf + svr->write_buf_offset, num);
+ if (count < 1)
+ lost_server = (errno == EIO || errno == EBADF ||
+ errno == EPIPE || errno == EINVAL ||
+ errno == ENOSPC);
+#if USE_OPENSSL
+ }
+ else
+ {
+ count = SSL_write(svr->ssl, svr->write_buf + svr->write_buf_offset, num);
+
+ if (count < 1)
+ {
+ ssl_err = SSL_get_error(svr->ssl, count);
+ lost_server = (ssl_err == SSL_ERROR_ZERO_RETURN);
+ }
+ }
+#endif
+
+ if (lost_server)
+ {
+ /* we lost our server! */
+ kill_server(svr);
+ return;
+ }
+
+ if (count < 1)
+ {
+#if USE_OPENSSL
+ if (svr->ssl && ssl_err == SSL_ERROR_WANT_READ)
+ ecore_main_fd_handler_active_set(svr->fd_handler,
+ ECORE_FD_READ);
+ else if (svr->ssl && ssl_err == SSL_ERROR_WANT_WRITE)
+ ecore_main_fd_handler_active_set(svr->fd_handler,
+ ECORE_FD_WRITE);
+#endif
+ return;
+ }
+
+ svr->write_buf_offset += count;
+ if (svr->write_buf_offset >= svr->write_buf_size)
+ {
+ svr->write_buf_size = 0;
+ svr->write_buf_offset = 0;
+ free(svr->write_buf);
+ svr->write_buf = NULL;
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
+ }
+}
+
+static void
+_ecore_con_client_flush(Ecore_Con_Client *cl)
+{
+ int count, num;
+
+ if (!cl->buf) return;
+ num = cl->buf_size - cl->buf_offset;
+ count = write(cl->fd, cl->buf + cl->buf_offset, num);
+ if (count < 1)
+ {
+ if ((errno == EIO) || (errno == EBADF) || (errno == EPIPE) ||
+ (errno == EINVAL) || (errno == ENOSPC))
+ {
+ /* we lost our client! */
+ Ecore_Con_Event_Client_Del *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
+ if (e)
+ {
+ e->client = cl;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e, NULL, NULL);
+ }
+ cl->dead = 1;
+ ecore_main_fd_handler_del(cl->fd_handler);
+ cl->fd_handler = NULL;
+ }
+ return;
+ }
+ cl->buf_offset += count;
+ if (cl->buf_offset >= cl->buf_size)
+ {
+ cl->buf_size = 0;
+ cl->buf_offset = 0;
+ free(cl->buf);
+ cl->buf = NULL;
+ ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
+ }
+}
+
+static void
+_ecore_con_event_client_data_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Client_Data *e;
+
+ e = ev;
+ if (e->data) free(e->data);
+ free(e);
+}
+
+static void
+_ecore_con_event_server_data_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Server_Data *e;
+
+ e = ev;
+ if (e->data) free(e->data);
+ free(e);
+}
diff --git a/ecore/src/lib/ecore_con/ecore_con_private.h b/ecore/src/lib/ecore_con/ecore_con_private.h
new file mode 100644
index 0000000..d94793e
--- /dev/null
+++ b/ecore/src/lib/ecore_con/ecore_con_private.h
@@ -0,0 +1,86 @@
+#ifndef _ECORE_CON_PRIVATE_H
+#define _ECORE_CON_PRIVATE_H
+
+#define ECORE_MAGIC_CON_SERVER 0x77665544
+#define ECORE_MAGIC_CON_CLIENT 0x77556677
+
+#if USE_OPENSSL
+#include <openssl/ssl.h>
+#endif
+#ifdef HAVE_CURL
+#include <curl/curl.h>
+#endif
+
+#define READBUFSIZ 65536
+
+typedef struct _Ecore_Con_Client Ecore_Con_Client;
+typedef struct _Ecore_Con_Server Ecore_Con_Server;
+#ifdef HAVE_CURL
+typedef struct _Ecore_Con_Url Ecore_Con_Url;
+#else
+typedef void Ecore_Con_Url;
+#endif
+
+typedef enum _Ecore_Con_Type
+{
+ ECORE_CON_LOCAL_USER,
+ ECORE_CON_LOCAL_SYSTEM,
+ ECORE_CON_REMOTE_SYSTEM
+#if USE_OPENSSL
+ ,ECORE_CON_USE_SSL = 16
+#endif
+} Ecore_Con_Type;
+
+struct _Ecore_Con_Client
+{
+ Ecore_List __list_data;
+ ECORE_MAGIC;
+ int fd;
+ Ecore_Con_Server *server;
+ void *data;
+ Ecore_Fd_Handler *fd_handler;
+ int buf_size;
+ int buf_offset;
+ unsigned char *buf;
+ char dead : 1;
+};
+
+struct _Ecore_Con_Server
+{
+ Ecore_List __list_data;
+ ECORE_MAGIC;
+ int fd;
+ Ecore_Con_Type type;
+ char *name;
+ int port;
+ char *path;
+ void *data;
+ Ecore_Fd_Handler *fd_handler;
+ Ecore_List *clients;
+ int write_buf_size;
+ int write_buf_offset;
+ unsigned char *write_buf;
+ char dead : 1;
+ char created : 1;
+ char connecting : 1;
+ char reject_excess_clients : 1;
+ int client_limit;
+
+#if USE_OPENSSL
+ SSL_CTX *ssl_ctx;
+ SSL *ssl;
+#endif
+};
+
+#ifdef HAVE_CURL
+struct _Ecore_Con_Url
+{
+ /* FIXME: ECORE_MAGIC ? */
+ CURL *curl_easy;
+ char *url;
+ struct curl_slist *headers;
+ Ecore_Fd_Handler *fd_handler;
+ char active : 1;
+};
+#endif
+#endif
diff --git a/ecore/src/lib/ecore_con/ecore_con_url.c b/ecore/src/lib/ecore_con/ecore_con_url.c
new file mode 100644
index 0000000..2789233
--- /dev/null
+++ b/ecore/src/lib/ecore_con/ecore_con_url.c
@@ -0,0 +1,408 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * For info on how to use libcurl, see:
+ * http://curl.haxx.se/libcurl/c/libcurl-tutorial.html
+ */
+
+/*
+ * Brief usage:
+ * 1. Create an Ecore_Con_Url object
+ * 2. Register to receive the ECORE_CON_EVENT_URL_COMPLETE event
+ * (and optionally the ECORE_CON_EVENT_URL_DATA event to receive
+ * the response, e.g. for HTTP/FTP downloads)
+ * 3. Set the URL with ecore_con_url_url_set(...);
+ * 4. Perform the operation with ecore_con_url_send(...);
+ *
+ * Note that it is good to reuse Ecore_Con_Url objects wherever possible, but
+ * bear in mind that each one can only perform one operation at a time.
+ * You need to wait for the ECORE_CON_EVENT_URL_COMPLETE event before re-using
+ * or destroying the object.
+ *
+ * Example Usage 1 (HTTP GET):
+ * ecore_con_url_url_set(url_con, "http://www.google.com");
+ * ecore_con_url_send(url, NULL, 0, NULL);
+ *
+ * Example usage 2 (HTTP POST):
+ * ecore_con_url_url_set(url_con, "http://www.example.com/post_handler.cgi");
+ * ecore_con_url_send(url, data, data_length, "multipart/form-data");
+ *
+ * Example Usage 3 (FTP download):
+ * ecore_con_url_url_set(url_con, "ftp://ftp.example.com/pub/myfile");
+ * ecore_con_url_send(url, NULL, 0, NULL);
+ *
+ * FIXME: Support more CURL features: Authentication, FTP upload, Progress callbacks and more...
+ */
+#include "Ecore.h"
+#include "config.h"
+#include "ecore_private.h"
+#include "ecore_con_private.h"
+#include "Ecore_Con.h"
+
+#ifdef HAVE_CURL
+static int _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_con_url_perform(Ecore_Con_Url *url_con);
+size_t _ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp);
+static void _ecore_con_event_url_complete_free(void *data __UNUSED__, void *ev);
+static void _ecore_con_event_url_data_free(void *data __UNUSED__, void *ev);
+static int _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match);
+
+int ECORE_CON_EVENT_URL_DATA = 0;
+int ECORE_CON_EVENT_URL_COMPLETE = 0;
+
+static CURLM *curlm = NULL;
+static Ecore_List *_url_con_list = NULL;
+static fd_set _current_fd_set;
+static int init_count = 0;
+#endif
+
+int
+ecore_con_url_init(void)
+{
+#ifdef HAVE_CURL
+ if (!ECORE_CON_EVENT_URL_DATA)
+ {
+ ECORE_CON_EVENT_URL_DATA = ecore_event_type_new();
+ ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new();
+ }
+
+ if (!_url_con_list)
+ {
+ _url_con_list = ecore_list_new();
+ if (!_url_con_list) return 0;
+ }
+
+ if (!curlm)
+ {
+ FD_ZERO(&_current_fd_set);
+ if (curl_global_init(CURL_GLOBAL_NOTHING))
+ {
+ ecore_list_destroy(_url_con_list);
+ _url_con_list = NULL;
+ return 0;
+ }
+
+ curlm = curl_multi_init();
+ if (!curlm)
+ {
+ ecore_list_destroy(_url_con_list);
+ _url_con_list = NULL;
+ return 0;
+ }
+ }
+ init_count++;
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+int
+ecore_con_url_shutdown(void)
+{
+#ifdef HAVE_CURL
+
+ if (!init_count)
+ return 0;
+
+ init_count--;
+ if (_url_con_list)
+ {
+ if (!ecore_list_is_empty(_url_con_list))
+ {
+ Ecore_Con_Url *url_con;
+ while ((url_con = ecore_list_remove_first(_url_con_list)))
+ {
+ ecore_con_url_destroy(url_con);
+ }
+ }
+ ecore_list_destroy(_url_con_list);
+ _url_con_list = NULL;
+ }
+
+ if (curlm)
+ {
+ curl_multi_cleanup(curlm);
+ curlm = NULL;
+ }
+
+ curl_global_cleanup();
+#endif
+ return 1;
+}
+
+Ecore_Con_Url *
+ecore_con_url_new(const char *url)
+{
+#ifdef HAVE_CURL
+ Ecore_Con_Url *url_con;
+
+ if (!init_count) return NULL;
+
+ url_con = calloc(1, sizeof(Ecore_Con_Url));
+ if (!url_con) return NULL;
+
+ url_con->curl_easy = curl_easy_init();
+ if (!url_con->curl_easy)
+ {
+ free(url_con);
+ return NULL;
+ }
+
+ ecore_con_url_url_set(url_con, url);
+
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_WRITEFUNCTION, _ecore_con_url_data_cb);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_WRITEDATA, url_con);
+ /*
+ * FIXME: Check that these timeouts are sensible defaults
+ * FIXME: Provide a means to change these timeouts
+ */
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_CONNECTTIMEOUT, 30);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEOUT, 300);
+
+ return url_con;
+#else
+ return NULL;
+#endif
+}
+
+void
+ecore_con_url_destroy(Ecore_Con_Url *url_con)
+{
+#ifdef HAVE_CURL
+ if (!url_con) return;
+
+ if (url_con->fd_handler)
+ ecore_main_fd_handler_del(url_con->fd_handler);
+ if (url_con->curl_easy)
+ {
+ if (url_con->active)
+ curl_multi_remove_handle(curlm, url_con->curl_easy);
+ curl_easy_cleanup(url_con->curl_easy);
+ }
+ curl_slist_free_all(url_con->headers);
+ free(url_con->url);
+ free(url_con);
+#endif
+}
+
+int
+ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url)
+{
+#ifdef HAVE_CURL
+ if (url_con->active) return 0;
+
+ free(url_con->url);
+ url_con->url = NULL;
+ if (url)
+ url_con->url = strdup(url);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_URL, url_con->url);
+
+#endif
+ return 1;
+}
+
+int
+ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *content_type)
+{
+#ifdef HAVE_CURL
+ char tmp[256];
+
+ if (url_con->active) return 0;
+ if (!url_con->url) return 0;
+
+ curl_slist_free_all(url_con->headers);
+ url_con->headers = NULL;
+
+ if (data)
+ {
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDS, data);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, length);
+
+ if (content_type && (strlen(content_type) < 200))
+ {
+ sprintf(tmp, "Content-type: %s", content_type);
+ url_con->headers = curl_slist_append(url_con->headers, tmp);
+ }
+ sprintf(tmp, "Content-length: %d", length);
+ url_con->headers = curl_slist_append(url_con->headers, tmp);
+ }
+ else
+ {
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDS, NULL);
+ }
+
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPHEADER, url_con->headers);
+
+ return _ecore_con_url_perform(url_con);
+#else
+ return 0;
+#endif
+}
+
+#ifdef HAVE_CURL
+size_t
+_ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp)
+{
+ Ecore_Con_Url *url_con;
+ Ecore_Con_Event_Url_Data *e;
+ size_t real_size = size * nmemb;
+
+ url_con = (Ecore_Con_Url *)userp;
+ e = calloc(1, sizeof(Ecore_Con_Event_Url_Data));
+ if (e)
+ {
+ e->url_con = url_con;
+ e->data = buffer;
+ e->size = real_size;
+ ecore_event_add(ECORE_CON_EVENT_URL_DATA, e,
+ _ecore_con_event_url_data_free, NULL);
+ }
+ return real_size;
+}
+
+/*
+ * FIXME: Use
+ * CURLOPT_PROGRESSFUNCTION and CURLOPT_PROGRESSDATA to
+ * get reports on progress.
+ * And maybe other nifty functions...
+ */
+static int
+_ecore_con_url_perform(Ecore_Con_Url *url_con)
+{
+ fd_set read_set, write_set, exc_set;
+ int fd_max;
+ int fd;
+ int flags;
+ int still_running;
+ int completed_immediately = 0;
+
+ ecore_list_append(_url_con_list, url_con);
+
+ url_con->active = 1;
+ curl_multi_add_handle(curlm, url_con->curl_easy);
+ while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM);
+
+ completed_immediately = _ecore_con_url_process_completed_jobs(url_con);
+
+ if (!completed_immediately)
+ {
+ /* url_con still active -- set up an fd_handler */
+ FD_ZERO(&read_set);
+ FD_ZERO(&write_set);
+ FD_ZERO(&exc_set);
+
+ /* Stupid curl, why can't I get the fd to the current added job? */
+ curl_multi_fdset(curlm, &read_set, &write_set, &exc_set, &fd_max);
+ for (fd = 0; fd <= fd_max; fd++)
+ {
+ if (!FD_ISSET(fd, &_current_fd_set))
+ {
+ flags = 0;
+ if (FD_ISSET(fd, &read_set)) flags |= ECORE_FD_READ;
+ if (FD_ISSET(fd, &write_set)) flags |= ECORE_FD_WRITE;
+ if (FD_ISSET(fd, &exc_set)) flags |= ECORE_FD_ERROR;
+ if (flags)
+ {
+ FD_SET(fd, &_current_fd_set);
+ url_con->fd_handler = ecore_main_fd_handler_add(fd, flags,
+ _ecore_con_url_fd_handler,
+ NULL, NULL, NULL);
+ }
+ }
+ }
+ if (!url_con->fd_handler)
+ {
+ /* Failed to set up an fd_handler */
+ curl_multi_remove_handle(curlm, url_con->curl_easy);
+ url_con->active = 0;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static int
+_ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ int still_running;
+
+ /* FIXME: Can this run for a long time? Maybe limit how long it can run */
+ while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM);
+
+ _ecore_con_url_process_completed_jobs(NULL);
+ return 1;
+}
+
+static int
+_ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match)
+{
+ Ecore_Con_Url *url_con;
+ CURLMsg *curlmsg;
+ int n_remaining;
+ int job_matched = 0;
+
+ /* Loop jobs and check if any are done */
+ while ((curlmsg = curl_multi_info_read(curlm, &n_remaining)) != NULL)
+ {
+ if (curlmsg->msg != CURLMSG_DONE) continue;
+
+ /* find the job which is done */
+ ecore_list_goto_first(_url_con_list);
+ while ((url_con = ecore_list_current(_url_con_list)))
+ {
+ if (curlmsg->easy_handle == url_con->curl_easy)
+ {
+ /* We have found the completed job in our job list */
+ if (url_con_to_match && (url_con == url_con_to_match)) {
+ job_matched = 1;
+ }
+ if (url_con->fd_handler)
+ {
+ FD_CLR(ecore_main_fd_handler_fd_get(url_con->fd_handler),
+ &_current_fd_set);
+ ecore_main_fd_handler_del(url_con->fd_handler);
+ url_con->fd_handler = NULL;
+ }
+ ecore_list_remove(_url_con_list);
+ curl_multi_remove_handle(curlm, url_con->curl_easy);
+ url_con->active = 0;
+ {
+ Ecore_Con_Event_Url_Complete *e;
+ e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete));
+ if (e)
+ {
+ e->url_con = url_con;
+ e->status = curlmsg->data.result;
+ ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e,
+ _ecore_con_event_url_complete_free, NULL);
+ }
+ }
+ break;
+ }
+ ecore_list_next(_url_con_list);
+ }
+ }
+ return job_matched;
+}
+static void
+_ecore_con_event_url_data_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Url_Data *e;
+
+ e = ev;
+ free(e);
+}
+
+static void
+_ecore_con_event_url_complete_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Url_Complete *e;
+
+ e = ev;
+ free(e);
+}
+#endif
diff --git a/ecore/src/lib/ecore_config/.cvsignore b/ecore/src/lib/ecore_config/.cvsignore
new file mode 100644
index 0000000..59bc827
--- /dev/null
+++ b/ecore/src/lib/ecore_config/.cvsignore
@@ -0,0 +1,8 @@
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+libecore_config.la
+ecore_config_ipc_ecore.la
+system.db
diff --git a/ecore/src/lib/ecore_config/CVS/Entries b/ecore/src/lib/ecore_config/CVS/Entries
new file mode 100644
index 0000000..c0a38b1
--- /dev/null
+++ b/ecore/src/lib/ecore_config/CVS/Entries
@@ -0,0 +1,14 @@
+/.cvsignore/1.7/Sat Oct 23 14:27:10 2004//THEAD
+/Ecore_Config.h/1.42/Wed Mar 2 07:06:34 2005//THEAD
+/Makefile.am/1.28/Tue Jun 7 21:53:58 2005//THEAD
+/ecore_config_db.c/1.6/Sat Jun 25 10:11:25 2005//THEAD
+/ecore_config_extra.c/1.6/Tue Mar 22 20:40:19 2005//THEAD
+/ecore_config_ipc.h/1.2/Wed Mar 2 07:06:34 2005//THEAD
+/ecore_config_ipc_ecore.c/1.8/Sat Jun 25 10:11:25 2005//THEAD
+/ecore_config_ipc_main.c/1.3/Tue Jun 7 21:54:07 2005//THEAD
+/ecore_config_private.h/1.8/Sat Jun 25 10:11:25 2005//THEAD
+/ecore_config_storage.c/1.9/Sat Jun 25 10:11:25 2005//THEAD
+/ecore_config_util.c/1.2/Wed Mar 2 07:06:34 2005//THEAD
+/ecore_config_util.h/1.2/Wed Mar 2 07:06:34 2005//THEAD
+/ecore_config.c/1.60/Sat Jul 23 17:35:06 2005//THEAD
+D
diff --git a/ecore/src/lib/ecore_config/CVS/Entries.Log b/ecore/src/lib/ecore_config/CVS/Entries.Log
new file mode 100644
index 0000000..8e2b110
--- /dev/null
+++ b/ecore/src/lib/ecore_config/CVS/Entries.Log
@@ -0,0 +1,2 @@
+A D/ipc////
+R D/ipc////
diff --git a/ecore/src/lib/ecore_config/CVS/Repository b/ecore/src/lib/ecore_config/CVS/Repository
new file mode 100644
index 0000000..eac9a27
--- /dev/null
+++ b/ecore/src/lib/ecore_config/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/lib/ecore_config
diff --git a/ecore/src/lib/ecore_config/CVS/Root b/ecore/src/lib/ecore_config/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/lib/ecore_config/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/lib/ecore_config/CVS/Tag b/ecore/src/lib/ecore_config/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/lib/ecore_config/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/lib/ecore_config/Ecore_Config.h b/ecore/src/lib/ecore_config/Ecore_Config.h
new file mode 100644
index 0000000..650feeb
--- /dev/null
+++ b/ecore/src/lib/ecore_config/Ecore_Config.h
@@ -0,0 +1,308 @@
+#ifndef _ECORE_CONFIG_H
+# define _ECORE_CONFIG_H
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef WIN32
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef GCC_HASCLASSVISIBILITY
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file
+ * @brief Provides the Enlightened Property Library.
+ *
+ * This file provies all headers and structs for use with Ecore_Config.
+ * Using individual header files should not be necessary.
+ */
+
+# define DIR_DELIMITER '/'
+# define ECORE_CONFIG_FLOAT_PRECISION 1000
+
+# ifndef TRUE
+# define FALSE (0)
+# define TRUE (!FALSE)
+# endif
+
+/* FIXME: this should only be included if evas is present */
+# include <Evas.h>
+
+# define ECORE_CONFIG_GLOBAL_ID "_system"
+
+/* structures */
+
+/**
+ * Valid configuration property types.
+ */
+typedef enum Ecore_Config_Type
+{
+ PT_NIL = 0, /**< Property with no value. */
+ PT_INT = 1, /**< Integer property type. */
+ PT_FLT = 2, /**< Float property type. */
+ PT_STR = 3, /**< String property type. */
+ PT_RGB = 4, /**< Colour property type. */
+ PT_THM = 5, /**< Theme property type. */
+ PT_BLN = 6, /**< Boolean property type. */
+} Ecore_Config_Type;
+
+typedef enum Ecore_Config_Flag
+{
+ PF_NONE = 0,
+ PF_BOUNDS = 1,
+ PF_MODIFIED = 2,
+ PF_SYSTEM = 4,
+ PF_CMDLN = 8
+} Ecore_Config_Flag;
+
+/**
+ * Property change callback function prototype.
+ */
+typedef int (*Ecore_Config_Listener) (const char *key,
+ const Ecore_Config_Type type,
+ const int tag, void *data);
+
+typedef struct Ecore_Config_Listener_List
+{
+ Ecore_Config_Listener listener;
+ const char *name;
+ void *data;
+ int tag;
+ struct Ecore_Config_Listener_List *next;
+} Ecore_Config_Listener_List;
+
+/**
+ * The actual property for storing a key-value pair.
+ */
+typedef struct Ecore_Config_Prop
+{
+ char *key; /* Property key. */
+ char *description; /* Description set by ecore_config_descibe. */
+ char short_opt; /* short identifier on command line (-f) */
+ char *long_opt; /* long identifier on command line (--foo) */
+ char *ptr; /* Used as the value when the property is a string or theme. */
+ Ecore_Config_Type type; /* Property type. */
+ long val; /* Used as the value when the property is an integer, float or colour. */
+ long lo; /* Lower bound for the value when the property is an integer or float. */
+ long hi; /* Higher bound for the value when the property is an integer or float. */
+ long step; /* Increment for the value when the property is an integer or float. */
+ Ecore_Config_Flag flags; /// < Configuration flags.
+ Ecore_Config_Listener_List *listeners; /* List of change listeners. */
+ void *data; /// < Stores extra data for the property.
+ struct Ecore_Config_Prop *next; /* Pointer to the next property in the list. */
+} Ecore_Config_Prop;
+
+/*
+ * A container for a list of properties. Provided so that an
+ * application can use different set of properties at any time. This
+ * is useful for multiple window support.
+ */
+typedef struct Ecore_Config_Bundle
+{
+ char *identifier; /* Identifier for this set of properties (window ID for example) */
+ char *owner; /* This is used to store the application name related to the bundle */
+ long serial; /* Unique identifier to identify bundle */
+ Ecore_Config_Prop *data; /* Pointer to root of property list */
+ void *user_data; /* App specific pointer to "other data" */
+ struct Ecore_Config_Bundle *next; /* Pointer to next bundle in this application */
+} Ecore_Config_Bundle;
+
+typedef struct Ecore_Config_Server
+{
+ void *server;
+ char *name;
+ Ecore_Config_Bundle *bundles; /* data anchor */
+ struct Ecore_Config_Server *next;
+} Ecore_Config_Server;
+
+# ifdef __cplusplus
+extern "C"
+{
+# endif
+
+/* global ptrs to save passing them through the API */
+ extern EAPI Ecore_Config_Server *__ecore_config_server_global;
+ extern EAPI Ecore_Config_Server *__ecore_config_server_local;
+ extern EAPI Ecore_Config_Bundle *__ecore_config_bundle_local;
+ extern EAPI char *__ecore_config_app_name;
+
+ EAPI Ecore_Config_Prop *ecore_config_get(const char *key);
+ EAPI const char *ecore_config_type_get(const Ecore_Config_Prop * e);
+ EAPI int ecore_config_boolean_get(const char *key);
+ EAPI void *ecore_config_data_get(const char *key);
+ EAPI char *ecore_config_string_get(const char *key);
+ EAPI long ecore_config_int_get(const char *key);
+ EAPI int ecore_config_rgb_get(const char *key, int *r, int *g,
+ int *b);
+ EAPI int ecore_config_argb_get(const char *key, int *a, int *r,
+ int *g, int *b);
+ EAPI char *ecore_config_rgbstr_get(const char *key);
+ EAPI char *ecore_config_argbstr_get(const char *key);
+ EAPI float ecore_config_float_get(const char *key);
+ EAPI char *ecore_config_theme_get(const char *key);
+ EAPI char *ecore_config_as_string_get(const char *key);
+ EAPI int ecore_config_bound(Ecore_Config_Prop * e);
+ EAPI int ecore_config_describe(const char *key, char *desc);
+ EAPI int ecore_config_short_opt_set(const char *key,
+ char short_opt);
+ EAPI int ecore_config_long_opt_set(const char *key,
+ char *long_opt);
+ EAPI int ecore_config_set(const char *key, char *val);
+ EAPI int ecore_config_typed_set(const char *key, const void *val,
+ int type);
+ EAPI int ecore_config_boolean_set(const char *key, int val);
+ EAPI int ecore_config_string_set(const char *key, char *val);
+ EAPI int ecore_config_int_set(const char *key, int val);
+ EAPI char *ecore_config_rgb_to_argb(char *rgb);
+ EAPI int ecore_config_rgb_set(const char *key, char *val);
+ EAPI int ecore_config_argb_set(const char *key, char *val);
+ EAPI int ecore_config_float_set(const char *key, float val);
+ EAPI int ecore_config_theme_set(const char *key, char *val);
+ EAPI int ecore_config_theme_preview_group_set(const char *key,
+ char *group);
+ EAPI int ecore_config_as_string_set(const char *key, char *val);
+
+ EAPI int ecore_config_default(const char *key, char *val,
+ float lo, float hi, float step);
+ EAPI int ecore_config_typed_default(const char *key, void *val,
+ int type);
+ EAPI int ecore_config_boolean_default(const char *key, int val);
+ EAPI int ecore_config_int_default(const char *key, int val);
+ EAPI int ecore_config_int_default_bound(const char *key, int val,
+ int lo, int hi, int step);
+ EAPI int ecore_config_string_default(const char *key, const char *val);
+ EAPI int ecore_config_float_default(const char *key, float val);
+ EAPI int ecore_config_float_default_bound(const char *key,
+ float val, float lo,
+ float hi, float step);
+ EAPI int ecore_config_rgb_default(const char *key, char *val);
+ EAPI int ecore_config_argb_default(const char *keym, char *val);
+ EAPI int ecore_config_theme_default(const char *key, char *val);
+
+ EAPI int ecore_config_listen(const char *name, const char *key,
+ Ecore_Config_Listener listener,
+ int tag, void *data);
+ EAPI int ecore_config_deaf(const char *name, const char *key,
+ Ecore_Config_Listener listener);
+ EAPI Ecore_Config_Prop *ecore_config_dst(Ecore_Config_Prop * e);
+ EAPI int ecore_config_type_guess(const char *key, const char *val);
+
+ EAPI Ecore_Config_Bundle *ecore_config_bundle_new(Ecore_Config_Server * srv,
+ const char *id);
+ EAPI Ecore_Config_Bundle *ecore_config_bundle_1st_get(Ecore_Config_Server * srv);
+ EAPI Ecore_Config_Bundle *ecore_config_bundle_next_get(Ecore_Config_Bundle * ns);
+ EAPI Ecore_Config_Bundle *ecore_config_bundle_by_serial_get(Ecore_Config_Server *
+ srv, long serial);
+ EAPI Ecore_Config_Bundle *ecore_config_bundle_by_label_get(Ecore_Config_Server *
+ srv,
+ const char *label);
+ EAPI long ecore_config_bundle_serial_get(Ecore_Config_Bundle * ns);
+ EAPI char *ecore_config_bundle_label_get(Ecore_Config_Bundle * ns);
+
+ EAPI int ecore_config_init(const char *name);
+ EAPI int ecore_config_shutdown(void);
+
+ EAPI int ecore_config_system_init(void);
+ EAPI int ecore_config_system_shutdown(void);
+
+ EAPI int ecore_config_load(void);
+ EAPI int ecore_config_file_load(const char *file);
+ EAPI int ecore_config_save(void);
+ EAPI int ecore_config_file_save(const char *file);
+
+/* error codes */
+# define ECORE_CONFIG_ERR_NOTSUPP (-16)
+# define ECORE_CONFIG_ERR_NOFILE (-15)
+# define ECORE_CONFIG_ERR_META_DLFAIL (-14)
+# define ECORE_CONFIG_ERR_META_FILE (-13)
+# define ECORE_CONFIG_ERR_META_FORMAT (-12)
+# define ECORE_CONFIG_ERR_MONMIS (-11)
+# define ECORE_CONFIG_ERR_NOEXEC (-10)
+# define ECORE_CONFIG_ERR_PARTIAL (-9)
+# define ECORE_CONFIG_ERR_PATHEX (-8)
+# define ECORE_CONFIG_ERR_TYPEMISMATCH (-7)
+# define ECORE_CONFIG_ERR_MUTEX (-6)
+# define ECORE_CONFIG_ERR_NOTFOUND (-5) /* Error indicating that the item searched for could not be found. */
+# define ECORE_CONFIG_ERR_OOM (-4) /* Error given when the program runs out of memory. */
+# define ECORE_CONFIG_ERR_IGNORED (-3) /* Error occurred, but was ignored. */
+# define ECORE_CONFIG_ERR_NODATA (-2) /* Error given when necessary data is not provided. */
+# define ECORE_CONFIG_ERR_FAIL (-1) /* Failure result. */
+# define ECORE_CONFIG_ERR_SUCC (0) /* Success result. */
+
+# define ECORE_CONFIG_PARSE_HELP (-2) /* Help was displayed */
+# define ECORE_CONFIG_PARSE_EXIT (-1) /* An error occurred */
+# define ECORE_CONFIG_PARSE_CONTINUE (0) /* Arguments parsed successfully */
+
+/* convenience mathods in convenience.c */
+ /* FIXME: this should only be included if evas is present */
+ EAPI int ecore_config_evas_font_path_apply(Evas * evas);
+ EAPI char *ecore_config_theme_search_path_get(void);
+ EAPI int ecore_config_theme_search_path_append(char *append);
+
+ EAPI char *ecore_config_theme_default_path_get(void);
+ EAPI char *ecore_config_theme_with_path_from_name_get(char *name);
+ EAPI char *ecore_config_theme_with_path_get(const char *key);
+ EAPI void ecore_config_args_display(void);
+ EAPI int ecore_config_args_parse(void);
+ EAPI void ecore_config_args_callback_str_add(char short_opt,
+ char *long_opt, char *desc,
+ void (*func)(char *val, void *data),
+ void *data);
+ EAPI void ecore_config_args_callback_noarg_add(char short_opt,
+ char *long_opt, char *desc,
+ void (*func)(char *val, void *data),
+ void *data);
+ EAPI void ecore_config_app_describe(char *description);
+
+ EAPI int ecore_config_create(const char *key, void *val,
+ char short_opt, char *long_opt,
+ char *desc);
+ EAPI int ecore_config_typed_create(const char *key, void *val,
+ int type, char short_opt,
+ char *long_opt, char *desc);
+ EAPI int ecore_config_boolean_create(const char *key, int val,
+ char short_opt, char *long_opt,
+ char *desc);
+ EAPI int ecore_config_int_create(const char *key, int val,
+ char short_opt, char *long_opt,
+ char *desc);
+ EAPI int ecore_config_int_create_bound(const char *key, int val,
+ int low, int high,
+ int step, char short_opt,
+ char *long_opt,
+ char *desc);
+ EAPI int ecore_config_string_create(const char *key, char *val,
+ char short_opt,
+ char *long_opt, char *desc);
+ EAPI int ecore_config_float_create(const char *key, float val,
+ char short_opt, char *long_opt,
+ char *desc);
+ EAPI int ecore_config_float_create_bound(const char *key,
+ float val, float low,
+ float high, float step,
+ char short_opt,
+ char *long_opt,
+ char *desc);
+ EAPI int ecore_config_rgb_create(const char *key, char *val,
+ char short_opt, char *long_opt,
+ char *desc);
+ EAPI int ecore_config_argb_create(const char *key, char *val,
+ char short_opt, char *long_opt,
+ char *desc);
+ EAPI int ecore_config_theme_create(const char *key, char *val,
+ char short_opt, char *long_opt,
+ char *desc);
+
+# ifdef __cplusplus
+}
+# endif
+#endif
diff --git a/ecore/src/lib/ecore_config/Makefile.am b/ecore/src/lib/ecore_config/Makefile.am
new file mode 100644
index 0000000..795eef4
--- /dev/null
+++ b/ecore/src/lib/ecore_config/Makefile.am
@@ -0,0 +1,65 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_ipc \
+-I$(top_srcdir)/ \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_ipc \
+-I$(top_builddir)/ \
+@evas_cflags@ @eet_cflags@
+
+CLEANFILES = $(DB)
+
+libecore_config_la_LDFLAGS = -version-info 1:0:0 \
+-L$(top_builddir)/src/lib/ecore/.libs
+
+if BUILD_ECORE_CONFIG
+
+#DB = system.db
+#$(DB): Makefile
+# edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /e/theme/name str "winter"
+# edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /e/font/path str "$(pkgdatadir)/data/fonts"
+# edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /apps/web/browser str `which firefox 2>/dev/null || which phoenix 2>/dev/null || which mozilla 2>/dev/null || which opera 2>/dev/null || which konqueror 2>/dev/null || which epiphany 2>/dev/null`
+# edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /apps/web/email str `which thunderbird 2>/dev/null || which mozilla 2>/dev/null || which kmail 2>/dev/null || which sylpheed 2>/dev/null || which evolution 2>/dev/null`
+
+lib_LTLIBRARIES = libecore_config.la
+include_HEADERS = \
+Ecore_Config.h
+
+#config_DATA = $(DB)
+#configdir = $(pkgdatadir)
+
+libecore_config_la_SOURCES = \
+ecore_config.c \
+ecore_config_ipc_main.c \
+ecore_config_ipc_ecore.c \
+ecore_config_util.c \
+ecore_config_storage.c \
+ecore_config_extra.c \
+ecore_config_db.c \
+ecore_config_private.h
+
+libecore_config_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_ipc/libecore_ipc.la \
+@eet_libs@ \
+@evas_libs@
+
+libecore_config_la_DEPENDENCIES = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_ipc/libecore_ipc.la
+
+
+endif
+
+EXTRA_DIST = \
+Ecore_Config.h \
+ecore_config.c \
+ecore_config_ipc_ecore.c \
+ecore_config_ipc_main.c \
+ecore_config_ipc.h \
+ecore_config_util.c \
+ecore_config_util.h \
+ecore_config_storage.c
+
diff --git a/ecore/src/lib/ecore_config/ecore_config.c b/ecore/src/lib/ecore_config/ecore_config.c
new file mode 100644
index 0000000..df6ea43
--- /dev/null
+++ b/ecore/src/lib/ecore_config/ecore_config.c
@@ -0,0 +1,1623 @@
+#include "Ecore_Config.h"
+#include "config.h"
+#include "ecore_config_private.h"
+#include "ecore_config_ipc.h"
+
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+#include "ecore_config_util.h"
+
+int DEBUG = 0;
+Ecore_Config_Server *__ecore_config_server_global = NULL;
+Ecore_Config_Server *__ecore_config_server_local = NULL;
+Ecore_Config_Bundle *__ecore_config_bundle_local = NULL;
+char *__ecore_config_app_name = NULL;
+int __ecore_config_system_init = 0;
+
+static int _ecore_config_system_init_no_load(void);
+static int _ecore_config_system_load(void);
+
+static const char *_ecore_config_type[] =
+ { "undefined", "integer", "float", "string", "colour", "theme", "boolean" };
+
+/**
+ * @defgroup Ecore_Config_Property_Group Ecore Config Property Functions
+ *
+ * Functions that retrieve or set the attributes relating to a property.
+ */
+
+/**
+ * Removes the given property from the local configuration and destroys it.
+ * @param e Property to destroy.
+ * @return @c NULL
+ * @ingroup Ecore_Config_Property_Group
+ */
+Ecore_Config_Prop *
+ecore_config_dst(Ecore_Config_Prop * e)
+{
+ Ecore_Config_Bundle *t;
+ Ecore_Config_Prop *p, *c;
+ Ecore_Config_Listener_List *l;
+
+ p = NULL;
+ c = e;
+ t = __ecore_config_bundle_local;
+
+ if (!e || !e->key)
+ return NULL;
+ if (t)
+ {
+ if (t->data == e)
+ t->data = e->next;
+ else
+ {
+ do
+ {
+ p = c;
+ c = c->next;
+ }
+ while (c && (c != e));
+ if (c) /* remove from list if even in there */
+ p->next = c->next;
+ }
+ }
+
+ while (e->listeners)
+ {
+ l = e->listeners;
+ e->listeners = e->listeners->next;
+ free(l);
+ }
+
+ if (e->key)
+ free(e->key);
+ if (e->ptr && (e->type == PT_STR))
+ free(e->ptr);
+
+ memset(e, 0, sizeof(Ecore_Config_Prop));
+ free(e);
+
+ return NULL;
+}
+
+/**
+ * @defgroup Ecore_Config_Get_Group Configuration Retrieve Functions
+ *
+ * Functions that retrieve configuration values, based on type.
+ */
+
+/**
+ * Returns the property with the given key.
+ * @param key The unique name of the wanted property.
+ * @return The property that corresponds to the given key. @c NULL if the
+ * key could not be found.
+ * @ingroup Ecore_Config_Get_Group
+ */
+Ecore_Config_Prop *
+ecore_config_get(const char *key)
+{
+ Ecore_Config_Bundle *t;
+ Ecore_Config_Prop *e;
+
+ t = __ecore_config_bundle_local;
+ if (!t || !key)
+ return NULL;
+ e = t->data;
+ while (e)
+ {
+ if (!strcmp(key, e->key))
+ return e;
+ e = e->next;
+ }
+ return NULL;
+}
+
+/**
+ * Returns the type of the property.
+ * @param e Property to get the type of.
+ * @returns The type of the property. If the property is invalid, then the
+ * string "not found" is returned.
+ * @ingroup Ecore_Config_Property_Group
+ */
+const char *
+ecore_config_type_get(const Ecore_Config_Prop * e)
+{
+ if (e)
+ {
+ return _ecore_config_type[e->type];
+ }
+ return "not found";
+}
+
+/**
+ * Obtains the data pointed to by the specified property.
+ * @param key The property key.
+ * @return Data pointer used by the property.
+ * @ingroup Ecore_Config_Get_Group
+ */
+void *
+ecore_config_data_get(const char *key)
+{
+ Ecore_Config_Prop *e;
+
+ e = ecore_config_get(key);
+ return (e ? ((e->type == PT_STR) ? ((void *)&e->ptr) : ((void *)&e->val))
+ : NULL);
+}
+
+/**
+ * Returns the specified property as a string.
+ * @param key The property key.
+ * @return The string value of the property. The function returns @c NULL if
+ * the property is not a string or is not set.
+ * @ingroup Ecore_Config_Get_Group
+ */
+char *
+ecore_config_string_get(const char *key)
+{
+ Ecore_Config_Prop *e;
+
+ e = ecore_config_get(key);
+ return (e && (e->type == PT_STR)) ? strdup(e->ptr) : NULL;
+}
+
+/**
+ * Returns the specified property as an integer.
+ * @param key The property key.
+ * @return The value of the property. The function returns -1 if the
+ * property is not an integer or is not set.
+ * @ingroup Ecore_Config_Get_Group
+ */
+int
+ecore_config_boolean_get(const char *key)
+{
+ Ecore_Config_Prop *e;
+
+ e = ecore_config_get(key);
+ return (e && ((e->type == PT_INT) || (e->type == PT_BLN))) ? (e->val != 0) : -1;
+}
+
+/**
+ * Returns the specified property as a long integer.
+ * @param key The property key.
+ * @return The integer value of the property. The function returns 0 if the
+ * property is not an integer or is not set.
+ * @ingroup Ecore_Config_Get_Group
+ */
+long
+ecore_config_int_get(const char *key)
+{
+ Ecore_Config_Prop *e;
+
+ e = ecore_config_get(key);
+ return (e && ((e->type == PT_INT) || (e->type == PT_RGB))) ? e->val : 0L;
+}
+
+/**
+ * Returns the specified property as a float.
+ * @param key The property key.
+ * @return The float value of the property. The function returns 0.0 if the
+ * property is not a float or is not set.
+ * @ingroup Ecore_Config_Get_Group
+ */
+float
+ecore_config_float_get(const char *key)
+{
+ Ecore_Config_Prop *e;
+
+ e = ecore_config_get(key);
+ return (e
+ && (e->type ==
+ PT_FLT)) ? ((float)e->val / ECORE_CONFIG_FLOAT_PRECISION) : 0.0;
+}
+
+/**
+ * Finds the red, green and blue values of a color property.
+ * @param key The property key.
+ * @param r A pointer to an integer to store the red value into.
+ * @param g A pointer to an integer to store the green value into.
+ * @param b A pointer to an integer to store the blue value into.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_FAIL
+ * otherwise.
+ * @ingroup Ecore_Config_Get_Group
+ * @deprecated
+ */
+int
+ecore_config_rgb_get(const char *key, int *r, int *g, int *b)
+{
+ int alpha;
+ return ecore_config_argb_get(key, &alpha, r, g, b);
+}
+
+/**
+ * Finds the alpha, red, green and blue values of a color property.
+ * @param key The property key.
+ * @param a A pointer to an integer to store the alpha value into.
+ * @param r A pointer to an integer to store the red value into.
+ * @param g A pointer to an integer to store the green value into.
+ * @param b A pointer to an integer to store the blue value into.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_FAIL
+ * otherwise.
+ * @ingroup Ecore_Config_Get_Group
+ */
+int
+ecore_config_argb_get(const char *key, int *a, int *r, int *g, int *b)
+{
+ Ecore_Config_Prop *e;
+
+ e = ecore_config_get(key);
+
+ if (e && ((e->type == PT_RGB)))
+ {
+ *a = (e->val >> 24) & 0xff;
+ *r = (e->val >> 16) & 0xff;
+ *g = (e->val >> 8) & 0xff;
+ *b = e->val & 0xff;
+ return ECORE_CONFIG_ERR_SUCC;
+ }
+ return ECORE_CONFIG_ERR_FAIL;
+}
+
+/**
+ * Returns a color property as a string of hexadecimal characters.
+ * @param key The property key.
+ * @return A string of hexadecimal characters in the format #rrggbb.
+ * @ingroup Ecore_Config_Get_Group
+ * @deprecated
+ */
+char *
+ecore_config_rgbstr_get(const char *key)
+{
+ char *argb, *rgb;
+
+ argb = ecore_config_argbstr_get(key);
+ rgb = argb + 2;
+ *rgb = '#';
+ return rgb;
+}
+
+/**
+ * Returns a color property as a string of hexadecimal characters.
+ * @param key The property key.
+ * @return A string of hexadecimal characters in the format #aarrggbb.
+ * @ingroup Ecore_Config_Get_Group
+ */
+char *
+ecore_config_argbstr_get(const char *key)
+{
+ char *r;
+
+ r = NULL;
+ esprintf(&r, "#%08x", ecore_config_int_get(key));
+ return r;
+}
+
+/**
+ * Returns a theme property.
+ * @param key The property key.
+ * @return The name of the theme the property refers to. The function returns
+ * @c NULL if the property is not a theme or is not set.
+ * @ingroup Ecore_Config_Get_Group
+ */
+char *
+ecore_config_theme_get(const char *key)
+{
+ Ecore_Config_Prop *e;
+
+ e = ecore_config_get(key);
+ return (e && (e->type == PT_THM)) ? strdup(e->ptr) : NULL;
+}
+
+/**
+ * Retrieves the key as a string.
+ * @param key The property key.
+ * @return Returns a character array in the form of 'key:type=value'. @c NULL
+ * is returned if the property does not exist.
+ * @ingroup Ecore_Config_Get_Group
+ */
+char *
+ecore_config_as_string_get(const char *key)
+{
+ Ecore_Config_Prop *e;
+ char *r;
+
+ r = NULL;
+ if (!(e = ecore_config_get(key)))
+ E(0, "no such property, \"%s\"...\n", key);
+ else
+ {
+ const char *type = ecore_config_type_get(e);
+
+ switch (e->type)
+ {
+ case PT_NIL:
+ esprintf(&r, "%s:%s=<nil>", key, type);
+ break;
+ case PT_INT:
+ esprintf(&r, "%s:%s=%ld", key, type, ecore_config_int_get(key));
+ break;
+ case PT_BLN:
+ esprintf(&r, "%s:%s=%ld", key, type, ecore_config_boolean_get(key));
+ break;
+ case PT_FLT:
+ esprintf(&r, "%s:%s=%lf", key, type, ecore_config_float_get(key));
+ break;
+ case PT_STR:
+ esprintf(&r, "%s:%s=\"%s\"", key, type,
+ ecore_config_string_get(key));
+ break;
+ case PT_RGB:
+ esprintf(&r, "%s:%s=#%08x", key, type, ecore_config_int_get(key));
+ break;
+ case PT_THM:
+ esprintf(&r, "%s:%s=\"%s\"", key, type,
+ ecore_config_theme_get(key));
+ break;
+ default:
+ esprintf(&r, "%s:unknown_type", key);
+ break;
+ }
+ }
+ return r;
+}
+
+int
+ecore_config_bound(Ecore_Config_Prop * e)
+{
+ int ret;
+ long v;
+
+ ret = ECORE_CONFIG_ERR_SUCC;
+
+ if (!e)
+ return ECORE_CONFIG_ERR_FAIL;
+ if (e->flags & PF_BOUNDS)
+ {
+ if ((e->val < e->lo))
+ {
+ E(0,
+ "ecore_config_bounds(\"%s\",%ld): value out of range; adjusted to %ld...\n",
+ e->key, e->val, e->lo);
+ e->val = e->lo;
+ }
+ else if ((e->val > e->hi))
+ {
+ E(0,
+ "ecore_config_bounds(\"%s\",%ld): value out of range; adjusted to %ld...\n",
+ e->key, e->val, e->hi);
+ e->val = e->hi;
+ }
+ else
+ ret = ECORE_CONFIG_ERR_IGNORED;
+ }
+ else
+ ret = ECORE_CONFIG_ERR_IGNORED;
+
+ if (e->step)
+ {
+ v = ((int)(e->val / e->step)) * e->step;
+ if (v != e->val)
+ {
+ if (e->type == PT_FLT)
+ E(0,
+ "ecore_config_bound(\"%s\"): float value %f not a multiple of %f, adjusted to %f...\n",
+ e->key, ((double)e->val) / ECORE_CONFIG_FLOAT_PRECISION,
+ ((double)e->step) / ECORE_CONFIG_FLOAT_PRECISION,
+ ((double)v) / ECORE_CONFIG_FLOAT_PRECISION);
+ else
+ E(0,
+ "ecore_config_bound(\"%s\"): integer value %ld not a multiple of %ld, adjusted to %ld...\n",
+ e->key, e->val, e->step, v);
+ ret = ECORE_CONFIG_ERR_SUCC;
+ e->val = v;
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * Tries to guess the type of a property.
+ *
+ * This function first checks to see if the property exists. If it does, then
+ * the type of the stored property is returned. Otherwise, the function tries
+ * to guess the type of the property based on @p val.
+ *
+ * @param key The property key.
+ * @param val The value in string form.
+ * @return The type of the property determined by the function. Note that if
+ * val is @c NULL, @c PT_NIL will be returned.
+ */
+int
+ecore_config_type_guess(const char *key, const char *val)
+{
+ Ecore_Config_Prop *p;
+ char *l;
+ long v;
+
+ l = NULL;
+
+ if ((p = ecore_config_get(key)) && p->type != PT_NIL)
+ return p->type;
+
+ if (!val)
+ return PT_NIL;
+ if (val[0] == '#')
+ return PT_RGB;
+ v = strtol(val, &l, 10);
+ if (*l)
+ {
+ float f;
+
+ if (sscanf(val, "%f%*s", &f) != 1)
+ return PT_STR;
+ return PT_FLT;
+ }
+ return PT_INT;
+}
+
+static int
+ecore_config_typed_val(Ecore_Config_Prop * e, const void *val, int type)
+{
+ char *l;
+ long v;
+ int *i;
+ float *f;
+
+ l = NULL;
+ v = 0;
+
+ if (!(val))
+ e->ptr = NULL;
+ else
+ {
+ if (type == PT_INT)
+ {
+ i = (int *)val;
+ e->val = (long)*i;
+ e->type = PT_INT;
+ }
+ else if (type == PT_BLN )
+ {
+ i = (int *)val;
+ e->val = (long)*i;
+ e->type = PT_BLN;
+ }
+ else if (type == PT_STR || type == PT_THM)
+ {
+ if (!(e->ptr = strdup(val)))
+ return ECORE_CONFIG_ERR_OOM;
+ if (e->type == PT_NIL)
+ e->type = type;
+ }
+ else if (type == PT_RGB)
+ {
+ if (((char *)val)[0] == '#')
+ {
+ if ((v = strtol(&((char *)val)[1], &l, 16)) < 0)
+ {
+ v = 0;
+ E(0,
+ "ecore_config_val: key \"%s\" -- hexadecimal value less than zero, bound to zero...\n",
+ (char *)val);
+ l = (char *)val;
+ }
+ }
+ else
+ {
+ E(0,
+ "ecore_config_val: key \"%s\" -- value \"%s\" not a valid hexadecimal RGB value?\n",
+ e->key, (char *)val);
+ return ECORE_CONFIG_ERR_FAIL;
+ }
+ if (*l)
+ E(0,
+ "ecore_config_val: key \"%s\" -- value \"%s\" not a valid hexadecimal RGB value?\n",
+ e->key, (char *)val);
+ else
+ {
+ e->val = v;
+ e->type = PT_RGB;
+ }
+ }
+ else if (type == PT_FLT)
+ {
+ f = (float *)val;
+ e->val = (long)((*f) * ECORE_CONFIG_FLOAT_PRECISION);
+ e->type = PT_FLT;
+ }
+ else
+ e->type = PT_NIL;
+
+ ecore_config_bound(e);
+ e->flags |= PF_MODIFIED;
+ e->flags = e->flags & ~PF_CMDLN;
+ return ECORE_CONFIG_ERR_SUCC;
+ }
+ return ECORE_CONFIG_ERR_IGNORED;
+}
+
+static int
+ecore_config_typed_add(const char *key, const void *val, int type)
+{
+ int error = ECORE_CONFIG_ERR_SUCC;
+ Ecore_Config_Prop *e;
+ Ecore_Config_Bundle *t;
+
+ t = __ecore_config_bundle_local;
+ if (!key)
+ return ECORE_CONFIG_ERR_NODATA;
+
+ if (!(e = malloc(sizeof(Ecore_Config_Prop))))
+ goto ret;
+ memset(e, 0, sizeof(Ecore_Config_Prop));
+
+ if (!(e->key = strdup(key)))
+ {
+ error = ECORE_CONFIG_ERR_OOM;
+ goto ret_free_nte;
+ }
+
+ if ((error = ecore_config_typed_val(e, val, type) != ECORE_CONFIG_ERR_SUCC))
+ goto ret_free_key;
+
+ e->next = t ? t->data : NULL;
+ if (t)
+ {
+ t->data = e;
+ return ECORE_CONFIG_ERR_SUCC;
+ }
+
+ ret_free_key:
+ free(e->key);
+ ret_free_nte:
+ free(e);
+ ret:
+ if (error == ECORE_CONFIG_ERR_SUCC)
+ error = ECORE_CONFIG_ERR_FAIL;
+ return error;
+}
+
+static int
+ecore_config_add(const char *key, const char *val)
+{
+ int type;
+
+ type = ecore_config_type_guess(key, val);
+ return ecore_config_typed_add(key, val, type);
+}
+
+/**
+ * Sets the description field of the indicated property.
+ * @param key The property key.
+ * @param desc Description string.
+ * @note The description string is copied for the property's use. You can
+ * free @p desc once this function is called.
+ * @ingroup Ecore_Config_Property_Group
+ */
+int
+ecore_config_describe(const char *key, char *desc)
+{
+ Ecore_Config_Prop *e;
+
+ if (!(e = ecore_config_get(key)))
+ return ECORE_CONFIG_ERR_NODATA;
+ e->description = strdup(desc);
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/**
+ * Set the short option character of a property.
+ * @param key The property key.
+ * @param short_opt Character used to indicate the value of a property
+ * given on the command line.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA
+ * is returned if the property does not exist.
+ * @ingroup Ecore_Config_Property_Group
+ */
+int
+ecore_config_short_opt_set(const char *key, char short_opt)
+{
+ Ecore_Config_Prop *e;
+
+ if (!(e = ecore_config_get(key)))
+ return ECORE_CONFIG_ERR_NODATA;
+ e->short_opt = short_opt;
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/**
+ * Set the long option string of the property.
+ * @param key The property key.
+ * @param long_opt String used to indicate the value of a property given
+ * on the command line.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA
+ * is returned if the property does not exist.
+ * @ingroup Ecore_Config_Property_Group
+ */
+int
+ecore_config_long_opt_set(const char *key, char *long_opt)
+{
+ Ecore_Config_Prop *e;
+
+ if (!(e = ecore_config_get(key)))
+ return ECORE_CONFIG_ERR_NODATA;
+ if (e->long_opt)
+ free(e->long_opt);
+ if (long_opt)
+ e->long_opt = strdup(long_opt);
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/**
+ * Sets the indicated property to the given value and type.
+ * @param key The property key.
+ * @param val A pointer to the value to set the property to.
+ * @param type The type of the property.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Property_Group
+ */
+int
+ecore_config_typed_set(const char *key, const void *val, int type)
+{
+ Ecore_Config_Prop *e;
+ Ecore_Config_Listener_List *l;
+ int ret;
+
+ if (!key)
+ return ECORE_CONFIG_ERR_NODATA;
+/* if (!t) { * global prop *
+ e=ecore_config_get(key);
+ if (e)
+ for(l=e->listeners;l;l=l->next)
+ l->listener(e->key,e->type,l->tag,l->data,t);
+ return ECORE_CONFIG_ERR_SUCC;
+ }
+*/
+ if (!(e = ecore_config_get(key)))
+ return ecore_config_typed_add(key, val, type);
+
+ if ((ret = ecore_config_typed_val(e, val, type)) == ECORE_CONFIG_ERR_SUCC)
+ {
+ for (l = e->listeners; l; l = l->next)
+ l->listener(e->key, e->type, l->tag, l->data);
+ }
+ else
+ {
+ E(0,
+ "ecore_config_typed_set(\"%s\"): ecore_config_typed_val() failed: %d\n",
+ key, ret);
+ }
+
+ return ret;
+}
+
+/**
+ * @defgroup Ecore_Config_Set_Group Ecore Config Setters
+ *
+ * Functions that set the value of a property.
+ */
+
+/**
+ * Sets the indicated property to the value indicated by @a val.
+ * @param key The property key.
+ * @param val String representation of value to set.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+int
+ecore_config_set(const char *key, char *val)
+{
+ int type;
+ int tmpi;
+ float tmpf;
+
+ type = ecore_config_type_guess(key, val);
+ if (type == PT_INT || type == PT_BLN)
+ {
+ tmpi = atoi(val);
+ return ecore_config_typed_set(key, (void *)&tmpi, type);
+ }
+ else if (type == PT_FLT)
+ {
+ tmpf = atof(val);
+ return ecore_config_typed_set(key, (void *)&tmpf, type);
+ }
+ else
+ return ecore_config_typed_set(key, (void *)val, type);
+}
+
+/**
+ * Sets the indicated property to the value given in the string.
+ * @param key The property key.
+ * @param val String representation of the value.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+int
+ecore_config_as_string_set(const char *key, char *val)
+{
+ return ecore_config_set(key, val);
+}
+
+/**
+ * Sets the indicated property to the given boolean.
+ * @param key The property key.
+ * @param val Boolean integer to set the property to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+int
+ecore_config_boolean_set(const char *key, int val)
+{
+ val = val ? 1 : 0;
+ return ecore_config_typed_set(key, (void *)&val, PT_BLN);
+}
+
+/**
+ * Sets the indicated property to the given integer.
+ * @param key The property key.
+ * @param val Integer to set the property to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+int
+ecore_config_int_set(const char *key, int val)
+{
+ return ecore_config_typed_set(key, (void *)&val, PT_INT);
+}
+
+/**
+ * Sets the indicated property to the given string.
+ * @param key The property key.
+ * @param val String to set the property to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+int
+ecore_config_string_set(const char *key, char *val)
+{
+ return ecore_config_typed_set(key, (void *)val, PT_STR);
+}
+
+/**
+ * Sets the indicated property to the given float value.
+ * @param key The property key.
+ * @param val Float to set the property to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+int
+ecore_config_float_set(const char *key, float val)
+{
+ return ecore_config_typed_set(key, (void *)&val, PT_FLT);
+}
+
+char *
+ecore_config_rgb_to_argb(char *rgb)
+{
+ char *argb;
+
+ argb = malloc(strlen(rgb) + 2);
+ strncpy(argb, "#ff", 3);
+ strncat(argb, rgb+1, strlen(rgb - 1));
+ return argb;
+}
+
+/**
+ * Sets the indicated property to a color value.
+ * @param key The property key
+ * @param val Color value in RGB format.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ * @deprecated
+ */
+int
+ecore_config_rgb_set(const char *key, char *val)
+{
+ char *argb;
+ int ret;
+
+ argb = ecore_config_rgb_to_argb(val);
+ ret = ecore_config_argb_set(key, argb);
+ free(argb);
+ return ret;
+}
+
+/**
+ * Sets the indicated property to a color value.
+ * @param key The property key
+ * @param val Color value in ARGB format.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+int
+ecore_config_argb_set(const char *key, char *val)
+{
+ return ecore_config_typed_set(key, (void *)val, PT_RGB);
+}
+
+/**
+ * Sets the indicated property to a theme name.
+ * @param key The property key.
+ * @param val String giving the name of the theme.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+int
+ecore_config_theme_set(const char *key, char *val)
+{
+ return ecore_config_typed_set(key, (void *)val, PT_THM);
+}
+
+/**
+ * Sets the theme preview group of an indicated property.
+ * @param key The property key.
+ * @param group The group name.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Set_Group
+ */
+int
+ecore_config_theme_preview_group_set(const char *key, char *group)
+{
+ int ret;
+ Ecore_Config_Prop *e;
+
+ ret = ECORE_CONFIG_ERR_SUCC;
+ if (!(e = ecore_config_get(key)))
+ { /* prop doesn't exist yet */
+ if ((ret = ecore_config_typed_add(key, "", PT_THM)) != ECORE_CONFIG_ERR_SUCC) /* try to add it */
+ return ret; /* ...failed */
+ if (!(e = ecore_config_get(key))) /* get handle */
+ return ECORE_CONFIG_ERR_FAIL;
+ }
+ if (e->data)
+ free(e->data);
+ e->data = strdup(group);
+
+ return ret;
+}
+
+int
+ecore_config_typed_default(const char *key, void *val, int type)
+{
+ int ret;
+ Ecore_Config_Prop *e;
+
+ ret = ECORE_CONFIG_ERR_SUCC;
+
+ if (!(e = ecore_config_get(key)))
+ { /* prop doesn't exist yet */
+ if ((ret = ecore_config_typed_add(key, val, type)) != ECORE_CONFIG_ERR_SUCC) /* try to add it */
+ return ret; /* ...failed */
+ if (!(e = ecore_config_get(key))) /* get handle */
+ return ECORE_CONFIG_ERR_FAIL;
+ e->flags = e->flags & ~PF_MODIFIED;
+ }
+ else if (!(e->flags & PF_MODIFIED) && !(e->flags & PF_SYSTEM))
+ {
+ ecore_config_typed_set(key, val, type);
+ if (!(e = ecore_config_get(key))) /* get handle */
+ return ECORE_CONFIG_ERR_FAIL;
+ e->flags = e->flags & ~PF_MODIFIED;
+ }
+ return ret;
+}
+
+/**
+ * @defgroup Ecore_Config_Default_Group Ecore Config Defaults
+ *
+ * Functions that are used to set the default values of properties.
+ */
+
+/**
+ * Sets the indicated property if it has not already been set or loaded.
+ * @param key The property key.
+ * @param val Default value of the key.
+ * @param lo Lowest valid value for the key.
+ * @param hi Highest valid value for the key.
+ * @param step Used by integer and float values.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there are no errors.
+ * @note The @p lo, @p hi and @p step parameters are only used when storing
+ * integer and float properties.
+ * @ingroup Ecore_Config_Default_Group
+ */
+int
+ecore_config_default(const char *key, char *val, float lo, float hi, float step)
+{
+ int ret, type;
+ Ecore_Config_Prop *e;
+
+ type = ecore_config_type_guess(key, val);
+ ret = ecore_config_typed_default(key, val, type);
+ e = ecore_config_get(key);
+ if (e)
+ {
+ if (type == PT_INT)
+ {
+ e->step = step;
+ e->flags |= PF_BOUNDS;
+ e->lo = lo;
+ e->hi = hi;
+ ecore_config_bound(e);
+ }
+ else if (type == PT_FLT)
+ {
+ e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION);
+ e->flags |= PF_BOUNDS;
+ e->lo = (int)(lo * ECORE_CONFIG_FLOAT_PRECISION);
+ e->hi = (int)(hi * ECORE_CONFIG_FLOAT_PRECISION);
+ ecore_config_bound(e);
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * Sets the indicated property to the given boolean if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val Boolean Integer to set the value to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+int
+ecore_config_boolean_default(const char *key, int val)
+{
+ val = val ? 1 : 0;
+ return ecore_config_typed_default(key, (void *)&val, PT_BLN);
+}
+
+/**
+ * Sets the indicated property to the given integer if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val Integer to set the value to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+int
+ecore_config_int_default(const char *key, int val)
+{
+ return ecore_config_typed_default(key, (void *)&val, PT_INT);
+}
+
+/**
+ * Sets the indicated property to the given integer if the property has not yet
+ * been set.
+ *
+ * The bounds and step values are set regardless.
+ *
+ * @param key The property key.
+ * @param val Integer to set the property to.
+ * @param low Lowest valid integer value for the property.
+ * @param high Highest valid integer value for the property.
+ * @param step Increment value for the property.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+int
+ecore_config_int_default_bound(const char *key, int val, int low, int high,
+ int step)
+{
+ Ecore_Config_Prop *e;
+ int ret;
+
+ ret = ecore_config_typed_default(key, (void *)&val, PT_INT);
+ e = ecore_config_get(key);
+ if (e)
+ {
+ e->step = step;
+ e->flags |= PF_BOUNDS;
+ e->lo = low;
+ e->hi = high;
+ ecore_config_bound(e);
+ }
+
+ return ret;
+}
+
+/**
+ * Sets the indicated property to the given string if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val String to set the property to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+int
+ecore_config_string_default(const char *key, const char *val)
+{
+ return ecore_config_typed_default(key, (void *)val, PT_STR);
+}
+
+/**
+ * Sets the indicated property to the given float if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val Float to set the property to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+int
+ecore_config_float_default(const char *key, float val)
+{
+ return ecore_config_typed_default(key, (void *)&val, PT_FLT);
+}
+
+/**
+ * Sets the indicated property to the given float if the property has not yet
+ * been set.
+ *
+ * The bounds and step values are set regardless.
+ *
+ * @param key The property key.
+ * @param val Float to set the property to.
+ * @param low Lowest valid integer value for the property.
+ * @param high Highest valid float value for the property.
+ * @param step Increment value for the property.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+int
+ecore_config_float_default_bound(const char *key, float val, float low,
+ float high, float step)
+{
+ Ecore_Config_Prop *e;
+ int ret;
+
+ ret = ecore_config_typed_default(key, (void *)&val, PT_FLT);
+ e = ecore_config_get(key);
+ if (e)
+ {
+ e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION);
+ e->flags |= PF_BOUNDS;
+ e->lo = (int)(low * ECORE_CONFIG_FLOAT_PRECISION);
+ e->hi = (int)(high * ECORE_CONFIG_FLOAT_PRECISION);
+ ecore_config_bound(e);
+ }
+
+ return ret;
+}
+
+/**
+ * Sets the indicated property to a color value if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val Color value in RGB format.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems.
+ * @ingroup Ecore_Config_Default_Group
+ * @deprecated
+ */
+int
+ecore_config_rgb_default(const char *key, char *val)
+{
+ char *argb;
+ int ret;
+
+ argb = ecore_config_rgb_to_argb(val);
+ ret = ecore_config_argb_default(key, argb);
+ free(argb);
+ return ret;
+}
+
+/**
+ * Sets the indicated property to a color value if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val Color value in ARGB format.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+int
+ecore_config_argb_default(const char *key, char *val)
+{
+ return ecore_config_typed_default(key, (void *)val, PT_RGB);
+}
+
+/**
+ * Sets the indicated property to a theme name if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val String giving the name of the theme.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Default_Group
+ */
+int
+ecore_config_theme_default(const char *key, char *val)
+{
+ return ecore_config_typed_default(key, (void *)val, PT_THM);
+}
+
+/**
+ * @defgroup Ecore_Config_Listeners_Group Ecore Config Listeners
+ *
+ * Functions that set and unset property listener callbacks.
+ */
+
+/**
+ * Adds a callback function to the list of functions called when a property
+ * changes.
+ * @param name Name of the callback.
+ * @param key The key of the property to listen to.
+ * @param listener Listener callback function.
+ * @param tag Tag to pass to @p listener when it is called.
+ * @param data Data to pass to @p listener when it is called.
+ * @return @c ECORE_CONFIG_ERR_SUCC if successful in setting up the callback.
+ * @ingroup Ecore_Config_Listeners_Group
+ */
+int
+ecore_config_listen(const char *name, const char *key,
+ Ecore_Config_Listener listener, int tag, void *data)
+{
+ Ecore_Config_Prop *e;
+ Ecore_Config_Listener_List *l;
+
+ if (!key)
+ return ECORE_CONFIG_ERR_NODATA;
+
+ if (!(e = ecore_config_get(key)))
+ {
+ int ret = ecore_config_add(key, "");
+
+ if (ret != ECORE_CONFIG_ERR_SUCC)
+ {
+ E(0, "ecore_config_listen: ecore_config_add(\"%s\") failed: %d\n",
+ key, ret);
+ return ret;
+ }
+ if (!(e = ecore_config_get(key)))
+ {
+ E(0, "ecore_config_listen: list of properties corrupted!?\n");
+ return ECORE_CONFIG_ERR_FAIL;
+ }
+ }
+
+ for (l = e->listeners; l; l = l->next)
+ if (!strcmp(l->name, name) || (l->listener == listener))
+ {
+ E(1,
+ "ecore_config_listen: %s is already listening for changes of %s...\n",
+ name, key);
+ return ECORE_CONFIG_ERR_IGNORED;
+ }
+
+ if (!(l = malloc(sizeof(Ecore_Config_Listener_List))))
+ return ECORE_CONFIG_ERR_OOM;
+
+ E(1, "registering listener \"%s\" for \"%s\" (%d)...\n", name, key, e->type);
+
+ memset(l, 0, sizeof(Ecore_Config_Listener_List));
+
+ l->listener = listener;
+ l->name = name;
+ l->data = data;
+ l->tag = tag;
+ l->next = e->listeners;
+ e->listeners = l;
+
+ if (e->type != PT_NIL) /* call right on creation if prop exists and has val */
+ listener(key, e->type, tag, data);
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/**
+ * Removes a listener callback.
+ * @param name Name of the callback to remove.
+ * @param key The property key the callback is listening to.
+ * @param listener The callback function to remove.
+ * @return @c ECORE_CONFIG_ERR_SUCC if successful in removing the callback.
+ * If no callback matches the given parameters, then
+ * @c ECORE_CONFIG_ERR_NOTFOUND is returned. If @c NULL is passed
+ * for the key pointer, @c ECORE_CONFIG_ERR_NODATA is returned.
+ * @ingroup Ecore_Config_Listeners_Group
+ */
+int
+ecore_config_deaf(const char *name, const char *key,
+ Ecore_Config_Listener listener)
+{
+ Ecore_Config_Prop *e;
+ Ecore_Config_Listener_List *l, *p;
+ int ret;
+
+ ret = ECORE_CONFIG_ERR_NOTFOUND;
+
+ if (!key)
+ return ECORE_CONFIG_ERR_NODATA;
+
+ if (!(e = ecore_config_get(key)))
+ return ECORE_CONFIG_ERR_NOTFOUND;
+
+ for (p = NULL, l = e->listeners; l; p = l)
+ {
+ Ecore_Config_Listener_List *nl;
+
+ nl = l->next;
+ if ((name && !strcmp(l->name, name)) || (l->listener == listener))
+ {
+ ret = ECORE_CONFIG_ERR_SUCC;
+ if (!p)
+ e->listeners = e->listeners->next;
+ else
+ p->next = l->next;
+ memset(l, 0, sizeof(Ecore_Config_Listener));
+ free(l);
+ }
+ l = nl;
+ }
+
+ return ret;
+}
+
+/**
+ * Locates the first configuration bundle on the given server.
+ * @param srv The configuration server.
+ * @return Pointer to the first configuration bundle.
+ */
+Ecore_Config_Bundle *
+ecore_config_bundle_1st_get(Ecore_Config_Server * srv)
+{ /* anchor: global, but read-only */
+ return srv->bundles;
+}
+
+/**
+ * Locates the configuration bundle after the given one.
+ * @param ns The configuration bundle.
+ * @return The next configuration bundle.
+ */
+Ecore_Config_Bundle *
+ecore_config_bundle_next_get(Ecore_Config_Bundle * ns)
+{
+ return ns ? ns->next : NULL;
+}
+
+/**
+ * Locates a configuration bundle on a configuration server based on its serial
+ * number.
+ * @param srv The configuration server.
+ * @param serial Serial number.
+ * @return The configuration bundle with the given serial number.
+ */
+Ecore_Config_Bundle *
+ecore_config_bundle_by_serial_get(Ecore_Config_Server * srv, long serial)
+{
+ Ecore_Config_Bundle *eb;
+
+ eb = srv->bundles;
+
+ if (serial < 0)
+ return NULL;
+ else if (serial == 0)
+ {
+ Ecore_Config_Bundle *r = eb;
+
+ return r;
+ }
+
+ while (eb)
+ {
+ if (eb->serial == serial)
+ return eb;
+ eb = eb->next;
+ }
+ return NULL;
+}
+
+/**
+ * Gets the Ecore_Config_Bundle with the given identifier from the given
+ * server.
+ * @param srv The configuration server.
+ * @param label The bundle's identifier string.
+ * @return The bundle with the given identifier string, or @c NULL if it
+ * could not be found.
+ */
+Ecore_Config_Bundle *
+ecore_config_bundle_by_label_get(Ecore_Config_Server * srv, const char *label)
+{
+ Ecore_Config_Bundle *ns;
+
+ ns = srv->bundles;
+
+ while (ns)
+ {
+ if (ns->identifier && !strcmp(ns->identifier, label))
+ return ns;
+ ns = ns->next;
+ }
+ return NULL;
+}
+
+/**
+ * Retrieves the bundle's serial number.
+ * @param ns The configuration bundle.
+ * @return The bundle's identifier string, or -1 if ns is @c NULL.
+ */
+long
+ecore_config_bundle_serial_get(Ecore_Config_Bundle * ns)
+{
+ return ns ? ns->serial : -1;
+}
+
+/**
+ * Retrieves the bundle's identifier.
+ * @param ns The configuration bundle.
+ * @return The bundle's identifer string.
+ */
+char *
+ecore_config_bundle_label_get(Ecore_Config_Bundle * ns)
+{
+ return ns ? ns->identifier : NULL;
+}
+
+/**
+ * Creates a new Ecore_Config_Bundle.
+ * @param srv Config server.
+ * @param identifier Identifier string for the new bundle.
+ * @return A pointer to a new Ecore_Config_Bundle. @c NULL is returned if the
+ * structure couldn't be allocated.
+ */
+Ecore_Config_Bundle *
+ecore_config_bundle_new(Ecore_Config_Server * srv, const char *identifier)
+{
+ Ecore_Config_Bundle *t;
+ static long ss;
+
+ ss = 0; /* bundle unique serial */
+
+ if ((t = malloc(sizeof(Ecore_Config_Bundle))))
+ {
+ memset(t, 0, sizeof(Ecore_Config_Bundle));
+
+ t->identifier = (char *)identifier;
+ t->serial = ++ss;
+ t->owner = srv->name;
+ t->next = srv->bundles;
+ srv->bundles = t;
+ }
+ return t;
+}
+
+static Ecore_Config_Server *
+do_init(const char *name)
+{
+ return _ecore_config_ipc_init(name);
+}
+
+static Ecore_Config_Server *
+ecore_config_init_local(const char *name)
+{
+ char *p;
+ char *buf;
+
+ if ((p = getenv("HOME")))
+ { /* debug-only ### FIXME */
+ if (!(buf = malloc(PATH_MAX * sizeof(char))))
+ return NULL;
+ snprintf(buf, PATH_MAX, "%s/.ecore/%s/.global", p, name);
+ unlink(buf);
+
+ free(buf);
+ }
+
+ return do_init(name);
+}
+
+static Ecore_Config_Server *
+ecore_config_init_global(const char *name)
+{
+ char *p;
+ int global;
+ char *buf;
+ global = 0;
+
+ if ((p = getenv("HOME")))
+ { /* debug-only ### FIXME */
+ if (!(buf = malloc(PATH_MAX * sizeof(char))))
+ return NULL;
+ snprintf(buf, PATH_MAX, "%s/.ecore/%s/.global", p, name);
+ global = creat(buf, S_IRWXU);
+
+ if (global)
+ close(global);
+
+ free(buf);
+ }
+
+ return do_init(name);
+}
+
+/**
+ * @defgroup Ecore_Config_App_Lib_Group Ecore Config App Library Functions
+ *
+ * Functions that are used to start up and shutdown the Enlightened
+ * Property Library when used directly by an application.
+ */
+
+/**
+ * Initializes the Enlightened Property Library.
+ *
+ * Either this function or @ref ecore_config_system_init must be run
+ * before any other function in the Enlightened Property Library, even
+ * if you have run @ref ecore_init . The name given is used to
+ * determine the default configuration to load.
+ *
+ * @param name Application name
+ * @return @c ECORE_CONFIG_ERR_SUCC if the library is successfully set up.
+ * @c ECORE_CONFIG_ERR_FAIL otherwise.
+ * @ingroup Ecore_Config_App_Lib_Group
+ */
+int
+ecore_config_init(const char *name)
+{
+ char *path;
+ Ecore_Config_Prop *list;
+ Ecore_Config_Bundle *temp;
+ _ecore_config_system_init_no_load();
+
+ __ecore_config_app_name = strdup(name);
+ __ecore_config_server_local = ecore_config_init_local(name);
+ if (!__ecore_config_server_local)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ temp = __ecore_config_bundle_local;
+ list = __ecore_config_bundle_local->data;
+ __ecore_config_bundle_local =
+ ecore_config_bundle_new(__ecore_config_server_local, "config");
+ __ecore_config_bundle_local->data = list;
+ free(temp);
+
+ path = ecore_config_theme_default_path_get();
+ ecore_config_string_default("/e/themes/search_path", path);
+ if (path)
+ free(path);
+
+ list = ecore_config_get("/e/themes/search_path");
+ if (list)
+ {
+ list->flags |= PF_SYSTEM;
+ list->flags &= ~PF_MODIFIED;
+ }
+
+ return _ecore_config_system_load();
+}
+
+/**
+ * Frees memory and shuts down the library for an application.
+ * @return @c ECORE_CONFIG_ERR_IGNORED .
+ * @ingroup Ecore_Config_App_Lib_Group
+ */
+int
+ecore_config_shutdown(void)
+{
+ return ecore_config_system_shutdown();
+}
+
+/**
+ * @defgroup Ecore_Config_Lib_Lib_Group Ecore Config Library Functions
+ *
+ * Functions that are used to start up and shutdown the Enlightened
+ * Property Library when used directly by an application.
+ */
+
+/**
+ * Initializes the Enlightened Property Library.
+ *
+ * This function is meant to be run from other programming libraries.
+ * It should not be called from applications.
+ *
+ * This function (or @ref ecore_config_init )
+ * must be run before any other function in the
+ * Enlightened Property Library, even if you have run @ref ecore_init .
+ *
+ * @return @c ECORE_CONFIG_ERR_SUCC if the library is successfully set up.
+ * @c ECORE_CONFIG_ERR_FAIL otherwise.
+ * @ingroup Ecore_Config_Lib_Lib_Group
+ */
+int
+ecore_config_system_init(void)
+{
+ _ecore_config_system_init_no_load();
+ return _ecore_config_system_load();
+}
+
+static int
+_ecore_config_system_init_no_load(void)
+{
+ char *p;
+
+ __ecore_config_system_init++;
+ if (__ecore_config_system_init > 1)
+ return ECORE_CONFIG_ERR_IGNORED;
+
+ DEBUG = -1;
+ if ((p = getenv("ECORE_CONFIG_DEBUG")) && strlen(p) > 0)
+ {
+ DEBUG = atoi(p);
+ }
+
+ __ecore_config_server_global =
+ ecore_config_init_global(ECORE_CONFIG_GLOBAL_ID);
+ if (!__ecore_config_server_global)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ __ecore_config_bundle_local =
+ ecore_config_bundle_new(__ecore_config_server_global, "system");
+
+ /* set up a simple default path */
+ ecore_config_string_default("/e/themes/search_path", PACKAGE_DATA_DIR "../ewl/themes");
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+
+static int
+_ecore_config_system_load(void)
+{
+ char *buf, *p;
+ Ecore_Config_Prop *sys;
+
+ if (__ecore_config_system_init != 1)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ if ((p = getenv("HOME")))
+ { /* debug-only ### FIXME */
+ if ((buf = malloc(PATH_MAX * sizeof(char))))
+ {
+ snprintf(buf, PATH_MAX, "%s/.e/config.eet", p);
+ if (ecore_config_file_load(buf) != 0) {
+ /* even if this file (system.eet) dosen't exist we can
+ * continue without it as it isn't striclty necessary.
+ */
+ ecore_config_file_load(PACKAGE_DATA_DIR "/system.eet");
+ }
+ sys = __ecore_config_bundle_local->data;
+ while (sys)
+ {
+ /* unmark it modified - modification will mean it has been overridden */
+ sys->flags &= ~PF_MODIFIED;
+ /* mark as system so that examine can hide them */
+ sys->flags |= PF_SYSTEM;
+ sys = sys->next;
+ }
+ }
+ free(buf);
+ }
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+
+/**
+ * Frees memory and shuts down the library for other programming libraries.
+ * @return @c ECORE_CONFIG_ERR_IGNORED
+ * @ingroup Ecore_Config_Lib_Lib_Group
+ */
+int
+ecore_config_system_shutdown(void)
+{
+ int ret;
+
+ __ecore_config_system_init--;
+ if (__ecore_config_system_init > 0)
+ return ECORE_CONFIG_ERR_IGNORED;
+
+ ret = _ecore_config_ipc_exit();
+ if (__ecore_config_app_name)
+ free(__ecore_config_app_name);
+ free(__ecore_config_bundle_local);
+ free(__ecore_config_server_local);
+ free(__ecore_config_server_global);
+ return ret;
+}
+
diff --git a/ecore/src/lib/ecore_config/ecore_config_db.c b/ecore/src/lib/ecore_config/ecore_config_db.c
new file mode 100644
index 0000000..59e673b
--- /dev/null
+++ b/ecore/src/lib/ecore_config/ecore_config_db.c
@@ -0,0 +1,286 @@
+#include "Ecore_Config.h"
+#include "ecore_config_private.h"
+#include <Eet.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <locale.h>
+
+struct _Ecore_Config_DB_File
+{
+ Eet_File *ef;
+};
+
+Ecore_Config_DB_File *
+_ecore_config_db_open_read(const char *file)
+{
+ Eet_File *ef;
+ Ecore_Config_DB_File *db;
+
+ eet_init();
+ db = malloc(sizeof(Ecore_Config_DB_File));
+ if (!db) return NULL;
+ ef = eet_open((char*)file, EET_FILE_MODE_READ);
+ if (!ef)
+ {
+ free(db);
+ return NULL;
+ }
+ db->ef = ef;
+ return db;
+}
+
+Ecore_Config_DB_File *
+_ecore_config_db_open_write(const char *file)
+{
+ Eet_File *ef;
+ Ecore_Config_DB_File *db;
+
+ eet_init();
+ db = malloc(sizeof(Ecore_Config_DB_File));
+ if (!db) return NULL;
+ ef = eet_open((char*)file, EET_FILE_MODE_WRITE);
+ if (!ef)
+ {
+ free(db);
+ return NULL;
+ }
+ db->ef = ef;
+ return db;
+}
+
+void
+_ecore_config_db_close(Ecore_Config_DB_File *db)
+{
+ eet_close(db->ef);
+ free(db);
+ eet_shutdown();
+}
+
+char **
+_ecore_config_db_keys_get(Ecore_Config_DB_File *db, int *num_ret)
+{
+ char **keys;
+ int key_count;
+ int i;
+
+ keys = eet_list(db->ef, (char*)"*", &key_count);
+ if (!keys)
+ {
+ *num_ret = 0;
+ return NULL;
+ }
+ /* make keys freeable - this is safe to do */
+ for (i = 0; i < key_count; i++) keys[i] = strdup(keys[i]);
+ *num_ret = key_count;
+ return keys;
+}
+
+Ecore_Config_Type
+_ecore_config_db_key_type_get(Ecore_Config_DB_File *db, const char *key)
+{
+ char *data;
+ int size;
+
+ data = eet_read(db->ef, (char*)key, &size);
+ if (data)
+ {
+ if (size <= 2)
+ {
+ free(data);
+ return PT_NIL;
+ }
+ if (data[size - 1] != 0)
+ {
+ free(data);
+ return PT_NIL;
+ }
+ return (Ecore_Config_Type) data[0];
+ }
+ return PT_NIL;
+}
+
+int
+_ecore_config_db_read(Ecore_Config_DB_File *db, const char *key)
+{
+ char *data, *value;
+ int size;
+ Ecore_Config_Prop *prop;
+ Ecore_Config_Type type;
+
+ data = eet_read(db->ef, (char*)key, &size);
+ if (data)
+ {
+ int l;
+ char *prev_locale;
+
+ if (size <= 2)
+ {
+ free(data);
+ return 0;
+ }
+ if (data[size - 1] != 0)
+ {
+ free(data);
+ return 0;
+ }
+ /* "type" NIL 1242 NIL */
+ l = strlen(data);
+ if (l >= (size - 1))
+ {
+ free(data);
+ return 0;
+ }
+
+ type = data[0];
+ value = data + l + 1;
+ prop = ecore_config_get(key);
+
+ switch (type)
+ {
+ case PT_INT:
+ case PT_BLN:
+ {
+ int tmp;
+ prev_locale = setlocale(LC_NUMERIC, "C");
+ tmp = atoi(value);
+ if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
+
+ ecore_config_typed_set(key, (void *)&tmp, type);
+ break;
+ }
+ case PT_FLT:
+ {
+ float tmp;
+ prev_locale = setlocale(LC_NUMERIC, "C");
+ tmp = atof(value);
+ if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
+
+ ecore_config_typed_set(key, (void *)&tmp, type);
+ break;
+ }
+ case PT_STR:
+ case PT_RGB:
+ case PT_THM:
+ ecore_config_typed_set(key, (void *)value, type);
+ break;
+ default:
+ E(0, "Type %d not handled\n", type);
+ }
+ free(data);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+void *
+_ecore_config_db_key_data_get(Ecore_Config_DB_File *db, const char *key, int *size_ret)
+{
+ char *data;
+ int size;
+
+ data = eet_read(db->ef, (char*)key, &size);
+ if (data)
+ {
+ int l;
+ char *dat;
+
+ if (size <= 2)
+ {
+ free(data);
+ return NULL;
+ }
+ if (data[size - 1] != 0)
+ {
+ free(data);
+ return NULL;
+ }
+ * "type" NIL data_goes_here NIL *
+ l = strlen(data);
+ if (l >= (size - 1))
+ {
+ free(data);
+ return NULL;
+ }
+ dat = malloc(size - (l + 2));
+ memcpy(dat, data + l + 1, size - (l + 2));
+ free(data);
+ *size_ret = size - (l + 2);
+ return dat;
+ }
+ return NULL;
+}*/
+
+void
+_ecore_config_db_write(Ecore_Config_DB_File *db, const char *key)
+{
+ char buf[256];
+ int num;
+ char *prev_locale;
+ // Ecore_Config_Prop *prop;
+ Ecore_Config_Type type;
+
+
+ type = ecore_config_get(key)->type;
+ prev_locale = setlocale(LC_NUMERIC, "C");
+
+ switch (type)
+ {
+ case PT_INT:
+ num = snprintf(buf, sizeof(buf), "%c %i ", (char) type,
+ (int) ecore_config_int_get(key));
+ break;
+ case PT_BLN:
+ num = snprintf(buf, sizeof(buf), "%c %i ", (char) type,
+ (int) ecore_config_int_get(key));
+ break;
+ case PT_FLT:
+ num = snprintf(buf, sizeof(buf), "%c %16.16f ", (char) type,
+ ecore_config_float_get(key));
+ break;
+ case PT_STR:
+ num = snprintf(buf, sizeof(buf), "%c %s ", (char) type,
+ ecore_config_string_get(key));
+ break;
+ case PT_THM:
+ num = snprintf(buf, sizeof(buf), "%c %s ", (char) type,
+ ecore_config_theme_get(key));
+ break;
+ case PT_RGB:
+ num = snprintf(buf, sizeof(buf), "%c %s ", (char) type,
+ ecore_config_argbstr_get(key));
+ break;
+ default:
+ E(0, "Type %d not handled\n", type);
+ }
+
+ if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
+ buf[1] = 0;
+ buf[num - 1] = 0;
+ eet_write(db->ef, (char*)key, buf, num, 1);
+}
+/*
+void
+_ecore_config_db_key_data_set(Ecore_Config_DB_File *db, const char *key, void *data, int data_size)
+{
+ char *buf;
+ int num;
+
+ num = 1 + 1 + data_size + 1;
+ buf = malloc(num);
+ if (!buf) return;
+ buf[0] = (char) PT_BIN;
+ buf[1] = 0;
+ memcpy(buf + 2, data, data_size);
+ buf[num - 1] = 0;
+ eet_write(db->ef, (char*)key, buf, num, 1);
+ free(buf);
+}*/
diff --git a/ecore/src/lib/ecore_config/ecore_config_extra.c b/ecore/src/lib/ecore_config/ecore_config_extra.c
new file mode 100644
index 0000000..bdc8b8c
--- /dev/null
+++ b/ecore/src/lib/ecore_config/ecore_config_extra.c
@@ -0,0 +1,828 @@
+#include "Ecore_Config.h"
+#include "Ecore.h"
+
+#include "config.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+typedef struct __Ecore_Config_Arg_Callback _Ecore_Config_Arg_Callback;
+struct __Ecore_Config_Arg_Callback
+{
+ char short_opt;
+ char *long_opt;
+ char *description;
+ void *data;
+ void (*func)(char *val, void *data);
+ Ecore_Config_Type type;
+ _Ecore_Config_Arg_Callback *next;
+};
+
+char *__ecore_config_app_description;
+_Ecore_Config_Arg_Callback *_ecore_config_arg_callbacks;
+
+/* shorthand prop setup code to make client apps a little smaller ;) */
+
+/**
+ * Creates a new property, if it does not already exist, and sets its
+ * attributes to those given.
+ *
+ * The type of the property is guessed from the key and the value
+ * given.
+ *
+ * @param key The property key.
+ * @param val Pointer to default value of key.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_create(const char *key, void *val, char short_opt, char *long_opt,
+ char *desc)
+{
+ int type = ecore_config_type_guess(key, val);
+
+ return ecore_config_typed_create(key, val, type, short_opt, long_opt, desc);
+}
+
+/**
+ * Creates a new property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Pointer to default value of key.
+ * @param type Type of the property.
+ * @param short_opt Short option used to set the property from
+ * command line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_typed_create(const char *key, void *val, int type, char short_opt,
+ char *long_opt, char *desc)
+{
+ int ret;
+
+ if ((ret =
+ ecore_config_typed_default(key, val, type)) != ECORE_CONFIG_ERR_SUCC)
+ return ret;
+ if ((ret =
+ ecore_config_short_opt_set(key, short_opt)) != ECORE_CONFIG_ERR_SUCC)
+ return ret;
+ if ((ret =
+ ecore_config_long_opt_set(key, long_opt)) != ECORE_CONFIG_ERR_SUCC)
+ return ret;
+ ret = ecore_config_describe(key, desc);
+ return ret;
+}
+
+/**
+ * Creates a new boolean property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default boolean value of key.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_boolean_create(const char *key, int val, char short_opt,
+ char *long_opt, char *desc)
+{
+ return
+ ecore_config_typed_create(key, (void *)&val, PT_BLN, short_opt, long_opt,
+ desc);
+}
+
+/**
+ * Creates a new integer property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default integer value of key.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_int_create(const char *key, int val, char short_opt,
+ char *long_opt, char *desc)
+{
+ return
+ ecore_config_typed_create(key, (void *)&val, PT_INT, short_opt, long_opt,
+ desc);
+}
+
+/**
+ * Creates a new integer property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default integer value of key.
+ * @param low Lowest valid integer value for the property.
+ * @param high Highest valid integer value for the property.
+ * @param step Increment value for the property.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_int_create_bound(const char *key, int val, int low, int high,
+ int step, char short_opt, char *long_opt,
+ char *desc)
+{
+ Ecore_Config_Prop *e;
+ int ret;
+
+ ret =
+ ecore_config_typed_create(key, (void *)&val, PT_INT, short_opt, long_opt,
+ desc);
+ if (ret != ECORE_CONFIG_ERR_SUCC)
+ return ret;
+ e = ecore_config_get(key);
+ if (e)
+ {
+ e->step = step;
+ e->flags |= PF_BOUNDS;
+ e->lo = low;
+ e->hi = high;
+ ecore_config_bound(e);
+ }
+ return ret;
+}
+
+/**
+ * Creates a new string property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default value of key.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_string_create(const char *key, char *val, char short_opt,
+ char *long_opt, char *desc)
+{
+ return
+ ecore_config_typed_create(key, (void *)val, PT_STR, short_opt, long_opt,
+ desc);
+}
+
+/**
+ * Creates a new float property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default float value of key.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_float_create(const char *key, float val, char short_opt,
+ char *long_opt, char *desc)
+{
+ return
+ ecore_config_typed_create(key, (void *)&val, PT_FLT, short_opt, long_opt,
+ desc);
+}
+
+/**
+ * Creates a new float property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default float value of key.
+ * @param low Lowest valid float value for the property.
+ * @param high Highest valid float value for the property.
+ * @param step Increment value for the property.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_float_create_bound(const char *key, float val, float low,
+ float high, float step, char short_opt,
+ char *long_opt, char *desc)
+{
+ Ecore_Config_Prop *e;
+ int ret;
+
+ ret =
+ ecore_config_typed_create(key, (void *)&val, PT_FLT, short_opt, long_opt,
+ desc);
+ e = ecore_config_get(key);
+ if (e)
+ {
+ e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION);
+ e->flags |= PF_BOUNDS;
+ e->lo = (int)(low * ECORE_CONFIG_FLOAT_PRECISION);
+ e->hi = (int)(high * ECORE_CONFIG_FLOAT_PRECISION);
+ ecore_config_bound(e);
+ }
+ return ret;
+}
+
+/**
+ * Creates a new color property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default color value of key, as a hexadecimal string.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ * @deprecated
+ */
+int
+ecore_config_rgb_create(const char *key, char *val, char short_opt,
+ char *long_opt, char *desc)
+{
+ char *argb;
+ int ret;
+
+ argb = ecore_config_rgb_to_argb(val);
+ ret = ecore_config_argb_create(key, argb, short_opt, long_opt, desc);
+ free(argb);
+ return ret;
+}
+
+/**
+ * Creates a new color property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default color value of key, as a hexadecimal string.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_argb_create(const char *key, char *val, char short_opt,
+ char *long_opt, char *desc)
+{
+ return
+ ecore_config_typed_create(key, (void *)val, PT_RGB, short_opt, long_opt,
+ desc);
+}
+
+/**
+ * Creates a new theme property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default theme name for the property.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_theme_create(const char *key, char *val, char short_opt,
+ char *long_opt, char *desc)
+{
+ return
+ ecore_config_typed_create(key, (void *)val, PT_THM, short_opt, long_opt,
+ desc);
+}
+
+/* this should only be built if evas is present */
+
+/**
+ * Calls evas_font_path_append on @p evas for each of the font names stored
+ * in the property "/e/font/path".
+ * @param evas Evas object to append the font names to.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA
+ * is returned if the property has not been set.
+ */
+int
+ecore_config_evas_font_path_apply(Evas * evas)
+{
+ char *font_path, *font_path_tmp, *ptr, *end;
+
+ font_path = ecore_config_string_get("/e/font/path");
+
+ if (!font_path)
+ return ECORE_CONFIG_ERR_NODATA;
+ ptr = font_path;
+ end = font_path + strlen(font_path);
+ font_path_tmp = font_path;
+ while (ptr && ptr < end)
+ {
+ while (*ptr != '|' && ptr < end)
+ ptr++;
+ if (ptr < end)
+ *ptr = '\0';
+
+ evas_font_path_append(evas, font_path_tmp);
+ ptr++;
+ font_path_tmp = ptr;
+ }
+
+ free(font_path);
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/**
+ * Retrieves the default theme search path.
+ *
+ * @return The default theme search path.
+ */
+char *
+ecore_config_theme_default_path_get(void)
+{
+ char *path, *home;
+ int len;
+
+ home = getenv("HOME");
+ len = strlen(PACKAGE_DATA_DIR "/../") + strlen(__ecore_config_app_name) +
+ strlen("/themes/") + 1;
+ if (home)
+ len += strlen(home) + strlen("/.e/apps/") +
+ strlen(__ecore_config_app_name) +
+ strlen("/themes/|"); /* no \0, as that is above */
+
+ if (!(path = malloc(len)))
+ return NULL;
+
+ *path = '\0';
+ if (home)
+ {
+ strcat(path, home);
+ strcat(path, "/.e/apps/");
+ strcat(path, __ecore_config_app_name);
+ strcat(path, "/themes/|");
+ }
+ strcat(path, PACKAGE_DATA_DIR "/../");
+ strcat(path, __ecore_config_app_name);
+ strcat(path, "/themes/");
+
+ return path;
+}
+
+/**
+ * Retrieves the search path used to find themes.
+ *
+ * The search path is stored in the property "/e/themes/search_path". If
+ * the property has not been set, the default path used is
+ * "/usr/local/share/<app_name>/themes|~/.e/apps/<app_name>/themes".
+ * See @ref ecore_config_theme_default_path_get for more information about
+ * the default path.
+ *
+ * @return The search path. @c NULL is returned if there is no memory left.
+ */
+char *
+ecore_config_theme_search_path_get(void)
+{
+ char *search_path;
+ search_path = ecore_config_string_get("/e/themes/search_path");
+
+ /* this should no longer be the case, as it is defaulted in init */
+ if (!search_path)
+ {
+ search_path = ecore_config_theme_default_path_get();
+ if (search_path)
+ {
+ ecore_config_string_default("/e/themes/search_path", search_path);
+ free(search_path);
+ }
+ }
+ return search_path;
+}
+
+/**
+ * Adds the given path to the search path used to find themes.
+ *
+ * If the search path is successfully, the new search path will be saved
+ * into the property "/e/themes/search_path". Therefore, this function
+ * should be called @b after @ref ecore_config_load to allow a user to
+ * override the default search path.
+ *
+ * @param path The given
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_FAIL
+ * will be returned if @p path already exists in the search path.
+ * @c ECORE_CONFIG_ERR_FAIL is returned if @p path is @c NULL.
+ */
+int
+ecore_config_theme_search_path_append(char *path)
+{
+ char *search_path, *loc, *new_search_path;
+ int len, search_len;
+ Ecore_Config_Prop *prop;
+
+ if (!path)
+ return ECORE_CONFIG_ERR_NODATA;
+ search_path = ecore_config_theme_search_path_get();
+
+ loc = strstr(search_path, path);
+ len = strlen(path);
+ search_len = strlen(search_path);
+
+ if (loc == NULL || (loc != search_path && *(loc - 1) != '|') ||
+ (loc != (search_path + search_len - len) && *(loc + len - 1) != '|'))
+ {
+ new_search_path = malloc(search_len + len + 2); /* 2 = \0 + | */
+ strcpy(new_search_path, search_path);
+ strncat(new_search_path, "|", 1);
+ strncat(new_search_path, path, len);
+
+ ecore_config_string_set("/e/themes/search_path", new_search_path);
+ prop = ecore_config_get("/e/themes/search_path");
+ if (prop)
+ prop->flags &= ~PF_MODIFIED;
+
+ free(new_search_path);
+
+ return ECORE_CONFIG_ERR_SUCC;
+ }
+ return ECORE_CONFIG_ERR_FAIL;
+}
+
+/**
+ * Retrieve a theme file's full path.
+ *
+ * The search path for theme files is given by @ref
+ * ecore_config_theme_search_path_get .
+ *
+ * @param name The name of the theme.
+ * @return A full path to the theme on success. @c NULL will be returned
+ * if @p name is @c NULL or no theme matching the given name could
+ * be found.
+ */
+char *
+ecore_config_theme_with_path_from_name_get(char *name)
+{
+ char *search_path, *search_path_tmp, *ptr, *end, *file;
+ struct stat st;
+
+ if (!name)
+ return NULL; /* no theme specified (nor a default) */
+
+ search_path = ecore_config_theme_search_path_get();
+ ptr = search_path;
+ end = search_path + strlen(search_path);
+ search_path_tmp = search_path;
+ while (ptr && ptr < end)
+ {
+ while (*ptr != '|' && ptr < end)
+ ptr++;
+ if (ptr < end)
+ *ptr = '\0';
+
+ file = malloc(strlen(search_path_tmp) + strlen(name) + 6);
+ /* 6 = / + .edj + \0 */
+
+ snprintf(file, strlen(search_path_tmp) + strlen(name) + 6,
+ "%s/%s.edj", search_path_tmp, name);
+
+ if (stat(file, &st) == 0)
+ {
+ free(search_path);
+ return file;
+ }
+ free(file);
+ ptr++;
+ search_path_tmp = ptr;
+ }
+
+ free(search_path);
+
+ return NULL; /* we could not find the theme with that name in search path */
+}
+
+/**
+ * Retrieves the full path to the theme file of the theme stored in the
+ * given property.
+ *
+ * The search path for themes is given by @ref
+ * ecore_config_theme_search_path_get .
+ *
+ * @param key The given property.
+ * @return A full path to the theme on success, or @c NULL on failure.
+ * This function will fail if no key is specified or not theme
+ * matching that given by the property @p key could be found.
+ */
+char *
+ecore_config_theme_with_path_get(const char *key)
+{
+ return
+ ecore_config_theme_with_path_from_name_get(ecore_config_theme_get(key));
+}
+
+static const char *_ecore_config_short_types[] =
+ { " ", "<int> ", "<flt> ", "<str> ", "<rgb> ", "<str> ", "<bool>" };
+
+/**
+ * Prints the property list of the local configuration bundle to output.
+ */
+void
+ecore_config_args_display(void)
+{
+ Ecore_Config_Prop *props;
+ _Ecore_Config_Arg_Callback *callbacks;
+
+ if (__ecore_config_app_description)
+ printf("%s\n\n", __ecore_config_app_description);
+ printf("Supported Options:\n");
+ printf(" -h, --help\t Print this text\n");
+ if (!__ecore_config_bundle_local)
+ return;
+ props = __ecore_config_bundle_local->data;
+ while (props)
+ {
+ /* if it is a system prop, or cannot be set on command line hide it */
+ if (props->flags & PF_SYSTEM || (!props->short_opt && !props->long_opt))
+ {
+ props = props->next;
+ continue;
+ }
+ printf(" %c%c%c --%s\t%s %s\n", props->short_opt ? '-' : ' ',
+ props->short_opt ? props->short_opt : ' ',
+ props->short_opt ? ',' : ' ',
+ props->long_opt ? props->long_opt : props->key,
+ _ecore_config_short_types[props->type],
+ props->description ? props->description :
+ "(no description available)");
+
+ props = props->next;
+ }
+ callbacks = _ecore_config_arg_callbacks;
+ while (callbacks)
+ {
+ printf(" %c%c%c --%s\t%s %s\n", callbacks->short_opt ? '-' : ' ',
+ callbacks->short_opt ? callbacks->short_opt : ' ',
+ callbacks->short_opt ? ',' : ' ',
+ callbacks->long_opt ? callbacks->long_opt : "",
+ _ecore_config_short_types[callbacks->type],
+ callbacks->description ? callbacks->description :
+ "(no description available)");
+
+ callbacks = callbacks->next;
+ }
+}
+
+static int
+ecore_config_parse_set(Ecore_Config_Prop * prop, char *arg, char *opt,
+ char opt2)
+{
+ if (!arg)
+ {
+ if (opt)
+ printf("Missing expected argument for option --%s\n", opt);
+ else
+ printf("Missing expected argument for option -%c\n", opt2);
+ return ECORE_CONFIG_PARSE_EXIT;
+ }
+ else
+ {
+ ecore_config_set(prop->key, arg);
+ prop->flags |= PF_CMDLN;
+ }
+ return ECORE_CONFIG_PARSE_CONTINUE;
+}
+
+static void
+ecore_config_args_callback_add(char short_opt, char *long_opt, char *desc,
+ void (*func)(char *val, void *data),
+ void *data, Ecore_Config_Type type) {
+ _Ecore_Config_Arg_Callback *new_cb;
+
+ new_cb = malloc(sizeof(_Ecore_Config_Arg_Callback));
+ new_cb->short_opt = short_opt;
+ if (long_opt)
+ new_cb->long_opt = strdup(long_opt);
+ if (desc)
+ new_cb->description = strdup(desc);
+ new_cb->data = data;
+ new_cb->func = func;
+ new_cb->type = type;
+
+ new_cb->next = _ecore_config_arg_callbacks;
+ _ecore_config_arg_callbacks = new_cb;
+}
+
+void
+ecore_config_args_callback_str_add(char short_opt, char *long_opt, char *desc,
+ void (*func)(char *val, void *data),
+ void *data) {
+ ecore_config_args_callback_add(short_opt, long_opt, desc, func, data, PT_STR);
+}
+
+void
+ecore_config_args_callback_noarg_add(char short_opt, char *long_opt, char *desc,
+ void (*func)(char *val, void *data),
+ void *data) {
+ ecore_config_args_callback_add(short_opt, long_opt, desc, func, data, PT_NIL);
+}
+
+/**
+ * Parse the arguments set by @ref ecore_app_args_set and set properties
+ * accordingly.
+ *
+ * @return @c ECORE_CONFIG_PARSE_CONTINUE if successful.
+ * @c ECORE_CONFIG_PARSE_EXIT is returned if an unrecognised option
+ * is found. @c ECORE_CONFIG_PARSE_HELP is returned if help was
+ * displayed.
+ */
+int
+ecore_config_args_parse(void)
+{
+ int argc;
+ char **argv;
+ int nextarg, next_short_opt, found, ret;
+ char *arg;
+ char *long_opt, short_opt;
+ Ecore_Config_Prop *prop;
+ _Ecore_Config_Arg_Callback *callback;
+
+ ecore_app_args_get(&argc, &argv);
+ nextarg = 1;
+ while (nextarg < argc)
+ {
+ arg = argv[nextarg];
+
+ if (*arg != '-')
+ {
+ printf("Unexpected attribute \"%s\"\n", arg);
+ nextarg++;
+ continue;
+ }
+
+ next_short_opt = 1;
+ short_opt = *(arg + next_short_opt);
+
+ if (short_opt == '-')
+ {
+ long_opt = arg + 2;
+
+ if (!strcmp(long_opt, "help"))
+ {
+ ecore_config_args_display();
+ return ECORE_CONFIG_PARSE_HELP;
+ }
+
+ found = 0;
+ prop = __ecore_config_bundle_local->data;
+ while (prop)
+ {
+ if ((prop->long_opt && !strcmp(long_opt, prop->long_opt))
+ || !strcmp(long_opt, prop->key))
+ {
+ found = 1;
+ if ((ret =
+ ecore_config_parse_set(prop, argv[++nextarg],
+ long_opt,
+ '\0')) !=
+ ECORE_CONFIG_PARSE_CONTINUE)
+ return ret;
+ break;
+ }
+ prop = prop->next;
+ }
+ if (!found)
+ {
+ callback = _ecore_config_arg_callbacks;
+ while (callback)
+ {
+ if ((callback->long_opt &&
+ !strcmp(long_opt, callback->long_opt)))
+ {
+ found = 1;
+ if (callback->type == PT_NIL)
+ {
+ callback->func(NULL, callback->data);
+ }
+ else
+ {
+ if (!argv[++nextarg])
+ {
+ printf("Missing expected argument for option --%s\n", long_opt);
+ return ECORE_CONFIG_PARSE_EXIT;
+ }
+ callback->func(argv[nextarg], callback->data);
+ }
+ break;
+ }
+ callback = callback->next;
+ }
+ }
+ if (!found)
+ {
+ printf("Unrecognised option \"%s\"\n", long_opt);
+ printf("Try using -h or --help for more information.\n\n");
+ return ECORE_CONFIG_PARSE_EXIT;
+ }
+ }
+ else
+ {
+ while (short_opt)
+ {
+ if (short_opt == 'h')
+ {
+ ecore_config_args_display();
+ return ECORE_CONFIG_PARSE_HELP;
+ }
+ else
+ {
+ found = 0;
+ prop = __ecore_config_bundle_local->data;
+ while (prop)
+ {
+ if (short_opt == prop->short_opt)
+ {
+ found = 1;
+ if ((ret =
+ ecore_config_parse_set(prop,
+ argv[++nextarg],
+ NULL,
+ short_opt)) !=
+ ECORE_CONFIG_PARSE_CONTINUE)
+ return ret;
+ break;
+ }
+ prop = prop->next;
+ }
+
+ if (!found)
+ {
+ callback = _ecore_config_arg_callbacks;
+ while (callback)
+ {
+ if (short_opt == callback->short_opt)
+ {
+ found = 1;
+ if (callback->type == PT_NIL)
+ {
+ callback->func(NULL, callback->data);
+ }
+ else
+ {
+ if (!argv[++nextarg])
+ {
+ printf("Missing expected argument for option -%c\n", short_opt);
+ return ECORE_CONFIG_PARSE_EXIT;
+ }
+ callback->func(argv[nextarg], callback->data);
+ }
+ break;
+ }
+ callback = callback->next;
+ }
+ }
+ if (!found)
+ {
+ printf("Unrecognised option '%c'\n", short_opt);
+ printf
+ ("Try using -h or --help for more information.\n\n");
+ return ECORE_CONFIG_PARSE_EXIT;
+ }
+ }
+ short_opt = *(arg + ++next_short_opt);
+ }
+ }
+ nextarg++;
+ }
+
+ return ECORE_CONFIG_PARSE_CONTINUE;
+}
+
+/**
+ * Sets the description string used by @ref ecore_config_args_display .
+ * @param description Description of application.
+ */
+void
+ecore_config_app_describe(char *description)
+{
+ if (__ecore_config_app_description)
+ free(__ecore_config_app_description);
+ __ecore_config_app_description = strdup(description);
+}
diff --git a/ecore/src/lib/ecore_config/ecore_config_ipc.h b/ecore/src/lib/ecore_config/ecore_config_ipc.h
new file mode 100644
index 0000000..7b3dea1
--- /dev/null
+++ b/ecore/src/lib/ecore_config/ecore_config_ipc.h
@@ -0,0 +1,50 @@
+#include <Ecore_Ipc.h>
+#include "Ecore_Config.h"
+
+typedef enum
+{
+ IPC_NONE,
+ IPC_PROP_LIST,
+ IPC_PROP_DESC,
+ IPC_PROP_GET,
+ IPC_PROP_SET, /* end of the codes shared by evidence and econf */
+
+ IPC_GLOBAL_PROP_LIST,
+
+ IPC_BUNDLE_LIST,
+ IPC_BUNDLE_NEW,
+ IPC_BUNDLE_LABEL_GET,
+ IPC_BUNDLE_LABEL_SET,
+ IPC_BUNDLE_LABEL_FIND,
+
+ IPC_LAST
+} Ecore_Config_Ipc_Call;
+
+Ecore_Config_Server *_ecore_config_ipc_init(const char *pipe_name);
+int _ecore_config_ipc_exit(void);
+
+Ecore_Config_Server *_ecore_config_server_convert(void *srv);
+
+char *_ecore_config_ipc_prop_list(Ecore_Config_Server * srv,
+ const long serial);
+char *_ecore_config_ipc_prop_desc(Ecore_Config_Server * srv,
+ const long serial,
+ const char *key);
+char *_ecore_config_ipc_prop_get(Ecore_Config_Server * srv,
+ const long serial,
+ const char *key);
+int _ecore_config_ipc_prop_set(Ecore_Config_Server * srv,
+ const long serial,
+ const char *key,
+ const char *val);
+
+char *_ecore_config_ipc_bundle_list(Ecore_Config_Server * srv);
+int _ecore_config_ipc_bundle_new(Ecore_Config_Server * srv,
+ const char *);
+char *_ecore_config_ipc_bundle_label_get(Ecore_Config_Server *
+ srv, const long);
+int _ecore_config_ipc_bundle_label_set(Ecore_Config_Server *
+ srv, const long,
+ const char *);
+long _ecore_config_ipc_bundle_label_find(Ecore_Config_Server *
+ srv, const char *);
diff --git a/ecore/src/lib/ecore_config/ecore_config_ipc_ecore.c b/ecore/src/lib/ecore_config/ecore_config_ipc_ecore.c
new file mode 100644
index 0000000..289c690
--- /dev/null
+++ b/ecore/src/lib/ecore_config/ecore_config_ipc_ecore.c
@@ -0,0 +1,378 @@
+/* by Azundris, with thanks to Corey Donohoe <atmos@atmos.org> */
+#include "ecore_private.h"
+#include "ecore_config_ipc.h"
+#include "ecore_config_util.h"
+#include "ecore_config_private.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include <Ecore.h>
+#include <Ecore_Ipc.h>
+
+#include "Ecore_Config.h"
+#include "config.h"
+
+
+/*****************************************************************************/
+
+static int
+_ecore_config_ipc_ecore_string_get(char **m, char **r)
+{
+ char *q;
+ int l = 0;
+
+ if (!m || !*m)
+ return ECORE_CONFIG_ERR_NODATA;
+ if (!r)
+ return ECORE_CONFIG_ERR_FAIL;
+ q = *m;
+ if (*q != 's')
+ return ECORE_CONFIG_ERR_TYPEMISMATCH;
+ q++;
+ l = (*(q++)) << 8;
+ l += *(q++);
+ *r = q;
+ q += l;
+ *m = q;
+ E(1, "IPC/eCore: got string-%d \"%s\"\n", l, *r);
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+static char *
+_ecore_config_ipc_global_prop_list(Ecore_Config_Server * srv __UNUSED__, long serial __UNUSED__)
+{
+ Ecore_Config_DB_File *db;
+ char **keys;
+ int key_count, x;
+ estring *s;
+ int f;
+ char buf[PATH_MAX], *p;
+ // char *data; UNUSED
+ Ecore_Config_Type type;
+
+ db = NULL;
+ s = estring_new(8192);
+ f = 0;
+ if ((p = getenv("HOME")))
+ {
+ snprintf(buf, sizeof(buf), "%s/.e/config.eet", p);
+ if (!(db = _ecore_config_db_open_read(buf)))
+ {
+ strcpy(buf, PACKAGE_DATA_DIR"/system.eet");
+ if (!(db = _ecore_config_db_open_read(buf)))
+ return NULL;
+ }
+ }
+ if (!db) return NULL;
+ key_count = 0;
+ keys = _ecore_config_db_keys_get(db, &key_count);
+ if (keys)
+ {
+ for (x = 0; x < key_count; x++)
+ {
+ type = _ecore_config_db_key_type_get(db, keys[x]);
+ switch (type)
+ {
+ case PT_INT:
+ estring_appendf(s, "%s%s: integer", f ? "\n" : "", keys[x]);
+ break;
+ case PT_BLN:
+ estring_appendf(s, "%s%s: boolean", f ? "\n" : "", keys[x]);
+ break;
+ case PT_FLT:
+ estring_appendf(s, "%s%s: float", f ? "\n" : "", keys[x]);
+ break;
+ case PT_STR:
+ estring_appendf(s, "%s%s: string", f ? "\n" : "", keys[x]);
+ break;
+ case PT_RGB:
+ estring_appendf(s, "%s%s: colour", f ? "\n" : "", keys[x]);
+ break;
+ case PT_THM:
+ estring_appendf(s, "%s%s: theme", f ? "\n" : "", keys[x]);
+ break;
+ default:
+ estring_appendf(s, "%s%s: unknown", f ? "\n" : "", keys[x]);
+ continue;
+ }
+ f = 1;
+ }
+ }
+ _ecore_config_db_close(db);
+ if (keys)
+ {
+ for (x = 0; x < key_count; x++)
+ {
+ free(keys[x]);
+ }
+ free(keys);
+ }
+
+ return estring_disown(s);
+}
+
+/*****************************************************************************/
+
+static int
+_ecore_config_ipc_ecore_send(Ecore_Ipc_Event_Client_Data * e, int code,
+ char *reply)
+{
+ static int our_ref = 0;
+ int len = reply ? strlen(reply) + 1 : 0;
+
+ our_ref++;
+ E(1, "IPC/eCore: replying [0,0] %d IRT %d => %d {\"%s\":%d}\n", our_ref,
+ e->ref, code, reply ? reply : "", len);
+ return ecore_ipc_client_send(e->client, 0, 0, our_ref, e->ref, code, reply,
+ len);
+}
+
+/*****************************************************************************/
+
+static int
+_ecore_config_ipc_ecore_handle_request(Ecore_Ipc_Server * server,
+ Ecore_Ipc_Event_Client_Data * e)
+{
+ Ecore_Config_Server *srv;
+ long serial;
+ int ret;
+ char *r, *k, *v, *m;
+
+ srv = _ecore_config_server_convert(server);
+ serial = e->minor;
+ ret = ECORE_CONFIG_ERR_FAIL;
+ r = NULL;
+ m = (char *)e->data;
+ E(1, "IPC/eCore: client sent: [%d,%d] #%d (%d) @ %p\n", e->major, e->minor,
+ e->ref, e->size, server);
+
+ switch (e->major)
+ {
+ case IPC_PROP_LIST:
+ if (srv == __ecore_config_server_global)
+ r = _ecore_config_ipc_global_prop_list(srv, serial);
+ else
+ r = _ecore_config_ipc_prop_list(srv, serial);
+ break;
+ case IPC_PROP_DESC:
+ if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
+ r = _ecore_config_ipc_prop_desc(srv, serial, k);
+ break;
+ case IPC_PROP_GET:
+ if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
+ r = _ecore_config_ipc_prop_get(srv, serial, k);
+ break;
+ case IPC_PROP_SET:
+ if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
+ {
+ if (_ecore_config_ipc_ecore_string_get(&m, &v) ==
+ ECORE_CONFIG_ERR_SUCC)
+ return _ecore_config_ipc_ecore_send(e,
+ _ecore_config_ipc_prop_set
+ (srv, serial, k, v), NULL);
+ }
+ break;
+
+ case IPC_BUNDLE_LIST:
+ r = _ecore_config_ipc_bundle_list(srv);
+ break;
+ case IPC_BUNDLE_NEW:
+ if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
+ return _ecore_config_ipc_ecore_send(e,
+ k ?
+ _ecore_config_ipc_bundle_new(srv,
+ k) :
+ ECORE_CONFIG_ERR_FAIL, NULL);
+ break;
+ case IPC_BUNDLE_LABEL_SET:
+ if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
+ return _ecore_config_ipc_ecore_send(e,
+ k ?
+ _ecore_config_ipc_bundle_label_set
+ (srv, serial,
+ k) : ECORE_CONFIG_ERR_FAIL,
+ NULL);
+ break;
+ case IPC_BUNDLE_LABEL_FIND:
+ if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
+ return _ecore_config_ipc_ecore_send(e,
+ _ecore_config_ipc_bundle_label_find
+ (srv, k), NULL);
+ break;
+ case IPC_BUNDLE_LABEL_GET:
+ r = _ecore_config_ipc_bundle_label_get(srv, serial);
+ break;
+ }
+
+ ret =
+ _ecore_config_ipc_ecore_send(e,
+ r ? ECORE_CONFIG_ERR_SUCC :
+ ECORE_CONFIG_ERR_FAIL, r);
+ if (r)
+ {
+ free(r);
+ return ret;
+ }
+ return ECORE_CONFIG_ERR_NOTFOUND;
+}
+
+/*****************************************************************************/
+
+static int
+_ecore_config_ipc_client_add(void *data, int type __UNUSED__, void *event)
+{
+ Ecore_Ipc_Server **server;
+ Ecore_Ipc_Event_Client_Data *e;
+
+ server = (Ecore_Ipc_Server **) data;
+ e = (Ecore_Ipc_Event_Client_Data *) event;
+
+ if (*server != ecore_ipc_client_server_get(e->client))
+ return 1;
+
+ E(1, "IPC/eCore: Client connected. @ %p\n", server);
+ return 1;
+}
+
+static int
+_ecore_config_ipc_client_del(void *data, int type __UNUSED__, void *event)
+{
+ Ecore_Ipc_Server **server;
+ Ecore_Ipc_Event_Client_Data *e;
+
+ server = (Ecore_Ipc_Server **) data;
+ e = (Ecore_Ipc_Event_Client_Data *) event;
+
+ if (*server != ecore_ipc_client_server_get(e->client))
+ return 1;
+
+ E(1, "IPC/eCore: Client disconnected. @ %p\n", server);
+ return 1;
+}
+
+static int
+_ecore_config_ipc_client_sent(void *data, int type __UNUSED__, void *event)
+{
+ Ecore_Ipc_Server **server;
+ Ecore_Ipc_Event_Client_Data *e;
+
+ server = (Ecore_Ipc_Server **) data;
+ e = (Ecore_Ipc_Event_Client_Data *) event;
+
+ if (*server != ecore_ipc_client_server_get(e->client))
+ return 1;
+
+ _ecore_config_ipc_ecore_handle_request(*server, e);
+ return 1;
+}
+
+/*****************************************************************************/
+
+int
+_ecore_config_ipc_ecore_init(const char *pipe_name, void **data)
+{
+ Ecore_Ipc_Server **server;
+ struct stat st;
+ char *p;
+ int port;
+ char socket[PATH_MAX];
+
+ server = (Ecore_Ipc_Server **) data;
+ port = 0;
+ if (!server)
+ return ECORE_CONFIG_ERR_FAIL;
+
+/* if(*server)
+ return ECORE_CONFIG_ERR_IGNORED; */
+
+ ecore_init();
+ if (ecore_ipc_init() < 1)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ if ((p = getenv("HOME")))
+ { /* debug-only ### FIXME */
+ int stale;
+
+ stale = 1;
+ while (stale)
+ {
+ snprintf(socket, PATH_MAX, "%s/.ecore/%s/%d", p, pipe_name, port);
+
+ if (!stat(socket, &st))
+ {
+ E(0, "IPC/eCore: pipe \"%s\" already exists!?\n", socket);
+/* if(unlink(buf))
+ E(0,"IPC/eCore: could not remove pipe \"%s\": %d\n",buf,errno); }}*/
+ port++;
+ }
+ else
+ {
+ stale = 0;
+ }
+ }
+ }
+ *server = ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, pipe_name, port, NULL);
+ ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD,
+ _ecore_config_ipc_client_add, server);
+ ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL,
+ _ecore_config_ipc_client_del, server);
+ ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,
+ _ecore_config_ipc_client_sent, server);
+
+ if (server)
+ {
+ E(1, "IPC/eCore: Server is listening on %s.\n", pipe_name);
+ }
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+int
+_ecore_config_ipc_ecore_exit(void **data)
+{
+ int ret;
+ Ecore_Ipc_Server **server;
+
+ ret = ECORE_CONFIG_ERR_SUCC;
+ server = (Ecore_Ipc_Server **) data;
+
+ if (!server)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ if (*server)
+ {
+ ecore_ipc_server_del(*server);
+ *server = NULL;
+ }
+
+ ecore_ipc_shutdown();
+
+ return ret;
+}
+
+/*****************************************************************************/
+
+int
+_ecore_config_ipc_ecore_poll(void **data)
+{
+ Ecore_Ipc_Server **server;
+
+ server = (Ecore_Ipc_Server **) data;
+
+ if (!server)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ ecore_main_loop_iterate();
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/*****************************************************************************/
diff --git a/ecore/src/lib/ecore_config/ecore_config_ipc_main.c b/ecore/src/lib/ecore_config/ecore_config_ipc_main.c
new file mode 100644
index 0000000..b4adf27
--- /dev/null
+++ b/ecore/src/lib/ecore_config/ecore_config_ipc_main.c
@@ -0,0 +1,284 @@
+/* ############## bad */
+#define HAVE_EVAS2
+
+#include "Ecore_Config.h"
+#include "ecore_config_util.h"
+#include "ecore_config_ipc.h"
+
+#include "config.h"
+#include "ecore_config_private.h"
+
+#include <signal.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <glob.h>
+#include <sys/param.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h> /* malloc(), free() */
+
+#ifndef TRUE
+# define FALSE 0
+# define TRUE (!FALSE)
+#endif
+
+static Ecore_Config_Server *__ecore_config_servers;
+static unsigned long ipc_timer = 0L;
+
+extern int _ecore_config_ipc_ecore_init(const char *pipe_name, void **data);
+extern int _ecore_config_ipc_ecore_exit(void **data);
+extern int _ecore_config_ipc_ecore_poll(void **data);
+
+Ecore_Config_Server *
+_ecore_config_server_convert(void *srv)
+{
+ Ecore_Config_Server *srv_tmp;
+
+ srv_tmp = __ecore_config_servers;
+ while (srv_tmp)
+ {
+ if (srv_tmp->server == srv)
+ return srv_tmp;
+ srv_tmp = srv_tmp->next;
+ }
+
+ return __ecore_config_server_global;
+}
+
+/*****************************************************************************/
+/* INTERFACE FOR IPC MODULES */
+/*****************************/
+
+char *
+_ecore_config_ipc_prop_list(Ecore_Config_Server * srv, const long serial)
+{
+ Ecore_Config_Bundle *theme;
+ Ecore_Config_Prop *e;
+ estring *s;
+ int f;
+
+ theme = ecore_config_bundle_by_serial_get(srv, serial);
+ e = theme ? theme->data : NULL;
+ s = estring_new(8192);
+ f = 0;
+ while (e)
+ {
+ /* ignore system properties in listings, unless they have been overridden */
+ if (e->flags & PF_SYSTEM && !(e->flags & PF_MODIFIED))
+ {
+ e = e->next;
+ continue;
+ }
+ estring_appendf(s, "%s%s: %s", f ? "\n" : "", e->key,
+ ecore_config_type_get(e));
+ if (e->flags & PF_BOUNDS)
+ {
+ if (e->type == PT_FLT)
+ estring_appendf(s, ", range %le..%le",
+ (float)e->lo / ECORE_CONFIG_FLOAT_PRECISION,
+ (float)e->hi / ECORE_CONFIG_FLOAT_PRECISION);
+ else
+ estring_appendf(s, ", range %d..%d", e->lo, e->hi);
+ }
+ if (e->type == PT_THM)
+ estring_appendf(s, ", group %s", e->data ? e->data : "Main");
+ f = 1;
+ e = e->next;
+ }
+
+ return estring_disown(s);
+}
+
+char *
+_ecore_config_ipc_prop_desc(Ecore_Config_Server * srv, const long serial,
+ const char *key)
+{
+#ifdef HAVE_EVAS2
+ Ecore_Config_Bundle *theme;
+ Ecore_Config_Prop *e;
+
+ theme = ecore_config_bundle_by_serial_get(srv, serial);
+ e = ecore_config_get(key);
+
+ if (e)
+ {
+ estring *s = estring_new(512);
+
+ estring_appendf(s, "%s: %s", e->key, ecore_config_type_get(e));
+ if (e->flags & PF_BOUNDS)
+ estring_appendf(s, ", range %d..%d", e->lo, e->hi);
+ return estring_disown(s);
+ }
+#endif
+ return strdup("<undefined>");
+}
+
+char *
+_ecore_config_ipc_prop_get(Ecore_Config_Server * srv, const long serial,
+ const char *key)
+{
+#ifdef HAVE_EVAS2
+ char *ret;
+ Ecore_Config_Bundle *theme;
+
+ ret = NULL;
+ theme = ecore_config_bundle_by_serial_get(srv, serial);
+ if ((ret = ecore_config_as_string_get( /*theme, */ key)))
+ return ret;
+#endif
+ return strdup("<undefined>");
+}
+
+int
+_ecore_config_ipc_prop_set(Ecore_Config_Server * srv, const long serial,
+ const char *key, const char *val)
+{
+#ifdef HAVE_EVAS2
+ int ret;
+ Ecore_Config_Bundle *theme;
+
+ theme = ecore_config_bundle_by_serial_get(srv, serial);
+ ret = ecore_config_set(key, (char *)val);
+ E(1, "ipc.prop.set(%s->%s,\"%s\") => %d\n", theme ? theme->identifier : "",
+ key, val, ret);
+ return ret;
+#else
+ return ECORE_CONFIG_ERR_NOTSUPP;
+#endif
+}
+
+/*****************************************************************************/
+
+char *
+_ecore_config_ipc_bundle_list(Ecore_Config_Server * srv)
+{
+ Ecore_Config_Bundle *ns;
+ estring *s;
+ int f;
+
+ ns = ecore_config_bundle_1st_get(srv);
+ s = estring_new(8192);
+ f = 0;
+ if (!ns)
+ return strdup("<no_bundles_created>");
+
+ while (ns)
+ {
+ estring_appendf(s, "%s%d: %s", f ? "\n" : "",
+ ecore_config_bundle_serial_get(ns),
+ ecore_config_bundle_label_get(ns));
+ f = 1;
+ ns = ecore_config_bundle_next_get(ns);
+ }
+
+ return estring_disown(s);
+}
+
+int
+_ecore_config_ipc_bundle_new(Ecore_Config_Server * srv, const char *label)
+{
+ if (ecore_config_bundle_new(srv, label))
+ return ECORE_CONFIG_ERR_SUCC;
+ return ECORE_CONFIG_ERR_FAIL;
+}
+
+char *
+_ecore_config_ipc_bundle_label_get(Ecore_Config_Server * srv, const long serial)
+{
+ Ecore_Config_Bundle *ns;
+ char *label;
+
+ ns = ecore_config_bundle_by_serial_get(srv, serial);
+ label = ecore_config_bundle_label_get(ns);
+ return strdup(label ? label : "<no such bundle>");
+}
+
+int
+_ecore_config_ipc_bundle_label_set(Ecore_Config_Server * srv, const long serial,
+ const char *label)
+{
+ Ecore_Config_Bundle *ns;
+
+ ns = ecore_config_bundle_by_serial_get(srv, serial);
+ if (!(ns->identifier = malloc(sizeof(label))))
+ return ECORE_CONFIG_ERR_OOM;
+ memcpy(ns->identifier, label, sizeof(label));
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+long
+_ecore_config_ipc_bundle_label_find(Ecore_Config_Server * srv,
+ const char *label)
+{
+ Ecore_Config_Bundle *ns;
+
+ ns = ecore_config_bundle_by_label_get(srv, label);
+ return ns ? ecore_config_bundle_serial_get(ns) : -1;
+}
+
+static int
+_ecore_config_ipc_poll(void *data)
+{
+ Ecore_Config_Server *s;
+
+ s = __ecore_config_servers;
+ while (s)
+ {
+ _ecore_config_ipc_ecore_poll(&s->server);
+ s = s->next;
+ }
+
+ return TRUE;
+}
+
+int
+_ecore_config_ipc_exit(void)
+{
+ Ecore_Config_Server *l;
+
+ if (ipc_timer)
+ timeout_remove(ipc_timer);
+ l = __ecore_config_servers;
+ while (l)
+ {
+ _ecore_config_ipc_ecore_exit(&l->server);
+ l = l->next;
+ }
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+Ecore_Config_Server *
+_ecore_config_ipc_init(const char *pipe_name)
+{
+ int ret;
+ Ecore_Config_Server *list;
+ Ecore_Config_Server *ret_srv;
+
+ list = NULL;
+ ret_srv = NULL;
+ list = NULL;
+
+ list = malloc(sizeof(Ecore_Config_Server));
+ memset(list, 0, sizeof(Ecore_Config_Server));
+ if ((ret = _ecore_config_ipc_ecore_init(pipe_name, &list->server)) != ECORE_CONFIG_ERR_SUCC)
+ {
+ E(2, "_ecore_config_ipc_init: failed to register %s, code %d\n",
+ pipe_name, ret);
+ }
+
+ E(2, "_ecore_config_ipc_init: registered \"%s\"...\n", pipe_name);
+
+ list->name = strdup(pipe_name);
+ list->next = __ecore_config_servers;
+
+ __ecore_config_servers = list;
+ if (!ret_srv)
+ ret_srv = list;
+
+ if (!ipc_timer)
+ ipc_timer = timeout_add(100, _ecore_config_ipc_poll, NULL);
+
+ return ret_srv;
+}
+/*****************************************************************************/
diff --git a/ecore/src/lib/ecore_config/ecore_config_private.h b/ecore/src/lib/ecore_config/ecore_config_private.h
new file mode 100644
index 0000000..2b8ed47
--- /dev/null
+++ b/ecore/src/lib/ecore_config/ecore_config_private.h
@@ -0,0 +1,28 @@
+#ifndef _ECORE_CONFIG_PRIVATE_H
+# define _ECORE_CONFIG_PRIVATE_H
+
+/* debug */
+extern int DEBUG;
+#ifdef __sgi
+# define D
+# define E
+#else
+# define D(fmt,args...) do { if(DEBUG>=0) fprintf(stderr,fmt,## args); } while(0);
+# define E(lvl,args...) do { if(DEBUG>=(lvl)) fprintf(stderr,## args); } while(0)
+#endif
+
+typedef struct _Ecore_Config_DB_File Ecore_Config_DB_File;
+
+int _ecore_config_mod_init(const char *pipe_name, void **data);
+int _ecore_config_mod_exit(void **data);
+int _ecore_config_mod_poll(void **data);
+
+Ecore_Config_DB_File *_ecore_config_db_open_read(const char *file);
+Ecore_Config_DB_File *_ecore_config_db_open_write(const char *file);
+void _ecore_config_db_close(Ecore_Config_DB_File *db);
+char **_ecore_config_db_keys_get(Ecore_Config_DB_File *db, int *num_ret);
+Ecore_Config_Type _ecore_config_db_key_type_get(Ecore_Config_DB_File *db, const char *key);
+int _ecore_config_db_read(Ecore_Config_DB_File *db, const char *key);
+void _ecore_config_db_write(Ecore_Config_DB_File *db, const char *key);
+
+#endif
diff --git a/ecore/src/lib/ecore_config/ecore_config_storage.c b/ecore/src/lib/ecore_config/ecore_config_storage.c
new file mode 100644
index 0000000..e3cba38
--- /dev/null
+++ b/ecore/src/lib/ecore_config/ecore_config_storage.c
@@ -0,0 +1,172 @@
+#include "Ecore_Config.h"
+#include "ecore_config_private.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+/**
+ * Loads the default configuration.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA
+ * is returned if the file cannot be loaded.
+ * @ingroup Ecore_Config_File_Group
+ */
+int
+ecore_config_load(void)
+{
+ char file[PATH_MAX];
+
+ if (!__ecore_config_app_name)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ snprintf(file, PATH_MAX, "%s/.e/apps/%s/config.eet", getenv("HOME"),
+ __ecore_config_app_name);
+ return ecore_config_file_load(file);
+}
+
+/**
+ * Saves the current configuration to the default file.
+ * @return @c ECORE_CONFIG_ERR_SUCC is returned on success.
+ * @c ECORE_CONFIG_ERR_FAIL is returned if the data cannot be
+ * saved.
+ * @ingroup Ecore_Config_File_Group
+ */
+int
+ecore_config_save(void)
+{
+ char file[PATH_MAX];
+
+ if (!__ecore_config_app_name)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ snprintf(file, PATH_MAX, "%s/.e/apps/%s/config.eet", getenv("HOME"),
+ __ecore_config_app_name);
+ return ecore_config_file_save(file);
+}
+
+/**
+ * Load the given configuration file to the local configuration.
+ * @param file Name of the file to load.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA
+ * is returned if the file cannot be loaded.
+ * @ingroup Ecore_Config_File_Group
+ */
+int
+ecore_config_file_load(const char *file)
+{
+ Ecore_Config_DB_File *db;
+ char **keys;
+ int key_count;
+ int x;
+ // double ftmp; UNUSED
+ // int pt; UNUSED
+ // int itmp; UNUSED
+ // Ecore_Config_Type type; UNUSED
+ char *data;
+
+ db = NULL;
+ data = NULL;
+
+ db = _ecore_config_db_open_read(file);
+ if (!db)
+ {
+ E(0, "Cannot open database from file %s!\n", file);
+ return ECORE_CONFIG_ERR_NODATA;
+ }
+ key_count = 0;
+ keys = _ecore_config_db_keys_get(db, &key_count);
+ if (keys)
+ {
+ for (x = 0; x < key_count; x++)
+ {
+ _ecore_config_db_read(db, keys[x]);
+ }
+ }
+ _ecore_config_db_close(db);
+ if (keys)
+ {
+ for (x = 0; x < key_count; x++)
+ {
+ free(keys[x]);
+ }
+ free(keys);
+ }
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+static void
+_ecore_config_recurse_mkdir(const char *file)
+{
+ char *file_ptr;
+ char *file_tmp;
+ struct stat status;
+
+ file_tmp = strdup(file);
+ file_ptr = file_tmp + strlen(file_tmp);
+ while (*file_ptr != '/' && file_ptr > file_tmp)
+ file_ptr--;
+ *file_ptr = '\0';
+
+ if (stat(file_tmp, &status))
+ {
+ _ecore_config_recurse_mkdir(file_tmp);
+ mkdir(file_tmp, S_IRUSR | S_IWUSR | S_IXUSR);
+ }
+ free(file_tmp);
+}
+
+/**
+ * Saves the local configuration to the given file.
+ * @param file Name of the file to save to.
+ * @return @c ECORE_CONFIG_ERR_SUCC is returned on success.
+ * @c ECORE_CONFIG_ERR_FAIL is returned if the data cannot be
+ * saved.
+ * @ingroup Ecore_Config_File_Group
+ */
+int
+ecore_config_file_save(const char *file)
+{
+ Ecore_Config_Prop *next;
+ Ecore_Config_DB_File *db;
+ struct stat status;
+
+ next = __ecore_config_bundle_local->data;
+ db = NULL;
+
+ /* if file does not exist check to see if the dirs exist, creating if not */
+ if (stat(file, &status))
+ _ecore_config_recurse_mkdir(file);
+
+ db = _ecore_config_db_open_write(file);
+ if (!db)
+ {
+ E(0, "Cannot open database from file %s!\n", file);
+ return ECORE_CONFIG_ERR_FAIL;
+ }
+
+ while (next)
+ {
+ /* let the config_db deal with this
+ * handyande: hmm, not sure that it ever does - reinstating until
+ * further discussions satisfy me!
+ */
+ if (!(next->flags & PF_MODIFIED) || next->flags & PF_CMDLN)
+ {
+ next = next->next;
+ continue;
+ }
+
+ _ecore_config_db_write(db, next->key);
+
+ next = next->next;
+ }
+
+ _ecore_config_db_close(db);
+ return ECORE_CONFIG_ERR_SUCC;
+}
diff --git a/ecore/src/lib/ecore_config/ecore_config_util.c b/ecore/src/lib/ecore_config/ecore_config_util.c
new file mode 100644
index 0000000..07f625a
--- /dev/null
+++ b/ecore/src/lib/ecore_config/ecore_config_util.c
@@ -0,0 +1,781 @@
+/* azundris */
+
+/*#include <glib.h>*/
+
+#include <sys/types.h>
+#include <sys/time.h> /* gimetimeofday() */
+#include <stdio.h> /* NULL */
+#include <stdlib.h> /* malloc(), free() */
+#include <string.h> /* str...() */
+#include <ctype.h> /* isspace() */
+
+#include <stdarg.h> /* varargs in dlmulti() */
+#include <dlfcn.h> /* dlopen() and friends for dlmulti() */
+
+/* #ifdef HAVE_GLIB2 */
+/* # include <glib/gmain.h> */
+/* #endif */
+
+#include "ecore_private.h"
+
+#include "Ecore_Config.h"
+#include "ecore_config_util.h"
+
+#include "ecore_config_private.h"
+
+#define CHUNKLEN 4096
+
+/*****************************************************************************/
+/* MISC */
+/********/
+
+int
+dlmulti(const char *name, const char *file, int flag, void **libr, const char *fmt, ...)
+{
+#define MAX_SYM_LEN 256
+ va_list ap;
+ void *lib;
+ int ret = ECORE_CONFIG_ERR_SUCC;
+ char buf[MAX_SYM_LEN] = "\0";
+
+ if (!libr)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ if (!name)
+ name = file;
+
+ *libr = NULL;
+
+ if ((lib = dlopen(file, flag)))
+ {
+ void **funr, *fun;
+ char *b, *e;
+ size_t l;
+ int required = 1;
+
+ va_start(ap, fmt);
+ while (*fmt)
+ {
+ switch (*fmt)
+ {
+ case '?':
+ required = 0;
+ fmt++;
+ break;
+
+ case '!':
+ case '.':
+ required = 1;
+ fmt++;
+ break;
+
+ case '\t':
+ case '\n':
+ case '\r':
+ case ';':
+ case ',':
+ case ' ':
+ fmt++;
+ break;
+
+ default:
+ e = b = (char *)fmt;
+ while (*e && (strchr("?!.,; \t\n\r", *e) == NULL))
+ e++;
+
+ fmt = e;
+ if (e == b)
+ ret = ECORE_CONFIG_ERR_NODATA;
+ else if ((l = (e - b)) >= MAX_SYM_LEN)
+ ret = ECORE_CONFIG_ERR_OOM;
+ else
+ {
+ memcpy(buf, b, l);
+ buf[l] = '\0';
+ funr = va_arg(ap, void **);
+
+ if (!(fun = dlsym(lib, buf)))
+ {
+ if ((ret =
+ required ? ECORE_CONFIG_ERR_NOTFOUND :
+ ECORE_CONFIG_ERR_PARTIAL) ==
+ ECORE_CONFIG_ERR_NOTFOUND)
+ E(1,
+ "DLMulti: library/plugin/engine \"%s\" (\"%s\") did not contain required function \"%s\"...\n",
+ name, file, buf);
+ }
+ E(2, "DLMulti: %p => %p %c\"%s\"\n", fun, funr,
+ required ? '!' : '?', buf);
+ if (funr)
+ *funr = fun;
+ }
+ required = 1;
+ }
+ }
+
+ va_end(ap);
+
+ if ((ret == ECORE_CONFIG_ERR_SUCC) || (ret == ECORE_CONFIG_ERR_PARTIAL))
+ *libr = lib;
+ else
+ dlclose(lib);
+ }
+ else
+ ret = ECORE_CONFIG_ERR_NODATA;
+
+ return ret;
+}
+
+#if 0 /* Unused */
+/*****************************************************************************/
+
+unsigned long
+now(long delay)
+{
+ static struct timeval tv;
+ unsigned long r;
+
+ gettimeofday(&tv, NULL);
+ r = tv.tv_sec * 1000 + (((float)tv.tv_usec) / 1000.0) + delay;
+ return r;
+}
+#endif
+
+/*****************************************************************************/
+
+int
+parse_line(char *in, char **o1, char **o2, char **o3, char **o4)
+{
+#define PLMAX 16
+ int c;
+ char *p = in;
+ char *r[PLMAX];
+
+ for (c = 0; c < PLMAX; c++)
+ r[c] = NULL;
+
+ c = 0;
+ if (!in || !*in)
+ goto pl_end;
+
+ do
+ {
+ while (isspace(*p))
+ *(p++) = '\0';
+
+ if (!*p || (strchr("#;", *p) && (!p[1] || isspace(p[1]))))
+ *p = '\0'; /* it ends HERE */
+ else
+ {
+ if (*p == '\"')
+ {
+ r[c++] = ++p;
+ while (*p && (*p != '\"'))
+ {
+ if ((*p == '\\') && p[1])
+ p += 2;
+ else
+ p++;
+ }
+ if (*p)
+ *(p++) = '\0';
+ }
+ else
+ {
+ r[c++] = p;
+ while (*p && !isspace(*p))
+ p++;
+ }
+ }
+ }
+ while (*p);
+
+ pl_end:
+ if (o1)
+ *o1 = r[0];
+ if (o2)
+ *o2 = r[1];
+ if (o3)
+ *o3 = r[2];
+ if (o4)
+ *o4 = r[3];
+
+ return c;
+}
+
+/*****************************************************************************/
+
+/*char *unit_size(char *size) {
+ gchar *unit="byte";
+ long s;
+
+ if((s=atol(size))&&(s>=1024)) {
+ if((s>(1024*1024*1024))) {
+ unit="GB";
+ s=(long)(s/(1024*1024)); }
+ else if((s>(1024*1024))) {
+ unit="MB";
+ s=(long)(s/1024); }
+ else
+ unit="KB";
+
+ if((s/1024)>31)
+ sprintf(size,"%ld %s",(long)(s/1024),unit);
+ else
+ sprintf(size,"%.1f %s",((float)s)/1024,unit); }
+ else
+ sprintf(size,"%ld %s",s,unit);
+
+ return size; }
+
+*/
+
+/*****************************************************************************/
+
+void
+qsrt(void *a[], void *data, int lo, int hi,
+ int (*compare) (const void *, const void *, const void *))
+{
+ int h, l;
+ void *p, *t;
+
+ if (lo < hi)
+ {
+ l = lo;
+ h = hi;
+ p = a[hi];
+
+ do
+ {
+ while ((l < h) && (compare(data, a[l], p) <= 0))
+ l = l + 1;
+ while ((h > l) && (compare(data, a[h], p) >= 0))
+ h = h - 1;
+ if (l < h)
+ {
+ t = a[l];
+ a[l] = a[h];
+ a[h] = t;
+ }
+ }
+ while (l < h);
+
+ t = a[l];
+ a[l] = a[hi];
+ a[hi] = t;
+
+ qsrt(a, data, lo, l - 1, compare);
+ qsrt(a, data, l + 1, hi, compare);
+ }
+}
+
+/*****************************************************************************/
+/* TIMERS */
+/**********/
+
+#ifdef HAVE_GLIB2
+
+unsigned long
+timeout_add(uint f, int (*fun) (void *), void *data)
+{
+ return g_timeout_add((guint) f, (GSourceFunc) fun, (gpointer) data);
+}
+
+int
+timeout_remove(unsigned long handle)
+{
+ return g_source_remove(handle) ? ECORE_CONFIG_ERR_SUCC :
+ ECORE_CONFIG_ERR_FAIL;
+}
+
+#else
+
+unsigned long
+timeout_add(uint f __UNUSED__, int (*fun) (void *) __UNUSED__, void *data __UNUSED__)
+{
+ return 0;
+}
+
+int
+timeout_remove(unsigned long handle __UNUSED__)
+{
+ return ECORE_CONFIG_ERR_NOTSUPP;
+}
+
+#endif /* HAVE_GLIB2 */
+
+/*****************************************************************************/
+/* HASHES */
+/**********/
+
+int
+eslist_free(eslist ** l)
+{
+ eslist *e, *f;
+
+ if (!l)
+ return ECORE_CONFIG_ERR_NODATA;
+ for (e = *l; e; e = f)
+ {
+ f = e->next;
+ free(e);
+ }
+ *l = NULL;
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+int
+eslist_next(eslist ** e)
+{
+ if (!e || !*e)
+ return ECORE_CONFIG_ERR_NODATA;
+ *e = (*e)->next;
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+void *
+eslist_payload(eslist ** e)
+{
+ return (!e || !*e) ? NULL : (*e)->payload;
+}
+
+int
+eslist_prepend(eslist ** e, void *p)
+{
+ eslist *f;
+
+ if (!e)
+ return ECORE_CONFIG_ERR_NODATA;
+
+ if (!(f = malloc(sizeof(eslist))))
+ return ECORE_CONFIG_ERR_OOM;
+
+ f->payload = p;
+ f->next = *e;
+
+ *e = f;
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+int
+eslist_append(eslist ** e, void *p)
+{
+ eslist *f;
+
+ if (!e)
+ return ECORE_CONFIG_ERR_NODATA;
+
+ if (!(f = malloc(sizeof(eslist))))
+ return ECORE_CONFIG_ERR_OOM;
+
+ f->payload = p;
+ f->next = NULL;
+
+ if (!*e)
+ *e = f;
+ else
+ {
+ eslist *g = *e;
+
+ while (g->next)
+ g = g->next;
+ g->next = f;
+ }
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/*****************************************************************************/
+/* HASHES */
+/**********/
+
+#ifdef HAVE_GLIB2
+
+void *
+hash_table_new(void (*freekey), void (*freeval))
+{
+ return g_hash_table_new_full(g_str_hash, g_str_equal, freekey, freeval);
+}
+
+void *
+hash_table_fetch(void *hashtable, char *key)
+{
+ return g_hash_table_lookup(hashtable, key);
+}
+
+int
+hash_table_insert(void *hashtable, char *key, void *value)
+{
+ g_hash_table_insert(hashtable, key, value);
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+int
+hash_table_replace(void *hashtable, char *key, void *value)
+{
+ g_hash_table_replace(hashtable, key, value);
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+int
+hash_table_remove(void *hashtable, char *key)
+{
+ g_hash_table_remove(hashtable, key);
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+int
+hash_table_dst(void *hashtable)
+{
+ g_hash_table_destroy(hashtable);
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+int
+hash_table_walk(void *hashtable, hash_walker fun, void *data)
+{
+ g_hash_table_foreach(hashtable, (GHFunc) fun, data);
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+#else
+
+void *
+hash_table_new(void (*freekey) __UNUSED__, void (*freeval) __UNUSED__)
+{
+ return NULL;
+}
+
+void *
+hash_table_fetch(void *hashtable __UNUSED__, char *key __UNUSED__)
+{
+ return NULL;
+}
+
+int
+hash_table_insert(void *hashtable __UNUSED__, char *key __UNUSED__, void *value __UNUSED__)
+{
+ return ECORE_CONFIG_ERR_NOTSUPP;
+}
+
+int
+hash_table_replace(void *hashtable __UNUSED__, char *key __UNUSED__, void *value __UNUSED__)
+{
+ return ECORE_CONFIG_ERR_NOTSUPP;
+}
+
+int
+hash_table_remove(void *hashtable __UNUSED__, char *key __UNUSED__)
+{
+ return ECORE_CONFIG_ERR_NOTSUPP;
+}
+
+int
+hash_table_dst(void *hashtable __UNUSED__)
+{
+ return ECORE_CONFIG_ERR_NOTSUPP;
+}
+
+int
+hash_table_walk(void *hashtable __UNUSED__, hash_walker fun __UNUSED__, void *data __UNUSED__)
+{
+ return ECORE_CONFIG_ERR_NOTSUPP;
+}
+
+#endif /* HAVE_GLIB2 */
+
+/*****************************************************************************/
+/* STRINGS */
+/***********/
+
+estring *
+estring_new(int size)
+{
+ estring *e = malloc(sizeof(estring));
+
+ if (e)
+ {
+ memset(e, 0, sizeof(estring));
+ if ((size > 0) && (e->str = malloc(size)))
+ e->alloc = size;
+ }
+ return e;
+}
+
+estring *
+estring_dst(estring * e)
+{
+ if (e)
+ {
+ if (e->str)
+ free(e->str);
+ free(e);
+ }
+ return NULL;
+}
+
+char *
+estring_disown(estring * e)
+{
+ if (e)
+ {
+ char *r = e->str;
+
+ free(e);
+ return r;
+ }
+ return NULL;
+}
+
+char *
+estring_free(estring * e, int release_payload)
+{ /* glib compat */
+ if (release_payload)
+ {
+ estring_dst(e);
+ return NULL;
+ }
+ return estring_disown(e);
+}
+
+int
+estring_truncate(estring * e, int size)
+{
+ if (!e || (size < 0))
+ return ECORE_CONFIG_ERR_FAIL;
+ if (e->used <= size)
+ return e->used;
+ e->str[size] = '\0';
+ e->used = size;
+ return size;
+}
+
+int
+estring_printf(estring * e, const char *fmt, ...)
+{
+ int need;
+ va_list ap;
+ char *p;
+
+ if (!e)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ if (!(e->str))
+ {
+ if (!(e->str = (char *)malloc(e->alloc = 512)))
+ return ECORE_CONFIG_ERR_OOM;
+ }
+
+ retry:
+ va_start(ap, fmt);
+ need = vsnprintf(e->str, e->alloc, fmt, ap);
+ va_end(ap);
+
+ if ((need >= e->alloc) || (need < 0))
+ {
+ if (need < 0)
+ need = 2 * e->alloc;
+ else
+ need++;
+ if (!(p = (char *)realloc(e->str, need)))
+ {
+ free(e->str);
+ e->alloc = e->used = 0;
+ return ECORE_CONFIG_ERR_OOM;
+ }
+ e->alloc = need;
+ e->str = p;
+ goto retry;
+ }
+
+ return e->used = need;
+}
+
+int
+estring_appendf(estring * e, const char *fmt, ...)
+{
+ int need;
+ va_list ap;
+ char *p;
+
+ if (!e)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ if (!e->str)
+ {
+ e->used = e->alloc = 0;
+ if (!(e->str = (char *)malloc(e->alloc = 512)))
+ return ECORE_CONFIG_ERR_OOM;
+ }
+
+ retry:
+ va_start(ap, fmt);
+ need = vsnprintf(e->str + e->used, e->alloc - e->used, fmt, ap);
+ va_end(ap);
+
+ if ((need >= (e->alloc - e->used)) || (need < 0))
+ {
+ if (need < 0)
+ need = 2 * e->alloc;
+ else
+ need++;
+ need += e->used;
+ need += (CHUNKLEN - (need % CHUNKLEN));
+
+ if (!(p = (char *)realloc(e->str, need)))
+ {
+ free(e->str);
+ e->alloc = e->used = 0;
+ return ECORE_CONFIG_ERR_OOM;
+ }
+ e->alloc = need;
+ e->str = p;
+ goto retry;
+ }
+
+ return e->used += need;
+}
+
+int
+esprintf(char **result, const char *fmt, ...)
+{
+ int need, have;
+ va_list ap;
+ char *n;
+
+ if (!result)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ if (!(n = (char *)malloc(have = 512)))
+ return ECORE_CONFIG_ERR_OOM;
+
+ retry:
+ va_start(ap, fmt);
+ need = vsnprintf(n, have, fmt, ap);
+ va_end(ap);
+
+ if ((need >= have) || (need < 0))
+ {
+ char *p;
+
+ if (need < 0)
+ need = 2 * have;
+ else
+ need++;
+ if (!(p = (char *)realloc(n, need)))
+ {
+ free(n);
+ return ECORE_CONFIG_ERR_OOM;
+ }
+ have = need;
+ n = p;
+ goto retry;
+ }
+
+ if (*result)
+ free(*result);
+ *result = n;
+
+ return need;
+}
+
+#if 0
+int
+ejoin(char **result, char *delim, ...)
+{
+ int dl, cl, ret = ECORE_CONFIG_ERR_SUCC;
+ va_list ap;
+ char *e, *n;
+
+ if (!result)
+ return ECORE_CONFIG_ERR_FAIL;
+ if (!delim)
+ delim = "";
+ dl = strlen(delim);
+
+ va_start(ap, delim);
+ cl = -dl;
+ while ((e = va_arg(ap, char *)))
+ cl += strlen(e) + dl;
+
+ va_end(ap);
+
+ if (cl <= 0)
+ {
+ if (!(n = strdup("")))
+ ret = ECORE_CONFIG_ERR_OOM;
+ }
+ else if (!(n = malloc(cl + 1)))
+ ret = ECORE_CONFIG_ERR_OOM;
+ else
+ {
+ char *p = n;
+
+ va_start(ap, delim);
+ while ((e = va_arg(ap, char *)))
+ {
+ if (dl && (p != n))
+ {
+ strcpy(p, delim);
+ p += dl;
+ }
+ strcpy(p, e);
+ p += strlen(p);
+ }
+ va_end(ap);
+ }
+
+ if (*result)
+ free(*result);
+ *result = n;
+
+ return ret;
+}
+
+int
+ecat(char **result, ...)
+{
+ int cl, ret = ECORE_CONFIG_ERR_SUCC;
+ va_list ap;
+ char *e, *n;
+
+ if (!result)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ va_start(ap, result);
+ cl = 0;
+ while ((e = va_arg(ap, char *)))
+ cl += strlen(e);
+
+ va_end(ap);
+
+ if (cl <= 0)
+ {
+ if (!(n = strdup("")))
+ ret = ECORE_CONFIG_ERR_OOM;
+ }
+ else if (!(n = malloc(cl + 1)))
+ ret = ECORE_CONFIG_ERR_OOM;
+ else
+ {
+ char *p = n;
+
+ va_start(ap, result);
+ while ((e = va_arg(ap, char *)))
+ {
+ strcpy(p, e);
+ p += strlen(p);
+ }
+ va_end(ap);
+ }
+
+ if (*result)
+ free(*result);
+ *result = n;
+
+ return ret;
+}
+#endif
+
+/*****************************************************************************/
diff --git a/ecore/src/lib/ecore_config/ecore_config_util.h b/ecore/src/lib/ecore_config/ecore_config_util.h
new file mode 100644
index 0000000..eff279e
--- /dev/null
+++ b/ecore/src/lib/ecore_config/ecore_config_util.h
@@ -0,0 +1,63 @@
+#define TIMER_STOP 0
+#define TIMER_CONT 1
+
+typedef struct _estring
+{
+ char *str;
+ int alloc, used;
+} estring;
+
+typedef struct _eslist
+{
+ void *payload;
+ struct _eslist *next;
+} eslist;
+
+int parse_line(char *, char **, char **, char **, char **);
+char *unit_size(char *size);
+
+/*unsigned long now(long delay);*/
+void qsrt(void *a[], void *data, int lo, int hi,
+ int (*compare) (const void *, const void *,
+ const void *));
+int dlmulti(const char *name, const char *file, int flag, void **libr,
+ const char *fmt, ...);
+
+typedef void (*hash_walker) (char *key, void *value, void *data);
+
+void *hash_table_new(void (*freekey), void (*freeval));
+void *hash_table_fetch(void *hashtable, char *key);
+int hash_table_insert(void *hashtable, char *key, void *value);
+int hash_table_replace(void *hashtable, char *key, void *value);
+int hash_table_remove(void *hashtable, char *key);
+int hash_table_dst(void *hashtable);
+int hash_table_walk(void *hashtable, hash_walker fun,
+ void *data);
+
+int eslist_free(eslist **);
+int eslist_next(eslist **);
+
+#define ESLIST_NEXT(e) (e=e->next)
+void *eslist_payload(eslist **);
+
+#define ESLIST_PAYLOAD(e) ((e)->payload)
+int eslist_prepend(eslist **, void *);
+int eslist_append(eslist **, void *);
+
+estring *estring_new(int size);
+estring *estring_dst(estring * e);
+char *estring_disown(estring * e);
+char *estring_free(estring * e, int release_payload); /* glib compat */
+int estring_printf(estring * e, const char *fmt, ...);
+int estring_appendf(estring * e, const char *fmt, ...);
+int estring_truncate(estring * e, int size);
+
+#define ESTRING_GET_CSTRING(a) ((a)->str)
+
+int esprintf(char **result, const char *fmt, ...);
+int ejoin(char **result, const char *delim, ...);
+int ecat(char **result, ...);
+
+unsigned long timeout_add(unsigned int f, int (*fun) (void *),
+ void *data);
+int timeout_remove(unsigned long handle);
diff --git a/ecore/src/lib/ecore_dbus/.cvsignore b/ecore/src/lib/ecore_dbus/.cvsignore
new file mode 100644
index 0000000..33d062e
--- /dev/null
+++ b/ecore/src/lib/ecore_dbus/.cvsignore
@@ -0,0 +1,7 @@
+.deps
+.libs
+Ecore_Con.h
+Makefile
+Makefile.in
+*.lo
+libecore_dbus.la
diff --git a/ecore/src/lib/ecore_dbus/CVS/Entries b/ecore/src/lib/ecore_dbus/CVS/Entries
new file mode 100644
index 0000000..c6fd67d
--- /dev/null
+++ b/ecore/src/lib/ecore_dbus/CVS/Entries
@@ -0,0 +1,6 @@
+/.cvsignore/1.2/Mon Jun 6 09:41:44 2005//THEAD
+/Ecore_DBus.h/1.2/Fri Jun 10 02:41:37 2005//THEAD
+/Makefile.am/1.3/Fri Apr 29 09:45:12 2005//THEAD
+/ecore_dbus.c/1.3/Fri Jun 10 02:41:37 2005//THEAD
+/ecore_dbus_private.h/1.1/Fri Apr 29 05:29:29 2005//THEAD
+D
diff --git a/ecore/src/lib/ecore_dbus/CVS/Repository b/ecore/src/lib/ecore_dbus/CVS/Repository
new file mode 100644
index 0000000..a763d9e
--- /dev/null
+++ b/ecore/src/lib/ecore_dbus/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/lib/ecore_dbus
diff --git a/ecore/src/lib/ecore_dbus/CVS/Root b/ecore/src/lib/ecore_dbus/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/lib/ecore_dbus/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/lib/ecore_dbus/CVS/Tag b/ecore/src/lib/ecore_dbus/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/lib/ecore_dbus/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/lib/ecore_dbus/Ecore_DBus.h b/ecore/src/lib/ecore_dbus/Ecore_DBus.h
new file mode 100644
index 0000000..3087a20
--- /dev/null
+++ b/ecore/src/lib/ecore_dbus/Ecore_DBus.h
@@ -0,0 +1,209 @@
+#ifndef _ECORE_DBUS_H
+#define _ECORE_DBUS_H
+#endif
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef WIN32
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef GCC_HASCLASSVISIBILITY
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef struct _Ecore_DBus_Server Ecore_DBus_Server;
+ typedef struct _Ecore_DBus_Client Ecore_DBus_Client;
+ typedef struct _Ecore_DBus_Event_Server_Add Ecore_DBus_Event_Server_Add;
+ typedef struct _Ecore_DBus_Event_Server_Del Ecore_DBus_Event_Server_Del;
+ typedef struct _Ecore_DBus_Event_Server_Data Ecore_DBus_Event_Server_Data;
+ typedef struct _Ecore_DBus_Message Ecore_DBus_Message;
+ typedef struct _Ecore_DBus_Message_Field Ecore_DBus_Message_Field;
+ typedef struct _Ecore_DBus_Auth Ecore_DBus_Auth;
+ typedef unsigned char* (*Ecore_DBus_Auth_Transaction)(void*);
+
+ typedef enum _Ecore_DBus_Type
+ {
+ ECORE_DBUS_BUS_SESSION,
+ ECORE_DBUS_BUS_SYSTEM,
+ ECORE_DBUS_BUS_ACTIVATION
+ } Ecore_DBus_Type;
+
+ typedef enum _Ecore_DBus_Message_Type
+ {
+ ECORE_DBUS_MESSAGE_TYPE_INVALID,
+ ECORE_DBUS_MESSAGE_TYPE_METHOD_CALL,
+ ECORE_DBUS_MESSAGE_TYPE_METHOD_RETURN,
+ ECORE_DBUS_MESSAGE_TYPE_ERROR,
+ ECORE_DBUS_MESSAGE_TYPE_SIGNAL
+ } Ecore_DBus_Message_Type;
+
+ /* message data types */
+ typedef enum _Ecore_DBus_Data_Type
+ {
+ ECORE_DBUS_DATA_TYPE_INVALID = ((int) '\0'),
+ ECORE_DBUS_DATA_TYPE_NIL = ((int) '\0'),
+ ECORE_DBUS_DATA_TYPE_BYTE = ((int) 'y'),
+ ECORE_DBUS_DATA_TYPE_BOOLEAN = ((int) 'b'), /* 0,1 */
+ ECORE_DBUS_DATA_TYPE_INT32 = ((int) 'i'),
+ ECORE_DBUS_DATA_TYPE_UINT32 =((int) 'u'),
+ ECORE_DBUS_DATA_TYPE_INT64 = ((int) 'x'),
+ ECORE_DBUS_DATA_TYPE_UINT64 = ((int) 't'),
+ ECORE_DBUS_DATA_TYPE_DOUBLE = ((int) 'd'),
+ ECORE_DBUS_DATA_TYPE_STRING = ((int) 's'),
+ ECORE_DBUS_DATA_TYPE_CUSTOM = ((int) 'c'),
+ ECORE_DBUS_DATA_TYPE_ARRAY =((int) 'a'),
+ ECORE_DBUS_DATA_TYPE_DICT = ((int) 'm'),
+ ECORE_DBUS_DATA_TYPE_OBJECT_PATH = ((int) 'o')
+ } Ecore_DBus_Data_Type;
+
+ typedef enum _Ecore_DBus_Message_Header_Field
+ {
+ ECORE_DBUS_HEADER_FIELD_INVALID,
+ ECORE_DBUS_HEADER_FIELD_PATH,
+ ECORE_DBUS_HEADER_FIELD_INTERFACE,
+ ECORE_DBUS_HEADER_FIELD_MEMBER,
+ ECORE_DBUS_HEADER_FIELD_ERROR_NAME,
+ ECORE_DBUS_HEADER_FIELD_REPLY_SERIAL,
+ ECORE_DBUS_HEADER_FIELD_DESTINATION,
+ ECORE_DBUS_HEADER_FIELD_SENDER,
+ ECORE_DBUS_HEADER_FIELD_SIGNATURE
+ } Ecore_DBus_Message_Header_Field;
+
+ typedef enum _Ecore_DBus_Auth_Type
+ {
+ ECORE_DBUS_AUTH_TYPE_EXTERNAL,
+ ECORE_DBUS_AUTH_MAGIC_COOKIE,
+ ECORE_DBUS_AUTH_TYPE_DBUS_COOKIE_SHA1,
+ ECORE_DBUS_AUTH_TYPE_KERBEROS_V4,
+ ECORE_DBUS_AUTH_TYPE_SKEY
+ } Ecore_DBus_Auth_Type;
+
+ struct _Ecore_DBus_Auth
+ {
+ char *name;
+ unsigned int num_transactions;
+ Ecore_DBus_Auth_Transaction transactions[5];
+ };
+
+ struct _Ecore_DBus_Event_Server_Add
+ {
+ Ecore_DBus_Server *server;
+ };
+
+ struct _Ecore_DBus_Event_Server_Del
+ {
+ Ecore_DBus_Server *server;
+ };
+
+ struct _Ecore_DBus_Message_Field
+ {
+ Ecore_List __list_data;
+ Ecore_DBus_Data_Type type;
+ unsigned int offset;
+ unsigned int count; /* number of elements, usefull for structs, arrays, dicts */
+ unsigned int hfield; /* if the field is a header field, we need the type of it */
+ };
+
+ struct _Ecore_DBus_Message
+ {
+ /* header fields */
+ unsigned char byte_order;
+ unsigned char type;
+ unsigned char flags;
+ unsigned char protocol;
+ unsigned long hlength;
+ unsigned long blength;
+ unsigned long serial;
+
+ Ecore_DBus_Server *ref_server;
+
+ unsigned char *header;
+ unsigned int hpos;
+ Ecore_DBus_Message_Field *header_fields;
+ unsigned char *body;
+ unsigned int bpos;
+ Ecore_DBus_Message_Field *body_fields;
+ unsigned char *signature;
+ };
+
+ extern int ECORE_DBUS_EVENT_SERVER_ADD;
+ extern int ECORE_DBUS_EVENT_SERVER_DATA;
+
+ /* Message byte order */
+#define DBUS_LITTLE_ENDIAN ('l') /* LSB first */
+#define DBUS_BIG_ENDIAN ('B') /* MSB first */
+
+ /* Protocol version */
+#define DBUS_MAJOR_PROTOCOL_VERSION 0
+
+
+ /* Max length in bytes of a service or interface or member name */
+#define DBUS_MAXIMUM_NAME_LENGTH 256
+
+ /* Max length of a match rule string */
+#define DBUS_MAXIMUM_MATCH_RULE_LENGTH 1024
+
+
+ /* Header flags */
+#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED 0x1
+#define DBUS_HEADER_FLAG_AUTO_ACTIVATION 0x2
+
+
+#define DBUS_HEADER_FIELD_LAST DBUS_HEADER_FIELD_SIGNATURE
+
+ /* Services */
+#define DBUS_SERVICE_ORG_FREEDESKTOP_DBUS "org.freedesktop.DBus"
+
+ /* Paths */
+#define DBUS_PATH_ORG_FREEDESKTOP_DBUS "/org/freedesktop/DBus"
+#define DBUS_PATH_ORG_FREEDESKTOP_LOCAL "/org/freedesktop/Local"
+
+ /* Interfaces, these #define don't do much other than
+ * * catch typos at compile time
+ * */
+#define DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS "org.freedesktop.DBus"
+#define DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE "org.freedesktop.Introspectable"
+
+ /* This is a special interface whose methods can only be invoked
+ * by the local implementation (messages from remote apps aren't
+ * allowed to specify this interface).
+ */
+#define DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL "org.freedesktop.Local"
+ /* Service owner flags */
+#define DBUS_SERVICE_FLAG_PROHIBIT_REPLACEMENT 0x1
+#define DBUS_SERVICE_FLAG_REPLACE_EXISTING 0x2
+
+ /* Service replies */
+#define DBUS_SERVICE_REPLY_PRIMARY_OWNER 0x1
+#define DBUS_SERVICE_REPLY_IN_QUEUE 0x2
+#define DBUS_SERVICE_REPLY_SERVICE_EXISTS 0x4
+#define DBUS_SERVICE_REPLY_ALREADY_OWNER 0x8
+
+ /* Activation replies */
+#define DBUS_ACTIVATION_REPLY_ACTIVATED 0x0
+#define DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE 0x1
+
+ /* connection */
+ EAPI int ecore_dbus_init(void);
+ EAPI Ecore_DBus_Server* ecore_dbus_server_connect(Ecore_DBus_Type compl_type, char *name, int port, const void *data);
+ /* message */
+ EAPI unsigned int ecore_dbus_message_new_method_call(Ecore_DBus_Server *svr,char *service,char *path,char *interface,char *method,char *fmt, ...);
+ EAPI void ecore_dbus_message_print(Ecore_DBus_Message *msg);
+ EAPI void * ecore_dbus_get_header_field(Ecore_DBus_Message *,Ecore_DBus_Message_Field *, Ecore_DBus_Message_Header_Field);
+ EAPI void * ecore_dbus_get_body_field(Ecore_DBus_Message *,Ecore_DBus_Message_Field *, unsigned int);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/ecore/src/lib/ecore_dbus/Makefile.am b/ecore/src/lib/ecore_dbus/Makefile.am
new file mode 100644
index 0000000..3758ca7
--- /dev/null
+++ b/ecore/src/lib/ecore_dbus/Makefile.am
@@ -0,0 +1,39 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_con \
+-I$(top_builddir)/src/lib/ecore_dbus \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_con \
+-I$(top_srcdir)/src/lib/ecore_dbus \
+@SSL_CFLAGS@
+
+libecore_dbus_la_LDFLAGS = -version-info 1:0:0 \
+-L$(top_builddir)/src/lib/ecore/.libs \
+-L$(top_builddir)/src/lib/ecore_con/.libs
+
+if BUILD_ECORE_DBUS
+
+lib_LTLIBRARIES = libecore_dbus.la
+include_HEADERS = \
+Ecore_DBus.h
+
+libecore_dbus_la_SOURCES = \
+ecore_dbus.c \
+ecore_dbus_private.h
+
+libecore_dbus_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_con/libecore_con.la \
+@SSL_LIBS@
+
+libecore_dbus_la_DEPENDENCIES = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_con/libecore_con.la
+
+endif
+
+EXTRA_DIST = \
+ecore_dbus.c \
+ecore_dbus_private.h
diff --git a/ecore/src/lib/ecore_dbus/ecore_dbus.c b/ecore/src/lib/ecore_dbus/ecore_dbus.c
new file mode 100644
index 0000000..6f2e1a6
--- /dev/null
+++ b/ecore/src/lib/ecore_dbus/ecore_dbus.c
@@ -0,0 +1,1235 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdarg.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_Con.h"
+#include "Ecore_DBus.h"
+#include "ecore_dbus_private.h"
+
+/********************************************************************************/
+/* About */
+/********************************************************************************/
+/* Author: Jorge Luis Zapata */
+/* Version: 0.2.1 */
+/********************************************************************************/
+/* Todo */
+/********************************************************************************/
+/* free allocated data */
+/* make other authentication mechanisms besides external */
+/********************************************************************************/
+/* Changelog */
+/********************************************************************************/
+/* 0.0 usable interface */
+/* 0.1 change dbus spec version (0.11): */
+/* different header format */
+/* new type signature */
+/* header length = 8 byte multiple */
+/* paddings value must be null */
+/* body need not to end in a 8 byte boundary */
+/* new data type: variant,signature,dict */
+/* ecore_oldlist cant join two lists so is difficult to handle compound */
+/* data types (variant,struct,dict,array) in a stack way */
+/* 0.2 change again the spec version (0.8) */
+/* i realized that the first version was correct, when i read the spec */
+/* for ecore_dbus 0.1 i was reading a previous version :( */
+/* put again the data type byte in each marshaled data */
+/* */
+/* 29-03-05 */
+/* 0.2.1 some segfault fixes, new tests */
+
+static int ecore_dbus_server_send(Ecore_DBus_Server * svr,
+ char *command, int length);
+Ecore_Oldlist *_ecore_dbus_message_print_field(Ecore_Oldlist * l,
+ unsigned char *buf);
+void _ecore_dbus_message_print_raw(unsigned char *msg,
+ unsigned int msg_len);
+
+/**********************/
+/* ecore dbus message */
+/**********************/
+
+#define BODY_LEN 64
+#define HEADER_LEN 16
+
+/* length functions */
+/********************/
+/* all of these increase the length */
+void
+_ecore_dbus_message_increase_lengthz(unsigned char **buf,
+ unsigned int old_length, unsigned int size)
+{
+ *buf = realloc(*buf, old_length + size);
+ memset(*buf + old_length, 0, size);
+}
+
+void
+_ecore_dbus_message_increase_length(unsigned char **buf,
+ unsigned int new_length)
+{
+ *buf = realloc(*buf, new_length);
+}
+
+/* padding functions */
+/*********************/
+/* all of these increase the length */
+void
+_ecore_dbus_message_4byte_padding(unsigned char **buf, unsigned int *old_length)
+{
+ unsigned int padding;
+
+ padding = *old_length % 4;
+ if (padding != 0)
+ {
+ padding = 4 - padding;
+ _ecore_dbus_message_increase_lengthz(buf, *old_length, padding);
+ }
+ *old_length += padding;
+}
+void
+_ecore_dbus_message_8byte_padding(unsigned char **buf, unsigned int *old_length)
+{
+ unsigned int padding;
+
+ padding = *old_length % 8;
+ if (padding != 0)
+ {
+ padding = 8 - padding;
+ _ecore_dbus_message_increase_lengthz(buf, *old_length, padding);
+ }
+ *old_length += padding;
+}
+
+void
+_ecore_dbus_message_skip_8byte_padding(unsigned int *old_length)
+{
+ unsigned int padding;
+
+ padding = *old_length % 8;
+ if (padding != 0)
+ *old_length += 8 - padding;
+ return;
+}
+
+void
+_ecore_dbus_message_skip_4byte_padding(unsigned int *old_length) /* DONE */
+{
+ unsigned int padding;
+
+ padding = *old_length % 4;
+ if (padding != 0)
+ *old_length += 4 - padding;
+ return;
+}
+
+/* appending/reading functions */
+/*******************************/
+/* non of these increase the length */
+void
+_ecore_dbus_message_append_nbytes(unsigned char *buf, unsigned char *data,
+ unsigned int data_length)
+{
+ memcpy(buf, data, data_length);
+}
+
+void
+_ecore_dbus_message_append_byte(unsigned char *buf, unsigned char c)
+{
+ *buf = c;
+}
+
+void
+_ecore_dbus_message_append_uint32(unsigned char *buf, unsigned long int i)
+{
+ unsigned char *c;
+
+ c = (unsigned char *)&i;
+ *(buf + 0) = *(c + 0);
+ *(buf + 1) = *(c + 1);
+ *(buf + 2) = *(c + 2);
+ *(buf + 3) = *(c + 3);
+}
+
+unsigned long
+_ecore_dbus_message_read_uint32(unsigned char *buf)
+{
+ return *(unsigned long *)buf;
+}
+
+unsigned char
+_ecore_dbus_message_read_byte(unsigned char *buf)
+{
+ return *(unsigned char *)buf;
+}
+
+/* field functions */
+/*******************/
+
+/* memory allocation */
+/**********************/
+Ecore_DBus_Message *
+_ecore_dbus_message_new(Ecore_DBus_Server * svr)
+{
+ Ecore_DBus_Message *msg = calloc(1, sizeof(Ecore_DBus_Message));
+
+ msg->ref_server = svr;
+ msg->body_fields = NULL;
+ msg->header_fields = NULL;
+ msg->hpos = 0;
+ msg->bpos = 0;
+ msg->header = NULL;
+ msg->body = NULL;
+ msg->hlength = 0;
+ msg->blength = 0;
+ return msg;
+}
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_new_field(Ecore_DBus_Data_Type type, unsigned int offset)
+{
+ Ecore_DBus_Message_Field *f;
+
+ f = malloc(sizeof(Ecore_DBus_Message_Field));
+ f->offset = offset;
+ f->type = type;
+ f->count = 0;
+ return f;
+}
+
+void
+_ecore_dbus_message_free(void *data, void *ev)
+{
+ Ecore_DBus_Message *msg = ev;
+ Ecore_Oldlist *l = (Ecore_Oldlist *) msg->body_fields;
+ Ecore_Oldlist *next;
+
+ while (l)
+ {
+ next = l->next;
+ free(l);
+ l = next;
+ }
+ l = (Ecore_Oldlist *) msg->header_fields;
+ while (l)
+ {
+ next = l->next;
+ free(l);
+ l = next;
+ }
+ free(msg->header);
+ free(msg->body);
+ free(msg);
+}
+
+/* signature functions */
+/***********************/
+
+/* marshal functions */
+/*********************/
+
+/* cambiar todos los *msg por char** asi se podra cambiar el puntero sin problemas */
+/* agregarle el parametro de signature por si se quiere q agregue una variable al signature */
+/* y pasarle la lista de campos por si pone el argumento en la lista del header o del body */
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_marshal_byte(unsigned char **buf, unsigned int *old_length,
+ unsigned char c)
+{
+ Ecore_DBus_Message_Field *f;
+
+ _ecore_dbus_message_increase_length(buf, *old_length + 1); // increase the length + 1, old_length changed
+ _ecore_dbus_message_append_byte(*buf + *old_length, ECORE_DBUS_DATA_TYPE_BYTE); // append the data type
+ *old_length += 1;
+ _ecore_dbus_message_increase_length(buf, *old_length + 1); // increase the length + 1, old_length changed
+ _ecore_dbus_message_append_byte(*buf + *old_length, c); // append c at cur_length
+ f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_BYTE, *old_length); // create field
+ *old_length += 1;
+ return f;
+}
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_marshal_uint32(unsigned char **buf,
+ unsigned int *old_length,
+ unsigned long int i)
+{
+ Ecore_DBus_Message_Field *f;
+
+ _ecore_dbus_message_increase_length(buf, *old_length + 1); // increase the length + 1, old_length changed
+ _ecore_dbus_message_append_byte(*buf + *old_length, ECORE_DBUS_DATA_TYPE_UINT32); // append the data type
+ *old_length += 1;
+ _ecore_dbus_message_4byte_padding(buf, old_length);
+ _ecore_dbus_message_increase_length(buf, *old_length + 4);
+ _ecore_dbus_message_append_uint32(*buf + *old_length, i);
+ f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_UINT32, *old_length);
+ *old_length += 4;
+ return f;
+}
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_marshal_path(unsigned char **buf, unsigned int *old_length,
+ unsigned char *str)
+{
+ int str_len;
+ Ecore_DBus_Message_Field *f;
+
+ _ecore_dbus_message_increase_length(buf, *old_length + 1); // increase the length + 1, old_length changed
+ _ecore_dbus_message_append_byte(*buf + *old_length, ECORE_DBUS_DATA_TYPE_OBJECT_PATH); // append the data type
+ *old_length += 1;
+
+ str_len = strlen((char *)str);
+ _ecore_dbus_message_4byte_padding(buf, old_length);
+ _ecore_dbus_message_increase_length(buf, *old_length + 4);
+ f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_OBJECT_PATH,
+ *old_length);
+ _ecore_dbus_message_append_uint32(*buf + *old_length, str_len);
+ *old_length += 4;
+ _ecore_dbus_message_increase_length(buf, *old_length + str_len + 1); // for the \n
+ _ecore_dbus_message_append_nbytes(*buf + *old_length, str, str_len + 1); // append all the string including \n
+ *old_length += str_len + 1;
+
+ return f;
+}
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_marshal_string(unsigned char **buf,
+ unsigned int *old_length, unsigned char *str)
+{
+ int str_len;
+ Ecore_DBus_Message_Field *f;
+
+ _ecore_dbus_message_increase_length(buf, *old_length + 1); // increase the length + 1, new_length changed
+ _ecore_dbus_message_append_byte(*buf + *old_length, ECORE_DBUS_DATA_TYPE_STRING); // append the data type
+ *old_length += 1; // old_length = new_length
+
+ str_len = strlen((char *)str);
+ _ecore_dbus_message_4byte_padding(buf, old_length);
+ _ecore_dbus_message_increase_length(buf, *old_length + 4);
+ f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_STRING, *old_length);
+ _ecore_dbus_message_append_uint32(*buf + *old_length, str_len);
+ *old_length += 4;
+ _ecore_dbus_message_increase_length(buf, *old_length + str_len + 1); // for the \n
+ _ecore_dbus_message_append_nbytes(*buf + *old_length, str, str_len + 1); // append all the string including \n
+ *old_length += str_len + 1;
+ return f;
+}
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_marshal_array(unsigned char **msg, unsigned int *old_length)
+{
+ Ecore_DBus_Message_Field *f;
+
+ _ecore_dbus_message_8byte_padding(msg, old_length);
+ _ecore_dbus_message_increase_length(msg, *old_length + 4); // for the array length value
+ f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_ARRAY, *old_length);
+ *old_length += 4;
+ return f;
+}
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_marshal_data(unsigned char **buf, unsigned int *old_length,
+ Ecore_DBus_Data_Type type, void *data)
+{
+ Ecore_DBus_Message_Field *f = NULL;
+
+ switch (type)
+ {
+ case ECORE_DBUS_DATA_TYPE_UINT32:
+ f = _ecore_dbus_message_marshal_uint32(buf, old_length,
+ *(unsigned long *)data);
+ break;
+ case ECORE_DBUS_DATA_TYPE_STRING:
+ f = _ecore_dbus_message_marshal_string(buf, old_length,
+ (unsigned char *)data);
+ break;
+ case ECORE_DBUS_DATA_TYPE_OBJECT_PATH:
+ f = _ecore_dbus_message_marshal_path(buf, old_length,
+ (unsigned char *)data);
+ break;
+ case ECORE_DBUS_DATA_TYPE_INVALID:
+ case ECORE_DBUS_DATA_TYPE_BYTE:
+ case ECORE_DBUS_DATA_TYPE_BOOLEAN:
+ case ECORE_DBUS_DATA_TYPE_INT32:
+ case ECORE_DBUS_DATA_TYPE_INT64:
+ case ECORE_DBUS_DATA_TYPE_UINT64:
+ case ECORE_DBUS_DATA_TYPE_DOUBLE:
+ case ECORE_DBUS_DATA_TYPE_CUSTOM:
+ case ECORE_DBUS_DATA_TYPE_ARRAY:
+ case ECORE_DBUS_DATA_TYPE_DICT:
+ default:
+ printf("[ecore_dbus] unknown/unhandled data type %c\n", type);
+ break;
+ }
+ return f;
+}
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_marshal_custom_header(unsigned char **buf,
+ unsigned int *old_length,
+ unsigned int code,
+ Ecore_DBus_Data_Type type, void *data)
+{
+ Ecore_DBus_Message_Field *f;
+
+ _ecore_dbus_message_increase_length(buf, *old_length + 1); // increase the length + 1, old_length changed
+ _ecore_dbus_message_append_byte(*buf + *old_length, code); // append header field name at cur_length
+ *old_length += 1;
+ f = _ecore_dbus_message_marshal_data(buf, old_length, type, data); // marshal header field data
+ f->hfield = code;
+ return f;
+}
+
+/* unmarshal functions */
+/***********************/
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_unmarshal_int32(unsigned char *buf,
+ unsigned int *old_length)
+{
+ Ecore_DBus_Message_Field *f;
+
+ _ecore_dbus_message_skip_4byte_padding(old_length);
+ f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_INT32, *old_length);
+ *old_length += 4;
+ return f;
+
+}
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_unmarshal_uint32(unsigned char *buf,
+ unsigned int *old_length)
+{
+ Ecore_DBus_Message_Field *f;
+
+ _ecore_dbus_message_skip_4byte_padding(old_length);
+ f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_UINT32, *old_length);
+ *old_length += 4;
+ return f;
+
+}
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_unmarshal_string(unsigned char *buf,
+ unsigned int *old_length)
+{
+ Ecore_DBus_Message_Field *f;
+ unsigned long str_len;
+
+ _ecore_dbus_message_skip_4byte_padding(old_length);
+ f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_STRING, *old_length);
+ str_len = _ecore_dbus_message_read_uint32(buf + *old_length);
+ *old_length += 4;
+ *old_length += str_len + 1;
+ return f;
+}
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_unmarshal_path(unsigned char *buf, unsigned int *old_length)
+{
+ Ecore_DBus_Message_Field *f;
+ unsigned long str_len;
+
+ _ecore_dbus_message_skip_4byte_padding(old_length);
+ f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_OBJECT_PATH,
+ *old_length);
+ str_len = _ecore_dbus_message_read_uint32(buf + *old_length);
+ *old_length += 4;
+ *old_length += str_len + 1;
+ return f;
+}
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_unmarshal_data(unsigned char *buf, unsigned int *old_length)
+{
+ Ecore_DBus_Message_Field *f = NULL;
+ unsigned char type = _ecore_dbus_message_read_byte(buf + *old_length);
+
+ *old_length += 1;
+ switch (type)
+ {
+ case ECORE_DBUS_DATA_TYPE_INT32:
+ f = _ecore_dbus_message_unmarshal_int32(buf, old_length);
+ break;
+ case ECORE_DBUS_DATA_TYPE_UINT32:
+ f = _ecore_dbus_message_unmarshal_uint32(buf, old_length);
+ break;
+ case ECORE_DBUS_DATA_TYPE_STRING:
+ f = _ecore_dbus_message_unmarshal_string(buf, old_length);
+ break;
+ case ECORE_DBUS_DATA_TYPE_OBJECT_PATH:
+ f = _ecore_dbus_message_unmarshal_path(buf, old_length);
+ break;
+ case ECORE_DBUS_DATA_TYPE_BYTE:
+ case ECORE_DBUS_DATA_TYPE_BOOLEAN:
+ case ECORE_DBUS_DATA_TYPE_INT64:
+ case ECORE_DBUS_DATA_TYPE_UINT64:
+ case ECORE_DBUS_DATA_TYPE_DOUBLE:
+ case ECORE_DBUS_DATA_TYPE_CUSTOM:
+ case ECORE_DBUS_DATA_TYPE_ARRAY:
+ case ECORE_DBUS_DATA_TYPE_DICT:
+ case ECORE_DBUS_DATA_TYPE_INVALID:
+ default:
+ printf("[ecore_dbus] unknown/unhandled data type %c\n", type);
+ break;
+ }
+ return f;
+}
+
+Ecore_DBus_Message_Field *
+_ecore_dbus_message_unmarshal_custom_header(unsigned char *buf,
+ unsigned int *old_length)
+{
+ Ecore_DBus_Message_Field *f;
+ unsigned int code;
+
+ code = _ecore_dbus_message_read_byte(buf + *old_length); // get header field name at cur_length
+ *old_length += 1;
+ f = _ecore_dbus_message_unmarshal_data(buf, old_length); // unmarshal header field data
+ f->hfield = code;
+ return f;
+}
+
+Ecore_DBus_Message *
+_ecore_dbus_message_unmarshal(Ecore_DBus_Server * svr, unsigned char *message)
+{
+ Ecore_DBus_Message_Field *f;
+
+ /* init */
+ /********/
+ Ecore_DBus_Message *msg = _ecore_dbus_message_new(svr);
+
+ printf("[ecore_dbus] unmarshaling\n");
+ /* message header */
+ /******************/
+ /* common fields */
+ msg->byte_order = *(message + 0);
+ msg->type = *(message + 1);
+ msg->flags = *(message + 2);
+ msg->protocol = *(message + 3);
+ msg->hlength = *(unsigned long *)(message + 4);
+ msg->blength = *(unsigned long *)(message + 8);
+ msg->serial = *(unsigned long *)(message + 12);
+ if (msg->type == ECORE_DBUS_MESSAGE_TYPE_INVALID)
+ {
+ printf("[ecore_dbus] message type invalid\n");
+ return NULL;
+ }
+ /* memcpy the header part */
+ _ecore_dbus_message_increase_length(&msg->header, msg->hlength);
+ _ecore_dbus_message_append_nbytes(msg->header, message, msg->hlength);
+ msg->hpos += 16;
+ /* custom fields */
+ while ((msg->hpos + 8 - (msg->hpos % 8)) < msg->hlength)
+ {
+ f = _ecore_dbus_message_unmarshal_custom_header(message, &msg->hpos);
+ msg->header_fields = _ecore_list_append(msg->header_fields, f);
+ }
+ msg->hpos = msg->hlength;
+ /* message body */
+ /****************/
+ message += msg->hlength;
+ _ecore_dbus_message_increase_length(&msg->body, msg->blength);
+ _ecore_dbus_message_append_nbytes(msg->body, message, msg->blength);
+ while (msg->bpos < msg->blength)
+ {
+ f = _ecore_dbus_message_unmarshal_data(message, &msg->bpos);
+ msg->body_fields = _ecore_list_append(msg->body_fields, f);
+
+ }
+ return msg;
+}
+
+/* header functions */
+/********************/
+void
+_ecore_dbus_message_common_header(Ecore_DBus_Message * msg, int type, int flags)
+{
+ _ecore_dbus_message_increase_lengthz(&msg->header, msg->hpos, 16); // the body,header length arent filled only alloc
+ msg->header[0] = msg->byte_order = 'l'; // endiannes (1)
+ msg->header[1] = msg->type = (char)type; // type (1)
+ msg->header[2] = msg->flags = 0x0; // flags (1) 0x1 = no reply expected, 0x2 auto activiation
+ msg->header[3] = msg->protocol = 0x0; // protocol (1)
+ msg->ref_server->cnt_msg++; // autoincrement the client_serial (0 is invalid)
+ *(msg->header + 12) = msg->serial = msg->ref_server->cnt_msg;
+ msg->hpos = 16;
+}
+
+void *
+_ecore_dbus_get_field(unsigned char *buf, Ecore_DBus_Message_Field * f)
+{
+ switch (f->type)
+ {
+ case ECORE_DBUS_DATA_TYPE_INT32:
+ case ECORE_DBUS_DATA_TYPE_UINT32:
+ case ECORE_DBUS_DATA_TYPE_BYTE:
+ case ECORE_DBUS_DATA_TYPE_BOOLEAN:
+ case ECORE_DBUS_DATA_TYPE_INT64:
+ case ECORE_DBUS_DATA_TYPE_UINT64:
+ case ECORE_DBUS_DATA_TYPE_DOUBLE:
+ return buf + f->offset;
+ break;
+ case ECORE_DBUS_DATA_TYPE_STRING:
+ case ECORE_DBUS_DATA_TYPE_OBJECT_PATH:
+ return buf + f->offset + 4;
+ break;
+ case ECORE_DBUS_DATA_TYPE_CUSTOM:
+ case ECORE_DBUS_DATA_TYPE_ARRAY:
+ case ECORE_DBUS_DATA_TYPE_DICT:
+ case ECORE_DBUS_DATA_TYPE_INVALID:
+ default:
+ printf("[ecore_dbus] unknown/unhandled data type %c\n", f->type);
+ break;
+
+ }
+ return NULL;
+}
+
+void *
+ecore_dbus_get_body_field(Ecore_DBus_Message * m, Ecore_DBus_Message_Field * mf,
+ unsigned int pos)
+{
+ Ecore_Oldlist *l, *list;
+
+ list = (Ecore_Oldlist *) mf;
+ unsigned int i = 0;
+
+ for (l = list; l; l = l->next)
+ {
+ if (i == pos)
+ return _ecore_dbus_get_field(m->body,
+ (Ecore_DBus_Message_Field *) l);
+ i++;
+ }
+ return NULL;
+}
+
+void *
+ecore_dbus_get_header_field(Ecore_DBus_Message * m,
+ Ecore_DBus_Message_Field * mf,
+ Ecore_DBus_Message_Header_Field hft)
+{
+ Ecore_Oldlist *l, *list;
+
+ list = (Ecore_Oldlist *) mf;
+ for (l = list; l; l = l->next)
+ if (((Ecore_DBus_Message_Field *) l)->hfield == hft)
+ return _ecore_dbus_get_field(m->header,
+ (Ecore_DBus_Message_Field *) l);
+ return NULL;
+}
+
+/* printing functions */
+/**********************/
+Ecore_Oldlist *
+_ecore_dbus_message_print_field(Ecore_Oldlist * l, unsigned char *buf)
+{
+ int i;
+ Ecore_DBus_Message_Field *f;
+
+ f = (Ecore_DBus_Message_Field *) l;
+ switch (f->type)
+ {
+ case ECORE_DBUS_DATA_TYPE_BYTE:
+ printf
+ ("[ecore_dbus] field BYTE : value offset = %d value = %d\n",
+ f->offset, (char)*(buf + f->offset));
+ break;
+ case ECORE_DBUS_DATA_TYPE_OBJECT_PATH:
+ printf
+ ("[ecore_dbus] field PATH : value offset = %d length = %d value = %s\n",
+ f->offset, *(buf + f->offset), (buf + f->offset + 4));
+ break;
+ case ECORE_DBUS_DATA_TYPE_STRING:
+ printf
+ ("[ecore_dbus] field STRING : value offset = %d length = %d value = %s\n",
+ f->offset, *(buf + f->offset), (buf + f->offset + 4));
+ break;
+ case ECORE_DBUS_DATA_TYPE_INT32:
+ printf
+ ("[ecore_dbus] field INT32 : value offset = %d value = %ld\n",
+ f->offset, (long int)*(buf + f->offset));
+ break;
+ case ECORE_DBUS_DATA_TYPE_UINT32:
+ printf
+ ("[ecore_dbus] field UINT32 : value offset = %d value = %lu\n",
+ f->offset, (unsigned long int)*(buf + f->offset));
+ break;
+ case ECORE_DBUS_DATA_TYPE_ARRAY:
+ printf
+ ("[ecore_dbus] field ARRAY : value offset = %d length = %lu elements = %u\n",
+ f->offset, *(unsigned long int *)(buf + f->offset), f->count);
+ printf("[ecore_dbus] * ARRAY elements begin *\n");
+ l = l->next;
+ for (i = 0; i < f->count; i++)
+ l = _ecore_dbus_message_print_field(l, buf);
+ printf("[ecore_dbus] * ARRAY elements end *\n");
+ return l;
+ break;
+ default:
+ printf("[ecore_dbus] field !UNKNOWN! : %c\n", f->type);
+ break;
+ }
+ return l->next;
+}
+
+Ecore_Oldlist *
+_ecore_dbus_message_print_header_field(Ecore_Oldlist * l, unsigned char *buf)
+{
+ static const char *header_fields[] =
+ { "INVALID", "PATH", "INTERFACE", "MEMBER", "ERROR_NAME", "REPLY_SERIAL",
+"DESTINATION", "SERIAL", "SIGNATURE" };
+ Ecore_DBus_Message_Field *f;
+
+ f = (Ecore_DBus_Message_Field *) l;
+ printf("[ecore_dbus] header field %s ", header_fields[f->hfield]);
+ l = _ecore_dbus_message_print_field(l, buf);
+ return l;
+}
+
+void
+_ecore_dbus_message_print_fields(Ecore_DBus_Message_Field * f)
+{
+ int i = 0;
+ Ecore_Oldlist *l;
+
+ l = (Ecore_Oldlist *) f;
+ while (l)
+ {
+ printf("%d\n", i);
+ l = l->next;
+ i++;
+ }
+
+}
+
+void
+_ecore_dbus_message_print_raw(unsigned char *msg, unsigned int msg_len)
+{
+ int i;
+
+ printf("[ecore_dbus] raw message:\n");
+ for (i = 0; i < msg_len; i++)
+ {
+ if (msg[i] == 0)
+ printf(",");
+ else if (msg[i] < 21)
+ printf("*");
+ else
+ printf("%c", msg[i]);
+ }
+ printf("\n");
+ printf("[ecore_dbus] end raw message\n");
+}
+
+void
+ecore_dbus_message_print(Ecore_DBus_Message * msg)
+{
+ Ecore_Oldlist *list;
+ static const char *msg_type[] =
+ { "INVALID", "METHOD_CALL", "METHOD_RETURN", "ERROR", "SIGNAL" };
+ printf("[ecore_dbus] per field message:\n");
+ printf("[ecore_dbus] header fields:\n");
+ /* header common fields */
+ printf("[ecore_dbus] header endianess : %c\n", msg->byte_order);
+ printf("[ecore_dbus] header type : %s\n", msg_type[msg->type]);
+ printf("[ecore_dbus] header flags : %c\n", msg->flags + 48);
+ printf("[ecore_dbus] header protocol : %c\n", msg->protocol + 48);
+ printf("[ecore_dbus] header hlength : %u\n",
+ *(unsigned int *)(msg->header + 4));
+ printf("[ecore_dbus] header blength : %lu\n", msg->blength);
+ printf("[ecore_dbus] header serial : %lu\n", msg->serial);
+
+ /* header custom fields */
+ list = (Ecore_Oldlist *) msg->header_fields;
+ while (list)
+ {
+ list = _ecore_dbus_message_print_header_field(list, msg->header);
+ }
+ /* body fields */
+ printf("[ecore_dbus] body fields:\n");
+ list = (Ecore_Oldlist *) msg->body_fields;
+ while (list)
+ {
+ list = _ecore_dbus_message_print_field(list, msg->body);
+ }
+ printf("[ecore_dbus] end per field message\n");
+
+}
+
+/* message type functions */
+/**************************/
+/* podria retornar el id del mensaje, para asi saber las respuestas y poderlas referenciar en el cliente */
+/* la idea aca seria hacer una funcion q llame metodos remotos, or ej: ("org.freedesktop.DBus", "/org/freedesktop/DBus","org.freedesktop.DBus","AddMatch","%s",rule);*/
+/* el parsing de los argumentos a la funcion podrian ser similares al printf s = string, d = int, f = float etc */
+
+unsigned int
+ecore_dbus_message_new_method_call(Ecore_DBus_Server * svr, char *service,
+ char *path, char *interface, char *method,
+ char *fmt, ...)
+{
+ va_list ap;
+
+ Ecore_DBus_Message_Field *f;
+
+ /* init message */
+ Ecore_DBus_Message *msg = _ecore_dbus_message_new(svr);
+
+ /* common header */
+ _ecore_dbus_message_common_header(msg, ECORE_DBUS_MESSAGE_TYPE_METHOD_CALL,
+ 0);
+ /* custom header */
+ if (path)
+ {
+ f = _ecore_dbus_message_marshal_custom_header(&msg->header, &msg->hpos,
+ 1,
+ ECORE_DBUS_DATA_TYPE_OBJECT_PATH,
+ path);
+ msg->header_fields = _ecore_list_append(msg->header_fields, f);
+ }
+
+ if (interface)
+ {
+ f = _ecore_dbus_message_marshal_custom_header(&msg->header, &msg->hpos,
+ 2,
+ ECORE_DBUS_DATA_TYPE_STRING,
+ interface);
+ msg->header_fields = _ecore_list_append(msg->header_fields, f);
+ }
+ if (method)
+ {
+ f = _ecore_dbus_message_marshal_custom_header(&msg->header, &msg->hpos,
+ 3,
+ ECORE_DBUS_DATA_TYPE_STRING,
+ method);
+ msg->header_fields = _ecore_list_append(msg->header_fields, f);
+ }
+ if (service)
+ {
+ f = _ecore_dbus_message_marshal_custom_header(&msg->header, &msg->hpos,
+ 6,
+ ECORE_DBUS_DATA_TYPE_STRING,
+ service);
+ msg->header_fields = _ecore_list_append(msg->header_fields, f);
+ }
+ if (fmt)
+ {
+ f = _ecore_dbus_message_marshal_custom_header(&msg->header, &msg->hpos,
+ 8,
+ ECORE_DBUS_DATA_TYPE_STRING,
+ fmt);
+ msg->header_fields = _ecore_list_append(msg->header_fields, f);
+ }
+ _ecore_dbus_message_8byte_padding(&msg->header, &msg->hpos);
+ /* header length */
+ *(msg->header + 4) = msg->hlength = msg->hpos;
+ /* message body */
+ va_start(ap, fmt);
+ while (*fmt)
+ {
+ switch (*fmt)
+ {
+ case ECORE_DBUS_DATA_TYPE_UINT32:
+ f = _ecore_dbus_message_marshal_uint32(&msg->body, &msg->bpos,
+ va_arg(ap, unsigned long));
+ msg->body_fields = _ecore_list_append(msg->body_fields, f);
+ break;
+ case ECORE_DBUS_DATA_TYPE_STRING:
+ f = _ecore_dbus_message_marshal_string(&msg->body, &msg->bpos,
+ (unsigned char *)va_arg(ap, char *));
+ msg->body_fields = _ecore_list_append(msg->body_fields, f);
+ break;
+ case ECORE_DBUS_DATA_TYPE_OBJECT_PATH:
+ f = _ecore_dbus_message_marshal_path(&msg->body, &msg->bpos,
+ (unsigned char *)va_arg(ap, char *));
+ msg->body_fields = _ecore_list_append(msg->body_fields, f);
+ break;
+ case ECORE_DBUS_DATA_TYPE_INVALID:
+ case ECORE_DBUS_DATA_TYPE_BYTE:
+ case ECORE_DBUS_DATA_TYPE_BOOLEAN:
+ case ECORE_DBUS_DATA_TYPE_INT32:
+ case ECORE_DBUS_DATA_TYPE_INT64:
+ case ECORE_DBUS_DATA_TYPE_UINT64:
+ case ECORE_DBUS_DATA_TYPE_DOUBLE:
+ case ECORE_DBUS_DATA_TYPE_CUSTOM:
+ case ECORE_DBUS_DATA_TYPE_ARRAY:
+ case ECORE_DBUS_DATA_TYPE_DICT:
+ default:
+ printf("[ecore_dbus] unknown/unhandled data type %c\n", *fmt);
+ break;
+ }
+ *fmt++;
+ }
+ va_end(ap);
+ *(unsigned int *)(msg->header + 8) = msg->blength = msg->bpos;
+ /* show message */
+ /*ecore_dbus_message_print(msg);
+ * _ecore_dbus_message_print_raw(msg->header,msg->hlength);
+ * _ecore_dbus_message_print_raw(msg->body,msg->blength); */
+ /* send message */
+ ecore_dbus_server_send(svr, (char *)msg->header, msg->hlength);
+ if (msg->body)
+ ecore_dbus_server_send(svr, (char *)msg->body, msg->blength);
+ /* free data TODO free the list of fields */
+ /*for(i=0; i<8; i++)
+ * free(msg->header_fields[i]);
+ * free(msg->buf);
+ * free(msg); */
+ return msg->serial;
+}
+
+/*******************/
+/* ecore_dbus_auth */
+/*******************/
+
+static char *_ecore_dbus_getuid(void);
+static char *_ecore_dbus_hex_encode(char *src_str);
+
+/* helper functions */
+static char *
+_ecore_dbus_getuid(void)
+{
+ /* this calculation is from comp.lang.c faq */
+#define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1) /* +1 for '-' */
+ int len;
+ char *uid;
+ char *tmp;
+
+ tmp = (char *)malloc(MAX_LONG_LEN);
+ len = snprintf(tmp, MAX_LONG_LEN, "%ld", (long) getuid());
+ uid = (char *)malloc(len + 1);
+ uid = memcpy(uid, tmp, len);
+ uid[len] = '\0';
+
+ free(tmp);
+ return uid;
+}
+
+/* encodes a string into a string of hex values */
+/* each byte is two hex digits */
+static char *
+_ecore_dbus_hex_encode(char *src_str)
+{
+ const char hexdigits[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+ char *enc_str;
+ char *p;
+ char *end;
+ int len;
+ int i = 0;
+
+ len = strlen(src_str);
+ p = src_str;
+ end = p + len;
+
+ enc_str = malloc(2 * len + 1);
+ while (p != end)
+ {
+ enc_str[i] = hexdigits[(*p >> 4)];
+ i++;
+ enc_str[i] = hexdigits[(*p & 0x0f)];
+ i++;
+ p++;
+ }
+ enc_str[i] = '\0';
+ return enc_str;
+}
+
+unsigned char *
+_ecore_dbus_auth_external(void *data)
+{
+ char *uid, *enc_uid, *msg;
+
+ uid = _ecore_dbus_getuid();
+ enc_uid = _ecore_dbus_hex_encode(uid);
+ free(uid);
+ msg = malloc(strlen(enc_uid) + 17);
+ sprintf(msg, "AUTH EXTERNAL %s\r\n", enc_uid);
+ free(enc_uid);
+ return (unsigned char *)msg;
+}
+
+/*****************************/
+/* main ecore_dbus functions */
+/*****************************/
+
+int ECORE_DBUS_EVENT_CLIENT_ADD = 0;
+int ECORE_DBUS_EVENT_CLIENT_DEL = 0;
+int ECORE_DBUS_EVENT_SERVER_ADD = 0;
+int ECORE_DBUS_EVENT_SERVER_DEL = 0;
+int ECORE_DBUS_EVENT_CLIENT_DATA = 0;
+int ECORE_DBUS_EVENT_SERVER_DATA = 0;
+
+static const Ecore_DBus_Auth auths[] = {
+ {"EXTERNAL", 1, {_ecore_dbus_auth_external, NULL, NULL, NULL, NULL}},
+ {"MAGIC_COOKIE", 0, {NULL, NULL, NULL, NULL, NULL}},
+ {"DBUS_COOKIE_SHA1", 0, {NULL, NULL, NULL, NULL, NULL}},
+ {"KERBEROS_V4", 0, {NULL, NULL, NULL, NULL, NULL}},
+ {"SKEY", 0, {NULL, NULL, NULL, NULL, NULL}},
+};
+
+static int init_count = 0;
+static Ecore_List *servers = NULL;
+
+static int _ecore_dbus_event_client_add(void *data, int ev_type,
+ void *ev);
+static int _ecore_dbus_event_client_del(void *data, int ev_type,
+ void *ev);
+static int _ecore_dbus_event_server_add(void *data, int ev_type,
+ void *ev);
+static int _ecore_dbus_event_server_del(void *data, int ev_type,
+ void *ev);
+static int _ecore_dbus_event_client_data(void *data, int ev_type,
+ void *ev);
+static int _ecore_dbus_event_server_data(void *data, int ev_type,
+ void *ev);
+/* helpers */
+void _ecore_dbus_message_free(void *data, void *ev);
+
+int
+ecore_dbus_init(void)
+{
+ if (!init_count)
+ ecore_con_init();
+ init_count++;
+ if (!ECORE_DBUS_EVENT_CLIENT_ADD)
+ {
+ ECORE_DBUS_EVENT_CLIENT_ADD = ecore_event_type_new();
+ ECORE_DBUS_EVENT_CLIENT_DEL = ecore_event_type_new();
+ ECORE_DBUS_EVENT_SERVER_ADD = ecore_event_type_new();
+ ECORE_DBUS_EVENT_SERVER_DEL = ecore_event_type_new();
+ ECORE_DBUS_EVENT_CLIENT_DATA = ecore_event_type_new();
+ ECORE_DBUS_EVENT_SERVER_DATA = ecore_event_type_new();
+
+ ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD,
+ _ecore_dbus_event_client_add, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL,
+ _ecore_dbus_event_client_del, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD,
+ _ecore_dbus_event_server_add, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL,
+ _ecore_dbus_event_server_del, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA,
+ _ecore_dbus_event_client_data, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA,
+ _ecore_dbus_event_server_data, NULL);
+ }
+ return init_count;
+}
+
+Ecore_DBus_Server *
+ecore_dbus_server_connect(Ecore_DBus_Type compl_type, char *name, int port,
+ const void *data)
+{
+ /* TODO */
+ /* se tiene q conectar por direccion (unix socket path) */
+ /* o por BUS directo */
+
+ Ecore_DBus_Server *svr;
+ Ecore_DBus_Type type;
+ Ecore_Con_Type extra = 0;
+
+ svr = calloc(1, sizeof(Ecore_DBus_Server));
+ if (!svr)
+ return NULL;
+ type = compl_type;
+ switch (type)
+ {
+ case ECORE_DBUS_BUS_SESSION:
+ svr->server =
+ ecore_con_server_connect(ECORE_CON_LOCAL_USER | extra, name, port,
+ svr);
+ break;
+ case ECORE_DBUS_BUS_SYSTEM:
+ svr->server =
+ ecore_con_server_connect(ECORE_CON_LOCAL_USER | extra, name, port,
+ svr);
+ break;
+
+ default:
+ free(svr);
+ return NULL;
+ }
+ if (!svr->server)
+ {
+ printf("no hay servidor\n");
+ free(svr);
+ return NULL;
+ }
+ svr->authenticated = 0;
+ svr->cnt_msg = 0;
+ svr->auth_type = -1;
+ svr->auth_type_transaction = 0;
+ servers = _ecore_list_append(servers, svr);
+
+ return svr;
+}
+
+int
+ecore_dbus_server_send(Ecore_DBus_Server * svr, char *command, int length)
+{
+ int ret;
+
+ ret = ecore_con_server_send(svr->server, command, length);
+ printf
+ ("[ecore_dbus] ecore_dbus_server: %p ecore_con_server: %p sent %d of %d bytes\n",
+ svr, svr->server, ret, length);
+ return ret;
+}
+
+/* private functions */
+static int
+_ecore_dbus_event_client_add(void *data, int ev_type, void *ev)
+{
+ printf("CLIENT ADDED \n");
+ printf("this line should appear\n");
+ return 1;
+}
+
+static int
+_ecore_dbus_event_client_del(void *data, int ev_type, void *ev)
+{
+ return 0;
+}
+
+static int
+_ecore_dbus_event_server_add(void *data, int ev_type, void *ev)
+{
+
+ Ecore_DBus_Event_Server_Add *e;
+
+ e = ev;
+ if (!_ecore_list_find(servers, ecore_con_server_data_get(e->server)))
+ return 1;
+ {
+ Ecore_DBus_Server *svr;
+
+ svr = ecore_con_server_data_get(e->server);
+ ecore_dbus_server_send(svr, "\0", 1);
+ ecore_dbus_server_send(svr, "AUTH\r\n", 6);
+ printf("[ecore_dbus] begining auth process\n");
+ }
+ return 0;
+}
+
+static int
+_ecore_dbus_event_server_del(void *udata, int ev_type, void *ev)
+{
+ Ecore_Con_Event_Server_Del *e;
+
+ e = ev;
+ if (!_ecore_list_find(servers, ecore_con_server_data_get(e->server)))
+ return 1;
+ {
+ Ecore_DBus_Server *svr;
+
+ svr = ecore_con_server_data_get(e->server);
+ {
+ Ecore_DBus_Event_Server_Del *e2;
+
+ e2 = calloc(1, sizeof(Ecore_DBus_Event_Server_Del));
+ if (e2)
+ {
+ e2->server = svr;
+ ecore_event_add(ECORE_DBUS_EVENT_SERVER_DEL, e2, NULL, NULL);
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+_ecore_dbus_event_client_data(void *udata, int ev_type, void *ev)
+{
+ printf("CLIENT DATA");
+ return 1;
+}
+
+static int
+_ecore_dbus_event_server_data(void *udata, int ev_type, void *ev)
+{
+ Ecore_Con_Event_Server_Data *e;
+
+ e = ev;
+ if (!_ecore_list_find(servers, ecore_con_server_data_get(e->server)))
+ return 1;
+
+ {
+ Ecore_DBus_Server *svr;
+ Ecore_DBus_Event_Server_Add *svr_add;
+
+ svr = ecore_con_server_data_get(e->server);
+
+ /* authentication protocol */
+ /***************************/
+ if (!svr->authenticated)
+ {
+ const Ecore_DBus_Auth *auth;
+ Ecore_DBus_Auth_Transaction trans;
+
+ if (!strncmp(e->data, "OK", 2))
+ {
+ printf("[ecore_dbus] auth type %s successful\n",
+ auths[svr->auth_type].name);
+ ecore_dbus_server_send(svr, "BEGIN\r\n", 7);
+ svr->authenticated = 1;
+ svr_add = malloc(sizeof(Ecore_DBus_Event_Server_Add));
+ svr_add->server = svr;
+ ecore_event_add(ECORE_DBUS_EVENT_SERVER_ADD, svr_add, NULL,
+ NULL);
+ }
+ if (!strncmp(e->data, "DATA", 4))
+ {
+ printf("[ecore_dbus] requering data (unaivable)\n");
+ }
+ if (!strncmp(e->data, "ERROR", 5))
+ {
+ printf("[ecore_dbus] auth process error\n");
+ }
+ if (!strncmp(e->data, "REJECTED", 8))
+ {
+ unsigned char *msg;
+
+ if (svr->auth_type >= 0)
+ printf("[ecore_dbus] auth type %s rejected\n",
+ auths[svr->auth_type].name);
+ svr->auth_type++;
+ auth = &auths[svr->auth_type];
+ trans = auth->transactions[0];
+ printf("[ecore_dbus] auth type %s started\n", auth->name);
+ msg = trans(NULL);
+ ecore_dbus_server_send(svr, (char *)msg, strlen((char *)msg));
+ free(msg);
+
+ }
+ }
+ /* message protocol */
+ /********************/
+ else
+ {
+ Ecore_DBus_Message *msg;
+ unsigned int offset = 0;
+
+ printf("[ecore_dbus] received server data, %d bytes\n", e->size);
+ while (e->size)
+ {
+ msg = _ecore_dbus_message_unmarshal(svr, e->data + offset);
+ if (msg == NULL)
+ break;
+ offset += msg->hlength + msg->blength;
+ e->size -= msg->hlength + msg->blength;
+ printf("[ecore_dbus] dbus message length %lu bytes, still %d\n",
+ msg->hlength + msg->blength, e->size);
+ /*ecore_dbus_message_print(msg); */
+ ecore_event_add(ECORE_DBUS_EVENT_SERVER_DATA, msg,
+ _ecore_dbus_message_free, NULL);
+
+ }
+ }
+ }
+ return 1;
+}
diff --git a/ecore/src/lib/ecore_dbus/ecore_dbus_private.h b/ecore/src/lib/ecore_dbus/ecore_dbus_private.h
new file mode 100644
index 0000000..f9e1a8e
--- /dev/null
+++ b/ecore/src/lib/ecore_dbus/ecore_dbus_private.h
@@ -0,0 +1,56 @@
+#ifndef _ECORE_DBUS_PRIVATE_H
+#define _ECORE_DBUS_PRIVATE_H
+
+struct _Ecore_DBus_Client
+{
+ Ecore_DBus_Client *client;
+};
+
+struct _Ecore_DBus_Server
+{
+ Ecore_List __list_data;
+ Ecore_Con_Server *server;
+ Ecore_DBus_Client *clients;
+ /* unsigned char *buf; */
+ /* int buf_size; */
+ unsigned int cnt_msg;
+ Ecore_List *msg_queue;
+ /* void *data;*/
+ unsigned int authenticated;
+ int auth_type;
+ unsigned int auth_type_transaction;
+};
+
+/* Errors */
+/* WARNING dont change order or ABI breaks. */
+#define DBUS_ERROR_FAILED "org.freedesktop.DBus.Error.Failed"
+#define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory"
+#define DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND "org.freedesktop.DBus.Error.ServiceNotFound"
+#define DBUS_ERROR_SERVICE_DOES_NOT_EXIST "org.freedesktop.DBus.Error.ServiceDoesNotExist"
+#define DBUS_ERROR_SERVICE_HAS_NO_OWNER "org.freedesktop.DBus.Error.ServiceHasNoOwner"
+#define DBUS_ERROR_NO_REPLY "org.freedesktop.DBus.Error.NoReply"
+#define DBUS_ERROR_IO_ERROR "org.freedesktop.DBus.Error.IOError"
+#define DBUS_ERROR_BAD_ADDRESS "org.freedesktop.DBus.Error.BadAddress"
+#define DBUS_ERROR_NOT_SUPPORTED "org.freedesktop.DBus.Error.NotSupported"
+#define DBUS_ERROR_LIMITS_EXCEEDED "org.freedesktop.DBus.Error.LimitsExceeded"
+#define DBUS_ERROR_ACCESS_DENIED "org.freedesktop.DBus.Error.AccessDenied"
+#define DBUS_ERROR_AUTH_FAILED "org.freedesktop.DBus.Error.AuthFailed"
+#define DBUS_ERROR_NO_SERVER "org.freedesktop.DBus.Error.NoServer"
+#define DBUS_ERROR_TIMEOUT "org.freedesktop.DBus.Error.Timeout"
+#define DBUS_ERROR_NO_NETWORK "org.freedesktop.DBus.Error.NoNetwork"
+#define DBUS_ERROR_ADDRESS_IN_USE "org.freedesktop.DBus.Error.AddressInUse"
+#define DBUS_ERROR_DISCONNECTED "org.freedesktop.DBus.Error.Disconnected"
+#define DBUS_ERROR_INVALID_ARGS "org.freedesktop.DBus.Error.InvalidArgs"
+#define DBUS_ERROR_FILE_NOT_FOUND "org.freedesktop.DBus.Error.FileNotFound"
+#define DBUS_ERROR_UNKNOWN_METHOD "org.freedesktop.DBus.Error.UnknownMethod"
+#define DBUS_ERROR_TIMED_OUT "org.freedesktop.DBus.Error.TimedOut"
+#define DBUS_ERROR_MATCH_RULE_NOT_FOUND "org.freedesktop.DBus.Error.MatchRuleNotFound"
+#define DBUS_ERROR_MATCH_RULE_INVALID "org.freedesktop.DBus.Error.MatchRuleInvalid"
+#define DBUS_ERROR_SPAWN_EXEC_FAILED "org.freedesktop.DBus.Error.Spawn.ExecFailed"
+#define DBUS_ERROR_SPAWN_FORK_FAILED "org.freedesktop.DBus.Error.Spawn.ForkFailed"
+#define DBUS_ERROR_SPAWN_CHILD_EXITED "org.freedesktop.DBus.Error.Spawn.ChildExited"
+#define DBUS_ERROR_SPAWN_CHILD_SIGNALED "org.freedesktop.DBus.Error.Spawn.ChildSignaled"
+#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed"
+#define DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN "org.freedesktop.DBus.Error.UnixProcessIdUnknown"
+
+#endif
diff --git a/ecore/src/lib/ecore_evas/.cvsignore b/ecore/src/lib/ecore_evas/.cvsignore
new file mode 100644
index 0000000..0bf42a4
--- /dev/null
+++ b/ecore/src/lib/ecore_evas/.cvsignore
@@ -0,0 +1,10 @@
+.deps
+.libs
+Ecore_Evas.h
+Makefile
+Makefile.in
+ecore_evas.lo
+ecore_evas_fb.lo
+ecore_evas_x.lo
+ecore_evas_buffer.lo
+libecore_evas.la
diff --git a/ecore/src/lib/ecore_evas/CVS/Entries b/ecore/src/lib/ecore_evas/CVS/Entries
new file mode 100644
index 0000000..b0e1a5c
--- /dev/null
+++ b/ecore/src/lib/ecore_evas/CVS/Entries
@@ -0,0 +1,9 @@
+/.cvsignore/1.3/Tue Feb 22 12:42:23 2005//THEAD
+/Ecore_Evas.h/1.11/Thu Jul 7 03:33:17 2005//THEAD
+/Makefile.am/1.11/Thu Mar 10 15:19:38 2005//THEAD
+/ecore_evas.c/1.18/Sat Jan 8 18:40:31 2005//THEAD
+/ecore_evas_private.h/1.12/Sat Jun 25 07:23:38 2005//THEAD
+/ecore_evas_buffer.c/1.5/Mon Jul 25 17:01:56 2005//THEAD
+/ecore_evas_fb.c/1.12/Mon Jul 25 17:01:56 2005//THEAD
+/ecore_evas_x.c/1.50/Mon Jul 25 17:01:56 2005//THEAD
+D
diff --git a/ecore/src/lib/ecore_evas/CVS/Repository b/ecore/src/lib/ecore_evas/CVS/Repository
new file mode 100644
index 0000000..d85de4a
--- /dev/null
+++ b/ecore/src/lib/ecore_evas/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/lib/ecore_evas
diff --git a/ecore/src/lib/ecore_evas/CVS/Root b/ecore/src/lib/ecore_evas/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/lib/ecore_evas/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/lib/ecore_evas/CVS/Tag b/ecore/src/lib/ecore_evas/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/lib/ecore_evas/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/lib/ecore_evas/Ecore_Evas.h b/ecore/src/lib/ecore_evas/Ecore_Evas.h
new file mode 100644
index 0000000..108de52
--- /dev/null
+++ b/ecore/src/lib/ecore_evas/Ecore_Evas.h
@@ -0,0 +1,165 @@
+#ifndef _ECORE_EVAS_H
+#define _ECORE_EVAS_H
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef WIN32
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef GCC_HASCLASSVISIBILITY
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file Ecore_Evas.h
+ * @brief Evas wrapper functions
+ */
+
+/* FIXME:
+ * to do soon:
+ * - iconfication api needs to work
+ * - maximization api nees to work
+ * - document all calls
+ *
+ * later:
+ * - buffer back-end that renders to an evas_image_object ???
+ * - qt back-end ???
+ * - dfb back-end ??? (dfb's threads make this REALLY HARD)
+ */
+
+#include <Evas.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* these are dummy and just tell u what API levels ecore_evas supports - not if
+ * the actual support is compiled in. you need to query for that separately.
+ */
+#define HAVE_ECORE_EVAS_X 1
+#define HAVE_ECORE_EVAS_FB 1
+#define HAVE_ECORE_EVAS_GL 1
+
+typedef enum
+{
+ ECORE_EVAS_ENGINE_SOFTWARE_X11,
+ ECORE_EVAS_ENGINE_SOFTWARE_FB,
+ ECORE_EVAS_ENGINE_GL_X11,
+ ECORE_EVAS_ENGINE_SOFTWARE_BUFFER
+} Ecore_Evas_Engine_Type;
+
+#ifndef _ECORE_X_H
+#define _ECORE_X_WINDOW_PREDEF
+typedef unsigned int Ecore_X_Window;
+#endif
+
+#ifndef _ECORE_EVAS_PRIVATE_H
+/* basic data types */
+typedef void Ecore_Evas;
+#endif
+
+/* module setup/shutdown calls */
+
+EAPI int ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine);
+
+EAPI int ecore_evas_init(void);
+EAPI int ecore_evas_shutdown(void);
+
+/* engine/target specific init calls */
+EAPI Ecore_Evas *ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_evas_software_x11_window_get(Ecore_Evas *ee);
+EAPI Ecore_X_Window ecore_evas_software_x11_subwindow_get(Ecore_Evas *ee);
+EAPI void ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_software_x11_direct_resize_get(Ecore_Evas *ee);
+
+EAPI Ecore_Evas *ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_evas_gl_x11_window_get(Ecore_Evas *ee);
+EAPI Ecore_X_Window ecore_evas_gl_x11_subwindow_get(Ecore_Evas *ee);
+EAPI void ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_gl_x11_direct_resize_get(Ecore_Evas *ee);
+
+EAPI Ecore_Evas *ecore_evas_fb_new(char *disp_name, int rotation, int w, int h);
+
+EAPI Ecore_Evas *ecore_evas_buffer_new(int w, int h);
+EAPI const int *ecore_evas_buffer_pixels_get(Ecore_Evas *ee);
+
+EAPI Evas_Object *ecore_evas_object_image_new(Ecore_Evas *ee_target);
+
+/* generic manipulation calls */
+EAPI void ecore_evas_free(Ecore_Evas *ee);
+EAPI void *ecore_evas_data_get(Ecore_Evas *ee, const char *key);
+EAPI void ecore_evas_data_set(Ecore_Evas *ee, const char *key, const void *data);
+EAPI void ecore_evas_callback_resize_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_move_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_show_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_hide_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_delete_request_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_destroy_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_focus_in_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_focus_out_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_pre_render_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_post_render_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI Evas *ecore_evas_get(Ecore_Evas *ee);
+EAPI void ecore_evas_move(Ecore_Evas *ee, int x, int y);
+EAPI void ecore_evas_resize(Ecore_Evas *ee, int w, int h);
+EAPI void ecore_evas_move_resize(Ecore_Evas *ee, int x, int y, int w, int h);
+EAPI void ecore_evas_geometry_get(Ecore_Evas *ee, int *x, int *y, int *w, int *h);
+EAPI void ecore_evas_rotation_set(Ecore_Evas *ee, int rot);
+EAPI int ecore_evas_rotation_get(Ecore_Evas *ee);
+EAPI void ecore_evas_shaped_set(Ecore_Evas *ee, int shaped);
+EAPI int ecore_evas_shaped_get(Ecore_Evas *ee);
+EAPI void ecore_evas_show(Ecore_Evas *ee);
+EAPI void ecore_evas_hide(Ecore_Evas *ee);
+EAPI int ecore_evas_visibility_get(Ecore_Evas *ee);
+EAPI void ecore_evas_raise(Ecore_Evas *ee);
+EAPI void ecore_evas_lower(Ecore_Evas *ee);
+EAPI void ecore_evas_title_set(Ecore_Evas *ee, const char *t);
+EAPI const char *ecore_evas_title_get(Ecore_Evas *ee);
+EAPI void ecore_evas_name_class_set(Ecore_Evas *ee, const char *n, const char *c);
+EAPI void ecore_evas_name_class_get(Ecore_Evas *ee, const char **n, const char **c);
+EAPI void ecore_evas_size_min_set(Ecore_Evas *ee, int w, int h);
+EAPI void ecore_evas_size_min_get(Ecore_Evas *ee, int *w, int *h);
+EAPI void ecore_evas_size_max_set(Ecore_Evas *ee, int w, int h);
+EAPI void ecore_evas_size_max_get(Ecore_Evas *ee, int *w, int *h);
+EAPI void ecore_evas_size_base_set(Ecore_Evas *ee, int w, int h);
+EAPI void ecore_evas_size_base_get(Ecore_Evas *ee, int *w, int *h);
+EAPI void ecore_evas_size_step_set(Ecore_Evas *ee, int w, int h);
+EAPI void ecore_evas_size_step_get(Ecore_Evas *ee, int *w, int *h);
+EAPI void ecore_evas_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y);
+EAPI void ecore_evas_cursor_get(Ecore_Evas *ee, char **file, int *layer, int *hot_x, int *hot_y);
+EAPI void ecore_evas_layer_set(Ecore_Evas *ee, int layer);
+EAPI int ecore_evas_layer_get(Ecore_Evas *ee);
+EAPI void ecore_evas_focus_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_focus_get(Ecore_Evas *ee);
+EAPI void ecore_evas_iconified_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_iconified_get(Ecore_Evas *ee);
+EAPI void ecore_evas_borderless_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_borderless_get(Ecore_Evas *ee);
+EAPI void ecore_evas_override_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_override_get(Ecore_Evas *ee);
+EAPI void ecore_evas_maximized_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_maximized_get(Ecore_Evas *ee);
+EAPI void ecore_evas_fullscreen_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_fullscreen_get(Ecore_Evas *ee);
+EAPI void ecore_evas_avoid_damage_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_avoid_damage_get(Ecore_Evas *ee);
+EAPI void ecore_evas_withdrawn_set(Ecore_Evas *ee, int withdrawn);
+EAPI int ecore_evas_withdrawn_get(Ecore_Evas *ee);
+EAPI void ecore_evas_sticky_set(Ecore_Evas *ee, int sticky);
+EAPI int ecore_evas_sticky_get(Ecore_Evas *ee);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ecore/src/lib/ecore_evas/Makefile.am b/ecore/src/lib/ecore_evas/Makefile.am
new file mode 100644
index 0000000..a79da95
--- /dev/null
+++ b/ecore/src/lib/ecore_evas/Makefile.am
@@ -0,0 +1,69 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+if BUILD_ECORE_X
+ECORE_X_INC = -I$(top_srcdir)/src/lib/ecore_x
+ECORE_X_LIB = $(top_builddir)/src/lib/ecore_x/libecore_x.la
+ECORE_X_LDF = -L$(top_builddir)/src/lib/ecore_x/.libs
+else
+ECORE_X_INC =
+ECORE_X_LIB =
+ECORE_X_LDF =
+endif
+
+if BUILD_ECORE_FB
+ECORE_FB_INC = -I$(top_srcdir)/src/lib/ecore_fb
+ECORE_FB_LIB = $(top_builddir)/src/lib/ecore_fb/libecore_fb.la
+ECORE_FB_LDF = -L$(top_builddir)/src/lib/ecore_fb/.libs
+else
+ECORE_FB_INC =
+ECORE_FB_LIB =
+ECORE_FB_LDF =
+endif
+
+INCLUDES = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_evas \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_evas \
+$(ECORE_X_INC) \
+$(ECORE_FB_INC) \
+@evas_cflags@
+
+libecore_evas_la_LDFLAGS = -version-info 1:0:0 \
+$(ECORE_X_LDF) \
+$(ECORE_FB_LDF) \
+-L$(top_builddir)/src/lib/ecore/.libs
+
+if BUILD_ECORE_EVAS
+
+lib_LTLIBRARIES = libecore_evas.la
+include_HEADERS = \
+Ecore_Evas.h
+
+libecore_evas_la_SOURCES = \
+ecore_evas.c \
+ecore_evas_private.h \
+ecore_evas_x.c \
+ecore_evas_fb.c \
+ecore_evas_buffer.c
+
+libecore_evas_la_LIBADD = \
+$(ECORE_X_LIB) \
+$(ECORE_FB_LIB) \
+$(top_builddir)/src/lib/ecore/libecore.la \
+@evas_libs@
+
+libecore_evas_la_DEPENDENCIES = \
+$(ECORE_X_LIB) \
+$(ECORE_FB_LIB) \
+$(top_builddir)/src/lib/ecore/libecore.la
+
+endif
+
+EXTRA_DIST = \
+ecore_evas.c \
+ecore_evas_private.h \
+ecore_evas_x.c \
+ecore_evas_fb.c \
+ecore_evas_buffer.c
+
diff --git a/ecore/src/lib/ecore_evas/ecore_evas.c b/ecore/src/lib/ecore_evas/ecore_evas.c
new file mode 100644
index 0000000..b6e57cd
--- /dev/null
+++ b/ecore/src/lib/ecore_evas/ecore_evas.c
@@ -0,0 +1,1605 @@
+#include "config.h"
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+static int _ecore_evas_init_count = 0;
+
+/**
+ * Query if a particular renginering engine target has support
+ * @param engine The engine to check support for
+ * @return 1 if the particualr engine is supported, 0 if it is not
+ *
+ * Query if engine @param engine is supported by ecore_evas. 1 is returned if
+ * it is, and 0 is returned if it is not supported.
+ */
+int
+ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine)
+{
+ switch (engine)
+ {
+ case ECORE_EVAS_ENGINE_SOFTWARE_X11:
+#ifdef BUILD_ECORE_X
+ return 1;
+#else
+ return 0;
+#endif
+ break;
+ case ECORE_EVAS_ENGINE_SOFTWARE_FB:
+#ifdef BUILD_ECORE_EVAS_FB
+ return 1;
+#else
+ return 0;
+#endif
+ break;
+ case ECORE_EVAS_ENGINE_GL_X11:
+#ifdef BUILD_ECORE_EVAS_GL
+ return 1;
+#else
+ return 0;
+#endif
+ break;
+ case ECORE_EVAS_ENGINE_SOFTWARE_BUFFER:
+#ifdef BUILD_ECORE_EVAS_BUFFER
+ return 1;
+#else
+ return 0;
+#endif
+ break;
+ default:
+ return 0;
+ break;
+ };
+ return 0;
+}
+
+/**
+ * Init the Evas system.
+ * @return greater than 0 on success, 0 on failure
+ *
+ * Set up the Evas wrapper system.
+ */
+int
+ecore_evas_init(void)
+{
+ if (_ecore_evas_init_count == 0)
+ evas_init ();
+ return ++_ecore_evas_init_count;
+}
+
+/**
+ * Shut down the Evas system.
+ * @return 0 if ecore evas is fully shut down, or > 0 if it still needs to be shut down
+ *
+ * This closes the Evas system down.
+ */
+int
+ecore_evas_shutdown(void)
+{
+ _ecore_evas_init_count--;
+ if (_ecore_evas_init_count == 0)
+ {
+#ifdef BUILD_ECORE_X
+ while (_ecore_evas_x_shutdown());
+#endif
+#ifdef BUILD_ECORE_EVAS_FB
+ while (_ecore_evas_fb_shutdown());
+#endif
+#ifdef BUILD_ECORE_EVAS_BUFFER
+ while (_ecore_evas_buffer_shutdown());
+#endif
+ evas_shutdown();
+ }
+ if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+ return _ecore_evas_init_count;
+}
+
+/**
+ * Free an Ecore_Evas
+ * @param ee The Ecore_Evas to free
+ *
+ * This frees up any memory used by the Ecore_Evas.
+ */
+void
+ecore_evas_free(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_free");
+ return;
+ }
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_NONE);
+ while (ee->sub_ecore_evas)
+ {
+ ecore_evas_free(ee->sub_ecore_evas->data);
+ }
+ if (ee->data) evas_hash_free(ee->data);
+ if (ee->driver) free(ee->driver);
+ if (ee->name) free(ee->name);
+ if (ee->prop.title) free(ee->prop.title);
+ if (ee->prop.name) free(ee->prop.name);
+ if (ee->prop.clas) free(ee->prop.clas);
+ if (ee->prop.cursor.file) free(ee->prop.cursor.file);
+ if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
+ if (ee->evas) evas_free(ee->evas);
+ ee->data = NULL;
+ ee->driver = NULL;
+ ee->name = NULL;
+ ee->prop.title = NULL;
+ ee->prop.name = NULL;
+ ee->prop.clas = NULL;
+ ee->prop.cursor.file = NULL;
+ ee->prop.cursor.object = NULL;
+ ee->evas = NULL;
+ if (ee->engine.func->fn_free) ee->engine.func->fn_free(ee);
+ free(ee);
+}
+
+void *
+ecore_evas_data_get(Ecore_Evas *ee, const char *key)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_data_get");
+ return NULL;
+ }
+
+ if (!key) return NULL;
+
+ return evas_hash_find(ee->data, key);
+}
+
+void
+ecore_evas_data_set(Ecore_Evas *ee, const char *key, const void *data)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_data_set");
+ return;
+ }
+
+ if (!key) return;
+
+ ee->data = evas_hash_del(ee->data, key, NULL);
+ ee->data = evas_hash_add(ee->data, key, data);
+}
+
+#define IFC(_ee, _fn) if (_ee->engine.func->_fn) {_ee->engine.func->_fn
+#define IFE return;}
+
+/**
+ * Set a callback for Ecore_Evas resize events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee is resized.
+ */
+void
+ecore_evas_callback_resize_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_resize_set");
+ return;
+ }
+ IFC(ee, fn_callback_resize_set) (ee, func);
+ IFE;
+ ee->func.fn_resize = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas move events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee is moved.
+ */
+void
+ecore_evas_callback_move_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_move_set");
+ return;
+ }
+ IFC(ee, fn_callback_move_set) (ee, func);
+ IFE;
+ ee->func.fn_move = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas show events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee is shown.
+ */
+void
+ecore_evas_callback_show_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_show_set");
+ return;
+ }
+ IFC(ee, fn_callback_show_set) (ee, func);
+ IFE;
+ ee->func.fn_show = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas hide events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee is hidden.
+ */
+void
+ecore_evas_callback_hide_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_hide_set");
+ return;
+ }
+ IFC(ee, fn_callback_hide_set) (ee, func);
+ IFE;
+ ee->func.fn_hide = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas delete request events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee gets a delete request.
+ */
+void
+ecore_evas_callback_delete_request_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_delete_request_set");
+ return;
+ }
+ IFC(ee, fn_callback_delete_request_set) (ee, func);
+ IFE;
+ ee->func.fn_delete_request = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas destroy events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee is destroyed.
+ */
+void
+ecore_evas_callback_destroy_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_destroy_set");
+ return;
+ }
+ IFC(ee, fn_callback_destroy_set) (ee, func);
+ IFE;
+ ee->func.fn_destroy = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas focus in events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee gets focus.
+ */
+void
+ecore_evas_callback_focus_in_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_focus_in_set");
+ return;
+ }
+ IFC(ee, fn_callback_focus_in_set) (ee, func);
+ IFE;
+ ee->func.fn_focus_in = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas focus out events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee loses focus.
+ */
+void
+ecore_evas_callback_focus_out_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_focus_out_set");
+ return;
+ }
+ IFC(ee, fn_callback_focus_out_set) (ee, func);
+ IFE;
+ ee->func.fn_focus_out = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas mouse in events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever the mouse enters @p ee.
+ */
+void
+ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_mouse_in_set");
+ return;
+ }
+ IFC(ee, fn_callback_mouse_in_set) (ee, func);
+ IFE;
+ ee->func.fn_mouse_in = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas mouse out events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever the mouse leaves @p ee.
+ */
+void
+ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_mouse_out_set");
+ return;
+ }
+ IFC(ee, fn_callback_mouse_out_set) (ee, func);
+ IFE;
+ ee->func.fn_mouse_out = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas mouse pre render events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called just before the evas in @p ee is rendered.
+ */
+void
+ecore_evas_callback_pre_render_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_pre_render_set");
+ return;
+ }
+ IFC(ee, fn_callback_pre_render_set) (ee, func);
+ IFE;
+ ee->func.fn_pre_render = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas mouse post render events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called just after the evas in @p ee is rendered.
+ */
+void
+ecore_evas_callback_post_render_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_post_render_set");
+ return;
+ }
+ IFC(ee, fn_callback_post_render_set) (ee, func);
+ IFE;
+ ee->func.fn_post_render = func;
+}
+
+/**
+ * Get an Ecore_Evas's Evas
+ * @param ee The Ecore_Evas whose Evas you wish to get
+ * @return The Evas wrapped by @p ee
+ *
+ * This function returns the Evas contained within @p ee.
+ */
+Evas *
+ecore_evas_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_get");
+ return NULL;
+ }
+ return ee->evas;
+}
+
+/**
+ * Move an Ecore_Evas
+ * @param ee The Ecore_Evas to move
+ * @param x The x coordinate to move to
+ * @param y The y coordinate to move to
+ *
+ * This moves @p ee to the screen coordinates (@p x, @p y)
+ */
+void
+ecore_evas_move(Ecore_Evas *ee, int x, int y)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_move");
+ return;
+ }
+ IFC(ee, fn_move) (ee, x, y);
+ IFE;
+}
+
+/**
+ * Resize an Ecore_Evas
+ * @param ee The Ecore_Evas to move
+ * @param w The w coordinate to resize to
+ * @param h The h coordinate to resize to
+ *
+ * This resizes @p ee to @p w x @p h
+ */
+void
+ecore_evas_resize(Ecore_Evas *ee, int w, int h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_resize");
+ return;
+ }
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ IFC(ee, fn_resize) (ee, h, w);
+ IFE;
+ }
+ else
+ {
+ IFC(ee, fn_resize) (ee, w, h);
+ IFE;
+ }
+}
+
+/**
+ * Resize an Ecore_Evas
+ * @param ee The Ecore_Evas to move
+ * @param x The x coordinate to move to
+ * @param y The y coordinate to move to
+ * @param w The w coordinate to resize to
+ * @param h The h coordinate to resize to
+ *
+ * This moves @p ee to the screen coordinates (@p x, @p y) and resizes
+ * it to @p w x @p h.
+ *
+ */
+void
+ecore_evas_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_move_resize");
+ return;
+ }
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ IFC(ee, fn_move_resize) (ee, x, y, h, w);
+ IFE;
+ }
+ else
+ {
+ IFC(ee, fn_move_resize) (ee, x, y, w, h);
+ IFE;
+ }
+}
+
+/**
+ * Get the geometry of an Ecore_Evas
+ * @param ee The Ecore_Evas whose geometry y
+ * @param x A pointer to an int to place the x coordinate in
+ * @param y A pointer to an int to place the y coordinate in
+ * @param w A pointer to an int to place the w size in
+ * @param h A pointer to an int to place the h size in
+ *
+ * This function takes four pointers to (already allocated) ints, and places
+ * the geometry of @p ee in them.
+ *
+ * @code
+ * int x, y, w, h;
+ * ecore_evas_geometry_get(ee, &x, &y, &w, &h);
+ * @endcode
+ *
+ */
+void
+ecore_evas_geometry_get(Ecore_Evas *ee, int *x, int *y, int *w, int *h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_geometry_get");
+ return;
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ if (x) *x = ee->x;
+ if (y) *y = ee->y;
+ if (w) *w = ee->h;
+ if (h) *h = ee->w;
+ }
+ else
+ {
+ if (x) *x = ee->x;
+ if (y) *y = ee->y;
+ if (w) *w = ee->w;
+ if (h) *h = ee->h;
+ }
+}
+
+/**
+ * Set the rotation of an Ecore_Evas' window
+ *
+ * @param ee The Ecore_Evas
+ * @param rot the angle (in degrees) of rotation.
+ *
+ * The allowed values of @p rot depend on the engine being used. Most only
+ * allow multiples of 90.
+ */
+void
+ecore_evas_rotation_set(Ecore_Evas *ee, int rot)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_rotation_set");
+ return;
+ }
+ rot = rot % 360;
+ while (rot < 0) rot += 360;
+ while (rot >= 360) rot -= 360;
+ IFC(ee, fn_rotation_set) (ee, rot);
+ IFE;
+}
+
+/**
+ * Set the rotation of an Ecore_Evas' window
+ *
+ * @param ee The Ecore_Evas
+ * @return the angle (in degrees) of rotation.
+ *
+ */
+int
+ecore_evas_rotation_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_rotation_get");
+ return 0;
+ }
+ return ee->rotation;
+}
+
+/**
+ * Set whether an Ecore_Evas is shaped or not.
+ * @param ee The Ecore_Evas to shape
+ * @param shaped 1 to shape, 0 to not
+ *
+ * This function allows one to make an Ecore_Evas shaped to the contents of the
+ * evas. If @p shaped is 1, @p ee will be transparent in parts of the evas that
+ * contain no objects. If @p shaped is 0, then @p ee will be rectangular, and
+ * and parts with no data will show random framebuffer artifacting. For
+ * non-shaped Ecore_Evases, it is recommend to cover the entire evas with a
+ * background object.
+ */
+void
+ecore_evas_shaped_set(Ecore_Evas *ee, int shaped)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_shaped_set");
+ return;
+ }
+ IFC(ee, fn_shaped_set) (ee, shaped);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas is shaped or not.
+ * @param ee The Ecore_Evas to query.
+ * @return 1 if shaped, 0 if not.
+ *
+ * This function returns 1 if @p ee is shaped, and 0 if not.
+ */
+int
+ecore_evas_shaped_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_shaped_get");
+ return 0;
+ }
+ return ee->shaped ? 1:0;
+}
+
+/**
+ * Show an Ecore_Evas' window
+ * @param ee The Ecore_Evas to show.
+ *
+ * This function makes @p ee visible.
+ */
+void
+ecore_evas_show(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_show");
+ return;
+ }
+ IFC(ee, fn_show) (ee);
+ IFE;
+}
+
+/**
+ * Hide an Ecore_Evas' window
+ * @param ee The Ecore_Evas to show.
+ *
+ * This function makes @p ee hidden.
+ */
+void
+ecore_evas_hide(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_hide");
+ return;
+ }
+ IFC(ee, fn_hide) (ee);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is visible or not.
+ * @param ee The Ecore_Evas to query.
+ * @return 1 if visible, 0 if not.
+ *
+ * This function queries @p ee and returns 1 if it is visible, and 0 if not.
+ */
+int
+ecore_evas_visibility_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_visibility_get");
+ return 0;
+ }
+ return ee->visible ? 1:0;
+}
+
+/**
+ * Raise and Ecore_Evas' window.
+ * @param ee The Ecore_Evas to raise.
+ *
+ * This functions raises the Ecore_Evas to the front.
+ */
+void
+ecore_evas_raise(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_raise");
+ return;
+ }
+ IFC(ee, fn_raise) (ee);
+ IFE;
+}
+
+/**
+ * Lower an Ecore_Evas' window.
+ * @param ee The Ecore_Evas to raise.
+ *
+ * This functions lowers the Ecore_Evas to the back.
+ */
+void
+ecore_evas_lower(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_lower");
+ return;
+ }
+ IFC(ee, fn_lower) (ee);
+ IFE;
+}
+
+/**
+ * Set the title of an Ecore_Evas' window
+ * @param ee The Ecore_Evas whose title you wish to set.
+ * @param t The title
+ *
+ * This function sets the title of @p ee to @p t.
+ */
+void
+ecore_evas_title_set(Ecore_Evas *ee, const char *t)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_title_set");
+ return;
+ }
+ IFC(ee, fn_title_set) (ee, t);
+ IFE;
+}
+
+/**
+ * Get the title of an Ecore_Evas' window
+ * @param ee The Ecore_Evas whose title you wish to get.
+ * @return The title of @p ee.
+ *
+ * This function returns the title of @p ee.
+ */
+const char *
+ecore_evas_title_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_title_get");
+ return NULL;
+ }
+ return ee->prop.title;
+}
+
+/**
+ * Set the name and class of an Ecore_Evas' window
+ * @param ee the Ecore_Evas
+ * @param n the name
+ * @param c the class
+ *
+ * This function sets the name of @p ee to @p n, and its class to @p c.
+ */
+void
+ecore_evas_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_name_class_set");
+ return;
+ }
+ IFC(ee, fn_name_class_set) (ee, n, c);
+ IFE;
+}
+
+/**
+ * Get the name and class of an Ecore_Evas' window
+ * @p ee The Ecore_Evas to query
+ * @p n A pointer to a string to place the name in.
+ * @p c A pointer to a string to place the class in.
+ *
+ * This function gets puts the name of @p ee into @p n, and its class into
+ * @p c.
+ */
+void
+ecore_evas_name_class_get(Ecore_Evas *ee, const char **n, const char **c)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_name_class_get");
+ return;
+ }
+ if (n) *n = ee->prop.name;
+ if (c) *c = ee->prop.clas;
+}
+
+/**
+ * Set the min size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w The minimum width
+ * @param h The minimum height
+ *
+ * This function sets the minimum size of @p ee to @p w x @p h.
+ */
+void
+ecore_evas_size_min_set(Ecore_Evas *ee, int w, int h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_min_set");
+ return;
+ }
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ IFC(ee, fn_size_min_set) (ee, h, w);
+ IFE;
+ }
+ else
+ {
+ IFC(ee, fn_size_min_set) (ee, w, h);
+ IFE;
+ }
+}
+
+/**
+ * Get the min size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w A pointer to an int to place the min width in.
+ * @param h A pointer to an int to place the min height in.
+ *
+ * This function puts the minimum size of @p ee into @p w and @p h.
+ */
+void
+ecore_evas_size_min_get(Ecore_Evas *ee, int *w, int *h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_min_get");
+ return;
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ if (w) *w = ee->prop.min.h;
+ if (h) *h = ee->prop.min.w;
+ }
+ else
+ {
+ if (w) *w = ee->prop.min.w;
+ if (h) *h = ee->prop.min.h;
+ }
+}
+
+/**
+ * Set the max size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w The maximum width
+ * @param h The maximum height
+ *
+ * This function sets the maximum size of @p ee to @p w x @p h.
+ */
+void
+ecore_evas_size_max_set(Ecore_Evas *ee, int w, int h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_max_set");
+ return;
+ }
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ IFC(ee, fn_size_max_set) (ee, h, w);
+ IFE;
+ }
+ else
+ {
+ IFC(ee, fn_size_max_set) (ee, w, h);
+ IFE;
+ }
+}
+
+/**
+ * Get the max size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w A pointer to an int to place the max width in.
+ * @param h A pointer to an int to place the max height in.
+ *
+ * This function puts the maximum size of @p ee into @p w and @p h.
+ */
+void
+ecore_evas_size_max_get(Ecore_Evas *ee, int *w, int *h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_max_get");
+ return;
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ if (w) *w = ee->prop.max.h;
+ if (h) *h = ee->prop.max.w;
+ }
+ else
+ {
+ if (w) *w = ee->prop.max.w;
+ if (h) *h = ee->prop.max.h;
+ }
+}
+
+/**
+ * Set the base size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w The base width
+ * @param h The base height
+ *
+ * This function sets the base size of @p ee to @p w x @p h.
+ */
+void
+ecore_evas_size_base_set(Ecore_Evas *ee, int w, int h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_base_set");
+ return;
+ }
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ IFC(ee, fn_size_base_set) (ee, h, w);
+ IFE;
+ }
+ else
+ {
+ IFC(ee, fn_size_base_set) (ee, w, h);
+ IFE;
+ }
+}
+
+/**
+ * Get the base size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w A pointer to an int to place the base width in.
+ * @param h A pointer to an int to place the base height in.
+ *
+ * This function puts the base size of @p ee into @p w and @p h.
+ */
+void
+ecore_evas_size_base_get(Ecore_Evas *ee, int *w, int *h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_base_get");
+ return;
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ if (w) *w = ee->prop.base.h;
+ if (h) *h = ee->prop.base.w;
+ }
+ else
+ {
+ if (w) *w = ee->prop.base.w;
+ if (h) *h = ee->prop.base.h;
+ }
+}
+
+/**
+ * Set the step size of an Ecore_Evas
+ * @param ee The Ecore_Evas to set
+ * @param w The step width
+ * @param h The step height
+ *
+ * This function sets the step size of @p ee to @p w x @p h. This limits the
+ * size of an Ecore_Evas to always being an integer multiple of the step size.
+ */
+void
+ecore_evas_size_step_set(Ecore_Evas *ee, int w, int h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_step_set");
+ return;
+ }
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ IFC(ee, fn_size_step_set) (ee, h, w);
+ IFE;
+ }
+ else
+ {
+ IFC(ee, fn_size_step_set) (ee, w, h);
+ IFE;
+ }
+}
+
+/**
+ * Get the step size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w A pointer to an int to place the step width in.
+ * @param h A pointer to an int to place the step height in.
+ *
+ * This function puts the step size of @p ee into @p w and @p h.
+ */
+void
+ecore_evas_size_step_get(Ecore_Evas *ee, int *w, int *h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_step_get");
+ return;
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ if (w) *w = ee->prop.step.h;
+ if (h) *h = ee->prop.step.w;
+ }
+ else
+ {
+ if (w) *w = ee->prop.step.w;
+ if (h) *h = ee->prop.step.h;
+ }
+}
+
+/**
+ * Set the cursor of an Ecore_Evas
+ * @param ee The Ecore_Evas
+ * @param file The path to an image file for the cursor
+ * @param layer
+ * @param hot_x The x coordinate of the cursor's hot spot
+ * @param hot_y The y coordinate of the cursor's hot spot
+ *
+ * This function makes the mouse cursor over @p ee be the image specified by
+ * @p file. The actual point within the image that the mouse is at is specified
+ * by @p hot_x and @p hot_y, which are coordinates with respect to the top left
+ * corner of the cursor image.
+ */
+void
+ecore_evas_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_cursor_set");
+ return;
+ }
+ IFC(ee, fn_cursor_set) (ee, file, layer, hot_x, hot_y);
+ IFE;
+}
+
+/**
+ * Get information about an Ecore_Evas' cursor
+ * @param ee The Ecore_Evas to set
+ * @param file A pointer to a string to place the cursor file name in.
+ * @param layer A pointer to an int to place the cursor's layer in..
+ * @param hot_x A pointer to an int to place the cursor's hot_x coordinate in.
+ * @param hot_y A pointer to an int to place the cursor's hot_y coordinate in.
+ *
+ * This function queries information about an Ecore_Evas' cursor.
+ */
+void
+ecore_evas_cursor_get(Ecore_Evas *ee, char **file, int *layer, int *hot_x, int *hot_y)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_cursor_get");
+ return;
+ }
+ if (file) *file = ee->prop.cursor.file;
+ if (layer) *layer = ee->prop.cursor.layer;
+ if (hot_x) *hot_x = ee->prop.cursor.hot.x;
+ if (hot_y) *hot_y = ee->prop.cursor.hot.y;
+}
+
+/**
+ * Set the layer of an Ecore_Evas' window
+ * @param ee The Ecore_Evas
+ * @param layer The layer to put @p ee on.
+ *
+ * This function moves @p ee to the layer @p layer.
+ */
+void
+ecore_evas_layer_set(Ecore_Evas *ee, int layer)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_layer_set");
+ return;
+ }
+ IFC(ee, fn_layer_set) (ee, layer);
+ IFE;
+}
+
+/**
+ * Get the layer of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @return the layer @p ee's window is on.
+ *
+ */
+int
+ecore_evas_layer_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_layer_get");
+ return 0;
+ }
+ return ee->prop.layer;
+}
+
+/**
+ * Set the focus of an Ecore_Evas' window
+ * @param ee The Ecore_Evas
+ * @param on 1 for focus, 0 to defocus.
+ *
+ * This function focuses @p ee if @p on is 1, or defocuses @p ee if @p on is 0.
+ */
+void
+ecore_evas_focus_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_focus_set");
+ return;
+ }
+ IFC(ee, fn_focus_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is focused or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee if focused, 0 if not.
+ *
+ */
+int
+ecore_evas_focus_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_focus_get");
+ return 0;
+ }
+ return ee->prop.focused ? 1:0;
+}
+
+/**
+ * Iconify or uniconify an Ecore_Evas' window
+ * @param ee The Ecore_Evas
+ * @param on 1 to iconify, 0 to uniconify.
+ *
+ * This function iconifies @p ee if @p on is 1, or uniconifies @p ee if @p on
+ * is 0.
+ */
+void
+ecore_evas_iconified_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_iconified_set");
+ return;
+ }
+ IFC(ee, fn_iconified_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is iconified or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee is iconified, 0 if not.
+ *
+ */
+int
+ecore_evas_iconified_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_iconified_get");
+ return 0;
+ }
+ return ee->prop.iconified ? 1:0;
+}
+
+/**
+ * Set whether an Ecore_Evas' window is borderless or not
+ * @param ee The Ecore_Evas
+ * @param on 1 for borderless, 0 for bordered.
+ *
+ * This function makes @p ee borderless if @p on is 1, or bordered if @p on
+ * is 0.
+ */
+void
+ecore_evas_borderless_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_borderless_set");
+ return;
+ }
+ IFC(ee, fn_borderless_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is borderless or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee is borderless, 0 if not.
+ *
+ */
+int
+ecore_evas_borderless_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_borderless_get");
+ return 0;
+ }
+ return ee->prop.borderless ? 1:0;
+}
+
+/**
+ * Tell the WM whether or not to ignore an Ecore_Evas' window
+ * @param ee The Ecore_Evas
+ * @param on 1 to ignore, 0 to not.
+ *
+ * This function causes the window manager to ignore @p ee if @p on is 1,
+ * or not ignore @p ee if @p on is 0.
+ */
+void
+ecore_evas_override_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_override_set");
+ return;
+ }
+ IFC(ee, fn_override_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is overridden or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee is overridden, 0 if not.
+ *
+ */
+int
+ecore_evas_override_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_override_get");
+ return 0;
+ }
+ return ee->prop.override ? 1:0;
+}
+
+/**
+ * Maximize (or unmaximize) an Ecore_Evas' window
+ * @param ee The Ecore_Evas
+ * @param on 1 to maximize, 0 to unmaximize.
+ *
+ * This function maximizes @p ee if @p on is 1, or unmaximizes @p ee
+ * if @p on is 0.
+ */
+void
+ecore_evas_maximized_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_maximized_set");
+ return;
+ }
+ IFC(ee, fn_maximized_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is maximized or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee is maximized, 0 if not.
+ *
+ */
+int
+ecore_evas_maximized_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_maximized_get");
+ return 0;
+ }
+ return ee->prop.maximized ? 1:0;
+}
+
+/**
+ * Set whether or not an Ecore_Evas' window is fullscreen
+ * @param ee The Ecore_Evas
+ * @param on 1 fullscreen, 0 not.
+ *
+ * This function causes @p ee to be fullscreen if @p on is 1,
+ * or not if @p on is 0.
+ */
+void
+ecore_evas_fullscreen_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_fullscreen_set");
+ return;
+ }
+ IFC(ee, fn_fullscreen_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is fullscreen or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee is fullscreen, 0 if not.
+ *
+ */
+int
+ecore_evas_fullscreen_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_fullscreen_get");
+ return 0;
+ }
+ return ee->prop.fullscreen ? 1:0;
+}
+
+/**
+ * Set whether or not an Ecore_Evas' window should avoid damage
+ *
+ * @param ee The Ecore_Evas
+ * @param on 1 to avoid damage, 0 to not
+ *
+ * This function causes @p ee to be drawn to a pixmap to avoid recalculations.
+ * On expose events it will copy from the pixmap to the window.
+ */
+void
+ecore_evas_avoid_damage_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_avoid_damage_set");
+ return;
+ }
+ IFC(ee, fn_avoid_damage_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window avoids damage or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee avoids damage, 0 if not.
+ *
+ */
+int
+ecore_evas_avoid_damage_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_avoid_damage_get");
+ return 0;
+ }
+ return ee->prop.avoid_damage ? 1:0;
+}
+
+/**
+ * Set the withdrawn state of an Ecore_Evas' window.
+ * @param ee The Ecore_Evas whose window's withdrawn state is set.
+ * @param withdrawn The Ecore_Evas window's new withdrawn state.
+ *
+ */
+void
+ecore_evas_withdrawn_set(Ecore_Evas *ee, int withdrawn)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_withdrawn_set");
+ return;
+ }
+
+ IFC(ee, fn_withdrawn_set) (ee, withdrawn);
+ IFE;
+}
+
+/**
+ * Returns the withdrawn state of an Ecore_Evas' window.
+ * @param ee The Ecore_Evas whose window's withdrawn state is returned.
+ * @return The Ecore_Evas window's withdrawn state.
+ *
+ */
+int
+ecore_evas_withdrawn_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_withdrawn_get");
+ return 0;
+ } else
+ return ee->prop.withdrawn ? 1:0;
+}
+
+/**
+ * Set the sticky state of an Ecore_Evas window.
+ *
+ * @param ee The Ecore_Evas whose window's sticky state is set.
+ * @param sticky The Ecore_Evas window's new sticky state.
+ *
+ */
+void
+ecore_evas_sticky_set(Ecore_Evas *ee, int sticky)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_sticky_set");
+ return;
+ }
+
+ IFC(ee, fn_sticky_set) (ee, sticky);
+ IFE;
+}
+
+/**
+ * Returns the sticky state of an Ecore_Evas' window.
+ *
+ * @param ee The Ecore_Evas whose window's sticky state is returned.
+ * @return The Ecore_Evas window's sticky state.
+ *
+ */
+int
+ecore_evas_sticky_get(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_sticky_get");
+ return 0;
+ } else
+ return ee->prop.sticky ? 1:0;
+}
+
+#ifndef WIN32
+/* fps debug calls - for debugging how much time your app actually spends */
+/* rendering graphics... :) */
+
+static int _ecore_evas_fps_debug_init_count = 0;
+static int _ecore_evas_fps_debug_fd = -1;
+unsigned int *_ecore_evas_fps_rendertime_mmap = NULL;
+
+void
+_ecore_evas_fps_debug_init(void)
+{
+ char buf[4096];
+
+ _ecore_evas_fps_debug_init_count++;
+ if (_ecore_evas_fps_debug_init_count > 1) return;
+ snprintf(buf, sizeof(buf), "/tmp/.ecore_evas_fps_debug-%i", (int)getpid());
+ _ecore_evas_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR);
+ if (_ecore_evas_fps_debug_fd < 0)
+ {
+ unlink(buf);
+ _ecore_evas_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR);
+ }
+ if (_ecore_evas_fps_debug_fd >= 0)
+ {
+ unsigned int zero = 0;
+
+ write(_ecore_evas_fps_debug_fd, &zero, sizeof(unsigned int));
+ _ecore_evas_fps_rendertime_mmap = mmap(NULL, sizeof(unsigned int),
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ _ecore_evas_fps_debug_fd, 0);
+ }
+}
+
+void
+_ecore_evas_fps_debug_shutdown(void)
+{
+ _ecore_evas_fps_debug_init_count--;
+ if (_ecore_evas_fps_debug_init_count > 0) return;
+ if (_ecore_evas_fps_debug_fd >= 0)
+ {
+ char buf[4096];
+
+ snprintf(buf, sizeof(buf), "/tmp/.ecore_evas_fps_debug-%i", (int)getpid());
+ unlink(buf);
+ if (_ecore_evas_fps_rendertime_mmap)
+ {
+ munmap(_ecore_evas_fps_rendertime_mmap, sizeof(int));
+ _ecore_evas_fps_rendertime_mmap = NULL;
+ }
+ close(_ecore_evas_fps_debug_fd);
+ _ecore_evas_fps_debug_fd = -1;
+ }
+}
+
+void
+_ecore_evas_fps_debug_rendertime_add(double t)
+{
+ if ((_ecore_evas_fps_debug_fd >= 0) &&
+ (_ecore_evas_fps_rendertime_mmap))
+ {
+ unsigned int tm;
+
+ tm = (unsigned int)(t * 1000000.0);
+ /* i know its not 100% theoretically guaranteed, but i'd say a write */
+ /* of an int could be considered atomic for all practical purposes */
+ /* oh and since this is cumulative, 1 second = 1,000,000 ticks, so */
+ /* this can run for about 4294 seconds becore looping. if you are */
+ /* doing performance testing in one run for over an hour... well */
+ /* time to restart or handle a loop condition :) */
+ *(_ecore_evas_fps_rendertime_mmap) += tm;
+ }
+}
+#endif
diff --git a/ecore/src/lib/ecore_evas/ecore_evas_buffer.c b/ecore/src/lib/ecore_evas/ecore_evas_buffer.c
new file mode 100644
index 0000000..84e0078
--- /dev/null
+++ b/ecore/src/lib/ecore_evas/ecore_evas_buffer.c
@@ -0,0 +1,634 @@
+#include "config.h"
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+#ifdef BUILD_ECORE_EVAS_BUFFER
+static int _ecore_evas_init_count = 0;
+
+static int _ecore_evas_fps_debug = 0;
+
+static Ecore_Evas *ecore_evases = NULL;
+
+static void
+_ecore_evas_mouse_move_process(Ecore_Evas *ee, int x, int y, unsigned int timestamp)
+{
+ ee->mouse.x = x;
+ ee->mouse.y = y;
+ evas_event_feed_mouse_move(ee->evas, x, y, timestamp, NULL);
+}
+
+static int
+_ecore_evas_buffer_init(void)
+{
+ _ecore_evas_init_count++;
+ if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
+ if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1;
+ if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init();
+ return _ecore_evas_init_count;
+}
+
+static void
+_ecore_evas_buffer_free(Ecore_Evas *ee)
+{
+ ecore_evases = _ecore_list_remove(ecore_evases, ee);
+ _ecore_evas_buffer_shutdown();
+ if (ee->engine.buffer.image)
+ {
+ Ecore_Evas *ee2;
+
+ ee2 = evas_object_data_get(ee->engine.buffer.image, "Ecore_Evas_Parent");
+ evas_object_del(ee->engine.buffer.image);
+ ee2->sub_ecore_evas = evas_list_remove(ee2->sub_ecore_evas, ee);
+ }
+ else
+ free(ee->engine.buffer.pixels);
+}
+
+static void
+_ecore_evas_resize(Ecore_Evas *ee, int w, int h)
+{
+ Evas_Engine_Info_Buffer *einfo;
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ if ((w == ee->w) && (h == ee->h)) return;
+ ee->w = w;
+ ee->h = h;
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+
+ if (ee->engine.buffer.image)
+ {
+ ee->engine.buffer.pixels = evas_object_image_data_get(ee->engine.buffer.image, 1);
+ }
+ else
+ {
+ if (ee->engine.buffer.pixels) free(ee->engine.buffer.pixels);
+ ee->engine.buffer.pixels = malloc(ee->w * ee->h * sizeof(int));
+ }
+
+ einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
+ einfo->info.dest_buffer = ee->engine.buffer.pixels;
+ einfo->info.dest_buffer_row_bytes = ee->w * sizeof(int);
+ einfo->info.use_color_key = 0;
+ einfo->info.alpha_threshold = 0;
+ einfo->info.func.new_update_region = NULL;
+ einfo->info.func.free_update_region = NULL;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+int
+_ecore_evas_buffer_shutdown(void)
+{
+ _ecore_evas_init_count--;
+ if (_ecore_evas_init_count == 0)
+ {
+ while (ecore_evases)
+ ecore_evas_free((Ecore_Evas *)(ecore_evases->data));
+ if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown();
+ }
+ if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+ return _ecore_evas_init_count;
+}
+
+void
+_ecore_evas_buffer_render(Ecore_Evas *ee)
+{
+ Evas_List *updates, *l, *ll;
+
+ for (ll = ee->sub_ecore_evas; ll; ll = ll->next)
+ {
+ Ecore_Evas *ee2;
+
+ ee2 = ll->data;
+ if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+ _ecore_evas_buffer_render(ee2);
+ if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+ }
+ if (ee->engine.buffer.image)
+ {
+ int w, h;
+
+ evas_object_image_size_get(ee->engine.buffer.image, &w, &h);
+ if ((w != ee->w) || (h != ee->h))
+ _ecore_evas_resize(ee, w, h);
+ }
+ updates = evas_render_updates(ee->evas);
+ if (ee->engine.buffer.image)
+ {
+ for (l = updates; l; l = l->next)
+ {
+ Evas_Rectangle *r;
+
+ r = l->data;
+ if (ee->engine.buffer.image)
+ evas_object_image_data_update_add(ee->engine.buffer.image,
+ r->x, r->y, r->w, r->h);
+ }
+ }
+ if (updates) evas_render_updates_free(updates);
+}
+
+static void
+_ecore_evas_buffer_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
+{
+ Evas_Coord xx, yy, fx, fy, fw, fh;
+
+ evas_object_geometry_get(ee->engine.buffer.image, &xx, &yy, NULL, NULL);
+ evas_object_image_fill_get(ee->engine.buffer.image, &fx, &fy, &fw, &fh);
+
+ if (fw < 1) fw = 1;
+ xx = (*x - xx) - fx;
+ while (xx < 0) xx += fw;
+ while (xx > fw) xx -= fw;
+ *x = (ee->w * xx) / fw;
+
+ if (fh < 1) fh = 1;
+ yy = (*y - yy) - fy;
+ while (yy < 0) yy += fh;
+ while (yy > fh) yy -= fh;
+ *y = (ee->h * yy) / fh;
+}
+
+static void
+_ecore_evas_buffer_cb_mouse_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Mouse_In *ev;
+
+ ee = data;
+ ev = event_info;
+ evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_mouse_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Mouse_Out *ev;
+
+ ee = data;
+ ev = event_info;
+ evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Mouse_Down *ev;
+
+ ee = data;
+ ev = event_info;
+ evas_event_feed_mouse_down(ee->evas, ev->button, ev->flags, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Mouse_Up *ev;
+
+ ee = data;
+ ev = event_info;
+ evas_event_feed_mouse_up(ee->evas, ev->button, ev->flags, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Mouse_Move *ev;
+ Evas_Coord x, y;
+
+ ee = data;
+ ev = event_info;
+ x = ev->cur.canvas.x;
+ y = ev->cur.canvas.y;
+ _ecore_evas_buffer_coord_translate(ee, &x, &y);
+ _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp);
+}
+
+static void
+_ecore_evas_buffer_cb_mouse_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Mouse_Wheel *ev;
+
+ ee = data;
+ ev = event_info;
+ evas_event_feed_mouse_wheel(ee->evas, ev->direction, ev->z, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_free(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ if (ee->driver)
+ ecore_evas_free(ee);
+}
+
+static void
+_ecore_evas_buffer_cb_key_down(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Key_Down *ev;
+
+ ee = data;
+ ev = event_info;
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift"))
+ evas_key_modifier_on(e, "Shift");
+ else
+ evas_key_modifier_off(e, "Shift");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control"))
+ evas_key_modifier_on(e, "Control");
+ else
+ evas_key_modifier_off(e, "Control");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt"))
+ evas_key_modifier_on(e, "Alt");
+ else
+ evas_key_modifier_off(e, "Alt");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta"))
+ evas_key_modifier_on(e, "Meta");
+ else
+ evas_key_modifier_off(e, "Meta");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper"))
+ evas_key_modifier_on(e, "Hyper");
+ else
+ evas_key_modifier_off(e, "Hyper");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super"))
+ evas_key_modifier_on(e, "Super");
+ else
+ evas_key_modifier_off(e, "Super");
+ if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock"))
+ evas_key_lock_on(e, "Scroll_Lock");
+ else
+ evas_key_lock_off(e, "Scroll_Lock");
+ if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock"))
+ evas_key_lock_on(e, "Num_Lock");
+ else
+ evas_key_lock_off(e, "Num_Lock");
+ if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock"))
+ evas_key_lock_on(e, "Caps_Lock");
+ else
+ evas_key_lock_off(e, "Caps_Lock");
+ evas_event_feed_key_down(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_key_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Key_Up *ev;
+
+ ee = data;
+ ev = event_info;
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift"))
+ evas_key_modifier_on(e, "Shift");
+ else
+ evas_key_modifier_off(e, "Shift");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control"))
+ evas_key_modifier_on(e, "Control");
+ else
+ evas_key_modifier_off(e, "Control");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt"))
+ evas_key_modifier_on(e, "Alt");
+ else
+ evas_key_modifier_off(e, "Alt");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta"))
+ evas_key_modifier_on(e, "Meta");
+ else
+ evas_key_modifier_off(e, "Meta");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper"))
+ evas_key_modifier_on(e, "Hyper");
+ else
+ evas_key_modifier_off(e, "Hyper");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super"))
+ evas_key_modifier_on(e, "Super");
+ else
+ evas_key_modifier_off(e, "Super");
+ if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock"))
+ evas_key_lock_on(e, "Scroll_Lock");
+ else
+ evas_key_lock_off(e, "Scroll_Lock");
+ if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock"))
+ evas_key_lock_on(e, "Num_Lock");
+ else
+ evas_key_lock_off(e, "Num_Lock");
+ if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock"))
+ evas_key_lock_on(e, "Caps_Lock");
+ else
+ evas_key_lock_off(e, "Caps_Lock");
+ evas_event_feed_key_up(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_focus_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ ee->prop.focused = 1;
+ if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
+}
+
+static void
+_ecore_evas_buffer_cb_focus_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ ee->prop.focused = 0;
+ if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
+}
+
+static void
+_ecore_evas_buffer_cb_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ ee->visible = 1;
+ if (ee->func.fn_show) ee->func.fn_show(ee);
+}
+
+static void
+_ecore_evas_buffer_cb_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ ee->visible = 0;
+ if (ee->func.fn_hide) ee->func.fn_hide(ee);
+}
+
+static const Ecore_Evas_Engine_Func _ecore_buffer_engine_func =
+{
+ _ecore_evas_buffer_free,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_resize,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+#endif
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+Ecore_Evas *
+ecore_evas_buffer_new(int w, int h)
+{
+#ifdef BUILD_ECORE_EVAS_BUFFER
+ Evas_Engine_Info_Buffer *einfo;
+ Ecore_Evas *ee;
+ int rmethod;
+
+ rmethod = evas_render_method_lookup("buffer");
+ if (!rmethod) return NULL;
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_buffer_init();
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_buffer_engine_func;
+
+ ee->driver = strdup("buffer");
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ee->rotation = 0;
+ ee->visible = 1;
+ ee->w = w;
+ ee->h = h;
+
+ ee->prop.max.w = 0;
+ ee->prop.max.h = 0;
+ ee->prop.layer = 0;
+ ee->prop.focused = 1;
+ ee->prop.borderless = 1;
+ ee->prop.override = 1;
+ ee->prop.maximized = 1;
+ ee->prop.fullscreen = 0;
+ ee->prop.withdrawn = 0;
+ ee->prop.sticky = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ ee->engine.buffer.pixels = malloc(w * h * sizeof(int));
+
+ einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
+ einfo->info.dest_buffer = ee->engine.buffer.pixels;
+ einfo->info.dest_buffer_row_bytes = ee->w * sizeof(int);
+ einfo->info.use_color_key = 0;
+ einfo->info.alpha_threshold = 0;
+ einfo->info.func.new_update_region = NULL;
+ einfo->info.func.free_update_region = NULL;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+ evas_key_modifier_add(ee->evas, "Shift");
+ evas_key_modifier_add(ee->evas, "Control");
+ evas_key_modifier_add(ee->evas, "Alt");
+ evas_key_modifier_add(ee->evas, "Meta");
+ evas_key_modifier_add(ee->evas, "Hyper");
+ evas_key_modifier_add(ee->evas, "Super");
+ evas_key_lock_add(ee->evas, "Caps_Lock");
+ evas_key_lock_add(ee->evas, "Num_Lock");
+ evas_key_lock_add(ee->evas, "Scroll_Lock");
+
+ evas_event_feed_mouse_in(ee->evas, 0, NULL);
+
+ ecore_evases = _ecore_list_prepend(ecore_evases, ee);
+ return ee;
+#else
+ return NULL;
+#endif
+}
+
+const int *
+ecore_evas_buffer_pixels_get(Ecore_Evas *ee)
+{
+#ifdef BUILD_ECORE_EVAS_BUFFER
+ _ecore_evas_buffer_render(ee);
+ return ee->engine.buffer.pixels;
+#else
+ return NULL;
+#endif
+}
+
+Evas_Object *
+ecore_evas_object_image_new(Ecore_Evas *ee_target)
+{
+#ifdef BUILD_ECORE_EVAS_BUFFER
+ Evas_Object *o;
+ Evas_Engine_Info_Buffer *einfo;
+ Ecore_Evas *ee;
+ int rmethod;
+ int w, h;
+
+ rmethod = evas_render_method_lookup("buffer");
+ if (!rmethod) return NULL;
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ o = evas_object_image_add(ee_target->evas);
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_buffer_init();
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_buffer_engine_func;
+
+ ee->driver = strdup("buffer");
+
+ w = 1;
+ h = 1;
+ ee->rotation = 0;
+ ee->visible = 0;
+ ee->w = w;
+ ee->h = h;
+
+ ee->prop.max.w = 0;
+ ee->prop.max.h = 0;
+ ee->prop.layer = 0;
+ ee->prop.focused = 0;
+ ee->prop.borderless = 1;
+ ee->prop.override = 1;
+ ee->prop.maximized = 0;
+ ee->prop.fullscreen = 0;
+ ee->prop.withdrawn = 0;
+ ee->prop.sticky = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ ee->engine.buffer.image = o;
+ evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas", ee);
+ evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas_Parent", ee_target);
+ evas_object_image_size_set(o, ee->w, ee->h);
+ evas_object_image_alpha_set(o, 1);
+ ee->engine.buffer.pixels = evas_object_image_data_get(o, 1);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MOUSE_IN,
+ _ecore_evas_buffer_cb_mouse_in, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MOUSE_OUT,
+ _ecore_evas_buffer_cb_mouse_out, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MOUSE_DOWN,
+ _ecore_evas_buffer_cb_mouse_down, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MOUSE_UP,
+ _ecore_evas_buffer_cb_mouse_up, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MOUSE_MOVE,
+ _ecore_evas_buffer_cb_mouse_move, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MOUSE_WHEEL,
+ _ecore_evas_buffer_cb_mouse_wheel, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_FREE,
+ _ecore_evas_buffer_cb_free, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_KEY_DOWN,
+ _ecore_evas_buffer_cb_key_down, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_KEY_UP,
+ _ecore_evas_buffer_cb_key_up, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_FOCUS_IN,
+ _ecore_evas_buffer_cb_focus_in, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_FOCUS_OUT,
+ _ecore_evas_buffer_cb_focus_out, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_SHOW,
+ _ecore_evas_buffer_cb_show, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_HIDE,
+ _ecore_evas_buffer_cb_hide, ee);
+ einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
+ einfo->info.dest_buffer = ee->engine.buffer.pixels;
+ einfo->info.dest_buffer_row_bytes = ee->w * sizeof(int);
+ einfo->info.use_color_key = 0;
+ einfo->info.alpha_threshold = 0;
+ einfo->info.func.new_update_region = NULL;
+ einfo->info.func.free_update_region = NULL;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+ evas_key_modifier_add(ee->evas, "Shift");
+ evas_key_modifier_add(ee->evas, "Control");
+ evas_key_modifier_add(ee->evas, "Alt");
+ evas_key_modifier_add(ee->evas, "Meta");
+ evas_key_modifier_add(ee->evas, "Hyper");
+ evas_key_modifier_add(ee->evas, "Super");
+ evas_key_lock_add(ee->evas, "Caps_Lock");
+ evas_key_lock_add(ee->evas, "Num_Lock");
+ evas_key_lock_add(ee->evas, "Scroll_Lock");
+
+ ee_target->sub_ecore_evas = evas_list_append(ee_target->sub_ecore_evas, ee);
+ return o;
+#else
+ return NULL;
+#endif
+}
diff --git a/ecore/src/lib/ecore_evas/ecore_evas_fb.c b/ecore/src/lib/ecore_evas/ecore_evas_fb.c
new file mode 100644
index 0000000..b0a6d2a
--- /dev/null
+++ b/ecore/src/lib/ecore_evas/ecore_evas_fb.c
@@ -0,0 +1,542 @@
+#include "config.h"
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+#ifdef BUILD_ECORE_EVAS_FB
+#include "Ecore_Fb.h"
+#endif
+
+#ifdef BUILD_ECORE_EVAS_FB
+static int _ecore_evas_init_count = 0;
+
+static int _ecore_evas_fps_debug = 0;
+
+static Ecore_Evas *ecore_evases = NULL;
+static Ecore_Event_Handler *ecore_evas_event_handlers[5];
+static Ecore_Idle_Enterer *ecore_evas_idle_enterer = NULL;
+
+static void
+_ecore_evas_mouse_move_process(Ecore_Evas *ee, int x, int y, unsigned int timestamp)
+{
+ int fbw, fbh;
+
+ ee->mouse.x = x;
+ ee->mouse.y = y;
+ ecore_fb_size_get(&fbw, &fbh);
+ if (ee->prop.cursor.object)
+ {
+ evas_object_show(ee->prop.cursor.object);
+ if (ee->rotation == 0)
+ evas_object_move(ee->prop.cursor.object,
+ x - ee->prop.cursor.hot.x,
+ y - ee->prop.cursor.hot.y);
+ else if (ee->rotation == 90)
+ evas_object_move(ee->prop.cursor.object,
+ (fbh - ee->h) + ee->h - y - 1 - ee->prop.cursor.hot.x,
+ x - ee->prop.cursor.hot.y);
+ else if (ee->rotation == 180)
+ evas_object_move(ee->prop.cursor.object,
+ (fbw - ee->w) + ee->w - x - 1 - ee->prop.cursor.hot.x,
+ (fbh - ee->h) + ee->h - y - 1 - ee->prop.cursor.hot.y);
+ else if (ee->rotation == 270)
+ evas_object_move(ee->prop.cursor.object,
+ y - ee->prop.cursor.hot.x,
+ (fbw - ee->w) + ee->w - x - 1 - ee->prop.cursor.hot.y);
+ }
+ if (ee->rotation == 0)
+ evas_event_feed_mouse_move(ee->evas, x, y, timestamp, NULL);
+ else if (ee->rotation == 90)
+ evas_event_feed_mouse_move(ee->evas, (fbh - ee->h) + ee->h - y - 1, x, timestamp, NULL);
+ else if (ee->rotation == 180)
+ evas_event_feed_mouse_move(ee->evas, (fbw - ee->w) + ee->w - x - 1, (fbh - ee->h) + ee->h - y - 1, timestamp, NULL);
+ else if (ee->rotation == 270)
+ evas_event_feed_mouse_move(ee->evas, y, (fbw - ee->w) + ee->w - x - 1, timestamp, NULL);
+}
+
+static Ecore_Evas *
+_ecore_evas_fb_match(void)
+{
+ Ecore_Oldlist *l;
+
+ for (l = (Ecore_Oldlist *)ecore_evases; l; l = l->next)
+ {
+ Ecore_Evas *ee;
+
+ ee = (Ecore_Evas *)l;
+ return ee;
+ }
+ return NULL;
+}
+
+static void
+_ecore_evas_fb_lose(void *data __UNUSED__)
+{
+ Ecore_Oldlist *l;
+
+ for (l = (Ecore_Oldlist *)ecore_evases; l; l = l->next)
+ {
+ Ecore_Evas *ee;
+
+ ee = (Ecore_Evas *)l;
+ ee->visible = 0;
+ }
+}
+
+static void
+_ecore_evas_fb_gain(void *data __UNUSED__)
+{
+ Ecore_Oldlist *l;
+
+ for (l = (Ecore_Oldlist *)ecore_evases; l; l = l->next)
+ {
+ Ecore_Evas *ee;
+
+ ee = (Ecore_Evas *)l;
+ ee->visible = 1;
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+}
+
+static int
+_ecore_evas_event_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Fb_Event_Key_Down *e;
+
+ e = event;
+ ee = _ecore_evas_fb_match();
+ if (!ee) return 1; /* pass on event */
+ evas_event_feed_key_down(ee->evas, e->keyname, e->keysymbol, e->key_compose, NULL, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ return 0; /* dont pass it on */
+}
+
+static int
+_ecore_evas_event_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Fb_Event_Key_Up *e;
+
+ e = event;
+ ee = _ecore_evas_fb_match();
+ if (!ee) return 1; /* pass on event */
+ evas_event_feed_key_up(ee->evas, e->keyname, e->keysymbol, e->key_compose, NULL, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ return 0; /* dont pass it on */
+}
+
+static int
+_ecore_evas_event_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Fb_Event_Mouse_Button_Down *e;
+ Evas_Button_Flags flags = EVAS_BUTTON_NONE;
+
+ e = event;
+ ee = _ecore_evas_fb_match();
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_mouse_move_process(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
+ if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
+ if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
+ evas_event_feed_mouse_down(ee->evas, e->button, flags, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ return 0; /* dont pass it on */
+}
+
+static int
+_ecore_evas_event_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Fb_Event_Mouse_Button_Up *e;
+
+ e = event;
+ ee = _ecore_evas_fb_match();
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_mouse_move_process(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
+ evas_event_feed_mouse_up(ee->evas, e->button, EVAS_BUTTON_NONE, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ return 0; /* dont pass it on */
+}
+
+static int
+_ecore_evas_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Fb_Event_Mouse_Move *e;
+
+ e = event;
+ ee = _ecore_evas_fb_match();
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_mouse_move_process(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
+ return 0; /* dont pass it on */
+}
+
+static int
+_ecore_evas_idle_enter(void *data __UNUSED__)
+{
+ Ecore_Oldlist *l;
+ double t1 = 0.;
+ double t2 = 0.;
+
+ if (_ecore_evas_fps_debug)
+ {
+ t1 = ecore_time_get();
+ }
+ for (l = (Ecore_Oldlist *)ecore_evases; l; l = l->next)
+ {
+ Ecore_Evas *ee;
+
+ ee = (Ecore_Evas *)l;
+ if (ee->visible)
+ {
+#ifdef BUILD_ECORE_EVAS_BUFFER
+ Evas_List *ll;
+#endif
+
+ if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
+#ifdef BUILD_ECORE_EVAS_BUFFER
+ for (ll = ee->sub_ecore_evas; ll; ll = ll->next)
+ {
+ Ecore_Evas *ee2;
+
+ ee2 = ll->data;
+ if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+ _ecore_evas_buffer_render(ee2);
+ if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+ }
+#endif
+ evas_render(ee->evas);
+ if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
+ }
+ }
+ if (_ecore_evas_fps_debug)
+ {
+ t2 = ecore_time_get();
+ _ecore_evas_fps_debug_rendertime_add(t2 - t1);
+ }
+ return 1;
+}
+
+static int
+_ecore_evas_fb_init(void)
+{
+ _ecore_evas_init_count++;
+ if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
+ if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1;
+ ecore_evas_idle_enterer = ecore_idle_enterer_add(_ecore_evas_idle_enter, NULL);
+ ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_FB_EVENT_KEY_DOWN, _ecore_evas_event_key_down, NULL);
+ ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_FB_EVENT_KEY_UP, _ecore_evas_event_key_up, NULL);
+ ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL);
+ ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL);
+ ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL);
+ if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init();
+ return _ecore_evas_init_count;
+}
+
+static void
+_ecore_evas_fb_free(Ecore_Evas *ee)
+{
+ ecore_evases = _ecore_list_remove(ecore_evases, ee);
+ _ecore_evas_fb_shutdown();
+ ecore_fb_shutdown();
+}
+
+static void
+_ecore_evas_resize(Ecore_Evas *ee, int w, int h)
+{
+ if ((w == ee->w) && (h == ee->h)) return;
+ ee->w = w;
+ ee->h = h;
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void
+_ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
+{
+ if ((w == ee->w) && (h == ee->h)) return;
+ ee->w = w;
+ ee->h = h;
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void
+_ecore_evas_rotation_set(Ecore_Evas *ee, int rotation)
+{
+ Evas_Engine_Info_FB *einfo;
+ int rot_dif;
+
+ if (ee->rotation == rotation) return;
+ einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+ rot_dif = ee->rotation - rotation;
+ if (rot_dif < 0) rot_dif = -rot_dif;
+ if (rot_dif != 180)
+ {
+
+ einfo->info.rotation = rotation;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ if (!ee->prop.fullscreen)
+ {
+ int tmp;
+
+ tmp = ee->w;
+ ee->w = ee->h;
+ ee->h = tmp;
+ }
+ else
+ {
+ if ((rotation == 0) || (rotation == 180))
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ }
+ ee->rotation = rotation;
+ }
+ else
+ {
+ einfo->info.rotation = rotation;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ ee->rotation = rotation;
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ else
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void
+_ecore_evas_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y)
+{
+ int x, y;
+
+ if (!file)
+ {
+ if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
+ if (ee->prop.cursor.file) free(ee->prop.cursor.file);
+ ee->prop.cursor.object = NULL;
+ ee->prop.cursor.file = NULL;
+ ee->prop.cursor.layer = 0;
+ ee->prop.cursor.hot.x = 0;
+ ee->prop.cursor.hot.y = 0;
+ return;
+ }
+ if (!ee->prop.cursor.object) ee->prop.cursor.object = evas_object_image_add(ee->evas);
+ if (ee->prop.cursor.file) free(ee->prop.cursor.file);
+ ee->prop.cursor.file = strdup(file);
+ ee->prop.cursor.layer = layer;
+ ee->prop.cursor.hot.x = hot_x;
+ ee->prop.cursor.hot.y = hot_y;
+ evas_pointer_output_xy_get(ee->evas, &x, &y);
+ evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
+ evas_object_color_set(ee->prop.cursor.object, 255, 255, 255, 255);
+ evas_object_move(ee->prop.cursor.object,
+ x - ee->prop.cursor.hot.x,
+ y - ee->prop.cursor.hot.y);
+ evas_object_image_file_set(ee->prop.cursor.object, ee->prop.cursor.file, NULL);
+ evas_object_image_size_get(ee->prop.cursor.object, &x, &y);
+ evas_object_resize(ee->prop.cursor.object, x, y);
+ evas_object_image_fill_set(ee->prop.cursor.object, 0, 0, x, y);
+ evas_object_pass_events_set(ee->prop.cursor.object, 1);
+ if (evas_pointer_inside_get(ee->evas))
+ evas_object_show(ee->prop.cursor.object);
+}
+
+static void
+_ecore_evas_fullscreen_set(Ecore_Evas *ee, int on)
+{
+ int resized = 0;
+
+ if (((ee->prop.fullscreen) && (on)) ||
+ ((!ee->prop.fullscreen) && (!on))) return;
+ if (on)
+ {
+ int w, h;
+
+ ee->engine.fb.real_w = ee->w;
+ ee->engine.fb.real_h = ee->h;
+ w = ee->w;
+ h = ee->h;
+ ecore_fb_size_get(&w, &h);
+ if ((w == 0) && (h == 0))
+ {
+ w = ee->w;
+ h = ee->h;
+ }
+ if ((w != ee->w) || (h != ee->h)) resized = 1;
+ ee->w = w;
+ ee->h = h;
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ else
+ {
+ if ((ee->engine.fb.real_w != ee->w) || (ee->engine.fb.real_h != ee->h)) resized = 1;
+ ee->w = ee->engine.fb.real_w;
+ ee->h = ee->engine.fb.real_h;
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ ee->prop.fullscreen = on;
+ if (resized)
+ {
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+}
+
+int
+_ecore_evas_fb_shutdown(void)
+{
+ _ecore_evas_init_count--;
+ if (_ecore_evas_init_count == 0)
+ {
+ int i;
+
+ while (ecore_evases) ecore_evas_free(ecore_evases);
+ for (i = 0; i < 5; i++)
+ ecore_event_handler_del(ecore_evas_event_handlers[i]);
+ ecore_idle_enterer_del(ecore_evas_idle_enterer);
+ ecore_evas_idle_enterer = NULL;
+ if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown();
+ }
+ if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+ return _ecore_evas_init_count;
+}
+
+static const Ecore_Evas_Engine_Func _ecore_fb_engine_func =
+{
+ _ecore_evas_fb_free,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_resize,
+ _ecore_evas_move_resize,
+ _ecore_evas_rotation_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_cursor_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_fullscreen_set,
+ NULL,
+ NULL,
+ NULL
+};
+#endif
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+Ecore_Evas *
+ecore_evas_fb_new(char *disp_name, int rotation, int w, int h)
+{
+#ifdef BUILD_ECORE_EVAS_FB
+ Evas_Engine_Info_FB *einfo;
+ Ecore_Evas *ee;
+ int rmethod;
+
+ rmethod = evas_render_method_lookup("fb");
+ if (!rmethod) return NULL;
+ if (!ecore_fb_init(disp_name)) return NULL;
+ ecore_fb_callback_gain_set(_ecore_evas_fb_gain, NULL);
+ ecore_fb_callback_lose_set(_ecore_evas_fb_lose, NULL);
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_fb_init();
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_fb_engine_func;
+
+ ee->driver = strdup("fb");
+ if (disp_name) ee->name = strdup(disp_name);
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ee->rotation = rotation;
+ ee->visible = 1;
+ ee->w = w;
+ ee->h = h;
+
+ ee->prop.max.w = 0;
+ ee->prop.max.h = 0;
+ ee->prop.layer = 0;
+ ee->prop.focused = 1;
+ ee->prop.borderless = 1;
+ ee->prop.override = 1;
+ ee->prop.maximized = 1;
+ ee->prop.fullscreen = 0;
+ ee->prop.withdrawn = 0;
+ ee->prop.sticky = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->info.virtual_terminal = 0;
+ einfo->info.device_number = 0;
+ einfo->info.refresh = 0;
+ einfo->info.rotation = ee->rotation;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+ evas_key_modifier_add(ee->evas, "Shift");
+ evas_key_modifier_add(ee->evas, "Control");
+ evas_key_modifier_add(ee->evas, "Alt");
+ evas_key_modifier_add(ee->evas, "Meta");
+ evas_key_modifier_add(ee->evas, "Hyper");
+ evas_key_modifier_add(ee->evas, "Super");
+ evas_key_lock_add(ee->evas, "Caps_Lock");
+ evas_key_lock_add(ee->evas, "Num_Lock");
+ evas_key_lock_add(ee->evas, "Scroll_Lock");
+
+ evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+
+ ecore_evases = _ecore_list_prepend(ecore_evases, ee);
+ return ee;
+#else
+ return NULL;
+#endif
+}
diff --git a/ecore/src/lib/ecore_evas/ecore_evas_private.h b/ecore/src/lib/ecore_evas/ecore_evas_private.h
new file mode 100644
index 0000000..675816d
--- /dev/null
+++ b/ecore/src/lib/ecore_evas/ecore_evas_private.h
@@ -0,0 +1,216 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#ifndef _ECORE_EVAS_PRIVATE_H
+#define _ECORE_EVAS_PRIVATE_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifndef WIN32
+#include <sys/mman.h>
+#endif
+
+#include <Evas.h>
+
+#define ECORE_MAGIC_EVAS 0x76543211
+
+#ifdef BUILD_ECORE_X
+#include "Ecore_X.h"
+#include <Evas_Engine_Software_X11.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#ifdef BUILD_ECORE_EVAS_GL
+#include <Evas_Engine_GL_X11.h>
+#endif
+#endif
+#ifdef BUILD_ECORE_EVAS_FB
+#include <Evas_Engine_FB.h>
+#endif
+#ifdef BUILD_ECORE_EVAS_BUFFER
+#include <Evas_Engine_Buffer.h>
+#endif
+
+typedef struct _Ecore_Evas Ecore_Evas;
+typedef struct _Ecore_Evas_Engine Ecore_Evas_Engine;
+typedef struct _Ecore_Evas_Engine_Func Ecore_Evas_Engine_Func;
+
+struct _Ecore_Evas_Engine_Func
+{
+ void (*fn_free) (Ecore_Evas *ee);
+ void (*fn_callback_resize_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_move_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_show_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_hide_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_delete_request_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_destroy_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_focus_in_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_focus_out_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_mouse_in_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_mouse_out_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_pre_render_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_post_render_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_move) (Ecore_Evas *ee, int x, int y);
+ void (*fn_resize) (Ecore_Evas *ee, int w, int h);
+ void (*fn_move_resize) (Ecore_Evas *ee, int x, int y, int w, int h);
+ void (*fn_rotation_set) (Ecore_Evas *ee, int rot);
+ void (*fn_shaped_set) (Ecore_Evas *ee, int shaped);
+ void (*fn_show) (Ecore_Evas *ee);
+ void (*fn_hide) (Ecore_Evas *ee);
+ void (*fn_raise) (Ecore_Evas *ee);
+ void (*fn_lower) (Ecore_Evas *ee);
+ void (*fn_title_set) (Ecore_Evas *ee, const char *t);
+ void (*fn_name_class_set) (Ecore_Evas *ee, const char *n, const char *c);
+ void (*fn_size_min_set) (Ecore_Evas *ee, int w, int h);
+ void (*fn_size_max_set) (Ecore_Evas *ee, int w, int h);
+ void (*fn_size_base_set) (Ecore_Evas *ee, int w, int h);
+ void (*fn_size_step_set) (Ecore_Evas *ee, int w, int h);
+ void (*fn_cursor_set) (Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y);
+ void (*fn_layer_set) (Ecore_Evas *ee, int layer);
+ void (*fn_focus_set) (Ecore_Evas *ee, int on);
+ void (*fn_iconified_set) (Ecore_Evas *ee, int on);
+ void (*fn_borderless_set) (Ecore_Evas *ee, int on);
+ void (*fn_override_set) (Ecore_Evas *ee, int on);
+ void (*fn_maximized_set) (Ecore_Evas *ee, int on);
+ void (*fn_fullscreen_set) (Ecore_Evas *ee, int on);
+ void (*fn_avoid_damage_set) (Ecore_Evas *ee, int on);
+ void (*fn_withdrawn_set) (Ecore_Evas *ee, int withdrawn);
+ void (*fn_sticky_set) (Ecore_Evas *ee, int sticky);
+};
+
+struct _Ecore_Evas_Engine
+{
+ Ecore_Evas_Engine_Func *func;
+
+#ifdef BUILD_ECORE_X
+ struct {
+ Ecore_X_Window win_root;
+ Ecore_X_Window win_container;
+ Ecore_X_Window win;
+ Ecore_X_Pixmap pmap;
+ Ecore_X_Pixmap mask;
+ Ecore_X_GC gc;
+ Region damages;
+ unsigned char direct_resize : 1;
+ unsigned char using_bg_pixmap : 1;
+ struct {
+ /*
+ unsigned char modal : 1;
+ */
+ unsigned char sticky : 1;
+ /*
+ unsigned char maximized_v : 1;
+ unsigned char maximized_h : 1;
+ unsigned char shaded : 1;
+ unsigned char skip_taskbar : 1;
+ unsigned char skip_pager : 1;
+ unsigned char fullscreen : 1;
+ */
+ unsigned char above : 1;
+ unsigned char below : 1;
+ } state;
+ } x;
+#endif
+#ifdef BUILD_ECORE_EVAS_FB
+ struct {
+ int real_w;
+ int real_h;
+ } fb;
+#endif
+#ifdef BUILD_ECORE_EVAS_BUFFER
+ struct {
+ void *pixels;
+ Evas_Object *image;
+ } buffer;
+#endif
+};
+
+struct _Ecore_Evas
+{
+ Ecore_List __list_data;
+ ECORE_MAGIC;
+ Evas *evas;
+ char *driver;
+ char *name;
+ int x, y, w, h;
+ short rotation;
+ char shaped : 1;
+ char visible : 1;
+ char should_be_visible : 1;
+
+ Evas_Hash *data;
+
+ struct {
+ int x, y;
+ } mouse;
+
+ struct {
+ int w, h;
+ } expecting_resize;
+
+ struct {
+ char *title;
+ char *name;
+ char *clas;
+ struct {
+ int w, h;
+ } min,
+ max,
+ base,
+ step;
+ struct {
+ Evas_Object *object;
+ char *file;
+ int layer;
+ struct {
+ int x, y;
+ } hot;
+ } cursor;
+ int layer;
+ char focused : 1;
+ char iconified : 1;
+ char borderless : 1;
+ char override : 1;
+ char maximized : 1;
+ char fullscreen : 1;
+ char avoid_damage : 1;
+ char withdrawn : 1;
+ char sticky : 1;
+ } prop;
+
+ struct {
+ void (*fn_resize) (Ecore_Evas *ee);
+ void (*fn_move) (Ecore_Evas *ee);
+ void (*fn_show) (Ecore_Evas *ee);
+ void (*fn_hide) (Ecore_Evas *ee);
+ void (*fn_delete_request) (Ecore_Evas *ee);
+ void (*fn_destroy) (Ecore_Evas *ee);
+ void (*fn_focus_in) (Ecore_Evas *ee);
+ void (*fn_focus_out) (Ecore_Evas *ee);
+ void (*fn_mouse_in) (Ecore_Evas *ee);
+ void (*fn_mouse_out) (Ecore_Evas *ee);
+ void (*fn_pre_render) (Ecore_Evas *ee);
+ void (*fn_post_render) (Ecore_Evas *ee);
+ } func;
+
+ Ecore_Evas_Engine engine;
+ Evas_List *sub_ecore_evas;
+};
+
+#ifdef BUILD_ECORE_X
+int _ecore_evas_x_shutdown(void);
+#endif
+#ifdef BUILD_ECORE_EVAS_FB
+int _ecore_evas_fb_shutdown(void);
+#endif
+#ifdef BUILD_ECORE_EVAS_BUFFER
+int _ecore_evas_buffer_shutdown(void);
+void _ecore_evas_buffer_render(Ecore_Evas *ee);
+#endif
+
+void _ecore_evas_fps_debug_init(void);
+void _ecore_evas_fps_debug_shutdown(void);
+void _ecore_evas_fps_debug_rendertime_add(double t);
+
+#endif
diff --git a/ecore/src/lib/ecore_evas/ecore_evas_x.c b/ecore/src/lib/ecore_evas/ecore_evas_x.c
new file mode 100644
index 0000000..243ddb6
--- /dev/null
+++ b/ecore/src/lib/ecore_evas/ecore_evas_x.c
@@ -0,0 +1,1938 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "config.h"
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+#ifdef BUILD_ECORE_X
+#include "Ecore_X.h"
+#endif
+
+#ifdef BUILD_ECORE_X
+static int _ecore_evas_init_count = 0;
+
+static int _ecore_evas_fps_debug = 0;
+
+static Ecore_Evas *ecore_evases = NULL;
+static Evas_Hash *ecore_evases_hash = NULL;
+static Ecore_Event_Handler *ecore_evas_event_handlers[16];
+static Ecore_Idle_Enterer *ecore_evas_idle_enterer = NULL;
+
+static void
+_ecore_evas_x_render(Ecore_Evas *ee)
+{
+#ifdef BUILD_ECORE_EVAS_BUFFER
+ Evas_List *ll;
+#endif
+
+#ifdef BUILD_ECORE_EVAS_BUFFER
+ for (ll = ee->sub_ecore_evas; ll; ll = ll->next)
+ {
+ Ecore_Evas *ee2;
+
+ ee2 = ll->data;
+ if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+ _ecore_evas_buffer_render(ee2);
+ if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+ }
+#endif
+ if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
+ if (ee->prop.avoid_damage)
+ {
+ Evas_List *updates, *l;
+
+ updates = evas_render_updates(ee->evas);
+#if 0
+ for (l = updates; l; l = l->next)
+ {
+ Evas_Rectangle *r;
+
+ r = l->data;
+ printf("DMG render [%p] %ix%i, [%i %i %ix%i]\n",
+ ee, ee->w, ee->h, r->x, r->y, r->w, r->h);
+ }
+#endif
+ if (ee->engine.x.using_bg_pixmap)
+ {
+ if (updates)
+ {
+ for (l = updates; l; l = l->next)
+ {
+ Evas_Rectangle *r;
+
+ r = l->data;
+ ecore_x_window_area_clear(ee->engine.x.win, r->x, r->y, r->w, r->h);
+ }
+ if ((ee->shaped) && (updates))
+ {
+ if (ee->prop.fullscreen)
+ ecore_x_window_shape_mask_set(ee->engine.x.win, ee->engine.x.mask);
+ else
+ ecore_x_window_shape_mask_set(ee->engine.x.win_container, ee->engine.x.mask);
+ }
+ }
+ if (updates) evas_render_updates_free(updates);
+ }
+ else
+ {
+ for (l = updates; l; l = l->next)
+ {
+ Evas_Rectangle *r;
+ XRectangle xr;
+ Region tmpr;
+
+ if (!ee->engine.x.damages)
+ ee->engine.x.damages = XCreateRegion();
+ r = l->data;
+ tmpr = XCreateRegion();
+ if (ee->rotation == 0)
+ {
+ xr.x = r->x;
+ xr.y = r->y;
+ xr.width = r->w;
+ xr.height = r->h;
+ }
+ else if (ee->rotation == 90)
+ {
+ xr.x = r->y;
+ xr.y = ee->h - r->x - r->w;
+ xr.width = r->h;
+ xr.height = r->w;
+ }
+ else if (ee->rotation == 180)
+ {
+ xr.x = ee->w - r->x - r->w;
+ xr.y = ee->h - r->y - r->h;
+ xr.width = r->w;
+ xr.height = r->h;
+ }
+ else if (ee->rotation == 270)
+ {
+ xr.x = ee->w - r->y - r->h;
+ xr.y = r->x;
+ xr.width = r->h;
+ xr.height = r->w;
+ }
+ XUnionRectWithRegion(&xr, ee->engine.x.damages, tmpr);
+ XDestroyRegion(ee->engine.x.damages);
+ ee->engine.x.damages = tmpr;
+ }
+ if (ee->engine.x.damages)
+ {
+ if ((ee->shaped) && (updates))
+ {
+ if (ee->prop.fullscreen)
+ ecore_x_window_shape_mask_set(ee->engine.x.win, ee->engine.x.mask);
+ else
+ ecore_x_window_shape_mask_set(ee->engine.x.win_container, ee->engine.x.mask);
+ }
+ XSetRegion(ecore_x_display_get(), ee->engine.x.gc, ee->engine.x.damages);
+ /* debug rendering */
+ /*
+ XSetForeground(ecore_x_display_get(), ee->engine.x.gc, rand());
+ XFillRectangle(ecore_x_display_get(), ee->engine.x.win, ee->engine.x.gc,
+ 0, 0, ee->w, ee->h);
+ XSync(ecore_x_display_get(), False);
+ usleep(20000);
+ XSync(ecore_x_display_get(), False);
+ */
+ ecore_x_pixmap_paste(ee->engine.x.pmap, ee->engine.x.win, ee->engine.x.gc,
+ 0, 0, ee->w, ee->h, 0, 0);
+ XDestroyRegion(ee->engine.x.damages);
+ ee->engine.x.damages = 0;
+ }
+ if (updates) evas_render_updates_free(updates);
+ }
+ }
+ else if ((ee->visible) ||
+ ((ee->should_be_visible) && (ee->prop.fullscreen)) ||
+ ((ee->should_be_visible) && (ee->prop.override)))
+ {
+ if (ee->shaped)
+ {
+ Evas_List *updates;
+
+ updates = evas_render_updates(ee->evas);
+ if (updates)
+ {
+ if (ee->prop.fullscreen)
+ ecore_x_window_shape_mask_set(ee->engine.x.win, ee->engine.x.mask);
+ else
+ ecore_x_window_shape_mask_set(ee->engine.x.win_container, ee->engine.x.mask);
+ evas_render_updates_free(updates);
+ }
+ }
+ else
+ {
+ Evas_List *updates;
+
+ updates = evas_render_updates(ee->evas);
+ if (updates)
+ {
+#if 0
+ Evas_List *l;
+
+ printf("RENDER [%p] [%i] %ix%i\n",
+ ee, ee->visible, ee->w, ee->h);
+ for (l = updates; l; l = l->next)
+ {
+ Evas_Rectangle *r;
+
+ r = l->data;
+ printf(" render [%i %i %ix%i]\n",
+ r->x, r->y, r->w, r->h);
+ }
+#endif
+ evas_render_updates_free(updates);
+ }
+ }
+ }
+ if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
+}
+
+static void
+_ecore_evas_x_mouse_move_process(Ecore_Evas *ee, int x, int y, unsigned int timestamp)
+{
+ ee->mouse.x = x;
+ ee->mouse.y = y;
+ if (ee->prop.cursor.object)
+ {
+ evas_object_show(ee->prop.cursor.object);
+ if (ee->rotation == 0)
+ evas_object_move(ee->prop.cursor.object,
+ x - ee->prop.cursor.hot.x,
+ y - ee->prop.cursor.hot.y);
+ else if (ee->rotation == 90)
+ evas_object_move(ee->prop.cursor.object,
+ ee->h - y - 1 - ee->prop.cursor.hot.x,
+ x - ee->prop.cursor.hot.y);
+ else if (ee->rotation == 180)
+ evas_object_move(ee->prop.cursor.object,
+ ee->w - x - 1 - ee->prop.cursor.hot.x,
+ ee->h - y - 1 - ee->prop.cursor.hot.y);
+ else if (ee->rotation == 270)
+ evas_object_move(ee->prop.cursor.object,
+ y - ee->prop.cursor.hot.x,
+ ee->w - x - 1 - ee->prop.cursor.hot.y);
+ }
+ if (ee->rotation == 0)
+ evas_event_feed_mouse_move(ee->evas, x, y, timestamp, NULL);
+ else if (ee->rotation == 90)
+ evas_event_feed_mouse_move(ee->evas, ee->h - y - 1, x, timestamp, NULL);
+ else if (ee->rotation == 180)
+ evas_event_feed_mouse_move(ee->evas, ee->w - x - 1, ee->h - y - 1, timestamp, NULL);
+ else if (ee->rotation == 270)
+ evas_event_feed_mouse_move(ee->evas, y, ee->w - x - 1, timestamp, NULL);
+}
+
+static char *
+_ecore_evas_x_winid_str_get(Ecore_X_Window win)
+{
+ const char *vals = "qWeRtYuIoP5-$&<~";
+ static char id[9];
+ unsigned int val;
+
+ val = (unsigned int)win;
+ id[0] = vals[(val >> 28) & 0xf];
+ id[1] = vals[(val >> 24) & 0xf];
+ id[2] = vals[(val >> 20) & 0xf];
+ id[3] = vals[(val >> 16) & 0xf];
+ id[4] = vals[(val >> 12) & 0xf];
+ id[5] = vals[(val >> 8) & 0xf];
+ id[6] = vals[(val >> 4) & 0xf];
+ id[7] = vals[(val ) & 0xf];
+ id[8] = 0;
+ return id;
+}
+
+static Ecore_Evas *
+_ecore_evas_x_match(Ecore_X_Window win)
+{
+ return evas_hash_find(ecore_evases_hash, _ecore_evas_x_winid_str_get(win));
+}
+
+static void
+_ecore_evas_x_resize_shape(Ecore_Evas *ee)
+{
+ Evas_Engine_Info_Software_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ GC gc;
+ XGCValues gcv;
+
+ if (ee->engine.x.mask) ecore_x_pixmap_del(ee->engine.x.mask);
+ ee->engine.x.mask = ecore_x_pixmap_new(ee->engine.x.win, ee->w, ee->h, 1);
+ gcv.foreground = 0;
+ gc = XCreateGC(ecore_x_display_get(), ee->engine.x.mask,
+ GCForeground,
+ &gcv);
+ XFillRectangle(ecore_x_display_get(), ee->engine.x.mask, gc,
+ 0, 0, ee->w, ee->h);
+ XFreeGC(ecore_x_display_get(), gc);
+ einfo->info.mask = ee->engine.x.mask;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+
+ }
+}
+
+static void
+_ecore_evas_x_modifier_locks_update(Ecore_Evas *ee, int modifiers)
+{
+ if (modifiers & ECORE_X_MODIFIER_SHIFT)
+ evas_key_modifier_on(ee->evas, "Shift");
+ else
+ evas_key_modifier_off(ee->evas, "Shift");
+ if (modifiers & ECORE_X_MODIFIER_CTRL)
+ evas_key_modifier_on(ee->evas, "Control");
+ else
+ evas_key_modifier_off(ee->evas, "Control");
+ if (modifiers & ECORE_X_MODIFIER_ALT)
+ evas_key_modifier_on(ee->evas, "Alt");
+ else
+ evas_key_modifier_off(ee->evas, "Alt");
+ if (modifiers & ECORE_X_MODIFIER_WIN)
+ {
+ evas_key_modifier_on(ee->evas, "Super");
+ evas_key_modifier_on(ee->evas, "Hyper");
+ }
+ else
+ {
+ evas_key_modifier_off(ee->evas, "Super");
+ evas_key_modifier_off(ee->evas, "Hyper");
+ }
+ if (modifiers & ECORE_X_LOCK_SCROLL)
+ evas_key_lock_on(ee->evas, "Scroll_Lock");
+ else
+ evas_key_lock_off(ee->evas, "Scroll_Lock");
+ if (modifiers & ECORE_X_LOCK_NUM)
+ evas_key_lock_on(ee->evas, "Num_Lock");
+ else
+ evas_key_lock_off(ee->evas, "Num_Lock");
+ if (modifiers & ECORE_X_LOCK_CAPS)
+ evas_key_lock_on(ee->evas, "Caps_Lock");
+ else
+ evas_key_lock_off(ee->evas, "Caps_Lock");
+}
+
+static int
+_ecore_evas_x_event_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Key_Down *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_x_modifier_locks_update(ee, e->modifiers);
+ evas_event_feed_key_down(ee->evas, e->keyname, e->keysymbol, e->key_compose, NULL, e->time, NULL);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Key_Up *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_x_modifier_locks_update(ee, e->modifiers);
+ evas_event_feed_key_up(ee->evas, e->keyname, e->keysymbol, e->key_compose, NULL, e->time, NULL);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Mouse_Button_Down *e;
+ Evas_Button_Flags flags = EVAS_BUTTON_NONE;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_x_modifier_locks_update(ee, e->modifiers);
+ _ecore_evas_x_mouse_move_process(ee, e->x, e->y, e->time);
+ if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
+ if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
+ evas_event_feed_mouse_down(ee->evas, e->button, flags, e->time, NULL);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Mouse_Button_Up *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_x_modifier_locks_update(ee, e->modifiers);
+ _ecore_evas_x_mouse_move_process(ee, e->x, e->y, e->time);
+ evas_event_feed_mouse_up(ee->evas, e->button, EVAS_BUTTON_NONE, e->time, NULL);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Mouse_Wheel *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+
+ if (!ee)
+ return 1; /* pass on event */
+
+ _ecore_evas_x_modifier_locks_update(ee, e->modifiers);
+ _ecore_evas_x_mouse_move_process(ee, e->x, e->y, e->time);
+ evas_event_feed_mouse_wheel(ee->evas, e->direction, e->z, e->time, NULL);
+
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Mouse_Move *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_x_modifier_locks_update(ee, e->modifiers);
+ _ecore_evas_x_mouse_move_process(ee, e->x, e->y, e->time);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Mouse_In *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (e->event_win == ee->engine.x.win_container) return 0;
+/* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */
+ if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
+ _ecore_evas_x_modifier_locks_update(ee, e->modifiers);
+ evas_event_feed_mouse_in(ee->evas, e->time, NULL);
+ _ecore_evas_x_mouse_move_process(ee, e->x, e->y, e->time);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Mouse_Out *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (e->event_win == ee->engine.x.win_container) return 0;
+/* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */
+ _ecore_evas_x_modifier_locks_update(ee, e->modifiers);
+ _ecore_evas_x_mouse_move_process(ee, e->x, e->y, e->time);
+ evas_event_feed_mouse_out(ee->evas, e->time, NULL);
+ if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
+ if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Focus_In *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ ee->prop.focused = 1;
+ if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Focus_Out *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (ee->prop.fullscreen)
+ ecore_x_window_focus(ee->engine.x.win);
+ ee->prop.focused = 0;
+ if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_damage(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Damage *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (ee->engine.x.using_bg_pixmap) return 1;
+ if (ee->prop.avoid_damage)
+ {
+ XRectangle xr;
+ Region tmpr;
+
+ if (!ee->engine.x.damages) ee->engine.x.damages = XCreateRegion();
+ tmpr = XCreateRegion();
+ xr.x = e->x;
+ xr.y = e->y;
+ xr.width = e->w;
+ xr.height = e->h;
+ XUnionRectWithRegion(&xr, ee->engine.x.damages, tmpr);
+ XDestroyRegion(ee->engine.x.damages);
+ ee->engine.x.damages = tmpr;
+ }
+ else
+ {
+ if (ee->rotation == 0)
+ evas_damage_rectangle_add(ee->evas,
+ e->x,
+ e->y,
+ e->w, e->h);
+ else if (ee->rotation == 90)
+ evas_damage_rectangle_add(ee->evas,
+ ee->h - e->y - e->h,
+ e->x,
+ e->h, e->w);
+ else if (ee->rotation == 180)
+ evas_damage_rectangle_add(ee->evas,
+ ee->w - e->x - e->w,
+ ee->h - e->y - e->h,
+ e->w, e->h);
+ else if (ee->rotation == 270)
+ evas_damage_rectangle_add(ee->evas,
+ e->y,
+ ee->w - e->x - e->w,
+ e->h, e->w);
+ }
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_destroy(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Destroy *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (ee->func.fn_destroy) ee->func.fn_destroy(ee);
+ ecore_evas_free(ee);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Configure *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if ((ee->prop.fullscreen) && (e->win == ee->engine.x.win_container)) return 0;
+ if (ee->engine.x.direct_resize) return 0;
+
+ if ((e->from_wm) || (ee->prop.fullscreen) || (ee->prop.override))
+ {
+ if ((ee->x != e->x) || (ee->y != e->y))
+ {
+ ee->x = e->x;
+ ee->y = e->y;
+ if (ee->func.fn_move) ee->func.fn_move(ee);
+ }
+ }
+ if ((ee->w != e->w) || (ee->h != e->h))
+ {
+ ee->w = e->w;
+ ee->h = e->h;
+ if (e->win == ee->engine.x.win_container)
+ ecore_x_window_move_resize(ee->engine.x.win, 0, 0, ee->w, ee->h);
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ if (ee->prop.avoid_damage)
+ {
+ ecore_evas_avoid_damage_set(ee, 0);
+ ecore_evas_avoid_damage_set(ee, 1);
+ }
+ if (ee->shaped)
+ {
+ _ecore_evas_x_resize_shape(ee);
+ }
+ if ((ee->expecting_resize.w > 0) &&
+ (ee->expecting_resize.h > 0))
+ {
+ if ((ee->expecting_resize.w == ee->w) &&
+ (ee->expecting_resize.h == ee->h))
+ _ecore_evas_x_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
+ ecore_x_current_time_get());
+ ee->expecting_resize.w = 0;
+ ee->expecting_resize.h = 0;
+ }
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_delete_request(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Delete_Request *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_show(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Show *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (ee->visible) return 0; /* dont pass it on */
+ ee->visible = 1;
+ if (ee->func.fn_show) ee->func.fn_show(ee);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_hide(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Hide *e;
+
+ e = event;
+ ee = _ecore_evas_x_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (!ee->visible) return 0; /* dont pass it on */
+ ee->visible = 0;
+ if (ee->func.fn_hide) ee->func.fn_hide(ee);
+ return 1;
+}
+
+/* FIXME, should be in idler */
+static void
+_ecore_evas_x_size_pos_hints_update(Ecore_Evas *ee)
+{
+ ecore_x_icccm_size_pos_hints_set(ee->engine.x.win_container,
+ 1 /*request_pos */,
+ ECORE_X_GRAVITY_NW /* gravity */,
+ ee->prop.min.w /* min_w */,
+ ee->prop.min.h /* min_h */,
+ ee->prop.max.w /* max_w */,
+ ee->prop.max.h /* max_h */,
+ ee->prop.base.w /* base_w */,
+ ee->prop.base.h /* base_h */,
+ ee->prop.step.w /* step_x */,
+ ee->prop.step.h /* step_y */,
+ 0 /* min_aspect */,
+ 0 /* max_aspect */);
+}
+
+/* FIXME, should be in idler */
+static void
+_ecore_evas_x_state_update(Ecore_Evas *ee)
+{
+ Ecore_X_Window_State state[10];
+ int num;
+
+ num = 0;
+
+ /*
+ if (bd->client.netwm.state.modal)
+ state[num++] = ECORE_X_WINDOW_STATE_MODAL;
+ */
+ if (ee->engine.x.state.sticky)
+ state[num++] = ECORE_X_WINDOW_STATE_STICKY;
+ /*
+ if (bd->client.netwm.state.maximized_v)
+ state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
+ if (bd->client.netwm.state.maximized_h)
+ state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
+ if (bd->client.netwm.state.shaded)
+ state[num++] = ECORE_X_WINDOW_STATE_SHADED;
+ if (bd->client.netwm.state.skip_taskbar)
+ state[num++] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
+ if (bd->client.netwm.state.skip_pager)
+ state[num++] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
+ if (bd->client.netwm.state.hidden)
+ state[num++] = ECORE_X_WINDOW_STATE_HIDDEN;
+ if (bd->client.netwm.state.fullscreen)
+ state[num++] = ECORE_X_WINDOW_STATE_FULLSCREEN;
+ */
+ if (ee->engine.x.state.above)
+ state[num++] = ECORE_X_WINDOW_STATE_ABOVE;
+ if (ee->engine.x.state.below)
+ state[num++] = ECORE_X_WINDOW_STATE_BELOW;
+
+ ecore_x_netwm_window_state_set(ee->engine.x.win_container, state, num);
+}
+
+void
+_ecore_evas_x_layer_update(Ecore_Evas *ee)
+{
+ if (ee->should_be_visible)
+ {
+ /* We need to send a netwm request to the wm */
+ /* FIXME: Do we have to remove old state before adding new? */
+ if (ee->prop.layer < 3)
+ {
+ if (ee->engine.x.state.above)
+ {
+ ee->engine.x.state.above = 0;
+ ecore_x_netwm_state_request_send(ee->engine.x.win_container,
+ ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_ABOVE, -1, 0);
+ }
+ if (!ee->engine.x.state.below)
+ {
+ ee->engine.x.state.below = 1;
+ ecore_x_netwm_state_request_send(ee->engine.x.win_container,
+ ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_BELOW, -1, 1);
+ }
+ }
+ else if (ee->prop.layer > 5)
+ {
+ if (ee->engine.x.state.below)
+ {
+ ee->engine.x.state.below = 0;
+ ecore_x_netwm_state_request_send(ee->engine.x.win_container,
+ ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_BELOW, -1, 0);
+ }
+ if (!ee->engine.x.state.above)
+ {
+ ee->engine.x.state.above = 1;
+ ecore_x_netwm_state_request_send(ee->engine.x.win_container,
+ ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_ABOVE, -1, 1);
+ }
+ }
+ else
+ {
+ if (ee->engine.x.state.below)
+ {
+ ee->engine.x.state.below = 0;
+ ecore_x_netwm_state_request_send(ee->engine.x.win_container,
+ ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_BELOW, -1, 0);
+ }
+ if (ee->engine.x.state.above)
+ {
+ ee->engine.x.state.above = 0;
+ ecore_x_netwm_state_request_send(ee->engine.x.win_container,
+ ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_ABOVE, -1, 0);
+ }
+ }
+ }
+ else
+ {
+ /* Just set the state */
+ if (ee->prop.layer < 3)
+ {
+ if ((ee->engine.x.state.above) || (!ee->engine.x.state.below))
+ {
+ ee->engine.x.state.above = 0;
+ ee->engine.x.state.below = 1;
+ _ecore_evas_x_state_update(ee);
+ }
+ }
+ else if (ee->prop.layer > 5)
+ {
+ if ((!ee->engine.x.state.above) || (ee->engine.x.state.below))
+ {
+ ee->engine.x.state.above = 1;
+ ee->engine.x.state.below = 0;
+ _ecore_evas_x_state_update(ee);
+ }
+ }
+ else
+ {
+ if ((ee->engine.x.state.above) || (ee->engine.x.state.below))
+ {
+ ee->engine.x.state.above = 0;
+ ee->engine.x.state.below = 0;
+ _ecore_evas_x_state_update(ee);
+ }
+ }
+ }
+ /* FIXME: Set gnome layer */
+}
+
+static int
+_ecore_evas_x_idle_enter(void *data __UNUSED__)
+{
+ Ecore_Oldlist *l;
+ double t1 = 0.0;
+ double t2 = 0.0;
+
+ if (_ecore_evas_fps_debug)
+ {
+ t1 = ecore_time_get();
+ }
+ for (l = (Ecore_Oldlist *)ecore_evases; l; l = l->next)
+ {
+ Ecore_Evas *ee;
+
+ ee = (Ecore_Evas *)l;
+ _ecore_evas_x_render(ee);
+ }
+ ecore_x_flush();
+ if (_ecore_evas_fps_debug)
+ {
+ t2 = ecore_time_get();
+ _ecore_evas_fps_debug_rendertime_add(t2 - t1);
+ }
+ return 1;
+}
+
+static int
+_ecore_evas_x_init(void)
+{
+ _ecore_evas_init_count++;
+ if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
+ if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1;
+ ecore_evas_idle_enterer = ecore_idle_enterer_add(_ecore_evas_x_idle_enter, NULL);
+ ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_X_EVENT_KEY_DOWN, _ecore_evas_x_event_key_down, NULL);
+ ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_X_EVENT_KEY_UP, _ecore_evas_x_event_key_up, NULL);
+ ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_x_event_mouse_button_down, NULL);
+ ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, _ecore_evas_x_event_mouse_button_up, NULL);
+ ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_MOVE, _ecore_evas_x_event_mouse_move, NULL);
+ ecore_evas_event_handlers[5] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _ecore_evas_x_event_mouse_in, NULL);
+ ecore_evas_event_handlers[6] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _ecore_evas_x_event_mouse_out, NULL);
+ ecore_evas_event_handlers[7] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _ecore_evas_x_event_window_focus_in, NULL);
+ ecore_evas_event_handlers[8] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _ecore_evas_x_event_window_focus_out, NULL);
+ ecore_evas_event_handlers[9] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DAMAGE, _ecore_evas_x_event_window_damage, NULL);
+ ecore_evas_event_handlers[10] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _ecore_evas_x_event_window_destroy, NULL);
+ ecore_evas_event_handlers[11] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _ecore_evas_x_event_window_configure, NULL);
+ ecore_evas_event_handlers[12] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, _ecore_evas_x_event_window_delete_request, NULL);
+ ecore_evas_event_handlers[13] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, _ecore_evas_x_event_window_show, NULL);
+ ecore_evas_event_handlers[14] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _ecore_evas_x_event_window_hide, NULL);
+ ecore_evas_event_handlers[15] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_WHEEL, _ecore_evas_x_event_mouse_wheel, NULL);
+ if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init();
+ return _ecore_evas_init_count;
+}
+
+static void
+_ecore_evas_x_free(Ecore_Evas *ee)
+{
+ ecore_x_window_del(ee->engine.x.win);
+ ecore_x_window_del(ee->engine.x.win_container);
+ if (ee->engine.x.pmap) ecore_x_pixmap_del(ee->engine.x.pmap);
+ if (ee->engine.x.mask) ecore_x_pixmap_del(ee->engine.x.mask);
+ if (ee->engine.x.gc) ecore_x_gc_del(ee->engine.x.gc);
+ if (ee->engine.x.damages) XDestroyRegion(ee->engine.x.damages);
+ ee->engine.x.pmap = 0;
+ ee->engine.x.mask = 0;
+ ee->engine.x.gc = 0;
+ ee->engine.x.damages = 0;
+ ecore_evases_hash = evas_hash_del(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win), ee);
+ ecore_evases_hash = evas_hash_del(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win_container), ee);
+ ecore_evases = _ecore_list_remove(ecore_evases, ee);
+ _ecore_evas_x_shutdown();
+ ecore_x_shutdown();
+}
+
+static void
+_ecore_evas_x_callback_delete_request_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (func)
+ ecore_x_icccm_protocol_set(ee->engine.x.win_container, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, 1);
+ else
+ ecore_x_icccm_protocol_set(ee->engine.x.win_container, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, 0);
+ ee->func.fn_delete_request = func;
+}
+
+static void
+_ecore_evas_x_move(Ecore_Evas *ee, int x, int y)
+{
+ ecore_x_window_move(ee->engine.x.win_container, x, y);
+ if (!ee->should_be_visible)
+ {
+ /* We need to request pos */
+ _ecore_evas_x_size_pos_hints_update(ee);
+ }
+}
+
+static void
+_ecore_evas_x_resize(Ecore_Evas *ee, int w, int h)
+{
+ ecore_x_window_resize(ee->engine.x.win_container, w, h);
+ if (ee->engine.x.direct_resize)
+ {
+ ecore_x_window_move_resize(ee->engine.x.win, 0, 0, w, h);
+ if ((ee->w != w) || (ee->h != h))
+ {
+ ee->w = w;
+ ee->h = h;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ if (ee->prop.avoid_damage)
+ {
+ ecore_evas_avoid_damage_set(ee, 0);
+ ecore_evas_avoid_damage_set(ee, 1);
+ }
+ if (ee->shaped)
+ {
+ _ecore_evas_x_resize_shape(ee);
+ }
+ }
+ }
+}
+
+static void
+_ecore_evas_x_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
+{
+ ecore_x_window_move_resize(ee->engine.x.win_container, x, y, w, h);
+ if (ee->engine.x.direct_resize)
+ {
+ ecore_x_window_move_resize(ee->engine.x.win, 0, 0, w, h);
+ if ((ee->w != w) || (ee->h != h))
+ {
+ ee->w = w;
+ ee->h = h;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ if (ee->prop.avoid_damage)
+ {
+ ecore_evas_avoid_damage_set(ee, 0);
+ ecore_evas_avoid_damage_set(ee, 1);
+ }
+ if (ee->shaped)
+ {
+ _ecore_evas_x_resize_shape(ee);
+ }
+ }
+ }
+}
+
+static void
+_ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation)
+{
+ Evas_Engine_Info_Software_X11 *einfo;
+ int rot_dif;
+
+ if (ee->rotation == rotation) return;
+ if (!strcmp(ee->driver, "gl_x11")) return;
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+ rot_dif = ee->rotation - rotation;
+ if (rot_dif < 0) rot_dif = -rot_dif;
+ if (rot_dif != 180)
+ {
+ int minw, minh, maxw, maxh, basew, baseh, stepw, steph;
+
+ einfo->info.rotation = rotation;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ if (!ee->prop.fullscreen)
+ {
+ ecore_x_window_resize(ee->engine.x.win_container, ee->h, ee->w);
+ ee->expecting_resize.w = ee->h;
+ ee->expecting_resize.h = ee->w;
+ }
+ else
+ {
+ int w, h;
+
+ ecore_x_window_size_get(ee->engine.x.win_container, &w, &h);
+ ecore_x_window_resize(ee->engine.x.win_container, h, w);
+ if ((rotation == 0) || (rotation == 180))
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+ ecore_evas_size_min_get(ee, &minw, &minh);
+ ecore_evas_size_max_get(ee, &maxw, &maxh);
+ ecore_evas_size_base_get(ee, &basew, &baseh);
+ ecore_evas_size_step_get(ee, &stepw, &steph);
+ ee->rotation = rotation;
+ ecore_evas_size_min_set(ee, minh, minw);
+ ecore_evas_size_max_set(ee, maxh, maxw);
+ ecore_evas_size_base_set(ee, baseh, basew);
+ ecore_evas_size_step_set(ee, steph, stepw);
+ _ecore_evas_x_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
+ ecore_x_current_time_get());
+ }
+ else
+ {
+ einfo->info.rotation = rotation;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ ee->rotation = rotation;
+ _ecore_evas_x_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
+ ecore_x_current_time_get());
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ else
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+}
+
+static void
+_ecore_evas_x_shaped_set(Ecore_Evas *ee, int shaped)
+{
+ Evas_Engine_Info_Software_X11 *einfo;
+
+ if (((ee->shaped) && (shaped)) ||
+ ((!ee->shaped) && (!shaped)))
+ return;
+ if (!strcmp(ee->driver, "gl_x11")) return;
+ ee->shaped = shaped;
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ if (ee->shaped)
+ {
+ GC gc;
+ XGCValues gcv;
+
+ ee->engine.x.mask = ecore_x_pixmap_new(ee->engine.x.win, ee->w, ee->h, 1);
+ gcv.foreground = 0;
+ gc = XCreateGC(ecore_x_display_get(), ee->engine.x.mask,
+ GCForeground,
+ &gcv);
+ XFillRectangle(ecore_x_display_get(), ee->engine.x.mask, gc,
+ 0, 0, ee->w, ee->h);
+ XFreeGC(ecore_x_display_get(), gc);
+ einfo->info.mask = ee->engine.x.mask;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ else
+ {
+ if (ee->engine.x.mask) ecore_x_pixmap_del(ee->engine.x.mask);
+ ee->engine.x.mask = 0;
+ einfo->info.mask = 0;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ ecore_x_window_shape_mask_set(ee->engine.x.win, 0);
+ ecore_x_window_shape_mask_set(ee->engine.x.win_container, 0);
+ }
+ }
+}
+
+static void
+_ecore_evas_x_show(Ecore_Evas *ee)
+{
+ ee->should_be_visible = 1;
+ if (ee->prop.avoid_damage)
+ _ecore_evas_x_render(ee);
+ if (!ee->prop.fullscreen)
+ ecore_x_window_show(ee->engine.x.win_container);
+ ecore_x_window_show(ee->engine.x.win);
+ if (ee->prop.fullscreen)
+ ecore_x_window_focus(ee->engine.x.win);
+}
+
+static void
+_ecore_evas_x_hide(Ecore_Evas *ee)
+{
+ if (!ee->prop.fullscreen)
+ ecore_x_window_hide(ee->engine.x.win_container);
+ ecore_x_window_hide(ee->engine.x.win);
+ ee->should_be_visible = 0;
+}
+
+static void
+_ecore_evas_x_raise(Ecore_Evas *ee)
+{
+ if (!ee->prop.fullscreen)
+ ecore_x_window_raise(ee->engine.x.win_container);
+ else
+ ecore_x_window_raise(ee->engine.x.win);
+}
+
+static void
+_ecore_evas_x_lower(Ecore_Evas *ee)
+{
+ if (!ee->prop.fullscreen)
+ ecore_x_window_lower(ee->engine.x.win_container);
+ else
+ ecore_x_window_lower(ee->engine.x.win);
+}
+
+static void
+_ecore_evas_x_title_set(Ecore_Evas *ee, const char *t)
+{
+ if (ee->prop.title) free(ee->prop.title);
+ ee->prop.title = NULL;
+ if (t) ee->prop.title = strdup(t);
+ ecore_x_icccm_title_set(ee->engine.x.win_container, ee->prop.title);
+ ecore_x_netwm_name_set(ee->engine.x.win_container, ee->prop.title);
+}
+
+static void
+_ecore_evas_x_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
+{
+ if (ee->prop.name) free(ee->prop.name);
+ if (ee->prop.clas) free(ee->prop.clas);
+ ee->prop.name = NULL;
+ ee->prop.clas = NULL;
+ ee->prop.name = strdup(n);
+ ee->prop.clas = strdup(c);
+ ecore_x_icccm_name_class_set(ee->engine.x.win_container, ee->prop.name, ee->prop.clas);
+}
+
+static void
+_ecore_evas_x_size_min_set(Ecore_Evas *ee, int w, int h)
+{
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
+ ee->prop.min.w = w;
+ ee->prop.min.h = h;
+ _ecore_evas_x_size_pos_hints_update(ee);
+}
+
+static void
+_ecore_evas_x_size_max_set(Ecore_Evas *ee, int w, int h)
+{
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
+ ee->prop.max.w = w;
+ ee->prop.max.h = h;
+ _ecore_evas_x_size_pos_hints_update(ee);
+}
+
+static void
+_ecore_evas_x_size_base_set(Ecore_Evas *ee, int w, int h)
+{
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
+ ee->prop.base.w = w;
+ ee->prop.base.h = h;
+ _ecore_evas_x_size_pos_hints_update(ee);
+}
+
+static void
+_ecore_evas_x_size_step_set(Ecore_Evas *ee, int w, int h)
+{
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
+ ee->prop.step.w = w;
+ ee->prop.step.h = h;
+ _ecore_evas_x_size_pos_hints_update(ee);
+}
+
+static void
+_ecore_evas_x_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y)
+{
+ int x, y;
+
+ if (!file)
+ {
+ if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
+ if (ee->prop.cursor.file) free(ee->prop.cursor.file);
+ ee->prop.cursor.object = NULL;
+ ee->prop.cursor.file = NULL;
+ ee->prop.cursor.layer = 0;
+ ee->prop.cursor.hot.x = 0;
+ ee->prop.cursor.hot.y = 0;
+ ecore_x_window_cursor_show(ee->engine.x.win, 1);
+ return;
+ }
+ ecore_x_window_cursor_show(ee->engine.x.win, 0);
+ if (!ee->prop.cursor.object) ee->prop.cursor.object = evas_object_image_add(ee->evas);
+ if (ee->prop.cursor.file) free(ee->prop.cursor.file);
+ ee->prop.cursor.file = strdup(file);
+ ee->prop.cursor.layer = layer;
+ ee->prop.cursor.hot.x = hot_x;
+ ee->prop.cursor.hot.y = hot_y;
+ evas_pointer_output_xy_get(ee->evas, &x, &y);
+ evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
+ evas_object_color_set(ee->prop.cursor.object, 255, 255, 255, 255);
+ evas_object_move(ee->prop.cursor.object,
+ x - ee->prop.cursor.hot.x,
+ y - ee->prop.cursor.hot.y);
+ evas_object_image_file_set(ee->prop.cursor.object, ee->prop.cursor.file, NULL);
+ evas_object_image_size_get(ee->prop.cursor.object, &x, &y);
+ evas_object_resize(ee->prop.cursor.object, x, y);
+ evas_object_image_fill_set(ee->prop.cursor.object, 0, 0, x, y);
+ evas_object_pass_events_set(ee->prop.cursor.object, 1);
+ if (evas_pointer_inside_get(ee->evas))
+ evas_object_show(ee->prop.cursor.object);
+}
+
+/*
+ * @param ee
+ * @param layer If < 3, @a ee will be put below all other windows.
+ * If > 5, @a ee will be "always-on-top"
+ * If = 4, @a ee will be put in the default layer.
+ * Acceptable values range from 1 to 255 (0 reserved for
+ * desktop windows)
+ */
+static void
+_ecore_evas_x_layer_set(Ecore_Evas *ee, int layer)
+{
+ if (ee->prop.layer == layer) return;
+
+ /* FIXME: Should this logic be here? */
+ if (layer < 1)
+ layer = 1;
+ else if (layer > 255)
+ layer = 255;
+
+ ee->prop.layer = layer;
+ _ecore_evas_x_layer_update(ee);
+}
+
+static void
+_ecore_evas_x_focus_set(Ecore_Evas *ee, int on __UNUSED__)
+{
+ ecore_x_window_focus(ee->engine.x.win_container);
+}
+
+static void
+_ecore_evas_x_iconified_set(Ecore_Evas *ee, int on)
+{
+ if (((ee->prop.iconified) && (on)) ||
+ ((!ee->prop.iconified) && (!on))) return;
+ ee->prop.iconified = on;
+ if (on)
+ {
+ ecore_x_icccm_hints_set(ee->engine.x.win_container,
+ 1 /* accepts_focus */,
+ ECORE_X_WINDOW_STATE_HINT_ICONIC /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+ ecore_x_icccm_iconic_request_send(ee->engine.x.win_container, ee->engine.x.win_root);
+ }
+ else
+ {
+ ecore_x_icccm_hints_set(ee->engine.x.win_container,
+ 1 /* accepts_focus */,
+ ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+ ecore_evas_show(ee);
+ }
+}
+
+static void
+_ecore_evas_x_borderless_set(Ecore_Evas *ee, int on)
+{
+ if (((ee->prop.borderless) && (on)) ||
+ ((!ee->prop.borderless) && (!on))) return;
+ ee->prop.borderless = on;
+ ecore_x_mwm_borderless_set(ee->engine.x.win_container, ee->prop.borderless);
+}
+
+/* FIXME: This function changes the initial state of the ee
+ * whilest the iconic function changes the current state! */
+static void
+_ecore_evas_x_withdrawn_set(Ecore_Evas *ee, int withdrawn)
+{
+ Ecore_X_Window_State_Hint hint;
+
+ if ((ee->prop.withdrawn && withdrawn) ||
+ (!ee->prop.withdrawn && !withdrawn)) return;
+
+ ee->prop.withdrawn = withdrawn;
+ if (withdrawn)
+ hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ else
+ hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+
+ ecore_x_icccm_hints_set(ee->engine.x.win_container,
+ 1 /* accepts_focus */,
+ hint /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+}
+
+static void
+_ecore_evas_x_sticky_set(Ecore_Evas *ee, int sticky)
+{
+ if ((ee->prop.sticky && sticky) ||
+ (!ee->prop.sticky && !sticky)) return;
+
+ ee->prop.sticky = sticky;
+ ee->engine.x.state.sticky = sticky;
+ if (ee->should_be_visible)
+ ecore_x_netwm_state_request_send(ee->engine.x.win_container, ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_STICKY, -1, sticky);
+ else
+ _ecore_evas_x_state_update(ee);
+}
+
+static void
+_ecore_evas_x_override_set(Ecore_Evas *ee, int on)
+{
+ if (((ee->prop.override) && (on)) ||
+ ((!ee->prop.override) && (!on))) return;
+ ecore_x_window_hide(ee->engine.x.win);
+ ecore_x_window_reparent(ee->engine.x.win, ee->engine.x.win_root, 0, 0);
+ ecore_x_window_del(ee->engine.x.win_container);
+ ecore_evases_hash = evas_hash_del(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win_container), ee);
+ if (on)
+ ee->engine.x.win_container = ecore_x_window_override_new(ee->engine.x.win_root, ee->x, ee->y, ee->w, ee->h);
+ else
+ {
+ Ecore_X_Window_State_Hint hint;
+ if (ee->prop.withdrawn)
+ hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ else
+ hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+
+ ee->engine.x.win_container = ecore_x_window_new(ee->engine.x.win_root, ee->x, ee->y, ee->w, ee->h);
+ ecore_x_icccm_title_set(ee->engine.x.win_container, ee->prop.title);
+ ecore_x_netwm_name_set(ee->engine.x.win_container, ee->prop.title);
+ ecore_x_icccm_name_class_set(ee->engine.x.win_container, ee->prop.name, ee->prop.clas);
+ if (ee->func.fn_delete_request)
+ ecore_x_icccm_protocol_set(ee->engine.x.win_container, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, 1);
+ _ecore_evas_x_size_pos_hints_update(ee);
+ ecore_x_mwm_borderless_set(ee->engine.x.win_container, ee->prop.borderless);
+ _ecore_evas_x_layer_update(ee);
+ ecore_x_icccm_hints_set(ee->engine.x.win_container, 1 /* accepts_focus */,
+ hint /* initial_state */, 0 /* icon_pixmap */, 0 /* icon_mask */,
+ 0 /* icon_window */, 0 /* window_group */, 0 /* is_urgent */);
+ _ecore_evas_x_state_update(ee);
+ }
+ ecore_evases_hash = evas_hash_add(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win_container), ee);
+ ecore_x_window_reparent(ee->engine.x.win, ee->engine.x.win_container, 0, 0);
+ ecore_x_window_show(ee->engine.x.win);
+ if (ee->visible) ecore_x_window_show(ee->engine.x.win_container);
+ if (ee->prop.focused) ecore_x_window_focus(ee->engine.x.win_container);
+ ee->prop.override = on;
+}
+
+static void
+_ecore_evas_x_fullscreen_set(Ecore_Evas *ee, int on)
+{
+ if (((ee->prop.fullscreen) && (on)) ||
+ ((!ee->prop.fullscreen) && (!on))) return;
+ if (on)
+ {
+ int rw, rh;
+
+ ecore_x_window_size_get(0, &rw, &rh);
+ ecore_x_window_move_resize(ee->engine.x.win, 0, 0, rw, rh);
+ ecore_x_window_reparent(ee->engine.x.win, ee->engine.x.win_root, 0, 0);
+ ecore_x_window_raise(ee->engine.x.win);
+ ecore_x_window_show(ee->engine.x.win);
+ ecore_x_window_focus(ee->engine.x.win);
+ ecore_x_window_hide(ee->engine.x.win_container);
+ ecore_x_window_shape_mask_set(ee->engine.x.win_container, 0);
+ if (ee->should_be_visible)
+ {
+ ecore_x_window_show(ee->engine.x.win);
+ ecore_x_window_focus(ee->engine.x.win);
+ }
+ ee->x = 0;
+ ee->y = 0;
+ ee->w = rw;
+ ee->h = rh;
+ }
+ else
+ {
+ int pw, ph;
+
+ ecore_x_window_size_get(ee->engine.x.win_container, &pw, &ph);
+ ecore_x_window_reparent(ee->engine.x.win, ee->engine.x.win_container, 0, 0);
+ ecore_x_window_move_resize(ee->engine.x.win, 0, 0, pw, ph);
+ ecore_x_window_shape_mask_set(ee->engine.x.win, 0);
+ if (ee->should_be_visible) ecore_x_window_show(ee->engine.x.win_container);
+ ee->w = pw;
+ ee->h = ph;
+ }
+ ecore_x_window_move_resize(ee->engine.x.win, 0, 0, ee->w, ee->h);
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ if (ee->prop.avoid_damage)
+ {
+ ecore_evas_avoid_damage_set(ee, 0);
+ ecore_evas_avoid_damage_set(ee, 1);
+ }
+ if (ee->shaped)
+ {
+ _ecore_evas_x_resize_shape(ee);
+ }
+ if ((ee->expecting_resize.w > 0) &&
+ (ee->expecting_resize.h > 0))
+ {
+ if ((ee->expecting_resize.w == ee->w) &&
+ (ee->expecting_resize.h == ee->h))
+ _ecore_evas_x_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
+ ecore_x_current_time_get());
+ ee->expecting_resize.w = 0;
+ ee->expecting_resize.h = 0;
+ }
+ ee->prop.fullscreen = on;
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void
+_ecore_evas_x_avoid_damage_set(Ecore_Evas *ee, int on)
+{
+ Evas_Engine_Info_Software_X11 *einfo;
+
+ if (((ee->prop.avoid_damage) && (on)) ||
+ ((!ee->prop.avoid_damage) && (!on)))
+ return;
+ if (!strcmp(ee->driver, "gl_x11")) return;
+ ee->prop.avoid_damage = on;
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ if (ee->prop.avoid_damage)
+ {
+ ee->engine.x.pmap = ecore_x_pixmap_new(ee->engine.x.win, ee->w, ee->h, 0);
+ ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap);
+ einfo->info.drawable = ee->engine.x.pmap;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ else
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ if (ee->engine.x.direct_resize)
+ {
+/* Turn this off for now
+ ee->engine.x.using_bg_pixmap = 1;
+ ecore_x_window_pixmap_set(ee->engine.x.win, ee->engine.x.pmap);
+ */
+ }
+ }
+ else
+ {
+ if (ee->engine.x.pmap) ecore_x_pixmap_del(ee->engine.x.pmap);
+ if (ee->engine.x.gc) ecore_x_gc_del(ee->engine.x.gc);
+ if (ee->engine.x.using_bg_pixmap)
+ {
+ ecore_x_window_pixmap_set(ee->engine.x.win, 0);
+ ee->engine.x.using_bg_pixmap = 0;
+ }
+ ee->engine.x.pmap = 0;
+ ee->engine.x.gc = 0;
+ einfo->info.drawable = ee->engine.x.win;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+ }
+}
+
+int
+_ecore_evas_x_shutdown(void)
+{
+ _ecore_evas_init_count--;
+ if (_ecore_evas_init_count == 0)
+ {
+ int i;
+
+ while (ecore_evases) ecore_evas_free(ecore_evases);
+ for (i = 0; i < 16; i++)
+ ecore_event_handler_del(ecore_evas_event_handlers[i]);
+ ecore_idle_enterer_del(ecore_evas_idle_enterer);
+ ecore_evas_idle_enterer = NULL;
+ if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown();
+ }
+ if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+ return _ecore_evas_init_count;
+}
+
+static const Ecore_Evas_Engine_Func _ecore_x_engine_func =
+{
+ _ecore_evas_x_free,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_x_callback_delete_request_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_x_move,
+ _ecore_evas_x_resize,
+ _ecore_evas_x_move_resize,
+ _ecore_evas_x_rotation_set,
+ _ecore_evas_x_shaped_set,
+ _ecore_evas_x_show,
+ _ecore_evas_x_hide,
+ _ecore_evas_x_raise,
+ _ecore_evas_x_lower,
+ _ecore_evas_x_title_set,
+ _ecore_evas_x_name_class_set,
+ _ecore_evas_x_size_min_set,
+ _ecore_evas_x_size_max_set,
+ _ecore_evas_x_size_base_set,
+ _ecore_evas_x_size_step_set,
+ _ecore_evas_x_cursor_set,
+ _ecore_evas_x_layer_set,
+ _ecore_evas_x_focus_set,
+ _ecore_evas_x_iconified_set,
+ _ecore_evas_x_borderless_set,
+ _ecore_evas_x_override_set,
+ NULL,
+ _ecore_evas_x_fullscreen_set,
+ _ecore_evas_x_avoid_damage_set,
+ _ecore_evas_x_withdrawn_set,
+ _ecore_evas_x_sticky_set
+};
+#endif
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+Ecore_Evas *
+ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent,
+ int x, int y, int w, int h)
+{
+#ifdef BUILD_ECORE_X
+ Evas_Engine_Info_Software_X11 *einfo;
+ Ecore_Evas *ee;
+ int rmethod;
+
+ rmethod = evas_render_method_lookup("software_x11");
+ if (!rmethod) return NULL;
+ if (!ecore_x_init(disp_name)) return NULL;
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_x_init();
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
+
+ ee->driver = strdup("software_x11");
+ if (disp_name) ee->name = strdup(disp_name);
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ee->x = x;
+ ee->y = y;
+ ee->w = w;
+ ee->h = h;
+
+ ee->prop.max.w = 32767;
+ ee->prop.max.h = 32767;
+ ee->prop.layer = 4;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ ee->engine.x.win_root = parent;
+ ee->engine.x.win_container = ecore_x_window_new(parent, x, y, w, h);
+ ee->engine.x.win = ecore_x_window_override_new(ee->engine.x.win_container, 0, 0, w, h);
+
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ int screen;
+
+ /* FIXME: this is inefficient as its a round trip */
+ screen = DefaultScreen(ecore_x_display_get());
+ if (ScreenCount(ecore_x_display_get()) > 1)
+ {
+ Ecore_X_Window *roots;
+ int num, i;
+
+ num = 0;
+ roots = ecore_x_window_root_list(&num);
+ if (roots)
+ {
+ XWindowAttributes at;
+
+ if (XGetWindowAttributes(ecore_x_display_get(),
+ parent, &at))
+ {
+ for (i = 0; i < num; i++)
+ {
+ if (at.root == roots[i])
+ {
+ screen = i;
+ break;
+ }
+ }
+ }
+ free(roots);
+ }
+ }
+ einfo->info.display = ecore_x_display_get();
+ einfo->info.visual = DefaultVisual(ecore_x_display_get(), screen);
+ einfo->info.colormap = DefaultColormap(ecore_x_display_get(), screen);
+ einfo->info.drawable = ee->engine.x.win;
+ einfo->info.depth = DefaultDepth(ecore_x_display_get(), screen);
+ einfo->info.rotation = 0;
+ einfo->info.debug = 0;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+ evas_key_modifier_add(ee->evas, "Shift");
+ evas_key_modifier_add(ee->evas, "Control");
+ evas_key_modifier_add(ee->evas, "Alt");
+ evas_key_modifier_add(ee->evas, "Meta");
+ evas_key_modifier_add(ee->evas, "Hyper");
+ evas_key_modifier_add(ee->evas, "Super");
+ evas_key_lock_add(ee->evas, "Caps_Lock");
+ evas_key_lock_add(ee->evas, "Num_Lock");
+ evas_key_lock_add(ee->evas, "Scroll_Lock");
+
+ ecore_evases = _ecore_list_prepend(ecore_evases, ee);
+ ecore_evases_hash = evas_hash_add(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win), ee);
+ ecore_evases_hash = evas_hash_add(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win_container), ee);
+ return ee;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+Ecore_X_Window
+ecore_evas_software_x11_window_get(Ecore_Evas *ee)
+{
+#ifdef BUILD_ECORE_X
+ return ee->engine.x.win_container;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+Ecore_X_Window
+ecore_evas_software_x11_subwindow_get(Ecore_Evas *ee)
+{
+#ifdef BUILD_ECORE_X
+ return ee->engine.x.win;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+void
+ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, int on)
+{
+#ifdef BUILD_ECORE_X
+ ee->engine.x.direct_resize = on;
+ if (ee->prop.avoid_damage)
+ {
+ if (ee->engine.x.direct_resize)
+ {
+/* turn this off for now
+ ee->engine.x.using_bg_pixmap = 1;
+ ecore_x_window_pixmap_set(ee->engine.x.win, ee->engine.x.pmap);
+ */
+ }
+ else
+ {
+ ee->engine.x.using_bg_pixmap = 0;
+ ecore_x_window_pixmap_set(ee->engine.x.win, 0);
+ ecore_x_window_area_expose(ee->engine.x.win, 0, 0, ee->w, ee->h);
+ }
+ }
+#else
+ return;
+#endif
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+int
+ecore_evas_software_x11_direct_resize_get(Ecore_Evas *ee)
+{
+#ifdef BUILD_ECORE_X
+ return ee->engine.x.direct_resize;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+Ecore_Evas *
+ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent,
+ int x, int y, int w, int h)
+{
+#ifdef BUILD_ECORE_EVAS_GL
+ Evas_Engine_Info_GL_X11 *einfo;
+ Ecore_Evas *ee;
+ int rmethod;
+
+ rmethod = evas_render_method_lookup("gl_x11");
+ if (!rmethod) return NULL;
+ if (!ecore_x_init(disp_name)) return NULL;
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_x_init();
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
+
+ ee->driver = strdup("gl_x11");
+ if (disp_name) ee->name = strdup(disp_name);
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ee->x = x;
+ ee->y = y;
+ ee->w = w;
+ ee->h = h;
+
+ ee->prop.max.w = 32767;
+ ee->prop.max.h = 32767;
+ ee->prop.layer = 4;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ ee->engine.x.win_root = parent;
+ ee->engine.x.win_container = ecore_x_window_new(parent, x, y, w, h);
+ einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ XSetWindowAttributes attr;
+ int screen;
+
+ /* FIXME: this is inefficient as its a round trip */
+ screen = DefaultScreen(ecore_x_display_get());
+ if (ScreenCount(ecore_x_display_get()) > 1)
+ {
+ Ecore_X_Window *roots;
+ int num, i;
+
+ num = 0;
+ roots = ecore_x_window_root_list(&num);
+ if (roots)
+ {
+ XWindowAttributes at;
+
+ if (XGetWindowAttributes(ecore_x_display_get(),
+ parent, &at))
+ {
+ for (i = 0; i < num; i++)
+ {
+ if (at.root == roots[i])
+ {
+ screen = i;
+ break;
+ }
+ }
+ }
+ free(roots);
+ }
+ }
+ attr.backing_store = NotUseful;
+ attr.override_redirect = True;
+ attr.colormap = einfo->func.best_colormap_get(ecore_x_display_get(), screen);
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.event_mask =
+ KeyPressMask | KeyReleaseMask |
+ ExposureMask | ButtonPressMask | ButtonReleaseMask |
+ EnterWindowMask | LeaveWindowMask |
+ PointerMotionMask | StructureNotifyMask | VisibilityChangeMask |
+ FocusChangeMask | PropertyChangeMask | ColormapChangeMask;
+ attr.bit_gravity = ForgetGravity;
+
+ ee->engine.x.win =
+ XCreateWindow(ecore_x_display_get(),
+ ee->engine.x.win_container,
+ 0, 0,
+ w, h, 0,
+ einfo->func.best_depth_get(ecore_x_display_get(), screen),
+ InputOutput,
+ einfo->func.best_visual_get(ecore_x_display_get(), screen),
+ CWBackingStore | CWColormap |
+ CWBackPixmap | CWBorderPixel |
+ CWBitGravity | CWEventMask |
+ CWOverrideRedirect,
+ &attr);
+ einfo->info.display = ecore_x_display_get();
+ einfo->info.visual = einfo->func.best_visual_get(ecore_x_display_get(), screen);
+ einfo->info.colormap = einfo->func.best_colormap_get(ecore_x_display_get(), screen);
+ einfo->info.drawable = ee->engine.x.win;
+ einfo->info.depth = einfo->func.best_depth_get(ecore_x_display_get(), screen);
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+ evas_key_modifier_add(ee->evas, "Shift");
+ evas_key_modifier_add(ee->evas, "Control");
+ evas_key_modifier_add(ee->evas, "Alt");
+ evas_key_modifier_add(ee->evas, "Meta");
+ evas_key_modifier_add(ee->evas, "Hyper");
+ evas_key_modifier_add(ee->evas, "Super");
+ evas_key_lock_add(ee->evas, "Caps_Lock");
+ evas_key_lock_add(ee->evas, "Num_Lock");
+ evas_key_lock_add(ee->evas, "Scroll_Lock");
+
+ ecore_evases = _ecore_list_prepend(ecore_evases, ee);
+ ecore_evases_hash = evas_hash_add(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win), ee);
+ ecore_evases_hash = evas_hash_add(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win_container), ee);
+ return ee;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+Ecore_X_Window
+ecore_evas_gl_x11_window_get(Ecore_Evas *ee)
+{
+#ifdef BUILD_ECORE_EVAS_GL
+ return ee->engine.x.win_container;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+Ecore_X_Window
+ecore_evas_gl_x11_subwindow_get(Ecore_Evas *ee)
+{
+#ifdef BUILD_ECORE_X
+ return ee->engine.x.win;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+void
+ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, int on)
+{
+#ifdef BUILD_ECORE_X
+ ee->engine.x.direct_resize = on;
+#else
+ return;
+#endif
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+int
+ecore_evas_gl_x11_direct_resize_get(Ecore_Evas *ee)
+{
+#ifdef BUILD_ECORE_X
+ return ee->engine.x.direct_resize;
+#else
+ return 0;
+#endif
+}
+
diff --git a/ecore/src/lib/ecore_fb/.cvsignore b/ecore/src/lib/ecore_fb/.cvsignore
new file mode 100644
index 0000000..8b1bf12
--- /dev/null
+++ b/ecore/src/lib/ecore_fb/.cvsignore
@@ -0,0 +1,6 @@
+.deps
+.libs
+Makefile
+Makefile.in
+ecore_fb.lo
+libecore_fb.la
diff --git a/ecore/src/lib/ecore_fb/CVS/Entries b/ecore/src/lib/ecore_fb/CVS/Entries
new file mode 100644
index 0000000..2a35cfe
--- /dev/null
+++ b/ecore/src/lib/ecore_fb/CVS/Entries
@@ -0,0 +1,7 @@
+/.cvsignore/1.2/Fri Jan 16 16:59:03 2004//THEAD
+/Ecore_Fb.h/1.5/Tue Dec 14 03:21:42 2004//THEAD
+/Makefile.am/1.7/Thu Mar 10 15:19:39 2005//THEAD
+/ecore_fb.c/1.11/Tue May 31 22:42:24 2005//THEAD
+/ecore_fb_keytab.h/1.1/Tue Dec 14 16:12:05 2004//THEAD
+/ecore_fb_private.h/1.2/Tue Sep 23 08:09:31 2003//THEAD
+D
diff --git a/ecore/src/lib/ecore_fb/CVS/Repository b/ecore/src/lib/ecore_fb/CVS/Repository
new file mode 100644
index 0000000..ffa9ebb
--- /dev/null
+++ b/ecore/src/lib/ecore_fb/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/lib/ecore_fb
diff --git a/ecore/src/lib/ecore_fb/CVS/Root b/ecore/src/lib/ecore_fb/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/lib/ecore_fb/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/lib/ecore_fb/CVS/Tag b/ecore/src/lib/ecore_fb/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/lib/ecore_fb/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/lib/ecore_fb/Ecore_Fb.h b/ecore/src/lib/ecore_fb/Ecore_Fb.h
new file mode 100644
index 0000000..9ec1596
--- /dev/null
+++ b/ecore/src/lib/ecore_fb/Ecore_Fb.h
@@ -0,0 +1,116 @@
+#ifndef _ECORE_FB_H
+#define _ECORE_FB_H
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef WIN32
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef GCC_HASCLASSVISIBILITY
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file
+ * @brief Ecore frame buffer system functions.
+ */
+
+/* FIXME:
+ * maybe a new module?
+ * - code to get battery info
+ * - code to get thermal info
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int ECORE_FB_EVENT_KEY_DOWN; /**< FB Key Down event */
+extern int ECORE_FB_EVENT_KEY_UP; /**< FB Key Up event */
+extern int ECORE_FB_EVENT_MOUSE_BUTTON_DOWN; /**< FB Mouse Down event */
+extern int ECORE_FB_EVENT_MOUSE_BUTTON_UP; /**< FB Mouse Up event */
+extern int ECORE_FB_EVENT_MOUSE_MOVE; /**< FB Mouse Move event */
+
+typedef struct _Ecore_Fb_Event_Key_Down Ecore_Fb_Event_Key_Down; /**< FB Key Down event */
+typedef struct _Ecore_Fb_Event_Key_Up Ecore_Fb_Event_Key_Up; /**< FB Key Up event */
+typedef struct _Ecore_Fb_Event_Mouse_Button_Down Ecore_Fb_Event_Mouse_Button_Down; /**< FB Mouse Down event */
+typedef struct _Ecore_Fb_Event_Mouse_Button_Up Ecore_Fb_Event_Mouse_Button_Up; /**< FB Mouse Up event */
+typedef struct _Ecore_Fb_Event_Mouse_Move Ecore_Fb_Event_Mouse_Move; /**< FB Mouse Move event */
+
+struct _Ecore_Fb_Event_Key_Down /** FB Key Down event */
+{
+ char *keyname; /**< The name of the key that was pressed */
+ char *keysymbol; /**< The logical symbol of the key that was pressed */
+ char *key_compose; /**< The UTF-8 string conversion if any */
+};
+
+struct _Ecore_Fb_Event_Key_Up /** FB Key Up event */
+{
+ char *keyname; /**< The name of the key that was released */
+ char *keysymbol; /**< The logical symbol of the key that was pressed */
+ char *key_compose; /**< The UTF-8 string conversion if any */
+};
+
+struct _Ecore_Fb_Event_Mouse_Button_Down /** FB Mouse Down event */
+{
+ int button; /**< Mouse button that was pressed (1 - 32) */
+ int x; /**< Mouse co-ordinates when mouse button was pressed */
+ int y; /**< Mouse co-ordinates when mouse button was pressed */
+ int double_click : 1; /**< Set if click was a double click */
+ int triple_click : 1; /**< Set if click was a triple click */
+};
+
+struct _Ecore_Fb_Event_Mouse_Button_Up /** FB Mouse Up event */
+{
+ int button; /**< Mouse button that was released (1 - 32) */
+ int x; /**< Mouse co-ordinates when mouse button was raised */
+ int y; /**< Mouse co-ordinates when mouse button was raised */
+};
+
+struct _Ecore_Fb_Event_Mouse_Move /** FB Mouse Move event */
+{
+ int x; /**< Mouse co-ordinates where the mouse cursor moved to */
+ int y; /**< Mouse co-ordinates where the mouse cursor moved to */
+};
+
+EAPI int ecore_fb_init(const char *name);
+EAPI int ecore_fb_shutdown(void);
+
+EAPI void ecore_fb_double_click_time_set(double t);
+EAPI double ecore_fb_double_click_time_get(void);
+
+EAPI void ecore_fb_size_get(int *w, int *h);
+
+EAPI void ecore_fb_touch_screen_calibrate_set(int xscale, int xtrans, int yscale, int ytrans, int xyswap);
+EAPI void ecore_fb_touch_screen_calibrate_get(int *xscale, int *xtrans, int *yscale, int *ytrans, int *xyswap);
+
+EAPI void ecore_fb_backlight_set(int on);
+EAPI int ecore_fb_backlight_get(void);
+
+EAPI void ecore_fb_backlight_brightness_set(double br);
+EAPI double ecore_fb_backlight_brightness_get(void);
+
+EAPI void ecore_fb_led_set(int on);
+EAPI void ecore_fb_led_blink_set(double speed);
+
+EAPI void ecore_fb_contrast_set(double cr);
+EAPI double ecore_fb_contrast_get(void);
+
+EAPI double ecore_fb_light_sensor_get(void);
+
+EAPI void ecore_fb_callback_gain_set(void (*func) (void *data), void *data);
+EAPI void ecore_fb_callback_lose_set(void (*func) (void *data), void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ecore/src/lib/ecore_fb/Makefile.am b/ecore/src/lib/ecore_fb/Makefile.am
new file mode 100644
index 0000000..46f9374
--- /dev/null
+++ b/ecore/src/lib/ecore_fb/Makefile.am
@@ -0,0 +1,32 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore
+
+libecore_fb_la_LDFLAGS = -version-info 1:0:0 \
+-L$(top_builddir)/src/lib/ecore/.libs
+
+if BUILD_ECORE_FB
+
+lib_LTLIBRARIES = libecore_fb.la
+include_HEADERS = \
+Ecore_Fb.h
+
+libecore_fb_la_SOURCES = \
+ecore_fb.c \
+ecore_fb_private.h \
+ecore_fb_keytab.h
+
+libecore_fb_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la
+
+libecore_fb_la_DEPENDENCIES = \
+$(top_builddir)/src/lib/ecore/libecore.la
+
+endif
+
+EXTRA_DIST = \
+Ecore_Fb.h \
+ecore_fb.c \
+ecore_fb_private.h
diff --git a/ecore/src/lib/ecore_fb/ecore_fb.c b/ecore/src/lib/ecore_fb/ecore_fb.c
new file mode 100644
index 0000000..14c18fa
--- /dev/null
+++ b/ecore/src/lib/ecore_fb/ecore_fb.c
@@ -0,0 +1,1273 @@
+
+#include "Ecore.h"
+#include "ecore_fb_private.h"
+#include "Ecore_Fb.h"
+#include "ecore_private.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+#include <linux/fb.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+
+typedef struct _Ecore_Fb_Ts_Event Ecore_Fb_Ts_Event;
+typedef struct _Ecore_Fb_Ts_Calibrate Ecore_Fb_Ts_Calibrate;
+typedef struct _Ecore_Fb_Ts_Backlight Ecore_Fb_Ts_Backlight;
+typedef struct _Ecore_Fb_Ts_Contrast Ecore_Fb_Ts_Contrast;
+typedef struct _Ecore_Fb_Ts_Led Ecore_Fb_Ts_Led;
+typedef struct _Ecore_Fb_Ts_Flite Ecore_Fb_Ts_Flite;
+typedef struct _Ecore_Fb_Ps2_Event Ecore_Fb_Ps2_Event;
+
+struct _Ecore_Fb_Ts_Event
+{
+ unsigned short pressure;
+ unsigned short x;
+ unsigned short y;
+ unsigned short _unused;
+};
+
+struct _Ecore_Fb_Ts_Calibrate
+{
+ int xscale;
+ int xtrans;
+ int yscale;
+ int ytrans;
+ int xyswap;
+};
+
+struct _Ecore_Fb_Ts_Backlight
+{
+ int on;
+ unsigned char brightness;
+};
+
+struct _Ecore_Fb_Ts_Contrast
+{
+ unsigned char contrast;
+};
+
+struct _Ecore_Fb_Ts_Led
+{
+ unsigned char on;
+ unsigned char blink_time;
+ unsigned char on_time;
+ unsigned char off_time;
+};
+
+struct _Ecore_Fb_Ts_Flite
+{
+ unsigned char mode;
+ unsigned char pwr;
+ unsigned char brightness;
+};
+
+struct _Ecore_Fb_Ps2_Event
+{
+ unsigned char button;
+ unsigned char x;
+ unsigned char y;
+ unsigned char z;
+};
+
+static void _ecore_fb_size_get(int *w, int *h);
+static int _ecore_fb_ts_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_fb_kbd_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_fb_ps2_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static void _ecore_fb_event_free_key_down(void *data, void *ev);
+static void _ecore_fb_event_free_key_up(void *data, void *ev);
+static int _ecore_fb_signal_usr_handler(void *data, int type, void *ev);
+static void _ecore_fb_vt_switch(int vt);
+
+int ECORE_FB_EVENT_KEY_DOWN = 0;
+int ECORE_FB_EVENT_KEY_UP = 0;
+int ECORE_FB_EVENT_MOUSE_BUTTON_DOWN = 0;
+int ECORE_FB_EVENT_MOUSE_BUTTON_UP = 0;
+int ECORE_FB_EVENT_MOUSE_MOVE = 0;
+
+static Ecore_Event_Handler *_ecore_fb_user_handler = NULL;
+static Ecore_Event_Filter *_ecore_fb_filter_handler = NULL;
+static Ecore_Fd_Handler *_ecore_fb_ts_fd_handler_handle = NULL;
+static Ecore_Fd_Handler *_ecore_fb_kbd_fd_handler_handle = NULL;
+static int _ecore_fb_init_count = 0;
+static int _ecore_fb_ts_fd = 0;
+static int _ecore_fb_ps2_fd = 0;
+static int _ecore_fb_kbd_fd = 0;
+static int _ecore_fb_tty_fd = 0;
+static int _ecore_fb_console_w = 0;
+static int _ecore_fb_console_h = 0;
+static int _ecore_fb_ts_event_byte_count = 0;
+static int _ecore_fb_ps2_event_byte_count = 0;
+static Ecore_Fb_Ts_Event _ecore_fb_ts_event;
+static Ecore_Fb_Ps2_Event _ecore_fb_ps2_event;
+static int _ecore_fb_tty_prev_mode = 0;
+static int _ecore_fb_tty_prev_kd_mode = 0;
+static struct termios _ecore_fb_tty_prev_tio_mode;
+static struct vt_mode _ecore_fb_vt_prev_mode;
+static int _ecore_fb_current_vt = 0;
+static int _ecore_fb_ctrl = 0;
+static int _ecore_fb_alt = 0;
+static int _ecore_fb_shift = 0;
+static int _ecore_fb_lock = 0;
+
+static void (*_ecore_fb_func_fb_lost) (void *data) = NULL;
+static void *_ecore_fb_func_fb_lost_data = NULL;
+static void (*_ecore_fb_func_fb_gain) (void *data) = NULL;
+static void *_ecore_fb_func_fb_gain_data = NULL;
+
+static void *_ecore_fb_event_filter_start(void *data);
+static int _ecore_fb_event_filter_filter(void *data, void *loop_data, int type, void *event);
+static void _ecore_fb_event_filter_end(void *data, void *loop_data);
+
+static double _ecore_fb_double_click_time = 0.25;
+
+static struct _Ecore_Fb_Ts_Calibrate _ecore_fb_ts_cal = {1,1,0,0,0};
+static int _ecore_fb_ts_apply_cal = 0;
+
+static const char *_ecore_fb_kbd_syms[128 * 6] =
+{
+#include "ecore_fb_keytab.h"
+};
+
+static const char *_ecore_fb_btn_syms[128] =
+{
+ "0x00",
+ "Escape",
+ "F1",
+ "F2",
+ "F3",
+ "F4",
+ "Up",
+ "Right",
+ "Left",
+ "Down",
+ "Return",
+ "0x1b",
+ "0x1c",
+ "0x1d",
+ "0x1e",
+ "0x1f",
+ "0x20",
+ "0x21",
+ "0x22",
+ "0x23",
+ "0x24",
+ "0x25",
+ "0x26",
+ "0x27",
+ "0x28",
+ "0x29",
+ "0x2a",
+ "0x2b",
+ "0x2c",
+ "0x2d",
+ "0x2e",
+ "0x2f",
+ "0x30",
+ "0x31",
+ "0x32",
+ "0x33",
+ "0x34",
+ "0x35",
+ "0x36",
+ "0x37",
+ "0x38",
+ "0x39",
+ "0x3a",
+ "0x3b",
+ "0x3c",
+ "0x3d",
+ "0x3e",
+ "0x3f",
+ "0x40",
+ "0x41",
+ "0x42",
+ "0x43",
+ "0x44",
+ "0x45",
+ "0x46",
+ "0x47",
+ "0x48",
+ "0x49",
+ "0x4a",
+ "0x4b",
+ "0x4c",
+ "0x4d",
+ "0x4e",
+ "0x4f",
+ "0x50",
+ "0x51",
+ "0x52",
+ "0x53",
+ "0x54",
+ "0x55",
+ "0x56",
+ "0x57",
+ "0x58",
+ "0x59",
+ "0x5a",
+ "0x5b",
+ "0x5c",
+ "0x5d",
+ "0x5e",
+ "0x5f",
+ "0x60",
+ "0x61",
+ "0x62",
+ "0x63",
+ "0x64",
+ "0x65",
+ "0x66",
+ "0x67",
+ "0x68",
+ "0x69",
+ "0x6a",
+ "0x6b",
+ "0x6c",
+ "0x6d",
+ "0x6e",
+ "0x6f",
+ "0x70",
+ "0x71",
+ "0x72",
+ "0x73",
+ "0x74",
+ "0x75",
+ "0x76",
+ "0x77",
+ "0x78",
+ "0x79",
+ "0x7a",
+ "0x7b",
+ "0x7c",
+ "0x7d",
+ "0x7e",
+ "0x7f"
+};
+
+/**
+ * @defgroup Ecore_FB_Library_Group Framebuffer Library Functions
+ *
+ * Functions used to set up and shut down the Ecore_Framebuffer functions.
+ */
+
+/**
+ * Sets up the Ecore_Fb library.
+ * @param name device target name
+ * @return @c 0 on failure. Otherwise, the number of times the library has
+ * been initialised without being shut down.
+ * @ingroup Ecore_FB_Library_Group
+ */
+int
+ecore_fb_init(const char *name __UNUSED__)
+{
+ int prev_flags;
+
+ _ecore_fb_init_count++;
+ if (_ecore_fb_init_count > 1) return _ecore_fb_init_count;
+ _ecore_fb_ts_fd = open("/dev/touchscreen/0", O_RDONLY);
+ if (_ecore_fb_ts_fd >= 0)
+ {
+ prev_flags = fcntl(_ecore_fb_ts_fd, F_GETFL);
+ fcntl(_ecore_fb_ts_fd, F_SETFL, prev_flags | O_NONBLOCK);
+ _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ts_fd,
+ ECORE_FD_READ,
+ _ecore_fb_ts_fd_handler, NULL,
+ NULL, NULL);
+ if (!_ecore_fb_ts_fd_handler_handle)
+ {
+ close(_ecore_fb_ts_fd);
+ }
+ }
+ if (_ecore_fb_ts_fd < 0)
+ {
+ _ecore_fb_ps2_fd = open("/dev/psaux", O_RDWR);
+ if (_ecore_fb_ps2_fd >= 0)
+ {
+ prev_flags = fcntl(_ecore_fb_ps2_fd, F_GETFL);
+ fcntl(_ecore_fb_ps2_fd, F_SETFL, prev_flags | O_NONBLOCK);
+ _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ps2_fd,
+ ECORE_FD_READ,
+ _ecore_fb_ps2_fd_handler, NULL,
+ NULL, NULL);
+ if (!_ecore_fb_ts_fd_handler_handle)
+ {
+ close(_ecore_fb_ps2_fd);
+ }
+ }
+ }
+ _ecore_fb_kbd_fd = open("/dev/touchscreen/key", O_RDONLY);
+ _ecore_fb_tty_fd = open("/dev/tty0", O_RDONLY);
+ if (_ecore_fb_tty_fd >= 0)
+ {
+ struct termios tio;
+ struct vt_mode new_vtmode;
+ int vtno;
+
+ if ((ioctl(_ecore_fb_tty_fd, VT_OPENQRY, &vtno) != -1))
+ {
+ char buf[64];
+
+ _ecore_fb_current_vt = vtno;
+ ioctl(_ecore_fb_tty_fd, VT_ACTIVATE, _ecore_fb_current_vt);
+ close(_ecore_fb_tty_fd);
+ snprintf(buf, sizeof(buf), "/dev/tty%i", _ecore_fb_current_vt);
+/* FIXME: switch away works.. but switch to the allocated vt doesnt */
+/* printf("%s\n", buf); */
+ _ecore_fb_tty_fd = open(buf, O_RDWR);
+ if (_ecore_fb_current_vt == 1)
+ {
+ Ecore_Event_Signal_User *e;
+
+ e = _ecore_event_signal_user_new();
+ if (e)
+ {
+ e->number = 2;
+ ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL);
+ }
+ }
+ }
+ tcgetattr(_ecore_fb_tty_fd, &_ecore_fb_tty_prev_tio_mode);
+ ioctl(_ecore_fb_tty_fd, KDGETMODE, &_ecore_fb_tty_prev_kd_mode);
+ ioctl(_ecore_fb_tty_fd, KDGKBMODE, &_ecore_fb_tty_prev_mode);
+ ioctl(_ecore_fb_tty_fd, VT_GETMODE, &_ecore_fb_vt_prev_mode);
+ tio.c_iflag = tio.c_oflag = tio.c_cflag = tio.c_lflag = 0;
+ tio.c_cc[VTIME] = 0;
+ tio.c_cc[VMIN] = 1;
+ new_vtmode.mode = VT_PROCESS;
+ new_vtmode.waitv = 0;
+ new_vtmode.relsig = SIGUSR1;
+ new_vtmode.acqsig = SIGUSR2;
+ tcsetattr(_ecore_fb_tty_fd, TCSAFLUSH, &tio);
+ ioctl(_ecore_fb_tty_fd, KDSETMODE, KD_GRAPHICS);
+ ioctl(_ecore_fb_tty_fd, KDSKBMODE, K_MEDIUMRAW);
+ ioctl(_ecore_fb_tty_fd, VT_SETMODE, &new_vtmode);
+ }
+ if (_ecore_fb_kbd_fd <= 0) _ecore_fb_kbd_fd = _ecore_fb_tty_fd;
+ if (_ecore_fb_kbd_fd >= 0)
+ {
+ prev_flags = fcntl(_ecore_fb_kbd_fd, F_GETFL);
+ fcntl(_ecore_fb_kbd_fd, F_SETFL, prev_flags | O_NONBLOCK);
+ _ecore_fb_kbd_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_kbd_fd,
+ ECORE_FD_READ,
+ _ecore_fb_kbd_fd_handler, NULL,
+ NULL, NULL);
+ if (!_ecore_fb_kbd_fd_handler_handle)
+ {
+ tcsetattr(_ecore_fb_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
+ ioctl(_ecore_fb_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
+ ioctl(_ecore_fb_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
+ close(_ecore_fb_tty_fd);
+ close(_ecore_fb_ts_fd);
+ close(_ecore_fb_kbd_fd);
+ if (_ecore_fb_ps2_fd > 0) close(_ecore_fb_ps2_fd);
+ if (_ecore_fb_tty_fd != _ecore_fb_kbd_fd)
+ close(_ecore_fb_tty_fd);
+ ecore_main_fd_handler_del(_ecore_fb_ts_fd_handler_handle);
+ _ecore_fb_ts_fd_handler_handle = NULL;
+ _ecore_fb_init_count--;
+ return 0;
+ }
+ }
+ if (!ECORE_FB_EVENT_KEY_DOWN)
+ {
+ ECORE_FB_EVENT_KEY_DOWN = ecore_event_type_new();
+ ECORE_FB_EVENT_KEY_UP = ecore_event_type_new();
+ ECORE_FB_EVENT_MOUSE_BUTTON_DOWN = ecore_event_type_new();
+ ECORE_FB_EVENT_MOUSE_BUTTON_UP = ecore_event_type_new();
+ ECORE_FB_EVENT_MOUSE_MOVE = ecore_event_type_new();
+
+ }
+ _ecore_fb_size_get(&_ecore_fb_console_w, &_ecore_fb_console_h);
+ _ecore_fb_user_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
+ _ecore_fb_signal_usr_handler,
+ NULL);
+ _ecore_fb_filter_handler = ecore_event_filter_add(_ecore_fb_event_filter_start, _ecore_fb_event_filter_filter, _ecore_fb_event_filter_end, NULL);
+ return _ecore_fb_init_count;
+}
+
+/**
+ * Shuts down the Ecore_Fb library.
+ * @return @c The number of times the system has been initialised without
+ * being shut down.
+ * @ingroup Ecore_FB_Library_Group
+ */
+int
+ecore_fb_shutdown(void)
+{
+ _ecore_fb_init_count--;
+ if (_ecore_fb_init_count > 0) return _ecore_fb_init_count;
+ if (_ecore_fb_init_count < 0)
+ {
+ _ecore_fb_init_count = 0;
+ return 0;
+ }
+ if (_ecore_fb_tty_fd != 0)
+ {
+ tcsetattr(_ecore_fb_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
+ ioctl(_ecore_fb_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
+ ioctl(_ecore_fb_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
+ ioctl(_ecore_fb_tty_fd, VT_SETMODE, &_ecore_fb_vt_prev_mode);
+ close(_ecore_fb_tty_fd);
+ if (_ecore_fb_tty_fd == _ecore_fb_kbd_fd) _ecore_fb_kbd_fd = 0;
+ }
+ if (_ecore_fb_ps2_fd > 0) close(_ecore_fb_ps2_fd);
+ if (_ecore_fb_ts_fd >= 0) close(_ecore_fb_ts_fd);
+ if (_ecore_fb_kbd_fd >= 0) close(_ecore_fb_kbd_fd);
+ if (_ecore_fb_ts_fd_handler_handle)
+ ecore_main_fd_handler_del(_ecore_fb_ts_fd_handler_handle);
+ if (_ecore_fb_kbd_fd_handler_handle)
+ ecore_main_fd_handler_del(_ecore_fb_kbd_fd_handler_handle);
+ if (_ecore_fb_user_handler)
+ ecore_event_handler_del(_ecore_fb_user_handler);
+ ecore_event_filter_del(_ecore_fb_filter_handler);
+ _ecore_fb_ts_fd = 0;
+ _ecore_fb_kbd_fd = 0;
+ _ecore_fb_tty_fd = 0;
+ _ecore_fb_ps2_fd = 0;
+ _ecore_fb_ts_fd_handler_handle = NULL;
+ _ecore_fb_filter_handler = NULL;
+ _ecore_fb_kbd_fd_handler_handle = NULL;
+ _ecore_fb_user_handler = NULL;
+ _ecore_fb_ctrl = 0;
+ _ecore_fb_alt = 0;
+ return _ecore_fb_init_count;
+}
+
+/**
+ * @defgroup Ecore_FB_Click_Group Framebuffer Double Click Functions
+ *
+ * Functions that deal with the double click time of the framebuffer.
+ */
+
+/**
+ * Sets the timeout for a double and triple clicks to be flagged.
+ *
+ * This sets the time between clicks before the double_click flag is
+ * set in a button down event. If 3 clicks occur within double this
+ * time, the triple_click flag is also set.
+ *
+ * @param t The time in seconds
+ * @ingroup Ecore_FB_Click_Group
+ */
+void
+ecore_fb_double_click_time_set(double t)
+{
+ if (t < 0.0) t = 0.0;
+ _ecore_fb_double_click_time = t;
+}
+
+/**
+ * Retrieves the double and triple click flag timeout.
+ *
+ * See @ref ecore_x_double_click_time_set for more information.
+ *
+ * @return The timeout for double clicks in seconds.
+ * @ingroup Ecore_FB_Click_Group
+ */
+double
+ecore_fb_double_click_time_get(void)
+{
+ return _ecore_fb_double_click_time;
+}
+
+/**
+ * Retrieves the width and height of the current frame buffer in pixels.
+ * @param w Pointer to an integer in which to store the width.
+ * @param h Pointer to an interge in which to store the height.
+ */
+void
+ecore_fb_size_get(int *w, int *h)
+{
+ if (w) *w = _ecore_fb_console_w;
+ if (h) *h = _ecore_fb_console_h;
+}
+
+/**
+ * @defgroup Ecore_FB_Calibrate_Group Framebuffer Calibration Functions
+ *
+ * Functions that calibrate the screen.
+ */
+
+/**
+ * Calibrates the touschreen using the given parameters.
+ * @param xscale X scaling, where 256 = 1.0
+ * @param xtrans X translation.
+ * @param yscale Y scaling.
+ * @param ytrans Y translation.
+ * @param xyswap Swap X & Y flag.
+ * @ingroup Ecore_FB_Calibrate_Group
+ */
+void
+ecore_fb_touch_screen_calibrate_set(int xscale, int xtrans, int yscale, int ytrans, int xyswap)
+{
+ Ecore_Fb_Ts_Calibrate cal;
+
+ if (_ecore_fb_ts_fd < 0) return;
+ cal.xscale = xscale;
+ cal.xtrans = xtrans;
+ cal.yscale = yscale;
+ cal.ytrans = ytrans;
+ cal.xyswap = xyswap;
+ if (ioctl(_ecore_fb_ts_fd, TS_SET_CAL, (void *)&cal))
+ {
+ _ecore_fb_ts_cal = cal;
+ _ecore_fb_ts_apply_cal = 1;
+ }
+}
+
+/**
+ * Retrieves the calibration parameters of the touchscreen.
+ * @param xscale Pointer to an integer in which to store the X scaling.
+ * Note that 256 = 1.0.
+ * @param xtrans Pointer to an integer in which to store the X translation.
+ * @param yscale Pointer to an integer in which to store the Y scaling.
+ * @param ytrans Pointer to an integer in which to store the Y translation.
+ * @param xyswap Pointer to an integer in which to store the Swap X & Y flag.
+ * @ingroup Ecore_FB_Calibrate_Group
+ */
+void
+ecore_fb_touch_screen_calibrate_get(int *xscale, int *xtrans, int *yscale, int *ytrans, int *xyswap)
+{
+ Ecore_Fb_Ts_Calibrate cal;
+
+ if (_ecore_fb_ts_fd < 0) return;
+ if (!_ecore_fb_ts_apply_cal)
+ {
+ if (ioctl(_ecore_fb_ts_fd, TS_GET_CAL, (void *)&cal))
+ _ecore_fb_ts_cal = cal;
+ }
+ else
+ cal = _ecore_fb_ts_cal;
+ if (xscale) *xscale = cal.xscale;
+ if (xtrans) *xtrans = cal.xtrans;
+ if (yscale) *yscale = cal.yscale;
+ if (ytrans) *ytrans = cal.ytrans;
+ if (xyswap) *xyswap = cal.xyswap;
+}
+
+/**
+ * @defgroup Ecore_FB_Backlight_Group Framebuffer Backlight Functions
+ *
+ * Functions that deal with the backlight of a framebuffer's screen.
+ */
+
+/**
+ * Turns on or off the backlight.
+ * @param on @c 1 to turn the backlight on. @c 0 to turn it off.
+ * @ingroup Ecore_FB_Backlight_Group
+ */
+void
+ecore_fb_backlight_set(int on)
+{
+ Ecore_Fb_Ts_Backlight bl;
+
+ if (_ecore_fb_ts_fd < 0) return;
+ ioctl(_ecore_fb_ts_fd, TS_GET_BACKLIGHT, &bl);
+ bl.on = on;
+ ioctl(_ecore_fb_ts_fd, TS_SET_BACKLIGHT, &bl);
+}
+
+/**
+ * Retrieves the backlight state.
+ * @return Whether the backlight is on.
+ * @ingroup Ecore_FB_Backlight_Group
+ */
+int
+ecore_fb_backlight_get(void)
+{
+ Ecore_Fb_Ts_Backlight bl;
+
+ if (_ecore_fb_ts_fd < 0) return 1;
+ ioctl(_ecore_fb_ts_fd, TS_GET_BACKLIGHT, &bl);
+ return bl.on;
+}
+
+/**
+ * Sets the backlight brightness.
+ * @param br Brightness between 0.0 to 1.0, where 0.0 is darkest and 1.0
+ * is brightest.
+ * @ingroup Ecore_FB_Backlight_Group
+ */
+void
+ecore_fb_backlight_brightness_set(double br)
+{
+ Ecore_Fb_Ts_Backlight bl;
+ int val;
+
+ if (br < 0) br = 0;
+ if (br > 1) br = 1;
+ val = (int)(255.0 * br);
+ ioctl(_ecore_fb_ts_fd, TS_GET_BACKLIGHT, &bl);
+ bl.brightness = val;
+ ioctl(_ecore_fb_ts_fd, TS_SET_BACKLIGHT, &bl);
+}
+
+/**
+ * Retrieves the backlight brightness.
+ * @return The current backlight brigntess, where 0.0 is the darkest and
+ * 1.0 is the brightest.
+ * @ingroup Ecore_FB_Backlight_Group
+ */
+double
+ecore_fb_backlight_brightness_get(void)
+{
+ Ecore_Fb_Ts_Backlight bl;
+
+ if (_ecore_fb_ts_fd < 0) return 1.0;
+ ioctl(_ecore_fb_ts_fd, TS_GET_BACKLIGHT, &bl);
+ return (double)bl.brightness / 255.0;
+}
+
+/**
+ * @defgroup Ecore_FB_LED_Group Framebuffer LED Functions
+ *
+ * Functions that deal with the light emitting diode connected to the
+ * current framebuffer.
+ */
+
+/**
+ * Sets whether the current framebuffer's LED to the given state.
+ * @param on @c 1 to indicate the LED should be on, @c 0 if it should be off.
+ * @ingroup Ecore_FB_LED_Group
+ */
+void
+ecore_fb_led_set(int on)
+{
+ Ecore_Fb_Ts_Led led;
+
+ if (_ecore_fb_ts_fd < 0) return;
+ if (on) led.on = 1;
+ else led.on = 0;
+ ioctl(_ecore_fb_ts_fd, LED_ON, &led);
+}
+
+/**
+ * Makes the LED of the current framebuffer blink.
+ * @param speed Number to give the speed on the blink.
+ * @ingroup Ecore_FB_LED_Group
+ * @todo Documentation: Work out what speed the units are in.
+ */
+void
+ecore_fb_led_blink_set(double speed)
+{
+ Ecore_Fb_Ts_Led led;
+
+ if (_ecore_fb_ts_fd < 0) return;
+ led.on = 1;
+ led.on_time = (unsigned char)(speed * 10);
+ led.off_time = (unsigned char)(speed * 10);
+ led.blink_time = 255;
+ ioctl(_ecore_fb_ts_fd, LED_ON, &led);
+}
+
+/**
+ * @defgroup Ecore_FB_Contrast_Group Framebuffer Contrast Functions
+ *
+ * Values that set and retrieve the contrast of a framebuffer screen.
+ */
+
+/**
+ * Sets the contrast used by the framebuffer screen.
+ * @param cr Value between 0 and 1 that gives the new contrast of the screen.
+ * @ingroup Ecore_FB_Contrast_Group
+ */
+void
+ecore_fb_contrast_set(double cr)
+{
+ Ecore_Fb_Ts_Contrast ct;
+ int val;
+
+ if (cr < 0) cr = 0;
+ if (cr > 1) cr = 1;
+ val = (int)(255.0 * cr);
+ ct.contrast = val;
+ ioctl(_ecore_fb_ts_fd, TS_SET_CONTRAST, &ct);
+}
+
+/**
+ * Retrieves the contrast currently being used by the framebuffer screen.
+ * @return A value between 0 and 1 that represents the current contrast of the
+ * screen.
+ * @ingroup Ecore_FB_Contrast_Group
+ */
+double
+ecore_fb_contrast_get(void)
+{
+ Ecore_Fb_Ts_Contrast ct;
+
+ if (_ecore_fb_ts_fd < 0) return 1.0;
+ ioctl(_ecore_fb_ts_fd, TS_GET_CONTRAST, &ct);
+ return (double)ct.contrast / 255.0;
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+double
+ecore_fb_light_sensor_get(void)
+{
+ Ecore_Fb_Ts_Flite fl;
+
+ if (_ecore_fb_ts_fd < 0) return 0.0;
+ fl.mode = 3;
+ fl.brightness = 0;
+ ioctl(_ecore_fb_ts_fd, FLITE_ON, &fl);
+ return (double)fl.brightness / 255.0;
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ * @todo Documentation: Find out what this does.
+ */
+void
+ecore_fb_callback_gain_set(void (*func) (void *data), void *data)
+{
+ _ecore_fb_func_fb_gain = func;
+ _ecore_fb_func_fb_gain_data = data;
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ * @todo Documentation: Find out what this does.
+ */
+void
+ecore_fb_callback_lose_set(void (*func) (void *data), void *data)
+{
+ _ecore_fb_func_fb_lost = func;
+ _ecore_fb_func_fb_lost_data = data;
+}
+
+static void
+_ecore_fb_size_get(int *w, int *h)
+{
+ struct fb_var_screeninfo fb_var;
+ int fb;
+
+ fb = open("/dev/fb0", O_RDWR);
+ if (fb < 0)
+ {
+ if (w) *w = 0;
+ if (h) *h = 0;
+ return;
+ }
+ if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) == -1)
+ {
+ if (w) *w = 0;
+ if (h) *h = 0;
+ return;
+ }
+ close(fb);
+ if (w) *w = fb_var.xres;
+ if (h) *h = fb_var.yres;
+}
+
+static int
+_ecore_fb_ts_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ static int prev_x = 0, prev_y = 0, prev_pressure = 0;
+ static double last_time = 0;
+ static double last_last_time = 0;
+ int v = 0;
+
+ do
+ {
+ int x, y, pressure;
+ int num;
+ char *ptr;
+ double t;
+ int did_triple = 0;
+
+ ptr = (char *)&(_ecore_fb_ts_event);
+ ptr += _ecore_fb_ts_event_byte_count;
+ num = sizeof(Ecore_Fb_Ts_Event) - _ecore_fb_ts_event_byte_count;
+ v = read(_ecore_fb_ts_fd, ptr, num);
+ if (v < 0) return 1;
+ _ecore_fb_ts_event_byte_count += v;
+ if (v < num) return 1;
+ t = ecore_time_get();
+ _ecore_fb_ts_event_byte_count = 0;
+ if (_ecore_fb_ts_apply_cal)
+ {
+ x = ((_ecore_fb_ts_cal.xscale * _ecore_fb_ts_event.x) >> 8) + _ecore_fb_ts_cal.xtrans;
+ y = ((_ecore_fb_ts_cal.yscale * _ecore_fb_ts_event.y) >> 8) + _ecore_fb_ts_cal.ytrans;
+ }
+ else
+ {
+ x = _ecore_fb_ts_event.x;
+ y = _ecore_fb_ts_event.y;
+ }
+ pressure = _ecore_fb_ts_event.pressure;
+ /* add event to queue */
+ /* always add a move event */
+ if ((pressure) || (prev_pressure))
+ {
+ /* MOVE: mouse is down and was */
+ Ecore_Fb_Event_Mouse_Move *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Move));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+ if ((pressure) && (!prev_pressure))
+ {
+ /* DOWN: mouse is down, but was not now */
+ Ecore_Fb_Event_Mouse_Button_Down *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ e->button = 1;
+ if ((t - last_time) <= _ecore_fb_double_click_time)
+ e->double_click = 1;
+ if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time))
+ {
+ did_triple = 1;
+ e->triple_click = 1;
+ }
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
+ }
+ else if ((!pressure) && (prev_pressure))
+ {
+ /* UP: mouse was down, but is not now */
+ Ecore_Fb_Event_Mouse_Button_Up *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Up));
+ if (!e) goto retry;
+ e->x = prev_x;
+ e->y = prev_y;
+ e->button = 1;
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
+ }
+ if (did_triple)
+ {
+ last_time = 0;
+ last_last_time = 0;
+ }
+ else
+ {
+ last_last_time = last_time;
+ last_time = t;
+ }
+ retry:
+ prev_x = x;
+ prev_y = y;
+ prev_pressure = pressure;
+ }
+ while (v > 0);
+ return 1;
+}
+
+static int
+_ecore_fb_kbd_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ int v = 0;
+
+ do
+ {
+ unsigned char buf;
+
+ v = read(_ecore_fb_kbd_fd, &buf, 1);
+ if (v < 0) return 1;
+ if (v < 1) return 1;
+ if (buf & 0x80)
+ {
+ /* DOWN */
+ int vt_switch = -1;
+ Ecore_Fb_Event_Key_Down *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Key_Down));
+ if (!e) goto retry;
+ if (_ecore_fb_kbd_fd == _ecore_fb_tty_fd)
+ {
+ int add = 0;
+
+ if (_ecore_fb_shift) add = 1;
+ else if (_ecore_fb_lock) add = 2;
+ e->keyname = strdup(_ecore_fb_kbd_syms[(buf & 0x7f) * 6]);
+ e->keysymbol = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 6) + add]);
+ e->key_compose = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 6) + 3 + add]);
+ }
+ else
+ e->keyname = strdup(_ecore_fb_btn_syms[buf & 0x7f]);
+ if (!e->keyname)
+ {
+ free(e);
+ goto retry;
+ }
+ ecore_event_add(ECORE_FB_EVENT_KEY_DOWN, e, _ecore_fb_event_free_key_down, NULL);
+ if (!strcmp(e->keyname, "Control_L"))
+ _ecore_fb_ctrl++;
+ else if (!strcmp(e->keyname, "Control_R"))
+ _ecore_fb_ctrl++;
+ else if (!strcmp(e->keyname, "Alt_L"))
+ _ecore_fb_alt++;
+ else if (!strcmp(e->keyname, "Alt_R"))
+ _ecore_fb_alt++;
+ else if (!strcmp(e->keyname, "Shift_L"))
+ _ecore_fb_shift++;
+ else if (!strcmp(e->keyname, "Shift_R"))
+ _ecore_fb_shift++;
+ else if (!strcmp(e->keyname, "Caps_Lock"))
+ _ecore_fb_lock++;
+ else if (!strcmp(e->keyname, "F1")) vt_switch = 0;
+ else if (!strcmp(e->keyname, "F2")) vt_switch = 1;
+ else if (!strcmp(e->keyname, "F3")) vt_switch = 2;
+ else if (!strcmp(e->keyname, "F4")) vt_switch = 3;
+ else if (!strcmp(e->keyname, "F5")) vt_switch = 4;
+ else if (!strcmp(e->keyname, "F6")) vt_switch = 5;
+ else if (!strcmp(e->keyname, "F7")) vt_switch = 6;
+ else if (!strcmp(e->keyname, "F8")) vt_switch = 7;
+ else if (!strcmp(e->keyname, "F9")) vt_switch = 8;
+ else if (!strcmp(e->keyname, "F10")) vt_switch = 9;
+ else if (!strcmp(e->keyname, "F11")) vt_switch = 10;
+ else if (!strcmp(e->keyname, "F12")) vt_switch = 11;
+ if (_ecore_fb_ctrl > 2) _ecore_fb_ctrl = 2;
+ if (_ecore_fb_alt > 2) _ecore_fb_alt = 2;
+ if ((vt_switch >= 0) &&
+ (_ecore_fb_ctrl) &&
+ (_ecore_fb_alt))
+ _ecore_fb_vt_switch(vt_switch);
+ }
+ else
+ {
+ /* UP */
+ Ecore_Fb_Event_Key_Up *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Key_Up));
+ if (!e) goto retry;
+ if (_ecore_fb_kbd_fd == _ecore_fb_tty_fd)
+ {
+ int add = 0;
+
+ if (_ecore_fb_shift) add = 1;
+ else if (_ecore_fb_lock) add = 2;
+ e->keyname = strdup(_ecore_fb_kbd_syms[(buf & 0x7f) * 6]);
+ e->keysymbol = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 6) + add]);
+ e->key_compose = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 6) + 3 + add]);
+ }
+ else
+ e->keyname = strdup(_ecore_fb_btn_syms[buf & 0x7f]);
+ if (!e->keyname)
+ {
+ free(e);
+ goto retry;
+ }
+ ecore_event_add(ECORE_FB_EVENT_KEY_UP, e, _ecore_fb_event_free_key_up, NULL);
+ if (!strcmp(e->keyname, "Control_L"))
+ _ecore_fb_ctrl--;
+ else if (!strcmp(e->keyname, "Control_R"))
+ _ecore_fb_ctrl--;
+ else if (!strcmp(e->keyname, "Alt_L"))
+ _ecore_fb_alt--;
+ else if (!strcmp(e->keyname, "Alt_R"))
+ _ecore_fb_alt--;
+ else if (!strcmp(e->keyname, "Shift_L"))
+ _ecore_fb_shift--;
+ else if (!strcmp(e->keyname, "Shift_R"))
+ _ecore_fb_shift--;
+ else if (!strcmp(e->keyname, "Caps_Lock"))
+ _ecore_fb_lock--;
+ if (_ecore_fb_ctrl < 0) _ecore_fb_ctrl = 0;
+ if (_ecore_fb_alt < 0) _ecore_fb_alt = 0;
+ if (_ecore_fb_shift < 0) _ecore_fb_shift = 0;
+ if (_ecore_fb_lock < 0) _ecore_fb_lock = 0;
+ }
+ retry:
+ ;
+ }
+ while (v > 0);
+ return 1;
+}
+
+static int
+_ecore_fb_ps2_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ static int prev_x = 0, prev_y = 0, prev_button = 0;
+ static double last_time = 0;
+ static double last_last_time = 0;
+ int v = 0;
+
+ do
+ {
+ int x, y, button, i;
+ int num;
+ char *ptr;
+ double t;
+ int did_triple = 0;
+
+ ptr = (char *)&(_ecore_fb_ps2_event);
+ ptr += _ecore_fb_ps2_event_byte_count;
+ num = sizeof(Ecore_Fb_Ps2_Event) - _ecore_fb_ps2_event_byte_count;
+ v = read(_ecore_fb_ps2_fd, ptr, num);
+ if (v < 0) return 1;
+ _ecore_fb_ps2_event_byte_count += v;
+ if (v < num) return 1;
+ t = ecore_time_get();
+ _ecore_fb_ps2_event_byte_count = 0;
+ if (_ecore_fb_ps2_event.button & 0x10)
+ x = prev_x + (0xffffff00 | _ecore_fb_ps2_event.x);
+ else
+ x = prev_x + _ecore_fb_ps2_event.x;
+ if (_ecore_fb_ps2_event.button & 0x20)
+ y = prev_y - (0xffffff00 | _ecore_fb_ps2_event.y);
+ else
+ y = prev_y - _ecore_fb_ps2_event.y;
+ button = _ecore_fb_ps2_event.button & 0x7;
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ if (x >= _ecore_fb_console_w) x = _ecore_fb_console_w - 1;
+ if (y >= _ecore_fb_console_h) y = _ecore_fb_console_h - 1;
+ /* add event to queue */
+ /* always add a move event */
+ if (1)
+ {
+ /* MOVE: mouse is down and was */
+ Ecore_Fb_Event_Mouse_Move *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Move));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+ for (i = 1; i <= 3; i++)
+ {
+ int mask;
+
+ mask = 1 << (i - 1);
+ if (((button & mask)) && (!(prev_button & mask)))
+ {
+ /* DOWN: mouse is down, but was not now */
+ Ecore_Fb_Event_Mouse_Button_Down *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ e->button = 1;
+ if ((t - last_time) <= _ecore_fb_double_click_time)
+ e->double_click = 1;
+ if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time))
+ {
+ did_triple = 1;
+ e->triple_click = 1;
+ }
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
+ }
+ else if ((!(button & mask)) && ((prev_button & mask)))
+ {
+ /* UP: mouse was down, but is not now */
+ Ecore_Fb_Event_Mouse_Button_Up *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Up));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ e->button = 1;
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
+ }
+ }
+ if (did_triple)
+ {
+ last_time = 0;
+ last_last_time = 0;
+ }
+ else
+ {
+ last_last_time = last_time;
+ last_time = t;
+ }
+ retry:
+ prev_x = x;
+ prev_y = y;
+ prev_button = button;
+ }
+ while (v > 0);
+ return 1;
+}
+
+static void
+_ecore_fb_event_free_key_down(void *data __UNUSED__, void *ev)
+{
+ Ecore_Fb_Event_Key_Up *e;
+
+ e = ev;
+ free(e->keyname);
+ if (e->keysymbol) free(e->keysymbol);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+}
+
+static void
+_ecore_fb_event_free_key_up(void *data __UNUSED__, void *ev)
+{
+ Ecore_Fb_Event_Key_Up *e;
+
+ e = ev;
+ free(e->keyname);
+ if (e->keysymbol) free(e->keysymbol);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+}
+
+static int
+_ecore_fb_signal_usr_handler(void *data __UNUSED__, int type __UNUSED__, void *ev)
+{
+ Ecore_Event_Signal_User *e;
+
+ e = (Ecore_Event_Signal_User *)ev;
+ if (e->number == 1)
+ {
+ /* release */
+ if (_ecore_fb_func_fb_lost)
+ _ecore_fb_func_fb_lost(_ecore_fb_func_fb_lost_data);
+ if (_ecore_fb_ps2_fd > 0) close(_ecore_fb_ps2_fd);
+ if (_ecore_fb_ts_fd >= 0) close(_ecore_fb_ts_fd);
+ if (_ecore_fb_ts_fd_handler_handle)
+ ecore_main_fd_handler_del(_ecore_fb_ts_fd_handler_handle);
+ _ecore_fb_ps2_fd = 0;
+ _ecore_fb_ts_fd = 0;
+ _ecore_fb_ts_fd_handler_handle = NULL;
+ ioctl(_ecore_fb_tty_fd, VT_RELDISP, 1);
+ }
+ else if (e->number == 2)
+ {
+ int prev_flags;
+
+ /* gain */
+ if (_ecore_fb_func_fb_gain)
+ _ecore_fb_func_fb_gain(_ecore_fb_func_fb_gain_data);
+ if (!_ecore_fb_ts_fd)
+ {
+ _ecore_fb_ts_fd = open("/dev/touchscreen/0", O_RDONLY);
+ if (_ecore_fb_ts_fd >= 0)
+ {
+ prev_flags = fcntl(_ecore_fb_ts_fd, F_GETFL);
+ fcntl(_ecore_fb_ts_fd, F_SETFL, prev_flags | O_NONBLOCK);
+ _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ts_fd,
+ ECORE_FD_READ,
+ _ecore_fb_ts_fd_handler, NULL,
+ NULL, NULL);
+ if (!_ecore_fb_ts_fd_handler_handle)
+ {
+ close(_ecore_fb_ts_fd);
+ }
+ }
+ }
+ if (_ecore_fb_ts_fd < 0)
+ {
+ if (!_ecore_fb_ps2_fd)
+ {
+ _ecore_fb_ps2_fd = open("/dev/psaux", O_RDWR);
+ if (_ecore_fb_ps2_fd >= 0)
+ {
+ prev_flags = fcntl(_ecore_fb_ps2_fd, F_GETFL);
+ fcntl(_ecore_fb_ps2_fd, F_SETFL, prev_flags | O_NONBLOCK);
+ _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ps2_fd,
+ ECORE_FD_READ,
+ _ecore_fb_ps2_fd_handler, NULL,
+ NULL, NULL);
+ if (!_ecore_fb_ts_fd_handler_handle)
+ {
+ close(_ecore_fb_ps2_fd);
+ }
+ }
+ }
+ }
+ if (_ecore_fb_tty_fd != 0)
+ {
+ struct termios tio;
+ struct vt_mode new_vtmode;
+
+ tio.c_iflag = tio.c_oflag = tio.c_cflag = tio.c_lflag = 0;
+ tio.c_cc[VTIME] = 0;
+ tio.c_cc[VMIN] = 1;
+ new_vtmode.mode = VT_PROCESS;
+ new_vtmode.waitv = 0;
+ new_vtmode.relsig = SIGUSR1;
+ new_vtmode.acqsig = SIGUSR2;
+ tcsetattr(_ecore_fb_tty_fd, TCSAFLUSH, &tio);
+ ioctl(_ecore_fb_tty_fd, KDSETMODE, KD_GRAPHICS);
+ ioctl(_ecore_fb_tty_fd, KDSKBMODE, K_MEDIUMRAW);
+ ioctl(_ecore_fb_tty_fd, VT_SETMODE, &new_vtmode);
+ }
+ }
+ return 1;
+}
+
+static void
+_ecore_fb_vt_switch(int vt)
+{
+ vt++;
+ if (_ecore_fb_tty_fd != 0)
+ {
+ if (vt != _ecore_fb_current_vt)
+ {
+ tcsetattr(_ecore_fb_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
+ ioctl(_ecore_fb_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
+ ioctl(_ecore_fb_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
+ }
+ }
+ ioctl(_ecore_fb_tty_fd, VT_ACTIVATE, vt);
+}
+
+typedef struct _Ecore_Fb_Filter_Data Ecore_Fb_Filter_Data;
+
+struct _Ecore_Fb_Filter_Data
+{
+ int last_event_type;
+};
+
+static void *
+_ecore_fb_event_filter_start(void *data __UNUSED__)
+{
+ Ecore_Fb_Filter_Data *filter_data;
+
+ filter_data = calloc(1, sizeof(Ecore_Fb_Filter_Data));
+ return filter_data;
+}
+
+static int
+_ecore_fb_event_filter_filter(void *data __UNUSED__, void *loop_data,int type, void *event __UNUSED__)
+{
+ Ecore_Fb_Filter_Data *filter_data;
+
+ filter_data = loop_data;
+ if (!filter_data) return 1;
+ if (type == ECORE_FB_EVENT_MOUSE_MOVE)
+ {
+ if ((filter_data->last_event_type) == ECORE_FB_EVENT_MOUSE_MOVE)
+ {
+ filter_data->last_event_type = type;
+ return 0;
+ }
+ }
+ filter_data->last_event_type = type;
+ return 1;
+}
+
+static void
+_ecore_fb_event_filter_end(void *data __UNUSED__, void *loop_data)
+{
+ Ecore_Fb_Filter_Data *filter_data;
+
+ filter_data = loop_data;
+ if (filter_data) free(filter_data);
+}
diff --git a/ecore/src/lib/ecore_fb/ecore_fb_keytab.h b/ecore/src/lib/ecore_fb/ecore_fb_keytab.h
new file mode 100644
index 0000000..dfc17b3
--- /dev/null
+++ b/ecore/src/lib/ecore_fb/ecore_fb_keytab.h
@@ -0,0 +1,128 @@
+ "0x00", "0x00", "0x00", /**/"", "", "",/***/
+ "Escape", "Escape", "Escape", /**/"", "", "",/***/
+ "1", "exclam", "1", /**/"1", "!", "1",/***/
+ "2", "at", "2", /**/"2", "@", "2",/***/
+ "3", "numbersign", "3", /**/"3", "#", "3",/***/
+ "4", "dollar", "4", /**/"4", "$", "4",/***/
+ "5", "percent", "5", /**/"5", "%", "5",/***/
+ "6", "asciicircumm", "6", /**/"6", "^", "6",/***/
+ "7", "ampersand", "7", /**/"7", "&", "7",/***/
+ "8", "asterik", "8", /**/"8", "*", "8",/***/
+ "9", "parenleft", "9", /**/"9", "(", "9",/***/
+ "0", "parenright", "0", /**/"0", ")", "0",/***/
+ "minus", "underscore", "minus", /**/"-", "_", "-",/***/
+ "equal", "plus", "equal", /**/"=", "+", "=",/***/
+ "BackSpace", "BackSpace", "BackSpace", /**/"\010","\010","\010",/***/
+ "Tab", "ISO_Left_Tab", "Tab", /**/"\011","", "\011",/***/
+ "q", "Q", "Q", /**/"q", "Q", "Q",/***/
+ "w", "W", "W", /**/"w", "W", "W",/***/
+ "e", "E", "E", /**/"e", "E", "E",/***/
+ "r", "R", "R", /**/"r", "R", "R",/***/
+ "t", "T", "T", /**/"t", "T", "T",/***/
+ "y", "Y", "Y", /**/"y", "Y", "Y",/***/
+ "u", "U", "U", /**/"u", "U", "U",/***/
+ "i", "I", "I", /**/"i", "I", "I",/***/
+ "o", "O", "O", /**/"o", "O", "O",/***/
+ "p", "P", "P", /**/"p", "P", "P",/***/
+ "bracketleft", "braceleft", "bracketleft", /**/"[", "{", "[",/***/
+ "bracketright", "braceright", "bracketright", /**/"]", "}", "]",/***/
+ "Return", "Return", "Return", /**/"\015","\015","\015",/***/
+ "Control_L", "Control_L", "Control_L", /**/"", "", "",/***/
+ "a", "A", "A", /**/"a", "A", "A",/***/
+ "s", "S", "S", /**/"s", "S", "S",/***/
+ "d", "D", "D", /**/"d", "D", "D",/***/
+ "f", "F", "F", /**/"f", "F", "F",/***/
+ "g", "G", "G", /**/"g", "G", "G",/***/
+ "h", "h", "H", /**/"h", "H", "H",/***/
+ "j", "J", "J", /**/"j", "J", "J",/***/
+ "k", "K", "K", /**/"k", "K", "K",/***/
+ "l", "L", "L", /**/"l", "L", "L",/***/
+ "semicolon", "colon", "semicolon", /**/";", ":", ";",/***/
+ "apostrophe", "quotedbl", "apostrophe", /**/"'", "\"", "'",/***/
+ "grave", "asciitilde", "grave", /**/"`", "~", "`",/***/
+ "Shift_L", "Shift_L", "Shift_L", /**/"", "", "",/***/
+ "backslash", "bar", "backslash", /**/"\\", "|", "\\",/***/
+ "z", "Z", "Z", /**/"z", "Z", "Z",/***/
+ "x", "X", "X", /**/"x", "X", "X",/***/
+ "c", "C", "C", /**/"c", "C", "C",/***/
+ "v", "V", "V", /**/"v", "V", "V",/***/
+ "b", "B", "B", /**/"b", "B", "B",/***/
+ "n", "N", "N", /**/"n", "N", "N",/***/
+ "m", "M", "M", /**/"m", "M", "M",/***/
+ "comma", "less", "comma", /**/",", "<", ",",/***/
+ "period", "greater", "period", /**/".", ">", ".",/***/
+ "slash", "question", "slash", /**/"/", "?", "/",/***/
+ "Shift_R", "Shift_R", "Shift_R", /**/"", "", "",/***/
+ "KP_Multiply", "KP_Multiply", "KP_Multiply", /**/"", "*", "",/***/
+ "Alt_L", "Alt_L", "Alt_L", /**/"", "", "",/***/
+ "space", "space", "space", /**/" ", " ", " ",/***/
+ "Caps_Lock", "Caps_Lock", "Caps_Lock", /**/"", "", "",/***/
+ "F1", "F1", "F1", /**/"", "", "",/***/
+ "F2", "F2", "F2", /**/"", "", "",/***/
+ "F3", "F3", "F3", /**/"", "", "",/***/
+ "F4", "F4", "F4", /**/"", "", "",/***/
+ "F5", "F5", "F5", /**/"", "", "",/***/
+ "F6", "F6", "F6", /**/"", "", "",/***/
+ "F7", "F7", "F7", /**/"", "", "",/***/
+ "F8", "F8", "F8", /**/"", "", "",/***/
+ "F9", "F9", "F9", /**/"", "", "",/***/
+ "F10", "F10", "F10", /**/"", "", "",/***/
+ "Num_Lock", "Num_Lock", "Num_Lock", /**/"", "", "",/***/
+ "Scroll_Lock", "Scroll_Lock", "Scroll_Lock", /**/"", "", "",/***/
+ "KP_Home", "KP_7", "KP_Home", /**/"", "7", "",/***/
+ "KP_Up", "KP_8", "KP_Up", /**/"", "8", "",/***/
+ "KP_Prior", "KP_9", "KP_Prior", /**/"", "9", "",/***/
+ "KP_Subtract", "KP_Subtract", "KP_Subtract", /**/"", "", "",/***/
+ "KP_Left", "KP_4", "KP_Left", /**/"", "4", "",/***/
+ "KP_Begin", "KP_5", "KP_Begin", /**/"", "5", "",/***/
+ "KP_Right", "KP_6", "KP_Right", /**/"", "6", "",/***/
+ "KP_Add", "KP_Add", "KP_Add", /**/"", "", "",/***/
+ "KP_End", "KP_1", "KP_End", /**/"", "1", "",/***/
+ "KP_Down", "KP_2", "KP_Down", /**/"", "2", "",/***/
+ "KP_Next", "KP_3", "KP_Next", /**/"", "3", "",/***/
+ "KP_Insert", "KP_0", "KP_Insert", /**/"", "0", "",/***/
+ "KP_Delete", "KP_Decimal", "KP_Delete", /**/"", ".", "",/***/
+ "0x54", "0x54", "0x54", /**/"", "", "",/***/
+ "0x55", "0x55", "0x55", /**/"", "", "",/***/
+ "0x56", "0x56", "0x56", /**/"", "", "",/***/
+ "F11", "F11", "F11", /**/"", "", "",/***/
+ "F12", "F12", "F12", /**/"", "", "",/***/
+ "0x59", "0x59", "0x59", /**/"", "", "",/***/
+ "0x5a", "0x5a", "0x5a", /**/"", "", "",/***/
+ "0x5b", "0x5b", "0x5b", /**/"", "", "",/***/
+ "0x5c", "0x5c", "0x5c", /**/"", "", "",/***/
+ "0x5d", "0x5d", "0x5d", /**/"", "", "",/***/
+ "0x5e", "0x5e", "0x5e", /**/"", "", "",/***/
+ "0x5f", "0x5f", "0x5f", /**/"", "", "",/***/
+ "KP_Enter", "KP_Enter", "KP_Enter", /**/"", "", "",/***/
+ "Control_R", "Control_R", "Control_R", /**/"", "", "",/***/
+ "KP_Divide", "KP_Divide", "KP_Divide", /**/"", "", "",/***/
+ "Print", "Print", "Print", /**/"", "", "",/***/
+ "Alt_R", "Alt_R", "Alt_R", /**/"", "", "",/***/
+ "0x65", "0x65", "0x65", /**/"", "", "",/***/
+ "Home", "Home", "Home", /**/"", "", "",/***/
+ "Up", "Up", "Up", /**/"", "", "",/***/
+ "Prior", "Prior", "Prior", /**/"", "", "",/***/
+ "Left", "Left", "Left", /**/"", "", "",/***/
+ "Right", "Right", "Right", /**/"", "", "",/***/
+ "End", "End", "End", /**/"", "", "",/***/
+ "Down", "Down", "Down", /**/"", "", "",/***/
+ "Next", "Next", "Next", /**/"", "", "",/***/
+ "Insert", "Insert", "Insert", /**/"", "", "",/***/
+ "Delete", "Delete", "Delete", /**/"\177","\177","\177",/***/
+ "0x70", "0x70", "0x70", /**/"", "", "",/***/
+ "0x71", "0x71", "0x71", /**/"", "", "",/***/
+ "0x72", "0x72", "0x72", /**/"", "", "",/***/
+ "0x73", "0x73", "0x73", /**/"", "", "",/***/
+ "0x74", "0x74", "0x74", /**/"", "", "",/***/
+ "0x75", "0x75", "0x75", /**/"", "", "",/***/
+ "0x76", "0x76", "0x76", /**/"", "", "",/***/
+ "Pause", "Pause", "Pause", /**/"", "", "",/***/
+ "0x78", "0x78", "0x78", /**/"", "", "",/***/
+ "0x79", "0x79", "0x79", /**/"", "", "",/***/
+ "0x7a", "0x7a", "0x7a", /**/"", "", "",/***/
+ "0x7b", "0x7b", "0x7b", /**/"", "", "",/***/
+ "0x7c", "0x7c", "0x7c", /**/"", "", "",/***/
+ "Super_L", "Super_L", "Super_L", /**/"", "", "",/***/
+ "Super_R", "Super_R", "Super_R", /**/"", "", "",/***/
+ "0x7f", "0x7f", "0x7f", /**/"", "", "" /***/
diff --git a/ecore/src/lib/ecore_fb/ecore_fb_private.h b/ecore/src/lib/ecore_fb/ecore_fb_private.h
new file mode 100644
index 0000000..3c27a34
--- /dev/null
+++ b/ecore/src/lib/ecore_fb/ecore_fb_private.h
@@ -0,0 +1,30 @@
+#ifndef _ECORE_FB_PRIVATE_H
+#define _ECORE_FB_PRIVATE_H
+
+/* hacks to stop people NEEDING #include <linux/h3600_ts.h> */
+#ifndef TS_SET_CAL
+#define TS_SET_CAL 0x4014660b
+#endif
+#ifndef TS_GET_CAL
+#define TS_GET_CAL 0x8014660a
+#endif
+#ifndef TS_SET_BACKLIGHT
+#define TS_SET_BACKLIGHT 0x40086614
+#endif
+#ifndef TS_GET_BACKLIGHT
+#define TS_GET_BACKLIGHT 0x80086614
+#endif
+#ifndef LED_ON
+#define LED_ON 0x40046605
+#endif
+#ifndef TS_SET_CONTRAST
+#define TS_SET_CONTRAST 0x40046615
+#endif
+#ifndef TS_GET_CONTRAST
+#define TS_GET_CONTRAST 0x80046615
+#endif
+#ifndef FLITE_ON
+#define FLITE_ON 0x40046607
+#endif
+
+#endif
diff --git a/ecore/src/lib/ecore_file/.cvsignore b/ecore/src/lib/ecore_file/.cvsignore
new file mode 100644
index 0000000..be74149
--- /dev/null
+++ b/ecore/src/lib/ecore_file/.cvsignore
@@ -0,0 +1,6 @@
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+libecore_file.la
diff --git a/ecore/src/lib/ecore_file/CVS/Entries b/ecore/src/lib/ecore_file/CVS/Entries
new file mode 100644
index 0000000..5ad56ea
--- /dev/null
+++ b/ecore/src/lib/ecore_file/CVS/Entries
@@ -0,0 +1,13 @@
+/.cvsignore/1.1/Sun Feb 20 12:17:07 2005//THEAD
+/Ecore_File.h/1.13/Wed Jun 22 14:51:36 2005//THEAD
+/Makefile.am/1.8/Fri Jun 17 23:52:32 2005//THEAD
+/ecore_file.c/1.11/Fri Jun 17 23:52:32 2005//THEAD
+/ecore_file_download.c/1.5/Wed Jun 22 14:51:37 2005//THEAD
+/ecore_file_monitor.c/1.2/Wed Mar 30 06:35:12 2005//THEAD
+/ecore_file_monitor_fam.c/1.4/Wed Apr 20 09:20:33 2005//THEAD
+/ecore_file_monitor_inotify.c/1.4/Wed Apr 20 09:20:33 2005//THEAD
+/ecore_file_monitor_poll.c/1.8/Wed Apr 20 09:20:33 2005//THEAD
+/ecore_file_path.c/1.2/Sun Jun 12 14:08:46 2005//THEAD
+/ecore_file_private.h/1.7/Fri Jun 17 23:52:32 2005//THEAD
+/ecore_file_utils.c/1.1/Sun Feb 20 12:17:07 2005//THEAD
+D
diff --git a/ecore/src/lib/ecore_file/CVS/Repository b/ecore/src/lib/ecore_file/CVS/Repository
new file mode 100644
index 0000000..bba5b7a
--- /dev/null
+++ b/ecore/src/lib/ecore_file/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/lib/ecore_file
diff --git a/ecore/src/lib/ecore_file/CVS/Root b/ecore/src/lib/ecore_file/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/lib/ecore_file/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/lib/ecore_file/CVS/Tag b/ecore/src/lib/ecore_file/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/lib/ecore_file/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/lib/ecore_file/Ecore_File.h b/ecore/src/lib/ecore_file/Ecore_File.h
new file mode 100644
index 0000000..541d51a
--- /dev/null
+++ b/ecore/src/lib/ecore_file/Ecore_File.h
@@ -0,0 +1,91 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#ifndef ECORE_FILE_H
+#define ECORE_FILE_H
+
+/*
+ * TODO:
+ * - More events, move/rename of directory file
+ */
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef WIN32
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef GCC_HASCLASSVISIBILITY
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+#endif
+
+#include <Ecore.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef struct _Ecore_File_Monitor Ecore_File_Monitor;
+ typedef struct _Ecore_File_Monitor_Event Ecore_File_Monitor_Event;
+
+ typedef enum
+ {
+ ECORE_FILE_EVENT_NONE,
+ ECORE_FILE_EVENT_CREATED_FILE,
+ ECORE_FILE_EVENT_CREATED_DIRECTORY,
+ ECORE_FILE_EVENT_DELETED_FILE,
+ ECORE_FILE_EVENT_DELETED_DIRECTORY,
+ ECORE_FILE_EVENT_DELETED_SELF,
+ ECORE_FILE_EVENT_MODIFIED
+ } Ecore_File_Event;
+
+
+ EAPI int ecore_file_init (void);
+ EAPI int ecore_file_shutdown (void);
+ EAPI time_t ecore_file_mod_time (const char *file);
+ EAPI int ecore_file_exists (const char *file);
+ EAPI int ecore_file_is_dir (const char *file);
+ EAPI int ecore_file_mkdir (const char *dir);
+ EAPI int ecore_file_rmdir (const char *dir);
+ EAPI int ecore_file_mkpath (const char *path);
+ EAPI int ecore_file_cp (const char *src, const char *dst);
+ EAPI int ecore_file_mv (const char *src, const char *dst);
+ EAPI char *ecore_file_realpath (const char *file);
+ EAPI int ecore_file_unlink (const char *file);
+ EAPI char *ecore_file_get_file (char *path);
+ EAPI char *ecore_file_get_dir (char *path);
+
+ EAPI int ecore_file_can_exec (const char *file);
+ EAPI char *ecore_file_readlink (const char *link);
+ EAPI Ecore_List *ecore_file_ls (const char *dir);
+
+ EAPI Ecore_File_Monitor *ecore_file_monitor_add(const char *path,
+ void (*func) (void *data,
+ Ecore_File_Monitor *ecore_file_monitor,
+ Ecore_File_Event event,
+ const char *path),
+ void *data);
+ EAPI void ecore_file_monitor_del(Ecore_File_Monitor *ecore_file_monitor);
+ EAPI const char *ecore_file_monitor_path_get(Ecore_File_Monitor *ecore_file_monitor);
+
+ EAPI int ecore_file_app_installed(const char *app);
+
+ EAPI int ecore_file_download(const char *url, const char *dst,
+ void (*completion_cb)(void *data,
+ const char *file,
+ int status),
+ void *data);
+ EAPI int ecore_file_download_protocol_available(const char *protocol);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ecore/src/lib/ecore_file/Makefile.am b/ecore/src/lib/ecore_file/Makefile.am
new file mode 100644
index 0000000..6aceac6
--- /dev/null
+++ b/ecore/src/lib/ecore_file/Makefile.am
@@ -0,0 +1,40 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore \
+@curl_cflags@
+
+libecore_file_la_LDFLAGS = -version-info 1:0:0 \
+-L$(top_builddir)/src/lib/ecore/.libs
+
+if BUILD_ECORE_FILE
+
+lib_LTLIBRARIES = libecore_file.la
+include_HEADERS = Ecore_File.h
+
+libecore_file_la_SOURCES = \
+ecore_file.c \
+ecore_file_private.h \
+ecore_file_monitor.c \
+ecore_file_monitor_fam.c \
+ecore_file_monitor_inotify.c \
+ecore_file_monitor_poll.c \
+ecore_file_path.c \
+ecore_file_download.c
+
+libecore_file_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+@fam_libs@ @curl_libs@
+
+endif
+
+EXTRA_DIST = \
+ecore_file.c \
+ecore_file_private.h \
+ecore_file_monitor.c \
+ecore_file_monitor_fam.c \
+ecore_file_monitor_inotify.c \
+ecore_file_monitor_poll.c \
+ecore_file_path.c
+
diff --git a/ecore/src/lib/ecore_file/ecore_file.c b/ecore/src/lib/ecore_file/ecore_file.c
new file mode 100644
index 0000000..e71fc19
--- /dev/null
+++ b/ecore/src/lib/ecore_file/ecore_file.c
@@ -0,0 +1,257 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "ecore_file_private.h"
+
+/* externally accessible functions */
+int
+ecore_file_init()
+{
+ if (!ecore_file_monitor_init())
+ return 0;
+ if (!ecore_file_path_init())
+ return 0;
+ if (!ecore_file_download_init())
+ return 0;
+ return 1;
+}
+
+int
+ecore_file_shutdown()
+{
+ if (!ecore_file_monitor_shutdown())
+ return 0;
+ if (!ecore_file_path_shutdown())
+ return 0;
+ if (!ecore_file_download_shutdown())
+ return 0;
+ return 1;
+}
+
+time_t
+ecore_file_mod_time(const char *file)
+{
+ struct stat st;
+
+ if (stat(file, &st) < 0) return 0;
+ return st.st_mtime;
+}
+
+int
+ecore_file_exists(const char *file)
+{
+ struct stat st;
+
+ if (stat(file, &st) < 0) return 0;
+ return 1;
+}
+
+int
+ecore_file_is_dir(const char *file)
+{
+ struct stat st;
+
+ if (stat(file, &st) < 0) return 0;
+ if (S_ISDIR(st.st_mode)) return 1;
+ return 0;
+}
+
+static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
+
+int
+ecore_file_mkdir(const char *dir)
+{
+ if (mkdir(dir, default_mode) < 0) return 0;
+ return 1;
+}
+
+int
+ecore_file_rmdir(const char *dir)
+{
+ if (rmdir(dir) < 0) return 0;
+ return 1;
+}
+
+int
+ecore_file_unlink(const char *file)
+{
+ if (unlink(file) < 0) return 0;
+ return 1;
+}
+
+int
+ecore_file_mkpath(const char *path)
+{
+ char ss[PATH_MAX];
+ int i;
+
+ ss[0] = 0;
+ i = 0;
+ while (path[i])
+ {
+ if (i == sizeof(ss) - 1) return 0;
+ ss[i] = path[i];
+ ss[i + 1] = 0;
+ if (path[i] == '/')
+ {
+ ss[i] = 0;
+ if ((ecore_file_exists(ss)) && (!ecore_file_is_dir(ss))) return 0;
+ else if (!ecore_file_exists(ss)) ecore_file_mkdir(ss);
+ ss[i] = '/';
+ }
+ i++;
+ }
+ if ((ecore_file_exists(ss)) && (!ecore_file_is_dir(ss))) return 0;
+ else if (!ecore_file_exists(ss)) ecore_file_mkdir(ss);
+ return 1;
+}
+
+int
+ecore_file_cp(const char *src, const char *dst)
+{
+ FILE *f1, *f2;
+ char buf[16384];
+ size_t num;
+
+ f1 = fopen(src, "rb");
+ if (!f1) return 0;
+ f2 = fopen(dst, "wb");
+ if (!f2)
+ {
+ fclose(f1);
+ return 0;
+ }
+ while ((num = fread(buf, 1, 16384, f1)) > 0) fwrite(buf, 1, num, f2);
+ fclose(f1);
+ fclose(f2);
+ return 1;
+}
+
+int
+ecore_file_mv(const char *src, const char *dst)
+{
+ if (ecore_file_exists(dst)) return 0;
+ if (rename(src, dst)) return 0;
+ return 1;
+}
+
+char *
+ecore_file_realpath(const char *file)
+{
+ char buf[PATH_MAX];
+ struct stat st;
+
+ if (!realpath(file, buf) || stat(buf, &st)) return strdup("");
+ return strdup(buf);
+}
+
+char *
+ecore_file_get_file(char *path)
+{
+ char *result = NULL;
+
+ if (!path) return NULL;
+ if ((result = strrchr(path, '/'))) result++;
+ else result = path;
+ return result;
+}
+
+char *
+ecore_file_get_dir(char *file)
+{
+ char *p;
+ char buf[PATH_MAX];
+
+ strncpy(buf, file, PATH_MAX);
+ p = strrchr(buf, '/');
+ if (!p)
+ {
+ return strdup(file);
+ }
+ *p = 0;
+ return strdup(buf);
+}
+
+int
+ecore_file_can_exec(const char *file)
+{
+ static int have_uid = 0;
+ static uid_t uid = -1;
+ static gid_t gid = -1;
+ struct stat st;
+ int ok;
+
+ if (!file) return 0;
+ if (stat(file, &st) < 0) return 0;
+
+ ok = 0;
+ if (!have_uid) uid = getuid();
+ if (!have_uid) gid = getgid();
+ have_uid = 1;
+ if (st.st_uid == uid)
+ {
+ if (st.st_mode & S_IXUSR) ok = 1;
+ }
+ else if (st.st_gid == gid)
+ {
+ if (st.st_mode & S_IXGRP) ok = 1;
+ }
+ else
+ {
+ if (st.st_mode & S_IXOTH) ok = 1;
+ }
+ return(ok);
+}
+
+char *
+ecore_file_readlink(const char *link)
+{
+ char buf[PATH_MAX];
+ int count;
+
+ if ((count = readlink(link, buf, sizeof(buf))) < 0) return NULL;
+ buf[count] = 0;
+ return strdup(buf);
+}
+
+Ecore_List *
+ecore_file_ls(const char *dir)
+{
+ DIR *dirp;
+ struct dirent *dp;
+ Ecore_List *list;
+
+ dirp = opendir(dir);
+ if (!dirp) return NULL;
+ list = ecore_list_new();
+ while ((dp = readdir(dirp)))
+ {
+ if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
+ {
+ char *file, *f;
+
+ /* insertion sort */
+ ecore_list_goto_first(list);
+ while ((file = ecore_list_current(list)))
+ {
+ if (strcmp(file, dp->d_name) > 0)
+ {
+ f = strdup(dp->d_name);
+ ecore_list_insert(list, f);
+ break;
+ }
+ ecore_list_next(list);
+ }
+ /* nowhwre to go? just append it */
+ if (!file)
+ {
+ f = strdup(dp->d_name);
+ ecore_list_append(list, f);
+ }
+ }
+ }
+ closedir(dirp);
+
+ ecore_list_goto_first(list);
+ return list;
+}
diff --git a/ecore/src/lib/ecore_file/ecore_file_download.c b/ecore/src/lib/ecore_file/ecore_file_download.c
new file mode 100644
index 0000000..500a051
--- /dev/null
+++ b/ecore/src/lib/ecore_file/ecore_file_download.c
@@ -0,0 +1,292 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "ecore_file_private.h"
+
+#ifdef HAVE_CURL
+#include <curl/curl.h>
+
+typedef struct _Ecore_File_Download_Job Ecore_File_Download_Job;
+
+struct _Ecore_File_Download_Job
+{
+ Ecore_Fd_Handler *fd_handler;
+ CURL *curl;
+ void (*completion_cb)(void *data, const char *file, int status);
+ void *data;
+ FILE *file;
+ char *dst;
+};
+
+Ecore_File_Download_Job *_ecore_file_download_curl(const char *url, const char *dst,
+ void (*completion_cb)(void *data, const char *file, int status),
+ void *data);
+static int _ecore_file_download_curl_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+
+static CURLM *curlm;
+static Ecore_List *_job_list;
+static fd_set _current_fd_set;
+#endif
+
+int
+ecore_file_download_init(void)
+{
+#ifdef HAVE_CURL
+ FD_ZERO(&_current_fd_set);
+ _job_list = ecore_list_new();
+ if (!_job_list) return 0;
+
+ if (curl_global_init(CURL_GLOBAL_NOTHING)) return 0;
+
+ curlm = curl_multi_init();
+ if (!curlm)
+ {
+ ecore_list_destroy(_job_list);
+ _job_list = NULL;
+ return 0;
+ }
+#endif
+ return 1;
+}
+
+int
+ecore_file_download_shutdown(void)
+{
+#ifdef HAVE_CURL
+ Ecore_File_Download_Job *job;
+
+ if (!ecore_list_is_empty(_job_list))
+ {
+ ecore_list_goto_first(_job_list);
+ while ((job = ecore_list_next(_job_list)))
+ {
+ ecore_main_fd_handler_del(job->fd_handler);
+ curl_multi_remove_handle(curlm, job->curl);
+ curl_easy_cleanup(job->curl);
+ fclose(job->file);
+ free(job->dst);
+ free(job);
+ }
+ }
+ ecore_list_destroy(_job_list);
+ curl_multi_cleanup(curlm);
+ curl_global_cleanup();
+#endif
+ return 1;
+}
+
+int
+ecore_file_download(const char *url, const char *dst,
+ void (*completion_cb)(void *data, const char *file, int status),
+ void *data)
+{
+ if (!ecore_file_is_dir(ecore_file_get_dir(dst))) return 0;
+ if (ecore_file_exists(dst)) return 0;
+
+ /* FIXME: Add handlers for http and ftp! */
+ if (!strncmp(url, "file://", 7))
+ {
+ /* FIXME: Maybe fork? Might take a while to copy.
+ * Check filesize? */
+ /* Just copy it */
+
+ url += 7;
+ /* skip hostname */
+ url = strchr(url, '/');
+ return ecore_file_cp(url, dst);
+ }
+#ifdef HAVE_CURL
+ else if ((!strncmp(url, "http://", 7)) ||
+ (!strncmp(url, "ftp://", 6)))
+ {
+ /* download */
+ Ecore_File_Download_Job *job;
+
+ job = _ecore_file_download_curl(url, dst, completion_cb, data);
+ if (job)
+ return 1;
+ else
+ return 0;
+ }
+#endif
+ else
+ {
+ return 0;
+ }
+}
+
+int
+ecore_file_download_protocol_available(const char *protocol)
+{
+ if (!strncmp(protocol, "file://", 7)) return 1;
+#ifdef HAVE_CURL
+ else if (!strncmp(protocol, "http://", 7)) return 1;
+ else if (!strncmp(protocol, "ftp://", 6)) return 1;
+#endif
+
+ return 0;
+}
+
+#ifdef HAVE_CURL
+/*
+ * FIXME: Use
+ * CURLOPT_PROGRESSFUNCTION and CURLOPT_PROGRESSDATA to
+ * get reports on progress.
+ * And maybe other nifty functions...
+ */
+Ecore_File_Download_Job *
+_ecore_file_download_curl(const char *url, const char *dst,
+ void (*completion_cb)(void *data, const char *file,
+ int status),
+ void *data)
+{
+ CURLMsg *curlmsg;
+ fd_set read_set, write_set, exc_set;
+ int fd_max;
+ int fd;
+ int flags;
+ int n_remaining, still_running;
+ Ecore_File_Download_Job *job;
+
+ job = calloc(1, sizeof(Ecore_File_Download_Job));
+ if (!job) return NULL;
+
+ job->file = fopen(dst, "wb");
+ if (!job->file)
+ {
+ free(job);
+ return NULL;
+ }
+ job->curl = curl_easy_init();
+ if (!job->curl)
+ {
+ fclose(job->file);
+ free(job);
+ return NULL;
+ }
+ curl_easy_setopt(job->curl, CURLOPT_URL, url);
+ curl_easy_setopt(job->curl, CURLOPT_WRITEDATA, job->file);
+
+ job->data = data;
+ job->completion_cb = completion_cb;
+ job->dst = strdup(dst);
+ ecore_list_append(_job_list, job);
+
+ curl_multi_add_handle(curlm, job->curl);
+ while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM);
+
+ /* check for completed jobs */
+ while ((curlmsg = curl_multi_info_read(curlm, &n_remaining)) != NULL)
+ {
+ Ecore_File_Download_Job *current;
+
+ if (curlmsg->msg != CURLMSG_DONE) continue;
+
+ /* find the job which is done */
+ ecore_list_goto_first(_job_list);
+ while ((current = ecore_list_current(_job_list)))
+ {
+ if (curlmsg->easy_handle == current->curl)
+ {
+ /* We have a match -- delete the job */
+ if (current == job)
+ job = NULL;
+ if (current->fd_handler)
+ {
+ FD_CLR(ecore_main_fd_handler_fd_get(current->fd_handler),
+ &_current_fd_set);
+ ecore_main_fd_handler_del(current->fd_handler);
+ }
+ ecore_list_remove(_job_list);
+ curl_multi_remove_handle(curlm, current->curl);
+ curl_easy_cleanup(current->curl);
+ fclose(current->file);
+ if (current->completion_cb)
+ current->completion_cb(current->data, current->dst,
+ curlmsg->data.result);
+ free(current->dst);
+ free(current);
+ break;
+ }
+ ecore_list_next(_job_list);
+ }
+ }
+
+ if (job)
+ {
+ FD_ZERO(&read_set);
+ FD_ZERO(&write_set);
+ FD_ZERO(&exc_set);
+
+ /* Stupid curl, why can't I get the fd to the current added job? */
+ curl_multi_fdset(curlm, &read_set, &write_set, &exc_set, &fd_max);
+ for (fd = 0; fd <= fd_max; fd++)
+ {
+ if (!FD_ISSET(fd, &_current_fd_set))
+ {
+ flags = 0;
+ if (FD_ISSET(fd, &read_set)) flags |= ECORE_FD_READ;
+ if (FD_ISSET(fd, &write_set)) flags |= ECORE_FD_WRITE;
+ if (FD_ISSET(fd, &exc_set)) flags |= ECORE_FD_ERROR;
+ if (flags)
+ {
+ FD_SET(fd, &_current_fd_set);
+ job->fd_handler = ecore_main_fd_handler_add(fd, flags,
+ _ecore_file_download_curl_fd_handler,
+ NULL, NULL, NULL);
+ }
+ }
+ }
+ if (!job->fd_handler)
+ {
+ curl_easy_cleanup(job->curl);
+ fclose(job->file);
+ free(job);
+ job = NULL;
+ }
+ }
+
+ return job;
+}
+
+static int
+_ecore_file_download_curl_fd_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ Ecore_File_Download_Job *job;
+ CURLMsg *curlmsg;
+ int n_remaining, still_running;
+
+ /* FIXME: Can this run for a long time? Maybe limit how long it can run */
+ while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM);
+
+ /* Loop jobs and check if any are done */
+ while ((curlmsg = curl_multi_info_read(curlm, &n_remaining)) != NULL)
+ {
+ if (curlmsg->msg != CURLMSG_DONE) continue;
+
+ /* find the job which is done */
+ ecore_list_goto_first(_job_list);
+ while ((job = ecore_list_current(_job_list)))
+ {
+ if (curlmsg->easy_handle == job->curl)
+ {
+ /* We have a match -- delete the job */
+ FD_CLR(ecore_main_fd_handler_fd_get(job->fd_handler),
+ &_current_fd_set);
+ ecore_list_remove(_job_list);
+ ecore_main_fd_handler_del(job->fd_handler);
+ curl_multi_remove_handle(curlm, job->curl);
+ curl_easy_cleanup(job->curl);
+ fclose(job->file);
+ if (job->completion_cb)
+ job->completion_cb(job->data, job->dst, !curlmsg->data.result);
+ free(job->dst);
+ free(job);
+ break;
+ }
+ ecore_list_next(_job_list);
+ }
+ }
+ return 1;
+}
+#endif
diff --git a/ecore/src/lib/ecore_file/ecore_file_monitor.c b/ecore/src/lib/ecore_file/ecore_file_monitor.c
new file mode 100644
index 0000000..e270e01
--- /dev/null
+++ b/ecore/src/lib/ecore_file/ecore_file_monitor.c
@@ -0,0 +1,126 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "ecore_file_private.h"
+
+typedef enum {
+ ECORE_FILE_MONITOR_TYPE_NONE,
+#ifdef HAVE_INOTIFY
+ ECORE_FILE_MONITOR_TYPE_INOTIFY,
+#endif
+#ifdef HAVE_FAM
+ ECORE_FILE_MONITOR_TYPE_FAM,
+#endif
+#ifdef HAVE_POLL
+ ECORE_FILE_MONITOR_TYPE_POLL
+#endif
+} Ecore_File_Monitor_Type;
+
+static Ecore_File_Monitor_Type monitor_type = ECORE_FILE_MONITOR_TYPE_NONE;
+
+int
+ecore_file_monitor_init(void)
+{
+#ifdef HAVE_INOTIFY
+#if 0
+ monitor_type = ECORE_FILE_MONITOR_TYPE_INOTIFY;
+ if (ecore_file_monitor_inotify_init())
+ return 1;
+#endif
+#endif
+#ifdef HAVE_FAM
+#if 0
+ monitor_type = ECORE_FILE_MONITOR_TYPE_FAM;
+ if (ecore_file_monitor_fam_init())
+ return 1;
+#endif
+#endif
+#ifdef HAVE_POLL
+ monitor_type = ECORE_FILE_MONITOR_TYPE_POLL;
+ if (ecore_file_monitor_poll_init())
+ return 1;
+#endif
+ monitor_type = ECORE_FILE_MONITOR_TYPE_NONE;
+ return 0;
+}
+
+int
+ecore_file_monitor_shutdown(void)
+{
+ switch (monitor_type)
+ {
+ case ECORE_FILE_MONITOR_TYPE_NONE:
+ return 1;
+#ifdef HAVE_INOTIFY
+ case ECORE_FILE_MONITOR_TYPE_INOTIFY:
+ return ecore_file_monitor_inotify_shutdown();
+#endif
+#ifdef HAVE_FAM
+ case ECORE_FILE_MONITOR_TYPE_FAM:
+ return ecore_file_monitor_fam_shutdown();
+#endif
+#ifdef HAVE_POLL
+ case ECORE_FILE_MONITOR_TYPE_POLL:
+ return ecore_file_monitor_poll_shutdown();
+#endif
+ }
+ return 0;
+}
+
+Ecore_File_Monitor *
+ecore_file_monitor_add(const char *path,
+ void (*func) (void *data, Ecore_File_Monitor *em,
+ Ecore_File_Event event,
+ const char *path),
+ void *data)
+{
+ switch (monitor_type)
+ {
+ case ECORE_FILE_MONITOR_TYPE_NONE:
+ return NULL;
+#ifdef HAVE_INOTIFY
+ case ECORE_FILE_MONITOR_TYPE_INOTIFY:
+ return ecore_file_monitor_inotify_add(path, func, data);
+#endif
+#ifdef HAVE_FAM
+ case ECORE_FILE_MONITOR_TYPE_FAM:
+ return ecore_file_monitor_fam_add(path, func, data);
+#endif
+#ifdef HAVE_POLL
+ case ECORE_FILE_MONITOR_TYPE_POLL:
+ return ecore_file_monitor_poll_add(path, func, data);
+#endif
+ }
+ return NULL;
+}
+
+void
+ecore_file_monitor_del(Ecore_File_Monitor *em)
+{
+ switch (monitor_type)
+ {
+ case ECORE_FILE_MONITOR_TYPE_NONE:
+ break;
+#ifdef HAVE_INOTIFY
+ case ECORE_FILE_MONITOR_TYPE_INOTIFY:
+ ecore_file_monitor_inotify_del(em);
+ break;
+#endif
+#ifdef HAVE_FAM
+ case ECORE_FILE_MONITOR_TYPE_FAM:
+ ecore_file_monitor_fam_del(em);
+ break;
+#endif
+#ifdef HAVE_POLL
+ case ECORE_FILE_MONITOR_TYPE_POLL:
+ ecore_file_monitor_poll_del(em);
+ break;
+#endif
+ }
+}
+
+const char *
+ecore_file_monitor_path_get(Ecore_File_Monitor *em)
+{
+ return em->path;
+}
diff --git a/ecore/src/lib/ecore_file/ecore_file_monitor_fam.c b/ecore/src/lib/ecore_file/ecore_file_monitor_fam.c
new file mode 100644
index 0000000..ffdfe7d
--- /dev/null
+++ b/ecore/src/lib/ecore_file/ecore_file_monitor_fam.c
@@ -0,0 +1,305 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "ecore_file_private.h"
+
+/*
+ * TODO:
+ * - When several subdirectories are created really fast, the code
+ * doesn't keep up!
+ * - Same for deletion of files in deleted directories!
+ */
+
+#ifdef HAVE_FAM
+
+#include <fam.h>
+
+typedef struct _Ecore_File_Monitor_Fam Ecore_File_Monitor_Fam;
+typedef struct _Ecore_File Ecore_File;
+
+#define ECORE_FILE_MONITOR_FAM(x) ((Ecore_File_Monitor_Fam *)(x))
+
+struct _Ecore_File_Monitor_Fam
+{
+ Ecore_File_Monitor monitor;
+ FAMRequest *request;
+};
+
+struct _Ecore_File
+{
+ Ecore_Oldlist __list_data;
+ char *name;
+};
+
+static Ecore_Fd_Handler *_fdh = NULL;
+static FAMConnection *_fc = NULL;
+static Ecore_Oldlist *_monitors = NULL;
+
+static int _ecore_file_monitor_fam_handler(void *data, Ecore_Fd_Handler *fdh);
+static Ecore_File *_ecore_file_monitor_fam_file_find(Ecore_File_Monitor *em, char *name);
+static Ecore_File_Event _ecore_file_monitor_fam_event_get(FAMCodes code, int self, int is_dir);
+
+int
+ecore_file_monitor_fam_init(void)
+{
+ _fc = calloc(1, sizeof(FAMConnection));
+ if (!_fc) return 0;
+
+ FAMOpen(_fc);
+ _fdh = ecore_main_fd_handler_add(FAMCONNECTION_GETFD(_fc), ECORE_FD_READ,
+ _ecore_file_monitor_fam_handler, NULL, NULL, NULL);
+
+ return 1;
+}
+
+int
+ecore_file_monitor_fam_shutdown(void)
+{
+ Ecore_Oldlist *l;
+
+ for (l = _monitors; l;)
+ {
+ Ecore_File_Monitor *em;
+
+ em = ECORE_FILE_MONITOR(l);
+ l = l->next;
+ ecore_file_monitor_fam_del(em);
+ }
+ if (_fdh) ecore_main_fd_handler_del(_fdh);
+ if (_fc)
+ {
+ FAMClose(_fc);
+ free(_fc);
+ }
+ return 1;
+}
+
+Ecore_File_Monitor *
+ecore_file_monitor_fam_add(const char *path,
+ void (*func) (void *data,
+ Ecore_File_Monitor *em,
+ Ecore_File_Event event,
+ const char *path),
+ void *data)
+{
+ Ecore_File_Monitor *em;
+ int len;
+
+ em = calloc(1, sizeof(Ecore_File_Monitor_Fam));
+ if (!em) return NULL;
+
+ em->func = func;
+ em->data = data;
+
+ em->path = strdup(path);
+ len = strlen(em->path);
+ if (em->path[len - 1] == '/')
+ em->path[len - 1] = 0;
+
+ if (ecore_file_exists(em->path))
+ {
+ ECORE_FILE_MONITOR_FAM(em)->request = calloc(1, sizeof(FAMRequest));
+ if (!ECORE_FILE_MONITOR_FAM(em)->request)
+ {
+ ecore_file_monitor_fam_del(em);
+ return NULL;
+ }
+ if (ecore_file_is_dir(em->path))
+ {
+ FAMMonitorDirectory(_fc, em->path, ECORE_FILE_MONITOR_FAM(em)->request, em);
+ }
+ else
+ {
+ FAMMonitorFile(_fc, em->path, ECORE_FILE_MONITOR_FAM(em)->request, em);
+ }
+ }
+ else
+ {
+ ecore_file_monitor_fam_del(em);
+ return NULL;
+ }
+
+ _monitors = _ecore_list_append(_monitors, em);
+
+ return em;
+}
+
+void
+ecore_file_monitor_fam_del(Ecore_File_Monitor *em)
+{
+ Ecore_Oldlist *l;
+
+ for (l = em->files; l; l = l->next)
+ {
+ Ecore_File *f;
+
+ f = (Ecore_File *)l;
+ free(f->name);
+ free(f);
+ }
+
+ _monitors = _ecore_list_remove(_monitors, em);
+
+ if (ECORE_FILE_MONITOR_FAM(em)->request)
+ {
+ FAMCancelMonitor(_fc, ECORE_FILE_MONITOR_FAM(em)->request);
+ free(ECORE_FILE_MONITOR_FAM(em)->request);
+ }
+ free(em->path);
+ free(em);
+}
+
+static int
+_ecore_file_monitor_fam_handler(void *data, Ecore_Fd_Handler *fdh)
+{
+ int pending, i;
+
+ while ((pending = FAMPending(_fc)))
+ {
+ for (i = 0; i < pending; i++)
+ {
+ Ecore_File_Monitor *em;
+ FAMEvent fe;
+ Ecore_File_Event event;
+ char buf[PATH_MAX];
+ int len, self;
+
+ buf[0] = 0;
+
+ FAMNextEvent(_fc, &fe);
+ len = strlen(fe.filename);
+ if (fe.filename[len - 1] == '/')
+ fe.filename[len - 1] = 0;
+ self = !strcmp(em->path, fe.filename);
+ if (!self)
+ snprintf(buf, sizeof(buf), "%s/%s", em->path, fe.filename);
+
+ event = _ecore_file_monitor_fam_event_get(fe.code, self, ecore_file_is_dir(buf));
+ em = fe.userdata;
+ if (!em) continue;
+ if (event == ECORE_FILE_EVENT_NONE) continue;
+#if 0
+ if (!strcmp(em->path, fe.filename))
+ {
+ Evas_List *l;
+
+ if (event == ECORE_FILE_EVENT_DELETED)
+ {
+ /* Notify all files deleted */
+ for (l = em->files; l;)
+ {
+ Ecore_File *f;
+ char buf[PATH_MAX];
+
+ f = l->data;
+ l = l->next;
+ snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
+ em->func(em->data, em, f->type, ECORE_FILE_EVENT_DELETED, buf);
+ free(f->name);
+ free(f);
+ }
+ em->files = evas_list_free(em->files);
+ em->func(em->data, em, em->type, event, em->path);
+ em->type = ECORE_FILE_TYPE_NONE;
+ }
+ else
+ {
+ em->func(em->data, em, em->type, event, em->path);
+ }
+ }
+ else
+ {
+ Ecore_File *f;
+
+ switch (event)
+ {
+ case ECORE_FILE_EVENT_NONE:
+ break;
+ case ECORE_FILE_EVENT_EXISTS:
+ f = _ecore_file_monitor_fam_file_find(em, fe.filename);
+ if (f)
+ {
+ em->func(em->data, em, f->type, event, buf);
+ break;
+ }
+ case ECORE_FILE_EVENT_CREATED:
+ f = calloc(1, sizeof(Ecore_File));
+ if (!f) break;
+
+ f->type = ecore_file_is_dir(buf) ?
+ ECORE_FILE_TYPE_DIRECTORY :
+ ECORE_FILE_TYPE_FILE;
+ f->name = strdup(fe.filename);
+ em->files = evas_list_append(em->files, f);
+ em->func(em->data, em, f->type, event, buf);
+ break;
+ case ECORE_FILE_EVENT_DELETED:
+ f = _ecore_file_monitor_fam_file_find(em, fe.filename);
+ if (f)
+ {
+ em->files = evas_list_remove(em->files, f);
+ em->func(em->data, em, f->type, event, buf);
+ free(f->name);
+ free(f);
+ }
+ break;
+ case ECORE_FILE_EVENT_CHANGED:
+ em->func(em->data, em, f->type, event, buf);
+ break;
+ }
+ }
+#endif
+ }
+ }
+ return 1;
+}
+
+static Ecore_File *
+_ecore_file_monitor_fam_file_find(Ecore_File_Monitor *em, char *name)
+{
+ for (l = em->files; l; l = l->next)
+ {
+ Ecore_File *f;
+ f = l->data;
+ if (!strcmp(f->name, name))
+ return f;
+ }
+ return NULL;
+}
+
+static Ecore_File_Event
+_ecore_file_monitor_fam_event_get(FAMCodes code, int self, int is_dir)
+{
+ switch (code)
+ {
+ case FAMCreated:
+ if (self)
+ return ECORE_FILE_EVENT_NONE;
+ else if (is_dir)
+ return ECORE_FILE_EVENT_CREATED_DIRECTORY;
+ else
+ return ECORE_FILE_EVENT_CREATED_FILE;
+ break;
+ case FAMDeleted:
+ if (self)
+ return ECORE_FILE_EVENT_DELETED_SELF;
+ else if (is_dir)
+ return ECORE_FILE_EVENT_DELETED_DIRECTORY;
+ else
+ return ECORE_FILE_EVENT_DELETED_FILE;
+ break;
+ case FAMChanged:
+ if (!is_dir)
+ return ECORE_FILE_EVENT_MODIFIED;
+ break;
+ case FAMExists:
+ case FAMStartExecuting:
+ case FAMStopExecuting:
+ case FAMMoved:
+ case FAMAcknowledge:
+ case FAMEndExist:
+ return ECORE_FILE_EVENT_NONE;
+ }
+ return ECORE_FILE_EVENT_NONE;
+}
+#endif
diff --git a/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c b/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c
new file mode 100644
index 0000000..1f8c34f
--- /dev/null
+++ b/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c
@@ -0,0 +1,235 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "ecore_file_private.h"
+
+/*
+ * TODO:
+ */
+
+#ifdef HAVE_INOTIFY
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/inotify.h>
+
+typedef struct _Ecore_File_Monitor_Inotify Ecore_File_Monitor_Inotify;
+
+#define ECORE_FILE_MONITOR_INOTIFY(x) ((Ecore_File_Monitor_Inotify *)(x))
+
+struct _Ecore_File_Monitor_Inotify
+{
+ Ecore_File_Monitor monitor;
+ int wd;
+};
+
+static Ecore_Fd_Handler *_fdh = NULL;
+static Ecore_Oldlist *_monitors = NULL;
+
+static int _ecore_file_monitor_inotify_handler(void *data, Ecore_Fd_Handler *fdh);
+static Ecore_File_Monitor *_ecore_file_monitor_inotify_monitor_find(int wd);
+static void _ecore_file_monitor_inotify_events(Ecore_File_Monitor *em,
+ char *file, int mask);
+
+int
+ecore_file_monitor_inotify_init(void)
+{
+ int fd;
+
+ fd = open("/dev/inotify", O_RDONLY);
+ if (fd < 0)
+ return 0;
+
+ _fdh = ecore_main_fd_handler_add(fd, ECORE_FD_READ, _ecore_file_monitor_inotify_handler,
+ NULL, NULL, NULL);
+ if (!_fdh)
+ {
+ close(fd);
+ return 0;
+ }
+
+ return 1;
+}
+
+int
+ecore_file_monitor_inotify_shutdown(void)
+{
+ int fd;
+ Ecore_Oldlist *l;
+
+ for (l = _monitors; l;)
+ {
+ Ecore_File_Monitor *em;
+
+ em = ECORE_FILE_MONITOR(l);
+ l = l->next;
+ ecore_file_monitor_inotify_del(em);
+ }
+
+ if (_fdh)
+ {
+ fd = ecore_main_fd_handler_fd_get(_fdh);
+ ecore_main_fd_handler_del(_fdh);
+ close(fd);
+ }
+ return 1;
+}
+
+Ecore_File_Monitor *
+ecore_file_monitor_inotify_add(const char *path,
+ void (*func) (void *data, Ecore_File_Monitor *em,
+ Ecore_File_Event event,
+ const char *path),
+ void *data)
+{
+ Ecore_File_Monitor *em;
+ int len;
+
+ em = calloc(1, sizeof(Ecore_File_Monitor_Inotify));
+ if (!em) return NULL;
+
+ em->func = func;
+ em->data = data;
+
+ em->path = strdup(path);
+ len = strlen(em->path);
+ if (em->path[len - 1] == '/')
+ em->path[len - 1] = 0;
+
+ if (ecore_file_exists(em->path))
+ {
+ struct inotify_watch_request request;
+
+ request.name = em->path;
+ request.mask = IN_MODIFY|
+ IN_MOVED_FROM|IN_MOVED_TO|
+ IN_DELETE_SUBDIR|IN_DELETE_FILE|
+ IN_CREATE_SUBDIR|IN_CREATE_FILE|
+ IN_DELETE_SELF|IN_UNMOUNT;
+ ECORE_FILE_MONITOR_INOTIFY(em)->wd = ioctl(ecore_main_fd_handler_fd_get(_fdh),
+ INOTIFY_WATCH, &request);
+ if (ECORE_FILE_MONITOR_INOTIFY(em)->wd < 0)
+ {
+ printf("ioctl error\n");
+ ecore_file_monitor_inotify_del(em);
+ return NULL;
+ }
+ }
+ else
+ {
+ ecore_file_monitor_inotify_del(em);
+ return NULL;
+ }
+
+ _monitors = _ecore_list_append(_monitors, em);
+
+ return em;
+}
+
+void
+ecore_file_monitor_inotify_del(Ecore_File_Monitor *em)
+{
+ int fd;
+
+ _monitors = _ecore_list_remove(_monitors, em);
+
+ fd = ecore_main_fd_handler_fd_get(_fdh);
+ if (ECORE_FILE_MONITOR_INOTIFY(em)->wd)
+ ioctl(fd, INOTIFY_IGNORE, ECORE_FILE_MONITOR_INOTIFY(em)->wd);
+ free(em->path);
+ free(em);
+}
+
+static int
+_ecore_file_monitor_inotify_handler(void *data, Ecore_Fd_Handler *fdh)
+{
+ Ecore_File_Monitor *em;
+ char buffer[16384];
+ struct inotify_event *event;
+ int i = 0;
+ int event_size;
+ ssize_t size;
+
+ size = read(ecore_main_fd_handler_fd_get(fdh), buffer, sizeof(buffer));
+ while (i < size)
+ {
+ event = (struct inotify_event *)&buffer[i];
+ event_size = sizeof(struct inotify_event) + event->len;
+ i += event_size;
+
+ em = _ecore_file_monitor_inotify_monitor_find(event->wd);
+ if (!em) continue;
+
+ _ecore_file_monitor_inotify_events(em, event->name, event->mask);
+ }
+
+ return 1;
+}
+
+static Ecore_File_Monitor *
+_ecore_file_monitor_inotify_monitor_find(int wd)
+{
+ Ecore_Oldlist *l;
+
+ for (l = _monitors; l; l = l->next)
+ {
+ Ecore_File_Monitor *em;
+
+ em = ECORE_FILE_MONITOR(l);
+
+ if (ECORE_FILE_MONITOR_INOTIFY(em)->wd == wd)
+ return em;
+ }
+ return NULL;
+}
+
+static void
+_ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, char *file, int mask)
+{
+ char buf[PATH_MAX];
+ if (file)
+ snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
+ else
+ strcpy(buf, em->path);
+
+ if (mask & IN_MODIFY)
+ {
+ if (!ecore_file_is_dir(buf))
+ em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf);
+ }
+ if (mask & IN_MOVED_FROM)
+ {
+ printf("MOVE_FROM ");
+ }
+ if (mask & IN_MOVED_TO)
+ {
+ printf("MOVE_TO ");
+ }
+ if (mask & IN_DELETE_SUBDIR)
+ {
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_DIRECTORY, buf);
+ }
+ if (mask & IN_DELETE_FILE)
+ {
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_FILE, buf);
+ }
+ if (mask & IN_CREATE_SUBDIR)
+ {
+ em->func(em->data, em, ECORE_FILE_EVENT_CREATED_DIRECTORY, buf);
+ }
+ if (mask & IN_CREATE_FILE)
+ {
+ em->func(em->data, em, ECORE_FILE_EVENT_CREATED_FILE, buf);
+ }
+ if (mask & IN_DELETE_SELF)
+ {
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
+ }
+ if (mask & IN_UNMOUNT)
+ {
+ printf("UNMOUNT ");
+ }
+}
+#endif
diff --git a/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c b/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c
new file mode 100644
index 0000000..420084c
--- /dev/null
+++ b/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c
@@ -0,0 +1,357 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "ecore_private.h"
+#include "ecore_file_private.h"
+
+#ifdef HAVE_POLL
+
+/*
+ * TODO:
+ * - Implement recursive as an option!
+ * - Keep whole path or just name of file? (Memory or CPU...)
+ * - Remove requests without files?
+ * - Change poll time
+ */
+
+typedef struct _Ecore_File_Monitor_Poll Ecore_File_Monitor_Poll;
+typedef struct _Ecore_File Ecore_File;
+
+#define ECORE_FILE_MONITOR_POLL(x) ((Ecore_File_Monitor_Poll *)(x))
+
+struct _Ecore_File_Monitor_Poll
+{
+ Ecore_File_Monitor monitor;
+ int mtime;
+ unsigned char deleted;
+};
+
+struct _Ecore_File
+{
+ Ecore_Oldlist __list_data;
+ char *name;
+ int mtime;
+ unsigned char is_dir;
+};
+
+#define ECORE_FILE_INTERVAL_MIN 1.0
+#define ECORE_FILE_INTERVAL_STEP 0.5
+#define ECORE_FILE_INTERVAL_MAX 5.0
+
+static double _interval = ECORE_FILE_INTERVAL_MIN;
+static Ecore_Timer *_timer = NULL;
+static Ecore_Oldlist *_monitors = NULL;
+static int _lock = 0;
+
+static int _ecore_file_monitor_poll_handler(void *data);
+static void _ecore_file_monitor_poll_check(Ecore_File_Monitor *em);
+static int _ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name);
+
+int
+ecore_file_monitor_poll_init(void)
+{
+ return 1;
+}
+
+int
+ecore_file_monitor_poll_shutdown(void)
+{
+ Ecore_Oldlist *l;
+
+ for (l = _monitors; l;)
+ {
+ Ecore_File_Monitor *em;
+
+ em = ECORE_FILE_MONITOR(l);
+ l = l->next;
+ ecore_file_monitor_poll_del(em);
+ }
+
+ if (_timer)
+ {
+ ecore_timer_del(_timer);
+ _timer = NULL;
+ }
+ return 1;
+}
+
+Ecore_File_Monitor *
+ecore_file_monitor_poll_add(const char *path,
+ void (*func) (void *data, Ecore_File_Monitor *em,
+ Ecore_File_Event event,
+ const char *path),
+ void *data)
+{
+ Ecore_File_Monitor *em;
+ int len;
+
+ if (!path) return NULL;
+ if (!func) return NULL;
+
+ em = calloc(1, sizeof(Ecore_File_Monitor_Poll));
+ if (!em) return NULL;
+
+ if (!_timer)
+ _timer = ecore_timer_add(_interval, _ecore_file_monitor_poll_handler, NULL);
+ else
+ ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
+
+ em->path = strdup(path);
+ len = strlen(em->path);
+ if (em->path[len - 1] == '/')
+ em->path[len - 1] = 0;
+
+ em->func = func;
+ em->data = data;
+
+ ECORE_FILE_MONITOR_POLL(em)->mtime = ecore_file_mod_time(em->path);
+ if (ecore_file_exists(em->path))
+ {
+ if (ecore_file_is_dir(em->path))
+ {
+ /* Check for subdirs */
+ Ecore_List *files;
+ char *file;
+
+ files = ecore_file_ls(em->path);
+ if (files)
+ {
+ while ((file = ecore_list_next(files)))
+ {
+ Ecore_File *f;
+ char buf[PATH_MAX];
+
+ f = calloc(1, sizeof(Ecore_File));
+ if (!f)
+ {
+ free(file);
+ continue;
+ }
+
+ snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
+ f->name = file;
+ f->mtime = ecore_file_mod_time(buf);
+ f->is_dir = ecore_file_is_dir(buf);
+ em->files = _ecore_list_append(em->files, f);
+ }
+ ecore_list_destroy(files);
+ }
+ }
+ }
+ else
+ {
+ ecore_file_monitor_poll_del(em);
+ return NULL;
+ }
+
+ _monitors = _ecore_list_append(_monitors, em);
+
+ return em;
+}
+
+void
+ecore_file_monitor_poll_del(Ecore_File_Monitor *em)
+{
+ Ecore_Oldlist *l;
+
+ if (_lock)
+ {
+ ECORE_FILE_MONITOR_POLL(em)->deleted = 1;
+ return;
+ }
+
+ /* Remove files */
+ for (l = em->files; l;)
+ {
+ Ecore_File *file;
+
+ file = (Ecore_File *)l;
+ l = l->next;
+ free(file->name);
+ free(file);
+ }
+
+ _monitors = _ecore_list_remove(_monitors, em);
+
+ free(em->path);
+ free(em);
+
+ if ((!_monitors) && (_timer))
+ {
+ ecore_timer_del(_timer);
+ _timer = NULL;
+ }
+ else
+ ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
+}
+
+static int
+_ecore_file_monitor_poll_handler(void *data __UNUSED__)
+{
+ Ecore_Oldlist *l;
+
+ _interval += ECORE_FILE_INTERVAL_STEP;
+
+ _lock = 1;
+ for (l = _monitors; l; l = l->next)
+ {
+ Ecore_File_Monitor *em;
+
+ em = ECORE_FILE_MONITOR(l);
+ _ecore_file_monitor_poll_check(em);
+ }
+ _lock = 0;
+
+ if (_interval > ECORE_FILE_INTERVAL_MAX)
+ _interval = ECORE_FILE_INTERVAL_MAX;
+ ecore_timer_interval_set(_timer, _interval);
+
+ for (l = _monitors; l;)
+ {
+ Ecore_File_Monitor *em;
+
+ em = ECORE_FILE_MONITOR(l);
+ l = l->next;
+ if (ECORE_FILE_MONITOR_POLL(em)->deleted)
+ ecore_file_monitor_del(em);
+ }
+ return 1;
+}
+
+static void
+_ecore_file_monitor_poll_check(Ecore_File_Monitor *em)
+{
+ int mtime;
+ int is_dir;
+
+ mtime = ecore_file_mod_time(em->path);
+ is_dir = ecore_file_is_dir(em->path);
+ if (mtime < ECORE_FILE_MONITOR_POLL(em)->mtime)
+ {
+ Ecore_Oldlist *l;
+ Ecore_File_Event event;
+
+ /* Notify all files deleted */
+ for (l = em->files; l;)
+ {
+ Ecore_File *f;
+ char buf[PATH_MAX];
+
+ f = (Ecore_File *)l;
+ l = l->next;
+
+ snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
+ if (f->is_dir)
+ event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
+ else
+ event = ECORE_FILE_EVENT_DELETED_FILE;
+ em->func(em->data, em, event, buf);
+ free(f->name);
+ free(f);
+ }
+ em->files = NULL;
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
+ _interval = ECORE_FILE_INTERVAL_MIN;
+ }
+ else
+ {
+ Ecore_Oldlist *l;
+
+ /* Check for changed files */
+ for (l = em->files; l;)
+ {
+ Ecore_File *f;
+ char buf[PATH_MAX];
+ int mtime;
+ Ecore_File_Event event;
+
+ f = (Ecore_File *)l;
+ l = l->next;
+
+ snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
+ mtime = ecore_file_mod_time(buf);
+ if (mtime < f->mtime)
+ {
+ if (f->is_dir)
+ event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
+ else
+ event = ECORE_FILE_EVENT_DELETED_FILE;
+
+ em->func(em->data, em, event, buf);
+ em->files = _ecore_list_remove(em->files, f);
+ free(f->name);
+ free(f);
+ _interval = ECORE_FILE_INTERVAL_MIN;
+ }
+ else if ((mtime > f->mtime) && !(f->is_dir))
+ {
+ em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf);
+ _interval = ECORE_FILE_INTERVAL_MIN;
+ }
+ f->mtime = mtime;
+ }
+
+ /* Check for new files */
+ if (ECORE_FILE_MONITOR_POLL(em)->mtime < mtime)
+ {
+ Ecore_List *files;
+ char *file;
+
+ /* Files have been added or removed */
+ files = ecore_file_ls(em->path);
+ while ((file = ecore_list_next(files)))
+ {
+ Ecore_File *f;
+ char buf[PATH_MAX];
+ Ecore_File_Event event;
+
+ if (_ecore_file_monitor_poll_checking(em, file))
+ {
+ free(file);
+ continue;
+ }
+
+ snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
+ f = calloc(1, sizeof(Ecore_File));
+ if (!f)
+ {
+ free(file);
+ continue;
+ }
+
+ f->name = file;
+ f->mtime = ecore_file_mod_time(buf);
+ f->is_dir = ecore_file_is_dir(buf);
+ if (f->is_dir)
+ event = ECORE_FILE_EVENT_CREATED_DIRECTORY;
+ else
+ event = ECORE_FILE_EVENT_CREATED_FILE;
+ em->func(em->data, em, event, buf);
+ em->files = _ecore_list_append(em->files, f);
+ }
+ ecore_list_destroy(files);
+ if (!ecore_file_is_dir(em->path))
+ em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, em->path);
+ _interval = ECORE_FILE_INTERVAL_MIN;
+ }
+ }
+ ECORE_FILE_MONITOR_POLL(em)->mtime = mtime;
+}
+
+static int
+_ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name)
+{
+ Ecore_Oldlist *l;
+
+ for (l = em->files; l; l = l->next)
+ {
+ Ecore_File *f;
+
+ f = (Ecore_File *)l;
+ if (!strcmp(f->name, name))
+ return 1;
+ }
+
+ return 0;
+}
+#endif
diff --git a/ecore/src/lib/ecore_file/ecore_file_path.c b/ecore/src/lib/ecore_file/ecore_file_path.c
new file mode 100644
index 0000000..d1b5d71
--- /dev/null
+++ b/ecore/src/lib/ecore_file/ecore_file_path.c
@@ -0,0 +1,84 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "ecore_file_private.h"
+
+Ecore_List *__ecore_file_path_bin;
+
+static Ecore_List *_ecore_file_path_from_env(const char *env);
+
+int
+ecore_file_path_init(void)
+{
+ __ecore_file_path_bin = _ecore_file_path_from_env("PATH");
+ return 1;
+}
+
+int
+ecore_file_path_shutdown(void)
+{
+ ecore_list_destroy(__ecore_file_path_bin);
+ return 1;
+}
+
+Ecore_List *
+_ecore_file_path_from_env(const char *env)
+{
+ Ecore_List *path;
+ char *env_path, *p, *last;
+
+ path = ecore_list_new();
+
+ env_path = getenv(env);
+ if (!env_path)
+ return path;
+
+ env_path = strdup(env_path);
+ last = env_path;
+ for (p = env_path; *p; p++)
+ {
+ if (*p == ':')
+ *p = '\0';
+
+ if (!*p)
+ {
+ ecore_list_append(path, strdup(last));
+ last = p+1;
+ }
+
+ }
+ if (p > last)
+ ecore_list_append(path, last);
+
+ free(env_path);
+ return path;
+}
+
+int
+ecore_file_app_installed(const char *app)
+{
+ int found;
+ char *dir;
+ char buf[PATH_MAX];
+
+ if (!app)
+ return 0;
+
+ found = 0;
+
+ if (ecore_list_is_empty(__ecore_file_path_bin))
+ return 0;
+ ecore_list_goto_first(__ecore_file_path_bin);
+
+ while ((dir = ecore_list_next(__ecore_file_path_bin)) != NULL)
+ {
+ snprintf(buf, sizeof(buf), "%s/%s", dir, app);
+ if (ecore_file_exists(buf) && ecore_file_can_exec(buf))
+ {
+ found = 1;
+ break;
+ }
+ }
+
+ return found;
+}
diff --git a/ecore/src/lib/ecore_file/ecore_file_private.h b/ecore/src/lib/ecore_file/ecore_file_private.h
new file mode 100644
index 0000000..b691655
--- /dev/null
+++ b/ecore/src/lib/ecore_file/ecore_file_private.h
@@ -0,0 +1,75 @@
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+
+#include "ecore_private.h"
+#include "Ecore.h"
+#include "Ecore_File.h"
+
+/* ecore_file_monitor */
+int ecore_file_monitor_init(void);
+int ecore_file_monitor_shutdown(void);
+
+#define ECORE_FILE_MONITOR(x) ((Ecore_File_Monitor *)(x))
+
+struct _Ecore_File_Monitor
+{
+ Ecore_Oldlist __list_data;
+ void (*func) (void *data,
+ Ecore_File_Monitor *ecore_file_monitor,
+ Ecore_File_Event event,
+ const char *path);
+
+ char *path;
+ void *data;
+ Ecore_Oldlist *files;
+};
+
+#ifdef HAVE_INOTIFY
+EAPI int ecore_file_monitor_inotify_init(void);
+EAPI int ecore_file_monitor_inotify_shutdown(void);
+EAPI Ecore_File_Monitor *ecore_file_monitor_inotify_add(const char *path,
+ void (*func) (void *data,
+ Ecore_File_Monitor *ecore_file_monitor,
+ Ecore_File_Event event,
+ const char *path),
+ void *data);
+EAPI void ecore_file_monitor_inotify_del(Ecore_File_Monitor *ecore_file_monitor);
+#endif
+
+#ifdef HAVE_FAM
+EAPI int ecore_file_monitor_fam_init(void);
+EAPI int ecore_file_monitor_fam_shutdown(void);
+EAPI Ecore_File_Monitor *ecore_file_monitor_fam_add(const char *path,
+ void (*func) (void *data,
+ Ecore_File_Monitor *ecore_file_monitor,
+ Ecore_File_Event event,
+ const char *path),
+ void *data);
+EAPI void ecore_file_monitor_fam_del(Ecore_File_Monitor *ecore_file_monitor);
+#endif
+
+#ifdef HAVE_POLL
+EAPI int ecore_file_monitor_poll_init(void);
+EAPI int ecore_file_monitor_poll_shutdown(void);
+EAPI Ecore_File_Monitor *ecore_file_monitor_poll_add(const char *path,
+ void (*func) (void *data,
+ Ecore_File_Monitor *ecore_file_monitor,
+ Ecore_File_Event event,
+ const char *path),
+ void *data);
+EAPI void ecore_file_monitor_poll_del(Ecore_File_Monitor *ecore_file_monitor);
+
+/* ecore_file_path */
+int ecore_file_path_init(void);
+int ecore_file_path_shutdown(void);
+
+/* ecore_file_download */
+int ecore_file_download_init(void);
+int ecore_file_download_shutdown(void);
+
+#endif
diff --git a/ecore/src/lib/ecore_file/ecore_file_utils.c b/ecore/src/lib/ecore_file/ecore_file_utils.c
new file mode 100644
index 0000000..b3217ad
--- /dev/null
+++ b/ecore/src/lib/ecore_file/ecore_file_utils.c
@@ -0,0 +1,4 @@
+void
+_ecore_file_add_slash(char *path)
+{
+}
diff --git a/ecore/src/lib/ecore_ipc/.cvsignore b/ecore/src/lib/ecore_ipc/.cvsignore
new file mode 100644
index 0000000..f98e6f6
--- /dev/null
+++ b/ecore/src/lib/ecore_ipc/.cvsignore
@@ -0,0 +1,7 @@
+.deps
+.libs
+Ecore_Ipc.h
+Makefile
+Makefile.in
+ecore_ipc.lo
+libecore_ipc.la
diff --git a/ecore/src/lib/ecore_ipc/CVS/Entries b/ecore/src/lib/ecore_ipc/CVS/Entries
new file mode 100644
index 0000000..789fd35
--- /dev/null
+++ b/ecore/src/lib/ecore_ipc/CVS/Entries
@@ -0,0 +1,6 @@
+/.cvsignore/1.2/Mon Apr 12 19:35:26 2004//THEAD
+/Ecore_Ipc.h/1.11/Thu May 12 14:45:15 2005//THEAD
+/Makefile.am/1.8/Thu Mar 10 15:19:40 2005//THEAD
+/ecore_ipc.c/1.20/Thu May 12 14:45:15 2005//THEAD
+/ecore_ipc_private.h/1.5/Sat Apr 2 15:59:55 2005//THEAD
+D
diff --git a/ecore/src/lib/ecore_ipc/CVS/Repository b/ecore/src/lib/ecore_ipc/CVS/Repository
new file mode 100644
index 0000000..328a12d
--- /dev/null
+++ b/ecore/src/lib/ecore_ipc/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/lib/ecore_ipc
diff --git a/ecore/src/lib/ecore_ipc/CVS/Root b/ecore/src/lib/ecore_ipc/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/lib/ecore_ipc/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/lib/ecore_ipc/CVS/Tag b/ecore/src/lib/ecore_ipc/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/lib/ecore_ipc/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/lib/ecore_ipc/Ecore_Ipc.h b/ecore/src/lib/ecore_ipc/Ecore_Ipc.h
new file mode 100644
index 0000000..36b7b70
--- /dev/null
+++ b/ecore/src/lib/ecore_ipc/Ecore_Ipc.h
@@ -0,0 +1,312 @@
+#ifndef _ECORE_IPC_H
+#define _ECORE_IPC_H
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef WIN32
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef GCC_HASCLASSVISIBILITY
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file Ecore_Ipc.h
+ * @brief Ecore inter-process communication functions.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ECORE_IPC_PRIVATE_H
+ typedef void Ecore_Ipc_Server; /**< An IPC connection handle */
+ typedef void Ecore_Ipc_Client; /**< An IPC connection handle */
+#endif
+
+/**
+ * Macros used for generic data packing
+ */
+EAPI unsigned short _ecore_ipc_swap_16(unsigned short v);
+EAPI unsigned int _ecore_ipc_swap_32(unsigned int v);
+EAPI unsigned long long _ecore_ipc_swap_64(unsigned long long v);
+
+#ifdef WORDS_BIGENDIAN
+#define ECORE_IPC_SWAP2NET64(x) _ecore_ipc_swap_64(x)
+#define ECORE_IPC_SWAP2CPU64(x) _ecore_ipc_swap_64(x)
+#define ECORE_IPC_SWAP2NET32(x) _ecore_ipc_swap_32(x)
+#define ECORE_IPC_SWAP2CPU32(x) _ecore_ipc_swap_32(x)
+#define ECORE_IPC_SWAP2NET16(x) _ecore_ipc_swap_16(x)
+#define ECORE_IPC_SWAP2CPU16(x) _ecore_ipc_swap_16(x)
+#define ECORE_IPC_SWAP2NET8(x) (x)
+#define ECORE_IPC_SWAP2CPU8(x) (x)
+#else
+#define ECORE_IPC_SWAP2NET64(x) (x)
+#define ECORE_IPC_SWAP2CPU64(x) (x)
+#define ECORE_IPC_SWAP2NET32(x) (x)
+#define ECORE_IPC_SWAP2CPU32(x) (x)
+#define ECORE_IPC_SWAP2NET16(x) (x)
+#define ECORE_IPC_SWAP2CPU16(x) (x)
+#define ECORE_IPC_SWAP2NET8(x) (x)
+#define ECORE_IPC_SWAP2CPU8(x) (x)
+#endif
+
+/* 1, 2, 4 and 8 byte datatypes */
+/* unpacking */
+#define ECORE_IPC_GET64(v)\
+ { \
+ p->v = ECORE_IPC_SWAP2CPU64(*(long long *)(ptr)); \
+ ptr += 8; \
+ }
+#define ECORE_IPC_GET32(v)\
+ { \
+ p->v = ECORE_IPC_SWAP2CPU32(*(int *)(ptr)); \
+ ptr += 4; \
+ }
+#define ECORE_IPC_GET16(v)\
+ { \
+ p->v = ECORE_IPC_SWAP2CPU16(*(short *)(ptr)); \
+ ptr += 2; \
+ }
+#define ECORE_IPC_GET8(v) \
+ { \
+ p->v = ECORE_IPC_SWAP2CPU8(*(char *)(ptr)); \
+ ptr += 1; \
+ }
+/* packing */
+#define ECORE_IPC_PUT64(v)\
+ { \
+ *(long long *)(ptr) = ECORE_IPC_SWAP2NET64(p->v); \
+ ptr += 8; \
+ }
+#define ECORE_IPC_PUT32(v)\
+ { \
+ *(int *)(ptr) = ECORE_IPC_SWAP2NET32(p->v); \
+ ptr += 4; \
+ }
+#define ECORE_IPC_PUT16(v)\
+ { \
+ *(short *)(ptr) = ECORE_IPC_SWAP2NET16(p->v); \
+ ptr += 2; \
+ }
+#define ECORE_IPC_PUT8(v) \
+ { \
+ *(char *)(ptr) = ECORE_IPC_SWAP2NET8(p->v); \
+ ptr += 1; \
+ }
+/* padding data */
+#define ECORE_IPC_PAD8() ptr += 1
+#define ECORE_IPC_PAD16() ptr += 2
+#define ECORE_IPC_PAD32() ptr += 4
+#define ECORE_IPC_PAD64() ptr += 8
+
+/* counting data when encoding lists */
+#define ECORE_IPC_CNT8() len += 1
+#define ECORE_IPC_CNT16() len += 2
+#define ECORE_IPC_CNT32() len += 4
+#define ECORE_IPC_CNT64() len += 8
+
+/* strings */
+#define ECORE_IPC_CHEKS() if (*((unsigned char *)d + s - 1) != 0) return 0;
+#define ECORE_IPC_GETS(v) \
+ { \
+ if (ptr < ((unsigned char *)d + s)) \
+ { \
+ p->v = (char *)ptr; \
+ ptr += strlen(p->v) + 1; \
+ } \
+ }
+#define ECORE_IPC_PUTS(v, l)\
+ { \
+ strcpy((char *)ptr, p->v); \
+ ptr += l + 1; \
+ }
+
+/* handy to calculate what sized block we need to alloc */
+#define ECORE_IPC_SLEN(l, v) ((l = strlen(p->v)) + 1)
+#define ECORE_IPC_CNTS(v) len += strlen(p->v) + 1
+
+/* saves typing function headers */
+#define ECORE_IPC_DEC_STRUCT_PROTO(x) static int x(void *d, int s, void *pp)
+#define ECORE_IPC_ENC_STRUCT_PROTO(x) static void *x(void *pp, int *s)
+#define ECORE_IPC_DEC_EVAS_LIST_PROTO(x) static Evas_List *x(void *d, int s)
+#define ECORE_IPC_ENC_EVAS_LIST_PROTO(x) static void *x(Evas_List *lp, int *s)
+
+
+/* decoder setup - saves typing. requires data packet of exact size, or fail */
+#define ECORE_IPC_DEC_STRUCT_HEAD_EXACT(typ, x) \
+ typ *p; \
+ unsigned char *ptr; \
+ p = (typ *)pp; \
+ if (!d) return 0; if (s != (x)) return 0; \
+ ptr = d;
+/* decoder setup - saves typing. requires data packet of a minimum size */
+#define ECORE_IPC_DEC_STRUCT_HEAD_MIN(typ, x) \
+ typ *p; \
+ unsigned char *ptr; \
+ p = (typ *)pp; \
+ if (!d) return 0; if (s < (x)) return 0; \
+ ptr = d;
+/* footer for the hell of it */
+#define ECORE_IPC_DEC_STRUCT_FOOT() return 1
+/* header for encoder - gives native strct type and size of flattened packet */
+#define ECORE_IPC_ENC_STRUCT_HEAD(typ, sz) \
+ typ *p; \
+ unsigned char *d, *ptr; \
+ int len; \
+ *s = 0; \
+ if(!pp) return NULL; \
+ p = (typ *)pp; \
+ len = sz; \
+ d = malloc(len); \
+ if (!d) return NULL; \
+ *s = len; \
+ ptr = d;
+/* footer for the hell of it */
+#define ECORE_IPC_ENC_STRUCT_FOOT() return d
+
+#define ECORE_IPC_DEC_EVAS_LIST_HEAD(typ) \
+ unsigned char *ptr; \
+ Evas_List *l; \
+ typ *p; \
+ l = NULL; \
+ ptr = d; \
+ while(ptr < (unsigned char *)(d + s)) \
+ { \
+ p = malloc(sizeof(typ));
+
+#define ECORE_IPC_DEC_EVAS_LIST_FOOT() \
+ l = evas_list_append(l, p); \
+ } \
+ return l
+#define ECORE_IPC_ENC_EVAS_LIST_HEAD_START(typ) \
+ Evas_List *l; \
+ typ *p; \
+ unsigned char *d, *ptr; \
+ int len; \
+ *s = 0; \
+ len = 0; \
+ for (l = lp; l; l = l->next) \
+ { \
+ p = l->data;
+#define ECORE_IPC_ENC_EVAS_LIST_HEAD_FINISH() \
+ } \
+ d = malloc(len); \
+ if(!d) return NULL; \
+ *s = len; \
+ ptr = d; \
+ for (l = lp; l; l = l->next) \
+ { \
+ p = l->data;
+
+#define ECORE_IPC_ENC_EVAS_LIST_FOOT() \
+ } \
+ return d
+
+ typedef enum _Ecore_Ipc_Type
+ {
+ ECORE_IPC_LOCAL_USER,
+ ECORE_IPC_LOCAL_SYSTEM,
+ ECORE_IPC_REMOTE_SYSTEM,
+ ECORE_IPC_USE_SSL = 16
+ } Ecore_Ipc_Type;
+
+ typedef struct _Ecore_Ipc_Event_Client_Add Ecore_Ipc_Event_Client_Add;
+ typedef struct _Ecore_Ipc_Event_Client_Del Ecore_Ipc_Event_Client_Del;
+ typedef struct _Ecore_Ipc_Event_Server_Add Ecore_Ipc_Event_Server_Add;
+ typedef struct _Ecore_Ipc_Event_Server_Del Ecore_Ipc_Event_Server_Del;
+ typedef struct _Ecore_Ipc_Event_Client_Data Ecore_Ipc_Event_Client_Data;
+ typedef struct _Ecore_Ipc_Event_Server_Data Ecore_Ipc_Event_Server_Data;
+
+ struct _Ecore_Ipc_Event_Client_Add
+ {
+ Ecore_Ipc_Client *client;
+ };
+
+ struct _Ecore_Ipc_Event_Client_Del
+ {
+ Ecore_Ipc_Client *client;
+ };
+
+ struct _Ecore_Ipc_Event_Server_Add
+ {
+ Ecore_Ipc_Server *server;
+ };
+
+ struct _Ecore_Ipc_Event_Server_Del
+ {
+ Ecore_Ipc_Server *server;
+ };
+
+ struct _Ecore_Ipc_Event_Client_Data
+ {
+ Ecore_Ipc_Client *client;
+ /* FIXME: this needs to become an ipc message */
+ int major;
+ int minor;
+ int ref;
+ int ref_to;
+ int response;
+ void *data;
+ int size;
+ };
+
+ struct _Ecore_Ipc_Event_Server_Data
+ {
+ Ecore_Ipc_Server *server;
+ /* FIXME: this needs to become an ipc message */
+ int major;
+ int minor;
+ int ref;
+ int ref_to;
+ int response;
+ void *data;
+ int size;
+ };
+
+ extern int ECORE_IPC_EVENT_CLIENT_ADD;
+ extern int ECORE_IPC_EVENT_CLIENT_DEL;
+ extern int ECORE_IPC_EVENT_SERVER_ADD;
+ extern int ECORE_IPC_EVENT_SERVER_DEL;
+ extern int ECORE_IPC_EVENT_CLIENT_DATA;
+ extern int ECORE_IPC_EVENT_SERVER_DATA;
+
+ EAPI int ecore_ipc_init(void);
+ EAPI int ecore_ipc_shutdown(void);
+
+ /* FIXME: need to add protocol type parameter */
+ EAPI Ecore_Ipc_Server *ecore_ipc_server_add(Ecore_Ipc_Type type, const char *name, int port, const void *data);
+
+ /* FIXME: need to add protocol type parameter */
+ EAPI Ecore_Ipc_Server *ecore_ipc_server_connect(Ecore_Ipc_Type type, char *name, int port, const void *data);
+ EAPI void *ecore_ipc_server_del(Ecore_Ipc_Server *svr);
+ EAPI void *ecore_ipc_server_data_get(Ecore_Ipc_Server *svr);
+ EAPI int ecore_ipc_server_connected_get(Ecore_Ipc_Server *svr);
+ /* FIXME: this needs to become an ipc message */
+ EAPI int ecore_ipc_server_send(Ecore_Ipc_Server *svr, int major, int minor, int ref, int ref_to, int response, void *data, int size);
+ EAPI void ecore_ipc_server_client_limit_set(Ecore_Ipc_Server *svr, int client_limit, char reject_excess_clients);
+
+ /* FIXME: this needs to become an ipc message */
+ EAPI int ecore_ipc_client_send(Ecore_Ipc_Client *cl, int major, int minor, int ref, int ref_to, int response, void *data, int size);
+ EAPI Ecore_Ipc_Server *ecore_ipc_client_server_get(Ecore_Ipc_Client *cl);
+ EAPI void *ecore_ipc_client_del(Ecore_Ipc_Client *cl);
+ EAPI void ecore_ipc_client_data_set(Ecore_Ipc_Client *cl, const void *data);
+ EAPI void *ecore_ipc_client_data_get(Ecore_Ipc_Client *cl);
+
+ EAPI int ecore_ipc_ssl_available_get(void);
+ /* FIXME: need to add a callback to "ok" large ipc messages greater than */
+ /* a certain size (seurity/DOS attack safety) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ecore/src/lib/ecore_ipc/Makefile.am b/ecore/src/lib/ecore_ipc/Makefile.am
new file mode 100644
index 0000000..48d8746
--- /dev/null
+++ b/ecore/src/lib/ecore_ipc/Makefile.am
@@ -0,0 +1,39 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_con \
+-I$(top_builddir)/src/lib/ecore_ipc \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_con \
+-I$(top_srcdir)/src/lib/ecore_ipc \
+@SSL_CFLAGS@
+
+libecore_ipc_la_LDFLAGS = -version-info 1:0:0 \
+-L$(top_builddir)/src/lib/ecore/.libs \
+-L$(top_builddir)/src/lib/ecore_con/.libs
+
+if BUILD_ECORE_IPC
+
+lib_LTLIBRARIES = libecore_ipc.la
+include_HEADERS = \
+Ecore_Ipc.h
+
+libecore_ipc_la_SOURCES = \
+ecore_ipc.c \
+ecore_ipc_private.h
+
+libecore_ipc_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_con/libecore_con.la \
+@SSL_LIBS@ @winsock_libs@
+
+libecore_ipc_la_DEPENDENCIES = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_con/libecore_con.la
+
+endif
+
+EXTRA_DIST = \
+ecore_ipc.c \
+ecore_ipc_private.h
diff --git a/ecore/src/lib/ecore_ipc/ecore_ipc.c b/ecore/src/lib/ecore_ipc/ecore_ipc.c
new file mode 100644
index 0000000..cbe2c03
--- /dev/null
+++ b/ecore/src/lib/ecore_ipc/ecore_ipc.c
@@ -0,0 +1,1257 @@
+#include "Ecore.h"
+#include "config.h"
+#include "Ecore_Con.h"
+#include "ecore_private.h"
+#include "ecore_ipc_private.h"
+#include "Ecore_Ipc.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#elif WIN32
+#include <winsock.h>
+#endif
+
+#define DLT_ZERO 0
+#define DLT_ONE 1
+#define DLT_SAME 2
+#define DLT_SHL 3
+#define DLT_SHR 4
+#define DLT_ADD8 5
+#define DLT_DEL8 6
+#define DLT_ADDU8 7
+#define DLT_DELU8 8
+#define DLT_ADD16 9
+#define DLT_DEL16 10
+#define DLT_ADDU16 11
+#define DLT_DELU16 12
+#define DLT_SET 13
+#define DLT_R1 14
+#define DLT_R2 15
+
+/* byte swappers - for dealing with big vs little endian machines */
+unsigned short
+_ecore_ipc_swap_16(unsigned short v)
+{
+ unsigned char *s, t;
+
+ s = (unsigned char *)(&v);
+ t = s[0]; s[0] = s[1]; s[1] = t;
+ return v;
+}
+
+unsigned int
+_ecore_ipc_swap_32(unsigned int v)
+{
+ unsigned char *s, t;
+
+ s = (unsigned char *)(&v);
+ t = s[0]; s[0] = s[3]; s[3] = t;
+ t = s[1]; s[1] = s[2]; s[2] = t;
+ return v;
+}
+
+unsigned long long
+_ecore_ipc_swap_64(unsigned long long v)
+{
+ unsigned char *s, t;
+
+ s = (unsigned char *)(&v);
+ t = s[0]; s[0] = s[7]; s[7] = t;
+ t = s[1]; s[1] = s[6]; s[6] = t;
+ t = s[2]; s[2] = s[5]; s[5] = t;
+ t = s[3]; s[3] = s[4]; s[4] = t;
+ return v;
+}
+
+static int _ecore_ipc_dlt_int(int out, int prev, int *mode);
+static int _ecore_ipc_ddlt_int(int in, int prev, int mode);
+
+static int
+_ecore_ipc_dlt_int(int out, int prev, int *mode)
+{
+ int dlt;
+
+ /* 0 byte */
+ if (out == 0)
+ {
+ *mode = DLT_ZERO;
+ return 0;
+ }
+ if (out == (int)0xffffffff)
+ {
+ *mode = DLT_ONE;
+ return 0;
+ }
+ if (out == prev)
+ {
+ *mode = DLT_SAME;
+ return 0;
+ }
+ if (out == prev << 1)
+ {
+ *mode = DLT_SHL;
+ return 0;
+ }
+ if (out == prev >> 1)
+ {
+ *mode = DLT_SHR;
+ return 0;
+ }
+ /* 1 byte */
+ dlt = out - prev;
+ if (!(dlt & 0xffffff00))
+ {
+ *mode = DLT_ADD8;
+ return dlt & 0xff;
+ }
+ dlt = prev - out;
+ if (!(dlt & 0xffffff00))
+ {
+ *mode = DLT_DEL8;
+ return dlt & 0xff;
+ }
+ dlt = out - prev;
+ if (!(dlt & 0x00ffffff))
+ {
+ *mode = DLT_ADDU8;
+ return (dlt >> 24) & 0xff;
+ }
+ dlt = prev - out;
+ if (!(dlt & 0x00ffffff))
+ {
+ *mode = DLT_DELU8;
+ return (dlt >> 24) & 0xff;
+ }
+ /* 2 byte */
+ dlt = out - prev;
+ if (!(dlt & 0xffff0000))
+ {
+ *mode = DLT_ADD16;
+ return dlt & 0xfffff;
+ }
+ dlt = prev - out;
+ if (!(dlt & 0xffff0000))
+ {
+ *mode = DLT_DEL16;
+ return dlt & 0xffff;
+ }
+ dlt = out - prev;
+ if (!(dlt & 0x0000ffff))
+ {
+ *mode = DLT_ADDU16;
+ return (dlt >> 16) & 0xffff;
+ }
+ dlt = prev - out;
+ if (!(dlt & 0x0000ffff))
+ {
+ *mode = DLT_DELU16;
+ return (dlt >> 16) & 0xffff;
+ }
+ /* 4 byte */
+ *mode = DLT_SET;
+ return out;
+}
+
+static int
+_ecore_ipc_ddlt_int(int in, int prev, int mode)
+{
+ switch (mode)
+ {
+ case DLT_ZERO:
+ return 0;
+ break;
+ case DLT_ONE:
+ return 0xffffffff;
+ break;
+ case DLT_SAME:
+ return prev;
+ break;
+ case DLT_SHL:
+ return prev << 1;
+ break;
+ case DLT_SHR:
+ return prev >> 1;
+ break;
+ case DLT_ADD8:
+ return prev + in;
+ break;
+ case DLT_DEL8:
+ return prev - in;
+ break;
+ case DLT_ADDU8:
+ return prev + (in << 24);
+ break;
+ case DLT_DELU8:
+ return prev - (in << 24);
+ break;
+ case DLT_ADD16:
+ return prev + in;
+ break;
+ case DLT_DEL16:
+ return prev - in;
+ break;
+ case DLT_ADDU16:
+ return prev + (in << 16);
+ break;
+ case DLT_DELU16:
+ return prev - (in << 16);
+ break;
+ case DLT_SET:
+ return in;
+ break;
+ case DLT_R1:
+ return 0;
+ break;
+ case DLT_R2:
+ return 0;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int _ecore_ipc_event_client_add(void *data, int ev_type, void *ev);
+static int _ecore_ipc_event_client_del(void *data, int ev_type, void *ev);
+static int _ecore_ipc_event_server_add(void *data, int ev_type, void *ev);
+static int _ecore_ipc_event_server_del(void *data, int ev_type, void *ev);
+static int _ecore_ipc_event_client_data(void *data, int ev_type, void *ev);
+static int _ecore_ipc_event_server_data(void *data, int ev_type, void *ev);
+static void _ecore_ipc_event_client_data_free(void *data, void *ev);
+static void _ecore_ipc_event_server_data_free(void *data, void *ev);
+
+int ECORE_IPC_EVENT_CLIENT_ADD = 0;
+int ECORE_IPC_EVENT_CLIENT_DEL = 0;
+int ECORE_IPC_EVENT_SERVER_ADD = 0;
+int ECORE_IPC_EVENT_SERVER_DEL = 0;
+int ECORE_IPC_EVENT_CLIENT_DATA = 0;
+int ECORE_IPC_EVENT_SERVER_DATA = 0;
+
+static int init_count = 0;
+static Ecore_Ipc_Server *servers = NULL;
+
+/**
+ * @defgroup Ecore_IPC_Library_Group IPC Library Functions
+ *
+ * Functions that set up and shut down the Ecore IPC Library.
+ */
+
+/**
+ * Initialises the Ecore IPC library.
+ * @return Number of times the library has been initialised without
+ * being shut down.
+ * @ingroup Ecore_IPC_Library_Group
+ */
+int
+ecore_ipc_init(void)
+{
+ if (!init_count) ecore_con_init();
+ init_count++;
+ if (!ECORE_IPC_EVENT_CLIENT_ADD)
+ {
+ ECORE_IPC_EVENT_CLIENT_ADD = ecore_event_type_new();
+ ECORE_IPC_EVENT_CLIENT_DEL = ecore_event_type_new();
+ ECORE_IPC_EVENT_SERVER_ADD = ecore_event_type_new();
+ ECORE_IPC_EVENT_SERVER_DEL = ecore_event_type_new();
+ ECORE_IPC_EVENT_CLIENT_DATA = ecore_event_type_new();
+ ECORE_IPC_EVENT_SERVER_DATA = ecore_event_type_new();
+
+ ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, _ecore_ipc_event_client_add, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, _ecore_ipc_event_client_del, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, _ecore_ipc_event_server_add, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, _ecore_ipc_event_server_del, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, _ecore_ipc_event_client_data, NULL);
+ ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, _ecore_ipc_event_server_data, NULL);
+ }
+ return init_count;
+}
+
+/**
+ * Shuts down the Ecore IPC library.
+ * @return Number of times the library has been initialised without being
+ * shut down.
+ * @ingroup Ecore_IPC_Library_Group
+ */
+int
+ecore_ipc_shutdown(void)
+{
+ if (init_count > 0)
+ {
+ init_count--;
+ if (init_count > 0) return init_count;
+ while (servers) ecore_ipc_server_del(servers);
+ ecore_con_shutdown();
+ }
+ return 0;
+}
+
+/**
+ * @defgroup Ecore_IPC_Server_Group IPC Server Functions
+ *
+ * Functions the deal with IPC server objects.
+ */
+
+/**
+ * Creates an IPC server that listens for connections.
+ *
+ * For more details about the @p compl_type, @p name and @p port
+ * parameters, see the @ref ecore_con_server_add documentation.
+ *
+ * @param compl_type The connection type.
+ * @param name Name to associate with the socket used for connection.
+ * @param port Number to identify with socket used for connection.
+ * @param data Data to associate with the IPC server.
+ * @return New IPC server. If there is an error, @c NULL is returned.
+ * @ingroup Ecore_IPC_Server_Group
+ * @todo Need to add protocol type parameter to this function.
+ */
+Ecore_Ipc_Server *
+ecore_ipc_server_add(Ecore_Ipc_Type compl_type, const char *name, int port, const void *data)
+{
+ Ecore_Ipc_Server *svr;
+ Ecore_Ipc_Type type;
+ Ecore_Con_Type extra = 0;
+
+ svr = calloc(1, sizeof(Ecore_Ipc_Server));
+ if (!svr) return NULL;
+ type = compl_type;
+ type &= ~ECORE_IPC_USE_SSL;
+ if (compl_type & ECORE_IPC_USE_SSL) extra = ECORE_CON_USE_SSL;
+ switch (type)
+ {
+ case ECORE_IPC_LOCAL_USER:
+ svr->server = ecore_con_server_add(ECORE_CON_LOCAL_USER | extra, name, port, svr);
+ break;
+ case ECORE_IPC_LOCAL_SYSTEM:
+ svr->server = ecore_con_server_add(ECORE_CON_LOCAL_SYSTEM | extra, name, port, svr);
+ break;
+ case ECORE_IPC_REMOTE_SYSTEM:
+ svr->server = ecore_con_server_add(ECORE_CON_REMOTE_SYSTEM | extra, name, port, svr);
+ break;
+ default:
+ free(svr);
+ return NULL;
+ }
+ if (!svr->server)
+ {
+ free(svr);
+ return NULL;
+ }
+ svr->data = (void *)data;
+ servers = _ecore_list_append(servers, svr);
+ ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER);
+ return svr;
+}
+
+/**
+ * Creates an IPC server object to represent the IPC server listening
+ * on the given port.
+ *
+ * For more details about the @p compl_type, @p name and @p port
+ * parameters, see the @ref ecore_con_server_connect documentation.
+ *
+ * @param compl_type The IPC connection type.
+ * @param name Name used to determine which socket to use for the
+ * IPC connection.
+ * @param port Number used to identify the socket to use for the
+ * IPC connection.
+ * @param data Data to associate with the server.
+ * @return A new IPC server. @c NULL is returned on error.
+ * @ingroup Ecore_IPC_Server_Group
+ * @todo Need to add protocol type parameter.
+ */
+Ecore_Ipc_Server *
+ecore_ipc_server_connect(Ecore_Ipc_Type compl_type, char *name, int port, const void *data)
+{
+ Ecore_Ipc_Server *svr;
+ Ecore_Ipc_Type type;
+ Ecore_Con_Type extra = 0;
+
+ svr = calloc(1, sizeof(Ecore_Ipc_Server));
+ if (!svr) return NULL;
+ type = compl_type;
+ type &= ~ECORE_IPC_USE_SSL;
+ if (compl_type & ECORE_IPC_USE_SSL) extra = ECORE_CON_USE_SSL;
+ switch (type)
+ {
+ case ECORE_IPC_LOCAL_USER:
+ svr->server = ecore_con_server_connect(ECORE_CON_LOCAL_USER | extra, name, port, svr);
+ break;
+ case ECORE_IPC_LOCAL_SYSTEM:
+ svr->server = ecore_con_server_connect(ECORE_CON_LOCAL_SYSTEM | extra, name, port, svr);
+ break;
+ case ECORE_IPC_REMOTE_SYSTEM:
+ svr->server = ecore_con_server_connect(ECORE_CON_REMOTE_SYSTEM | extra, name, port, svr);
+ break;
+ default:
+ free(svr);
+ return NULL;
+ }
+ if (!svr->server)
+ {
+ free(svr);
+ return NULL;
+ }
+ svr->data = (void *)data;
+ servers = _ecore_list_append(servers, svr);
+ ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER);
+ return svr;
+}
+
+/**
+ * Closes the connection and frees the given IPC server.
+ * @param svr The given IPC server.
+ * @return The data associated with the server when it was created.
+ * @ingroup Ecore_IPC_Server_Group
+ */
+void *
+ecore_ipc_server_del(Ecore_Ipc_Server *svr)
+{
+ void *data;
+
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_del");
+ return NULL;
+ }
+ ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE);
+ data = svr->data;
+ while (svr->clients) ecore_ipc_client_del((Ecore_Ipc_Client *)svr->clients);
+ ecore_con_server_del(svr->server);
+ servers = _ecore_list_remove(servers, svr);
+ if (svr->buf) free(svr->buf);
+ free(svr);
+ return data;
+}
+
+/**
+ * Retrieves the data associated with the given IPC server.
+ * @param svr The given IPC server.
+ * @return The associated data.
+ * @ingroup Ecore_IPC_Server_Group
+ */
+void *
+ecore_ipc_server_data_get(Ecore_Ipc_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_data_get");
+ return NULL;
+ }
+ return svr->data;
+}
+
+/**
+ * Retrieves whether the given IPC server is currently connected.
+ * @param svr The given IPC server.
+ * @return @c 1 if the server is connected. @c 0 otherwise.
+ * @ingroup Ecore_IPC_Server_Group
+ */
+int
+ecore_ipc_server_connected_get(Ecore_Ipc_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_connected_get");
+ return 0;
+ }
+ return ecore_con_server_connected_get(svr->server);
+}
+
+#define SVENC(_member) \
+ d = _ecore_ipc_dlt_int(msg._member, svr->prev.o._member, &md); \
+ if (md >= DLT_SET) \
+ { \
+ unsigned int v; \
+ unsigned char *dd; \
+ dd = (unsigned char *)&v; \
+ v = d; \
+ v = htonl(v); \
+ *(dat + s + 0) = dd[0]; \
+ *(dat + s + 1) = dd[1]; \
+ *(dat + s + 2) = dd[2]; \
+ *(dat + s + 3) = dd[3]; \
+ s += 4; \
+ } \
+ else if (md >= DLT_ADD16) \
+ { \
+ unsigned short v; \
+ unsigned char *dd; \
+ dd = (unsigned char *)&v; \
+ v = d; \
+ v = htons(v); \
+ *(dat + s + 0) = dd[0]; \
+ *(dat + s + 1) = dd[1]; \
+ s += 2; \
+ } \
+ else if (md >= DLT_ADD8) \
+ { \
+ *(dat + s + 0) = (unsigned char)d; \
+ s += 1; \
+ }
+
+/**
+ * Sends a message to the given IPC server.
+ *
+ * The content of the parameters, excluding the @p svr paramter, is up to
+ * the client.
+ *
+ * @param svr The given IPC server.
+ * @param major Major opcode of the message.
+ * @param minor Minor opcode of the message.
+ * @param ref Message reference number.
+ * @param ref_to Reference number of the message this message refers to.
+ * @param response Requires response.
+ * @param data The data to send as part of the message.
+ * @param size Length of the data, in bytes, to send.
+ * @return Number of bytes sent. @c 0 is returned if there is an error.
+ * @ingroup Ecore_IPC_Server_Group
+ * @todo This function needs to become an IPC message.
+ * @todo Fix up the documentation: Make sure what ref_to and response are.
+ */
+int
+ecore_ipc_server_send(Ecore_Ipc_Server *svr, int major, int minor, int ref, int ref_to, int response, void *data, int size)
+{
+ Ecore_Ipc_Msg_Head msg;
+ int ret;
+ int *head, md = 0, d, s;
+ unsigned char dat[sizeof(Ecore_Ipc_Msg_Head)];
+
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_send");
+ return 0;
+ }
+ if (size < 0) size = 0;
+ msg.major = major;
+ msg.minor = minor;
+ msg.ref = ref;
+ msg.ref_to = ref_to;
+ msg.response = response;
+ msg.size = size;
+ head = (int *)dat;
+ s = 4;
+ SVENC(major);
+ *head = md;
+ SVENC(minor);
+ *head |= md << (4 * 1);
+ SVENC(ref);
+ *head |= md << (4 * 2);
+ SVENC(ref_to);
+ *head |= md << (4 * 3);
+ SVENC(response);
+ *head |= md << (4 * 4);
+ SVENC(size);
+ *head |= md << (4 * 5);
+ *head = htonl(*head);
+ svr->prev.o = msg;
+ ret = ecore_con_server_send(svr->server, dat, s);
+ if (size > 0) ret += ecore_con_server_send(svr->server, data, size);
+ return ret;
+}
+
+/**
+ * Sets a limit on the number of clients that can be handled concurrently
+ * by the given server, and a policy on what to do if excess clients try to
+ * connect.
+ * Beware that if you set this once ecore is already running, you may
+ * already have pending CLIENT_ADD events in your event queue. Those
+ * clients have already connected and will not be affected by this call.
+ * Only clients subsequently trying to connect will be affected.
+ * @param svr The given server.
+ * @param client_limit The maximum number of clients to handle
+ * concurrently. -1 means unlimited (default). 0
+ * effectively disables the server.
+ * @param reject_excess_clients Set to 1 to automatically disconnect
+ * excess clients as soon as they connect if you are
+ * already handling client_limit clients. Set to 0
+ * (default) to just hold off on the "accept()"
+ * system call until the number of active clients
+ * drops. This causes the kernel to queue up to 4096
+ * connections (or your kernel's limit, whichever is
+ * lower).
+ * @ingroup Ecore_Ipc_Server_Group
+ */
+void
+ecore_ipc_server_client_limit_set(Ecore_Ipc_Server *svr, int client_limit, char reject_excess_clients)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_client_limit_set");
+ return;
+ }
+ ecore_con_server_client_limit_set(svr->server, client_limit, reject_excess_clients);
+}
+
+#define CLENC(_member) \
+ d = _ecore_ipc_dlt_int(msg._member, cl->prev.o._member, &md); \
+ if (md >= DLT_SET) \
+ { \
+ unsigned int v; \
+ unsigned char *dd; \
+ dd = (unsigned char *)&v; \
+ v = d; \
+ v = htonl(v); \
+ *(dat + s + 0) = dd[0]; \
+ *(dat + s + 1) = dd[1]; \
+ *(dat + s + 2) = dd[2]; \
+ *(dat + s + 3) = dd[3]; \
+ s += 4; \
+ } \
+ else if (md >= DLT_ADD16) \
+ { \
+ unsigned short v; \
+ unsigned char *dd; \
+ dd = (unsigned char *)&v; \
+ v = d; \
+ v = htons(v); \
+ *(dat + s + 0) = dd[0]; \
+ *(dat + s + 1) = dd[1]; \
+ s += 2; \
+ } \
+ else if (md >= DLT_ADD8) \
+ { \
+ *(dat + s) = (unsigned char)d; \
+ s += 1; \
+ }
+
+/**
+ * @defgroup Ecore_IPC_Client_Group IPC Client Functions
+ *
+ * Functions that deal with IPC client objects.
+ */
+
+/**
+ * Sends a message to the given IPC client.
+ * @param cl The given IPC client.
+ * @param major Major opcode of the message.
+ * @param minor Minor opcode of the message.
+ * @param ref Reference number of the message.
+ * @param ref_to Reference number of the message this message refers to.
+ * @param response Requires response.
+ * @param data The data to send as part of the message.
+ * @param size Length of the data, in bytes, to send.
+ * @return The number of bytes sent. @c 0 will be returned if there is
+ * an error.
+ * @ingroup Ecore_IPC_Client_Group
+ * @todo This function needs to become an IPC message.
+ * @todo Make sure ref_to and response parameters are described correctly.
+ */
+int
+ecore_ipc_client_send(Ecore_Ipc_Client *cl, int major, int minor, int ref, int ref_to, int response, void *data, int size)
+{
+ Ecore_Ipc_Msg_Head msg;
+ int ret;
+ int *head, md = 0, d, s;
+ unsigned char dat[sizeof(Ecore_Ipc_Msg_Head)];
+
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_send");
+ return 0;
+ }
+ if (size < 0) size = 0;
+ msg.major = major;
+ msg.minor = minor;
+ msg.ref = ref;
+ msg.ref_to = ref_to;
+ msg.response = response;
+ msg.size = size;
+ head = (int *)dat;
+ s = 4;
+ CLENC(major);
+ *head = md;
+ CLENC(minor);
+ *head |= md << (4 * 1);
+ CLENC(ref);
+ *head |= md << (4 * 2);
+ CLENC(ref_to);
+ *head |= md << (4 * 3);
+ CLENC(response);
+ *head |= md << (4 * 4);
+ CLENC(size);
+ *head |= md << (4 * 5);
+ *head = htonl(*head);
+ cl->prev.o = msg;
+ ret = ecore_con_client_send(cl->client, dat, s);
+ if (size > 0) ret += ecore_con_client_send(cl->client, data, size);
+ return ret;
+}
+
+/**
+ * Retrieves the IPC server that the given IPC client is connected to.
+ * @param cl The given IPC client.
+ * @return The IPC server the IPC client is connected to.
+ * @ingroup Ecore_IPC_Client_Group
+ */
+Ecore_Ipc_Server *
+ecore_ipc_client_server_get(Ecore_Ipc_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_server_get");
+ return NULL;
+ }
+ return (ecore_con_server_data_get(ecore_con_client_server_get(cl->client)));
+}
+
+/**
+ * Closes the connection and frees memory allocated to the given IPC
+ * client.
+ * @param cl The given client.
+ * @return Data associated with the client.
+ * @ingroup Ecore_IPC_Client_Group
+ */
+void *
+ecore_ipc_client_del(Ecore_Ipc_Client *cl)
+{
+ void *data;
+ Ecore_Ipc_Server *svr;
+
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_del");
+ return NULL;
+ }
+ ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE);
+ data = cl->data;
+ svr = ecore_con_server_data_get(ecore_con_client_server_get(cl->client));
+ ecore_con_client_del(cl->client);
+ svr->clients = _ecore_list_remove(svr->clients, cl);
+ if (cl->buf) free(cl->buf);
+ free(cl);
+ return data;
+}
+
+/**
+ * Sets the IPC data associated with the given IPC client to @p data.
+ * @param cl The given IPC client.
+ * @param data The data to associate with the IPC client.
+ * @ingroup Ecore_IPC_Client_Group
+ */
+void
+ecore_ipc_client_data_set(Ecore_Ipc_Client *cl, const void *data)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_data_set");
+ return;
+ }
+ cl->data = (void *)data;
+}
+
+/**
+ * Retrieves the data that has been associated with the given IPC client.
+ * @param cl The given client.
+ * @return The data associated with the IPC client.
+ * @ingroup Ecore_IPC_Client_Group
+ */
+void *
+ecore_ipc_client_data_get(Ecore_Ipc_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_data_get");
+ return NULL;
+ }
+ return cl->data;
+}
+
+/**
+ * Returns if SSL support is available
+ * @return 1 if SSL is available, 0 if it is not.
+ * @ingroup Ecore_Con_Client_Group
+ */
+int
+ecore_ipc_ssl_available_get(void)
+{
+ return ecore_con_ssl_available_get();
+}
+
+
+static int
+_ecore_ipc_event_client_add(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Client_Add *e;
+
+ e = ev;
+ if (!_ecore_list_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return 1;
+ /* handling code here */
+ {
+ Ecore_Ipc_Client *cl;
+ Ecore_Ipc_Server *svr;
+
+ cl = calloc(1, sizeof(Ecore_Ipc_Client));
+ if (!cl) return 0;
+ svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client));
+ ECORE_MAGIC_SET(cl, ECORE_MAGIC_IPC_CLIENT);
+ cl->client = e->client;
+ ecore_con_client_data_set(cl->client, (void *)cl);
+ svr->clients = _ecore_list_append(svr->clients, cl);
+ {
+ Ecore_Ipc_Event_Client_Add *e2;
+
+ e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Add));
+ if (e2)
+ {
+ e2->client = cl;
+ ecore_event_add(ECORE_IPC_EVENT_CLIENT_ADD, e2, NULL, NULL);
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+_ecore_ipc_event_client_del(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Client_Del *e;
+
+ e = ev;
+ if (!_ecore_list_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return 1;
+ /* handling code here */
+ {
+ Ecore_Ipc_Client *cl;
+
+ cl = ecore_con_client_data_get(e->client);
+ {
+ Ecore_Ipc_Event_Client_Del *e2;
+
+ e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Del));
+ if (e2)
+ {
+ e2->client = cl;
+ ecore_event_add(ECORE_IPC_EVENT_CLIENT_DEL, e2, NULL, NULL);
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+_ecore_ipc_event_server_add(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Server_Add *e;
+
+ e = ev;
+ if (!_ecore_list_find(servers, ecore_con_server_data_get(e->server))) return 1;
+ /* handling code here */
+ {
+ Ecore_Ipc_Server *svr;
+
+ svr = ecore_con_server_data_get(e->server);
+ {
+ Ecore_Ipc_Event_Server_Add *e2;
+
+ e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Add));
+ if (e2)
+ {
+ e2->server = svr;
+ ecore_event_add(ECORE_IPC_EVENT_SERVER_ADD, e2, NULL, NULL);
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+_ecore_ipc_event_server_del(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Server_Del *e;
+
+ e = ev;
+ if (!_ecore_list_find(servers, ecore_con_server_data_get(e->server))) return 1;
+ /* handling code here */
+ {
+ Ecore_Ipc_Server *svr;
+
+ svr = ecore_con_server_data_get(e->server);
+ {
+ Ecore_Ipc_Event_Server_Del *e2;
+
+ e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Del));
+ if (e2)
+ {
+ e2->server = svr;
+ ecore_event_add(ECORE_IPC_EVENT_SERVER_DEL, e2, NULL, NULL);
+ }
+ }
+ }
+ return 0;
+}
+
+#define CLSZ(_n) \
+ md = ((head >> (4 * _n)) & 0xf); \
+ if (md >= DLT_SET) s += 4; \
+ else if (md >= DLT_ADD16) s += 2; \
+ else if (md >= DLT_ADD8) s += 1;
+
+#define CLDEC(_n, _member) \
+ md = ((head >> (4 * _n)) & 0xf); \
+ if (md >= DLT_SET) \
+ { \
+ unsigned int v; \
+ unsigned char *dv; \
+ dv = (unsigned char *)&v; \
+ dv[0] = *(cl->buf + offset + s + 0); \
+ dv[1] = *(cl->buf + offset + s + 1); \
+ dv[2] = *(cl->buf + offset + s + 2); \
+ dv[3] = *(cl->buf + offset + s + 3); \
+ d = (int)ntohl(d); \
+ s += 4; \
+ } \
+ else if (md >= DLT_ADD16) \
+ { \
+ unsigned short v; \
+ unsigned char *dv; \
+ dv = (unsigned char *)&v; \
+ dv[0] = *(cl->buf + offset + s + 0); \
+ dv[1] = *(cl->buf + offset + s + 1); \
+ d = (int)ntohs(v); \
+ s += 2; \
+ } \
+ else if (md >= DLT_ADD8) \
+ { \
+ unsigned char v; \
+ unsigned char *dv; \
+ dv = (unsigned char *)&v; \
+ dv[0] = *(cl->buf + offset + s + 0); \
+ d = (int)v; \
+ s += 1; \
+ } \
+ msg._member = _ecore_ipc_ddlt_int(d, cl->prev.i._member, md);
+
+static int
+_ecore_ipc_event_client_data(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Client_Data *e;
+
+ e = ev;
+ if (!_ecore_list_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return 1;
+ /* handling code here */
+ {
+ Ecore_Ipc_Client *cl;
+ Ecore_Ipc_Msg_Head msg;
+ int offset = 0;
+ unsigned char *buf;
+
+ cl = ecore_con_client_data_get(e->client);
+
+ if (!cl->buf)
+ {
+ cl->buf_size = e->size;
+ cl->buf = e->data;
+ e->data = NULL; /* take it out of the old event */
+ }
+ else
+ {
+ unsigned char *buf;
+
+ buf = realloc(cl->buf, cl->buf_size + e->size);
+ if (!buf)
+ {
+ free(cl->buf);
+ cl->buf = 0;
+ cl->buf_size = 0;
+ return 0;
+ }
+ cl->buf = buf;
+ memcpy(cl->buf + cl->buf_size, e->data, e->size);
+ cl->buf_size += e->size;
+ }
+ /* examine header */
+ redo:
+ if ((cl->buf_size - offset) >= (int)sizeof(int))
+ {
+ int s, md, d, head;
+ unsigned char *dd;
+
+ dd = (unsigned char *)&head;
+ dd[0] = *(cl->buf + offset + 0);
+ dd[1] = *(cl->buf + offset + 1);
+ dd[2] = *(cl->buf + offset + 2);
+ dd[3] = *(cl->buf + offset + 3);
+ head = ntohl(head);
+ dd = (unsigned char *)&d;
+ s = 4;
+ CLSZ(0);
+ CLSZ(1);
+ CLSZ(2);
+ CLSZ(3);
+ CLSZ(4);
+ CLSZ(5);
+ if ((cl->buf_size - offset) < s)
+ {
+ if (offset > 0) goto scroll;
+ return 0;
+ }
+
+ s = 4;
+ CLDEC(0, major);
+ CLDEC(1, minor);
+ CLDEC(2, ref);
+ CLDEC(3, ref_to);
+ CLDEC(4, response);
+ CLDEC(5, size);
+ if (msg.size < 0) msg.size = 0;
+ /* there is enough data in the buffer for a full message */
+ if ((cl->buf_size - offset) >= (s + msg.size))
+ {
+ Ecore_Ipc_Event_Client_Data *e2;
+
+ buf = NULL;
+ if (msg.size > 0)
+ {
+ buf = malloc(msg.size);
+ if (!buf) return 0;
+ memcpy(buf, cl->buf + offset + s, msg.size);
+ }
+ e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Data));
+ if (e2)
+ {
+ e2->client = cl;
+ e2->major = msg.major;
+ e2->minor = msg.minor;
+ e2->ref = msg.ref;
+ e2->ref_to = msg.ref_to;
+ e2->response = msg.response;
+ e2->size = msg.size;
+ e2->data = buf;
+ ecore_event_add(ECORE_IPC_EVENT_CLIENT_DATA, e2,
+ _ecore_ipc_event_client_data_free, NULL);
+ }
+ cl->prev.i = msg;
+ offset += (s + msg.size);
+ if (cl->buf_size == offset)
+ {
+ free(cl->buf);
+ cl->buf = NULL;
+ cl->buf_size = 0;
+ return 0;
+ }
+ goto redo;
+ }
+ else goto scroll;
+ }
+ else
+ {
+ scroll:
+ buf = malloc(cl->buf_size - offset);
+ if (!buf)
+ {
+ free(cl->buf);
+ cl->buf = NULL;
+ cl->buf_size = 0;
+ return 0;
+ }
+ memcpy(buf, cl->buf + offset, cl->buf_size - offset);
+ free(cl->buf);
+ cl->buf = buf;
+ cl->buf_size -= offset;
+ }
+ }
+ return 0;
+}
+
+#define SVSZ(_n) \
+ md = ((head >> (4 * _n)) & 0xf); \
+ if (md >= DLT_SET) s += 4; \
+ else if (md >= DLT_ADD16) s += 2; \
+ else if (md >= DLT_ADD8) s += 1;
+
+#define SVDEC(_n, _member) \
+ md = ((head >> (4 * _n)) & 0xf); \
+ if (md >= DLT_SET) \
+ { \
+ unsigned int v; \
+ unsigned char *dv; \
+ dv = (unsigned char *)&v; \
+ dv[0] = *(svr->buf + offset + s + 0); \
+ dv[1] = *(svr->buf + offset + s + 1); \
+ dv[2] = *(svr->buf + offset + s + 2); \
+ dv[3] = *(svr->buf + offset + s + 3); \
+ d = (int)ntohl(d); \
+ s += 4; \
+ } \
+ else if (md >= DLT_ADD16) \
+ { \
+ unsigned short v; \
+ unsigned char *dv; \
+ dv = (unsigned char *)&v; \
+ dv[0] = *(svr->buf + offset + s + 0); \
+ dv[1] = *(svr->buf + offset + s + 1); \
+ d = (int)ntohs(v); \
+ s += 2; \
+ } \
+ else if (md >= DLT_ADD8) \
+ { \
+ unsigned char v; \
+ unsigned char *dv; \
+ dv = (unsigned char *)&v; \
+ dv[0] = *(svr->buf + offset + s + 0); \
+ d = (int)v; \
+ s += 1; \
+ } \
+ msg._member = _ecore_ipc_ddlt_int(d, svr->prev.i._member, md);
+
+static int
+_ecore_ipc_event_server_data(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Server_Data *e;
+
+ e = ev;
+ if (!_ecore_list_find(servers, ecore_con_server_data_get(e->server))) return 1;
+ /* handling code here */
+ {
+ Ecore_Ipc_Server *svr;
+ Ecore_Ipc_Msg_Head msg;
+ int offset = 0;
+ unsigned char *buf;
+
+ svr = ecore_con_server_data_get(e->server);
+
+ if (!svr->buf)
+ {
+ svr->buf_size = e->size;
+ svr->buf = e->data;
+ e->data = NULL; /* take it out of the old event */
+ }
+ else
+ {
+ unsigned char *buf;
+
+ buf = realloc(svr->buf, svr->buf_size + e->size);
+ if (!buf)
+ {
+ free(svr->buf);
+ svr->buf = 0;
+ svr->buf_size = 0;
+ return 0;
+ }
+ svr->buf = buf;
+ memcpy(svr->buf + svr->buf_size, e->data, e->size);
+ svr->buf_size += e->size;
+ }
+ /* examine header */
+ redo:
+ if ((svr->buf_size - offset) >= (int)sizeof(int))
+ {
+ int s, md, d, head;
+ unsigned char *dd;
+
+ dd = (unsigned char *)&head;
+ dd[0] = *(svr->buf + offset + 0);
+ dd[1] = *(svr->buf + offset + 1);
+ dd[2] = *(svr->buf + offset + 2);
+ dd[3] = *(svr->buf + offset + 3);
+ head = ntohl(head);
+ dd = (unsigned char *)&d;
+ s = 4;
+ SVSZ(0);
+ SVSZ(1);
+ SVSZ(2);
+ SVSZ(3);
+ SVSZ(4);
+ SVSZ(5);
+ if ((svr->buf_size - offset) < s)
+ {
+ if (offset > 0) goto scroll;
+ return 0;
+ }
+
+ s = 4;
+ SVDEC(0, major);
+ SVDEC(1, minor);
+ SVDEC(2, ref);
+ SVDEC(3, ref_to);
+ SVDEC(4, response);
+ SVDEC(5, size);
+ if (msg.size < 0) msg.size = 0;
+ /* there is enough data in the buffer for a full message */
+ if ((svr->buf_size - offset) >= (s + msg.size))
+ {
+ Ecore_Ipc_Event_Server_Data *e2;
+
+ buf = NULL;
+ if (msg.size > 0)
+ {
+ buf = malloc(msg.size);
+ if (!buf) return 0;
+ memcpy(buf, svr->buf + offset + s, msg.size);
+ }
+ e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Data));
+ if (e2)
+ {
+ e2->server = svr;
+ e2->major = msg.major;
+ e2->minor = msg.minor;
+ e2->ref = msg.ref;
+ e2->ref_to = msg.ref_to;
+ e2->response = msg.response;
+ e2->size = msg.size;
+ e2->data = buf;
+ ecore_event_add(ECORE_IPC_EVENT_SERVER_DATA, e2,
+ _ecore_ipc_event_server_data_free, NULL);
+ }
+ svr->prev.i = msg;
+ offset += (s + msg.size);
+ if (svr->buf_size == offset)
+ {
+ free(svr->buf);
+ svr->buf = NULL;
+ svr->buf_size = 0;
+ return 0;
+ }
+ goto redo;
+ }
+ else goto scroll;
+ }
+ else
+ {
+ scroll:
+ buf = malloc(svr->buf_size - offset);
+ if (!buf)
+ {
+ free(svr->buf);
+ svr->buf = NULL;
+ svr->buf_size = 0;
+ return 0;
+ }
+ memcpy(buf, svr->buf + offset, svr->buf_size - offset);
+ free(svr->buf);
+ svr->buf = buf;
+ svr->buf_size -= offset;
+ }
+ }
+ return 0;
+}
+
+static void
+_ecore_ipc_event_client_data_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Ipc_Event_Client_Data *e;
+
+ e = ev;
+ if (e->data) free(e->data);
+ free(e);
+}
+
+static void
+_ecore_ipc_event_server_data_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Ipc_Event_Server_Data *e;
+
+ e = ev;
+ if (e->data) free(e->data);
+ free(e);
+}
diff --git a/ecore/src/lib/ecore_ipc/ecore_ipc_private.h b/ecore/src/lib/ecore_ipc/ecore_ipc_private.h
new file mode 100644
index 0000000..0e4d6ea
--- /dev/null
+++ b/ecore/src/lib/ecore_ipc/ecore_ipc_private.h
@@ -0,0 +1,66 @@
+#ifndef _ECORE_IPC_PRIVATE_H
+#define _ECORE_IPC_PRIVATE_H
+
+#if USE_OPENSSL
+#include <openssl/ssl.h>
+#endif
+
+#define ECORE_MAGIC_IPC_SERVER 0x87786556
+#define ECORE_MAGIC_IPC_CLIENT 0x78875665
+
+typedef struct _Ecore_Ipc_Client Ecore_Ipc_Client;
+typedef struct _Ecore_Ipc_Server Ecore_Ipc_Server;
+typedef struct _Ecore_Ipc_Msg_Head Ecore_Ipc_Msg_Head;
+
+
+#ifdef __sgi
+#pragma pack 4
+#endif
+struct _Ecore_Ipc_Msg_Head
+{
+ int head;
+ int major;
+ int minor;
+ int ref;
+ int ref_to;
+ int response;
+ int size;
+}
+#ifdef _GNU_C_
+__attribute__ ((packed));
+#endif
+;
+#ifdef __sgi
+#pragma pack 0
+#endif
+
+struct _Ecore_Ipc_Client
+{
+ Ecore_List __list_data;
+ ECORE_MAGIC;
+ Ecore_Con_Client *client;
+ void *data;
+ unsigned char *buf;
+ int buf_size;
+
+ struct {
+ Ecore_Ipc_Msg_Head i, o;
+ } prev;
+};
+
+struct _Ecore_Ipc_Server
+{
+ Ecore_List __list_data;
+ ECORE_MAGIC;
+ Ecore_Con_Server *server;
+ Ecore_Ipc_Client *clients;
+ void *data;
+ unsigned char *buf;
+ int buf_size;
+
+ struct {
+ Ecore_Ipc_Msg_Head i, o;
+ } prev;
+};
+
+#endif
diff --git a/ecore/src/lib/ecore_job/.cvsignore b/ecore/src/lib/ecore_job/.cvsignore
new file mode 100644
index 0000000..0aac4af
--- /dev/null
+++ b/ecore/src/lib/ecore_job/.cvsignore
@@ -0,0 +1,6 @@
+.deps
+.libs
+Makefile
+Makefile.in
+ecore_job.lo
+libecore_job.la
diff --git a/ecore/src/lib/ecore_job/CVS/Entries b/ecore/src/lib/ecore_job/CVS/Entries
new file mode 100644
index 0000000..93e034b
--- /dev/null
+++ b/ecore/src/lib/ecore_job/CVS/Entries
@@ -0,0 +1,6 @@
+/.cvsignore/1.1/Thu Nov 13 12:30:47 2003//THEAD
+/Ecore_Job.h/1.4/Thu Nov 25 05:17:17 2004//THEAD
+/Makefile.am/1.6/Thu Mar 10 15:19:41 2005//THEAD
+/ecore_job.c/1.7/Wed Mar 2 07:06:42 2005//THEAD
+/ecore_job_private.h/1.2/Tue Sep 23 08:09:31 2003//THEAD
+D
diff --git a/ecore/src/lib/ecore_job/CVS/Repository b/ecore/src/lib/ecore_job/CVS/Repository
new file mode 100644
index 0000000..65ef847
--- /dev/null
+++ b/ecore/src/lib/ecore_job/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/lib/ecore_job
diff --git a/ecore/src/lib/ecore_job/CVS/Root b/ecore/src/lib/ecore_job/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/lib/ecore_job/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/lib/ecore_job/CVS/Tag b/ecore/src/lib/ecore_job/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/lib/ecore_job/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/lib/ecore_job/Ecore_Job.h b/ecore/src/lib/ecore_job/Ecore_Job.h
new file mode 100644
index 0000000..e676ede
--- /dev/null
+++ b/ecore/src/lib/ecore_job/Ecore_Job.h
@@ -0,0 +1,41 @@
+#ifndef _ECORE_JOB_H
+#define _ECORE_JOB_H
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef WIN32
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef GCC_HASCLASSVISIBILITY
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file
+ * @brief Functions for dealing with Ecore jobs.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ECORE_JOB_PRIVATE_H
+typedef void Ecore_Job; /**< A job handle */
+#endif
+
+EAPI Ecore_Job *ecore_job_add(void (*func) (void *data), const void *data);
+EAPI void *ecore_job_del(Ecore_Job *job);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ecore/src/lib/ecore_job/Makefile.am b/ecore/src/lib/ecore_job/Makefile.am
new file mode 100644
index 0000000..476b7c0
--- /dev/null
+++ b/ecore/src/lib/ecore_job/Makefile.am
@@ -0,0 +1,31 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore
+
+libecore_job_la_LDFLAGS = -version-info 1:0:0 \
+-L$(top_builddir)/src/lib/ecore/.libs
+
+if BUILD_ECORE_JOB
+
+lib_LTLIBRARIES = libecore_job.la
+include_HEADERS = \
+Ecore_Job.h
+
+libecore_job_la_SOURCES = \
+ecore_job.c \
+ecore_job_private.h
+
+libecore_job_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la
+
+libecore_job_la_DEPENDENCIES = \
+$(top_builddir)/src/lib/ecore/libecore.la
+
+endif
+
+EXTRA_DIST = \
+Ecore_Job.h \
+ecore_job.c \
+ecore_job_private.h
diff --git a/ecore/src/lib/ecore_job/ecore_job.c b/ecore/src/lib/ecore_job/ecore_job.c
new file mode 100644
index 0000000..b4fba2a
--- /dev/null
+++ b/ecore/src/lib/ecore_job/ecore_job.c
@@ -0,0 +1,86 @@
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_job_private.h"
+#include "Ecore_Job.h"
+
+static int _ecore_job_event_handler(void *data, int type, void *ev);
+static void _ecore_job_event_free(void *data, void *ev);
+
+static int ecore_event_job_type = 0;
+
+/**
+ * Add a job to the event queue.
+ * @param func The function to call when the job gets handled.
+ * @param data Data pointer to be passed to the job function when the job is
+ * handled.
+ * @return The handle of the job. @c NULL is returned if the job could not be
+ * added to the queue.
+ * @ingroup Ecore_Job_Group
+ * @note Once the job has been executed, the job handle is invalid.
+ */
+Ecore_Job *
+ecore_job_add(void (*func) (void *data), const void *data)
+{
+ Ecore_Job *job;
+
+ if (!func) return NULL;
+ if (!ecore_event_job_type)
+ {
+ ecore_event_job_type = ecore_event_type_new();
+ ecore_event_handler_add(ecore_event_job_type, _ecore_job_event_handler, NULL);
+ }
+ job = calloc(1, sizeof(Ecore_Job));
+ if (!job) return NULL;
+ ECORE_MAGIC_SET(job, ECORE_MAGIC_JOB);
+ job->event = ecore_event_add(ecore_event_job_type, job, _ecore_job_event_free, NULL);
+ if (!job->event)
+ {
+ free(job);
+ return NULL;
+ }
+ job->func = func;
+ job->data = (void *)data;
+ return job;
+}
+
+/**
+ * Delete a queued job that has not yet been executed.
+ * @param job Handle of the job to delete.
+ * @return The data pointer that was to be passed to the job.
+ * @ingroup Ecore_Job_Group
+ */
+void *
+ecore_job_del(Ecore_Job *job)
+{
+ void *data;
+
+ if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_JOB))
+ {
+ ECORE_MAGIC_FAIL(job, ECORE_MAGIC_JOB,
+ "ecore_job_del");
+ return NULL;
+ }
+ data = job->data;
+ ECORE_MAGIC_SET(job, ECORE_MAGIC_NONE);
+ ecore_event_del(job->event);
+ return data;
+}
+
+static int
+_ecore_job_event_handler(void *data __UNUSED__, int type __UNUSED__, void *ev)
+{
+ Ecore_Job *job;
+
+ job = ev;
+ job->func(job->data);
+ return 0;
+}
+
+static void
+_ecore_job_event_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Job *job;
+
+ job = ev;
+ free(ev);
+}
diff --git a/ecore/src/lib/ecore_job/ecore_job_private.h b/ecore/src/lib/ecore_job/ecore_job_private.h
new file mode 100644
index 0000000..d5795f2
--- /dev/null
+++ b/ecore/src/lib/ecore_job/ecore_job_private.h
@@ -0,0 +1,16 @@
+#ifndef _ECORE_JOB_PRIVATE_H
+#define _ECORE_JOB_PRIVATE_H
+
+#define ECORE_MAGIC_JOB 0x76543210
+
+typedef struct _Ecore_Job Ecore_Job;
+
+struct _Ecore_Job
+{
+ ECORE_MAGIC;
+ Ecore_Event *event;
+ void (*func) (void *data);
+ void *data;
+};
+
+#endif
diff --git a/ecore/src/lib/ecore_txt/.cvsignore b/ecore/src/lib/ecore_txt/.cvsignore
new file mode 100644
index 0000000..e599172
--- /dev/null
+++ b/ecore/src/lib/ecore_txt/.cvsignore
@@ -0,0 +1,6 @@
+.deps
+.libs
+Makefile
+Makefile.in
+ecore_txt.lo
+libecore_txt.la
diff --git a/ecore/src/lib/ecore_txt/CVS/Entries b/ecore/src/lib/ecore_txt/CVS/Entries
new file mode 100644
index 0000000..bdeacd8
--- /dev/null
+++ b/ecore/src/lib/ecore_txt/CVS/Entries
@@ -0,0 +1,6 @@
+/.cvsignore/1.2/Fri Jan 16 16:59:05 2004//THEAD
+/Ecore_Txt.h/1.4/Mon Nov 29 22:26:30 2004//THEAD
+/Makefile.am/1.5/Thu Mar 10 15:19:42 2005//THEAD
+/ecore_txt.c/1.6/Wed Mar 2 07:06:42 2005//THEAD
+/ecore_txt_private.h/1.1/Thu Oct 9 07:49:59 2003//THEAD
+D
diff --git a/ecore/src/lib/ecore_txt/CVS/Repository b/ecore/src/lib/ecore_txt/CVS/Repository
new file mode 100644
index 0000000..6d66175
--- /dev/null
+++ b/ecore/src/lib/ecore_txt/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/lib/ecore_txt
diff --git a/ecore/src/lib/ecore_txt/CVS/Root b/ecore/src/lib/ecore_txt/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/lib/ecore_txt/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/lib/ecore_txt/CVS/Tag b/ecore/src/lib/ecore_txt/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/lib/ecore_txt/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/lib/ecore_txt/Ecore_Txt.h b/ecore/src/lib/ecore_txt/Ecore_Txt.h
new file mode 100644
index 0000000..60dc659
--- /dev/null
+++ b/ecore/src/lib/ecore_txt/Ecore_Txt.h
@@ -0,0 +1,36 @@
+#ifndef _ECORE_TXT_H
+#define _ECORE_TXT_H
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef WIN32
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef GCC_HASCLASSVISIBILITY
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file Ecore_Txt.h
+ * @brief Provides a text encoding conversion function.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EAPI char *ecore_txt_convert(const char *enc_from, const char *enc_to, const char *text);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ecore/src/lib/ecore_txt/Makefile.am b/ecore/src/lib/ecore_txt/Makefile.am
new file mode 100644
index 0000000..e3fdd01
--- /dev/null
+++ b/ecore/src/lib/ecore_txt/Makefile.am
@@ -0,0 +1,34 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore \
+@iconv_cflags@
+
+libecore_txt_la_LDFLAGS = -version-info 1:0:0 \
+-L$(top_builddir)/src/lib/ecore/.libs
+
+if BUILD_ECORE_TXT
+
+lib_LTLIBRARIES = libecore_txt.la
+include_HEADERS = \
+Ecore_Txt.h
+
+libecore_txt_la_SOURCES = \
+ecore_txt.c \
+ecore_txt_private.h
+
+# FIXME: may have to link with -liconv
+libecore_txt_la_LIBADD = \
+@iconv_libs@
+
+
+libecore_txt_la_DEPENDENCIES =
+
+
+endif
+
+EXTRA_DIST = \
+Ecore_Txt.h \
+ecore_txt.c \
+ecore_txt_private.h
diff --git a/ecore/src/lib/ecore_txt/ecore_txt.c b/ecore/src/lib/ecore_txt/ecore_txt.c
new file mode 100644
index 0000000..cab8f5d
--- /dev/null
+++ b/ecore/src/lib/ecore_txt/ecore_txt.c
@@ -0,0 +1,78 @@
+#include "ecore_txt_private.h"
+#include "Ecore_Txt.h"
+
+#include <iconv.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+/**
+ * To be documented.
+ *
+ * FIXME: Finish this.
+ */
+char *
+ecore_txt_convert(const char *enc_from, const char *enc_to, const char *text)
+{
+ iconv_t ic;
+ char *new_txt, *inp, *outp;
+ size_t inb, outb, outlen, tob, outalloc;
+
+ if (!text) return strdup("");
+ ic = iconv_open(enc_to, enc_from);
+ if (!ic) return strdup("");
+ new_txt = malloc(64);
+ inb = strlen(text);
+ outb = 64;
+ inp = (char*)text;
+ outp = new_txt;
+ outalloc = 64;
+ outlen = 0;
+ tob = 0;
+
+ for (;;)
+ {
+ size_t count;
+
+ tob = outb;
+ count = iconv(ic, &inp, &inb, &outp, &outb);
+ outlen += tob - outb;
+ if (count == (size_t)(-1))
+ {
+ if (errno == E2BIG)
+ {
+ new_txt = realloc(new_txt, outalloc + 64);
+ outalloc += 64;
+ outb += 64;
+ }
+ else if (errno == EILSEQ)
+ {
+ if (new_txt) free(new_txt);
+ new_txt = NULL;
+ break;
+ }
+ else if (errno == EINVAL)
+ {
+ if (new_txt) free(new_txt);
+ new_txt = NULL;
+ break;
+ }
+ else
+ {
+ if (new_txt) free(new_txt);
+ new_txt = NULL;
+ break;
+ }
+ }
+ if (inb == 0)
+ {
+ if (outalloc == outlen) new_txt = realloc(new_txt, outalloc + 1);
+ new_txt[outlen] = 0;
+ break;
+ }
+ }
+ iconv_close(ic);
+ return new_txt;
+}
diff --git a/ecore/src/lib/ecore_txt/ecore_txt_private.h b/ecore/src/lib/ecore_txt/ecore_txt_private.h
new file mode 100644
index 0000000..b3e975a
--- /dev/null
+++ b/ecore/src/lib/ecore_txt/ecore_txt_private.h
@@ -0,0 +1,4 @@
+#ifndef _ECORE_TXT_PRIVATE_H
+#define _ECORE_TXT_PRIVATE_H
+
+#endif
diff --git a/ecore/src/lib/ecore_x/.cvsignore b/ecore/src/lib/ecore_x/.cvsignore
new file mode 100644
index 0000000..8728e80
--- /dev/null
+++ b/ecore/src/lib/ecore_x/.cvsignore
@@ -0,0 +1,6 @@
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+libecore_x.la
diff --git a/ecore/src/lib/ecore_x/CVS/Entries b/ecore/src/lib/ecore_x/CVS/Entries
new file mode 100644
index 0000000..907365e
--- /dev/null
+++ b/ecore/src/lib/ecore_x/CVS/Entries
@@ -0,0 +1,23 @@
+/.cvsignore/1.4/Tue Sep 21 19:18:44 2004//THEAD
+/Ecore_X.h/1.138/Sat Jun 25 07:23:38 2005//THEAD
+/Ecore_X_Atoms.h/1.10/Mon Jun 6 15:04:28 2005//THEAD
+/Ecore_X_Cursor.h/1.2/Fri Apr 30 03:10:17 2004//THEAD
+/Makefile.am/1.23/Mon Jun 6 09:40:00 2005//THEAD
+/ecore_x.c/1.91/Tue Jul 12 15:27:45 2005//THEAD
+/ecore_x_dnd.c/1.20/Sun Apr 10 10:20:18 2005//THEAD
+/ecore_x_e.c/1.2/Mon May 16 12:59:26 2005//THEAD
+/ecore_x_error.c/1.5/Wed Jun 22 06:47:44 2005//THEAD
+/ecore_x_events.c/1.68/Tue Jul 12 15:27:46 2005//THEAD
+/ecore_x_gc.c/1.4/Thu Jul 15 13:43:15 2004//THEAD
+/ecore_x_icccm.c/1.34/Fri Jun 17 09:05:22 2005//THEAD
+/ecore_x_mwm.c/1.4/Fri Jun 10 04:18:24 2005//THEAD
+/ecore_x_netwm.c/1.36/Fri Jun 10 04:18:24 2005//THEAD
+/ecore_x_pixmap.c/1.5/Thu Aug 12 11:29:18 2004//THEAD
+/ecore_x_private.h/1.46/Tue Jul 12 15:27:46 2005//THEAD
+/ecore_x_selection.c/1.26/Mon May 16 12:59:26 2005//THEAD
+/ecore_x_sync.c/1.2/Mon Jun 6 15:04:28 2005//THEAD
+/ecore_x_window.c/1.41/Sat Jun 25 07:23:38 2005//THEAD
+/ecore_x_window_prop.c/1.72/Sat Jun 25 00:15:19 2005//THEAD
+/ecore_x_window_shape.c/1.6/Sat Apr 23 05:06:18 2005//THEAD
+/ecore_x_xinerama.c/1.2/Sat Feb 5 12:59:35 2005//THEAD
+D
diff --git a/ecore/src/lib/ecore_x/CVS/Repository b/ecore/src/lib/ecore_x/CVS/Repository
new file mode 100644
index 0000000..df9cfee
--- /dev/null
+++ b/ecore/src/lib/ecore_x/CVS/Repository
@@ -0,0 +1 @@
+e17/libs/ecore/src/lib/ecore_x
diff --git a/ecore/src/lib/ecore_x/CVS/Root b/ecore/src/lib/ecore_x/CVS/Root
new file mode 100644
index 0000000..0b69fe3
--- /dev/null
+++ b/ecore/src/lib/ecore_x/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment
diff --git a/ecore/src/lib/ecore_x/CVS/Tag b/ecore/src/lib/ecore_x/CVS/Tag
new file mode 100644
index 0000000..3903919
--- /dev/null
+++ b/ecore/src/lib/ecore_x/CVS/Tag
@@ -0,0 +1 @@
+NHEAD
diff --git a/ecore/src/lib/ecore_x/Ecore_X.h b/ecore/src/lib/ecore_x/Ecore_X.h
new file mode 100644
index 0000000..68ff1dd
--- /dev/null
+++ b/ecore/src/lib/ecore_x/Ecore_X.h
@@ -0,0 +1,1320 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifndef _ECORE_X_H
+#define _ECORE_X_H
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef WIN32
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef GCC_HASCLASSVISIBILITY
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file
+ * @brief Ecore functions for dealing with the X Windows System
+ *
+ * Ecore_X provides a wrapper and convenience functions for using the
+ * X Windows System. Function groups for this part of the library
+ * include the following:
+ * @li @ref Ecore_X_Init_Group
+ * @li @ref Ecore_X_Display_Attr_Group
+ * @li @ref Ecore_X_Flush_Group
+ */
+
+typedef unsigned int Ecore_X_ID;
+#ifndef _ECORE_X_WINDOW_PREDEF
+typedef Ecore_X_ID Ecore_X_Window;
+#endif
+typedef Ecore_X_ID Ecore_X_Pixmap;
+typedef Ecore_X_ID Ecore_X_Drawable;
+typedef void * Ecore_X_GC;
+typedef Ecore_X_ID Ecore_X_Atom;
+typedef Ecore_X_ID Ecore_X_Colormap;
+typedef Ecore_X_ID Ecore_X_Time;
+typedef Ecore_X_ID Ecore_X_Cursor;
+typedef void Ecore_X_Display;
+typedef Ecore_X_ID Ecore_X_Sync_Counter;
+typedef Ecore_X_ID Ecore_X_Sync_Alarm;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _Ecore_X_Rectangle {
+ int x, y;
+ unsigned int width, height;
+} Ecore_X_Rectangle;
+
+typedef enum _Ecore_X_Window_State {
+ /** The window is iconified. */
+ ECORE_X_WINDOW_STATE_ICONIFIED,
+
+ /** The window is a modal dialog box. */
+ ECORE_X_WINDOW_STATE_MODAL,
+
+ /** The window manager should keep the window's position fixed
+ * even if the virtual desktop scrolls. */
+ ECORE_X_WINDOW_STATE_STICKY,
+
+ /** The window has the maximum vertical size. */
+ ECORE_X_WINDOW_STATE_MAXIMIZED_VERT,
+
+ /** The window has the maximum horizontal size. */
+ ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ,
+
+ /** The window is shaded. */
+ ECORE_X_WINDOW_STATE_SHADED,
+
+ /** The window should not be included in the taskbar. */
+ ECORE_X_WINDOW_STATE_SKIP_TASKBAR,
+
+ /** The window should not be included in the pager. */
+ ECORE_X_WINDOW_STATE_SKIP_PAGER,
+
+ /** The window is invisible (i.e. minimized/iconified) */
+ ECORE_X_WINDOW_STATE_HIDDEN,
+
+ /** The window should fill the entire screen and have no
+ * window border/decorations */
+ ECORE_X_WINDOW_STATE_FULLSCREEN,
+
+ /* The following are not documented because they are not
+ * intended for use in applications. */
+ ECORE_X_WINDOW_STATE_ABOVE,
+ ECORE_X_WINDOW_STATE_BELOW,
+
+ /* FIXME: Documentation */
+ ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION,
+
+ /* Unknown state */
+ ECORE_X_WINDOW_STATE_UNKNOWN
+
+} Ecore_X_Window_State;
+
+typedef enum _Ecore_X_Window_State_Action {
+ ECORE_X_WINDOW_STATE_ACTION_REMOVE,
+ ECORE_X_WINDOW_STATE_ACTION_ADD,
+ ECORE_X_WINDOW_STATE_ACTION_TOGGLE
+} Ecore_X_Window_State_Action;
+
+typedef enum _Ecore_X_Window_Stack_Mode {
+ ECORE_X_WINDOW_STACK_ABOVE = 0,
+ ECORE_X_WINDOW_STACK_BELOW = 1,
+ ECORE_X_WINDOW_STACK_TOP_IF = 2,
+ ECORE_X_WINDOW_STACK_BOTTOM_IF = 3,
+ ECORE_X_WINDOW_STACK_OPPOSITE = 4
+} Ecore_X_Window_Stack_Mode;
+
+#define ECORE_X_SELECTION_TARGET_TARGETS "TARGETS"
+#define ECORE_X_SELECTION_TARGET_TEXT "TEXT"
+#define ECORE_X_SELECTION_TARGET_COMPOUND_TEXT "COMPOUND_TEXT"
+#define ECORE_X_SELECTION_TARGET_STRING "STRING"
+#define ECORE_X_SELECTION_TARGET_UTF8_STRING "UTF8_STRING"
+#define ECORE_X_SELECTION_TARGET_FILENAME "FILENAME"
+
+#define ECORE_X_DND_VERSION 5
+
+extern EAPI Ecore_X_Atom ECORE_X_DND_ACTION_COPY;
+extern EAPI Ecore_X_Atom ECORE_X_DND_ACTION_MOVE;
+extern EAPI Ecore_X_Atom ECORE_X_DND_ACTION_LINK;
+extern EAPI Ecore_X_Atom ECORE_X_DND_ACTION_ASK;
+extern EAPI Ecore_X_Atom ECORE_X_DND_ACTION_PRIVATE;
+
+typedef enum _Ecore_X_Selection {
+ ECORE_X_SELECTION_PRIMARY,
+ ECORE_X_SELECTION_SECONDARY,
+ ECORE_X_SELECTION_XDND,
+ ECORE_X_SELECTION_CLIPBOARD
+} Ecore_X_Selection;
+
+typedef enum _Ecore_X_Event_Mode
+{
+ ECORE_X_EVENT_MODE_NORMAL,
+ ECORE_X_EVENT_MODE_WHILE_GRABBED,
+ ECORE_X_EVENT_MODE_GRAB,
+ ECORE_X_EVENT_MODE_UNGRAB
+} Ecore_X_Event_Mode;
+
+typedef enum _Ecore_X_Event_Detail
+{
+ ECORE_X_EVENT_DETAIL_ANCESTOR,
+ ECORE_X_EVENT_DETAIL_VIRTUAL,
+ ECORE_X_EVENT_DETAIL_INFERIOR,
+ ECORE_X_EVENT_DETAIL_NON_LINEAR,
+ ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL,
+ ECORE_X_EVENT_DETAIL_POINTER,
+ ECORE_X_EVENT_DETAIL_POINTER_ROOT,
+ ECORE_X_EVENT_DETAIL_DETAIL_NONE
+} Ecore_X_Event_Detail;
+
+typedef enum _Ecore_X_Event_Mask
+{
+ ECORE_X_EVENT_MASK_NONE = 0L,
+ ECORE_X_EVENT_MASK_KEY_DOWN = (1L << 0),
+ ECORE_X_EVENT_MASK_KEY_UP = (1L << 1),
+ ECORE_X_EVENT_MASK_MOUSE_DOWN = (1L << 2),
+ ECORE_X_EVENT_MASK_MOUSE_UP = (1L << 3),
+ ECORE_X_EVENT_MASK_MOUSE_IN = (1L << 4),
+ ECORE_X_EVENT_MASK_MOUSE_OUT = (1L << 5),
+ ECORE_X_EVENT_MASK_MOUSE_MOVE = (1L << 6),
+ ECORE_X_EVENT_MASK_WINDOW_DAMAGE = (1L << 15),
+ ECORE_X_EVENT_MASK_WINDOW_VISIBILITY = (1L << 16),
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE = (1L << 17),
+ ECORE_X_EVENT_MASK_WINDOW_RESIZE_MANAGE = (1L << 18),
+ ECORE_X_EVENT_MASK_WINDOW_MANAGE = (1L << 19),
+ ECORE_X_EVENT_MASK_WINDOW_CHILD_CONFIGURE = (1L << 20),
+ ECORE_X_EVENT_MASK_WINDOW_FOCUS_CHANGE = (1L << 21),
+ ECORE_X_EVENT_MASK_WINDOW_PROPERTY = (1L << 22),
+ ECORE_X_EVENT_MASK_WINDOW_COLORMAP = (1L << 23),
+ ECORE_X_EVENT_MASK_WINDOW_GRAB = (1L << 24),
+ ECORE_X_EVENT_MASK_MOUSE_WHEEL = (1L << 29),
+ ECORE_X_EVENT_MASK_WINDOW_FOCUS_IN = (1L << 30),
+ ECORE_X_EVENT_MASK_WINDOW_FOCUS_OUT = (1L << 31)
+} Ecore_X_Event_Mask;
+
+typedef enum _Ecore_X_Gravity {
+ ECORE_X_GRAVITY_FORGET = 0,
+ ECORE_X_GRAVITY_UNMAP = 0,
+ ECORE_X_GRAVITY_NW = 1,
+ ECORE_X_GRAVITY_N = 2,
+ ECORE_X_GRAVITY_NE = 3,
+ ECORE_X_GRAVITY_W = 4,
+ ECORE_X_GRAVITY_CENTER = 5,
+ ECORE_X_GRAVITY_E = 6,
+ ECORE_X_GRAVITY_SW = 7,
+ ECORE_X_GRAVITY_S = 8,
+ ECORE_X_GRAVITY_SE = 9,
+ ECORE_X_GRAVITY_STATIC = 10
+} Ecore_X_Gravity;
+
+typedef struct _Ecore_X_Event_Key_Down Ecore_X_Event_Key_Down;
+typedef struct _Ecore_X_Event_Key_Up Ecore_X_Event_Key_Up;
+typedef struct _Ecore_X_Event_Mouse_Button_Down Ecore_X_Event_Mouse_Button_Down;
+typedef struct _Ecore_X_Event_Mouse_Button_Up Ecore_X_Event_Mouse_Button_Up;
+typedef struct _Ecore_X_Event_Mouse_Move Ecore_X_Event_Mouse_Move;
+typedef struct _Ecore_X_Event_Mouse_In Ecore_X_Event_Mouse_In;
+typedef struct _Ecore_X_Event_Mouse_Out Ecore_X_Event_Mouse_Out;
+typedef struct _Ecore_X_Event_Mouse_Wheel Ecore_X_Event_Mouse_Wheel;
+typedef struct _Ecore_X_Event_Window_Focus_In Ecore_X_Event_Window_Focus_In;
+typedef struct _Ecore_X_Event_Window_Focus_Out Ecore_X_Event_Window_Focus_Out;
+typedef struct _Ecore_X_Event_Window_Keymap Ecore_X_Event_Window_Keymap;
+typedef struct _Ecore_X_Event_Window_Damage Ecore_X_Event_Window_Damage;
+typedef struct _Ecore_X_Event_Window_Visibility_Change Ecore_X_Event_Window_Visibility_Change;
+typedef struct _Ecore_X_Event_Window_Create Ecore_X_Event_Window_Create;
+typedef struct _Ecore_X_Event_Window_Destroy Ecore_X_Event_Window_Destroy;
+typedef struct _Ecore_X_Event_Window_Hide Ecore_X_Event_Window_Hide;
+typedef struct _Ecore_X_Event_Window_Show Ecore_X_Event_Window_Show;
+typedef struct _Ecore_X_Event_Window_Show_Request Ecore_X_Event_Window_Show_Request;
+typedef struct _Ecore_X_Event_Window_Reparent Ecore_X_Event_Window_Reparent;
+typedef struct _Ecore_X_Event_Window_Configure Ecore_X_Event_Window_Configure;
+typedef struct _Ecore_X_Event_Window_Configure_Request Ecore_X_Event_Window_Configure_Request;
+typedef struct _Ecore_X_Event_Window_Gravity Ecore_X_Event_Window_Gravity;
+typedef struct _Ecore_X_Event_Window_Resize_Request Ecore_X_Event_Window_Resize_Request;
+typedef struct _Ecore_X_Event_Window_Stack Ecore_X_Event_Window_Stack;
+typedef struct _Ecore_X_Event_Window_Stack_Request Ecore_X_Event_Window_Stack_Request;
+typedef struct _Ecore_X_Event_Window_Property Ecore_X_Event_Window_Property;
+typedef struct _Ecore_X_Event_Window_Colormap Ecore_X_Event_Window_Colormap;
+typedef struct _Ecore_X_Event_Window_Mapping Ecore_X_Event_Window_Mapping;
+typedef struct _Ecore_X_Event_Selection_Clear Ecore_X_Event_Selection_Clear;
+typedef struct _Ecore_X_Event_Selection_Request Ecore_X_Event_Selection_Request;
+typedef struct _Ecore_X_Event_Selection_Notify Ecore_X_Event_Selection_Notify;
+typedef struct _Ecore_X_Selection_Data Ecore_X_Selection_Data;
+typedef struct _Ecore_X_Selection_Data_Files Ecore_X_Selection_Data_Files;
+typedef struct _Ecore_X_Selection_Data_Text Ecore_X_Selection_Data_Text;
+typedef struct _Ecore_X_Selection_Data_Targets Ecore_X_Selection_Data_Targets;
+typedef struct _Ecore_X_Event_Xdnd_Enter Ecore_X_Event_Xdnd_Enter;
+typedef struct _Ecore_X_Event_Xdnd_Position Ecore_X_Event_Xdnd_Position;
+typedef struct _Ecore_X_Event_Xdnd_Status Ecore_X_Event_Xdnd_Status;
+typedef struct _Ecore_X_Event_Xdnd_Leave Ecore_X_Event_Xdnd_Leave;
+typedef struct _Ecore_X_Event_Xdnd_Drop Ecore_X_Event_Xdnd_Drop;
+typedef struct _Ecore_X_Event_Xdnd_Finished Ecore_X_Event_Xdnd_Finished;
+typedef struct _Ecore_X_Event_Client_Message Ecore_X_Event_Client_Message;
+typedef struct _Ecore_X_Event_Window_Shape Ecore_X_Event_Window_Shape;
+typedef struct _Ecore_X_Event_Sync_Counter Ecore_X_Event_Sync_Counter;
+typedef struct _Ecore_X_Event_Sync_Alarm Ecore_X_Event_Sync_Alarm;
+
+typedef struct _Ecore_X_Event_Window_Delete_Request Ecore_X_Event_Window_Delete_Request;
+typedef struct _Ecore_X_Event_Window_Prop_Title_Change Ecore_X_Event_Window_Prop_Title_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Visible_Title_Change Ecore_X_Event_Window_Prop_Visible_Title_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Icon_Name_Change Ecore_X_Event_Window_Prop_Icon_Name_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Client_Machine_Change Ecore_X_Event_Window_Prop_Client_Machine_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Name_Class_Change Ecore_X_Event_Window_Prop_Name_Class_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Pid_Change Ecore_X_Event_Window_Prop_Pid_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Desktop_Change Ecore_X_Event_Window_Prop_Desktop_Change;
+
+typedef struct _Ecore_X_Event_Window_Move_Resize_Request Ecore_X_Event_Window_Move_Resize_Request;
+typedef struct _Ecore_X_Event_Window_State_Request Ecore_X_Event_Window_State_Request;
+typedef struct _Ecore_X_Event_Frame_Extents_Request Ecore_X_Event_Frame_Extents_Request;
+typedef struct _Ecore_X_Event_Ping Ecore_X_Event_Ping;
+typedef struct _Ecore_X_Event_Desktop_Change Ecore_X_Event_Desktop_Change;
+
+struct _Ecore_X_Event_Key_Down
+{
+ char *keyname;
+ char *keysymbol;
+ char *key_compose;
+ int modifiers;
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Key_Up
+{
+ char *keyname;
+ char *keysymbol;
+ char *key_compose;
+ int modifiers;
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Mouse_Button_Down
+{
+ int button;
+ int modifiers;
+ int x, y;
+ struct {
+ int x, y;
+ } root;
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+ int double_click : 1;
+ int triple_click : 1;
+};
+
+struct _Ecore_X_Event_Mouse_Button_Up
+{
+ int button;
+ int modifiers;
+ int x, y;
+ struct {
+ int x, y;
+ } root;
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Mouse_Move
+{
+ int modifiers;
+ int x, y;
+ struct {
+ int x, y;
+ } root;
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Mouse_In
+{
+ int modifiers;
+ int x, y;
+ struct {
+ int x, y;
+ } root;
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Event_Mode mode;
+ Ecore_X_Event_Detail detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Mouse_Out
+{
+ int modifiers;
+ int x, y;
+ struct {
+ int x, y;
+ } root;
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Event_Mode mode;
+ Ecore_X_Event_Detail detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Mouse_Wheel
+{
+ int direction; /* 0 = default up/down wheel FIXME: more wheel types */
+ int z; /* ...,-2,-1 = down, 1,2,... = up */
+ int modifiers;
+ int x, y;
+
+ struct {
+ int x, y;
+ } root;
+
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Focus_In
+{
+ Ecore_X_Window win;
+ Ecore_X_Event_Mode mode;
+ Ecore_X_Event_Detail detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Focus_Out
+{
+ Ecore_X_Window win;
+ Ecore_X_Event_Mode mode;
+ Ecore_X_Event_Detail detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Keymap
+{
+ Ecore_X_Window win;
+};
+
+struct _Ecore_X_Event_Window_Damage
+{
+ Ecore_X_Window win;
+ int x, y, w, h;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Visibility_Change
+{
+ Ecore_X_Window win;
+ int fully_obscured;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Create
+{
+ Ecore_X_Window win;
+ int override;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Destroy
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Hide
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Show
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Show_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Window parent;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Reparent
+{
+ Ecore_X_Window win;
+ Ecore_X_Window parent;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Configure
+{
+ Ecore_X_Window win;
+ Ecore_X_Window abovewin;
+ int x, y, w, h;
+ int border;
+ int override : 1;
+ int from_wm : 1;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Configure_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Window abovewin;
+ int x, y, w, h;
+ int border;
+ Ecore_X_Window_Stack_Mode detail;
+ unsigned long value_mask;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Gravity
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Resize_Request
+{
+ Ecore_X_Window win;
+ int w, h;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Stack
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Stack_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Property
+{
+ Ecore_X_Window win;
+ Ecore_X_Atom atom;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Colormap
+{
+ Ecore_X_Window win;
+ Ecore_X_Colormap cmap;
+ int installed;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Selection_Clear
+{
+ Ecore_X_Window win;
+ Ecore_X_Selection selection;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Selection_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Selection_Notify
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+ Ecore_X_Selection selection;
+ char *target;
+ void *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;
+};
+
+struct _Ecore_X_Selection_Data
+{
+ unsigned char *data;
+ int length;
+
+ int (*free)(void *data);
+};
+
+struct _Ecore_X_Selection_Data_Files
+{
+ Ecore_X_Selection_Data data;
+ char **files;
+ int num_files;
+};
+
+struct _Ecore_X_Selection_Data_Text
+{
+ Ecore_X_Selection_Data data;
+ char *text;
+};
+
+struct _Ecore_X_Selection_Data_Targets
+{
+ Ecore_X_Selection_Data data;
+ char **targets;
+ int num_targets;
+};
+
+struct _Ecore_X_Event_Xdnd_Enter
+{
+ Ecore_X_Window win, source;
+
+ char **types;
+ int num_types;
+};
+
+struct _Ecore_X_Event_Xdnd_Position
+{
+ Ecore_X_Window win, source;
+ struct {
+ int x, y;
+ } position;
+ Ecore_X_Atom action;
+};
+
+struct _Ecore_X_Event_Xdnd_Status
+{
+ Ecore_X_Window win, target;
+ int will_accept;
+ Ecore_X_Rectangle rectangle;
+ Ecore_X_Atom action;
+};
+
+struct _Ecore_X_Event_Xdnd_Leave
+{
+ Ecore_X_Window win, source;
+};
+
+struct _Ecore_X_Event_Xdnd_Drop
+{
+ Ecore_X_Window win, source;
+ Ecore_X_Atom action;
+ struct {
+ int x, y;
+ } position;
+};
+
+struct _Ecore_X_Event_Xdnd_Finished
+{
+ Ecore_X_Window win, target;
+ int completed;
+ Ecore_X_Atom action;
+};
+
+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;
+};
+
+struct _Ecore_X_Event_Window_Shape
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Sync_Counter
+{
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Sync_Alarm
+{
+ Ecore_X_Time time;
+ Ecore_X_Sync_Alarm alarm;
+};
+
+struct _Ecore_X_Event_Window_Delete_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Title_Change
+{
+ Ecore_X_Window win;
+ char *title;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Visible_Title_Change
+{
+ Ecore_X_Window win;
+ char *title;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Icon_Name_Change
+{
+ Ecore_X_Window win;
+ char *name;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change
+{
+ Ecore_X_Window win;
+ char *name;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Client_Machine_Change
+{
+ Ecore_X_Window win;
+ char *name;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Name_Class_Change
+{
+ Ecore_X_Window win;
+ char *name;
+ char *clas;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Pid_Change
+{
+ Ecore_X_Window win;
+ pid_t pid;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Desktop_Change
+{
+ Ecore_X_Window win;
+ long desktop;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Move_Resize_Request
+{
+ Ecore_X_Window win;
+ int x, y;
+ int direction;
+ int button;
+ int source;
+};
+
+struct _Ecore_X_Event_Window_State_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Window_State_Action action;
+ Ecore_X_Window_State state[2];
+ int source;
+};
+
+struct _Ecore_X_Event_Frame_Extents_Request
+{
+ Ecore_X_Window win;
+};
+
+struct _Ecore_X_Event_Ping
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Desktop_Change
+{
+ Ecore_X_Window win;
+ unsigned int desk;
+ int source;
+};
+
+extern EAPI int ECORE_X_EVENT_KEY_DOWN;
+extern EAPI int ECORE_X_EVENT_KEY_UP;
+extern EAPI int ECORE_X_EVENT_MOUSE_BUTTON_DOWN;
+extern EAPI int ECORE_X_EVENT_MOUSE_BUTTON_UP;
+extern EAPI int ECORE_X_EVENT_MOUSE_MOVE;
+extern EAPI int ECORE_X_EVENT_MOUSE_IN;
+extern EAPI int ECORE_X_EVENT_MOUSE_OUT;
+extern EAPI int ECORE_X_EVENT_MOUSE_WHEEL;
+extern EAPI int ECORE_X_EVENT_WINDOW_FOCUS_IN;
+extern EAPI int ECORE_X_EVENT_WINDOW_FOCUS_OUT;
+extern EAPI int ECORE_X_EVENT_WINDOW_KEYMAP;
+extern EAPI int ECORE_X_EVENT_WINDOW_DAMAGE;
+extern EAPI int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE;
+extern EAPI int ECORE_X_EVENT_WINDOW_CREATE;
+extern EAPI int ECORE_X_EVENT_WINDOW_DESTROY;
+extern EAPI int ECORE_X_EVENT_WINDOW_HIDE;
+extern EAPI int ECORE_X_EVENT_WINDOW_SHOW;
+extern EAPI int ECORE_X_EVENT_WINDOW_SHOW_REQUEST;
+extern EAPI int ECORE_X_EVENT_WINDOW_REPARENT;
+extern EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE;
+extern EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST;
+extern EAPI int ECORE_X_EVENT_WINDOW_GRAVITY;
+extern EAPI int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST;
+extern EAPI int ECORE_X_EVENT_WINDOW_STACK;
+extern EAPI int ECORE_X_EVENT_WINDOW_STACK_REQUEST;
+extern EAPI int ECORE_X_EVENT_WINDOW_PROPERTY;
+extern EAPI int ECORE_X_EVENT_WINDOW_COLORMAP;
+extern EAPI int ECORE_X_EVENT_WINDOW_MAPPING;
+extern EAPI int ECORE_X_EVENT_SELECTION_CLEAR;
+extern EAPI int ECORE_X_EVENT_SELECTION_REQUEST;
+extern EAPI int ECORE_X_EVENT_SELECTION_NOTIFY;
+extern EAPI int ECORE_X_EVENT_CLIENT_MESSAGE;
+extern EAPI int ECORE_X_EVENT_WINDOW_SHAPE;
+extern EAPI int ECORE_X_EVENT_SYNC_COUNTER;
+extern EAPI int ECORE_X_EVENT_SYNC_ALARM;
+
+extern EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST;
+/*
+extern EAPI int ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE;
+extern EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE;
+extern EAPI int ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE;
+extern EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE;
+extern EAPI int ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE;
+extern EAPI int ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE;
+extern EAPI int ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE;
+extern EAPI int ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE;
+*/
+
+extern EAPI int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST;
+extern EAPI int ECORE_X_EVENT_WINDOW_STATE_REQUEST;
+extern EAPI int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST;
+extern EAPI int ECORE_X_EVENT_PING;
+extern EAPI int ECORE_X_EVENT_DESKTOP_CHANGE;
+
+extern EAPI int ECORE_X_EVENT_XDND_ENTER;
+extern EAPI int ECORE_X_EVENT_XDND_POSITION;
+extern EAPI int ECORE_X_EVENT_XDND_STATUS;
+extern EAPI int ECORE_X_EVENT_XDND_LEAVE;
+extern EAPI int ECORE_X_EVENT_XDND_DROP;
+extern EAPI int ECORE_X_EVENT_XDND_FINISHED;
+
+extern EAPI int ECORE_X_MODIFIER_SHIFT;
+extern EAPI int ECORE_X_MODIFIER_CTRL;
+extern EAPI int ECORE_X_MODIFIER_ALT;
+extern EAPI int ECORE_X_MODIFIER_WIN;
+
+extern EAPI int ECORE_X_LOCK_SCROLL;
+extern EAPI int ECORE_X_LOCK_NUM;
+extern EAPI int ECORE_X_LOCK_CAPS;
+
+typedef enum _Ecore_X_WM_Protocol {
+ /**
+ * If enabled the window manager will be asked to send a
+ * delete message instead of just closing (destroying) the window.
+ */
+ ECORE_X_WM_PROTOCOL_DELETE_REQUEST,
+
+ /**
+ * If enabled the window manager will be told that the window
+ * explicitly sets input focus.
+ */
+ ECORE_X_WM_PROTOCOL_TAKE_FOCUS,
+
+ /**
+ * If enabled the window manager can ping the window to check
+ * if it is alive.
+ */
+ ECORE_X_NET_WM_PROTOCOL_PING,
+
+ /**
+ * If enabled the window manager can sync updating with the
+ * window (?)
+ */
+ ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST,
+
+ /* Number of defined items */
+ ECORE_X_WM_PROTOCOL_NUM
+} Ecore_X_WM_Protocol;
+
+typedef enum _Ecore_X_Window_Input_Mode {
+ /** The window can never be focused */
+ ECORE_X_WINDOW_INPUT_MODE_NONE,
+
+ /** The window can be focused by the WM but doesn't focus itself */
+ ECORE_X_WINDOW_INPUT_MODE_PASSIVE,
+
+ /** The window sets the focus itself if one of its sub-windows
+ * already is focused
+ */
+ ECORE_X_WINDOW_INPUT_MODE_ACTIVE_LOCAL,
+
+ /** The window sets the focus itself even if another window
+ * is currently focused
+ */
+ ECORE_X_WINDOW_INPUT_MODE_ACTIVE_GLOBAL
+} Ecore_X_Window_Input_Mode;
+
+typedef enum _Ecore_X_Window_State_Hint {
+ /** Do not provide any state hint to the window manager */
+ ECORE_X_WINDOW_STATE_HINT_NONE = -1,
+
+ /** The window wants to remain hidden and NOT iconified */
+ ECORE_X_WINDOW_STATE_HINT_WITHDRAWN,
+
+ /** The window wants to be mapped normally */
+ ECORE_X_WINDOW_STATE_HINT_NORMAL,
+
+ /** The window wants to start in an iconified state */
+ ECORE_X_WINDOW_STATE_HINT_ICONIC,
+} Ecore_X_Window_State_Hint;
+
+typedef enum _Ecore_X_Window_Type {
+ ECORE_X_WINDOW_TYPE_DESKTOP,
+ ECORE_X_WINDOW_TYPE_DOCK,
+ ECORE_X_WINDOW_TYPE_TOOLBAR,
+ ECORE_X_WINDOW_TYPE_MENU,
+ ECORE_X_WINDOW_TYPE_UTILITY,
+ ECORE_X_WINDOW_TYPE_SPLASH,
+ ECORE_X_WINDOW_TYPE_DIALOG,
+ ECORE_X_WINDOW_TYPE_NORMAL,
+ ECORE_X_WINDOW_TYPE_UNKNOWN
+} Ecore_X_Window_Type;
+
+typedef enum _Ecore_X_Action {
+ ECORE_X_ACTION_MOVE,
+ ECORE_X_ACTION_RESIZE,
+ ECORE_X_ACTION_MINIMIZE,
+ ECORE_X_ACTION_SHADE,
+ ECORE_X_ACTION_STICK,
+ ECORE_X_ACTION_MAXIMIZE_HORZ,
+ ECORE_X_ACTION_MAXIMIZE_VERT,
+ ECORE_X_ACTION_FULLSCREEN,
+ ECORE_X_ACTION_CHANGE_DESKTOP,
+ ECORE_X_ACTION_CLOSE
+} Ecore_X_Action;
+
+typedef enum _Ecore_X_Window_Configure_Mask {
+ ECORE_X_WINDOW_CONFIGURE_MASK_X = (1 << 0),
+ ECORE_X_WINDOW_CONFIGURE_MASK_Y = (1 << 1),
+ ECORE_X_WINDOW_CONFIGURE_MASK_W = (1 << 2),
+ ECORE_X_WINDOW_CONFIGURE_MASK_H = (1 << 3),
+ ECORE_X_WINDOW_CONFIGURE_MASK_BORDER_WIDTH = (1 << 4),
+ ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING = (1 << 5),
+ ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE = (1 << 6)
+} Ecore_X_Window_Configure_Mask;
+
+/* Window layer constants */
+#define ECORE_X_WINDOW_LAYER_BELOW 2
+#define ECORE_X_WINDOW_LAYER_NORMAL 4
+#define ECORE_X_WINDOW_LAYER_ABOVE 6
+
+EAPI int ecore_x_init(const char *name);
+EAPI int ecore_x_shutdown(void);
+EAPI int ecore_x_disconnect(void);
+EAPI Ecore_X_Display *ecore_x_display_get(void);
+EAPI int ecore_x_fd_get(void);
+EAPI void ecore_x_double_click_time_set(double t);
+EAPI double ecore_x_double_click_time_get(void);
+EAPI void ecore_x_flush(void);
+EAPI void ecore_x_sync(void);
+EAPI void ecore_x_killall(Ecore_X_Window root);
+EAPI void ecore_x_kill(Ecore_X_Window win);
+
+EAPI Ecore_X_Time ecore_x_current_time_get(void);
+
+EAPI void ecore_x_error_handler_set(void (*func) (void *data), const void *data);
+EAPI void ecore_x_io_error_handler_set(void (*func) (void *data), const void *data);
+EAPI int ecore_x_error_request_get(void);
+EAPI int ecore_x_error_code_get(void);
+
+EAPI void ecore_x_event_mask_set(Ecore_X_Window w, Ecore_X_Event_Mask mask);
+EAPI void ecore_x_event_mask_unset(Ecore_X_Window w, Ecore_X_Event_Mask mask);
+
+EAPI int ecore_x_selection_primary_set(Ecore_X_Window w, unsigned char *data, int size);
+EAPI int ecore_x_selection_primary_clear(void);
+EAPI int ecore_x_selection_secondary_set(Ecore_X_Window w, unsigned char *data, int size);
+EAPI int ecore_x_selection_secondary_clear(void);
+EAPI int ecore_x_selection_xdnd_set(Ecore_X_Window w, unsigned char *data, int size);
+EAPI int ecore_x_selection_xdnd_clear(void);
+EAPI int ecore_x_selection_clipboard_set(Ecore_X_Window w, unsigned char *data, int size);
+EAPI int ecore_x_selection_clipboard_clear(void);
+EAPI void ecore_x_selection_primary_request(Ecore_X_Window w, char *target);
+EAPI void ecore_x_selection_primary_request_data_get(void **buf, int *len);
+EAPI void ecore_x_selection_secondary_request(Ecore_X_Window w, char *target);
+EAPI void ecore_x_selection_secondary_request_data_get(void **buf, int *len);
+EAPI void ecore_x_selection_xdnd_request(Ecore_X_Window w, char *target);
+EAPI void ecore_x_selection_xdnd_request_data_get(void **buf, int *len);
+EAPI void ecore_x_selection_clipboard_request(Ecore_X_Window w, char *target);
+EAPI void ecore_x_selection_clipboard_request_data_get(void **buf, int *len);
+EAPI void ecore_x_selection_converter_add(char *target, int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret));
+EAPI void ecore_x_selection_converter_atom_add(Ecore_X_Atom target, int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret));
+EAPI void ecore_x_selection_converter_del(char *target);
+EAPI void ecore_x_selection_converter_atom_del(Ecore_X_Atom target);
+EAPI void ecore_x_selection_parser_add(const char *target, void *(*func)(const char *target, unsigned char *data, int size));
+EAPI void ecore_x_selection_parser_del(const char *target);
+
+EAPI void ecore_x_dnd_aware_set(Ecore_X_Window win, int on);
+EAPI int ecore_x_dnd_version_get(Ecore_X_Window win);
+EAPI int ecore_x_dnd_type_isset(Ecore_X_Window win, const char *type);
+EAPI void ecore_x_dnd_type_set(Ecore_X_Window win, const char *type, int on);
+EAPI int ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size);
+EAPI void ecore_x_dnd_drop(void);
+EAPI void ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectangle, Ecore_X_Atom action);
+EAPI void ecore_x_dnd_send_finished(void);
+
+EAPI Ecore_X_Window ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_x_window_override_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_x_window_input_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI void ecore_x_window_configure(Ecore_X_Window win,
+ Ecore_X_Window_Configure_Mask mask,
+ int x, int y, int w, int h,
+ int border_width,
+ Ecore_X_Window sibling,
+ int stack_mode);
+EAPI void ecore_x_window_cursor_set(Ecore_X_Window win,
+ Ecore_X_Cursor c);
+EAPI void ecore_x_window_del(Ecore_X_Window win);
+EAPI void ecore_x_window_delete_request_send(Ecore_X_Window win);
+EAPI void ecore_x_window_show(Ecore_X_Window win);
+EAPI void ecore_x_window_hide(Ecore_X_Window win);
+EAPI void ecore_x_window_move(Ecore_X_Window win, int x, int y);
+EAPI void ecore_x_window_resize(Ecore_X_Window win, int w, int h);
+EAPI void ecore_x_window_move_resize(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_focus(Ecore_X_Window win);
+EAPI void ecore_x_window_focus_at_time(Ecore_X_Window win, Ecore_X_Time t);
+EAPI Ecore_X_Window ecore_x_window_focus_get(void);
+EAPI void ecore_x_window_raise(Ecore_X_Window win);
+EAPI void ecore_x_window_lower(Ecore_X_Window win);
+EAPI void ecore_x_window_reparent(Ecore_X_Window win, Ecore_X_Window new_parent, int x, int y);
+EAPI void ecore_x_window_size_get(Ecore_X_Window win, int *w, int *h);
+EAPI void ecore_x_window_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h);
+EAPI int ecore_x_window_border_width_get(Ecore_X_Window win);
+EAPI void ecore_x_window_border_width_set(Ecore_X_Window win, int width);
+EAPI int ecore_x_window_depth_get(Ecore_X_Window win);
+EAPI void ecore_x_window_cursor_show(Ecore_X_Window win, int show);
+EAPI void ecore_x_window_defaults_set(Ecore_X_Window win);
+EAPI int ecore_x_window_visible_get(Ecore_X_Window win);
+EAPI Ecore_X_Window ecore_x_window_at_xy_get(int x, int y);
+EAPI Ecore_X_Window ecore_x_window_parent_get(Ecore_X_Window win);
+
+EAPI void ecore_x_window_background_color_set(Ecore_X_Window win,
+ unsigned short r,
+ unsigned short g,
+ unsigned short b);
+EAPI void ecore_x_window_gravity_set(Ecore_X_Window win,
+ Ecore_X_Gravity grav);
+EAPI void ecore_x_window_pixel_gravity_set(Ecore_X_Window win,
+ Ecore_X_Gravity grav);
+EAPI void ecore_x_window_pixmap_set(Ecore_X_Window win,
+ Ecore_X_Pixmap pmap);
+EAPI void ecore_x_window_area_clear(Ecore_X_Window win,
+ int x, int y, int w, int h);
+EAPI void ecore_x_window_area_expose(Ecore_X_Window win,
+ int x, int y, int w, int h);
+
+EAPI void ecore_x_window_prop_card32_set(Ecore_X_Window win, Ecore_X_Atom atom,
+ unsigned int *val, unsigned int num);
+EAPI int ecore_x_window_prop_card32_get(Ecore_X_Window win, Ecore_X_Atom atom,
+ unsigned int *val, unsigned int len);
+EAPI Ecore_X_Atom ecore_x_window_prop_any_type(void);
+EAPI void ecore_x_window_prop_property_set(Ecore_X_Window win, Ecore_X_Atom type, Ecore_X_Atom format, int size, void *data, int number);
+EAPI int ecore_x_window_prop_property_get(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size, unsigned char **data, int *num);
+EAPI void ecore_x_window_prop_property_del(Ecore_X_Window win, Ecore_X_Atom property);
+EAPI Ecore_X_Atom *ecore_x_window_prop_list(Ecore_X_Window win, int *num_ret);
+EAPI void ecore_x_window_prop_string_set(Ecore_X_Window win, Ecore_X_Atom type, const char *str);
+EAPI char *ecore_x_window_prop_string_get(Ecore_X_Window win, Ecore_X_Atom type);
+EAPI int ecore_x_window_prop_protocol_isset(Ecore_X_Window win, Ecore_X_WM_Protocol protocol);
+EAPI Ecore_X_WM_Protocol *ecore_x_window_prop_protocol_list_get(Ecore_X_Window win, int *num_ret);
+
+EAPI void ecore_x_window_shape_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask);
+EAPI void ecore_x_window_shape_window_set(Ecore_X_Window win, Ecore_X_Window shape_win);
+EAPI void ecore_x_window_shape_window_set_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y);
+EAPI void ecore_x_window_shape_rectangle_set(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_rectangles_set(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num);
+EAPI void ecore_x_window_shape_window_add(Ecore_X_Window win, Ecore_X_Window shape_win);
+EAPI void ecore_x_window_shape_window_add_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y);
+EAPI void ecore_x_window_shape_rectangle_add(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_rectangle_clip(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_rectangles_add(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num);
+EAPI Ecore_X_Rectangle *ecore_x_window_shape_rectangles_get(Ecore_X_Window win, int *num_ret);
+EAPI void ecore_x_window_shape_events_select(Ecore_X_Window win, int on);
+
+EAPI Ecore_X_Pixmap ecore_x_pixmap_new(Ecore_X_Window win, int w, int h, int dep);
+EAPI void ecore_x_pixmap_del(Ecore_X_Pixmap pmap);
+EAPI void ecore_x_pixmap_paste(Ecore_X_Pixmap pmap, Ecore_X_Drawable dest, Ecore_X_GC gc, int sx, int sy, int w, int h, int dx, int dy);
+EAPI void ecore_x_pixmap_geometry_get(Ecore_X_Pixmap pmap, int *x, int *y, int *w, int *h);
+EAPI int ecore_x_pixmap_depth_get(Ecore_X_Pixmap pmap);
+
+EAPI Ecore_X_GC ecore_x_gc_new(Ecore_X_Drawable draw);
+EAPI void ecore_x_gc_del(Ecore_X_GC gc);
+
+EAPI int ecore_x_client_message32_send(Ecore_X_Window win, Ecore_X_Atom type, Ecore_X_Event_Mask mask, long d0, long d1, long d2, long d3, long d4);
+EAPI int ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type, const void *data, int len);
+
+
+/* FIXME: these funcs need categorising */
+EAPI void ecore_x_drawable_geometry_get(Ecore_X_Drawable d, int *x, int *y, int *w, int *h);
+EAPI int ecore_x_drawable_border_width_get(Ecore_X_Drawable d);
+EAPI int ecore_x_drawable_depth_get(Ecore_X_Drawable d);
+EAPI Ecore_X_Window *ecore_x_window_root_list(int *num_ret);
+EAPI Ecore_X_Window ecore_x_window_root_first_get(void);
+EAPI int ecore_x_window_manage(Ecore_X_Window win);
+EAPI void ecore_x_window_container_manage(Ecore_X_Window win);
+EAPI void ecore_x_window_client_manage(Ecore_X_Window win);
+EAPI void ecore_x_window_sniff(Ecore_X_Window win);
+EAPI void ecore_x_window_client_sniff(Ecore_X_Window win);
+EAPI Ecore_X_Atom ecore_x_atom_get(const char *name);
+
+EAPI void ecore_x_icccm_init(void);
+EAPI void ecore_x_icccm_state_set(Ecore_X_Window win, Ecore_X_Window_State_Hint state);
+EAPI Ecore_X_Window_State_Hint ecore_x_icccm_state_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_delete_window_send(Ecore_X_Window win, Ecore_X_Time t);
+EAPI void ecore_x_icccm_take_focus_send(Ecore_X_Window win, Ecore_X_Time t);
+EAPI void ecore_x_icccm_save_yourself_send(Ecore_X_Window win, Ecore_X_Time t);
+EAPI void ecore_x_icccm_move_resize_send(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_icccm_hints_set(Ecore_X_Window win,
+ int 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,
+ int is_urgent);
+EAPI int ecore_x_icccm_hints_get(Ecore_X_Window win,
+ int *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,
+ int *is_urgent);
+EAPI void ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win,
+ int request_pos,
+ Ecore_X_Gravity gravity,
+ int min_w, int min_h,
+ int max_w, int max_h,
+ int base_w, int base_h,
+ int step_x, int step_y,
+ double min_aspect,
+ double max_aspect);
+EAPI int ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win,
+ int *request_pos,
+ Ecore_X_Gravity *gravity,
+ int *min_w, int *min_h,
+ int *max_w, int *max_h,
+ int *base_w, int *base_h,
+ int *step_x, int *step_y,
+ double *min_aspect,
+ double *max_aspect);
+EAPI void ecore_x_icccm_title_set(Ecore_X_Window win, const char *t);
+EAPI char *ecore_x_icccm_title_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_protocol_set(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol,
+ int on);
+EAPI int ecore_x_icccm_protocol_isset(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol);
+EAPI void ecore_x_icccm_name_class_set(Ecore_X_Window win,
+ const char *n,
+ const char *c);
+EAPI void ecore_x_icccm_name_class_get(Ecore_X_Window win,
+ char **n,
+ char **c);
+EAPI char *ecore_x_icccm_client_machine_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_command_set(Ecore_X_Window win, int argc, char **argv);
+EAPI void ecore_x_icccm_command_get(Ecore_X_Window win, int *argc, char ***argv);
+EAPI char *ecore_x_icccm_icon_name_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_icon_name_set(Ecore_X_Window win, const char *t);
+EAPI void ecore_x_icccm_colormap_window_set(Ecore_X_Window win, Ecore_X_Window subwin);
+EAPI void ecore_x_icccm_colormap_window_unset(Ecore_X_Window win, Ecore_X_Window subwin);
+EAPI void ecore_x_icccm_transient_for_set(Ecore_X_Window win, Ecore_X_Window forwin);
+EAPI void ecore_x_icccm_transient_for_unset(Ecore_X_Window win);
+EAPI Ecore_X_Window ecore_x_icccm_transient_for_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_window_role_set(Ecore_X_Window win, const char *role);
+EAPI char *ecore_x_icccm_window_role_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_client_leader_set(Ecore_X_Window win, Ecore_X_Window l);
+EAPI Ecore_X_Window ecore_x_icccm_client_leader_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_iconic_request_send(Ecore_X_Window win, Ecore_X_Window root);
+
+
+typedef enum _Ecore_X_MWM_Hint_Func
+{
+ ECORE_X_MWM_HINT_FUNC_ALL = (1 << 0),
+ ECORE_X_MWM_HINT_FUNC_RESIZE = (1 << 1),
+ ECORE_X_MWM_HINT_FUNC_MOVE = (1 << 2),
+ ECORE_X_MWM_HINT_FUNC_MINIMIZE = (1 << 3),
+ ECORE_X_MWM_HINT_FUNC_MAXIMIZE = (1 << 4),
+ ECORE_X_MWM_HINT_FUNC_CLOSE = (1 << 5)
+} Ecore_X_MWM_Hint_Func;
+
+typedef enum _Ecore_X_MWM_Hint_Decor
+{
+ ECORE_X_MWM_HINT_DECOR_ALL = (1 << 0),
+ ECORE_X_MWM_HINT_DECOR_BORDER = (1 << 1),
+ ECORE_X_MWM_HINT_DECOR_RESIZEH = (1 << 2),
+ ECORE_X_MWM_HINT_DECOR_TITLE = (1 << 3),
+ ECORE_X_MWM_HINT_DECOR_MENU = (1 << 4),
+ ECORE_X_MWM_HINT_DECOR_MINIMIZE = (1 << 5),
+ ECORE_X_MWM_HINT_DECOR_MAXIMIZE = (1 << 6)
+} Ecore_X_MWM_Hint_Decor;
+
+typedef enum _Ecore_X_MWM_Hint_Input
+{
+ ECORE_X_MWM_HINT_INPUT_MODELESS = 0,
+ ECORE_X_MWM_HINT_INPUT_PRIMARY_APPLICATION_MODAL = 1,
+ ECORE_X_MWM_HINT_INPUT_SYSTEM_MODAL = 2,
+ ECORE_X_MWM_HINT_INPUT_FULL_APPLICATION_MODAL = 3,
+} Ecore_X_MWM_Hint_Input;
+
+EAPI int ecore_x_mwm_hints_get(Ecore_X_Window win,
+ Ecore_X_MWM_Hint_Func *fhint,
+ Ecore_X_MWM_Hint_Decor *dhint,
+ Ecore_X_MWM_Hint_Input *ihint);
+EAPI void ecore_x_mwm_borderless_set(Ecore_X_Window win, int borderless);
+
+/* netwm */
+EAPI void ecore_x_netwm_init(void);
+EAPI void ecore_x_netwm_wm_identify(Ecore_X_Window root, Ecore_X_Window check, const char *wm_name);
+EAPI void ecore_x_netwm_supported_set(Ecore_X_Window root, Ecore_X_Atom *supported, int num);
+EAPI int ecore_x_netwm_supported_get(Ecore_X_Window root, Ecore_X_Atom **supported, int *num);
+EAPI void ecore_x_netwm_desk_count_set(Ecore_X_Window root, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_roots_set(Ecore_X_Window root, Ecore_X_Window *vroots, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_names_set(Ecore_X_Window root, const char **names, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_size_set(Ecore_X_Window root, unsigned int width, unsigned int height);
+EAPI void ecore_x_netwm_desk_workareas_set(Ecore_X_Window root, unsigned int *areas, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_current_set(Ecore_X_Window root, unsigned int desk);
+EAPI void ecore_x_netwm_desk_viewports_set(Ecore_X_Window root, unsigned int *origins, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_layout_set(Ecore_X_Window root, int orientation, int columns, int rows, int starting_corner);
+EAPI void ecore_x_netwm_showing_desktop_set(Ecore_X_Window root, int on);
+EAPI void ecore_x_netwm_client_list_set(Ecore_X_Window root, Ecore_X_Window *p_clients, unsigned int n_clients);
+EAPI void ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root, Ecore_X_Window *p_clients, unsigned int n_clients);
+EAPI void ecore_x_netwm_client_active_set(Ecore_X_Window root, Ecore_X_Window win);
+EAPI void ecore_x_netwm_name_set(Ecore_X_Window win, const char *name);
+EAPI int ecore_x_netwm_name_get(Ecore_X_Window win, char **name);
+EAPI void ecore_x_netwm_visible_name_set(Ecore_X_Window win, const char *name);
+EAPI int ecore_x_netwm_visible_name_get(Ecore_X_Window win, char **name);
+EAPI void ecore_x_netwm_icon_name_set(Ecore_X_Window win, const char *name);
+EAPI int ecore_x_netwm_icon_name_get(Ecore_X_Window win, char **name);
+EAPI void ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win, const char *name);
+EAPI int ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win, char **name);
+EAPI void ecore_x_netwm_desktop_set(Ecore_X_Window win, unsigned int desk);
+EAPI int ecore_x_netwm_desktop_get(Ecore_X_Window win, unsigned int *desk);
+EAPI void ecore_x_netwm_strut_set(Ecore_X_Window win, int left, int right, int top, int bottom);
+EAPI int ecore_x_netwm_strut_get(Ecore_X_Window win, int *left, int *right, int *top, int *bottom);
+EAPI void ecore_x_netwm_strut_partial_set(Ecore_X_Window win, int left, int right, int top, int bottom, int left_start_y, int left_end_y, int right_start_y, int right_end_y, int top_start_x, int top_end_x, int bottom_start_x, int bottom_end_x);
+EAPI int ecore_x_netwm_strut_partial_get(Ecore_X_Window win, int *left, int *right, int *top, int *bottom, int *left_start_y, int *left_end_y, int *right_start_y, int *right_end_y, int *top_start_x, int *top_end_x, int *bottom_start_x, int *bottom_end_x);
+EAPI int ecore_x_netwm_icon_get(Ecore_X_Window win, int *width, int *height, unsigned int **data, int *num);
+EAPI void ecore_x_netwm_icon_geometry_set(Ecore_X_Window win, int x, int y, int width, int height);
+EAPI int ecore_x_netwm_icon_geometry_get(Ecore_X_Window win, int *x, int *y, int *width, int *height);
+EAPI void ecore_x_netwm_pid_set(Ecore_X_Window win, int pid);
+EAPI int ecore_x_netwm_pid_get(Ecore_X_Window win, int *pid);
+EAPI void ecore_x_netwm_handled_icons_set(Ecore_X_Window win);
+EAPI int ecore_x_netwm_handled_icons_get(Ecore_X_Window win);
+EAPI void ecore_x_netwm_user_time_set(Ecore_X_Window win, unsigned int time);
+EAPI int ecore_x_netwm_user_time_get(Ecore_X_Window win, unsigned int *time);
+EAPI void ecore_x_netwm_window_state_set(Ecore_X_Window win, Ecore_X_Window_State *state, unsigned int num);
+EAPI int ecore_x_netwm_window_state_get(Ecore_X_Window win, Ecore_X_Window_State **state, unsigned int *num);
+EAPI void ecore_x_netwm_window_type_set(Ecore_X_Window win, Ecore_X_Window_Type type);
+EAPI int ecore_x_netwm_window_type_get(Ecore_X_Window win, Ecore_X_Window_Type *type);
+EAPI int ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, Ecore_X_Action action);
+EAPI void ecore_x_netwm_allowed_action_set(Ecore_X_Window win, Ecore_X_Action action, int on);
+EAPI void ecore_x_netwm_opacity_set(Ecore_X_Window win, unsigned int opacity);
+EAPI int ecore_x_netwm_opacity_get(Ecore_X_Window win, unsigned int *opacity);
+EAPI void ecore_x_netwm_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb);
+EAPI int ecore_x_netwm_frame_size_get(Ecore_X_Window win, int *fl, int *fr, int *ft, int *fb);
+EAPI int ecore_x_netwm_sync_counter_get(Ecore_X_Window win, Ecore_X_Sync_Counter *counter);
+EAPI void ecore_x_netwm_ping_send(Ecore_X_Window win);
+EAPI void ecore_x_netwm_sync_request_send(Ecore_X_Window win, unsigned int serial);
+EAPI void ecore_x_netwm_state_request_send(Ecore_X_Window win, Ecore_X_Window root, Ecore_X_Window_State s1, Ecore_X_Window_State s2, int set);
+EAPI void ecore_x_netwm_desktop_request_send(Ecore_X_Window win, Ecore_X_Window root, unsigned int desktop);
+
+
+
+
+EAPI void ecore_x_e_init(void);
+EAPI void ecore_x_e_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb);
+
+
+EAPI int ecore_x_xinerama_screen_count_get(void);
+EAPI int ecore_x_xinerama_screen_geometry_get(int screen, int *x, int *y, int *w, int *h);
+
+/* FIXME: these funcs need categorising */
+EAPI void ecore_x_drawable_geometry_get(Ecore_X_Drawable d, int *x, int *y, int *w, int *h);
+EAPI int ecore_x_drawable_border_width_get(Ecore_X_Drawable d);
+EAPI int ecore_x_drawable_depth_get(Ecore_X_Drawable d);
+EAPI Ecore_X_Window *ecore_x_window_root_list(int *num_ret);
+EAPI int ecore_x_window_manage(Ecore_X_Window win);
+EAPI void ecore_x_window_container_manage(Ecore_X_Window win);
+EAPI void ecore_x_window_client_manage(Ecore_X_Window win);
+EAPI void ecore_x_window_sniff(Ecore_X_Window win);
+EAPI void ecore_x_window_client_sniff(Ecore_X_Window win);
+EAPI Ecore_X_Atom ecore_x_atom_get(const char *name);
+
+typedef struct _Ecore_X_Window_Attributes
+{
+ Ecore_X_Window root;
+ int x, y, w, h;
+ int border;
+ int depth;
+ char visible : 1;
+ char viewable : 1;
+ char override : 1;
+ char input_only : 1;
+ char save_under : 1;
+ struct {
+ Ecore_X_Event_Mask mine;
+ Ecore_X_Event_Mask all;
+ Ecore_X_Event_Mask no_propagate;
+ } event_mask;
+ Ecore_X_Gravity window_gravity;
+ Ecore_X_Gravity pixel_gravity;
+ Ecore_X_Colormap colormap;
+ /* FIXME: missing
+ * Colormap comormap;
+ * int map_installed;
+ * Screen *screen;
+ * Visual *visual;
+ */
+} Ecore_X_Window_Attributes;
+
+EAPI int ecore_x_window_attributes_get(Ecore_X_Window win, Ecore_X_Window_Attributes *att_ret);
+EAPI void ecore_x_window_save_set_add(Ecore_X_Window win);
+EAPI void ecore_x_window_save_set_del(Ecore_X_Window win);
+EAPI Ecore_X_Window *ecore_x_window_children_get(Ecore_X_Window win, int *num);
+
+EAPI int ecore_x_cursor_color_supported_get(void);
+EAPI Ecore_X_Cursor ecore_x_cursor_new(Ecore_X_Window win, int *pixels, int w, int h, int hot_x, int hot_y);
+EAPI void ecore_x_cursor_free(Ecore_X_Cursor c);
+EAPI Ecore_X_Cursor ecore_x_cursor_shape_get(int shape);
+
+EAPI int ecore_x_pointer_grab(Ecore_X_Window win);
+EAPI int ecore_x_pointer_confine_grab(Ecore_X_Window win);
+EAPI void ecore_x_pointer_ungrab(void);
+EAPI int ecore_x_pointer_warp(Ecore_X_Window win, int x, int y);
+EAPI int ecore_x_keyboard_grab(Ecore_X_Window win);
+EAPI void ecore_x_keyboard_ungrab(void);
+EAPI void ecore_x_grab(void);
+EAPI void ecore_x_ungrab(void);
+EAPI void ecore_x_passive_grab_replay_func_set(int (*func) (void *data, int event_type, void *event), void *data);
+EAPI void ecore_x_window_button_grab(Ecore_X_Window win, int button,
+ Ecore_X_Event_Mask event_mask,
+ int mod, int any_mod);
+EAPI void ecore_x_window_button_ungrab(Ecore_X_Window win, int button,
+ int mod, int any_mod);
+EAPI void ecore_x_window_key_grab(Ecore_X_Window win, char *key,
+ int mod, int any_mod);
+EAPI void ecore_x_window_key_ungrab(Ecore_X_Window win, char *key,
+ int mod, int any_mod);
+
+EAPI void ecore_x_focus_reset(void);
+EAPI void ecore_x_events_allow_all(void);
+EAPI void ecore_x_pointer_last_xy_get(int *x, int *y);
+EAPI void ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y);
+
+/* ecore_x_sync.c */
+EAPI Ecore_X_Sync_Alarm ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter);
+EAPI int ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ecore/src/lib/ecore_x/Ecore_X_Atoms.h b/ecore/src/lib/ecore_x/Ecore_X_Atoms.h
new file mode 100644
index 0000000..759016c
--- /dev/null
+++ b/ecore/src/lib/ecore_x/Ecore_X_Atoms.h
@@ -0,0 +1,152 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#ifndef _ECORE_X_ATOMS_H
+#define _ECORE_X_ATOMS_H
+
+#include "Ecore_X.h"
+
+/**
+ * @file
+ * @brief Ecore X atoms
+ */
+
+/* General */
+extern Ecore_X_Atom ECORE_X_ATOM_UTF8_STRING;
+extern Ecore_X_Atom ECORE_X_ATOM_FILE_NAME;
+extern Ecore_X_Atom ECORE_X_ATOM_STRING;
+extern Ecore_X_Atom ECORE_X_ATOM_TEXT;
+extern Ecore_X_Atom ECORE_X_ATOM_COMPOUND_TEXT;
+
+/* ICCCM */
+extern Ecore_X_Atom ECORE_X_ATOM_WM_STATE;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_DELETE_WINDOW;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_TAKE_FOCUS;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_PROTOCOLS;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_CLASS;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_NAME;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_COMMAND;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_ICON_NAME;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_MACHINE;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_CHANGE_STATE;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_COLORMAP_WINDOWS;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_WINDOW_ROLE;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_HINTS;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_NORMAL_HINTS;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_LEADER;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_TRANSIENT_FOR;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_SAVE_YOURSELF;
+
+/* MWM */
+extern Ecore_X_Atom ECORE_X_ATOM_MOTIF_WM_HINTS;
+
+/* GNOME */
+extern Ecore_X_Atom ECORE_X_ATOM_WIN_LAYER;
+
+/* EWMH */
+extern Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTED;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK;
+
+extern Ecore_X_Atom ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_VIRTUAL_ROOTS;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_NAMES;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_GEOMETRY;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_VIEWPORT;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_LAYOUT;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WORKAREA;
+
+extern Ecore_X_Atom ECORE_X_ATOM_NET_CURRENT_DESKTOP;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_SHOWING_DESKTOP;
+
+extern Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST_STACKING;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_ACTIVE_WINDOW;
+
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_NAME;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_NAME;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_NAME;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_DESKTOP;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT_PARTIAL;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_GEOMETRY;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_PID;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_HANDLED_ICONS;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_USER_TIME;
+
+extern Ecore_X_Atom ECORE_X_ATOM_NET_CLOSE_WINDOW;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_MOVERESIZE;
+
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MOVE;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_SHADE;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_STICK;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CLOSE; /*x*/
+
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL;
+
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MODAL;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_STICKY;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SHADED;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_HIDDEN;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_ABOVE;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_BELOW;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION;
+
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_OPACITY;
+
+extern Ecore_X_Atom ECORE_X_ATOM_NET_FRAME_EXTENTS;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS;
+
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_PING;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
+extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER;
+
+/* Selections */
+extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_TARGETS;
+extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PRIMARY;
+extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_SECONDARY;
+extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_CLIPBOARD;
+extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_PRIMARY;
+extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_SECONDARY;
+extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD;
+
+/* DND */
+extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_XDND;
+extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_XDND;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_AWARE;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_TYPE_LIST;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_COPY;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_PRIVATE;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_ASK;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LIST;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_DESCRIPTION;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_ENTER;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_LEAVE;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_STATUS;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_POSITION;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_DROP;
+extern Ecore_X_Atom ECORE_X_ATOM_XDND_FINISHED;
+
+#endif /* _ECORE_X_ATOMS_H */
diff --git a/ecore/src/lib/ecore_x/Ecore_X_Cursor.h b/ecore/src/lib/ecore_x/Ecore_X_Cursor.h
new file mode 100644
index 0000000..af2e97a
--- /dev/null
+++ b/ecore/src/lib/ecore_x/Ecore_X_Cursor.h
@@ -0,0 +1,86 @@
+#ifndef _ECORE_X_CURSOR_H
+#define _ECORE_X_CURSOR_H
+
+/**
+ * @file
+ * @brief Defines the various cursor types for the X Windows system.
+ */
+
+#define ECORE_X_CURSOR_X 0
+#define ECORE_X_CURSOR_ARROW 2
+#define ECORE_X_CURSOR_BASED_ARROW_DOWN 4
+#define ECORE_X_CURSOR_UP 6
+#define ECORE_X_CURSOR_BOAT 8
+#define ECORE_X_CURSOR_BOTTOM_LEFT_CORNER 12
+#define ECORE_X_CURSOR_BOTTOM_RIGHT_CORNER 14
+#define ECORE_X_CURSOR_BOTTOM_SIDE 16
+#define ECORE_X_CURSOR_BOTTOM_TEE 18
+#define ECORE_X_CURSOR_BOX_SPIRAL 20
+#define ECORE_X_CURSOR_CENTER_PTR 22
+#define ECORE_X_CURSOR_CIRCLE 24
+#define ECORE_X_CURSOR_CLOCK 26
+#define ECORE_X_CURSOR_COFFEE_MUG 28
+#define ECORE_X_CURSOR_CROSS 30
+#define ECORE_X_CURSOR_CROSS_REVERSE 32
+#define ECORE_X_CURSOR_CROSSHAIR 34
+#define ECORE_X_CURSOR_DIAMOND_CROSS 36
+#define ECORE_X_CURSOR_DOT 38
+#define ECORE_X_CURSOR_DOT_BOX_MASK 40
+#define ECORE_X_CURSOR_DOUBLE_ARROW 42
+#define ECORE_X_CURSOR_DRAFT_LARGE 44
+#define ECORE_X_CURSOR_DRAFT_SMALL 46
+#define ECORE_X_CURSOR_DRAPED_BOX 48
+#define ECORE_X_CURSOR_EXCHANGE 50
+#define ECORE_X_CURSOR_FLEUR 52
+#define ECORE_X_CURSOR_GOBBLER 54
+#define ECORE_X_CURSOR_GUMBY 56
+#define ECORE_X_CURSOR_HAND1 58
+#define ECORE_X_CURSOR_HAND2 60
+#define ECORE_X_CURSOR_HEART 62
+#define ECORE_X_CURSOR_ICON 64
+#define ECORE_X_CURSOR_IRON_CROSS 66
+#define ECORE_X_CURSOR_LEFT_PTR 68
+#define ECORE_X_CURSOR_LEFT_SIDE 70
+#define ECORE_X_CURSOR_LEFT_TEE 72
+#define ECORE_X_CURSOR_LEFTBUTTON 74
+#define ECORE_X_CURSOR_LL_ANGLE 76
+#define ECORE_X_CURSOR_LR_ANGLE 78
+#define ECORE_X_CURSOR_MAN 80
+#define ECORE_X_CURSOR_MIDDLEBUTTON 82
+#define ECORE_X_CURSOR_MOUSE 84
+#define ECORE_X_CURSOR_PENCIL 86
+#define ECORE_X_CURSOR_PIRATE 88
+#define ECORE_X_CURSOR_PLUS 90
+#define ECORE_X_CURSOR_QUESTION_ARROW 92
+#define ECORE_X_CURSOR_RIGHT_PTR 94
+#define ECORE_X_CURSOR_RIGHT_SIDE 96
+#define ECORE_X_CURSOR_RIGHT_TEE 98
+#define ECORE_X_CURSOR_RIGHTBUTTON 100
+#define ECORE_X_CURSOR_RTL_LOGO 102
+#define ECORE_X_CURSOR_SAILBOAT 104
+#define ECORE_X_CURSOR_SB_DOWN_ARROW 106
+#define ECORE_X_CURSOR_SB_H_DOUBLE_ARROW 108
+#define ECORE_X_CURSOR_SB_LEFT_ARROW 110
+#define ECORE_X_CURSOR_SB_RIGHT_ARROW 112
+#define ECORE_X_CURSOR_SB_UP_ARROW 114
+#define ECORE_X_CURSOR_SB_V_DOUBLE_ARROW 116
+#define ECORE_X_CURSOR_SHUTTLE 118
+#define ECORE_X_CURSOR_SIZING 120
+#define ECORE_X_CURSOR_SPIDER 122
+#define ECORE_X_CURSOR_SPRAYCAN 124
+#define ECORE_X_CURSOR_STAR 126
+#define ECORE_X_CURSOR_TARGET 128
+#define ECORE_X_CURSOR_TCROSS 130
+#define ECORE_X_CURSOR_TOP_LEFT_ARROW 132
+#define ECORE_X_CURSOR_TOP_LEFT_CORNER 134
+#define ECORE_X_CURSOR_TOP_RIGHT_CORNER 136
+#define ECORE_X_CURSOR_TOP_SIDE 138
+#define ECORE_X_CURSOR_TOP_TEE 140
+#define ECORE_X_CURSOR_TREK 142
+#define ECORE_X_CURSOR_UL_ANGLE 144
+#define ECORE_X_CURSOR_UMBRELLA 146
+#define ECORE_X_CURSOR_UR_ANGLE 148
+#define ECORE_X_CURSOR_WATCH 150
+#define ECORE_X_CURSOR_XTERM 152
+
+#endif
diff --git a/ecore/src/lib/ecore_x/Makefile.am b/ecore/src/lib/ecore_x/Makefile.am
new file mode 100644
index 0000000..6b3bac9
--- /dev/null
+++ b/ecore/src/lib/ecore_x/Makefile.am
@@ -0,0 +1,81 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = \
+@Xcursor_cflags@ \
+@Xprint_cflags@ \
+@Xinerama_cflags@ \
+@x_cflags@ \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_txt \
+-I$(top_srcdir)/src/lib/ecore_job \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_txt \
+-I$(top_builddir)/src/lib/ecore_job
+
+libecore_x_la_LDFLAGS = -version-info 1:0:0 \
+-L$(top_builddir)/src/lib/ecore/.libs \
+-L$(top_builddir)/src/lib/ecore_txt/.libs \
+-L$(top_builddir)/src/lib/ecore_job/.libs
+
+if BUILD_ECORE_X
+
+lib_LTLIBRARIES = libecore_x.la
+include_HEADERS = \
+Ecore_X.h \
+Ecore_X_Atoms.h \
+Ecore_X_Cursor.h
+
+libecore_x_la_SOURCES = \
+ecore_x.c \
+ecore_x_dnd.c \
+ecore_x_sync.c \
+ecore_x_error.c \
+ecore_x_events.c \
+ecore_x_icccm.c \
+ecore_x_netwm.c \
+ecore_x_mwm.c \
+ecore_x_e.c \
+ecore_x_selection.c \
+ecore_x_window.c \
+ecore_x_window_prop.c \
+ecore_x_window_shape.c \
+ecore_x_pixmap.c \
+ecore_x_gc.c \
+ecore_x_xinerama.c \
+ecore_x_private.h
+
+libecore_x_la_LIBADD = \
+@Xcursor_libs@ \
+@Xprint_libs@ \
+@Xinerama_libs@ \
+@x_ldflags@ \
+@x_libs@ \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_txt/libecore_txt.la \
+$(top_builddir)/src/lib/ecore_job/libecore_job.la
+
+libecore_x_la_DEPENDENCIES = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_txt/libecore_txt.la \
+$(top_builddir)/src/lib/ecore_job/libecore_job.la
+
+endif
+
+EXTRA_DIST = \
+Ecore_X.h \
+Ecore_X_Atoms.h \
+Ecore_X_Cursor.h \
+ecore_x.c \
+ecore_x_dnd.c \
+ecore_x_sync.c \
+ecore_x_error.c \
+ecore_x_events.c \
+ecore_x_icccm.c \
+ecore_x_netwm.c \
+ecore_x_selection.c \
+ecore_x_window.c \
+ecore_x_window_prop.c \
+ecore_x_window_shape.c \
+ecore_x_pixmap.c \
+ecore_x_gc.c \
+ecore_x_private.h
diff --git a/ecore/src/lib/ecore_x/ecore_x.c b/ecore/src/lib/ecore_x/ecore_x.c
new file mode 100644
index 0000000..2d52bc3
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x.c
@@ -0,0 +1,1685 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "ecore_private.h"
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+static int _ecore_x_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_x_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_x_key_mask_get(KeySym sym);
+static void *_ecore_x_event_filter_start(void *data);
+static int _ecore_x_event_filter_filter(void *data, void *loop_data,int type, void *event);
+static void _ecore_x_event_filter_end(void *data, void *loop_data);
+
+static Ecore_Fd_Handler *_ecore_x_fd_handler_handle = NULL;
+static Ecore_Event_Filter *_ecore_x_filter_handler = NULL;
+static int _ecore_x_event_shape_id = 0;
+static int _ecore_x_event_sync_id = 0;
+static int _ecore_x_event_handlers_num = 0;
+static void (**_ecore_x_event_handlers) (XEvent * event) = NULL;
+
+static int _ecore_x_init_count = 0;
+static int _ecore_x_grab_count = 0;
+
+Display *_ecore_x_disp = NULL;
+double _ecore_x_double_click_time = 0.25;
+Time _ecore_x_event_last_time = 0;
+Window _ecore_x_event_last_win = 0;
+int _ecore_x_event_last_root_x = 0;
+int _ecore_x_event_last_root_y = 0;
+int _ecore_x_xcursor = 0;
+
+Ecore_X_Window _ecore_x_private_win = 0;
+
+/* FIXME - These are duplicates after making ecore atoms public */
+Ecore_X_Atom ECORE_X_ATOM_FILE_NAME = 0;
+Ecore_X_Atom ECORE_X_ATOM_STRING = 0;
+Ecore_X_Atom ECORE_X_ATOM_TEXT = 0;
+Ecore_X_Atom ECORE_X_ATOM_UTF8_STRING = 0;
+Ecore_X_Atom ECORE_X_ATOM_COMPOUND_TEXT = 0;
+
+Ecore_X_Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
+
+/*
+ * GNOME hints.
+ */
+Ecore_X_Atom ECORE_X_ATOM_WIN_LAYER = 0;
+
+/*
+ * Other hints.
+ */
+Ecore_X_Atom ECORE_X_ATOM_SELECTION_TARGETS;
+Ecore_X_Atom ECORE_X_ATOM_SELECTION_PRIMARY = 0;
+Ecore_X_Atom ECORE_X_ATOM_SELECTION_SECONDARY = 0;
+Ecore_X_Atom ECORE_X_ATOM_SELECTION_CLIPBOARD = 0;
+Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_PRIMARY = 0;
+Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_SECONDARY = 0;
+Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD = 0;
+
+Ecore_X_Atom ECORE_X_ATOM_SELECTION_XDND = 0;
+Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_XDND = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_AWARE = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_ENTER = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_TYPE_LIST = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_POSITION = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_COPY = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_MOVE = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LINK = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_PRIVATE = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_ASK = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LIST = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_DESCRIPTION = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_PROXY = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_STATUS = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_DROP = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_FINISHED = 0;
+Ecore_X_Atom ECORE_X_ATOM_XDND_LEAVE = 0;
+
+/* Xdnd atoms that need to be exposed to the application interface */
+Ecore_X_Atom ECORE_X_DND_ACTION_COPY = 0;
+Ecore_X_Atom ECORE_X_DND_ACTION_MOVE = 0;
+Ecore_X_Atom ECORE_X_DND_ACTION_LINK = 0;
+Ecore_X_Atom ECORE_X_DND_ACTION_ASK = 0;
+Ecore_X_Atom ECORE_X_DND_ACTION_PRIVATE = 0;
+
+int ECORE_X_EVENT_KEY_DOWN = 0;
+int ECORE_X_EVENT_KEY_UP = 0;
+int ECORE_X_EVENT_MOUSE_BUTTON_DOWN = 0;
+int ECORE_X_EVENT_MOUSE_BUTTON_UP = 0;
+int ECORE_X_EVENT_MOUSE_MOVE = 0;
+int ECORE_X_EVENT_MOUSE_IN = 0;
+int ECORE_X_EVENT_MOUSE_OUT = 0;
+int ECORE_X_EVENT_MOUSE_WHEEL = 0;
+int ECORE_X_EVENT_WINDOW_FOCUS_IN = 0;
+int ECORE_X_EVENT_WINDOW_FOCUS_OUT = 0;
+int ECORE_X_EVENT_WINDOW_KEYMAP = 0;
+int ECORE_X_EVENT_WINDOW_DAMAGE = 0;
+int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = 0;
+int ECORE_X_EVENT_WINDOW_CREATE = 0;
+int ECORE_X_EVENT_WINDOW_DESTROY = 0;
+int ECORE_X_EVENT_WINDOW_HIDE = 0;
+int ECORE_X_EVENT_WINDOW_SHOW = 0;
+int ECORE_X_EVENT_WINDOW_SHOW_REQUEST = 0;
+int ECORE_X_EVENT_WINDOW_REPARENT = 0;
+int ECORE_X_EVENT_WINDOW_CONFIGURE = 0;
+int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = 0;
+int ECORE_X_EVENT_WINDOW_GRAVITY = 0;
+int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = 0;
+int ECORE_X_EVENT_WINDOW_STACK = 0;
+int ECORE_X_EVENT_WINDOW_STACK_REQUEST = 0;
+int ECORE_X_EVENT_WINDOW_PROPERTY = 0;
+int ECORE_X_EVENT_WINDOW_COLORMAP = 0;
+int ECORE_X_EVENT_WINDOW_MAPPING = 0;
+int ECORE_X_EVENT_SELECTION_CLEAR = 0;
+int ECORE_X_EVENT_SELECTION_REQUEST = 0;
+int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
+int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
+int ECORE_X_EVENT_WINDOW_SHAPE = 0;
+int ECORE_X_EVENT_SYNC_COUNTER = 0;
+int ECORE_X_EVENT_SYNC_ALARM = 0;
+
+int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0;
+/*
+int ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = 0;
+int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = 0;
+int ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = 0;
+int ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = 0;
+int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = 0;
+int ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = 0;
+int ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = 0;
+int ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = 0;
+*/
+
+int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = 0;
+int ECORE_X_EVENT_WINDOW_STATE_REQUEST = 0;
+int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = 0;
+int ECORE_X_EVENT_PING = 0;
+int ECORE_X_EVENT_DESKTOP_CHANGE = 0;
+
+int ECORE_X_EVENT_XDND_ENTER = 0;
+int ECORE_X_EVENT_XDND_POSITION = 0;
+int ECORE_X_EVENT_XDND_STATUS = 0;
+int ECORE_X_EVENT_XDND_LEAVE = 0;
+int ECORE_X_EVENT_XDND_DROP = 0;
+int ECORE_X_EVENT_XDND_FINISHED = 0;
+
+int ECORE_X_MODIFIER_SHIFT = 0;
+int ECORE_X_MODIFIER_CTRL = 0;
+int ECORE_X_MODIFIER_ALT = 0;
+int ECORE_X_MODIFIER_WIN = 0;
+
+int ECORE_X_LOCK_SCROLL = 0;
+int ECORE_X_LOCK_NUM = 0;
+int ECORE_X_LOCK_CAPS = 0;
+
+/**
+ * @defgroup Ecore_X_Init_Group X Library Init and Shutdown Functions
+ *
+ * Functions that start and shut down the Ecore X Library.
+ */
+
+/**
+ * Initialize the X display connection to the given display.
+ *
+ * @param name Display target name. If @c NULL, the default display is
+ * assumed.
+ * @return The number of times the library has been initialized without
+ * being shut down. 0 is returned if an error occurs.
+ * @ingroup Ecore_X_Init_Group
+ */
+int
+ecore_x_init(const char *name)
+{
+ int shape_base = 0;
+ int shape_err_base = 0;
+ int sync_base = 0;
+ int sync_err_base = 0;
+
+ if (_ecore_x_init_count > 0)
+ {
+ _ecore_x_init_count++;
+ return _ecore_x_init_count;
+ }
+ _ecore_x_disp = XOpenDisplay((char *)name);
+ if (!_ecore_x_disp) return 0;
+ _ecore_x_error_handler_init();
+ _ecore_x_event_handlers_num = LASTEvent;
+
+ if (XShapeQueryExtension(_ecore_x_disp, &shape_base, &shape_err_base))
+ _ecore_x_event_shape_id = shape_base + ShapeNotify;
+ if (_ecore_x_event_shape_id >= LASTEvent)
+ _ecore_x_event_handlers_num = _ecore_x_event_shape_id + 1;
+
+ if (XSyncQueryExtension(_ecore_x_disp, &sync_base, &sync_err_base))
+ {
+ int major, minor;
+
+ _ecore_x_event_sync_id = sync_base;
+ if (!XSyncInitialize(_ecore_x_disp, &major, &minor))
+ _ecore_x_event_sync_id = 0;
+ }
+ if (_ecore_x_event_sync_id + XSyncAlarmNotify >= LASTEvent)
+ _ecore_x_event_handlers_num = _ecore_x_event_sync_id + XSyncAlarmNotify + 1;
+
+ _ecore_x_event_handlers = calloc(_ecore_x_event_handlers_num, sizeof(void *));
+ if (!_ecore_x_event_handlers)
+ {
+ XCloseDisplay(_ecore_x_disp);
+ _ecore_x_fd_handler_handle = NULL;
+ _ecore_x_disp = NULL;
+ return 0;
+ }
+#ifdef ECORE_XCURSOR
+ _ecore_x_xcursor = XcursorSupportsARGB(_ecore_x_disp);
+#endif
+ _ecore_x_event_handlers[KeyPress] = _ecore_x_event_handle_key_press;
+ _ecore_x_event_handlers[KeyRelease] = _ecore_x_event_handle_key_release;
+ _ecore_x_event_handlers[ButtonPress] = _ecore_x_event_handle_button_press;
+ _ecore_x_event_handlers[ButtonRelease] = _ecore_x_event_handle_button_release;
+ _ecore_x_event_handlers[MotionNotify] = _ecore_x_event_handle_motion_notify;
+ _ecore_x_event_handlers[EnterNotify] = _ecore_x_event_handle_enter_notify;
+ _ecore_x_event_handlers[LeaveNotify] = _ecore_x_event_handle_leave_notify;
+ _ecore_x_event_handlers[FocusIn] = _ecore_x_event_handle_focus_in;
+ _ecore_x_event_handlers[FocusOut] = _ecore_x_event_handle_focus_out;
+ _ecore_x_event_handlers[KeymapNotify] = _ecore_x_event_handle_keymap_notify;
+ _ecore_x_event_handlers[Expose] = _ecore_x_event_handle_expose;
+ _ecore_x_event_handlers[GraphicsExpose] = _ecore_x_event_handle_graphics_expose;
+ _ecore_x_event_handlers[VisibilityNotify] = _ecore_x_event_handle_visibility_notify;
+ _ecore_x_event_handlers[CreateNotify] = _ecore_x_event_handle_create_notify;
+ _ecore_x_event_handlers[DestroyNotify] = _ecore_x_event_handle_destroy_notify;
+ _ecore_x_event_handlers[UnmapNotify] = _ecore_x_event_handle_unmap_notify;
+ _ecore_x_event_handlers[MapNotify] = _ecore_x_event_handle_map_notify;
+ _ecore_x_event_handlers[MapRequest] = _ecore_x_event_handle_map_request;
+ _ecore_x_event_handlers[ReparentNotify] = _ecore_x_event_handle_reparent_notify;
+ _ecore_x_event_handlers[ConfigureNotify] = _ecore_x_event_handle_configure_notify;
+ _ecore_x_event_handlers[ConfigureRequest] = _ecore_x_event_handle_configure_request;
+ _ecore_x_event_handlers[GravityNotify] = _ecore_x_event_handle_gravity_notify;
+ _ecore_x_event_handlers[ResizeRequest] = _ecore_x_event_handle_resize_request;
+ _ecore_x_event_handlers[CirculateNotify] = _ecore_x_event_handle_circulate_notify;
+ _ecore_x_event_handlers[CirculateRequest] = _ecore_x_event_handle_circulate_request;
+ _ecore_x_event_handlers[PropertyNotify] = _ecore_x_event_handle_property_notify;
+ _ecore_x_event_handlers[SelectionClear] = _ecore_x_event_handle_selection_clear;
+ _ecore_x_event_handlers[SelectionRequest] = _ecore_x_event_handle_selection_request;
+ _ecore_x_event_handlers[SelectionNotify] = _ecore_x_event_handle_selection_notify;
+ _ecore_x_event_handlers[ColormapNotify] = _ecore_x_event_handle_colormap_notify;
+ _ecore_x_event_handlers[MappingNotify] = _ecore_x_event_handle_mapping_notify;
+ _ecore_x_event_handlers[ClientMessage] = _ecore_x_event_handle_client_message;
+ if (_ecore_x_event_shape_id)
+ _ecore_x_event_handlers[_ecore_x_event_shape_id] = _ecore_x_event_handle_shape_change;
+ if (_ecore_x_event_sync_id)
+ {
+ _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncCounterNotify] =
+ _ecore_x_event_handle_sync_counter;
+ _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncAlarmNotify] =
+ _ecore_x_event_handle_sync_alarm;
+ }
+ if (!ECORE_X_EVENT_KEY_DOWN)
+ {
+ ECORE_X_EVENT_KEY_DOWN = ecore_event_type_new();
+ ECORE_X_EVENT_KEY_UP = ecore_event_type_new();
+ ECORE_X_EVENT_MOUSE_BUTTON_DOWN = ecore_event_type_new();
+ ECORE_X_EVENT_MOUSE_BUTTON_UP = ecore_event_type_new();
+ ECORE_X_EVENT_MOUSE_MOVE = ecore_event_type_new();
+ ECORE_X_EVENT_MOUSE_IN = ecore_event_type_new();
+ ECORE_X_EVENT_MOUSE_OUT = ecore_event_type_new();
+ ECORE_X_EVENT_MOUSE_WHEEL = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_KEYMAP = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_DAMAGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_CREATE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_DESTROY = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_HIDE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_SHOW = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_SHOW_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_REPARENT = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_GRAVITY = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_STACK = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_STACK_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROPERTY = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_COLORMAP = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_MAPPING = ecore_event_type_new();
+ ECORE_X_EVENT_SELECTION_CLEAR = ecore_event_type_new();
+ ECORE_X_EVENT_SELECTION_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_SELECTION_NOTIFY = ecore_event_type_new();
+ ECORE_X_EVENT_CLIENT_MESSAGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_SHAPE = ecore_event_type_new();
+ ECORE_X_EVENT_SYNC_COUNTER = ecore_event_type_new();
+ ECORE_X_EVENT_SYNC_ALARM = ecore_event_type_new();
+
+ ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
+ /*
+ ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = ecore_event_type_new();
+ */
+
+ ECORE_X_EVENT_DESKTOP_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_STATE_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_PING = ecore_event_type_new();
+
+ ECORE_X_EVENT_XDND_ENTER = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_POSITION = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_STATUS = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_LEAVE = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_DROP = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_FINISHED = ecore_event_type_new();
+ }
+
+ /* everything has these... unless its like a pda... :) */
+ ECORE_X_MODIFIER_SHIFT = _ecore_x_key_mask_get(XK_Shift_L);
+ ECORE_X_MODIFIER_CTRL = _ecore_x_key_mask_get(XK_Control_L);
+
+ /* apple's xdarwin has no alt!!!! */
+ ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Alt_L);
+ if (!ECORE_X_MODIFIER_ALT)
+ ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Meta_L);
+ if (!ECORE_X_MODIFIER_ALT)
+ ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Super_L);
+
+ /* the windows key... a valid modifier :) */
+ ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Super_L);
+ if (!ECORE_X_MODIFIER_WIN)
+ ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Mode_switch);
+ if (!ECORE_X_MODIFIER_WIN)
+ ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Meta_L);
+
+ ECORE_X_LOCK_SCROLL = _ecore_x_key_mask_get(XK_Scroll_Lock);
+ ECORE_X_LOCK_NUM = _ecore_x_key_mask_get(XK_Num_Lock);
+ ECORE_X_LOCK_CAPS = _ecore_x_key_mask_get(XK_Caps_Lock);
+
+ _ecore_x_fd_handler_handle =
+ ecore_main_fd_handler_add(ConnectionNumber(_ecore_x_disp),
+ ECORE_FD_READ,
+ _ecore_x_fd_handler, _ecore_x_disp,
+ _ecore_x_fd_handler_buf, _ecore_x_disp);
+ if (!_ecore_x_fd_handler_handle)
+ {
+ XCloseDisplay(_ecore_x_disp);
+ free(_ecore_x_event_handlers);
+ _ecore_x_fd_handler_handle = NULL;
+ _ecore_x_disp = NULL;
+ _ecore_x_event_handlers = NULL;
+ return 0;
+ }
+ _ecore_x_filter_handler = ecore_event_filter_add(_ecore_x_event_filter_start, _ecore_x_event_filter_filter, _ecore_x_event_filter_end, NULL);
+
+ ECORE_X_ATOM_COMPOUND_TEXT = XInternAtom(_ecore_x_disp, "COMPOUND_TEXT", False);
+ ECORE_X_ATOM_UTF8_STRING = XInternAtom(_ecore_x_disp, "UTF8_STRING", False);
+ ECORE_X_ATOM_FILE_NAME = XInternAtom(_ecore_x_disp, "FILE_NAME", False);
+ ECORE_X_ATOM_STRING = XInternAtom(_ecore_x_disp, "STRING", False);
+ ECORE_X_ATOM_TEXT = XInternAtom(_ecore_x_disp, "TEXT", False);
+
+ /* Set up the ICCCM hints */
+ ecore_x_icccm_init();
+
+ ECORE_X_ATOM_MOTIF_WM_HINTS = XInternAtom(_ecore_x_disp, "_MOTIF_WM_HINTS", False);
+
+ ECORE_X_ATOM_WIN_LAYER = XInternAtom(_ecore_x_disp, "_WIN_LAYER", False);
+
+ /* Set up the _NET_... hints */
+ ecore_x_netwm_init();
+
+ /* old e hints init */
+ ecore_x_e_init();
+
+ /* This is just to be anal about naming conventions */
+ ECORE_X_ATOM_SELECTION_TARGETS = XInternAtom(_ecore_x_disp, "TARGETS", False);
+ ECORE_X_ATOM_SELECTION_PRIMARY = XA_PRIMARY;
+ ECORE_X_ATOM_SELECTION_SECONDARY = XA_SECONDARY;
+ ECORE_X_ATOM_SELECTION_CLIPBOARD = XInternAtom(_ecore_x_disp, "CLIPBOARD", False);
+ ECORE_X_ATOM_SELECTION_PROP_PRIMARY = XInternAtom(_ecore_x_disp, "_ECORE_SELECTION_PRIMARY", False);
+ ECORE_X_ATOM_SELECTION_PROP_SECONDARY = XInternAtom(_ecore_x_disp, "_ECORE_SELECTION_SECONDARY", False);
+ ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD = XInternAtom(_ecore_x_disp, "_ECORE_SELECTION_CLIPBOARD", False);
+ ECORE_X_ATOM_SELECTION_PROP_XDND = XInternAtom(_ecore_x_disp, "JXSelectionWindowProperty", False);
+ ECORE_X_ATOM_SELECTION_XDND = XInternAtom(_ecore_x_disp, "XdndSelection", False);
+ ECORE_X_ATOM_XDND_AWARE = XInternAtom(_ecore_x_disp, "XdndAware", False);
+ ECORE_X_ATOM_XDND_TYPE_LIST = XInternAtom(_ecore_x_disp, "XdndTypeList", False);
+ ECORE_X_ATOM_XDND_ENTER = XInternAtom(_ecore_x_disp, "XdndEnter", False);
+ ECORE_X_ATOM_XDND_POSITION = XInternAtom(_ecore_x_disp, "XdndPosition", False);
+ ECORE_X_ATOM_XDND_ACTION_COPY = XInternAtom(_ecore_x_disp, "XdndActionCopy", False);
+ ECORE_X_ATOM_XDND_ACTION_MOVE = XInternAtom(_ecore_x_disp, "XdndActionMove", False);
+ ECORE_X_ATOM_XDND_ACTION_PRIVATE = XInternAtom(_ecore_x_disp, "XdndActionPrivate", False);
+ ECORE_X_ATOM_XDND_ACTION_ASK = XInternAtom(_ecore_x_disp, "XdndActionAsk", False);
+ ECORE_X_ATOM_XDND_ACTION_LIST = XInternAtom(_ecore_x_disp, "XdndActionList", False);
+ ECORE_X_ATOM_XDND_ACTION_LINK = XInternAtom(_ecore_x_disp, "XdndActionLink", False);
+ ECORE_X_ATOM_XDND_ACTION_DESCRIPTION = XInternAtom(_ecore_x_disp, "XdndActionDescription", False);
+ ECORE_X_ATOM_XDND_PROXY = XInternAtom(_ecore_x_disp, "XdndProxy", False);
+ ECORE_X_ATOM_XDND_STATUS = XInternAtom(_ecore_x_disp, "XdndStatus", False);
+ ECORE_X_ATOM_XDND_LEAVE = XInternAtom(_ecore_x_disp, "XdndLeave", False);
+ ECORE_X_ATOM_XDND_DROP = XInternAtom(_ecore_x_disp, "XdndDrop", False);
+ ECORE_X_ATOM_XDND_FINISHED = XInternAtom(_ecore_x_disp, "XdndFinished", False);
+
+ /* Initialize the globally defined xdnd atoms */
+ ECORE_X_DND_ACTION_COPY = ECORE_X_ATOM_XDND_ACTION_COPY;
+ ECORE_X_DND_ACTION_MOVE = ECORE_X_ATOM_XDND_ACTION_MOVE;
+ ECORE_X_DND_ACTION_LINK = ECORE_X_ATOM_XDND_ACTION_LINK;
+ ECORE_X_DND_ACTION_ASK = ECORE_X_ATOM_XDND_ACTION_ASK;
+ ECORE_X_DND_ACTION_PRIVATE = ECORE_X_ATOM_XDND_ACTION_PRIVATE;
+
+ _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] = ECORE_X_ATOM_WM_DELETE_WINDOW;
+ _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] = ECORE_X_ATOM_WM_TAKE_FOCUS;
+ _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_PING] = ECORE_X_ATOM_NET_WM_PING;
+ _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
+
+ _ecore_x_selection_data_init();
+ _ecore_x_dnd_init();
+
+ _ecore_x_init_count++;
+
+ _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456);
+
+ return _ecore_x_init_count;
+}
+
+static int
+_ecore_x_shutdown(int close_display)
+{
+ _ecore_x_init_count--;
+ if (_ecore_x_init_count > 0) return _ecore_x_init_count;
+ if (!_ecore_x_disp) return _ecore_x_init_count;
+ if (close_display)
+ XCloseDisplay(_ecore_x_disp);
+ else
+ close(ConnectionNumber(_ecore_x_disp));
+ free(_ecore_x_event_handlers);
+ ecore_main_fd_handler_del(_ecore_x_fd_handler_handle);
+ ecore_event_filter_del(_ecore_x_filter_handler);
+ _ecore_x_fd_handler_handle = NULL;
+ _ecore_x_filter_handler = NULL;
+ _ecore_x_disp = NULL;
+ _ecore_x_event_handlers = NULL;
+ _ecore_x_selection_shutdown();
+ _ecore_x_dnd_shutdown();
+ if (_ecore_x_init_count < 0) _ecore_x_init_count = 0;
+ return _ecore_x_init_count;
+}
+
+/**
+ * Shuts down the Ecore X library.
+ *
+ * In shutting down the library, the X display connection is terminated
+ * and any event handlers for it are removed.
+ *
+ * @return The number of times the library has been initialized without
+ * being shut down.
+ * @ingroup Ecore_X_Init_Group
+ */
+int
+ecore_x_shutdown(void)
+{
+ return _ecore_x_shutdown(1);
+}
+
+/**
+ * Shuts down the Ecore X library.
+ *
+ * As ecore_x_shutdown, except do not close Display, only connection.
+ *
+ * @ingroup Ecore_X_Init_Group
+ */
+int
+ecore_x_disconnect(void)
+{
+ return _ecore_x_shutdown(0);
+}
+
+/**
+ * @defgroup Ecore_X_Display_Attr_Group X Display Attributes
+ *
+ * Functions that set and retrieve X display attributes.
+ */
+
+/**
+ * Retrieves the Ecore_X_Display handle used for the current X connection.
+ * @return The current X display.
+ * @ingroup Ecore_X_Display_Attr_Group
+ */
+Ecore_X_Display *
+ecore_x_display_get(void)
+{
+ return (Ecore_X_Display *)_ecore_x_disp;
+}
+
+/**
+ * Retrieves the X display file descriptor.
+ * @return The current X display file descriptor.
+ * @ingroup Ecore_X_Display_Attr_Group
+ */
+int
+ecore_x_fd_get(void)
+{
+ return ConnectionNumber(_ecore_x_disp);
+}
+
+/**
+ * Sets the timeout for a double and triple clicks to be flagged.
+ *
+ * This sets the time between clicks before the double_click flag is
+ * set in a button down event. If 3 clicks occur within double this
+ * time, the triple_click flag is also set.
+ *
+ * @param t The time in seconds
+ * @ingroup Ecore_X_Display_Attr_Group
+ */
+void
+ecore_x_double_click_time_set(double t)
+{
+ if (t < 0.0) t = 0.0;
+ _ecore_x_double_click_time = t;
+}
+
+/**
+ * Retrieves the double and triple click flag timeout.
+ *
+ * See @ref ecore_x_double_click_time_set for more information.
+ *
+ * @return The timeout for double clicks in seconds.
+ * @ingroup Ecore_X_Display_Attr_Group
+ */
+double
+ecore_x_double_click_time_get(void)
+{
+ return _ecore_x_double_click_time;
+}
+
+/**
+ * @defgroup Ecore_X_Flush_Group X Synchronization Functions
+ *
+ * Functions that ensure that all commands that have been issued by the
+ * Ecore X library have been sent to the server.
+ */
+
+/**
+ * Sends all X commands in the X Display buffer.
+ * @ingroup Ecore_X_Flush_Group
+ */
+void
+ecore_x_flush(void)
+{
+ XFlush(_ecore_x_disp);
+}
+
+/**
+ * Flushes the command buffer and waits until all requests have been
+ * processed by the server.
+ * @ingroup Ecore_X_Flush_Group
+ */
+void
+ecore_x_sync(void)
+{
+ XSync(_ecore_x_disp, False);
+}
+
+/**
+ * Kill all clients with subwindows under a given window.
+ *
+ * You can kill all clients connected to the X server by using
+ * @ref ecore_x_window_root_list to get a list of root windows, and
+ * then passing each root window to this function.
+ *
+ * @param root The window whose children will be killed.
+ */
+void
+ecore_x_killall(Ecore_X_Window root)
+{
+ int screens;
+ int i, j;
+
+ XGrabServer(_ecore_x_disp);
+ screens = ScreenCount(_ecore_x_disp);
+
+ /* Tranverse window tree starting from root, and drag each
+ * before the firing squad */
+ for (i = 0; i < screens; ++i)
+ {
+ Window root_r;
+ Window parent_r;
+ Window *children_r = NULL;
+ unsigned int num_children = 0;
+
+ while (XQueryTree(_ecore_x_disp, root, &root_r, &parent_r,
+ &children_r, &num_children) && (num_children > 0))
+ {
+ for (j = 0; j < num_children; ++j)
+ {
+ XKillClient(_ecore_x_disp, children_r[j]);
+ }
+
+ XFree(children_r);
+ }
+ }
+
+ XUngrabServer(_ecore_x_disp);
+ XSync(_ecore_x_disp, False);
+}
+
+/**
+ * Kill a specific client
+ *
+ * You can kill a specific client woning window @p win
+ *
+ * @param win Window of the client to be killed
+ */
+void
+ecore_x_kill(Ecore_X_Window win)
+{
+ XKillClient(_ecore_x_disp, win);
+}
+
+/**
+ * Return the last event time
+ */
+Ecore_X_Time
+ecore_x_current_time_get(void)
+{
+ return _ecore_x_event_last_time;
+}
+
+static int
+_ecore_x_fd_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ Display *d;
+
+ d = data;
+ while (XPending(d))
+ {
+ XEvent ev;
+
+ XNextEvent(d, &ev);
+ if ((ev.type >= 0) && (ev.type < _ecore_x_event_handlers_num))
+ {
+ if (_ecore_x_event_handlers[ev.type])
+ _ecore_x_event_handlers[ev.type] (&ev);
+ }
+ }
+ return 1;
+}
+
+static int
+_ecore_x_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ Display *d;
+
+ d = data;
+ if (XPending(d)) return 1;
+ return 0;
+}
+
+static int
+_ecore_x_key_mask_get(KeySym sym)
+{
+ XModifierKeymap *mod;
+ KeySym sym2;
+ int i, j;
+ const int masks[8] =
+ {
+ ShiftMask, LockMask, ControlMask,
+ Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
+ };
+
+ mod = XGetModifierMapping(_ecore_x_disp);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ sym2 = XKeycodeToKeysym(_ecore_x_disp, mod->modifiermap[i], j);
+ if (sym2 != 0) break;
+ }
+ if (sym2 == sym)
+ {
+ int mask;
+
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap) XFree(mod->modifiermap);
+ XFree(mod);
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap) XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+typedef struct _Ecore_X_Filter_Data Ecore_X_Filter_Data;
+
+struct _Ecore_X_Filter_Data
+{
+ int last_event_type;
+};
+
+static void *
+_ecore_x_event_filter_start(void *data __UNUSED__)
+{
+ Ecore_X_Filter_Data *filter_data;
+
+ filter_data = calloc(1, sizeof(Ecore_X_Filter_Data));
+ return filter_data;
+}
+
+static int
+_ecore_x_event_filter_filter(void *data __UNUSED__, void *loop_data,int type, void *event __UNUSED__)
+{
+ Ecore_X_Filter_Data *filter_data;
+
+ filter_data = loop_data;
+ if (!filter_data) return 1;
+ if (type == ECORE_X_EVENT_MOUSE_MOVE)
+ {
+ if ((filter_data->last_event_type) == ECORE_X_EVENT_MOUSE_MOVE)
+ {
+ filter_data->last_event_type = type;
+ return 0;
+ }
+ }
+ filter_data->last_event_type = type;
+ return 1;
+}
+
+static void
+_ecore_x_event_filter_end(void *data __UNUSED__, void *loop_data)
+{
+ Ecore_X_Filter_Data *filter_data;
+
+ filter_data = loop_data;
+ if (filter_data) free(filter_data);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+/* FIXME: these funcs need categorising */
+/*****************************************************************************/
+
+/**
+ * Retrieves the geometry of the given drawable.
+ * @param d The given drawable.
+ * @param x Pointer to an integer into which the X position is to be stored.
+ * @param y Pointer to an integer into which the Y position is to be stored.
+ * @param w Pointer to an integer into which the width is to be stored.
+ * @param h Pointer to an integer into which the height is to be stored.
+ */
+void
+ecore_x_drawable_geometry_get(Ecore_X_Drawable d, int *x, int *y, int *w, int *h)
+{
+ Window dummy_win;
+ int ret_x, ret_y;
+ unsigned int ret_w, ret_h, dummy_border, dummy_depth;
+
+ if (!XGetGeometry(_ecore_x_disp, d, &dummy_win, &ret_x, &ret_y,
+ &ret_w, &ret_h, &dummy_border, &dummy_depth))
+ {
+ ret_x = 0;
+ ret_y = 0;
+ ret_w = 0;
+ ret_h = 0;
+ }
+
+ if (x) *x = ret_x;
+ if (y) *y = ret_y;
+ if (w) *w = (int) ret_w;
+ if (h) *h = (int) ret_h;
+}
+
+/**
+ * Retrieves the width of the border of the given drawable.
+ * @param d The given drawable.
+ * @return The border width of the given drawable.
+ */
+int
+ecore_x_drawable_border_width_get(Ecore_X_Drawable d)
+{
+ Window dummy_win;
+ int dummy_x, dummy_y;
+ unsigned int dummy_w, dummy_h, border_ret, dummy_depth;
+
+ if (!XGetGeometry(_ecore_x_disp, d, &dummy_win, &dummy_x, &dummy_y,
+ &dummy_w, &dummy_h, &border_ret, &dummy_depth))
+ border_ret = 0;
+
+ return (int) border_ret;
+}
+
+/**
+ * Retrieves the depth of the given drawable.
+ * @param d The given drawable.
+ * @return The depth of the given drawable.
+ */
+int
+ecore_x_drawable_depth_get(Ecore_X_Drawable d)
+{
+ Window dummy_win;
+ int dummy_x, dummy_y;
+ unsigned int dummy_w, dummy_h, dummy_border, depth_ret;
+
+ if (!XGetGeometry(_ecore_x_disp, d, &dummy_win, &dummy_x, &dummy_y,
+ &dummy_w, &dummy_h, &dummy_border, &depth_ret))
+ depth_ret = 0;
+
+ return (int) depth_ret;
+}
+
+/**
+ * Get a list of all the root windows on the server.
+ *
+ * @note The returned array will need to be freed after use.
+ * @param num_ret Pointer to integer to put number of windows returned in.
+ * @return An array of all the root windows. @c NULL is returned if memory
+ * could not be allocated for the list, or if @p num_ret is @c NULL.
+ */
+Ecore_X_Window *
+ecore_x_window_root_list(int *num_ret)
+{
+ int num, i;
+ Ecore_X_Window *roots;
+
+ if (!num_ret) return NULL;
+ *num_ret = 0;
+#ifdef ECORE_XPRINT
+ {
+ Screen **ps = NULL;
+ int psnum = 0;
+
+ num = ScreenCount(_ecore_x_disp);
+ ps = XpQueryScreens(_ecore_x_disp, &psnum);
+ if (ps)
+ {
+ int overlap, j;
+
+ overlap = 0;
+ for (i = 0; i < num; i++)
+ {
+ for (j = 0; j < psnum; j++)
+ {
+ if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
+ overlap++;
+ }
+ }
+ roots = malloc((num - overlap) * sizeof(Window));
+ if (roots)
+ {
+ int k;
+
+ k = 0;
+ for (i = 0; i < num; i++)
+ {
+ int is_print;
+
+ is_print = 0;
+ for (j = 0; j < psnum; j++)
+ {
+ if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
+ {
+ is_print = 1;
+ break;
+ }
+ }
+ if (!is_print)
+ {
+ roots[k] = RootWindow(_ecore_x_disp, i);
+ k++;
+ }
+ }
+ *num_ret = k;
+ }
+ XFree(ps);
+ }
+ else
+ {
+ roots = malloc(num * sizeof(Window));
+ if (!roots) return NULL;
+ *num_ret = num;
+ for (i = 0; i < num; i++)
+ roots[i] = RootWindow(_ecore_x_disp, i);
+ }
+ }
+#else
+ num = ScreenCount(_ecore_x_disp);
+ roots = malloc(num * sizeof(Window));
+ if (!roots) return NULL;
+ *num_ret = num;
+ for (i = 0; i < num; i++)
+ roots[i] = RootWindow(_ecore_x_disp, i);
+#endif
+ return roots;
+}
+
+Ecore_X_Window
+ecore_x_window_root_first_get(void)
+{
+ int num;
+ Ecore_X_Window root, *roots = NULL;
+
+ roots = ecore_x_window_root_list(&num);
+ if(!(roots)) return 0;
+
+ if (num > 0)
+ root = roots[0];
+ else
+ root = 0;
+
+ free(roots);
+ return root;
+}
+
+
+static void _ecore_x_window_manage_error(void *data);
+
+static int _ecore_x_window_manage_failed = 0;
+static void
+_ecore_x_window_manage_error(void *data __UNUSED__)
+{
+ if ((ecore_x_error_request_get() == X_ChangeWindowAttributes) &&
+ (ecore_x_error_code_get() == BadAccess))
+ _ecore_x_window_manage_failed = 1;
+}
+
+int
+ecore_x_window_manage(Ecore_X_Window win)
+{
+ XWindowAttributes att;
+
+ if (XGetWindowAttributes(_ecore_x_disp, win, &att) != True) return 0;
+ ecore_x_sync();
+ _ecore_x_window_manage_failed = 0;
+ ecore_x_error_handler_set(_ecore_x_window_manage_error, NULL);
+ XSelectInput(_ecore_x_disp, win,
+ EnterWindowMask |
+ LeaveWindowMask |
+ PropertyChangeMask |
+ ResizeRedirectMask |
+ SubstructureRedirectMask |
+ SubstructureNotifyMask |
+ StructureNotifyMask |
+ KeyPressMask |
+ KeyReleaseMask |
+ att.your_event_mask);
+ ecore_x_sync();
+ ecore_x_error_handler_set(NULL, NULL);
+ if (_ecore_x_window_manage_failed)
+ {
+ _ecore_x_window_manage_failed = 0;
+ return 0;
+ }
+ return 1;
+}
+
+void
+ecore_x_window_container_manage(Ecore_X_Window win)
+{
+ XSelectInput(_ecore_x_disp, win,
+ ResizeRedirectMask |
+ SubstructureRedirectMask |
+ SubstructureNotifyMask);
+}
+
+void
+ecore_x_window_client_manage(Ecore_X_Window win)
+{
+ XSelectInput(_ecore_x_disp, win,
+ PropertyChangeMask |
+ ResizeRedirectMask |
+ FocusChangeMask |
+ ColormapChangeMask |
+ VisibilityChangeMask |
+ StructureNotifyMask
+ );
+ XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
+}
+
+void
+ecore_x_window_sniff(Ecore_X_Window win)
+{
+ XSelectInput(_ecore_x_disp, win,
+ PropertyChangeMask |
+ SubstructureNotifyMask);
+}
+
+void
+ecore_x_window_client_sniff(Ecore_X_Window win)
+{
+ XSelectInput(_ecore_x_disp, win,
+ PropertyChangeMask |
+ FocusChangeMask |
+ ColormapChangeMask |
+ VisibilityChangeMask |
+ StructureNotifyMask);
+ XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
+}
+
+/**
+ * Retrieves the atom value associated with the given name.
+ * @param name The given name.
+ * @return Associated atom value.
+ */
+Ecore_X_Atom
+ecore_x_atom_get(const char *name)
+{
+ if (!_ecore_x_disp) return 0;
+ return XInternAtom(_ecore_x_disp, name, False);
+}
+
+
+
+
+
+
+int
+ecore_x_window_attributes_get(Ecore_X_Window win, Ecore_X_Window_Attributes *att_ret)
+{
+ XWindowAttributes att;
+
+ if (!XGetWindowAttributes(_ecore_x_disp, win, &att)) return 0;
+ memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
+ att_ret->root = att.root;
+ att_ret->x = att.x;
+ att_ret->y = att.y;
+ att_ret->w = att.width;
+ att_ret->h = att.height;
+ att_ret->border = att.border_width;
+ att_ret->depth = att.depth;
+ if (att.map_state != IsUnmapped) att_ret->visible = 1;
+ if (att.map_state == IsViewable) att_ret->viewable = 1;
+ if (att.override_redirect) att_ret->override = 1;
+ if (att.class == InputOnly) att_ret->input_only = 1;
+ if (att.save_under) att_ret->save_under = 1;
+ att_ret->event_mask.mine = att.your_event_mask;
+ att_ret->event_mask.all = att.your_event_mask;
+ att_ret->event_mask.no_propagate = att.do_not_propagate_mask;
+ att_ret->window_gravity = att.win_gravity;
+ att_ret->pixel_gravity = att.win_gravity;
+ att_ret->colormap = att.colormap;
+ return 1;
+}
+
+void
+ecore_x_window_save_set_add(Ecore_X_Window win)
+{
+ XAddToSaveSet(_ecore_x_disp, win);
+}
+
+void
+ecore_x_window_save_set_del(Ecore_X_Window win)
+{
+ XRemoveFromSaveSet(_ecore_x_disp, win);
+}
+
+Ecore_X_Window *
+ecore_x_window_children_get(Ecore_X_Window win, int *num)
+{
+ Ecore_X_Window *windows = NULL;
+ Window root_ret = 0, parent_ret = 0, *children_ret = NULL;
+ unsigned int children_ret_num = 0;
+
+ if (!XQueryTree(_ecore_x_disp, win, &root_ret, &parent_ret, &children_ret,
+ &children_ret_num))
+ {
+ return NULL;
+ }
+ if (children_ret)
+ {
+ windows = malloc(children_ret_num * sizeof(Ecore_X_Window));
+ if (windows)
+ {
+ unsigned int i;
+
+ for (i = 0; i < children_ret_num; i++)
+ windows[i] = children_ret[i];
+ *num = children_ret_num;
+ }
+ XFree(children_ret);
+ }
+ return windows;
+}
+
+
+
+
+
+
+int
+ecore_x_cursor_color_supported_get(void)
+{
+ return _ecore_x_xcursor;
+}
+
+Ecore_X_Cursor
+ecore_x_cursor_new(Ecore_X_Window win, int *pixels, int w, int h, int hot_x, int hot_y)
+{
+#ifdef ECORE_XCURSOR
+ if (_ecore_x_xcursor)
+ {
+ Cursor c;
+ XcursorImage *xci;
+
+ xci = XcursorImageCreate(w, h);
+ if (xci)
+ {
+ int i;
+
+ xci->xhot = hot_x;
+ xci->yhot = hot_y;
+ xci->delay = 0;
+ for (i = 0; i < (w * h); i++)
+ {
+ int r, g, b, a;
+
+ a = (pixels[i] >> 24) & 0xff;
+ r = (((pixels[i] >> 16) & 0xff) * a) / 0xff;
+ g = (((pixels[i] >> 8 ) & 0xff) * a) / 0xff;
+ b = (((pixels[i] ) & 0xff) * a) / 0xff;
+ xci->pixels[i] = (a << 24) | (r << 16) | (g << 8) | (b);
+ }
+ c = XcursorImageLoadCursor(_ecore_x_disp, xci);
+ XcursorImageDestroy(xci);
+ return c;
+ }
+ }
+ else
+#endif
+ {
+ XColor c1, c2;
+ Cursor c;
+ Pixmap pmap, mask;
+ GC gc;
+ XGCValues gcv;
+ XImage *xim;
+ unsigned int *pix;
+ int fr, fg, fb, br, bg, bb;
+ int brightest = 0;
+ int darkest = 255 * 3;
+ int x, y;
+ const int dither[2][2] =
+ {
+ {0, 2},
+ {3, 1}
+ };
+
+
+ pmap = XCreatePixmap(_ecore_x_disp, win, w, h, 1);
+ mask = XCreatePixmap(_ecore_x_disp, win, w, h, 1);
+ xim = XCreateImage(_ecore_x_disp,
+ DefaultVisual(_ecore_x_disp, 0),
+ 1, ZPixmap, 0, NULL, w, h, 32, 0);
+ xim->data = malloc(xim->bytes_per_line * xim->height);
+
+ fr = 0x00; fg = 0x00; fb = 0x00;
+ br = 0xff; bg = 0xff; bb = 0xff;
+ pix = pixels;
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int r, g, b, a;
+
+ a = (pix[0] >> 24) & 0xff;
+ r = (pix[0] >> 16) & 0xff;
+ g = (pix[0] >> 8 ) & 0xff;
+ b = (pix[0] ) & 0xff;
+ if (a > 0)
+ {
+ if ((r + g + b) > brightest)
+ {
+ brightest = r + g + b;
+ br = r;
+ bg = g;
+ bb = b;
+ }
+ if ((r + g + b) < darkest)
+ {
+ darkest = r + g + b;
+ fr = r;
+ fg = g;
+ fb = b;
+ }
+ }
+ pix++;
+ }
+ }
+
+ pix = pixels;
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int v;
+ int r, g, b;
+ int d1, d2;
+
+ r = (pix[0] >> 16) & 0xff;
+ g = (pix[0] >> 8 ) & 0xff;
+ b = (pix[0] ) & 0xff;
+ d1 =
+ ((r - fr) * (r - fr)) +
+ ((g - fg) * (g - fg)) +
+ ((b - fb) * (b - fb));
+ d2 =
+ ((r - br) * (r - br)) +
+ ((g - bg) * (g - bg)) +
+ ((b - bb) * (b - bb));
+ v = (((d2 * 255) / (d1 + d2)) * 5) / 256;
+ if (v > dither[x & 0x1][y & 0x1]) v = 1;
+ else v = 0;
+ XPutPixel(xim, x, y, v);
+ pix++;
+ }
+ }
+ gc = XCreateGC(_ecore_x_disp, pmap, 0, &gcv);
+ XPutImage(_ecore_x_disp, pmap, gc, xim, 0, 0, 0, 0, w, h);
+ XFreeGC(_ecore_x_disp, gc);
+
+ pix = pixels;
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int v;
+
+ v = (((pix[0] >> 24) & 0xff) * 5) / 256;
+ if (v > dither[x & 0x1][y & 0x1]) v = 1;
+ else v = 0;
+ XPutPixel(xim, x, y, v);
+ pix++;
+ }
+ }
+ gc = XCreateGC(_ecore_x_disp, mask, 0, &gcv);
+ XPutImage(_ecore_x_disp, mask, gc, xim, 0, 0, 0, 0, w, h);
+ XFreeGC(_ecore_x_disp, gc);
+
+ free(xim->data);
+ xim->data = NULL;
+ XDestroyImage(xim);
+
+ c1.pixel = 0;
+ c1.red = fr << 8 | fr;
+ c1.green = fg << 8 | fg;
+ c1.blue = fb << 8 | fb;
+ c1.flags = DoRed | DoGreen | DoBlue;
+
+ c2.pixel = 0;
+ c2.red = br << 8 | br;
+ c2.green = bg << 8 | bg;
+ c2.blue = bb << 8 | bb;
+ c2.flags = DoRed | DoGreen | DoBlue;
+
+ c = XCreatePixmapCursor(_ecore_x_disp,
+ pmap, mask,
+ &c1, &c2,
+ hot_x, hot_y);
+ XFreePixmap(_ecore_x_disp, pmap);
+ XFreePixmap(_ecore_x_disp, mask);
+ return c;
+ }
+ return 0;
+}
+
+void
+ecore_x_cursor_free(Ecore_X_Cursor c)
+{
+ XFreeCursor(_ecore_x_disp, c);
+}
+
+/*
+ * Returns the cursor for the given shape.
+ * Note that the return value must not be freed with
+ * ecore_x_cursor_free()!
+ */
+Ecore_X_Cursor
+ecore_x_cursor_shape_get(int shape)
+{
+ /* Shapes are defined in Ecore_X_Cursor.h */
+ return XCreateFontCursor(_ecore_x_disp, shape);
+}
+
+int
+ecore_x_pointer_grab(Ecore_X_Window win)
+{
+ return XGrabPointer(_ecore_x_disp, win, False,
+ ButtonPressMask | ButtonReleaseMask |
+ EnterWindowMask | LeaveWindowMask | PointerMotionMask,
+ GrabModeAsync, GrabModeAsync,
+ None, None, CurrentTime);
+}
+
+int
+ecore_x_pointer_confine_grab(Ecore_X_Window win)
+{
+ return XGrabPointer(_ecore_x_disp, win, False,
+ ButtonPressMask | ButtonReleaseMask |
+ EnterWindowMask | LeaveWindowMask | PointerMotionMask,
+ GrabModeAsync, GrabModeAsync,
+ win, None, CurrentTime);
+}
+
+void
+ecore_x_pointer_ungrab(void)
+{
+ XUngrabPointer(_ecore_x_disp, CurrentTime);
+}
+
+int
+ecore_x_pointer_warp(Ecore_X_Window win, int x, int y)
+{
+ return XWarpPointer(_ecore_x_disp, None, win, 0, 0, 0, 0, x, y);
+}
+
+int
+ecore_x_keyboard_grab(Ecore_X_Window win)
+{
+ return XGrabKeyboard(_ecore_x_disp, win, False,
+ GrabModeAsync, GrabModeAsync,
+ CurrentTime);
+}
+
+void ecore_x_keyboard_ungrab(void)
+{
+ XUngrabKeyboard(_ecore_x_disp, CurrentTime);
+}
+
+void
+ecore_x_grab(void)
+{
+ _ecore_x_grab_count++;
+
+ if (_ecore_x_grab_count == 1)
+ XGrabServer(_ecore_x_disp);
+}
+
+void
+ecore_x_ungrab(void)
+{
+ _ecore_x_grab_count--;
+ if (_ecore_x_grab_count < 0)
+ _ecore_x_grab_count = 0;
+
+ if (_ecore_x_grab_count == 0)
+ {
+ XUngrabServer(_ecore_x_disp);
+ XSync(_ecore_x_disp, False);
+ }
+}
+
+int _ecore_window_grabs_num = 0;
+Window *_ecore_window_grabs = NULL;
+int (*_ecore_window_grab_replay_func) (void *data, int event_type, void *event);
+void *_ecore_window_grab_replay_data;
+
+void
+ecore_x_passive_grab_replay_func_set(int (*func) (void *data, int event_type, void *event), void *data)
+{
+ _ecore_window_grab_replay_func = func;
+ _ecore_window_grab_replay_data = data;
+}
+
+void
+ecore_x_window_button_grab(Ecore_X_Window win, int button,
+ Ecore_X_Event_Mask event_mask,
+ int mod, int any_mod)
+{
+ unsigned int b;
+ unsigned int m;
+ unsigned int locks[8];
+ int i, ev;
+
+ b = button;
+ if (b == 0) b = AnyButton;
+ m = mod;
+ if (any_mod) m = AnyModifier;
+ locks[0] = 0;
+ locks[1] = ECORE_X_LOCK_CAPS;
+ locks[2] = ECORE_X_LOCK_NUM;
+ locks[3] = ECORE_X_LOCK_SCROLL;
+ locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
+ locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
+ locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ ev = event_mask;
+ for (i = 0; i < 8; i++)
+ XGrabButton(_ecore_x_disp, b, m | locks[i],
+ win, False, ev, GrabModeSync, GrabModeAsync, None, None);
+ _ecore_window_grabs_num++;
+ _ecore_window_grabs = realloc(_ecore_window_grabs,
+ _ecore_window_grabs_num * sizeof(Window));
+ _ecore_window_grabs[_ecore_window_grabs_num - 1] = win;
+}
+
+void
+_ecore_x_sync_magic_send(int val, Ecore_X_Window swin)
+{
+ XEvent xev;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = _ecore_x_private_win;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = 27777;
+ xev.xclient.data.l[0] = 0x7162534;
+ xev.xclient.data.l[1] = 0x10000000 + val;
+ xev.xclient.data.l[2] = swin;
+ XSendEvent(_ecore_x_disp, _ecore_x_private_win, False, NoEventMask, &xev);
+}
+
+void
+_ecore_x_window_grab_remove(Ecore_X_Window win)
+{
+ int i, shuffle = 0;
+
+ if (_ecore_window_grabs_num > 0)
+ {
+ for (i = 0; i < _ecore_window_grabs_num; i++)
+ {
+ if (shuffle) _ecore_window_grabs[i - 1] = _ecore_window_grabs[i];
+ if ((!shuffle) && (_ecore_window_grabs[i] == win))
+ shuffle = 1;
+ }
+ if (shuffle)
+ {
+ _ecore_window_grabs_num--;
+ _ecore_window_grabs = realloc(_ecore_window_grabs,
+ _ecore_window_grabs_num * sizeof(Window));
+ }
+ }
+}
+
+void
+ecore_x_window_button_ungrab(Ecore_X_Window win, int button,
+ int mod, int any_mod)
+{
+ unsigned int b;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+
+ b = button;
+ if (b == 0) b = AnyButton;
+ m = mod;
+ if (any_mod) m = AnyModifier;
+ locks[0] = 0;
+ locks[1] = ECORE_X_LOCK_CAPS;
+ locks[2] = ECORE_X_LOCK_NUM;
+ locks[3] = ECORE_X_LOCK_SCROLL;
+ locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
+ locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
+ locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ for (i = 0; i < 8; i++)
+ XUngrabButton(_ecore_x_disp, b, m | locks[i], win);
+ _ecore_x_sync_magic_send(1, win);
+}
+
+int _ecore_key_grabs_num = 0;
+Window *_ecore_key_grabs = NULL;
+
+void
+ecore_x_window_key_grab(Ecore_X_Window win, char *key,
+ int mod, int any_mod)
+{
+ KeyCode keycode = 0;
+ KeySym keysym;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ else
+ {
+ keysym = XStringToKeysym(key);
+ if (keysym == NoSymbol) return;
+ keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
+ }
+ if (keycode == 0) return;
+
+ m = mod;
+ if (any_mod) m = AnyModifier;
+ locks[0] = 0;
+ locks[1] = ECORE_X_LOCK_CAPS;
+ locks[2] = ECORE_X_LOCK_NUM;
+ locks[3] = ECORE_X_LOCK_SCROLL;
+ locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
+ locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
+ locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ for (i = 0; i < 8; i++)
+ XGrabKey(_ecore_x_disp, keycode, m | locks[i],
+ win, True, GrabModeSync, GrabModeAsync);
+ _ecore_key_grabs_num++;
+ _ecore_key_grabs = realloc(_ecore_key_grabs,
+ _ecore_key_grabs_num * sizeof(Window));
+ _ecore_key_grabs[_ecore_key_grabs_num - 1] = win;
+}
+
+void
+_ecore_x_key_grab_remove(Ecore_X_Window win)
+{
+ int i, shuffle = 0;
+
+ if (_ecore_key_grabs_num > 0)
+ {
+ for (i = 0; i < _ecore_key_grabs_num; i++)
+ {
+ if (shuffle) _ecore_key_grabs[i - 1] = _ecore_key_grabs[i];
+ if ((!shuffle) && (_ecore_key_grabs[i] == win))
+ shuffle = 1;
+ }
+ if (shuffle)
+ {
+ _ecore_key_grabs_num--;
+ _ecore_key_grabs = realloc(_ecore_key_grabs,
+ _ecore_key_grabs_num * sizeof(Window));
+ }
+ }
+}
+
+void
+ecore_x_window_key_ungrab(Ecore_X_Window win, char *key,
+ int mod, int any_mod)
+{
+ KeyCode keycode = 0;
+ KeySym keysym;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ else
+ {
+ keysym = XStringToKeysym(key);
+ if (keysym == NoSymbol) return;
+ keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
+ }
+ if (keycode == 0) return;
+
+ m = mod;
+ if (any_mod) m = AnyModifier;
+ locks[0] = 0;
+ locks[1] = ECORE_X_LOCK_CAPS;
+ locks[2] = ECORE_X_LOCK_NUM;
+ locks[3] = ECORE_X_LOCK_SCROLL;
+ locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
+ locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
+ locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ for (i = 0; i < 8; i++)
+ XUngrabKey(_ecore_x_disp, keycode, m | locks[i], win);
+ _ecore_x_sync_magic_send(2, win);
+}
+
+/**
+ * Send client message with given type and format 32.
+ *
+ * @param win The window the message is sent to.
+ * @param type The client message type.
+ * @param d0 The client message data item 1
+ * @param d1 The client message data item 2
+ * @param d2 The client message data item 3
+ * @param d3 The client message data item 4
+ * @param d4 The client message data item 5
+ *
+ * @return !0 on success.
+ */
+int
+ecore_x_client_message32_send(Ecore_X_Window win, Ecore_X_Atom type,
+ Ecore_X_Event_Mask mask,
+ long d0, long d1, long d2, long d3, long d4)
+{
+ XEvent xev;
+
+ xev.xclient.window = win;
+ xev.xclient.type = ClientMessage;
+ xev.xclient.message_type = type;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = d0;
+ xev.xclient.data.l[1] = d1;
+ xev.xclient.data.l[2] = d2;
+ xev.xclient.data.l[3] = d3;
+ xev.xclient.data.l[4] = d4;
+
+ return XSendEvent(_ecore_x_disp, win, False, mask, &xev);
+}
+
+/**
+ * Send client message with given type and format 8.
+ *
+ * @param win The window the message is sent to.
+ * @param type The client message type.
+ * @param data Data to be sent.
+ * @param len Number of data bytes, max 20.
+ *
+ * @return !0 on success.
+ */
+int
+ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type,
+ const void *data, int len)
+{
+ XEvent xev;
+
+ xev.xclient.window = win;
+ xev.xclient.type = ClientMessage;
+ xev.xclient.message_type = type;
+ xev.xclient.format = 8;
+ if (len > 20)
+ len = 20;
+ memcpy(xev.xclient.data.b, data, len);
+ memset(xev.xclient.data.b + len, 0, 20 - len);
+
+ return XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
+}
+
+void
+ecore_x_focus_reset(void)
+{
+ XSetInputFocus(_ecore_x_disp, PointerRoot, RevertToPointerRoot, CurrentTime);
+}
+
+void
+ecore_x_events_allow_all(void)
+{
+ XAllowEvents(_ecore_x_disp, AsyncBoth, CurrentTime);
+}
+
+void
+ecore_x_pointer_last_xy_get(int *x, int *y)
+{
+ if (x) *x = _ecore_x_event_last_root_x;
+ if (y) *y = _ecore_x_event_last_root_y;
+}
+
+void
+ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y)
+{
+ Window rwin, cwin;
+ int rx, ry, wx, wy;
+ unsigned int mask;
+
+ XQueryPointer(_ecore_x_disp, win, &rwin, &cwin, &rx, &ry, &wx, &wy, &mask);
+ if (x) *x = wx;
+ if (y) *y = wy;
+}
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
diff --git a/ecore/src/lib/ecore_x/ecore_x_dnd.c b/ecore/src/lib/ecore_x/ecore_x_dnd.c
new file mode 100644
index 0000000..84f3357
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_dnd.c
@@ -0,0 +1,405 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+static Ecore_X_DND_Source *_source = NULL;
+static Ecore_X_DND_Target *_target = NULL;
+static int _ecore_x_dnd_init_count = 0;
+
+void
+_ecore_x_dnd_init(void)
+{
+ if (!_ecore_x_dnd_init_count)
+ {
+ _source = calloc(1, sizeof(Ecore_X_DND_Source));
+ _source->version = ECORE_X_DND_VERSION;
+ _source->win = None;
+ _source->dest = None;
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+
+ _target = calloc(1, sizeof(Ecore_X_DND_Target));
+ _target->win = None;
+ _target->source = None;
+ _target->state = ECORE_X_DND_TARGET_IDLE;
+ }
+
+ _ecore_x_dnd_init_count++;
+}
+
+void
+_ecore_x_dnd_shutdown(void)
+{
+ _ecore_x_dnd_init_count--;
+ if (_ecore_x_dnd_init_count > 0)
+ return;
+
+ if (_source)
+ free(_source);
+ _source = NULL;
+
+ if (_target)
+ free(_target);
+ _target = NULL;
+
+ _ecore_x_dnd_init_count = 0;
+}
+
+void
+ecore_x_dnd_aware_set(Ecore_X_Window win, int on)
+{
+ Ecore_X_Atom prop_data = ECORE_X_DND_VERSION;
+
+ if (on)
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_AWARE,
+ XA_ATOM, 32, &prop_data, 1);
+ else
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_AWARE);
+}
+
+int
+ecore_x_dnd_version_get(Ecore_X_Window win)
+{
+ unsigned char *prop_data;
+ int num;
+
+ if (ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_AWARE,
+ XA_ATOM, 32, &prop_data, &num))
+ {
+ int version = (int) *prop_data;
+ free(prop_data);
+ return version;
+ }
+ else
+ return 0;
+}
+
+int
+ecore_x_dnd_type_isset(Ecore_X_Window win, const char *type)
+{
+ int num, i, ret = 0;
+ unsigned char *data;
+ Ecore_X_Atom *atoms, atom;
+
+ if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, &data, &num))
+ return ret;
+
+ atom = ecore_x_atom_get(type);
+ atoms = (Ecore_X_Atom *)data;
+
+ for (i = 0; i < num; ++i)
+ {
+ if (atom == atoms[i])
+ {
+ ret = 1;
+ break;
+ }
+ }
+
+ XFree(data);
+ return ret;
+}
+
+void
+ecore_x_dnd_type_set(Ecore_X_Window win, const char *type, int on)
+{
+ Ecore_X_Atom atom;
+ Ecore_X_Atom *oldset = NULL, *newset = NULL;
+ int i, j = 0, num = 0;
+ unsigned char *data = NULL;
+ unsigned char *old_data = NULL;
+
+ atom = ecore_x_atom_get(type);
+ ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, &old_data, &num);
+ oldset = (Ecore_X_Atom *)old_data;
+
+ if (on)
+ {
+ if (ecore_x_dnd_type_isset(win, type))
+ {
+ XFree(old_data);
+ return;
+ }
+ newset = calloc(num + 1, sizeof(Ecore_X_Atom));
+ if (!newset) return;
+ data = (unsigned char *)newset;
+
+ for (i = 0; i < num; i++)
+ newset[i + 1] = oldset[i];
+ /* prepend the new type */
+ newset[0] = atom;
+
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, data, num + 1);
+ }
+ else
+ {
+ if (!ecore_x_dnd_type_isset(win, type))
+ {
+ XFree(old_data);
+ return;
+ }
+ newset = calloc(num - 1, sizeof(Ecore_X_Atom));
+ if (!newset)
+ {
+ XFree(old_data);
+ return;
+ }
+ data = (unsigned char *)newset;
+ for (i = 0; i < num; i++)
+ if (oldset[i] != atom)
+ newset[j++] = oldset[i];
+
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, data, num - 1);
+ }
+ XFree(oldset);
+ free(newset);
+}
+
+Ecore_X_DND_Source *
+_ecore_x_dnd_source_get(void)
+{
+ return _source;
+}
+
+Ecore_X_DND_Target *
+_ecore_x_dnd_target_get(void)
+{
+ return _target;
+}
+
+int
+ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size)
+{
+
+ if (!ecore_x_dnd_version_get(source))
+ return 0;
+
+ /* Take ownership of XdndSelection */
+ if (!ecore_x_selection_xdnd_set(source, data, size))
+ return 0;
+
+ _source->win = source;
+ printf("source: 0x%x\n", source);
+ _source->state = ECORE_X_DND_SOURCE_DRAGGING;
+ _source->time = _ecore_x_event_last_time;
+
+ /* Default Accepted Action: ask */
+ _source->action = ECORE_X_ATOM_XDND_ACTION_ASK;
+ _source->accepted_action = None;
+ return 1;
+}
+
+void
+ecore_x_dnd_drop(void)
+{
+ XEvent xev;
+
+ if (_source->dest)
+ {
+ xev.xany.type = ClientMessage;
+ xev.xany.display = _ecore_x_disp;
+ xev.xclient.format = 32;
+ xev.xclient.window = _source->dest;
+
+ if (_source->will_accept)
+ {
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_DROP;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0;
+ xev.xclient.data.l[2] = _source->time;
+ XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev);
+ _source->state = ECORE_X_DND_SOURCE_DROPPED;
+ }
+ else
+ {
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0;
+ XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev);
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+ }
+ else
+ {
+ /* Dropping on nothing */
+ ecore_x_selection_xdnd_clear();
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+}
+
+void
+ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectangle, Ecore_X_Atom action)
+{
+ XEvent xev;
+
+ if (_target->state == ECORE_X_DND_TARGET_IDLE)
+ return;
+
+ memset(&xev, 0, sizeof(XEvent));
+
+ _target->will_accept = will_accept;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_STATUS;
+ xev.xclient.format = 32;
+ xev.xclient.window = _target->source;
+
+ xev.xclient.data.l[0] = _target->win;
+ xev.xclient.data.l[1] = 0;
+ if (will_accept)
+ xev.xclient.data.l[1] |= 0x1UL;
+ if (!suppress)
+ xev.xclient.data.l[1] |= 0x2UL;
+
+ /* Set rectangle information */
+ xev.xclient.data.l[2] = rectangle.x;
+ xev.xclient.data.l[2] <<= 16;
+ xev.xclient.data.l[2] |= rectangle.y;
+ xev.xclient.data.l[3] = rectangle.width;
+ xev.xclient.data.l[3] <<= 16;
+ xev.xclient.data.l[3] |= rectangle.height;
+
+ if (will_accept)
+ {
+ xev.xclient.data.l[4] = action;
+ _target->accepted_action = action;
+ }
+ else
+ {
+ xev.xclient.data.l[4] = None;
+ _target->accepted_action = action;
+ }
+
+ XSendEvent(_ecore_x_disp, _target->source, False, 0, &xev);
+}
+
+void
+ecore_x_dnd_send_finished(void)
+{
+ XEvent xev;
+
+ if (_target->state == ECORE_X_DND_TARGET_IDLE)
+ return;
+
+ xev.xany.type = ClientMessage;
+ xev.xany.display = _ecore_x_disp;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_FINISHED;
+ xev.xclient.format = 32;
+ xev.xclient.window = _target->source;
+
+ xev.xclient.data.l[0] = _target->win;
+ xev.xclient.data.l[1] = 0;
+ xev.xclient.data.l[2] = 0;
+ if (_target->will_accept)
+ {
+ xev.xclient.data.l[1] |= 0x1UL;
+ xev.xclient.data.l[2] = _target->accepted_action;
+ }
+ XSendEvent(_ecore_x_disp, _target->source, False, 0, &xev);
+
+ _target->state = ECORE_X_DND_TARGET_IDLE;
+}
+
+void
+_ecore_x_dnd_drag(int x, int y)
+{
+ XEvent xev;
+ Ecore_X_Window win;
+
+ if (_source->state != ECORE_X_DND_SOURCE_DRAGGING)
+ return;
+
+ /* Preinitialize XEvent struct */
+ memset(&xev, 0, sizeof(XEvent));
+ xev.xany.type = ClientMessage;
+ xev.xany.display = _ecore_x_disp;
+ xev.xclient.format = 32;
+
+ /* Attempt to find a DND-capable window under the cursor */
+ win = ecore_x_window_at_xy_get(x, y);
+ while ((win) && !(ecore_x_dnd_version_get(win)))
+ win = ecore_x_window_parent_get(win);
+
+ /* Send XdndLeave to current destination window if we have left it */
+ if ((_source->dest) && (win != _source->dest))
+ {
+ xev.xclient.window = _source->dest;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0;
+
+ XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev);
+ _source->suppress = 0;
+ }
+
+ if (win)
+ {
+ int x1, x2, y1, y2;
+
+ _source->version = MIN(ECORE_X_DND_VERSION,
+ ecore_x_dnd_version_get(win));
+ if (win != _source->dest)
+ {
+ int i, num;
+ unsigned char *data;
+ Ecore_X_Atom *types;
+
+ ecore_x_window_prop_property_get(_source->win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, &data, &num);
+ types = (Ecore_X_Atom *)data;
+
+ /* Entered new window, send XdndEnter */
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_ENTER;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0;
+ if (num > 3)
+ xev.xclient.data.l[1] |= 0x1UL;
+ else
+ xev.xclient.data.l[1] &= 0xfffffffeUL;
+ xev.xclient.data.l[1] |= ((unsigned long) _source->version) << 24;
+
+ for (i = 2; i < 5; i++)
+ xev.xclient.data.l[i] = 0;
+ for (i = 0; i < MIN(num, 3); ++i)
+ xev.xclient.data.l[i + 2] = types[i];
+ XFree(data);
+ XSendEvent(_ecore_x_disp, win, False, 0, &xev);
+ _source->await_status = 0;
+ }
+
+ /* Determine if we're still in the rectangle from the last status */
+ x1 = _source->rectangle.x;
+ x2 = _source->rectangle.x + _source->rectangle.width;
+ y1 = _source->rectangle.y;
+ y2 = _source->rectangle.y + _source->rectangle.height;
+
+ if (!(_source->await_status)
+ || !(_source->suppress)
+ || ((x < x1) || (x > x2)
+ || (y < y1) || (y > y2)))
+ {
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_POSITION;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0; /* Reserved */
+ xev.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
+ xev.xclient.data.l[3] = _source->time; /* Version 1 */
+ xev.xclient.data.l[4] = _source->action; /* Version 2, Needs to be pre-set */
+ XSendEvent(_ecore_x_disp, win, False, 0, &xev);
+
+ _source->await_status = 1;
+ }
+ }
+
+ _source->dest = win;
+}
+
diff --git a/ecore/src/lib/ecore_x/ecore_x_e.c b/ecore/src/lib/ecore_x/ecore_x_e.c
new file mode 100644
index 0000000..398f4cc
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_e.c
@@ -0,0 +1,37 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+/*
+ * OLD E hints
+ */
+#include "config.h"
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+/*
+ * Convenience macros
+ */
+#define _ATOM_GET(name) \
+ XInternAtom(_ecore_x_disp, name, False)
+
+Ecore_X_Atom ECORE_X_ATOM_E_FRAME_SIZE = 0;
+
+void
+ecore_x_e_init(void)
+{
+ ECORE_X_ATOM_E_FRAME_SIZE = _ATOM_GET("_E_FRAME_SIZE");
+}
+
+void
+ecore_x_e_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb)
+{
+ unsigned int frames[4];
+
+ frames[0] = fl;
+ frames[1] = fr;
+ frames[2] = ft;
+ frames[3] = fb;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_FRAME_SIZE, frames, 4);
+}
diff --git a/ecore/src/lib/ecore_x/ecore_x_error.c b/ecore/src/lib/ecore_x/ecore_x_error.c
new file mode 100644
index 0000000..4307da0
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_error.c
@@ -0,0 +1,95 @@
+#include "ecore_private.h"
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+static void _ecore_x_error_handle(Display * d, XErrorEvent * ev);
+static int _ecore_x_io_error_handle(Display *d);
+
+static void (*_error_func) (void *data) = NULL;
+static void *_error_data = NULL;
+static void (*_io_error_func) (void *data) = NULL;
+static void *_io_error_data = NULL;
+static int _error_request_code = 0;
+static int _error_code = 0;
+
+/**
+ * Set the error handler.
+ * @param func The error handler function
+ * @param data The data to be passed to the handler function
+ *
+ * Set the X error handler function
+ */
+void
+ecore_x_error_handler_set(void (*func) (void *data), const void *data)
+{
+ _error_func = func;
+ _error_data = (void *)data;
+}
+
+/**
+ * Set the I/O error handler.
+ * @param func The I/O error handler function
+ * @param data The data to be passed to the handler function
+ *
+ * Set the X I/O error handler function
+ */
+void
+ecore_x_io_error_handler_set(void (*func) (void *data), const void *data)
+{
+ _io_error_func = func;
+ _io_error_data = (void *)data;
+}
+
+/**
+ * Get the request code that caused the error.
+ * @return The request code causing the X error
+ *
+ * Return the X request code that caused the last X error
+ */
+int
+ecore_x_error_request_get(void)
+{
+ return _error_request_code;
+}
+
+/**
+ * Get the error code from the error.
+ * @return The error code from the X error
+ *
+ * Return the error code from the last X error
+ */
+int
+ecore_x_error_code_get(void)
+{
+ return _error_code;
+}
+
+void
+_ecore_x_error_handler_init(void)
+{
+ XSetErrorHandler((XErrorHandler)_ecore_x_error_handle);
+ XSetIOErrorHandler((XIOErrorHandler)_ecore_x_io_error_handle);
+}
+
+static void
+_ecore_x_error_handle(Display *d, XErrorEvent *ev)
+{
+ if (d == _ecore_x_disp)
+ {
+ _error_request_code = ev->request_code;
+ _error_code = ev->error_code;
+ if (_error_func) _error_func(_error_data);
+ }
+}
+
+static int
+_ecore_x_io_error_handle(Display *d)
+{
+ if (d == _ecore_x_disp)
+ {
+ if (_io_error_func) _io_error_func(_io_error_data);
+ else exit(-1);
+ }
+ return 0;
+}
diff --git a/ecore/src/lib/ecore_x/ecore_x_events.c b/ecore/src/lib/ecore_x/ecore_x_events.c
new file mode 100644
index 0000000..5668442
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_events.c
@@ -0,0 +1,1565 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "ecore_private.h"
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+#if 0
+static void _ecore_x_event_free_window_prop_name_class_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_title_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev);
+#endif
+static void _ecore_x_event_free_key_down(void *data, void *ev);
+static void _ecore_x_event_free_key_up(void *data, void *ev);
+
+void
+ecore_x_event_mask_set(Ecore_X_Window w, Ecore_X_Event_Mask mask)
+{
+ XWindowAttributes attr;
+ XSetWindowAttributes s_attr;
+
+ if (!w)
+ w = DefaultRootWindow(_ecore_x_disp);
+
+ memset(&attr, 0, sizeof(XWindowAttributes));
+ XGetWindowAttributes(_ecore_x_disp, w, &attr);
+ s_attr.event_mask = mask | attr.your_event_mask;
+ XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr);
+}
+
+void
+ecore_x_event_mask_unset(Ecore_X_Window w, Ecore_X_Event_Mask mask)
+{
+ XWindowAttributes attr;
+ XSetWindowAttributes s_attr;
+
+ if (!w)
+ w = DefaultRootWindow(_ecore_x_disp);
+
+ memset(&attr, 0, sizeof(XWindowAttributes));
+ XGetWindowAttributes(_ecore_x_disp, w, &attr);
+ s_attr.event_mask = attr.your_event_mask & ~mask;
+ XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr);
+}
+
+#if 0
+static void
+_ecore_x_event_free_window_prop_name_class_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Name_Class_Change *e;
+
+ e = ev;
+ if (e->name) free(e->name);
+ if (e->clas) free(e->clas);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_title_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Title_Change *e;
+
+ e = ev;
+ if (e->title) free(e->title);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
+
+ e = ev;
+ if (e->title) free(e->title);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
+
+ e = ev;
+ if (e->name) free(e->name);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
+
+ e = ev;
+ if (e->name) free(e->name);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
+
+ e = ev;
+ if (e->name) free(e->name);
+ free(e);
+}
+#endif
+
+static void
+_ecore_x_event_free_key_down(void *data __UNUSED__, void *ev)
+{
+ Ecore_X_Event_Key_Down *e;
+
+ e = ev;
+ if (e->keyname) free(e->keyname);
+ if (e->keysymbol) free(e->keysymbol);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_key_up(void *data __UNUSED__, void *ev)
+{
+ Ecore_X_Event_Key_Up *e;
+
+ e = ev;
+ if (e->keyname) free(e->keyname);
+ if (e->keysymbol) free(e->keysymbol);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_xdnd_enter(void *data __UNUSED__, void *ev)
+{
+ Ecore_X_Event_Xdnd_Enter *e;
+ int i;
+
+ e = ev;
+ for (i = 0; i < e->num_types; i++)
+ XFree(e->types[i]);
+ free(e->types);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_selection_notify(void *data __UNUSED__, void *ev)
+{
+ Ecore_X_Event_Selection_Notify *e;
+ Ecore_X_Selection_Data *sel;
+
+ e = ev;
+ sel = e->data;
+ if (sel->free)
+ sel->free(sel);
+ free(e->target);
+ free(e);
+}
+
+void
+_ecore_x_event_handle_key_press(XEvent *xevent)
+{
+ Ecore_X_Event_Key_Down *e;
+ char *keyname;
+ int val;
+ char buf[256];
+ KeySym sym;
+ XComposeStatus stat;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Key_Down));
+ if (!e) return;
+ keyname = XKeysymToString(XKeycodeToKeysym(xevent->xkey.display,
+ xevent->xkey.keycode, 0));
+ if (!keyname)
+ {
+ snprintf(buf, sizeof(buf), "Keycode-%i", xevent->xkey.keycode);
+ keyname = buf;
+ }
+ e->keyname = strdup(keyname);
+ if (!e->keyname)
+ {
+ free(e);
+ return;
+ }
+ val = XLookupString((XKeyEvent *)xevent, buf, sizeof(buf), &sym, &stat);
+ if (val > 0)
+ {
+ buf[val] = 0;
+ e->key_compose = ecore_txt_convert("LATIN1", "UTF-8", buf);
+ }
+ else e->key_compose = NULL;
+ keyname = XKeysymToString(sym);
+ if (keyname) e->keysymbol = strdup(keyname);
+ else e->keysymbol = strdup(e->keyname);
+ if (!e->keysymbol)
+ {
+ if (e->keyname) free(e->keyname);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+ return;
+ }
+ if (xevent->xkey.subwindow) e->win = xevent->xkey.subwindow;
+ else e->win = xevent->xkey.window;
+ e->event_win = xevent->xkey.window;
+ e->time = xevent->xkey.time;
+ e->modifiers = xevent->xkey.state;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_KEY_DOWN, e, _ecore_x_event_free_key_down, NULL);
+}
+
+void
+_ecore_x_event_handle_key_release(XEvent *xevent)
+{
+ Ecore_X_Event_Key_Up *e;
+ char *keyname;
+ int val;
+ char buf[256];
+ KeySym sym;
+ XComposeStatus stat;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Key_Up));
+ if (!e) return;
+ keyname = XKeysymToString(XKeycodeToKeysym(xevent->xkey.display,
+ xevent->xkey.keycode, 0));
+ if (!keyname)
+ {
+ snprintf(buf, sizeof(buf), "Keycode-%i", xevent->xkey.keycode);
+ keyname = buf;
+ }
+ e->keyname = strdup(keyname);
+ if (!e->keyname)
+ {
+ free(e);
+ return;
+ }
+ val = XLookupString((XKeyEvent *)xevent, buf, sizeof(buf), &sym, &stat);
+ if (val > 0)
+ {
+ buf[val] = 0;
+ e->key_compose = ecore_txt_convert("LATIN1", "UTF-8", buf);
+ }
+ else e->key_compose = NULL;
+ keyname = XKeysymToString(sym);
+ if (keyname) e->keysymbol = strdup(keyname);
+ else e->keysymbol = strdup(e->keyname);
+ if (!e->keysymbol)
+ {
+ if (e->keyname) free(e->keyname);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+ return;
+ }
+ if (xevent->xkey.subwindow) e->win = xevent->xkey.subwindow;
+ else e->win = xevent->xkey.window;
+ e->event_win = xevent->xkey.window;
+ e->time = xevent->xkey.time;
+ e->modifiers = xevent->xkey.state;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_KEY_UP, e, _ecore_x_event_free_key_up, NULL);
+}
+
+void
+_ecore_x_event_handle_button_press(XEvent *xevent)
+{
+ static Window last_win = 0;
+ static Window last_last_win = 0;
+ static Window last_event_win = 0;
+ static Window last_last_event_win = 0;
+ static Time last_time = 0;
+ static Time last_last_time = 0;
+ int did_triple = 0;
+ int i;
+
+ if ((xevent->xbutton.button > 3) && (xevent->xbutton.button < 6))
+ {
+ Ecore_X_Event_Mouse_Wheel *e;
+
+ e = malloc(sizeof(Ecore_X_Event_Mouse_Wheel));
+
+ if (!e)
+ return;
+
+ e->modifiers = 0;
+ e->direction = 0;
+ e->z = 0;
+ if (xevent->xbutton.button == 4) e->z = -1;
+ else if (xevent->xbutton.button == 5) e->z = 1;
+ e->x = xevent->xbutton.x;
+ e->y = xevent->xbutton.y;
+ e->root.x = xevent->xbutton.x_root;
+ e->root.y = xevent->xbutton.y_root;
+
+ if (xevent->xbutton.subwindow)
+ e->win = xevent->xbutton.subwindow;
+ else
+ e->win = xevent->xbutton.window;
+
+ e->event_win = xevent->xbutton.window;
+ e->time = xevent->xbutton.time;
+ _ecore_x_event_last_time = e->time;
+ _ecore_x_event_last_win = e->win;
+ _ecore_x_event_last_root_x = e->root.x;
+ _ecore_x_event_last_root_y = e->root.y;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_WHEEL, e, NULL, NULL);
+ for (i = 0; i < _ecore_window_grabs_num; i++)
+ {
+ if ((_ecore_window_grabs[i] == xevent->xbutton.window) ||
+ (_ecore_window_grabs[i] == xevent->xbutton.subwindow))
+ {
+ int replay = 0;
+
+ if (_ecore_window_grab_replay_func)
+ replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data,
+ ECORE_X_EVENT_MOUSE_WHEEL,
+ e);
+ if (replay)
+ XAllowEvents(xevent->xbutton.display,
+ ReplayPointer,
+ xevent->xbutton.time);
+ else
+ XAllowEvents(xevent->xbutton.display,
+ AsyncPointer,
+ xevent->xbutton.time);
+ break;
+ }
+ }
+ }
+ else
+ {
+ {
+ Ecore_X_Event_Mouse_Move *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
+ if (!e) return;
+ e->modifiers = xevent->xbutton.state;
+ e->x = xevent->xbutton.x;
+ e->y = xevent->xbutton.y;
+ e->root.x = xevent->xbutton.x_root;
+ e->root.y = xevent->xbutton.y_root;
+ if (xevent->xbutton.subwindow) e->win = xevent->xbutton.subwindow;
+ else e->win = xevent->xbutton.window;
+ e->event_win = xevent->xbutton.window;
+ e->time = xevent->xbutton.time;
+ _ecore_x_event_last_time = e->time;
+ _ecore_x_event_last_win = e->win;
+ _ecore_x_event_last_root_x = e->root.x;
+ _ecore_x_event_last_root_y = e->root.y;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+ {
+ Ecore_X_Event_Mouse_Button_Down *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_Button_Down));
+ if (!e) return;
+ e->button = xevent->xbutton.button;
+ e->modifiers = xevent->xbutton.state;
+ e->x = xevent->xbutton.x;
+ e->y = xevent->xbutton.y;
+ e->root.x = xevent->xbutton.x_root;
+ e->root.y = xevent->xbutton.y_root;
+ if (xevent->xbutton.subwindow) e->win = xevent->xbutton.subwindow;
+ else e->win = xevent->xbutton.window;
+ e->event_win = xevent->xbutton.window;
+ e->time = xevent->xbutton.time;
+ if (e->win == e->event_win)
+ {
+ if (((int)(e->time - last_time) <=
+ (int)(1000 * _ecore_x_double_click_time)) &&
+ (e->win == last_win)
+ && (e->event_win == last_event_win)
+ )
+ e->double_click = 1;
+ if (((int)(e->time - last_last_time) <=
+ (int)(2 * 1000 * _ecore_x_double_click_time)) &&
+ (e->win == last_win) && (e->win == last_last_win)
+ && (e->event_win == last_event_win) && (e->event_win == last_last_event_win)
+ )
+ {
+ did_triple = 1;
+ e->triple_click = 1;
+ }
+ }
+ _ecore_x_event_last_time = e->time;
+ _ecore_x_event_last_win = e->win;
+ _ecore_x_event_last_root_x = e->root.x;
+ _ecore_x_event_last_root_y = e->root.y;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
+ for (i = 0; i < _ecore_window_grabs_num; i++)
+ {
+ if ((_ecore_window_grabs[i] == xevent->xbutton.window) ||
+ (_ecore_window_grabs[i] == xevent->xbutton.subwindow))
+ {
+ int replay = 0;
+
+ if (_ecore_window_grab_replay_func)
+ replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data,
+ ECORE_X_EVENT_MOUSE_BUTTON_DOWN,
+ e);
+ if (replay)
+ XAllowEvents(xevent->xbutton.display,
+ ReplayPointer,
+ xevent->xbutton.time);
+ else
+ XAllowEvents(xevent->xbutton.display,
+ AsyncPointer,
+ xevent->xbutton.time);
+ break;
+ }
+ }
+ if (e->win == e->event_win)
+ {
+ if (did_triple)
+ {
+ last_win = 0;
+ last_last_win = 0;
+ last_event_win = 0;
+ last_last_event_win = 0;
+ last_time = 0;
+ last_last_time = 0;
+ }
+ else
+ {
+ last_last_win = last_win;
+ if (xevent->xbutton.subwindow)
+ last_win = xevent->xbutton.subwindow;
+ else
+ last_win = xevent->xbutton.window;
+ last_last_event_win = last_event_win;
+ last_event_win = xevent->xbutton.window;
+ last_last_time = last_time;
+ last_time = xevent->xbutton.time;
+ }
+ }
+ }
+ }
+}
+
+void
+_ecore_x_event_handle_button_release(XEvent *xevent)
+{
+ /* filter out wheel buttons */
+ if (xevent->xbutton.button <= 3)
+ {
+ {
+ Ecore_X_Event_Mouse_Move *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
+ if (!e) return;
+ e->modifiers = xevent->xbutton.state;
+ e->x = xevent->xbutton.x;
+ e->y = xevent->xbutton.y;
+ e->root.x = xevent->xbutton.x_root;
+ e->root.y = xevent->xbutton.y_root;
+ if (xevent->xbutton.subwindow) e->win = xevent->xbutton.subwindow;
+ else e->win = xevent->xbutton.window;
+ e->event_win = xevent->xbutton.window;
+ e->time = xevent->xbutton.time;
+ _ecore_x_event_last_time = e->time;
+ _ecore_x_event_last_win = e->win;
+ _ecore_x_event_last_root_x = e->root.x;
+ _ecore_x_event_last_root_y = e->root.y;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+ {
+ Ecore_X_Event_Mouse_Button_Up *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_Button_Up));
+ if (!e) return;
+ e->button = xevent->xbutton.button;
+ e->modifiers = xevent->xbutton.state;
+ e->x = xevent->xbutton.x;
+ e->y = xevent->xbutton.y;
+ e->root.x = xevent->xbutton.x_root;
+ e->root.y = xevent->xbutton.y_root;
+ if (xevent->xbutton.subwindow) e->win = xevent->xbutton.subwindow;
+ else e->win = xevent->xbutton.window;
+ e->event_win = xevent->xbutton.window;
+ e->time = xevent->xbutton.time;
+ _ecore_x_event_last_time = e->time;
+ _ecore_x_event_last_win = e->win;
+ _ecore_x_event_last_root_x = e->root.x;
+ _ecore_x_event_last_root_y = e->root.y;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
+ }
+ }
+}
+
+void
+_ecore_x_event_handle_motion_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Mouse_Move *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
+ if (!e) return;
+ e->modifiers = xevent->xmotion.state;
+ e->x = xevent->xmotion.x;
+ e->y = xevent->xmotion.y;
+ e->root.x = xevent->xmotion.x_root;
+ e->root.y = xevent->xmotion.y_root;
+ if (xevent->xmotion.subwindow) e->win = xevent->xmotion.subwindow;
+ else e->win = xevent->xmotion.window;
+ e->event_win = xevent->xmotion.window;
+ e->time = xevent->xmotion.time;
+ _ecore_x_event_last_time = e->time;
+ _ecore_x_event_last_win = e->win;
+ _ecore_x_event_last_root_x = e->root.x;
+ _ecore_x_event_last_root_y = e->root.y;
+
+ /* Xdnd handling */
+ _ecore_x_dnd_drag(e->root.x, e->root.y);
+
+ ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_enter_notify(XEvent *xevent)
+{
+ {
+ Ecore_X_Event_Mouse_Move *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
+ if (!e) return;
+ e->modifiers = xevent->xcrossing.state;
+ e->x = xevent->xcrossing.x;
+ e->y = xevent->xcrossing.y;
+ e->root.x = xevent->xcrossing.x_root;
+ e->root.y = xevent->xcrossing.y_root;
+ if (xevent->xcrossing.subwindow) e->win = xevent->xcrossing.subwindow;
+ else e->win = xevent->xcrossing.window;
+ e->event_win = xevent->xcrossing.window;
+ e->time = xevent->xcrossing.time;
+ _ecore_x_event_last_time = e->time;
+ _ecore_x_event_last_win = e->win;
+ _ecore_x_event_last_root_x = e->root.x;
+ _ecore_x_event_last_root_y = e->root.y;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+ {
+ Ecore_X_Event_Mouse_In *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_In));
+ if (!e) return;
+ e->modifiers = xevent->xcrossing.state;
+ e->x = xevent->xcrossing.x;
+ e->y = xevent->xcrossing.y;
+ e->root.x = xevent->xcrossing.x_root;
+ e->root.y = xevent->xcrossing.y_root;
+ if (xevent->xcrossing.subwindow) e->win = xevent->xcrossing.subwindow;
+ else e->win = xevent->xcrossing.window;
+ e->event_win = xevent->xcrossing.window;
+ if (xevent->xcrossing.mode == NotifyNormal) e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ else if (xevent->xcrossing.mode == NotifyGrab) e->mode = ECORE_X_EVENT_MODE_GRAB;
+ else if (xevent->xcrossing.mode == NotifyUngrab) e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+ if (xevent->xcrossing.detail == NotifyAncestor) e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ else if (xevent->xcrossing.detail == NotifyVirtual) e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ else if (xevent->xcrossing.detail == NotifyInferior) e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ else if (xevent->xcrossing.detail == NotifyNonlinear) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ else if (xevent->xcrossing.detail == NotifyNonlinearVirtual) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+ e->time = xevent->xcrossing.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_leave_notify(XEvent *xevent)
+{
+ {
+ Ecore_X_Event_Mouse_Move *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
+ if (!e) return;
+ e->modifiers = xevent->xcrossing.state;
+ e->x = xevent->xcrossing.x;
+ e->y = xevent->xcrossing.y;
+ e->root.x = xevent->xcrossing.x_root;
+ e->root.y = xevent->xcrossing.y_root;
+ if (xevent->xcrossing.subwindow) e->win = xevent->xcrossing.subwindow;
+ else e->win = xevent->xcrossing.window;
+ e->event_win = xevent->xcrossing.window;
+ e->time = xevent->xcrossing.time;
+ _ecore_x_event_last_time = e->time;
+ _ecore_x_event_last_win = e->win;
+ _ecore_x_event_last_root_x = e->root.x;
+ _ecore_x_event_last_root_y = e->root.y;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+ {
+ Ecore_X_Event_Mouse_Out *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out));
+ if (!e) return;
+ e->modifiers = xevent->xcrossing.state;
+ e->x = xevent->xcrossing.x;
+ e->y = xevent->xcrossing.y;
+ e->root.x = xevent->xcrossing.x_root;
+ e->root.y = xevent->xcrossing.y_root;
+ if (xevent->xcrossing.subwindow) e->win = xevent->xcrossing.subwindow;
+ else e->win = xevent->xcrossing.window;
+ e->event_win = xevent->xcrossing.window;
+ if (xevent->xcrossing.mode == NotifyNormal) e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ else if (xevent->xcrossing.mode == NotifyGrab) e->mode = ECORE_X_EVENT_MODE_GRAB;
+ else if (xevent->xcrossing.mode == NotifyUngrab) e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+ if (xevent->xcrossing.detail == NotifyAncestor) e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ else if (xevent->xcrossing.detail == NotifyVirtual) e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ else if (xevent->xcrossing.detail == NotifyInferior) e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ else if (xevent->xcrossing.detail == NotifyNonlinear) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ else if (xevent->xcrossing.detail == NotifyNonlinearVirtual) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+ e->time = xevent->xcrossing.time;
+ _ecore_x_event_last_time = e->time;
+ _ecore_x_event_last_win = e->win;
+ _ecore_x_event_last_root_x = e->root.x;
+ _ecore_x_event_last_root_y = e->root.y;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_focus_in(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Focus_In *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In));
+ if (!e) return;
+ e->win = xevent->xfocus.window;
+ if (xevent->xfocus.mode == NotifyNormal) e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ else if (xevent->xfocus.mode == NotifyWhileGrabbed) e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
+ else if (xevent->xfocus.mode == NotifyGrab) e->mode = ECORE_X_EVENT_MODE_GRAB;
+ else if (xevent->xfocus.mode == NotifyUngrab) e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+ if (xevent->xfocus.detail == NotifyAncestor) e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ else if (xevent->xfocus.detail == NotifyVirtual) e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ else if (xevent->xfocus.detail == NotifyInferior) e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ else if (xevent->xfocus.detail == NotifyNonlinear) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ else if (xevent->xfocus.detail == NotifyNonlinearVirtual) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+ else if (xevent->xfocus.detail == NotifyPointer) e->detail = ECORE_X_EVENT_DETAIL_POINTER;
+ else if (xevent->xfocus.detail == NotifyPointerRoot) e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
+ else if (xevent->xfocus.detail == NotifyDetailNone) e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
+ e->time = _ecore_x_event_last_time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_focus_out(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Focus_Out *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out));
+ if (!e) return;
+ e->win = xevent->xfocus.window;
+ if (xevent->xfocus.mode == NotifyNormal) e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ else if (xevent->xfocus.mode == NotifyWhileGrabbed) e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
+ else if (xevent->xfocus.mode == NotifyGrab) e->mode = ECORE_X_EVENT_MODE_GRAB;
+ else if (xevent->xfocus.mode == NotifyUngrab) e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+ if (xevent->xfocus.detail == NotifyAncestor) e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ else if (xevent->xfocus.detail == NotifyVirtual) e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ else if (xevent->xfocus.detail == NotifyInferior) e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ else if (xevent->xfocus.detail == NotifyNonlinear) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ else if (xevent->xfocus.detail == NotifyNonlinearVirtual) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+ else if (xevent->xfocus.detail == NotifyPointer) e->detail = ECORE_X_EVENT_DETAIL_POINTER;
+ else if (xevent->xfocus.detail == NotifyPointerRoot) e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
+ else if (xevent->xfocus.detail == NotifyDetailNone) e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
+ e->time = _ecore_x_event_last_time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_keymap_notify(XEvent *xevent __UNUSED__)
+{
+ /* FIXME: handle this event type */
+}
+
+void
+_ecore_x_event_handle_expose(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Damage *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
+ if (!e) return;
+ e->win = xevent->xexpose.window;
+ e->time = _ecore_x_event_last_time;
+ e->x = xevent->xexpose.x;
+ e->y = xevent->xexpose.y;
+ e->w = xevent->xexpose.width;
+ e->h = xevent->xexpose.height;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_graphics_expose(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Damage *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
+ if (!e) return;
+ e->win = xevent->xgraphicsexpose.drawable;
+ e->time = _ecore_x_event_last_time;
+ e->x = xevent->xgraphicsexpose.x;
+ e->y = xevent->xgraphicsexpose.y;
+ e->w = xevent->xgraphicsexpose.width;
+ e->h = xevent->xgraphicsexpose.height;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_visibility_notify(XEvent *xevent)
+{
+ if (xevent->xvisibility.state != VisibilityPartiallyObscured)
+ {
+ Ecore_X_Event_Window_Visibility_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change));
+ if (!e) return;
+ e->win = xevent->xvisibility.window;
+ e->time = _ecore_x_event_last_time;
+ if (xevent->xvisibility.state == VisibilityFullyObscured)
+ e->fully_obscured = 1;
+ else
+ e->fully_obscured = 0;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_create_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Create *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Create));
+ e->win = xevent->xcreatewindow.window;
+ if (xevent->xcreatewindow.override_redirect)
+ e->override = 1;
+ else
+ e->override = 0;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_destroy_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Destroy *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy));
+ if (!e) return;
+ e->win = xevent->xdestroywindow.window;
+ e->time = _ecore_x_event_last_time;
+ if (e->win == _ecore_x_event_last_win) _ecore_x_event_last_win = 0;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_unmap_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Hide *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Hide));
+ if (!e) return;
+ e->win = xevent->xunmap.window;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_map_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Show *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Show));
+ if (!e) return;
+ e->win = xevent->xmap.window;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_map_request(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Show_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request));
+ if (!e) return;
+ e->win = xevent->xmaprequest.window;
+ e->time = _ecore_x_event_last_time;
+ e->parent = xevent->xmaprequest.parent;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_reparent_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Reparent *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent));
+ if (!e) return;
+ e->win = xevent->xreparent.window;
+ e->parent = xevent->xreparent.parent;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_configure_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Configure *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Configure));
+ if (!e) return;
+ e->win = xevent->xconfigure.window;
+ e->abovewin = xevent->xconfigure.above;
+ e->x = xevent->xconfigure.x;
+ e->y = xevent->xconfigure.y;
+ e->w = xevent->xconfigure.width;
+ e->h = xevent->xconfigure.height;
+ e->border = xevent->xconfigure.border_width;
+ e->override = xevent->xconfigure.override_redirect;
+ e->from_wm = xevent->xconfigure.send_event;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_configure_request(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Configure_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request));
+ if (!e) return;
+ e->win = xevent->xconfigurerequest.window;
+ e->abovewin = xevent->xconfigurerequest.above;
+ e->x = xevent->xconfigurerequest.x;
+ e->y = xevent->xconfigurerequest.y;
+ e->w = xevent->xconfigurerequest.width;
+ e->h = xevent->xconfigurerequest.height;
+ e->border = xevent->xconfigurerequest.border_width;
+ e->value_mask = xevent->xconfigurerequest.value_mask;
+ e->time = _ecore_x_event_last_time;
+ if (xevent->xconfigurerequest.detail == Above)
+ e->detail = ECORE_X_WINDOW_STACK_ABOVE;
+ else if (xevent->xconfigurerequest.detail == Below)
+ e->detail = ECORE_X_WINDOW_STACK_BELOW;
+ else if (xevent->xconfigurerequest.detail == TopIf)
+ e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
+ else if (xevent->xconfigurerequest.detail == BottomIf)
+ e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
+ else if (xevent->xconfigurerequest.detail == Opposite)
+ e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_gravity_notify(XEvent *xevent __UNUSED__)
+{
+ /* FIXME: handle this event type */
+}
+
+void
+_ecore_x_event_handle_resize_request(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Resize_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request));
+ if (!e) return;
+ e->win = xevent->xresizerequest.window;
+ e->w = xevent->xresizerequest.width;
+ e->h = xevent->xresizerequest.height;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_circulate_notify(XEvent *xevent __UNUSED__)
+{
+ /* FIXME: handle this event type */
+}
+
+void
+_ecore_x_event_handle_circulate_request(XEvent *xevent __UNUSED__)
+{
+ /* FIXME: handle this event type */
+}
+
+void
+_ecore_x_event_handle_property_notify(XEvent *xevent)
+{
+#if 0 /* for now i disabled this. nice idea though this is - it leaves a lot
+ * to be desired for efficiency that is better left to the app layer
+ */
+ if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLASS)
+ {
+ Ecore_X_Event_Window_Prop_Name_Class_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Name_Class_Change));
+ if (!e) return;
+ ecore_x_window_prop_name_class_get(xevent->xproperty.window,
+ &(e->name), &(e->clas));
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE, e, _ecore_x_event_free_window_prop_name_class_change, NULL);
+ }
+ else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_NAME))
+ {
+ Ecore_X_Event_Window_Prop_Title_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Title_Change));
+ if (!e) return;
+ e->title = ecore_x_window_prop_title_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_title_change, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_NAME)
+ {
+ Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Title_Change));
+ if (!e) return;
+ e->title = ecore_x_window_prop_visible_title_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_visible_title_change, NULL);
+ }
+ else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_ICON_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_ICON_NAME))
+ {
+ Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Icon_Name_Change));
+ if (!e) return;
+ e->name = ecore_x_window_prop_icon_name_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_icon_name_change, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME)
+ {
+ Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change));
+ if (!e) return;
+ e->name = ecore_x_window_prop_visible_icon_name_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_visible_icon_name_change, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
+ {
+ Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Client_Machine_Change));
+ if (!e) return;
+ e->name = ecore_x_window_prop_client_machine_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE, e, _ecore_x_event_free_window_prop_client_machine_change, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_PID)
+ {
+ Ecore_X_Event_Window_Prop_Pid_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Pid_Change));
+ if (!e) return;
+ e->pid = ecore_x_window_prop_pid_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_DESKTOP)
+ {
+ Ecore_X_Event_Window_Prop_Desktop_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Desktop_Change));
+ if (!e) return;
+ e->desktop = ecore_x_window_prop_desktop_get(xevent->xproperty.window);
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
+ }
+ else
+#endif
+ {
+ Ecore_X_Event_Window_Property *e;
+
+ e = calloc(1,sizeof(Ecore_X_Event_Window_Property));
+ if (!e) return;
+ e->win = xevent->xproperty.window;
+ e->atom = xevent->xproperty.atom;
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_selection_clear(XEvent *xevent)
+{
+ Ecore_X_Selection_Intern *d;
+ Ecore_X_Event_Selection_Clear *e;
+ Ecore_X_Atom sel;
+
+ if (!(d = _ecore_x_selection_get(xevent->xselectionclear.selection)))
+ return;
+ if (xevent->xselectionclear.time > d->time)
+ {
+ _ecore_x_selection_set(None, NULL, 0,
+ xevent->xselectionclear.selection);
+ }
+
+ /* Generate event for app cleanup */
+ e = malloc(sizeof(Ecore_X_Event_Selection_Clear));
+ e->win = xevent->xselectionclear.window;
+ e->time = xevent->xselectionclear.time;
+ sel = xevent->xselectionclear.selection;
+ if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
+ e->selection = ECORE_X_SELECTION_PRIMARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
+ e->selection = ECORE_X_SELECTION_SECONDARY;
+ else
+ e->selection = ECORE_X_SELECTION_CLIPBOARD;
+ ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
+
+}
+
+void
+_ecore_x_event_handle_selection_request(XEvent *xevent)
+{
+ Ecore_X_Selection_Intern *sd;
+ XSelectionEvent xnotify;
+ XEvent xev;
+ void *data;
+
+ xnotify.type = SelectionNotify;
+ xnotify.display = xevent->xselectionrequest.display;
+ xnotify.requestor = xevent->xselectionrequest.requestor;
+ xnotify.selection = xevent->xselectionrequest.selection;
+ xnotify.target = xevent->xselectionrequest.target;
+ xnotify.time = CurrentTime;
+ xnotify.send_event = True;
+ xnotify.serial = 0;
+
+ if ((sd = _ecore_x_selection_get(xnotify.selection))
+ && (sd->win == xevent->xselectionrequest.owner))
+ {
+ if (!_ecore_x_selection_convert(xnotify.selection, xnotify.target,
+ &data) == -1)
+ {
+ /* Refuse selection, conversion to requested target failed */
+ xnotify.property = None;
+ }
+ else
+ {
+ /* FIXME: This does not properly handle large data transfers */
+ ecore_x_window_prop_property_set(xevent->xselectionrequest.requestor,
+ xevent->xselectionrequest.property,
+ xevent->xselectionrequest.target,
+ 8, data, sd->length);
+ xnotify.property = xevent->xselectionrequest.property;
+ free(data);
+ }
+ }
+ else
+ {
+ xnotify.property = None;
+ return;
+ }
+
+ xev.xselection = xnotify;
+ XSendEvent(xevent->xselectionrequest.display,
+ xevent->xselectionrequest.requestor, False, 0, &xev);
+}
+
+void
+_ecore_x_event_handle_selection_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Selection_Notify *e;
+ unsigned char *data = NULL;
+ Ecore_X_Atom selection;
+ int num_ret;
+
+ selection = xevent->xselection.selection;
+
+ if (xevent->xselection.target == ECORE_X_ATOM_SELECTION_TARGETS)
+ {
+ if (!ecore_x_window_prop_property_get(xevent->xselection.requestor,
+ xevent->xselection.property,
+ XA_ATOM, 32, &data, &num_ret))
+ return;
+ }
+ else
+ {
+ if (!ecore_x_window_prop_property_get(xevent->xselection.requestor,
+ xevent->xselection.property,
+ AnyPropertyType, 8, &data, &num_ret))
+ return;
+ }
+
+ e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
+ e->win = xevent->xselection.requestor;
+ e->time = xevent->xselection.time;
+ e->target = _ecore_x_selection_target_get(xevent->xselection.target);
+
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ e->selection = ECORE_X_SELECTION_PRIMARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ e->selection = ECORE_X_SELECTION_SECONDARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_XDND)
+ e->selection = ECORE_X_SELECTION_XDND;
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ e->selection = ECORE_X_SELECTION_CLIPBOARD;
+ else
+ {
+ free(e);
+ return;
+ }
+ e->data = _ecore_x_selection_parse(e->target, data, num_ret);
+
+ ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, _ecore_x_event_free_selection_notify, NULL);
+}
+
+void
+_ecore_x_event_handle_colormap_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Colormap *e;
+
+ e = calloc(1,sizeof(Ecore_X_Event_Window_Colormap));
+ e->win = xevent->xcolormap.window;
+ e->cmap = xevent->xcolormap.colormap;
+ e->time = _ecore_x_event_last_time;
+ if (xevent->xcolormap.state == ColormapInstalled)
+ e->installed = 1;
+ else
+ e->installed = 0;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_client_message(XEvent *xevent)
+{
+ /* Special client message event handling here. need to put LOTS of if */
+ /* checks here and generate synthetic events per special message known */
+ /* otherwise generate generic client message event. this would handle*/
+ /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */
+ if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS) &&
+ (xevent->xclient.format == 32) &&
+ (xevent->xclient.data.l[0] == (long)ECORE_X_ATOM_WM_DELETE_WINDOW))
+ {
+ Ecore_X_Event_Window_Delete_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
+ }
+
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
+ (xevent->xclient.format == 32) &&
+ /* Ignore move and resize with keyboard */
+ (xevent->xclient.data.l[2] < 9))
+ {
+ Ecore_X_Event_Window_Move_Resize_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->x = xevent->xclient.data.l[0];
+ e->y = xevent->xclient.data.l[1];
+ e->direction = xevent->xclient.data.l[2];
+ e->button = xevent->xclient.data.l[3];
+ e->source = xevent->xclient.data.l[4];
+ ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
+ }
+
+ /* Xdnd Client Message Handling Begin */
+ /* Message Type: XdndEnter target */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_ENTER)
+ {
+ Ecore_X_Event_Xdnd_Enter *e;
+ Ecore_X_DND_Target *target;
+ unsigned long three;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter));
+ if (!e) return;
+
+ target = _ecore_x_dnd_target_get();
+ target->state = ECORE_X_DND_TARGET_ENTERED;
+
+ target = _ecore_x_dnd_target_get();
+ target->source = xevent->xclient.data.l[0];
+ target->win = xevent->xclient.window;
+ target->version = (int) (xevent->xclient.data.l[1] >> 24);
+ if (target->version > ECORE_X_DND_VERSION)
+ {
+ printf("DND: Requested version %d, we only support up to %d\n", target->version,
+ ECORE_X_DND_VERSION);
+ return;
+ }
+
+ if ((three = xevent->xclient.data.l[1] & 0x1UL))
+ {
+ /* source supports more than 3 types, fetch property */
+ unsigned char *data;
+ Ecore_X_Atom *types;
+ int i, num_ret;
+ if (!(ecore_x_window_prop_property_get(target->source,
+ ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM,
+ 32,
+ &data,
+ &num_ret)))
+ {
+ printf("DND: Could not fetch data type list from source window, aborting.\n");
+ return;
+ }
+ types = (Ecore_X_Atom *)data;
+ e->types = calloc(num_ret, sizeof(char *));
+ for (i = 0; i < num_ret; i++)
+ e->types[i] = XGetAtomName(_ecore_x_disp, types[i]);
+ e->num_types = num_ret;
+ }
+ else
+ {
+ int i = 0;
+
+ e->types = calloc(3, sizeof(char *));
+ while ((i < 3) && (xevent->xclient.data.l[i + 2]))
+ {
+ e->types[i] = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[i + 2]);
+ i++;
+ }
+ e->num_types = i;
+ }
+
+ e->win = target->win;
+ e->source = target->source;
+ ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e, _ecore_x_event_free_xdnd_enter, NULL);
+ }
+
+ /* Message Type: XdndPosition target */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_POSITION)
+ {
+ Ecore_X_Event_Xdnd_Position *e;
+ Ecore_X_DND_Target *target;
+
+ target = _ecore_x_dnd_target_get();
+ if ((target->source != xevent->xclient.data.l[0])
+ || (target->win != xevent->xclient.window))
+ return;
+
+ target->pos.x = xevent->xclient.data.l[2] >> 16;
+ target->pos.y = xevent->xclient.data.l[2] & 0xFFFFUL;
+ target->action = xevent->xclient.data.l[4]; /* Version 2 */
+
+ target->time = (target->version >= 1) ?
+ (Time)xevent->xclient.data.l[3] : CurrentTime;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
+ if (!e) return;
+ e->win = target->win;
+ e->source = target->source;
+ e->position.x = target->pos.x;
+ e->position.y = target->pos.y;
+ e->action = target->action;
+ ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
+ }
+
+ /* Message Type: XdndStatus source */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_STATUS)
+ {
+ Ecore_X_Event_Xdnd_Status *e;
+ Ecore_X_DND_Source *source;
+
+ source = _ecore_x_dnd_source_get();
+ /* Make sure source/target match */
+ if ((source->win != xevent->xclient.window )
+ || (source->dest != (Window)xevent->xclient.data.l[0]))
+ return;
+
+ source->await_status = 0;
+
+ source->will_accept = xevent->xclient.data.l[1] & 0x1UL;
+ source->suppress = (xevent->xclient.data.l[1] & 0x2UL) ? 0 : 1;
+
+ source->rectangle.x = xevent->xclient.data.l[2] >> 16;
+ source->rectangle.y = xevent->xclient.data.l[2] & 0xFFFFUL;
+ source->rectangle.width = xevent->xclient.data.l[3] >> 16;
+ source->rectangle.height = xevent->xclient.data.l[3] & 0xFFFFUL;
+
+ source->accepted_action = xevent->xclient.data.l[4];
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
+ if (!e) return;
+ e->win = source->win;
+ e->target = source->dest;
+ e->will_accept = source->will_accept;
+ e->rectangle.x = source->rectangle.x;
+ e->rectangle.y = source->rectangle.y;
+ e->rectangle.width = source->rectangle.width;
+ e->rectangle.height = source->rectangle.height;
+ e->action = source->accepted_action;
+
+ ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
+ }
+
+ /* Message Type: XdndLeave target */
+ /* Pretend the whole thing never happened, sort of */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_LEAVE)
+ {
+ Ecore_X_Event_Xdnd_Leave *e;
+ Ecore_X_DND_Target *target;
+
+ target = _ecore_x_dnd_target_get();
+ if ((target->source != xevent->xclient.data.l[0])
+ || (target->win != xevent->xclient.window))
+ return;
+
+ target->state = ECORE_X_DND_TARGET_IDLE;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->source = (Window)xevent->xclient.data.l[0];
+ ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
+ }
+
+ /* Message Type: XdndDrop target */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_DROP)
+ {
+ Ecore_X_Event_Xdnd_Drop *e;
+ Ecore_X_DND_Target *target;
+
+ target = _ecore_x_dnd_target_get();
+ /* Match source/target */
+ if ((target->source != (Window)xevent->xclient.data.l[0])
+ || (target->win != xevent->xclient.window))
+ return;
+
+ target->time = (target->version >= 1) ?
+ (Time)xevent->xclient.data.l[2] : _ecore_x_event_last_time;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
+ if (!e) return;
+ e->win = target->win;
+ e->source = target->source;
+ e->action = target->action;
+ e->position.x = target->pos.x;
+ e->position.y = target->pos.y;
+ ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
+ }
+
+ /* Message Type: XdndFinished source */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_FINISHED)
+ {
+ Ecore_X_Event_Xdnd_Finished *e;
+ Ecore_X_DND_Source *source;
+ int completed = 1;
+
+ source = _ecore_x_dnd_source_get();
+ /* Match source/target */
+ if ((source->win != xevent->xclient.window)
+ || (source->dest != (Window)xevent->xclient.data.l[0]))
+ return;
+
+ if ((source->version >= 5) && (xevent->xclient.data.l[1] & 0x1UL))
+ {
+ /* Target successfully performed drop action */
+ ecore_x_selection_xdnd_clear();
+ source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+ else
+ {
+ completed = 0;
+ source->state = ECORE_X_DND_SOURCE_CONVERTING;
+
+ /* FIXME: Probably need to add a timer to switch back to idle
+ * and discard the selection data */
+ }
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished));
+ if (!e) return;
+ e->win = source->win;
+ e->target = source->dest;
+ e->completed = completed;
+ if (source->version >= 5)
+ {
+ source->accepted_action = xevent->xclient.data.l[2];
+ e->action = source->accepted_action;
+ }
+ else
+ {
+ source->accepted_action = 0;
+ e->action = source->action;
+ }
+
+ ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
+ }
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_STATE)
+ {
+ Ecore_X_Event_Window_State_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ if (xevent->xclient.data.l[0] == 0)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
+ else if (xevent->xclient.data.l[0] == 1)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
+ else if (xevent->xclient.data.l[0] == 2)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
+ else
+ {
+ free(e);
+ return;
+ }
+ e->state[0] = _ecore_x_netwm_state_get(xevent->xclient.data.l[1]);
+ if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
+ {
+ char *name;
+ name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[1]);
+ if (name)
+ printf("Unknown state: %s\n", name);
+ XFree(name);
+ }
+ e->state[1] = _ecore_x_netwm_state_get(xevent->xclient.data.l[2]);
+ if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
+ {
+ char *name;
+ name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[2]);
+ if (name)
+ printf("Unknown state: %s\n", name);
+ XFree(name);
+ }
+ e->source = xevent->xclient.data.l[3];
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_CHANGE_STATE)
+ && (xevent->xclient.format == 32)
+ && (xevent->xclient.data.l[0] == IconicState))
+ {
+ Ecore_X_Event_Window_State_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
+ e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED;
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_DESKTOP)
+ && (xevent->xclient.format == 32))
+ {
+ Ecore_X_Event_Desktop_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->desk = xevent->xclient.data.l[0];
+ e->source = xevent->xclient.data.l[1];
+
+ ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS))
+ {
+ Ecore_X_Event_Frame_Extents_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+
+ ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS)
+ && (xevent->xclient.data.l[0] == ECORE_X_ATOM_NET_WM_PING)
+ && (xevent->xclient.format == 32))
+ {
+ Ecore_X_Event_Ping *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Ping));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->time = xevent->xclient.data.l[1];
+ e->event_win = xevent->xclient.data.l[2];
+
+ ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_type == 27777)
+ && (xevent->xclient.data.l[0] == 0x7162534)
+ && (xevent->xclient.format == 32)
+ && (xevent->xclient.window == _ecore_x_private_win))
+ {
+ /* a grab sync marker */
+ if (xevent->xclient.data.l[1] == 0x10000001)
+ _ecore_x_window_grab_remove(xevent->xclient.data.l[2]);
+ else if (xevent->xclient.data.l[1] == 0x10000002)
+ _ecore_x_key_grab_remove(xevent->xclient.data.l[2]);
+ }
+ else
+ {
+ Ecore_X_Event_Client_Message *e;
+ int i;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Client_Message));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->message_type = xevent->xclient.message_type;
+ e->format = xevent->xclient.format;
+ for (i = 0; i < 5; i++)
+ e->data.l[i] = xevent->xclient.data.l[i];
+
+ ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_mapping_notify(XEvent *xevent __UNUSED__)
+{
+ /* FIXME: handle this event type */
+}
+
+void
+_ecore_x_event_handle_shape_change(XEvent *xevent)
+{
+ XShapeEvent *shape_event;
+ Ecore_X_Event_Window_Shape *e;
+
+ shape_event = (XShapeEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Shape));
+ if (!e) return;
+ e->win = shape_event->window;
+ e->time = shape_event->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_sync_counter(XEvent *xevent)
+{
+ XSyncCounterNotifyEvent *sync_counter_event;
+ Ecore_X_Event_Sync_Counter *e;
+
+ sync_counter_event = (XSyncCounterNotifyEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter));
+ if (!e) return;
+ e->time = sync_counter_event->time;
+ ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_sync_alarm(XEvent *xevent)
+{
+ XSyncAlarmNotifyEvent *sync_alarm_event;
+ Ecore_X_Event_Sync_Alarm *e;
+
+ sync_alarm_event = (XSyncAlarmNotifyEvent *)xevent;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm));
+ if (!e) return;
+ e->time = sync_alarm_event->time;
+ e->alarm = sync_alarm_event->alarm;
+ ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL);
+}
diff --git a/ecore/src/lib/ecore_x/ecore_x_gc.c b/ecore/src/lib/ecore_x/ecore_x_gc.c
new file mode 100644
index 0000000..99ff0e1
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_gc.c
@@ -0,0 +1,29 @@
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+/**
+ * Creates a new default graphics context associated with the given
+ * drawable.
+ * @param draw Drawable to create graphics context with. If @c 0 is
+ * given instead, the default root window is used.
+ * @return The new default graphics context.
+ */
+Ecore_X_GC
+ecore_x_gc_new(Ecore_X_Drawable draw)
+{
+ XGCValues gcv;
+
+ if (!draw) draw = DefaultRootWindow(_ecore_x_disp);
+ return XCreateGC(_ecore_x_disp, draw, 0, &gcv);
+}
+
+/**
+ * Deletes and frees the given graphics context.
+ * @param gc The given graphics context.
+ */
+void
+ecore_x_gc_del(Ecore_X_GC gc)
+{
+ XFreeGC(_ecore_x_disp, gc);
+}
diff --git a/ecore/src/lib/ecore_x/ecore_x_icccm.c b/ecore/src/lib/ecore_x/ecore_x_icccm.c
new file mode 100644
index 0000000..a29a83a
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_icccm.c
@@ -0,0 +1,1082 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+/*
+ * Various ICCCM related functions.
+ *
+ * This is ALL the code involving anything ICCCM related. for both WM and
+ * client.
+ */
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+/* Atoms */
+Ecore_X_Atom ECORE_X_ATOM_WM_STATE = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_DELETE_WINDOW = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_TAKE_FOCUS = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_PROTOCOLS = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_CLASS = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_NAME = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_COMMAND = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_ICON_NAME = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_MACHINE = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_CHANGE_STATE = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_COLORMAP_WINDOWS = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_WINDOW_ROLE = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_HINTS = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_NORMAL_HINTS = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_LEADER = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_TRANSIENT_FOR = 0;
+Ecore_X_Atom ECORE_X_ATOM_WM_SAVE_YOURSELF = 0;
+
+void
+ecore_x_icccm_init(void)
+{
+
+ ECORE_X_ATOM_WM_STATE = XInternAtom(_ecore_x_disp, "WM_STATE", False);
+ ECORE_X_ATOM_WM_DELETE_WINDOW =
+ XInternAtom(_ecore_x_disp, "WM_DELETE_WINDOW", False);
+ ECORE_X_ATOM_WM_TAKE_FOCUS =
+ XInternAtom(_ecore_x_disp, "WM_TAKE_FOCUS", False);
+ ECORE_X_ATOM_WM_PROTOCOLS =
+ XInternAtom(_ecore_x_disp, "WM_PROTOCOLS", False);
+ ECORE_X_ATOM_WM_CLASS = XInternAtom(_ecore_x_disp, "WM_CLASS", False);
+ ECORE_X_ATOM_WM_NAME = XInternAtom(_ecore_x_disp, "WM_NAME", False);
+ ECORE_X_ATOM_WM_COMMAND = XInternAtom(_ecore_x_disp, "WM_COMMAND", False);
+ ECORE_X_ATOM_WM_ICON_NAME =
+ XInternAtom(_ecore_x_disp, "WM_ICON_NAME", False);
+ ECORE_X_ATOM_WM_CLIENT_MACHINE =
+ XInternAtom(_ecore_x_disp, "WM_CLIENT_MACHINE", False);
+ ECORE_X_ATOM_WM_CHANGE_STATE =
+ XInternAtom(_ecore_x_disp, "WM_CHANGE_STATE", False);
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS =
+ XInternAtom(_ecore_x_disp, "WM_COLORMAP_WINDOWS", False);
+ ECORE_X_ATOM_WM_WINDOW_ROLE =
+ XInternAtom(_ecore_x_disp, "WM_WINDOW_ROLE", False);
+ ECORE_X_ATOM_WM_HINTS = XInternAtom(_ecore_x_disp, "WM_HINTS", False);
+ ECORE_X_ATOM_WM_NORMAL_HINTS =
+ XInternAtom(_ecore_x_disp, "WM_NORMAL_HINTS", False);
+ ECORE_X_ATOM_WM_CLIENT_LEADER =
+ XInternAtom(_ecore_x_disp, "WM_CLIENT_LEADER", False);
+ ECORE_X_ATOM_WM_TRANSIENT_FOR =
+ XInternAtom(_ecore_x_disp, "WM_TRANSIENT_FOR", False);
+ ECORE_X_ATOM_WM_SAVE_YOURSELF =
+ XInternAtom(_ecore_x_disp, "WM_SAVE_YOURSELF", False);
+}
+
+void
+ecore_x_icccm_state_set(Ecore_X_Window win, Ecore_X_Window_State_Hint state)
+{
+ unsigned long c[2];
+
+ if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+ c[0] = WithdrawnState;
+ else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
+ c[0] = NormalState;
+ else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
+ c[0] = IconicState;
+ c[1] = None;
+ XChangeProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_STATE,
+ ECORE_X_ATOM_WM_STATE, 32, PropModeReplace,
+ (unsigned char *)c, 2);
+}
+
+Ecore_X_Window_State_Hint
+ecore_x_icccm_state_get(Ecore_X_Window win)
+{
+ unsigned char *prop_ret = NULL;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ Ecore_X_Window_State_Hint hint;
+
+ hint = ECORE_X_WINDOW_STATE_HINT_NONE;
+ XGetWindowProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_STATE,
+ 0, 0x7fffffff, False, ECORE_X_ATOM_WM_STATE,
+ &type_ret, &format_ret, &num_ret, &bytes_after,
+ &prop_ret);
+ if ((prop_ret) && (num_ret == 2))
+ {
+ if (prop_ret[0] == WithdrawnState)
+ hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ else if (prop_ret[0] == NormalState)
+ hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ else if (prop_ret[0] == IconicState)
+ hint = ECORE_X_WINDOW_STATE_HINT_ICONIC;
+ }
+
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return hint;
+}
+
+void
+ecore_x_icccm_delete_window_send(Ecore_X_Window win, Ecore_X_Time t)
+{
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_EVENT_MASK_NONE,
+ ECORE_X_ATOM_WM_DELETE_WINDOW,
+ t, 0, 0, 0);
+}
+
+void
+ecore_x_icccm_take_focus_send(Ecore_X_Window win, Ecore_X_Time t)
+{
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_EVENT_MASK_NONE,
+ ECORE_X_ATOM_WM_TAKE_FOCUS,
+ t, 0, 0, 0);
+}
+
+void
+ecore_x_icccm_save_yourself_send(Ecore_X_Window win, Ecore_X_Time t)
+{
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_EVENT_MASK_NONE,
+ ECORE_X_ATOM_WM_SAVE_YOURSELF,
+ t, 0, 0, 0);
+}
+
+void
+ecore_x_icccm_move_resize_send(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ XEvent ev;
+
+ ev.type = ConfigureNotify;
+ ev.xconfigure.display = _ecore_x_disp;
+ ev.xconfigure.event = win;
+ ev.xconfigure.window = win;
+ ev.xconfigure.x = x;
+ ev.xconfigure.y = y;
+ ev.xconfigure.width = w;
+ ev.xconfigure.height = h;
+ ev.xconfigure.border_width = 0;
+ ev.xconfigure.above = None;
+ ev.xconfigure.override_redirect = False;
+ XSendEvent(_ecore_x_disp, win, False, StructureNotifyMask, &ev);
+}
+
+void
+ecore_x_icccm_hints_set(Ecore_X_Window win,
+ int 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, int is_urgent)
+{
+ XWMHints *hints;
+
+ hints = XAllocWMHints();
+ if (!hints)
+ return;
+
+ hints->flags = InputHint | StateHint;
+ hints->input = accepts_focus;
+ if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+ hints->initial_state = WithdrawnState;
+ else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
+ hints->initial_state = NormalState;
+ else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
+ hints->initial_state = IconicState;
+ if (icon_pixmap != 0)
+ {
+ hints->icon_pixmap = icon_pixmap;
+ hints->flags |= IconPixmapHint;
+ }
+ if (icon_mask != 0)
+ {
+ hints->icon_mask = icon_mask;
+ hints->flags |= IconMaskHint;
+ }
+ if (icon_window != 0)
+ {
+ hints->icon_window = icon_window;
+ hints->flags |= IconWindowHint;
+ }
+ if (window_group != 0)
+ {
+ hints->window_group = window_group;
+ hints->flags |= WindowGroupHint;
+ }
+ if (is_urgent)
+ hints->flags |= XUrgencyHint;
+ XSetWMHints(_ecore_x_disp, win, hints);
+ XFree(hints);
+}
+
+int
+ecore_x_icccm_hints_get(Ecore_X_Window win,
+ int *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, int *is_urgent)
+{
+ XWMHints *hints;
+
+ if (accepts_focus)
+ *accepts_focus = 0;
+ if (initial_state)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ if (icon_pixmap)
+ *icon_pixmap = 0;
+ if (icon_mask)
+ *icon_mask = 0;
+ if (icon_window)
+ *icon_window = 0;
+ if (window_group)
+ *window_group = 0;
+ if (is_urgent)
+ *is_urgent = 0;
+ hints = XGetWMHints(_ecore_x_disp, win);
+ if (hints)
+ {
+ if ((hints->flags & InputHint) && (accepts_focus))
+ {
+ if (hints->input)
+ *accepts_focus = 1;
+ else
+ *accepts_focus = 0;
+ }
+ if ((hints->flags & StateHint) && (initial_state))
+ {
+ if (hints->initial_state == WithdrawnState)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ else if (hints->initial_state == NormalState)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ else if (hints->initial_state == IconicState)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
+ }
+ if ((hints->flags & IconPixmapHint) && (icon_pixmap))
+ {
+ *icon_pixmap = hints->icon_pixmap;
+ }
+ if ((hints->flags & IconMaskHint) && (icon_mask))
+ {
+ *icon_mask = hints->icon_mask;
+ }
+ if ((hints->flags & IconWindowHint) && (icon_window))
+ {
+ *icon_window = hints->icon_window;
+ }
+ if ((hints->flags & WindowGroupHint) && (window_group))
+ {
+ *window_group = hints->window_group;
+ }
+ if ((hints->flags & XUrgencyHint) && (is_urgent))
+ {
+ *is_urgent = 1;
+ }
+ XFree(hints);
+ return 1;
+ }
+ return 0;
+}
+
+void
+ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win,
+ int request_pos,
+ Ecore_X_Gravity gravity,
+ int min_w, int min_h,
+ int max_w, int max_h,
+ int base_w, int base_h,
+ int step_x, int step_y,
+ double min_aspect, double max_aspect)
+{
+ XSizeHints hint;
+ long mask;
+
+ if (!XGetWMNormalHints(_ecore_x_disp, win, &hint, &mask))
+ {
+ memset(&hint, 0, sizeof(XSizeHints));
+ }
+
+ hint.flags = 0;
+ if (request_pos)
+ {
+ hint.flags |= USPosition;
+ }
+ if (gravity != ECORE_X_GRAVITY_NW)
+ {
+ hint.flags |= PWinGravity;
+ hint.win_gravity = gravity;
+ }
+ if ((min_w > 0) || (min_h > 0))
+ {
+ hint.flags |= PMinSize;
+ hint.min_width = min_w;
+ hint.min_height = min_h;
+ }
+ if ((max_w > 0) || (max_h > 0))
+ {
+ hint.flags |= PMaxSize;
+ hint.max_width = max_w;
+ hint.max_height = max_h;
+ }
+ if ((base_w > 0) || (base_h > 0))
+ {
+ hint.flags |= PBaseSize;
+ hint.base_width = base_w;
+ hint.base_height = base_h;
+ }
+ if ((step_x > 1) || (step_y > 1))
+ {
+ hint.flags |= PResizeInc;
+ hint.width_inc = step_x;
+ hint.height_inc = step_y;
+ }
+ if ((min_aspect > 0.0) || (max_aspect > 0.0))
+ {
+ hint.flags |= PAspect;
+ hint.min_aspect.x = min_aspect * 10000;
+ hint.min_aspect.y = 10000;
+ hint.max_aspect.x = max_aspect * 10000;
+ hint.max_aspect.y = 10000;
+ }
+ XSetWMNormalHints(_ecore_x_disp, win, &hint);
+}
+
+int
+ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win,
+ int *request_pos,
+ Ecore_X_Gravity *gravity,
+ int *min_w, int *min_h,
+ int *max_w, int *max_h,
+ int *base_w, int *base_h,
+ int *step_x, int *step_y,
+ double *min_aspect, double *max_aspect)
+{
+ XSizeHints hint;
+ long mask;
+
+ int minw = 0, minh = 0;
+ int maxw = 32767, maxh = 32767;
+ int basew = -1, baseh = -1;
+ int stepx = 1, stepy = 1;
+ double mina = 0.0, maxa = 0.0;
+
+ if (!XGetWMNormalHints(_ecore_x_disp, win, &hint, &mask))
+ return 0;
+
+ if ((hint.flags & USPosition) || ((hint.flags & PPosition)))
+ {
+ if (request_pos)
+ *request_pos = 1;
+ }
+ else
+ {
+ if (request_pos)
+ *request_pos = 0;
+ }
+ if (hint.flags & PWinGravity)
+ {
+ if (gravity)
+ *gravity = hint.win_gravity;
+ }
+ else
+ {
+ if (gravity)
+ *gravity = ECORE_X_GRAVITY_NW;
+ }
+ if (hint.flags & PMinSize)
+ {
+ minw = hint.min_width;
+ minh = hint.min_height;
+ }
+ if (hint.flags & PMaxSize)
+ {
+ maxw = hint.max_width;
+ maxh = hint.max_height;
+ if (maxw < minw)
+ maxw = minw;
+ if (maxh < minh)
+ maxh = minh;
+ }
+ if (hint.flags & PBaseSize)
+ {
+ basew = hint.base_width;
+ baseh = hint.base_height;
+ if (basew > minw)
+ minw = basew;
+ if (baseh > minh)
+ minh = baseh;
+ }
+ if (hint.flags & PResizeInc)
+ {
+ stepx = hint.width_inc;
+ stepy = hint.height_inc;
+ if (stepx < 1)
+ stepx = 1;
+ if (stepy < 1)
+ stepy = 1;
+ }
+ if (hint.flags & PAspect)
+ {
+ if (hint.min_aspect.y > 0)
+ mina = ((double)hint.min_aspect.x) / ((double)hint.min_aspect.y);
+ if (hint.max_aspect.y > 0)
+ maxa = ((double)hint.max_aspect.x) / ((double)hint.max_aspect.y);
+ }
+ if (min_w)
+ *min_w = minw;
+ if (min_h)
+ *min_h = minh;
+ if (max_w)
+ *max_w = maxw;
+ if (max_h)
+ *max_h = maxh;
+ if (base_w)
+ *base_w = basew;
+ if (base_h)
+ *base_h = baseh;
+ if (step_x)
+ *step_x = stepx;
+ if (step_y)
+ *step_y = stepy;
+ if (min_aspect)
+ *min_aspect = mina;
+ if (max_aspect)
+ *max_aspect = maxa;
+ return 1;
+}
+
+void
+ecore_x_icccm_title_set(Ecore_X_Window win, const char *t)
+{
+ char *list[1];
+ XTextProperty xprop;
+ int ret;
+
+ xprop.value = NULL;
+#ifdef X_HAVE_UTF8_STRING
+ list[0] = strdup(t);
+ ret =
+ Xutf8TextListToTextProperty(_ecore_x_disp, list, 1, XUTF8StringStyle,
+ &xprop);
+#else
+ list[0] = strdup(t);
+ ret =
+ XmbTextListToTextProperty(_ecore_x_disp, list, 1, XStdICCTextStyle,
+ &xprop);
+#endif
+ if (ret >= Success)
+ {
+ XSetWMName(_ecore_x_disp, win, &xprop);
+ if (xprop.value) XFree(xprop.value);
+ }
+ else
+ {
+ if (XStringListToTextProperty(list, 1, &xprop) >= Success)
+ {
+ XSetWMName(_ecore_x_disp, win, &xprop);
+ if (xprop.value) XFree(xprop.value);
+ }
+ }
+ free(list[0]);
+}
+
+char *
+ecore_x_icccm_title_get(Ecore_X_Window win)
+{
+ XTextProperty xprop;
+
+ xprop.value = NULL;
+ if (XGetWMName(_ecore_x_disp, win, &xprop) >= Success)
+ {
+ if (xprop.value)
+ {
+ char **list = NULL;
+ char *t = NULL;
+ int num = 0;
+ int ret;
+
+ if (xprop.encoding == ECORE_X_ATOM_UTF8_STRING)
+ {
+ t = strdup((char *)xprop.value);
+ }
+ else
+ {
+
+ /* convert to utf8 */
+#ifdef X_HAVE_UTF8_STRING
+ ret = Xutf8TextPropertyToTextList(_ecore_x_disp, &xprop,
+ &list, &num);
+#else
+ ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop,
+ &list, &num);
+#endif
+
+ if ((ret == XLocaleNotSupported) ||
+ (ret == XNoMemory) || (ret == XConverterNotFound))
+ {
+ t = strdup((char *)xprop.value);
+ }
+ else if ((ret >= Success) && (num > 0))
+ {
+ t = strdup(list[0]);
+ }
+ if (list)
+ XFreeStringList(list);
+ }
+
+ if (xprop.value) XFree(xprop.value);
+ return t;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Set or unset a wm protocol property.
+ * @param win The Window
+ * @param protocol The protocol to enable/disable
+ * @param on On/Off
+ */
+void
+ecore_x_icccm_protocol_set(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol, int on)
+{
+ Atom *protos = NULL;
+ Atom proto;
+ int protos_count = 0;
+ int already_set = 0;
+ int i;
+
+ /* Check for invalid values */
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
+ return;
+
+ proto = _ecore_x_atoms_wm_protocols[protocol];
+
+ if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
+ {
+ protos = NULL;
+ protos_count = 0;
+ }
+
+ for (i = 0; i < protos_count; i++)
+ {
+ if (protos[i] == proto)
+ {
+ already_set = 1;
+ break;
+ }
+ }
+
+ if (on)
+ {
+ Atom *new_protos = NULL;
+
+ if (already_set)
+ goto leave;
+ new_protos = malloc((protos_count + 1) * sizeof(Atom));
+ if (!new_protos)
+ goto leave;
+ for (i = 0; i < protos_count; i++)
+ new_protos[i] = protos[i];
+ new_protos[protos_count] = proto;
+ XSetWMProtocols(_ecore_x_disp, win, new_protos, protos_count + 1);
+ free(new_protos);
+ }
+ else
+ {
+ if (!already_set)
+ goto leave;
+ for (i = 0; i < protos_count; i++)
+ {
+ if (protos[i] == proto)
+ {
+ int j;
+
+ for (j = i + 1; j < protos_count; j++)
+ protos[j - 1] = protos[j];
+ if (protos_count > 1)
+ XSetWMProtocols(_ecore_x_disp, win, protos,
+ protos_count - 1);
+ else
+ XDeleteProperty(_ecore_x_disp, win,
+ ECORE_X_ATOM_WM_PROTOCOLS);
+ goto leave;
+ }
+ }
+ }
+
+ leave:
+ if (protos)
+ XFree(protos);
+
+}
+
+/**
+ * Determines whether a protocol is set for a window.
+ * @param win The Window
+ * @param protocol The protocol to query
+ * @return 1 if the protocol is set, else 0.
+ */
+int
+ecore_x_icccm_protocol_isset(Ecore_X_Window win, Ecore_X_WM_Protocol protocol)
+{
+ Atom proto, *protos = NULL;
+ int i, ret = 0, protos_count = 0;
+
+ /* check for invalid values */
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
+ return 0;
+
+ proto = _ecore_x_atoms_wm_protocols[protocol];
+
+ if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
+ return 0;
+
+ for (i = 0; i < protos_count; i++)
+ if (protos[i] == proto)
+ {
+ ret = 1;
+ break;
+ }
+
+ if (protos) XFree(protos);
+ return ret;
+
+}
+
+/**
+ * Set a window name & class.
+ * @param win The window
+ * @param n The name string
+ * @param c The class string
+ *
+ * Set a window name * class
+ */
+void
+ecore_x_icccm_name_class_set(Ecore_X_Window win, const char *n, const char *c)
+{
+ XClassHint *xch;
+
+ xch = XAllocClassHint();
+ if (!xch)
+ return;
+ xch->res_name = (char *)n;
+ xch->res_class = (char *)c;
+ XSetClassHint(_ecore_x_disp, win, xch);
+ XFree(xch);
+}
+
+/**
+ * Get a window name & class.
+ * @param win The window
+ * @param n The name string
+ * @param c The class string
+ *
+ * Get a window name * class
+ */
+void
+ecore_x_icccm_name_class_get(Ecore_X_Window win, char **n, char **c)
+{
+ XClassHint xch;
+
+ if (n) *n = NULL;
+ if (c) *c = NULL;
+ xch.res_name = NULL;
+ xch.res_class = NULL;
+ if (XGetClassHint(_ecore_x_disp, win, &xch))
+ {
+ if (n)
+ {
+ if (xch.res_name) *n = strdup(xch.res_name);
+ }
+ if (c)
+ {
+ if (xch.res_class) *c = strdup(xch.res_class);
+ }
+ XFree(xch.res_name);
+ XFree(xch.res_class);
+ }
+}
+
+/**
+ * Get a window client machine string.
+ * @param win The window
+ * @return The windows client machine string
+ *
+ * Return the client machine of a window. String must be free'd when done with.
+ */
+char *
+ecore_x_icccm_client_machine_get(Ecore_X_Window win)
+{
+ char *name;
+
+ name = ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_CLIENT_MACHINE);
+ return name;
+}
+
+/**
+ * Sets the WM_COMMAND property for @a win.
+ *
+ * @param win The window.
+ * @param argc Number of arguments.
+ * @param argv Arguments.
+ */
+void
+ecore_x_icccm_command_set(Ecore_X_Window win, int argc, char **argv)
+{
+ XSetCommand(_ecore_x_disp, win, argv, argc);
+}
+
+/**
+ * Get the WM_COMMAND property for @a win.
+ *
+ * Return the command of a window. String must be free'd when done with.
+ *
+ * @param win The window.
+ * @param argc Number of arguments.
+ * @param argv Arguments.
+ */
+void
+ecore_x_icccm_command_get(Ecore_X_Window win, int *argc, char ***argv)
+{
+ XGetCommand(_ecore_x_disp, win, argv, argc);
+}
+
+/**
+ * Set a window icon name.
+ * @param win The window
+ * @param t The icon name string
+ *
+ * Set a window icon name
+ */
+void
+ecore_x_icccm_icon_name_set(Ecore_X_Window win, const char *t)
+{
+ char *list[1];
+ XTextProperty xprop;
+ int ret;
+
+ xprop.value = NULL;
+#ifdef X_HAVE_UTF8_STRING
+ list[0] = strdup(t);
+ ret = Xutf8TextListToTextProperty(_ecore_x_disp, list, 1,
+ XUTF8StringStyle, &xprop);
+#else
+ list[0] = strdup(t);
+ ret = XmbTextListToTextProperty(_ecore_x_disp, list, 1,
+ XStdICCTextStyle, &xprop);
+#endif
+ if (ret >= Success)
+ {
+ XSetWMIconName(_ecore_x_disp, win, &xprop);
+ if (xprop.value) XFree(xprop.value);
+ }
+ else
+ {
+ if (XStringListToTextProperty(list, 1, &xprop) >= Success)
+ {
+ XSetWMIconName(_ecore_x_disp, win, &xprop);
+ if (xprop.value) XFree(xprop.value);
+ }
+ }
+ free(list[0]);
+}
+
+/**
+ * Get a window icon name.
+ * @param win The window
+ * @return The windows icon name string
+ *
+ * Return the icon name of a window. String must be free'd when done with.
+ */
+char *
+ecore_x_icccm_icon_name_get(Ecore_X_Window win)
+{
+ XTextProperty xprop;
+
+ xprop.value = NULL;
+ if (XGetWMIconName(_ecore_x_disp, win, &xprop) >= Success)
+ {
+ if (xprop.value)
+ {
+ char **list = NULL;
+ char *t = NULL;
+ int num = 0;
+ int ret;
+
+ if (xprop.encoding == ECORE_X_ATOM_UTF8_STRING)
+ {
+ t = strdup((char *)xprop.value);
+ }
+ else
+ {
+
+ /* convert to utf8 */
+#ifdef X_HAVE_UTF8_STRING
+ ret = Xutf8TextPropertyToTextList(_ecore_x_disp, &xprop,
+ &list, &num);
+#else
+ ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop,
+ &list, &num);
+#endif
+
+ if ((ret == XLocaleNotSupported) ||
+ (ret == XNoMemory) || (ret == XConverterNotFound))
+ {
+ t = strdup((char *)xprop.value);
+ }
+ else if (ret >= Success)
+ {
+ if ((num >= 1) && (list))
+ {
+ t = strdup(list[0]);
+ }
+ if (list)
+ XFreeStringList(list);
+ }
+ }
+
+ if (xprop.value) XFree(xprop.value);
+ return t;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Add a subwindow to the list of windows that need a different colormap installed.
+ * @param win The toplevel window
+ * @param subwin The subwindow to be added to the colormap windows list
+ */
+void
+ecore_x_icccm_colormap_window_set(Ecore_X_Window win, Ecore_X_Window subwin)
+{
+ int num = 0, i;
+ unsigned char *old_data = NULL;
+ unsigned char *data = NULL;
+ Window *oldset = NULL;
+ Window *newset = NULL;
+
+ if (!ecore_x_window_prop_property_get(win,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ XA_WINDOW, 32, &old_data, &num))
+ {
+ newset = calloc(1, sizeof(Window));
+ if (!newset)
+ return;
+ newset[0] = subwin;
+ num = 1;
+ data = (unsigned char *)newset;
+ }
+ else
+ {
+ newset = calloc(num + 1, sizeof(Window));
+ oldset = (Window *) old_data;
+ if (!newset)
+ return;
+ for (i = 0; i < num; ++i)
+ {
+ if (oldset[i] == subwin)
+ {
+ if (old_data) XFree(old_data);
+ old_data = NULL;
+ free(newset);
+ return;
+ }
+
+ newset[i] = oldset[i];
+ }
+
+ newset[num++] = subwin;
+ if (old_data) XFree(old_data);
+ data = (unsigned char *)newset;
+ }
+
+ ecore_x_window_prop_property_set(win,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ XA_WINDOW, 32, data, num);
+ free(newset);
+}
+
+/**
+ * Remove a window from the list of colormap windows.
+ * @param win The toplevel window
+ * @param subwin The window to be removed from the colormap window list.
+ */
+void
+ecore_x_icccm_colormap_window_unset(Ecore_X_Window win, Ecore_X_Window subwin)
+{
+ int num = 0, i, j, k = 0;
+ unsigned char *old_data = NULL;
+ unsigned char *data = NULL;
+ Window *oldset = NULL;
+ Window *newset = NULL;
+
+ if (!ecore_x_window_prop_property_get(win,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ XA_WINDOW, 32, &old_data, &num))
+ return;
+
+ oldset = (Window *) old_data;
+ for (i = 0; i < num; i++)
+ {
+ if (oldset[i] == subwin)
+ {
+ if (num == 1)
+ {
+ XDeleteProperty(_ecore_x_disp,
+ win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS);
+ if (old_data) XFree(old_data);
+ old_data = NULL;
+ return;
+ }
+ else
+ {
+ newset = calloc(num - 1, sizeof(Window));
+ data = (unsigned char *)newset;
+ for (j = 0; j < num; ++j)
+ if (oldset[j] != subwin)
+ newset[k++] = oldset[j];
+ ecore_x_window_prop_property_set(win,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ XA_WINDOW, 32, data, k);
+ if (old_data) XFree(old_data);
+ old_data = NULL;
+ free(newset);
+ return;
+ }
+ }
+ }
+
+ if (old_data) XFree(old_data);
+}
+
+/**
+ * Specify that a window is transient for another top-level window and should be handled accordingly.
+ * @param win the transient window
+ * @param forwin the toplevel window
+ */
+void
+ecore_x_icccm_transient_for_set(Ecore_X_Window win, Ecore_X_Window forwin)
+{
+ XSetTransientForHint(_ecore_x_disp, win, forwin);
+}
+
+/**
+ * Remove the transient_for setting from a window.
+ * @param The window
+ */
+void
+ecore_x_icccm_transient_for_unset(Ecore_X_Window win)
+{
+ XDeleteProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_TRANSIENT_FOR);
+}
+
+/**
+ * Get the window this window is transient for, if any.
+ * @param win The window to check
+ * @return The window ID of the top-level window, or 0 if the property does not exist.
+ */
+Ecore_X_Window
+ecore_x_icccm_transient_for_get(Ecore_X_Window win)
+{
+ Window forwin;
+
+ if (XGetTransientForHint(_ecore_x_disp, win, &forwin))
+ return (Ecore_X_Window) forwin;
+ else
+ return 0;
+
+}
+
+/**
+ * Set the window role hint.
+ * @param win The window
+ * @param role The role string
+ */
+void
+ecore_x_icccm_window_role_set(Ecore_X_Window win, const char *role)
+{
+ ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_WINDOW_ROLE,
+ (char *)role);
+}
+
+/**
+ * Get the window role.
+ * @param win The window
+ * @return The window's role string.
+ */
+char *
+ecore_x_icccm_window_role_get(Ecore_X_Window win)
+{
+ return ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_WINDOW_ROLE);
+}
+
+/**
+ * Set the window's client leader.
+ * @param win The window
+ * @param l The client leader window
+ *
+ * All non-transient top-level windows created by an app other than
+ * the main window must have this property set to the app's main window.
+ */
+void
+ecore_x_icccm_client_leader_set(Ecore_X_Window win, Ecore_X_Window l)
+{
+ ecore_x_window_prop_property_set(win,
+ ECORE_X_ATOM_WM_CLIENT_LEADER,
+ XA_WINDOW, 32, &l, 1);
+}
+
+/**
+ * Get the window's client leader.
+ * @param win The window
+ * @return The window's client leader window, or 0 if unset */
+Ecore_X_Window
+ecore_x_icccm_client_leader_get(Ecore_X_Window win)
+{
+ unsigned char *data;
+ int num;
+
+ if (ecore_x_window_prop_property_get(win,
+ ECORE_X_ATOM_WM_CLIENT_LEADER,
+ XA_WINDOW, 32, &data, &num))
+ {
+ if (data)
+ {
+ Ecore_X_Window wlead;
+
+ wlead = *((Ecore_X_Window *)data);
+ free(data);
+ return wlead;
+ }
+ }
+ return 0;
+}
+
+void
+ecore_x_icccm_iconic_request_send(Ecore_X_Window win, Ecore_X_Window root)
+{
+ XEvent xev;
+
+ if (!win) return;
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = ECORE_X_ATOM_WM_CHANGE_STATE;
+ xev.xclient.data.l[0] = IconicState;
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureNotifyMask | SubstructureRedirectMask, &xev);
+}
+
+/* FIXME: there are older E hints, gnome hints and mwm hints and new netwm */
+/* hints. each should go in their own file/section so we know which */
+/* is which. also older kde hints too. we should try support as much */
+/* as makese sense to support */
diff --git a/ecore/src/lib/ecore_x/ecore_x_mwm.c b/ecore/src/lib/ecore_x/ecore_x_mwm.c
new file mode 100644
index 0000000..caf9e49
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_mwm.c
@@ -0,0 +1,93 @@
+/*
+ * Various MWM related functions.
+ *
+ * This is ALL the code involving anything MWM related. for both WM and
+ * client.
+ */
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+#define ECORE_X_MWM_HINTS_FUNCTIONS (1 << 0)
+#define ECORE_X_MWM_HINTS_DECORATIONS (1 << 1)
+#define ECORE_X_MWM_HINTS_INPUT_MODE (1 << 2)
+#define ECORE_X_MWM_HINTS_STATUS (1 << 3)
+
+typedef struct _mwmhints
+{
+ CARD32 flags;
+ CARD32 functions;
+ CARD32 decorations;
+ INT32 inputmode;
+ CARD32 status;
+}
+MWMHints;
+
+/* Atoms */
+Ecore_X_Atom ECORE_X_ATOM_MOTIF_WM_HINTS = 0;
+
+int
+ecore_x_mwm_hints_get(Ecore_X_Window win,
+ Ecore_X_MWM_Hint_Func * fhint,
+ Ecore_X_MWM_Hint_Decor * dhint,
+ Ecore_X_MWM_Hint_Input * ihint)
+{
+ unsigned char *p = NULL;
+ MWMHints *mwmhints = NULL;
+ int num;
+ int ret;
+
+ ret = 0;
+ if (!ecore_x_window_prop_property_get(win,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ 32, &p, &num))
+ return 0;
+ mwmhints = (MWMHints *) p;
+ if (mwmhints)
+ {
+ if (num >= 4)
+ {
+ if (dhint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_DECORATIONS)
+ *dhint = mwmhints->decorations;
+ else
+ *dhint = ECORE_X_MWM_HINT_DECOR_ALL;
+ }
+ if (fhint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_FUNCTIONS)
+ *fhint = mwmhints->functions;
+ else
+ *fhint = ECORE_X_MWM_HINT_FUNC_ALL;
+ }
+ if (ihint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_INPUT_MODE)
+ *ihint = mwmhints->inputmode;
+ else
+ *ihint = ECORE_X_MWM_HINT_INPUT_MODELESS;
+ }
+ ret = 1;
+ }
+ free(mwmhints);
+ }
+ return ret;
+}
+
+void
+ecore_x_mwm_borderless_set(Ecore_X_Window win, int borderless)
+{
+ unsigned int data[5] = {0, 0, 0, 0, 0};
+
+ data[0] = 2; /* just set the decorations hint! */
+ data[2] = !borderless;
+
+ ecore_x_window_prop_property_set(win,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ 32, (void *)data, 5);
+}
+
diff --git a/ecore/src/lib/ecore_x/ecore_x_netwm.c b/ecore/src/lib/ecore_x/ecore_x_netwm.c
new file mode 100644
index 0000000..76d970e
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_netwm.c
@@ -0,0 +1,1238 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+/*
+ * _NET_WM... aka Extended Window Manager Hint (EWMH) functions.
+ */
+#include "config.h"
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+/*
+ * Convenience macros
+ */
+#define _ATOM_GET(name) \
+ XInternAtom(_ecore_x_disp, name, False)
+
+#define _ATOM_SET_UTF8_STRING(win, atom, string) \
+ XChangeProperty(_ecore_x_disp, win, atom, ECORE_X_ATOM_UTF8_STRING, 8, PropModeReplace, \
+ (unsigned char *)string, strlen(string))
+#define _ATOM_SET_UTF8_STRING_LIST(win, atom, string, cnt) \
+ XChangeProperty(_ecore_x_disp, win, atom, ECORE_X_ATOM_UTF8_STRING, 8, PropModeReplace, \
+ (unsigned char *)string, cnt)
+#define _ATOM_SET_WINDOW(win, atom, p_wins, cnt) \
+ XChangeProperty(_ecore_x_disp, win, atom, XA_WINDOW, 32, PropModeReplace, \
+ (unsigned char *)p_wins, cnt)
+#define _ATOM_SET_ATOM(win, atom, p_atom, cnt) \
+ XChangeProperty(_ecore_x_disp, win, atom, XA_ATOM, 32, PropModeReplace, \
+ (unsigned char *)p_atom, cnt)
+#define _ATOM_SET_CARD32(win, atom, p_val, cnt) \
+ XChangeProperty(_ecore_x_disp, win, atom, XA_CARDINAL, 32, PropModeReplace, \
+ (unsigned char *)p_val, cnt)
+
+/*
+ * Set UTF-8 string property
+ */
+static void
+_ecore_x_window_prop_string_utf8_set(Ecore_X_Window win, Ecore_X_Atom atom,
+ const char *str)
+{
+ _ATOM_SET_UTF8_STRING(win, atom, str);
+}
+
+/*
+ * Get UTF-8 string property
+ */
+static char *
+_ecore_x_window_prop_string_utf8_get(Ecore_X_Window win, Ecore_X_Atom atom)
+{
+ char *str;
+ unsigned char *prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+
+ str = NULL;
+ prop_ret = NULL;
+ XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
+ ECORE_X_ATOM_UTF8_STRING, &type_ret,
+ &format_ret, &num_ret, &bytes_after, &prop_ret);
+ if (prop_ret && num_ret > 0 && format_ret == 8)
+ {
+ str = malloc(num_ret + 1);
+ if (str)
+ {
+ memcpy(str, prop_ret, num_ret);
+ str[num_ret] = '\0';
+ }
+ }
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return str;
+}
+
+/*
+ * Root window NetWM hints.
+ */
+Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTED = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK = 0;
+
+Ecore_X_Atom ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_VIRTUAL_ROOTS = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_NAMES = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_GEOMETRY = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_VIEWPORT = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_LAYOUT = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WORKAREA = 0;
+
+Ecore_X_Atom ECORE_X_ATOM_NET_CURRENT_DESKTOP = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_SHOWING_DESKTOP = 0;
+
+Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST_STACKING = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_ACTIVE_WINDOW = 0;
+
+/*
+ * Client message types.
+ */
+Ecore_X_Atom ECORE_X_ATOM_NET_CLOSE_WINDOW = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_MOVERESIZE = 0;
+
+/*
+ * Pagers
+ */
+Ecore_X_Atom ECORE_X_ATOM_NET_MOVERESIZE_WINDOW = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_RESTACK_WINDOW = 0;
+
+/*
+ * Application window specific NetWM hints.
+ */
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_NAME = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_NAME = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_NAME = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_DESKTOP = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT_PARTIAL = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_GEOMETRY = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_PID = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_HANDLED_ICONS = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_USER_TIME = 0;
+
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MOVE = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_RESIZE = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_SHADE = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_STICK = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CLOSE = 0;
+
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL = 0;
+
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MODAL = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_STICKY = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SHADED = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_HIDDEN = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_ABOVE = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_BELOW = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION = 0;
+
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_OPACITY = 0;
+
+Ecore_X_Atom ECORE_X_ATOM_NET_FRAME_EXTENTS = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS = 0;
+
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_PING = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST = 0;
+Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER = 0;
+
+void
+ecore_x_netwm_init(void)
+{
+ ECORE_X_ATOM_NET_SUPPORTED = _ATOM_GET("_NET_SUPPORTED");
+ ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK = _ATOM_GET("_NET_SUPPORTING_WM_CHECK");
+
+ ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS = _ATOM_GET("_NET_NUMBER_OF_DESKTOPS");
+ ECORE_X_ATOM_NET_VIRTUAL_ROOTS = _ATOM_GET("_NET_VIRTUAL_ROOTS");
+ ECORE_X_ATOM_NET_DESKTOP_NAMES = _ATOM_GET("_NET_DESKTOP_NAMES");
+ ECORE_X_ATOM_NET_DESKTOP_GEOMETRY = _ATOM_GET("_NET_DESKTOP_GEOMETRY");
+ ECORE_X_ATOM_NET_DESKTOP_VIEWPORT = _ATOM_GET("_NET_DESKTOP_VIEWPORT");
+ ECORE_X_ATOM_NET_DESKTOP_LAYOUT = _ATOM_GET("_NET_DESKTOP_LAYOUT");
+ ECORE_X_ATOM_NET_WORKAREA = _ATOM_GET("_NET_WORKAREA");
+
+ ECORE_X_ATOM_NET_CURRENT_DESKTOP = _ATOM_GET("_NET_CURRENT_DESKTOP");
+ ECORE_X_ATOM_NET_SHOWING_DESKTOP = _ATOM_GET("_NET_SHOWING_DESKTOP");
+
+ ECORE_X_ATOM_NET_CLIENT_LIST = _ATOM_GET("_NET_CLIENT_LIST");
+ ECORE_X_ATOM_NET_CLIENT_LIST_STACKING =
+ _ATOM_GET("_NET_CLIENT_LIST_STACKING");
+ ECORE_X_ATOM_NET_ACTIVE_WINDOW = _ATOM_GET("_NET_ACTIVE_WINDOW");
+
+ ECORE_X_ATOM_NET_CLOSE_WINDOW = _ATOM_GET("_NET_CLOSE_WINDOW");
+ ECORE_X_ATOM_NET_WM_MOVERESIZE = _ATOM_GET("_NET_WM_MOVERESIZE");
+
+ ECORE_X_ATOM_NET_MOVERESIZE_WINDOW = _ATOM_GET("_NET_MOVERESIZE_WINDOW");
+ ECORE_X_ATOM_NET_RESTACK_WINDOW = _ATOM_GET("_NET_RESTACK_WINDOW");
+
+ ECORE_X_ATOM_NET_WM_NAME = _ATOM_GET("_NET_WM_NAME");
+ ECORE_X_ATOM_NET_WM_VISIBLE_NAME = _ATOM_GET("_NET_WM_VISIBLE_NAME");
+ ECORE_X_ATOM_NET_WM_ICON_NAME = _ATOM_GET("_NET_WM_ICON_NAME");
+ ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME =
+ _ATOM_GET("_NET_WM_VISIBLE_ICON_NAME");
+ ECORE_X_ATOM_NET_WM_DESKTOP = _ATOM_GET("_NET_WM_DESKTOP");
+ ECORE_X_ATOM_NET_WM_STRUT = _ATOM_GET("_NET_WM_STRUT");
+ ECORE_X_ATOM_NET_WM_STRUT_PARTIAL = _ATOM_GET("_NET_WM_STRUT_PARTIAL");
+ ECORE_X_ATOM_NET_WM_ICON_GEOMETRY = _ATOM_GET("_NET_WM_ICON_GEOMETRY");
+ ECORE_X_ATOM_NET_WM_ICON = _ATOM_GET("_NET_WM_ICON");
+ ECORE_X_ATOM_NET_WM_PID = _ATOM_GET("_NET_WM_PID");
+ ECORE_X_ATOM_NET_WM_HANDLED_ICONS = _ATOM_GET("_NET_WM_HANDLED_ICONS");
+ ECORE_X_ATOM_NET_WM_USER_TIME = _ATOM_GET("_NET_WM_USER_TIME");
+
+ ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS = _ATOM_GET("_NET_WM_ALLOWED_ACTIONS");
+ ECORE_X_ATOM_NET_WM_ACTION_MOVE = _ATOM_GET("_NET_WM_ACTION_MOVE");
+ ECORE_X_ATOM_NET_WM_ACTION_RESIZE = _ATOM_GET("_NET_WM_ACTION_RESIZE");
+ ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE = _ATOM_GET("_NET_WM_ACTION_MINIMIZE");
+ ECORE_X_ATOM_NET_WM_ACTION_SHADE = _ATOM_GET("_NET_WM_ACTION_SHADE");
+ ECORE_X_ATOM_NET_WM_ACTION_STICK = _ATOM_GET("_NET_WM_ACTION_STICK");
+ ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ = _ATOM_GET("_NET_WM_ACTION_MAXIMIZE_HORZ");
+ ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT = _ATOM_GET("_NET_WM_ACTION_MAXIMIZE_VERT");
+ ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN = _ATOM_GET("_NET_WM_ACTION_FULLSCREEN");
+ ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP = _ATOM_GET("_NET_WM_ACTION_CHANGE_DESKTOP");
+ ECORE_X_ATOM_NET_WM_ACTION_CLOSE = _ATOM_GET("_NET_WM_ACTION_CLOSE");
+
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE = _ATOM_GET("_NET_WM_WINDOW_TYPE");
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP =
+ _ATOM_GET("_NET_WM_WINDOW_TYPE_DESKTOP");
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK = _ATOM_GET("_NET_WM_WINDOW_TYPE_DOCK");
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR =
+ _ATOM_GET("_NET_WM_WINDOW_TYPE_TOOLBAR");
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU = _ATOM_GET("_NET_WM_WINDOW_TYPE_MENU");
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY =
+ _ATOM_GET("_NET_WM_WINDOW_TYPE_UTILITY");
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH =
+ _ATOM_GET("_NET_WM_WINDOW_TYPE_SPLASH");
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG =
+ _ATOM_GET("_NET_WM_WINDOW_TYPE_DIALOG");
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL =
+ _ATOM_GET("_NET_WM_WINDOW_TYPE_NORMAL");
+
+ ECORE_X_ATOM_NET_WM_STATE = _ATOM_GET("_NET_WM_STATE");
+ ECORE_X_ATOM_NET_WM_STATE_MODAL = _ATOM_GET("_NET_WM_STATE_MODAL");
+ ECORE_X_ATOM_NET_WM_STATE_STICKY = _ATOM_GET("_NET_WM_STATE_STICKY");
+ ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT =
+ _ATOM_GET("_NET_WM_STATE_MAXIMIZED_VERT");
+ ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ =
+ _ATOM_GET("_NET_WM_STATE_MAXIMIZED_HORZ");
+ ECORE_X_ATOM_NET_WM_STATE_SHADED = _ATOM_GET("_NET_WM_STATE_SHADED");
+ ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR =
+ _ATOM_GET("_NET_WM_STATE_SKIP_TASKBAR");
+ ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER = _ATOM_GET("_NET_WM_STATE_SKIP_PAGER");
+ ECORE_X_ATOM_NET_WM_STATE_HIDDEN = _ATOM_GET("_NET_WM_STATE_HIDDEN");
+ ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN = _ATOM_GET("_NET_WM_STATE_FULLSCREEN");
+ ECORE_X_ATOM_NET_WM_STATE_ABOVE = _ATOM_GET("_NET_WM_STATE_ABOVE");
+ ECORE_X_ATOM_NET_WM_STATE_BELOW = _ATOM_GET("_NET_WM_STATE_BELOW");
+ ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION = _ATOM_GET("_NET_WM_STATE_DEMANDS_ATTENTION");
+
+ ECORE_X_ATOM_NET_WM_WINDOW_OPACITY = _ATOM_GET("_NET_WM_WINDOW_OPACITY");
+
+ ECORE_X_ATOM_NET_FRAME_EXTENTS = _ATOM_GET("_NET_FRAME_EXTENTS");
+ ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS = _ATOM_GET("_NET_REQUEST_FRAME_EXTENTS");
+
+ ECORE_X_ATOM_NET_WM_PING = _ATOM_GET("_NET_WM_PING");
+ ECORE_X_ATOM_NET_WM_SYNC_REQUEST = _ATOM_GET("_NET_WM_SYNC_REQUEST");
+ ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER = _ATOM_GET("_NET_WM_SYNC_REQUEST_COUNTER");
+}
+
+/*
+ * WM identification
+ */
+void
+ecore_x_netwm_wm_identify(Ecore_X_Window root, Ecore_X_Window check,
+ const char *wm_name)
+{
+ _ATOM_SET_WINDOW(root, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1);
+ _ATOM_SET_WINDOW(check, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1);
+ _ATOM_SET_UTF8_STRING(check, ECORE_X_ATOM_NET_WM_NAME, wm_name);
+ /* This one isn't mandatory */
+ _ATOM_SET_UTF8_STRING(root, ECORE_X_ATOM_NET_WM_NAME, wm_name);
+}
+
+/*
+ * Set supported atoms
+ */
+void
+ecore_x_netwm_supported_set(Ecore_X_Window root, Ecore_X_Atom *supported, int num)
+{
+ _ATOM_SET_ATOM(root, ECORE_X_ATOM_NET_SUPPORTED, supported, num);
+}
+
+int
+ecore_x_netwm_supported_get(Ecore_X_Window root, Ecore_X_Atom **supported, int *num)
+{
+ int num_ret;
+ unsigned char *data;
+
+ if (num) *num = 0;
+ if (supported) *supported = NULL;
+
+ if (!ecore_x_window_prop_property_get(root, ECORE_X_ATOM_NET_SUPPORTED,
+ XA_ATOM, 32, &data, &num_ret))
+ return 0;
+
+ if ((!data) || (!num_ret)) return 0;
+
+ if (num) *num = num_ret;
+ if (supported) *supported = (Ecore_X_Atom *)data;
+ return 1;
+}
+
+/*
+ * Desktop configuration and status
+ */
+void
+ecore_x_netwm_desk_count_set(Ecore_X_Window root, unsigned int n_desks)
+{
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS,
+ &n_desks, 1);
+}
+
+void
+ecore_x_netwm_desk_roots_set(Ecore_X_Window root,
+ Ecore_X_Window *vroots, unsigned int n_desks)
+{
+ _ATOM_SET_WINDOW(root, ECORE_X_ATOM_NET_VIRTUAL_ROOTS, vroots, n_desks);
+}
+
+void
+ecore_x_netwm_desk_names_set(Ecore_X_Window root,
+ const char **names, unsigned int n_desks)
+{
+ char ss[32], *buf;
+ const char *s;
+ unsigned int i;
+ int l, len;
+
+ buf = NULL;
+ len = 0;
+
+ for (i = 0; i < n_desks; i++)
+ {
+ s = (names) ? names[i] : NULL;
+ if (!s)
+ {
+ /* Default to "Desk-<number>" */
+ sprintf(ss, "Desk-%d", i);
+ s = ss;
+ }
+
+ l = strlen(s) + 1;
+ buf = realloc(buf, len + l);
+ memcpy(buf + len, s, l);
+ len += l;
+ }
+
+ _ATOM_SET_UTF8_STRING_LIST(root, ECORE_X_ATOM_NET_DESKTOP_NAMES, buf, len);
+
+ free(buf);
+}
+
+void
+ecore_x_netwm_desk_size_set(Ecore_X_Window root, unsigned int width,
+ unsigned int height)
+{
+ unsigned int size[2];
+
+ size[0] = width;
+ size[1] = height;
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_GEOMETRY, size,
+ 2);
+}
+
+void
+ecore_x_netwm_desk_viewports_set(Ecore_X_Window root,
+ unsigned int *origins, unsigned int n_desks)
+{
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_VIEWPORT,
+ origins, 2 * n_desks);
+}
+
+void
+ecore_x_netwm_desk_layout_set(Ecore_X_Window root, int orientation,
+ int columns, int rows,
+ int starting_corner)
+{
+ unsigned int layout[4];
+
+ layout[0] = orientation;
+ layout[1] = columns;
+ layout[2] = rows;
+ layout[3] = starting_corner;
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_LAYOUT,
+ layout, 4);
+}
+
+void
+ecore_x_netwm_desk_workareas_set(Ecore_X_Window root,
+ unsigned int *areas, unsigned int n_desks)
+{
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_WORKAREA, areas,
+ 4 * n_desks);
+}
+
+void
+ecore_x_netwm_desk_current_set(Ecore_X_Window root, unsigned int desk)
+{
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_CURRENT_DESKTOP, &desk,
+ 1);
+}
+
+void
+ecore_x_netwm_showing_desktop_set(Ecore_X_Window root, int on)
+{
+ unsigned int val;
+
+ val = (on) ? 1 : 0;
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_SHOWING_DESKTOP, &val,
+ 1);
+}
+
+/*
+ * Client status
+ */
+
+/* Mapping order */
+void
+ecore_x_netwm_client_list_set(Ecore_X_Window root,
+ Ecore_X_Window *p_clients, unsigned int n_clients)
+{
+ _ATOM_SET_WINDOW(root, ECORE_X_ATOM_NET_CLIENT_LIST, p_clients, n_clients);
+}
+
+/* Stacking order */
+void
+ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root,
+ Ecore_X_Window *p_clients,
+ unsigned int n_clients)
+{
+ _ATOM_SET_WINDOW(root, ECORE_X_ATOM_NET_CLIENT_LIST_STACKING, p_clients,
+ n_clients);
+}
+
+void
+ecore_x_netwm_client_active_set(Ecore_X_Window root, Ecore_X_Window win)
+{
+ _ATOM_SET_WINDOW(root, ECORE_X_ATOM_NET_ACTIVE_WINDOW, &win, 1);
+}
+
+void
+ecore_x_netwm_name_set(Ecore_X_Window win, const char *name)
+{
+ _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_NAME, name);
+}
+
+int
+ecore_x_netwm_name_get(Ecore_X_Window win, char **name)
+{
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(win, ECORE_X_ATOM_NET_WM_NAME);
+ return 1;
+}
+
+void
+ecore_x_netwm_visible_name_set(Ecore_X_Window win, const char *name)
+{
+ _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_VISIBLE_NAME,
+ name);
+}
+
+int
+ecore_x_netwm_visible_name_get(Ecore_X_Window win, char **name)
+{
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(win,
+ ECORE_X_ATOM_NET_WM_VISIBLE_NAME);
+ return 1;
+}
+
+void
+ecore_x_netwm_icon_name_set(Ecore_X_Window win, const char *name)
+{
+ _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_ICON_NAME,
+ name);
+}
+
+int
+ecore_x_netwm_icon_name_get(Ecore_X_Window win, char **name)
+{
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(win,
+ ECORE_X_ATOM_NET_WM_ICON_NAME);
+ return 1;
+}
+
+void
+ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win, const char *name)
+{
+ _ecore_x_window_prop_string_utf8_set(win,
+ ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME,
+ name);
+}
+
+int
+ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win, char **name)
+{
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(win,
+ ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME);
+ return 1;
+}
+
+void
+ecore_x_netwm_desktop_set(Ecore_X_Window win, unsigned int desk)
+{
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1);
+}
+
+int
+ecore_x_netwm_desktop_get(Ecore_X_Window win, unsigned int *desk)
+{
+ int ret;
+ unsigned int tmp;
+
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_DESKTOP,
+ &tmp, 1);
+
+ if (desk) *desk = tmp;
+ return ret == 1 ? 1 : 0;
+}
+
+/*
+ * _NET_WM_STRUT is deprecated
+ */
+void
+ecore_x_netwm_strut_set(Ecore_X_Window win, int left, int right,
+ int top, int bottom)
+{
+ unsigned int strut[4];
+
+ strut[0] = left;
+ strut[1] = right;
+ strut[2] = top;
+ strut[3] = bottom;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
+}
+
+/*
+ * _NET_WM_STRUT is deprecated
+ */
+int
+ecore_x_netwm_strut_get(Ecore_X_Window win, int *left, int *right,
+ int *top, int *bottom)
+{
+ int ret = 0;
+ unsigned int strut[4];
+
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
+ if (ret != 4)
+ return 0;
+
+ if (left) *left = strut[0];
+ if (right) *right = strut[1];
+ if (top) *top = strut[2];
+ if (bottom) *bottom = strut[3];
+ return 1;
+}
+
+void
+ecore_x_netwm_strut_partial_set(Ecore_X_Window win, int left, int right,
+ int top, int bottom, int left_start_y, int left_end_y,
+ int right_start_y, int right_end_y, int top_start_x,
+ int top_end_x, int bottom_start_x, int bottom_end_x)
+{
+ unsigned int strut[12];
+
+ strut[0] = left;
+ strut[1] = right;
+ strut[2] = top;
+ strut[3] = bottom;
+ strut[4] = left_start_y;
+ strut[5] = left_end_y;
+ strut[6] = right_start_y;
+ strut[7] = right_end_y;
+ strut[8] = top_start_x;
+ strut[9] = top_end_x;
+ strut[10] = bottom_start_x;
+ strut[11] = bottom_end_x;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12);
+}
+
+int
+ecore_x_netwm_strut_partial_get(Ecore_X_Window win, int *left, int *right,
+ int *top, int *bottom, int *left_start_y, int *left_end_y,
+ int *right_start_y, int *right_end_y, int *top_start_x,
+ int *top_end_x, int *bottom_start_x, int *bottom_end_x)
+{
+ int ret = 0;
+ unsigned int strut[12];
+
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12);
+ if (ret != 12)
+ return 0;
+
+ if (left) *left = strut[0];
+ if (right) *right = strut[1];
+ if (top) *top = strut[2];
+ if (bottom) *bottom = strut[3];
+ if (left_start_y) *left_start_y = strut[4];
+ if (left_end_y) *left_end_y = strut[5];
+ if (right_start_y) *right_start_y = strut[6];
+ if (right_end_y) *right_end_y = strut[7];
+ if (top_start_x) *top_start_x = strut[8];
+ if (top_end_x) *top_end_x = strut[9];
+ if (bottom_start_x) *bottom_start_x = strut[10];
+ if (bottom_end_x) *bottom_end_x = strut[11];
+ return 1;
+}
+
+int
+ecore_x_netwm_icon_get(Ecore_X_Window win, int *width, int *height, unsigned int **icon, int *num)
+{
+ unsigned char *data_ret;
+ unsigned int *data;
+ unsigned int *src;
+ int num_ret, len;
+
+ if (width) *width = 0;
+ if (height) *height = 0;
+ if (num) *num = 0;
+
+ if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_NET_WM_ICON,
+ XA_CARDINAL, 32, &data_ret, &num_ret))
+ return 0;
+ data = (unsigned int *)data_ret;
+
+ if (icon)
+ {
+ *icon = malloc((num_ret - 2) * sizeof(unsigned int));
+ if (!(*icon)) return 0;
+ }
+
+ if (num) *num = (num_ret - 2);
+ if (width) *width = data[0];
+ if (height) *height = data[1];
+
+ len = data[0] * data[1];
+ src = &(data[2]);
+ if (icon)
+ memcpy(*icon, &(data[2]), len * sizeof(unsigned int));
+ free(data_ret);
+
+ return 1;
+}
+
+void
+ecore_x_netwm_icon_geometry_set(Ecore_X_Window win, int x, int y, int width, int height)
+{
+ unsigned int geometry[4];
+
+ geometry[0] = x;
+ geometry[1] = y;
+ geometry[2] = width;
+ geometry[3] = height;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4);
+}
+
+int
+ecore_x_netwm_icon_geometry_get(Ecore_X_Window win, int *x, int *y, int *width, int *height)
+{
+ int ret;
+ unsigned int geometry[4];
+
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4);
+ if (ret != 4)
+ return 0;
+
+ if (x) *x = geometry[0];
+ if (y) *y = geometry[1];
+ if (width) *width = geometry[2];
+ if (height) *height = geometry[3];
+ return 1;
+}
+
+void
+ecore_x_netwm_pid_set(Ecore_X_Window win, int pid)
+{
+ unsigned int tmp;
+
+ tmp = pid;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_PID,
+ &tmp, 1);
+}
+
+int
+ecore_x_netwm_pid_get(Ecore_X_Window win, int *pid)
+{
+ int ret;
+ unsigned int tmp;
+
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_PID,
+ &tmp, 1);
+ if (pid) *pid = tmp;
+ return ret == 1 ? 1 : 0;
+}
+
+void
+ecore_x_netwm_handled_icons_set(Ecore_X_Window win)
+{
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
+ NULL, 0);
+}
+
+int
+ecore_x_netwm_handled_icons_get(Ecore_X_Window win)
+{
+ int ret = 0;
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
+ NULL, 0);
+ return ret == 0 ? 1 : 0;
+}
+
+void
+ecore_x_netwm_user_time_set(Ecore_X_Window win, unsigned int time)
+{
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME,
+ &time, 1);
+}
+
+int
+ecore_x_netwm_user_time_get(Ecore_X_Window win, unsigned int *time)
+{
+ int ret;
+ unsigned int tmp;
+
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_USER_TIME,
+ &tmp, 1);
+ if (time) *time = tmp;
+ return ret == 1 ? 1 : 0;
+}
+
+Ecore_X_Window_State
+_ecore_x_netwm_state_get(Ecore_X_Atom a)
+{
+ if (a == ECORE_X_ATOM_NET_WM_STATE_MODAL)
+ return ECORE_X_WINDOW_STATE_MODAL;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_STICKY)
+ return ECORE_X_WINDOW_STATE_STICKY;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT)
+ return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ)
+ return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_SHADED)
+ return ECORE_X_WINDOW_STATE_SHADED;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR)
+ return ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER)
+ return ECORE_X_WINDOW_STATE_SKIP_PAGER;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_HIDDEN)
+ return ECORE_X_WINDOW_STATE_HIDDEN;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN)
+ return ECORE_X_WINDOW_STATE_FULLSCREEN;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_ABOVE)
+ return ECORE_X_WINDOW_STATE_ABOVE;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_BELOW)
+ return ECORE_X_WINDOW_STATE_BELOW;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION)
+ return ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION;
+ else
+ return ECORE_X_WINDOW_STATE_UNKNOWN;
+}
+
+static Ecore_X_Atom
+_ecore_x_netwm_state_atom_get(Ecore_X_Window_State s)
+{
+ switch(s)
+ {
+ case ECORE_X_WINDOW_STATE_MODAL:
+ return ECORE_X_ATOM_NET_WM_STATE_MODAL;
+ case ECORE_X_WINDOW_STATE_STICKY:
+ return ECORE_X_ATOM_NET_WM_STATE_STICKY;
+ case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT:
+ return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT;
+ case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ:
+ return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ;
+ case ECORE_X_WINDOW_STATE_SHADED:
+ return ECORE_X_ATOM_NET_WM_STATE_SHADED;
+ case ECORE_X_WINDOW_STATE_SKIP_TASKBAR:
+ return ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR;
+ case ECORE_X_WINDOW_STATE_SKIP_PAGER:
+ return ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER;
+ case ECORE_X_WINDOW_STATE_HIDDEN:
+ return ECORE_X_ATOM_NET_WM_STATE_HIDDEN;
+ case ECORE_X_WINDOW_STATE_FULLSCREEN:
+ return ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN;
+ case ECORE_X_WINDOW_STATE_ABOVE:
+ return ECORE_X_ATOM_NET_WM_STATE_ABOVE;
+ case ECORE_X_WINDOW_STATE_BELOW:
+ return ECORE_X_ATOM_NET_WM_STATE_BELOW;
+ case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION:
+ return ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION;
+ default:
+ return 0;
+ }
+}
+
+void
+ecore_x_netwm_window_state_set(Ecore_X_Window win, Ecore_X_Window_State *state, unsigned int num)
+{
+ unsigned char *data;
+ Ecore_X_Atom *set;
+ int i;
+
+ if (!num)
+ {
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_NET_WM_STATE);
+ return;
+ }
+
+ data = malloc(num * sizeof(Ecore_X_Atom));
+ if (!data) return;
+
+ set = (Ecore_X_Atom *) data;
+ for (i = 0; i < num; i++)
+ set[i] = _ecore_x_netwm_state_atom_get(state[i]);
+
+ _ATOM_SET_ATOM(win, ECORE_X_ATOM_NET_WM_STATE, data, num);
+
+ free(data);
+ return;
+}
+
+int
+ecore_x_netwm_window_state_get(Ecore_X_Window win, Ecore_X_Window_State **state, unsigned int *num)
+{
+ int num_ret, i;
+ unsigned char *data;
+ Ecore_X_Atom *atoms;
+
+ if (num) *num = 0;
+ if (state) *state = NULL;
+
+ if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_NET_WM_STATE,
+ XA_ATOM, 32, &data, &num_ret))
+ return 0;
+
+ if ((!data) || (!num_ret)) return 0;
+
+ atoms = (Ecore_X_Atom *) data;
+ if (state)
+ {
+ *state = malloc(num_ret * sizeof(Ecore_X_Window_State));
+ if (*state)
+ for (i = 0; i < num_ret; ++i)
+ (*state)[i] = _ecore_x_netwm_state_get(atoms[i]);
+
+ if (num) *num = num_ret;
+ }
+
+ free(data);
+ return 1;
+}
+
+static Ecore_X_Window_Type
+_ecore_x_netwm_window_type_type_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP)
+ return ECORE_X_WINDOW_TYPE_DESKTOP;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK)
+ return ECORE_X_WINDOW_TYPE_DOCK;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR)
+ return ECORE_X_WINDOW_TYPE_TOOLBAR;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU)
+ return ECORE_X_WINDOW_TYPE_MENU;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY)
+ return ECORE_X_WINDOW_TYPE_UTILITY;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH)
+ return ECORE_X_WINDOW_TYPE_SPLASH;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG)
+ return ECORE_X_WINDOW_TYPE_DIALOG;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL)
+ return ECORE_X_WINDOW_TYPE_NORMAL;
+ else
+ return ECORE_X_WINDOW_TYPE_UNKNOWN;
+}
+
+static Ecore_X_Atom
+_ecore_x_netwm_window_type_atom_get(Ecore_X_Window_Type type)
+{
+ switch (type)
+ {
+ case ECORE_X_WINDOW_TYPE_DESKTOP:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP;
+ case ECORE_X_WINDOW_TYPE_DOCK:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK;
+ case ECORE_X_WINDOW_TYPE_TOOLBAR:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR;
+ case ECORE_X_WINDOW_TYPE_MENU:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU;
+ case ECORE_X_WINDOW_TYPE_UTILITY:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY;
+ case ECORE_X_WINDOW_TYPE_SPLASH:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH;
+ case ECORE_X_WINDOW_TYPE_DIALOG:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG;
+ case ECORE_X_WINDOW_TYPE_NORMAL:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL;
+ default:
+ return 0;
+ }
+}
+
+/*
+ * FIXME: We should set WM_TRANSIENT_FOR if type is ECORE_X_WINDOW_TYPE_TOOLBAR
+ * , ECORE_X_WINDOW_TYPE_MENU or ECORE_X_WINDOW_TYPE_DIALOG
+ */
+void
+ecore_x_netwm_window_type_set(Ecore_X_Window win, Ecore_X_Window_Type type)
+{
+ Ecore_X_Atom atom;
+
+ atom = _ecore_x_netwm_window_type_atom_get(type);
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ XA_ATOM, 32, (unsigned char *)&atom, 1);
+}
+
+/* FIXME: Maybe return 0 on some conditions? */
+int
+ecore_x_netwm_window_type_get(Ecore_X_Window win, Ecore_X_Window_Type *type)
+{
+ int num, i;
+ unsigned char *data;
+ Ecore_X_Atom *atoms;
+
+ if (type) *type = ECORE_X_WINDOW_TYPE_NORMAL;
+
+ if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ XA_ATOM, 32, &data, &num))
+ {
+ /* Check if WM_TRANSIENT_FOR is set */
+ if ((type) && (ecore_x_icccm_transient_for_get(win)))
+ *type = ECORE_X_WINDOW_TYPE_DIALOG;
+ return 1;
+ }
+
+ atoms = (Ecore_X_Atom *) data;
+
+ if (type)
+ {
+ for (i = 0; i < num; ++i)
+ {
+ *type = _ecore_x_netwm_window_type_type_get(atoms[i]);
+ if (*type != ECORE_X_WINDOW_TYPE_UNKNOWN)
+ break;
+ }
+ }
+
+ free(data);
+ return 1;
+}
+
+static Ecore_X_Atom
+_ecore_x_netwm_action_atom_get(Ecore_X_Action action)
+{
+ switch (action)
+ {
+ case ECORE_X_ACTION_MOVE:
+ return ECORE_X_ATOM_NET_WM_ACTION_MOVE;
+ case ECORE_X_ACTION_RESIZE:
+ return ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
+ case ECORE_X_ACTION_MINIMIZE:
+ return ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
+ case ECORE_X_ACTION_SHADE:
+ return ECORE_X_ATOM_NET_WM_ACTION_SHADE;
+ case ECORE_X_ACTION_STICK:
+ return ECORE_X_ATOM_NET_WM_ACTION_STICK;
+ case ECORE_X_ACTION_MAXIMIZE_HORZ:
+ return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
+ case ECORE_X_ACTION_MAXIMIZE_VERT:
+ return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
+ case ECORE_X_ACTION_FULLSCREEN:
+ return ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
+ case ECORE_X_ACTION_CHANGE_DESKTOP:
+ return ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
+ case ECORE_X_ACTION_CLOSE:
+ return ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
+ default:
+ return 0;
+ }
+}
+
+/* FIXME: Get complete list */
+int
+ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, Ecore_X_Action action)
+{
+ int num, i, ret = 0;
+ unsigned char *data;
+ Ecore_X_Atom *atoms, atom;
+
+ if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ XA_ATOM, 32, &data, &num))
+ return ret;
+
+ atom = _ecore_x_netwm_action_atom_get(action);
+ atoms = (Ecore_X_Atom *) data;
+
+ for (i = 0; i < num; ++i)
+ {
+ if (atom == atoms[i])
+ {
+ ret = 1;
+ break;
+ }
+ }
+
+ free(data);
+ return ret;
+}
+
+/* FIXME: Set complete list */
+void
+ecore_x_netwm_allowed_action_set(Ecore_X_Window win, Ecore_X_Action action, int on)
+{
+ Ecore_X_Atom atom;
+ Ecore_X_Atom *oldset = NULL, *newset = NULL;
+ int i, j = 0, num = 0;
+ unsigned char *data = NULL;
+ unsigned char *old_data = NULL;
+
+ atom = _ecore_x_netwm_action_atom_get(action);
+
+ ecore_x_window_prop_property_get(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
+ XA_ATOM, 32, &old_data, &num);
+ oldset = (Ecore_X_Atom *) old_data;
+
+ if (on)
+ {
+ for (i = 0; i < num; ++i)
+ {
+ if (oldset[i] == atom)
+ goto done;
+ }
+
+ newset = calloc(num + 1, sizeof(Ecore_X_Atom));
+ if (!newset)
+ goto done;
+
+ data = (unsigned char *) newset;
+ for (i = 0; i < num; i++)
+ newset[i] = oldset[i];
+ newset[num] = atom;
+
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
+ XA_ATOM, 32, data, num + 1);
+ }
+ else
+ {
+ int has;
+
+ has = 0;
+ for (i = 0; i < num; ++i)
+ {
+ if (oldset[i] == atom)
+ has = 1;
+ }
+ if (!has)
+ goto done;
+
+ newset = calloc(num - 1, sizeof(Ecore_X_Atom));
+ if (!newset)
+ goto done;
+
+ data = (unsigned char *) newset;
+ for (i = 0; i < num; i++)
+ if (oldset[i] != atom)
+ newset[j++] = oldset[i];
+
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
+ XA_ATOM, 32, data, num - 1);
+ }
+ free(newset);
+done:
+ free(oldset);
+}
+
+void
+ecore_x_netwm_opacity_set(Ecore_X_Window win, unsigned int opacity)
+{
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
+ &opacity, 1);
+}
+
+int
+ecore_x_netwm_opacity_get(Ecore_X_Window win, unsigned int *opacity)
+{
+ int ret;
+ unsigned int tmp;
+
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
+ &tmp, 1);
+ if (opacity) *opacity = tmp;
+ return ret == 1 ? 1 : 0;
+}
+
+void
+ecore_x_netwm_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb)
+{
+ unsigned int frames[4];
+
+ frames[0] = fl;
+ frames[1] = fr;
+ frames[2] = ft;
+ frames[3] = fb;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4);
+}
+
+int
+ecore_x_netwm_frame_size_get(Ecore_X_Window win, int *fl, int *fr, int *ft, int *fb)
+{
+ int ret = 0;
+ unsigned int frames[4];
+
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4);
+ if (ret != 4)
+ return 0;
+
+ if (fl) *fl = frames[0];
+ if (fr) *fr = frames[1];
+ if (ft) *ft = frames[2];
+ if (fb) *fb = frames[3];
+ return 1;
+}
+
+int
+ecore_x_netwm_sync_counter_get(Ecore_X_Window win, Ecore_X_Sync_Counter *counter)
+{
+ int ret;
+ unsigned int tmp;
+
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER,
+ &tmp, 1);
+
+ if (counter) *counter = tmp;
+ return ret == 1 ? 1 : 0;
+}
+
+void
+ecore_x_netwm_ping_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ if (!win) return;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_PING;
+ xev.xclient.data.l[1] = CurrentTime;
+ xev.xclient.data.l[2] = win;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+ xev.xclient.data.l[5] = 0;
+
+ XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
+}
+
+void
+ecore_x_netwm_sync_request_send(Ecore_X_Window win, unsigned int serial)
+{
+ XSyncValue value;
+ XEvent xev;
+
+ if (!win) return;
+
+ XSyncIntToValue(&value, serial);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
+ xev.xclient.data.l[1] = CurrentTime;
+ xev.xclient.data.l[2] = XSyncValueLow32(value);
+ xev.xclient.data.l[3] = XSyncValueHigh32(value);
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(_ecore_x_disp, win, False, 0, &xev);
+}
+
+void
+ecore_x_netwm_state_request_send(Ecore_X_Window win, Ecore_X_Window root,
+ Ecore_X_Window_State s1, Ecore_X_Window_State s2, int set)
+{
+ XEvent xev;
+
+ if (!win) return;
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = ECORE_X_ATOM_NET_WM_STATE;
+ xev.xclient.data.l[0] = !!set;
+ xev.xclient.data.l[1] = _ecore_x_netwm_state_atom_get(s1);
+ xev.xclient.data.l[2] = _ecore_x_netwm_state_atom_get(s2);
+ /* 1 == normal client, if someone wants to use this
+ * function in a pager, this should be 2 */
+ xev.xclient.data.l[3] = 1;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(_ecore_x_disp, root, False, 0, &xev);
+}
+
+void
+ecore_x_netwm_desktop_request_send(Ecore_X_Window win, Ecore_X_Window root, unsigned int desktop)
+{
+ XEvent xev;
+
+ if (!win) return;
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = ECORE_X_ATOM_NET_WM_DESKTOP;
+ xev.xclient.data.l[0] = desktop;
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureNotifyMask | SubstructureRedirectMask, &xev);
+}
diff --git a/ecore/src/lib/ecore_x/ecore_x_pixmap.c b/ecore/src/lib/ecore_x/ecore_x_pixmap.c
new file mode 100644
index 0000000..bfc96a2
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_pixmap.c
@@ -0,0 +1,95 @@
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+/**
+ * @defgroup Ecore_X_Pixmap_Group X Pixmap Functions
+ *
+ * Functions that operate on pixmaps.
+ */
+
+/**
+ * Creates a new pixmap.
+ * @param win Window used to determine which screen of the display the
+ * pixmap should be created on. If 0, the default root window
+ * is used.
+ * @param w Width of the new pixmap.
+ * @param h Height of the new pixmap.
+ * @param dep Depth of the pixmap. If 0, the default depth of the default
+ * screen is used.
+ * @return New pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+Ecore_X_Pixmap
+ecore_x_pixmap_new(Ecore_X_Window win, int w, int h, int dep)
+{
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+ if (dep == 0) dep = DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp));
+ return XCreatePixmap(_ecore_x_disp, win, w, h, dep);
+}
+
+/**
+ * Deletes the reference to the given pixmap.
+ *
+ * If no other clients have a reference to the given pixmap, the server
+ * will destroy it.
+ *
+ * @param pmap The given pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+void
+ecore_x_pixmap_del(Ecore_X_Pixmap pmap)
+{
+ XFreePixmap(_ecore_x_disp, pmap);
+}
+
+/**
+ * Pastes a rectangular area of the given pixmap onto the given drawable.
+ * @param pmap The given pixmap.
+ * @param dest The given drawable.
+ * @param gc The graphics context which governs which operation will
+ * be used to paste the area onto the drawable.
+ * @param sx The X position of the area on the pixmap.
+ * @param sy The Y position of the area on the pixmap.
+ * @param w The width of the area.
+ * @param h The height of the area.
+ * @param dx The X position at which to paste the area on @p dest.
+ * @param dy The Y position at which to paste the area on @p dest.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+void
+ecore_x_pixmap_paste(Ecore_X_Pixmap pmap, Ecore_X_Drawable dest,
+ Ecore_X_GC gc, int sx, int sy,
+ int w, int h, int dx, int dy)
+{
+ XCopyArea(_ecore_x_disp, pmap, dest, gc, sx, sy, w, h, dx, dy);
+}
+
+/**
+ * Retrieves the size of the given pixmap.
+ * @param pmap The given pixmap.
+ * @param x Pointer to an integer in which to store the X position.
+ * @param y Pointer to an integer in which to store the Y position.
+ * @param w Pointer to an integer in which to store the width.
+ * @param h Pointer to an integer in which to store the height.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+void
+ecore_x_pixmap_geometry_get(Ecore_X_Pixmap pmap, int *x, int *y, int *w, int *h)
+{
+ if (pmap)
+ ecore_x_drawable_geometry_get(pmap, x, y, w, h);
+}
+
+/**
+ * Retrieves the depth of the given pixmap.
+ * @param pmap The given pixmap.
+ * @return The depth of the pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+int
+ecore_x_pixmap_depth_get(Ecore_X_Pixmap pmap)
+{
+ return ecore_x_drawable_depth_get(pmap);
+}
+
diff --git a/ecore/src/lib/ecore_x/ecore_x_private.h b/ecore/src/lib/ecore_x/ecore_x_private.h
new file mode 100644
index 0000000..bc9d87b
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_private.h
@@ -0,0 +1,210 @@
+#ifndef _ECORE_X_PRIVATE_H
+#define _ECORE_X_PRIVATE_H
+
+#include "config.h"
+
+#include <sys/param.h>
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
+
+#define XK_MISCELLANY 1
+#include <X11/Xlib.h>
+#include <X11/Xproto.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/Xresource.h>
+#include <X11/keysymdef.h>
+#include <X11/extensions/XShm.h>
+#include <X11/extensions/shape.h>
+#include <X11/extensions/sync.h>
+#ifdef ECORE_XCURSOR
+#include <X11/Xcursor/Xcursor.h>
+#endif
+#ifdef ECORE_XPRINT
+#include <X11/extensions/Print.h>
+#endif
+#ifdef ECORE_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+
+#include "Ecore_X.h"
+
+/* FIXME: this is for simulation only */
+#include "Ecore_Job.h"
+#include "Ecore_Txt.h"
+
+typedef struct _Ecore_X_Reply Ecore_X_Reply;
+
+struct _Ecore_X_Reply
+{
+/* FIXME: this is for simulation only */
+ Ecore_Job *job;
+
+ void *reply_data;
+ void (*reply_data_free) (void *reply_data);
+
+ void (*func) (void *data, Ecore_X_Reply *reply, void *reply_data);
+ void *data;
+};
+
+typedef struct _Ecore_X_Selection_Intern Ecore_X_Selection_Intern;
+
+struct _Ecore_X_Selection_Intern
+{
+ Ecore_X_Window win;
+ Ecore_X_Atom selection;
+ unsigned char *data;
+ int length;
+ Time time;
+};
+
+typedef struct _Ecore_X_Selection_Converter Ecore_X_Selection_Converter;
+
+struct _Ecore_X_Selection_Converter
+{
+ Ecore_X_Atom target;
+ int (*convert)(char *target, void *data, int size,
+ void **data_ret, int *size_ret);
+ Ecore_X_Selection_Converter *next;
+};
+
+typedef struct _Ecore_X_Selection_Parser Ecore_X_Selection_Parser;
+
+struct _Ecore_X_Selection_Parser
+{
+ char *target;
+ void *(*parse)(const char *target, unsigned char *data, int size);
+ Ecore_X_Selection_Parser *next;
+};
+
+typedef struct _Ecore_X_DND_Source
+{
+ int version;
+ Ecore_X_Window win, dest;
+
+ enum {
+ ECORE_X_DND_SOURCE_IDLE,
+ ECORE_X_DND_SOURCE_DRAGGING,
+ ECORE_X_DND_SOURCE_DROPPED,
+ ECORE_X_DND_SOURCE_CONVERTING
+ } state;
+
+ struct {
+ short x, y;
+ unsigned short width, height;
+ } rectangle;
+
+ Time time;
+
+ Ecore_X_Atom action, accepted_action;
+
+ int will_accept;
+ int suppress;
+
+ int await_status;
+} Ecore_X_DND_Source;
+
+typedef struct _Ecore_X_DND_Target
+{
+ int version;
+ Ecore_X_Window win, source;
+
+ enum {
+ ECORE_X_DND_TARGET_IDLE,
+ ECORE_X_DND_TARGET_ENTERED
+ } state;
+
+ struct {
+ int x, y;
+ } pos;
+
+ Time time;
+
+ Ecore_X_Atom action, accepted_action;
+
+ int will_accept;
+} Ecore_X_DND_Target;
+
+extern Display *_ecore_x_disp;
+extern double _ecore_x_double_click_time;
+extern Time _ecore_x_event_last_time;
+extern Window _ecore_x_event_last_win;
+extern int _ecore_x_event_last_root_x;
+extern int _ecore_x_event_last_root_y;
+extern int _ecore_x_xcursor;
+
+extern Ecore_X_Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
+
+extern int _ecore_window_grabs_num;
+extern Window *_ecore_window_grabs;
+extern int (*_ecore_window_grab_replay_func) (void *data, int event_type, void *event);
+extern void *_ecore_window_grab_replay_data;
+
+extern Ecore_X_Window _ecore_x_private_win;
+
+void _ecore_x_error_handler_init(void);
+void _ecore_x_event_handle_key_press(XEvent *xevent);
+void _ecore_x_event_handle_key_release(XEvent *xevent);
+void _ecore_x_event_handle_button_press(XEvent *xevent);
+void _ecore_x_event_handle_button_release(XEvent *xevent);
+void _ecore_x_event_handle_motion_notify(XEvent *xevent);
+void _ecore_x_event_handle_enter_notify(XEvent *xevent);
+void _ecore_x_event_handle_leave_notify(XEvent *xevent);
+void _ecore_x_event_handle_focus_in(XEvent *xevent);
+void _ecore_x_event_handle_focus_out(XEvent *xevent);
+void _ecore_x_event_handle_keymap_notify(XEvent *xevent);
+void _ecore_x_event_handle_expose(XEvent *xevent);
+void _ecore_x_event_handle_graphics_expose(XEvent *xevent);
+void _ecore_x_event_handle_visibility_notify(XEvent *xevent);
+void _ecore_x_event_handle_create_notify(XEvent *xevent);
+void _ecore_x_event_handle_destroy_notify(XEvent *xevent);
+void _ecore_x_event_handle_unmap_notify(XEvent *xevent);
+void _ecore_x_event_handle_map_notify(XEvent *xevent);
+void _ecore_x_event_handle_map_request(XEvent *xevent);
+void _ecore_x_event_handle_reparent_notify(XEvent *xevent);
+void _ecore_x_event_handle_configure_notify(XEvent *xevent);
+void _ecore_x_event_handle_configure_request(XEvent *xevent);
+void _ecore_x_event_handle_gravity_notify(XEvent *xevent);
+void _ecore_x_event_handle_resize_request(XEvent *xevent);
+void _ecore_x_event_handle_circulate_notify(XEvent *xevent);
+void _ecore_x_event_handle_circulate_request(XEvent *xevent);
+void _ecore_x_event_handle_property_notify(XEvent *xevent);
+void _ecore_x_event_handle_selection_clear(XEvent *xevent);
+void _ecore_x_event_handle_selection_request(XEvent *xevent);
+void _ecore_x_event_handle_selection_notify(XEvent *xevent);
+void _ecore_x_event_handle_colormap_notify(XEvent *xevent);
+void _ecore_x_event_handle_client_message(XEvent *xevent);
+void _ecore_x_event_handle_mapping_notify(XEvent *xevent);
+void _ecore_x_event_handle_shape_change(XEvent *xevent);
+void _ecore_x_event_handle_sync_counter(XEvent *xevent);
+void _ecore_x_event_handle_sync_alarm(XEvent *xevent);
+
+void _ecore_x_selection_data_init(void);
+void _ecore_x_selection_shutdown(void);
+Ecore_X_Atom
+ _ecore_x_selection_target_atom_get(const char *target);
+char *_ecore_x_selection_target_get(Ecore_X_Atom target);
+Ecore_X_Selection_Intern *
+ _ecore_x_selection_get(Ecore_X_Atom selection);
+int _ecore_x_selection_set(Window w, unsigned char *data, int len, Ecore_X_Atom selection);
+int _ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret);
+void *_ecore_x_selection_parse(const char *target, unsigned char *data, int size);
+
+void _ecore_x_sync_magic_send(int val, Ecore_X_Window swin);
+void _ecore_x_window_grab_remove(Ecore_X_Window win);
+void _ecore_x_key_grab_remove(Ecore_X_Window win);
+
+/* from dnd */
+void _ecore_x_dnd_init(void);
+Ecore_X_DND_Source *_ecore_x_dnd_source_get(void);
+Ecore_X_DND_Target *_ecore_x_dnd_target_get(void);
+void _ecore_x_dnd_drag(int x, int y);
+void _ecore_x_dnd_shutdown(void);
+
+/* from netwm */
+Ecore_X_Window_State _ecore_x_netwm_state_get(Ecore_X_Atom a);
+
+/* from sync */
+
+#endif
diff --git a/ecore/src/lib/ecore_x/ecore_x_selection.c b/ecore/src/lib/ecore_x/ecore_x_selection.c
new file mode 100644
index 0000000..5306219
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_selection.c
@@ -0,0 +1,773 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "ecore_private.h"
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+static Ecore_X_Selection_Intern selections[4];
+static Ecore_X_Selection_Converter *converters = NULL;
+static Ecore_X_Selection_Parser *parsers = NULL;
+
+static int _ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret);
+static int _ecore_x_selection_data_default_free(void *data);
+static void *_ecore_x_selection_parser_files(const char *target, unsigned char *data, int size);
+static int _ecore_x_selection_data_files_free(void *data);
+static void *_ecore_x_selection_parser_text(const char *target, unsigned char *data, int size);
+static int _ecore_x_selection_data_text_free(void *data);
+static void *_ecore_x_selection_parser_targets(const char *target, unsigned char *data, int size);
+static int _ecore_x_selection_data_targets_free(void *data);
+
+#define ECORE_X_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x))
+
+void
+_ecore_x_selection_data_init(void)
+{
+ /* Initialize global data */
+ memset(selections, 0, sizeof(selections));
+
+ /* Initialize converters */
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT,
+ _ecore_x_selection_converter_text);
+#ifdef X_HAVE_UTF8_STRING
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING,
+ _ecore_x_selection_converter_text);
+#endif
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_COMPOUND_TEXT,
+ _ecore_x_selection_converter_text);
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_STRING,
+ _ecore_x_selection_converter_text);
+
+ /* Initialize parsers */
+ ecore_x_selection_parser_add("text/plain",
+ _ecore_x_selection_parser_text);
+ ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_UTF8_STRING,
+ _ecore_x_selection_parser_text);
+ ecore_x_selection_parser_add("text/uri-list",
+ _ecore_x_selection_parser_files);
+ ecore_x_selection_parser_add("_NETSCAPE_URL",
+ _ecore_x_selection_parser_files);
+ ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS,
+ _ecore_x_selection_parser_targets);
+}
+
+void
+_ecore_x_selection_shutdown(void)
+{
+ Ecore_X_Selection_Converter *cnv;
+ Ecore_X_Selection_Parser *prs;
+
+ /* free the selection converters */
+ cnv = converters;
+ while (cnv)
+ {
+ Ecore_X_Selection_Converter *tmp;
+
+ tmp = cnv->next;
+ free(cnv);
+ cnv = tmp;
+ }
+ converters = NULL;
+
+ /* free the selection parsers */
+ prs = parsers;
+ while (prs)
+ {
+ Ecore_X_Selection_Parser *tmp;
+
+ tmp = prs;
+ prs = prs->next;
+ free(tmp->target);
+ free(tmp);
+ }
+ parsers = NULL;
+}
+
+Ecore_X_Selection_Intern *
+_ecore_x_selection_get(Ecore_X_Atom selection)
+{
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ return &selections[0];
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ return &selections[1];
+ else if (selection == ECORE_X_ATOM_SELECTION_XDND)
+ return &selections[2];
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ return &selections[3];
+ else
+ return NULL;
+}
+
+int
+_ecore_x_selection_set(Window w, unsigned char *data, int size, Ecore_X_Atom selection)
+{
+ int in;
+ unsigned char *buf = NULL;
+
+ XSetSelectionOwner(_ecore_x_disp, selection, w, _ecore_x_event_last_time);
+ if (XGetSelectionOwner(_ecore_x_disp, selection) != w)
+ return 0;
+
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ in = 0;
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ in = 1;
+ else if (selection == ECORE_X_ATOM_SELECTION_XDND)
+ in = 2;
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ in = 3;
+ else
+ return 0;
+
+ if (data)
+ {
+ selections[in].win = w;
+ selections[in].selection = selection;
+ selections[in].length = size;
+ selections[in].time = _ecore_x_event_last_time;
+
+ buf = malloc(size);
+ memcpy(buf, data, size);
+ selections[in].data = buf;
+ }
+ else
+ {
+ if (selections[in].data)
+ {
+ free(selections[in].data);
+ memset(&selections[in], 0, sizeof(Ecore_X_Selection_Data));
+ }
+ }
+
+ return 1;
+}
+
+/**
+ * Claim ownership of the PRIMARY selection and set its data.
+ * @param w The window to which this selection belongs
+ * @param data The data associated with the selection
+ * @param size The size of the data buffer in bytes
+ * @return Returns 1 if the ownership of the selection was successfully
+ * claimed, or 0 if unsuccessful.
+ */
+int
+ecore_x_selection_primary_set(Ecore_X_Window w, unsigned char *data, int size)
+{
+ return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_PRIMARY);
+}
+
+/**
+ * Release ownership of the primary selection
+ * @return Returns 1 if the selection was successfully cleared,
+ * or 0 if unsuccessful.
+ *
+ */
+int
+ecore_x_selection_primary_clear(void)
+{
+ return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_PRIMARY);
+}
+
+/**
+ * Claim ownership of the SECONDARY selection and set its data.
+ * @param w The window to which this selection belongs
+ * @param data The data associated with the selection
+ * @param size The size of the data buffer in bytes
+ * @return Returns 1 if the ownership of the selection was successfully
+ * claimed, or 0 if unsuccessful.
+ */
+int
+ecore_x_selection_secondary_set(Ecore_X_Window w, unsigned char *data, int size)
+{
+ return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_SECONDARY);
+}
+
+/**
+ * Release ownership of the secondary selection
+ * @return Returns 1 if the selection was successfully cleared,
+ * or 0 if unsuccessful.
+ *
+ */
+int
+ecore_x_selection_secondary_clear(void)
+{
+ return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_SECONDARY);
+}
+
+/**
+ * Claim ownership of the XDND selection and set its data.
+ * @param w The window to which this selection belongs
+ * @param data The data associated with the selection
+ * @param size The size of the data buffer in bytes
+ * @return Returns 1 if the ownership of the selection was successfully
+ * claimed, or 0 if unsuccessful.
+ */
+int
+ecore_x_selection_xdnd_set(Ecore_X_Window w, unsigned char *data, int size)
+{
+ return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_XDND);
+}
+
+/**
+ * Release ownership of the XDND selection
+ * @return Returns 1 if the selection was successfully cleared,
+ * or 0 if unsuccessful.
+ *
+ */
+int
+ecore_x_selection_xdnd_clear(void)
+{
+ return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_XDND);
+}
+
+/**
+ * Claim ownership of the CLIPBOARD selection and set its data.
+ * @param w The window to which this selection belongs
+ * @param data The data associated with the selection
+ * @param size The size of the data buffer in bytes
+ * @return Returns 1 if the ownership of the selection was successfully
+ * claimed, or 0 if unsuccessful.
+ *
+ * Get the converted data from a previous CLIPBOARD selection
+ * request. The buffer must be freed when done with.
+ */
+int
+ecore_x_selection_clipboard_set(Ecore_X_Window w, unsigned char *data, int size)
+{
+ return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_CLIPBOARD);
+}
+
+/**
+ * Release ownership of the clipboard selection
+ * @return Returns 1 if the selection was successfully cleared,
+ * or 0 if unsuccessful.
+ *
+ */
+int
+ecore_x_selection_clipboard_clear(void)
+{
+ return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_CLIPBOARD);
+}
+
+Ecore_X_Atom
+_ecore_x_selection_target_atom_get(const char *target)
+{
+ Ecore_X_Atom x_target;
+
+ if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT))
+ x_target = ECORE_X_ATOM_TEXT;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT))
+ x_target = ECORE_X_ATOM_COMPOUND_TEXT;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING))
+ x_target = ECORE_X_ATOM_STRING;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING))
+ x_target = ECORE_X_ATOM_UTF8_STRING;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME))
+ x_target = ECORE_X_ATOM_FILE_NAME;
+ else
+ {
+ x_target = ecore_x_atom_get(target);
+ }
+
+ return x_target;
+}
+
+char *
+_ecore_x_selection_target_get(Ecore_X_Atom target)
+{
+ if (target == ECORE_X_ATOM_FILE_NAME)
+ return strdup(ECORE_X_SELECTION_TARGET_FILENAME);
+ else if (target == ECORE_X_ATOM_STRING)
+ return strdup(ECORE_X_SELECTION_TARGET_STRING);
+ else if (target == ECORE_X_ATOM_UTF8_STRING)
+ return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING);
+ else if (target == ECORE_X_ATOM_TEXT)
+ return strdup(ECORE_X_SELECTION_TARGET_TEXT);
+ else
+ return XGetAtomName(_ecore_x_disp, target);
+}
+
+static void
+_ecore_x_selection_request(Ecore_X_Window w, Ecore_X_Atom selection, char *target_str)
+{
+ Ecore_X_Atom target, prop;
+
+ target = _ecore_x_selection_target_atom_get(target_str);
+
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ prop = ECORE_X_ATOM_SELECTION_PROP_PRIMARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ prop = ECORE_X_ATOM_SELECTION_PROP_SECONDARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ prop = ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD;
+ else
+ return;
+
+ XConvertSelection(_ecore_x_disp, selection, target, prop,
+ w, CurrentTime);
+}
+
+void
+ecore_x_selection_primary_request(Ecore_X_Window w, char *target)
+{
+ _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_PRIMARY, target);
+}
+
+void
+ecore_x_selection_secondary_request(Ecore_X_Window w, char *target)
+{
+ _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_SECONDARY, target);
+}
+
+void
+ecore_x_selection_xdnd_request(Ecore_X_Window w, char *target)
+{
+ Ecore_X_Atom atom;
+ Ecore_X_DND_Target *_target;
+
+ _target = _ecore_x_dnd_target_get();
+ atom = _ecore_x_selection_target_atom_get(target);
+ XConvertSelection(_ecore_x_disp, ECORE_X_ATOM_SELECTION_XDND, atom,
+ ECORE_X_ATOM_SELECTION_PROP_XDND, w,
+ _target->time);
+}
+
+void
+ecore_x_selection_clipboard_request(Ecore_X_Window w, char *target)
+{
+ _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_CLIPBOARD, target);
+}
+
+void
+ecore_x_selection_converter_atom_add(Ecore_X_Atom target,
+ int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret))
+{
+ Ecore_X_Selection_Converter *cnv;
+
+ cnv = converters;
+ if (converters)
+ {
+ while (1)
+ {
+ if (cnv->target == target)
+ {
+ cnv->convert = func;
+ return;
+ }
+ if (cnv->next)
+ cnv = cnv->next;
+ else
+ break;
+ }
+
+ cnv->next = calloc(1, sizeof(Ecore_X_Selection_Converter));
+ cnv = cnv->next;
+ }
+ else
+ {
+ converters = calloc(1, sizeof(Ecore_X_Selection_Converter));
+ cnv = converters;
+ }
+ cnv->target = target;
+ cnv->convert = func;
+}
+
+void
+ecore_x_selection_converter_add(char *target,
+ int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret))
+{
+ Ecore_X_Atom x_target;
+
+ if (!func || !target)
+ return;
+
+ x_target = _ecore_x_selection_target_atom_get(target);
+
+ ecore_x_selection_converter_atom_add(x_target, func);
+}
+
+void
+ecore_x_selection_converter_atom_del(Ecore_X_Atom target)
+{
+ Ecore_X_Selection_Converter *cnv, *prev_cnv;
+
+ prev_cnv = NULL;
+ cnv = converters;
+
+ while (cnv)
+ {
+ if (cnv->target == target)
+ {
+ if (prev_cnv)
+ prev_cnv->next = cnv->next;
+ else
+ converters = cnv->next; /* This was the first converter */
+ free(cnv);
+
+ return;
+ }
+ prev_cnv = cnv;
+ cnv = cnv->next;
+ }
+}
+
+void
+ecore_x_selection_converter_del(char *target)
+{
+ Ecore_X_Atom x_target;
+
+ if (!target)
+ return;
+
+ x_target = _ecore_x_selection_target_atom_get(target);
+ ecore_x_selection_converter_atom_del(x_target);
+}
+
+/* Locate and run conversion callback for specified selection target */
+int
+_ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret)
+{
+ Ecore_X_Selection_Intern *sel;
+ Ecore_X_Selection_Converter *cnv;
+ void *data;
+ int size;
+ char *tgt_str;
+
+ sel = _ecore_x_selection_get(selection);
+ tgt_str = _ecore_x_selection_target_get(target);
+
+ for (cnv = converters; cnv; cnv = cnv->next)
+ {
+ if (cnv->target == target)
+ {
+ int r;
+ r = cnv->convert(tgt_str, sel->data, sel->length, &data, &size);
+ free(tgt_str);
+ if (r)
+ {
+ *data_ret = data;
+ return r;
+ }
+ else
+ return 0;
+ }
+ }
+
+ /* Default, just return the data */
+ *data_ret = malloc(sel->length);
+ memcpy(*data_ret, sel->data, sel->length);
+ free(tgt_str);
+ return 1;
+}
+
+/* TODO: We need to work out a mechanism for automatic conversion to any requested
+ * locale using Ecore_Txt functions */
+/* Converter for standard non-utf8 text targets */
+static int
+_ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret)
+{
+ XTextProperty text_prop;
+ char *mystr;
+ XICCEncodingStyle style;
+
+ if (!data || !size)
+ return 0;
+
+ if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT))
+ style = XTextStyle;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT))
+ style = XCompoundTextStyle;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING))
+ style = XStringStyle;
+#ifdef X_HAVE_UTF8_STRING
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING))
+ style = XUTF8StringStyle;
+#endif
+ else
+ return 0;
+
+ if (!(mystr = strdup(data)))
+ return 0;
+
+#ifdef X_HAVE_UTF8_STRING
+ if (Xutf8TextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success)
+ {
+ int bufsize = strlen((char *)text_prop.value) + 1;
+ *data_ret = malloc(bufsize);
+ memcpy(*data_ret, text_prop.value, bufsize);
+ *size_ret = bufsize;
+ XFree(text_prop.value);
+ free(mystr);
+ return 1;
+ }
+#else
+ if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success)
+ {
+ int bufsize = strlen(text_prop.value) + 1;
+ *data_ret = malloc(bufsize);
+ memcpy(*data_ret, text_prop.value, bufsize);
+ *size_ret = bufsize;
+ XFree(text_prop.value);
+ free(mystr);
+ return 1;
+ }
+#endif
+ else
+ {
+ free(mystr);
+ return 0;
+ }
+}
+
+void
+ecore_x_selection_parser_add(const char *target,
+ void *(*func)(const char *target, unsigned char *data, int size))
+{
+ Ecore_X_Selection_Parser *prs;
+
+ if (!target)
+ return;
+
+ prs = parsers;
+ if (parsers)
+ {
+ while (prs->next)
+ {
+ if (!strcmp(prs->target, target))
+ {
+ prs->parse = func;
+ return;
+ }
+ prs = prs->next;
+ }
+
+ prs->next = calloc(1, sizeof(Ecore_X_Selection_Parser));
+ prs = prs->next;
+ }
+ else
+ {
+ parsers = calloc(1, sizeof(Ecore_X_Selection_Parser));
+ prs = parsers;
+ }
+ prs->target = strdup(target);
+ prs->parse = func;
+}
+
+void
+ecore_x_selection_parser_del(const char *target)
+{
+ Ecore_X_Selection_Parser *prs, *prev_prs;
+
+ if (!target)
+ return;
+
+ prev_prs = NULL;
+ prs = parsers;
+
+ while (prs)
+ {
+ if (!strcmp(prs->target, target))
+ {
+ if (prev_prs)
+ prev_prs->next = prs->next;
+ else
+ parsers = prs->next; /* This was the first parser */
+ free(prs->target);
+ free(prs);
+
+ return;
+ }
+ prev_prs = prs;
+ prs = prs->next;
+ }
+}
+
+/* Locate and run conversion callback for specified selection target */
+void *
+_ecore_x_selection_parse(const char *target, unsigned char *data, int size)
+{
+ Ecore_X_Selection_Parser *prs;
+ Ecore_X_Selection_Data *sel;
+
+ for (prs = parsers; prs; prs = prs->next)
+ {
+ if (!strcmp(prs->target, target))
+ {
+ sel = prs->parse(target, data, size);
+ return sel;
+ }
+ }
+
+ /* Default, just return the data */
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data));
+ sel->free = _ecore_x_selection_data_default_free;
+ sel->length = size;
+ sel->data = data;
+ return sel;
+}
+
+static int
+_ecore_x_selection_data_default_free(void *data)
+{
+ Ecore_X_Selection_Data *sel;
+
+ sel = data;
+ free(sel->data);
+ free(sel);
+ return 1;
+}
+
+static void *
+_ecore_x_selection_parser_files(const char *target, unsigned char *data, int size)
+{
+ Ecore_X_Selection_Data_Files *sel;
+ int i, is;
+ char *tmp;
+
+ if (strcmp(target, "text/uri-list")
+ && strcmp(target, "_NETSCAPE_URL"))
+ return NULL;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files));
+ ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_files_free;
+
+ if (data[size - 1])
+ {
+ /* Isn't nul terminated */
+ printf("BUG: isn't nul terminated!\n");
+ size++;
+ data = realloc(data, size);
+ data[size - 1] = 0;
+ }
+
+ tmp = malloc(size);
+ i = 0;
+ is = 0;
+ while ((is < size) && (data[is]))
+ {
+ if ((i == 0) && (data[is] == '#'))
+ {
+ for (; ((data[is]) && (data[is] != '\n')); is++);
+ }
+ else
+ {
+ if ((data[is] != '\r')
+ && (data[is] != '\n'))
+ {
+ tmp[i++] = data[is++];
+ }
+ else
+ {
+ while ((data[is] == '\r')
+ || (data[is] == '\n'))
+ is++;
+ tmp[i] = 0;
+ sel->num_files++;
+ sel->files = realloc(sel->files, sel->num_files * sizeof(char *));
+ sel->files[sel->num_files - 1] = strdup(tmp);
+ tmp[0] = 0;
+ i = 0;
+ }
+ }
+ }
+ if (i > 0)
+ {
+ tmp[i] = 0;
+ sel->num_files++;
+ sel->files = realloc(sel->files, sel->num_files * sizeof(char *));
+ sel->files[sel->num_files - 1] = strdup(tmp);
+ }
+ free(tmp);
+ free(data);
+
+ return ECORE_X_SELECTION_DATA(sel);
+}
+
+static int
+_ecore_x_selection_data_files_free(void *data)
+{
+ Ecore_X_Selection_Data_Files *sel;
+ int i;
+
+ sel = data;
+ if (sel->files)
+ {
+ for (i = 0; i < sel->num_files; i++)
+ free(sel->files[i]);
+ free(sel->files);
+ }
+ free(sel);
+ return 0;
+}
+
+static void *
+_ecore_x_selection_parser_text(const char *target __UNUSED__, unsigned char *data, int size)
+{
+ Ecore_X_Selection_Data_Text *sel;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text));
+
+ if (data[size - 1])
+ {
+ /* Isn't nul terminated */
+ printf("BUG: isn't nul terminated!\n");
+ size++;
+ data = realloc(data, size);
+ data[size - 1] = 0;
+ }
+
+ sel->text = (char *)data;
+ ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_text_free;
+ return sel;
+}
+
+static int
+_ecore_x_selection_data_text_free(void *data)
+{
+ Ecore_X_Selection_Data_Text *sel;
+
+ sel = data;
+ free(sel->text);
+ free(sel);
+ return 1;
+}
+
+static void *
+_ecore_x_selection_parser_targets(const char *target __UNUSED__, unsigned char *data, int size)
+{
+ Ecore_X_Selection_Data_Targets *sel;
+ unsigned long *targets;
+ int i;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets));
+ targets = (unsigned long *)data;
+
+ sel->num_targets = size - 2;
+ sel->targets = malloc((size - 2) * sizeof(char *));
+ for (i = 2; i < size; i++)
+ sel->targets[i - 2] = XGetAtomName(_ecore_x_disp, targets[i]);
+ free(data);
+
+ ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_targets_free;
+ return sel;
+}
+
+static int
+_ecore_x_selection_data_targets_free(void *data)
+{
+ Ecore_X_Selection_Data_Targets *sel;
+ int i;
+
+ sel = data;
+
+ if (sel->targets)
+ {
+ for (i = 0; i < sel->num_targets; i++)
+ XFree(sel->targets[i]);
+ free(sel->targets);
+ }
+ free(sel);
+ return 1;
+}
diff --git a/ecore/src/lib/ecore_x/ecore_x_sync.c b/ecore/src/lib/ecore_x/ecore_x_sync.c
new file mode 100644
index 0000000..0b567bf
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_sync.c
@@ -0,0 +1,48 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+/*
+ * XSync code
+ */
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+Ecore_X_Sync_Alarm
+ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter)
+{
+ Ecore_X_Sync_Alarm alarm;
+ XSyncAlarmAttributes values;
+ XSyncValue init;
+
+ XSyncIntToValue(&init, 0);
+ XSyncSetCounter(_ecore_x_disp, counter, init);
+
+ values.trigger.counter = counter;
+ values.trigger.value_type = XSyncAbsolute;
+ XSyncIntToValue(&values.trigger.wait_value, 1);
+ values.trigger.test_type = XSyncPositiveComparison;
+
+ XSyncIntToValue(&values.delta, 1);
+
+ values.events = True;
+
+ alarm = XSyncCreateAlarm(_ecore_x_disp,
+ XSyncCACounter |
+ XSyncCAValueType |
+ XSyncCAValue |
+ XSyncCATestType |
+ XSyncCADelta |
+ XSyncCAEvents,
+ &values);
+
+ ecore_x_sync();
+ return alarm;
+}
+
+int
+ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm)
+{
+ return XSyncDestroyAlarm(_ecore_x_disp, alarm);
+}
diff --git a/ecore/src/lib/ecore_x/ecore_x_window.c b/ecore/src/lib/ecore_x/ecore_x_window.c
new file mode 100644
index 0000000..3577b74
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_window.c
@@ -0,0 +1,768 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+/**
+ * @defgroup Ecore_X_Window_Create_Group X Window Creation Functions
+ *
+ * Functions that can be used to create an X window.
+ */
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @return The new window handle.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+Ecore_X_Window
+ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ if (parent == 0) parent = DefaultRootWindow(_ecore_x_disp);
+ attr.backing_store = NotUseful;
+ attr.override_redirect = False;
+ attr.colormap = DefaultColormap(_ecore_x_disp, DefaultScreen(_ecore_x_disp));
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.save_under = False;
+ attr.do_not_propagate_mask = NoEventMask;
+ attr.event_mask = KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ EnterWindowMask |
+ LeaveWindowMask |
+ PointerMotionMask |
+ ExposureMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ FocusChangeMask |
+ PropertyChangeMask |
+ ColormapChangeMask;
+ win = XCreateWindow(_ecore_x_disp, parent,
+ x, y, w, h, 0,
+ 0, /*DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ InputOutput,
+ CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ CWBackingStore |
+ CWOverrideRedirect |
+/* CWColormap | */
+ CWBorderPixel |
+ CWBackPixmap |
+ CWSaveUnder |
+ CWDontPropagate |
+ CWEventMask,
+ &attr);
+
+ if (parent == DefaultRootWindow(_ecore_x_disp)) ecore_x_window_defaults_set(win);
+ return win;
+}
+
+/**
+ * Creates a window with the override redirect attribute set to @c True.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @return The new window handle.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+Ecore_X_Window
+ecore_x_window_override_new(Ecore_X_Window parent, int x, int y, int w, int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ if (parent == 0) parent = DefaultRootWindow(_ecore_x_disp);
+ attr.backing_store = NotUseful;
+ attr.override_redirect = True;
+ attr.colormap = DefaultColormap(_ecore_x_disp, DefaultScreen(_ecore_x_disp));
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.save_under = False;
+ attr.do_not_propagate_mask = NoEventMask;
+ attr.event_mask = KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ EnterWindowMask |
+ LeaveWindowMask |
+ PointerMotionMask |
+ ExposureMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ FocusChangeMask |
+ PropertyChangeMask |
+ ColormapChangeMask;
+ win = XCreateWindow(_ecore_x_disp, parent,
+ x, y, w, h, 0,
+ 0, /*DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ InputOutput,
+ CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ CWBackingStore |
+ CWOverrideRedirect |
+/* CWColormap | */
+ CWBorderPixel |
+ CWBackPixmap |
+ CWSaveUnder |
+ CWDontPropagate |
+ CWEventMask,
+ &attr);
+
+ if (parent == DefaultRootWindow(_ecore_x_disp)) ecore_x_window_defaults_set(win);
+ return win;
+}
+
+/**
+ * Creates a new input window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @return The new window.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+Ecore_X_Window
+ecore_x_window_input_new(Ecore_X_Window parent, int x, int y, int w, int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ if (parent == 0) parent = DefaultRootWindow(_ecore_x_disp);
+ attr.override_redirect = True;
+ attr.do_not_propagate_mask = NoEventMask;
+ attr.event_mask = KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ EnterWindowMask |
+ LeaveWindowMask |
+ PointerMotionMask |
+ ExposureMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ FocusChangeMask |
+ PropertyChangeMask |
+ ColormapChangeMask;
+ win = XCreateWindow(_ecore_x_disp, parent,
+ x, y, w, h, 0,
+ 0,
+ InputOnly,
+ CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ CWOverrideRedirect |
+ CWDontPropagate |
+ CWEventMask,
+ &attr);
+
+ if (parent == DefaultRootWindow(_ecore_x_disp))
+ {
+ }
+ return win;
+}
+
+/**
+ * @defgroup Evas_X_Window_Properties_Group X Window Property Functions
+ *
+ * Functions that set window properties.
+ */
+
+/**
+ * Sets the default properties for the given window.
+ *
+ * The default properties set for the window are @c WM_CLIENT_MACHINE and
+ * @c _NET_WM_PID.
+ *
+ * @param win The given window.
+ * @ingroup Evas_X_Window_Properties_Groups
+ */
+void
+ecore_x_window_defaults_set(Ecore_X_Window win)
+{
+ long pid;
+ char buf[MAXHOSTNAMELEN];
+ char *hostname[1];
+ int argc;
+ char **argv;
+ XTextProperty xprop;
+
+ /*
+ * Set WM_CLIENT_MACHINE.
+ */
+ gethostname(buf, MAXHOSTNAMELEN);
+ buf[MAXHOSTNAMELEN - 1] = '\0';
+ hostname[0] = buf;
+ /* The ecore function uses UTF8 which Xlib may not like (especially
+ * with older clients) */
+ /* ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_CLIENT_MACHINE,
+ (char *)buf); */
+ if (XStringListToTextProperty(hostname, 1, &xprop))
+ {
+ XSetWMClientMachine(_ecore_x_disp, win, &xprop);
+ XFree(xprop.value);
+ }
+
+ /*
+ * Set _NET_WM_PID
+ */
+ pid = getpid();
+ ecore_x_netwm_pid_set(win, pid);
+
+ ecore_x_netwm_window_type_set(win, ECORE_X_WINDOW_TYPE_NORMAL);
+
+ ecore_app_args_get(&argc, &argv);
+ ecore_x_icccm_command_set(win, argc, argv);
+}
+
+void
+ecore_x_window_configure(Ecore_X_Window win,
+ Ecore_X_Window_Configure_Mask mask,
+ int x, int y, int w, int h,
+ int border_width, Ecore_X_Window sibling,
+ int stack_mode)
+{
+ XWindowChanges xwc;
+
+ if (!win)
+ return;
+
+ xwc.x = x;
+ xwc.y = y;
+ xwc.width = w;
+ xwc.height = h;
+ xwc.border_width = border_width;
+ xwc.sibling = sibling;
+ xwc.stack_mode = stack_mode;
+
+ XConfigureWindow(_ecore_x_disp, win, mask, &xwc);
+}
+
+/**
+ * @defgroup Evas_X_Window_Destroy_Group X Window Destroy Functions
+ *
+ * Functions to destroy X windows.
+ */
+
+/**
+ * Deletes the given window.
+ * @param win The given window.
+ * @ingroup Evas_X_Window_Destroy_Group
+ */
+void
+ecore_x_window_del(Ecore_X_Window win)
+{
+ /* sorry sir, deleting the root window doesn't sound like
+ * a smart idea.
+ */
+ if (win)
+ XDestroyWindow(_ecore_x_disp, win);
+}
+
+/**
+ * Sends a delete request to the given window.
+ * @param win The given window.
+ * @ingroup Evas_X_Window_Destroy_Group
+ */
+void
+ecore_x_window_delete_request_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ /* sorry sir, deleting the root window doesn't sound like
+ * a smart idea.
+ */
+ if (!win)
+ return;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = ECORE_X_ATOM_WM_DELETE_WINDOW;
+ xev.xclient.data.l[1] = CurrentTime;
+
+ XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
+}
+
+/**
+ * @defgroup Evas_X_Window_Visibility_Group X Window Visibility Functions
+ *
+ * Functions to access and change the visibility of X windows.
+ */
+
+/**
+ * Shows a window.
+ *
+ * Synonymous to "mapping" a window in X Window System terminology.
+ *
+ * @param win The window to show.
+ * @ingroup Evas_X_Window_Visibility
+ */
+void
+ecore_x_window_show(Ecore_X_Window win)
+{
+ XMapWindow(_ecore_x_disp, win);
+}
+
+/**
+ * Hides a window.
+ *
+ * Synonymous to "unmapping" a window in X Window System terminology.
+ *
+ * @param win The window to hide.
+ * @ingroup Evas_X_Window_Visibility
+ */
+void
+ecore_x_window_hide(Ecore_X_Window win)
+{
+ XUnmapWindow(_ecore_x_disp, win);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions
+ *
+ * Functions that change or retrieve the geometry of X windows.
+ */
+
+/**
+ * Moves a window to the position @p x, @p y.
+ *
+ * The position is relative to the upper left hand corner of the
+ * parent window.
+ *
+ * @param win The window to move.
+ * @param x X position.
+ * @param y Y position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+void
+ecore_x_window_move(Ecore_X_Window win, int x, int y)
+{
+ XMoveWindow(_ecore_x_disp, win, x, y);
+}
+
+/**
+ * Resizes a window.
+ * @param win The window to resize.
+ * @param w New width of the window.
+ * @param h New height of the window.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+void
+ecore_x_window_resize(Ecore_X_Window win, int w, int h)
+{
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ XResizeWindow(_ecore_x_disp, win, w, h);
+}
+
+/**
+ * Moves and resizes a window.
+ * @param win The window to move and resize.
+ * @param x New X position of the window.
+ * @param y New Y position of the window.
+ * @param w New width of the window.
+ * @param h New height of the window.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+void
+ecore_x_window_move_resize(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ XMoveResizeWindow(_ecore_x_disp, win, x, y, w, h);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Focus_Functions X Window Focus Functions
+ *
+ * Functions that give the focus to an X Window.
+ */
+
+/**
+ * Sets the focus to the window @p win.
+ * @param win The window to focus.
+ * @ingroup Ecore_X_Window_Focus_Functions
+ */
+void
+ecore_x_window_focus(Ecore_X_Window win)
+{
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+// XSetInputFocus(_ecore_x_disp, win, RevertToNone, CurrentTime);
+ XSetInputFocus(_ecore_x_disp, win, PointerRoot, CurrentTime);
+}
+
+/**
+ * Sets the focus to the given window at a specific time.
+ * @param win The window to focus.
+ * @param t When to set the focus to the window.
+ * @ingroup Ecore_X_Window_Focus_Functions
+ */
+void
+ecore_x_window_focus_at_time(Ecore_X_Window win, Ecore_X_Time t)
+{
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+// XSetInputFocus(_ecore_x_disp, win, RevertToNone, t);
+ XSetInputFocus(_ecore_x_disp, win, PointerRoot, t);
+}
+
+/**
+ * gets the focus to the window @p win.
+ * @return The window that has focus.
+ * @ingroup Ecore_X_Window_Focus_Functions
+ */
+Ecore_X_Window
+ecore_x_window_focus_get(void)
+{
+ Window win;
+ int revert_mode;
+
+ win = 0;
+
+ XGetInputFocus(_ecore_x_disp, &win, &revert_mode);
+ return win;
+}
+
+/**
+ * @defgroup Ecore_X_Window_Z_Order_Group X Window Z Order Functions
+ *
+ * Functions that change the Z order of X windows.
+ */
+
+/**
+ * Raises the given window.
+ * @param win The window to raise.
+ * @ingroup Ecore_X_Window_Z_Order_Group
+ */
+void
+ecore_x_window_raise(Ecore_X_Window win)
+{
+ XRaiseWindow(_ecore_x_disp, win);
+}
+
+/**
+ * Lowers the given window.
+ * @param win The window to lower.
+ * @ingroup Ecore_X_Window_Z_Order_Group
+ */
+void
+ecore_x_window_lower(Ecore_X_Window win)
+{
+ XLowerWindow(_ecore_x_disp, win);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Parent_Group X Window Parent Functions
+ *
+ * Functions that retrieve or changes the parent window of a window.
+ */
+
+/**
+ * Moves a window to within another window at a given position.
+ * @param win The window to reparent.
+ * @param new_parent The new parent window.
+ * @param x X position within new parent window.
+ * @param y Y position within new parent window.
+ * @ingroup Ecore_X_Window_Parent_Group
+ */
+void
+ecore_x_window_reparent(Ecore_X_Window win, Ecore_X_Window new_parent, int x, int y)
+{
+ if (new_parent == 0) new_parent = DefaultRootWindow(_ecore_x_disp);
+ XReparentWindow(_ecore_x_disp, win, new_parent, x, y);
+}
+
+/**
+ * Retrieves the size of the given window.
+ * @param win The given window.
+ * @param w Pointer to an integer into which the width is to be stored.
+ * @param h Pointer to an integer into which the height is to be stored.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+void
+ecore_x_window_size_get(Ecore_X_Window win, int *w, int *h)
+{
+ int dummy_x, dummy_y;
+
+ if (win == 0)
+ win = DefaultRootWindow(_ecore_x_disp);
+
+ ecore_x_drawable_geometry_get(win, &dummy_x, &dummy_y, w, h);
+}
+
+/**
+ * Retrieves the geometry of the given window.
+ * @param win The given window.
+ * @param x Pointer to an integer in which the X position is to be stored.
+ * @param y Pointer to an integer in which the Y position is to be stored.
+ * @param w Pointer to an integer in which the width is to be stored.
+ * @param h Pointer to an integer in which the height is to be stored.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+void
+ecore_x_window_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h)
+{
+ if (!win)
+ win = DefaultRootWindow(_ecore_x_disp);
+
+ ecore_x_drawable_geometry_get(win, x, y, w, h);
+}
+
+/**
+ * Retrieves the width of the border of the given window.
+ * @param win The given window.
+ * @return Width of the border of @p win.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+int
+ecore_x_window_border_width_get(Ecore_X_Window win)
+{
+ /* doesn't make sense to call this on a root window */
+ if (!win)
+ return 0;
+
+ return ecore_x_drawable_border_width_get(win);
+}
+
+/**
+ * Sets the width of the border of the given window.
+ * @param win The given window.
+ * @param width The new border width.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+void
+ecore_x_window_border_width_set(Ecore_X_Window win, int width)
+{
+ /* doesn't make sense to call this on a root window */
+ if (!win)
+ return;
+
+ XSetWindowBorderWidth (_ecore_x_disp, win, width);
+}
+
+/**
+ * Retrieves the depth of the given window.
+ * @param win The given window.
+ * @return Depth of the window.
+ */
+int
+ecore_x_window_depth_get(Ecore_X_Window win)
+{
+ return ecore_x_drawable_depth_get(win);
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+void
+ecore_x_window_cursor_show(Ecore_X_Window win, int show)
+{
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+ if (!show)
+ {
+ Cursor c;
+ XColor cl;
+ Pixmap p, m;
+ GC gc;
+ XGCValues gcv;
+
+ p = XCreatePixmap(_ecore_x_disp, win, 1, 1, 1);
+ m = XCreatePixmap(_ecore_x_disp, win, 1, 1, 1);
+ gc = XCreateGC(_ecore_x_disp, m, 0, &gcv);
+ XSetForeground(_ecore_x_disp, gc, 0);
+ XDrawPoint(_ecore_x_disp, m, gc, 0, 0);
+ XFreeGC(_ecore_x_disp, gc);
+ c = XCreatePixmapCursor(_ecore_x_disp, p, m, &cl, &cl, 0, 0);
+ XDefineCursor(_ecore_x_disp, win, c);
+ XFreeCursor(_ecore_x_disp, c);
+ XFreePixmap(_ecore_x_disp, p);
+ XFreePixmap(_ecore_x_disp, m);
+ }
+ else
+ {
+ XDefineCursor(_ecore_x_disp, win, 0);
+ }
+}
+
+void
+ecore_x_window_cursor_set(Ecore_X_Window win, Ecore_X_Cursor c)
+{
+ if (c == 0)
+ XUndefineCursor(_ecore_x_disp, win);
+ else
+ XDefineCursor(_ecore_x_disp, win, c);
+}
+
+/**
+ * Finds out whether the given window is currently visible.
+ * @param win The given window.
+ * @return 1 if the window is visible, otherwise 0.
+ * @ingroup Ecore_X_Window_Visibility_Group
+ */
+int
+ecore_x_window_visible_get(Ecore_X_Window win)
+{
+ XWindowAttributes attr;
+
+ return (XGetWindowAttributes(_ecore_x_disp, win, &attr) &&
+ (attr.map_state == IsViewable));
+}
+
+static Window
+_ecore_x_window_at_xy_get(Window base, int bx, int by, int x, int y)
+{
+ Window *list = NULL;
+ Window parent_win = 0, child = 0, root_win = 0;
+ int i, wx, wy, ww, wh;
+ unsigned int num;
+
+ if (!ecore_x_window_visible_get(base))
+ return 0;
+
+ ecore_x_window_geometry_get(base, &wx, &wy, &ww, &wh);
+ wx += bx;
+ wy += by;
+
+ if (!((x >= wx) && (y >= wy) && (x < (wx + ww)) && (y < (wy + wh))))
+ return 0;
+
+ if (!XQueryTree(_ecore_x_disp, base, &root_win, &parent_win, &list, &num))
+ return base;
+
+ if (list)
+ {
+ for (i = num - 1;; --i)
+ {
+ if ((child = _ecore_x_window_at_xy_get(list[i], wx, wy, x, y)))
+ {
+ XFree(list);
+ return child;
+ }
+ if (!i)
+ break;
+ }
+ XFree(list);
+ }
+
+ return base;
+}
+
+/**
+ * Retrieves the top, visible window at the given location.
+ * @param x The given X position.
+ * @param y The given Y position.
+ * @return The window at that position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+Ecore_X_Window
+ecore_x_window_at_xy_get(int x, int y)
+{
+ Ecore_X_Window win, root;
+
+ /* FIXME: Proper function to determine current root/virtual root
+ * window missing here */
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ ecore_x_grab();
+ win = _ecore_x_window_at_xy_get(root, 0, 0, x, y);
+ ecore_x_ungrab();
+
+ return win ? win : root;
+}
+
+/**
+ * Retrieves the parent window of the given window.
+ * @param win The given window.
+ * @return The parent window of @p win.
+ * @ingroup Ecore_X_Window_Parent_Group
+ */
+Ecore_X_Window
+ecore_x_window_parent_get(Ecore_X_Window win)
+{
+ Window root, parent, *children = NULL;
+ unsigned int num;
+
+ if (!XQueryTree(_ecore_x_disp, win, &root, &parent, &children, &num))
+ return 0;
+ if (children)
+ XFree(children);
+
+ return parent;
+}
+
+/**
+ * Sets the background color of the given window.
+ * @param win The given window
+ * @param color The color to set to (i.e. 0xff0000)
+ */
+void
+ecore_x_window_background_color_set(Ecore_X_Window win, unsigned short r,
+ unsigned short g, unsigned short b)
+{
+ XSetWindowAttributes attr;
+ XColor col;
+
+ col.red = r;
+ col.green = g;
+ col.blue = b;
+
+ XAllocColor(_ecore_x_disp, DefaultColormap(_ecore_x_disp,
+ DefaultScreen(_ecore_x_disp)),
+ &col);
+
+ attr.background_pixel = col.pixel;
+ XChangeWindowAttributes(_ecore_x_disp, win, CWBackPixel, &attr);
+}
+
+void
+ecore_x_window_gravity_set(Ecore_X_Window win, Ecore_X_Gravity grav)
+{
+ XSetWindowAttributes att;
+
+ att.win_gravity = grav;
+ XChangeWindowAttributes(_ecore_x_disp, win, CWWinGravity, &att);
+}
+
+void
+ecore_x_window_pixel_gravity_set(Ecore_X_Window win, Ecore_X_Gravity grav)
+{
+ XSetWindowAttributes att;
+
+ att.bit_gravity = grav;
+ XChangeWindowAttributes(_ecore_x_disp, win, CWBitGravity, &att);
+}
+
+void
+ecore_x_window_pixmap_set(Ecore_X_Window win, Ecore_X_Pixmap pmap)
+{
+ XSetWindowBackgroundPixmap(_ecore_x_disp, win, pmap);
+}
+
+void
+ecore_x_window_area_clear(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ XClearArea(_ecore_x_disp, win, x, y, w, h, False);
+}
+
+void
+ecore_x_window_area_expose(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ XClearArea(_ecore_x_disp, win, x, y, w, h, True);
+}
diff --git a/ecore/src/lib/ecore_x/ecore_x_window_prop.c b/ecore/src/lib/ecore_x/ecore_x_window_prop.c
new file mode 100644
index 0000000..1c45607
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_window_prop.c
@@ -0,0 +1,342 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+#include <inttypes.h>
+#include <limits.h>
+
+#define _ATOM_SET_CARD32(win, atom, p_val, cnt) \
+ XChangeProperty(_ecore_x_disp, win, atom, XA_CARDINAL, 32, PropModeReplace, \
+ (unsigned char *)p_val, cnt)
+
+/*
+ * Set CARD32 (array) property
+ */
+void
+ecore_x_window_prop_card32_set(Ecore_X_Window win, Ecore_X_Atom atom,
+ unsigned int *val, unsigned int num)
+{
+#if SIZEOF_INT == 4
+ _ATOM_SET_CARD32(win, atom, val, num);
+#else
+ CARD32 *c32;
+ unsigned int i;
+
+ c32 = malloc(num * sizeof(CARD32));
+ if (!c32)
+ return;
+ for (i = 0; i < num; i++)
+ c32[i] = val[i];
+ _ATOM_SET_CARD32(win, atom, c32, num);
+ free(c32);
+#endif
+}
+
+/*
+ * Get CARD32 (array) property
+ *
+ * At most len items are returned in val.
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+int
+ecore_x_window_prop_card32_get(Ecore_X_Window win, Ecore_X_Atom atom,
+ unsigned int *val, unsigned int len)
+{
+ unsigned char *prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ unsigned int i;
+ int num;
+
+ prop_ret = NULL;
+ XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
+ XA_CARDINAL, &type_ret, &format_ret, &num_ret,
+ &bytes_after, &prop_ret);
+ if (prop_ret && type_ret == XA_CARDINAL && format_ret == 32)
+ {
+ if (num_ret < len)
+ len = num_ret;
+ for (i = 0; i < len; i++)
+ val[i] = ((unsigned long *)prop_ret)[i];
+ num = len;
+ }
+ else
+ {
+ num = -1;
+ }
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return num;
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+Ecore_X_Atom
+ecore_x_window_prop_any_type(void)
+{
+ return AnyPropertyType;
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+void
+ecore_x_window_prop_property_set(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size, void *data, int number)
+{
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+ if (size != 32)
+ XChangeProperty(_ecore_x_disp, win, property, type, size, PropModeReplace,
+ (unsigned char *)data, number);
+ else
+ {
+ unsigned long *dat;
+ int i, *ptr;
+
+ dat = malloc(sizeof(unsigned long) * number);
+ if (dat)
+ {
+ for (ptr = (int *)data, i = 0; i < number; i++) dat[i] = ptr[i];
+ XChangeProperty(_ecore_x_disp, win, property, type, size,
+ PropModeReplace, (unsigned char *)dat, number);
+ free(dat);
+ }
+ }
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+int
+ecore_x_window_prop_property_get(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size, unsigned char **data, int *num)
+{
+ Atom type_ret = 0;
+ int ret, size_ret = 0;
+ unsigned long num_ret = 0, bytes = 0, i;
+ unsigned char *prop_ret = NULL;
+
+ /* make sure these are initialized */
+ if (num) *num = 0;
+
+ if (data)
+ *data = NULL;
+ else /* we can't store the retrieved data, so just return */
+ return 0;
+
+ if (!win) win = DefaultRootWindow(_ecore_x_disp);
+
+ ret = XGetWindowProperty(_ecore_x_disp, win, property, 0, LONG_MAX,
+ False, type, &type_ret, &size_ret,
+ &num_ret, &bytes, &prop_ret);
+
+ if (ret != Success)
+ return 0;
+
+ if (size != size_ret || !num_ret) {
+ XFree(prop_ret);
+ return 0;
+ }
+
+ if (!(*data = malloc(num_ret * size / 8))) {
+ XFree(prop_ret);
+ return 0;
+ }
+
+ switch (size) {
+ case 8:
+ for (i = 0; i < num_ret; i++)
+ (*data)[i] = prop_ret[i];
+ break;
+ case 16:
+ for (i = 0; i < num_ret; i++)
+ ((uint16_t *) *data)[i] = ((uint16_t *) prop_ret)[i];
+ break;
+ case 32:
+ for (i = 0; i < num_ret; i++)
+ ((uint32_t *) *data)[i] = ((uint32_t *) prop_ret)[i];
+ break;
+ }
+
+ XFree(prop_ret);
+
+ if (num) *num = num_ret;
+ return 1;
+}
+
+void
+ecore_x_window_prop_property_del(Ecore_X_Window win, Ecore_X_Atom property)
+{
+ XDeleteProperty(_ecore_x_disp, win, property);
+}
+
+Ecore_X_Atom *
+ecore_x_window_prop_list(Ecore_X_Window win, int *num_ret)
+{
+ Ecore_X_Atom *atoms;
+ Atom *atom_ret;
+ int num = 0, i;
+
+ if (num_ret) *num_ret = 0;
+
+ atom_ret = XListProperties(_ecore_x_disp, win, &num);
+ if (!atom_ret) return NULL;
+
+ atoms = malloc(num * sizeof(Ecore_X_Atom));
+ if (atoms)
+ {
+ for (i = 0; i < num; i++) atoms[i] = atom_ret[i];
+ if (num_ret) *num_ret = num;
+ }
+ XFree(atom_ret);
+ return atoms;
+}
+
+/**
+ * Set a window string property.
+ * @param win The window
+ * @param type The property
+ * @param str The string
+ *
+ * Set a window string property
+ */
+void
+ecore_x_window_prop_string_set(Ecore_X_Window win, Ecore_X_Atom type, const char *str)
+{
+ XTextProperty xtp;
+
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+ xtp.value = (unsigned char *)str;
+ xtp.format = 8;
+ xtp.encoding = ECORE_X_ATOM_UTF8_STRING;
+ xtp.nitems = strlen(str);
+ XSetTextProperty(_ecore_x_disp, win, &xtp, type);
+}
+
+/**
+ * Get a window string property.
+ * @param win The window
+ * @param type The property
+ *
+ * Return window string property of a window. String must be free'd when done.
+ */
+char *
+ecore_x_window_prop_string_get(Ecore_X_Window win, Ecore_X_Atom type)
+{
+ XTextProperty xtp;
+ char *str = NULL;
+
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+ if (XGetTextProperty(_ecore_x_disp, win, &xtp, type))
+ {
+ int items;
+ char **list = NULL;
+ Status s;
+
+ if (xtp.encoding == ECORE_X_ATOM_UTF8_STRING)
+ {
+ str = strdup((char *)xtp.value);
+ }
+ else
+ {
+#ifdef X_HAVE_UTF8_STRING
+ s = Xutf8TextPropertyToTextList(_ecore_x_disp, &xtp,
+ &list, &items);
+#else
+ s = XmbTextPropertyToTextList(_ecore_x_disp, &xtp,
+ &list, &items);
+#endif
+ if ((s == XLocaleNotSupported) ||
+ (s == XNoMemory) || (s == XConverterNotFound))
+ {
+ str = strdup((char *)xtp.value);
+ }
+ else if ((s >= Success) && (items > 0))
+ {
+ str = strdup(list[0]);
+ }
+ if (list)
+ XFreeStringList(list);
+ }
+ XFree(xtp.value);
+ }
+ return str;
+}
+
+int
+ecore_x_window_prop_protocol_isset(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol)
+{
+ Atom proto, *protos = NULL;
+ int i, ret = 0, protos_count = 0;
+
+ /* check for invalid values */
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
+ return 0;
+
+ proto = _ecore_x_atoms_wm_protocols[protocol];
+
+ if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
+ return ret;
+
+ for (i = 0; i < protos_count; i++)
+ if (protos[i] == proto)
+ {
+ ret = 1;
+ break;
+ }
+
+ XFree(protos);
+
+ return ret;
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+Ecore_X_WM_Protocol *
+ecore_x_window_prop_protocol_list_get(Ecore_X_Window win, int *num_ret)
+{
+ Atom *protos = NULL;
+ int i, protos_count = 0;
+ Ecore_X_WM_Protocol *prot_ret = NULL;
+
+ if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
+ return NULL;
+
+ if ((!protos) || (protos_count <= 0)) return NULL;
+ prot_ret = calloc(1, protos_count * sizeof(Ecore_X_WM_Protocol));
+ if (!prot_ret)
+ {
+ XFree(protos);
+ return NULL;
+ }
+ for (i = 0; i < protos_count; i++)
+ {
+ Ecore_X_WM_Protocol j;
+
+ prot_ret[i] = -1;
+ for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++)
+ {
+ if (_ecore_x_atoms_wm_protocols[j] == protos[i])
+ prot_ret[i] = j;
+ }
+ }
+ XFree(protos);
+ *num_ret = protos_count;
+ return prot_ret;
+}
diff --git a/ecore/src/lib/ecore_x/ecore_x_window_shape.c b/ecore/src/lib/ecore_x/ecore_x_window_shape.c
new file mode 100644
index 0000000..27ea707
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_window_shape.c
@@ -0,0 +1,159 @@
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+/**
+ * @defgroup Ecore_X_Window_Shape X Window Shape Functions
+ *
+ * These functions use the shape extension of the X server to change
+ * shape of given windows.
+ */
+
+/**
+ * Sets the shape of the given window to that given by the pixmap @p mask.
+ * @param win The given window.
+ * @param mask A 2-bit depth pixmap that provides the new shape of the
+ * window.
+ * @ingroup Ecore_X_Window_Shape
+ */
+void
+ecore_x_window_shape_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask)
+{
+ XShapeCombineMask(_ecore_x_disp, win, ShapeBounding, 0, 0, mask, ShapeSet);
+}
+
+void
+ecore_x_window_shape_window_set(Ecore_X_Window win, Ecore_X_Window shape_win)
+{
+ XShapeCombineShape(_ecore_x_disp, win, ShapeBounding, 0, 0, shape_win, ShapeBounding, ShapeSet);
+}
+
+void
+ecore_x_window_shape_window_set_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y)
+{
+ XShapeCombineShape(_ecore_x_disp, win, ShapeBounding, x, y, shape_win, ShapeBounding, ShapeSet);
+}
+
+void
+ecore_x_window_shape_rectangle_set(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ XRectangle rect;
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeSet, Unsorted);
+}
+
+void
+ecore_x_window_shape_rectangles_set(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num)
+{
+ XRectangle *rect = NULL;
+ int i;
+
+ if (num > 0)
+ {
+ rect = alloca(sizeof(XRectangle) * num);
+ for (i = 0; i < num; i++)
+ {
+ rect[i].x = rects[i].x;
+ rect[i].y = rects[i].y;
+ rect[i].width = rects[i].width;
+ rect[i].height = rects[i].height;
+ }
+ }
+ XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, rect, num, ShapeSet, Unsorted);
+}
+
+void
+ecore_x_window_shape_window_add(Ecore_X_Window win, Ecore_X_Window shape_win)
+{
+ XShapeCombineShape(_ecore_x_disp, win, ShapeBounding, 0, 0, shape_win, ShapeBounding, ShapeUnion);
+}
+
+void
+ecore_x_window_shape_window_add_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y)
+{
+ XShapeCombineShape(_ecore_x_disp, win, ShapeBounding, x, y, shape_win, ShapeBounding, ShapeUnion);
+}
+
+void
+ecore_x_window_shape_rectangle_add(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ XRectangle rect;
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeUnion, Unsorted);
+}
+
+void
+ecore_x_window_shape_rectangle_clip(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ XRectangle rect;
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeIntersect, Unsorted);
+}
+
+void
+ecore_x_window_shape_rectangles_add(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num)
+{
+ XRectangle *rect = NULL;
+ int i;
+
+ if (num > 0)
+ {
+ rect = alloca(sizeof(XRectangle) * num);
+ for (i = 0; i < num; i++)
+ {
+ rect[i].x = rects[i].x;
+ rect[i].y = rects[i].y;
+ rect[i].width = rects[i].width;
+ rect[i].height = rects[i].height;
+ }
+ }
+ XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, rect, num, ShapeUnion, Unsorted);
+}
+
+Ecore_X_Rectangle *
+ecore_x_window_shape_rectangles_get(Ecore_X_Window win, int *num_ret)
+{
+ XRectangle *rect;
+ Ecore_X_Rectangle *rects = NULL;
+ int i, num = 0, ord;
+
+ rect = XShapeGetRectangles(_ecore_x_disp, win, ShapeBounding, &num, &ord);
+ if (rect)
+ {
+ rects = malloc(sizeof(Ecore_X_Rectangle) * num);
+ if (rects)
+ {
+ for (i = 0; i < num; i++)
+ {
+ rects[i].x = rect[i].x;
+ rects[i].y = rect[i].y;
+ rects[i].width = rect[i].width;
+ rects[i].height = rect[i].height;
+ }
+ }
+ XFree(rect);
+ }
+ if (num_ret) *num_ret = num;
+ return rects;
+}
+
+void
+ecore_x_window_shape_events_select(Ecore_X_Window win, int on)
+{
+ if (on)
+ XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
+ else
+ XShapeSelectInput(_ecore_x_disp, win, 0);
+}
diff --git a/ecore/src/lib/ecore_x/ecore_x_xinerama.c b/ecore/src/lib/ecore_x/ecore_x_xinerama.c
new file mode 100644
index 0000000..d26d8aa
--- /dev/null
+++ b/ecore/src/lib/ecore_x/ecore_x_xinerama.c
@@ -0,0 +1,54 @@
+/*
+ * Xinerama code
+ */
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+#ifdef ECORE_XINERAMA
+static XineramaScreenInfo *_xin_info = NULL;
+static int _xin_scr_num = 0;
+#endif
+
+int
+ecore_x_xinerama_screen_count_get(void)
+{
+#ifdef ECORE_XINERAMA
+ if (_xin_info) XFree(_xin_info);
+ _xin_info = NULL;
+ _xin_info = XineramaQueryScreens(_ecore_x_disp, &_xin_scr_num);
+ if (_xin_info) return _xin_scr_num;
+ else return 0;
+#else
+ return 0;
+#endif
+}
+
+int
+ecore_x_xinerama_screen_geometry_get(int screen, int *x, int *y, int *w, int *h)
+{
+#ifdef ECORE_XINERAMA
+ if (_xin_info)
+ {
+ int i;
+
+ for (i = 0; i < _xin_scr_num; i++)
+ {
+ if (_xin_info[i].screen_number == screen)
+ {
+ if (x) *x = _xin_info[i].x_org;
+ if (y) *y = _xin_info[i].y_org;
+ if (w) *w = _xin_info[i].width;
+ if (h) *h = _xin_info[i].height;
+ return 1;
+ }
+ }
+ }
+#endif
+ if (x) *x = 0;
+ if (y) *y = 0;
+ if (w) *w = DisplayWidth(_ecore_x_disp, 0);
+ if (h) *h = DisplayHeight(_ecore_x_disp, 0);
+ return 0;
+}