Enlightenment CVS committal

Author  : sebastid
Project : e17
Module  : libs/ecore

Dir     : e17/libs/ecore/src/lib/ecore_x


Modified Files:
        Ecore_X.h ecore_x_dnd.c ecore_x_events.c ecore_x_private.h 
        ecore_x_selection.c 


Log Message:
The start of some dnd cleanups.
- Formatting
- ecore_x_dnd_type_set() to set the type of a dnd object
- Fix SelectionNotify to accept dnd
- ecore_x_selection_xdnd_request_data_get() to get the data from a drop

===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ecore/src/lib/ecore_x/Ecore_X.h,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -3 -r1.99 -r1.100
--- Ecore_X.h   14 Mar 2005 15:32:06 -0000      1.99
+++ Ecore_X.h   22 Mar 2005 21:59:33 -0000      1.100
@@ -75,6 +75,7 @@
 typedef enum _Ecore_X_Selection {
    ECORE_X_SELECTION_PRIMARY,
    ECORE_X_SELECTION_SECONDARY,
+   ECORE_X_SELECTION_XDND,
    ECORE_X_SELECTION_CLIPBOARD
 } Ecore_X_Selection;
 
@@ -809,6 +810,7 @@
 EAPI void             ecore_x_selection_clipboard_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_data_get(void **buf, 
int *len);
+EAPI void             ecore_x_selection_xdnd_request_data_get(void **buf, int 
*len);
 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));
@@ -817,7 +819,9 @@
 
 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_begin (Ecore_X_Window source, unsigned char 
*data, int size);
+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_send_status(int will_accept, int suppress, 
Ecore_X_Rectangle rectangle, Ecore_X_Atom action);
                  
 EAPI Ecore_X_Window   ecore_x_window_new(Ecore_X_Window parent, int x, int y, 
int w, int h);
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ecore/src/lib/ecore_x/ecore_x_dnd.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -3 -r1.14 -r1.15
--- ecore_x_dnd.c       27 Dec 2004 18:30:28 -0000      1.14
+++ ecore_x_dnd.c       22 Mar 2005 21:59:33 -0000      1.15
@@ -1,3 +1,6 @@
+/*
+ * 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"
@@ -8,88 +11,177 @@
 static int _ecore_x_dnd_init_count = 0;
 
 void
-_ecore_x_dnd_init (void)
+_ecore_x_dnd_init(void)
 {
    if (!_ecore_x_dnd_init_count)
-   {
-      _xdnd = calloc(1, sizeof(Ecore_X_DND_Protocol));
-   
-      _xdnd->version = ECORE_X_DND_VERSION;
-      _xdnd->source = None;
-      _xdnd->dest = None;
-      _xdnd->state = ECORE_X_DND_IDLE;
-   }
+     {
+       _xdnd = calloc(1, sizeof(Ecore_X_DND_Protocol));
 
-   _ecore_x_dnd_init_count++;
+       _xdnd->version = ECORE_X_DND_VERSION;
+       _xdnd->source = None;
+       _xdnd->dest = None;
+       _xdnd->state = ECORE_X_DND_IDLE;
+     }
 
+   _ecore_x_dnd_init_count++;
 }
 
 void
 _ecore_x_dnd_shutdown(void)
 {
-   if(_xdnd)
-      free(_xdnd);
+   _ecore_x_dnd_init_count--;
+   if (_ecore_x_dnd_init_count > 0)
+     return;
+
+   if (_xdnd)
+     free(_xdnd);
    _xdnd = NULL;
    _ecore_x_dnd_init_count = 0;
 }
 
 void
-ecore_x_dnd_aware_set (Ecore_X_Window win, int on)
+ecore_x_dnd_aware_set(Ecore_X_Window win, int on)
 {
    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);
+     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);
-   /* TODO: Add dnd typelist to window properties */
+     ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_AWARE);
+   ecore_x_dnd_type_set(win, "text/plain", 1);
 }
 
 int
-ecore_x_dnd_version_get (Ecore_X_Window win)
+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;
-   }
+     {
+       int version = (int) *prop_data;
+       free(prop_data);
+       return version;
+     }
    else
-      return 0;
-} 
+     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(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_Protocol *
-_ecore_x_dnd_protocol_get (void)
+_ecore_x_dnd_protocol_get(void)
 {
    return _xdnd;
 }
 
-int 
-ecore_x_dnd_begin (Ecore_X_Window source, unsigned char *data, int size)
+int
+ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size)
 {
    unsigned char *buf;
-   Atom _type_text_plain; /* FIXME: API-ize this stuff */
+   unsigned char *atoms;
+   int num;
 
    if (!ecore_x_dnd_version_get(source))
-      return 0;
-   
+     return 0;
+
    /* Take ownership of XdndSelection */
    XSetSelectionOwner(_ecore_x_disp, ECORE_X_ATOM_SELECTION_XDND, source,
                       _ecore_x_event_last_time);
    if (XGetSelectionOwner(_ecore_x_disp, ECORE_X_ATOM_SELECTION_XDND) != 
source)
-      return 0;
-   
+     return 0;
+
    /* Initialize Selection Data Struct */
    _xdnd_selection.win = source;
    _xdnd_selection.selection = ECORE_X_ATOM_SELECTION_XDND;
    _xdnd_selection.length = size;
    _xdnd_selection.time = _ecore_x_event_last_time;
-   
+
    buf = malloc(size);
    memcpy(buf, data, size);
    _xdnd_selection.data = buf;
@@ -102,22 +194,21 @@
    _xdnd->action = ECORE_X_ATOM_XDND_ACTION_ASK;
    _xdnd->accepted_action = None;
 
-   /* TODO: Set supported data types in API */
-   _type_text_plain = ecore_x_atom_get("text/plain");
-   _xdnd->num_types = 1;
-   _xdnd->types = (Atom *) calloc(1, sizeof(Atom));
-   _xdnd->types[0] = _type_text_plain;
+   ecore_x_window_prop_property_get(source, ECORE_X_ATOM_XDND_TYPE_LIST,
+                                    XA_ATOM, 32, &atoms, &num);
+   _xdnd->num_types = num;
+   _xdnd->types = (Ecore_X_Atom *)atoms;
    return 1;
 }
 
-void 
+void
 ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle 
rectangle, Ecore_X_Atom action)
 {
    XEvent xev;
 
-   if (_xdnd->state == ECORE_X_DND_IDLE || 
+   if (_xdnd->state == ECORE_X_DND_IDLE ||
        _xdnd->state == ECORE_X_DND_FINISHED)
-      return;
+     return;
 
    memset(&xev, 0, sizeof(XEvent));
 
@@ -136,10 +227,10 @@
 
    xev.xclient.data.l[0] = _xdnd->dest;
    if (will_accept)
-      xev.xclient.data.l[1] |= 0x1UL;
+     xev.xclient.data.l[1] |= 0x1UL;
    if (!suppress)
-      xev.xclient.data.l[1] |= 0x2UL;
-   
+     xev.xclient.data.l[1] |= 0x2UL;
+
    /* Set rectangle information */
    xev.xclient.data.l[2] = rectangle.x;
    xev.xclient.data.l[2] <<= 16;
@@ -149,15 +240,15 @@
    xev.xclient.data.l[3] |= rectangle.height;
 
    if (will_accept)
-   {
-      xev.xclient.data.l[4] = action;
-      _xdnd->accepted_action = action;
-   }
+     {
+       xev.xclient.data.l[4] = action;
+       _xdnd->accepted_action = action;
+     }
    else
-   {
-      xev.xclient.data.l[4] = None;
-      _xdnd->accepted_action = action;
-   }
+     {
+       xev.xclient.data.l[4] = None;
+       _xdnd->accepted_action = action;
+     }
 
    XSendEvent(_ecore_x_disp, _xdnd->source, False, 0, &xev);
 }
@@ -167,7 +258,7 @@
 {
    XEvent         xev;
    Ecore_X_Window win;
-   
+
    /* Preinitialize XEvent struct */
    memset(&xev, 0, sizeof(XEvent));
    xev.xany.type = ClientMessage;
@@ -177,89 +268,89 @@
    /* 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);
+     win = ecore_x_window_parent_get(win);
 
    /* Send XdndLeave to current destination window if we have left it */
    if ((win != _xdnd->dest) && (_xdnd->dest))
-   {
-      xev.xclient.window = _xdnd->dest;
-      xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
-      xev.xclient.data.l[0] = _xdnd->source;
+     {
+       xev.xclient.window = _xdnd->dest;
+       xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
+       xev.xclient.data.l[0] = _xdnd->source;
 
-      XSendEvent(_ecore_x_disp, _xdnd->dest, False, 0, &xev);
-   }
+       XSendEvent(_ecore_x_disp, _xdnd->dest, False, 0, &xev);
+     }
 
    if (win)
-   {
-      _xdnd->version = MIN(ECORE_X_DND_VERSION, 
-                           ecore_x_dnd_version_get(win));
-      if (win != _xdnd->dest)
-      {
-         int i;
-         
-         /* Entered new window, send XdndEnter */
-         xev.xclient.window = win;
-         xev.xclient.message_type = ECORE_X_ATOM_XDND_ENTER;
-         xev.xclient.data.l[0] = _xdnd->source;
-         if(_xdnd->num_types > 3)
-            xev.xclient.data.l[1] |= 0x1UL;
-         else
-            xev.xclient.data.l[1] &= 0xfffffffeUL;
-         xev.xclient.data.l[1] |= ((unsigned long) _xdnd->version) << 24;
-         
-         for (i = 0; i < MIN(_xdnd->num_types, 3); ++i)
-            xev.xclient.data.l[i + 2] = _xdnd->types[i];
-         XSendEvent(_ecore_x_disp, win, False, 0, &xev);
-         _xdnd->await_status = 0;
-      }
-
-      /* FIXME: Handle box information */
-      /*if (!_xdnd->await_status)
-      {*/
-         xev.xclient.window = win;
-         xev.xclient.message_type = ECORE_X_ATOM_XDND_POSITION;
-         xev.xclient.data.l[0] = _xdnd->source;
-         xev.xclient.data.l[1] = 0; /* Reserved */
-         xev.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
-         xev.xclient.data.l[3] = CurrentTime; /* Version 1 */
-         xev.xclient.data.l[4] = _xdnd->action; /* Version 2, Needs to be 
pre-set */
-         XSendEvent(_ecore_x_disp, win, False, 0, &xev);
-         _xdnd->await_status = 1;
-      /*}*/
-   }
+     {
+       _xdnd->version = MIN(ECORE_X_DND_VERSION,
+                            ecore_x_dnd_version_get(win));
+       if (win != _xdnd->dest)
+         {
+            int i;
+
+            /* Entered new window, send XdndEnter */
+            xev.xclient.window = win;
+            xev.xclient.message_type = ECORE_X_ATOM_XDND_ENTER;
+            xev.xclient.data.l[0] = _xdnd->source;
+            if(_xdnd->num_types > 3)
+              xev.xclient.data.l[1] |= 0x1UL;
+            else
+              xev.xclient.data.l[1] &= 0xfffffffeUL;
+            xev.xclient.data.l[1] |= ((unsigned long) _xdnd->version) << 24;
+
+            for (i = 0; i < MIN(_xdnd->num_types, 3); ++i)
+              xev.xclient.data.l[i + 2] = _xdnd->types[i];
+            XSendEvent(_ecore_x_disp, win, False, 0, &xev);
+            _xdnd->await_status = 0;
+         }
+
+       /* FIXME: Handle box information */
+       /*if (!_xdnd->await_status)
+         {*/
+       xev.xclient.window = win;
+       xev.xclient.message_type = ECORE_X_ATOM_XDND_POSITION;
+       xev.xclient.data.l[0] = _xdnd->source;
+       xev.xclient.data.l[1] = 0; /* Reserved */
+       xev.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
+       xev.xclient.data.l[3] = CurrentTime; /* Version 1 */
+       xev.xclient.data.l[4] = _xdnd->action; /* Version 2, Needs to be 
pre-set */
+       XSendEvent(_ecore_x_disp, win, False, 0, &xev);
+       _xdnd->await_status = 1;
+       /*}*/
+     }
 
    if (_xdnd->state == ECORE_X_DND_DROPPED)
-   {
-      if (win)
-      {
-         if (_xdnd->will_accept)
-         {
-            xev.xclient.window = win;
-            xev.xclient.message_type = ECORE_X_ATOM_XDND_DROP;
-            xev.xclient.data.l[0] = _xdnd->source;
-            xev.xclient.data.l[1] = 0;
-            xev.xclient.data.l[2] = CurrentTime;
-            xev.xclient.data.l[3] = 0;
-            xev.xclient.data.l[4] = 0;
-            XSendEvent(_ecore_x_disp, win, False, 0, &xev);
-         }
-         else
-         {
-            xev.xclient.window = win;
-            xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
-            xev.xclient.data.l[0] = _xdnd->source;
-            memset(xev.xclient.data.l + 1, 0, sizeof(long) * 3); /* Evil */
-            XSendEvent(_ecore_x_disp, win, False, 0, &xev);
-         }
-      }
+     {
+       if (win)
+         {
+            if (_xdnd->will_accept)
+              {
+                 xev.xclient.window = win;
+                 xev.xclient.message_type = ECORE_X_ATOM_XDND_DROP;
+                 xev.xclient.data.l[0] = _xdnd->source;
+                 xev.xclient.data.l[1] = 0;
+                 xev.xclient.data.l[2] = CurrentTime;
+                 xev.xclient.data.l[3] = 0;
+                 xev.xclient.data.l[4] = 0;
+                 XSendEvent(_ecore_x_disp, win, False, 0, &xev);
+              }
+            else
+              {
+                 xev.xclient.window = win;
+                 xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
+                 xev.xclient.data.l[0] = _xdnd->source;
+                 memset(xev.xclient.data.l + 1, 0, sizeof(long) * 3); /* Evil 
*/
+                 XSendEvent(_ecore_x_disp, win, False, 0, &xev);
+              }
+         }
 
-      _xdnd->will_accept = 0;
-   }
+       _xdnd->will_accept = 0;
+     }
    _xdnd->dest = win;
 }
 
 #if 0 /* Unused? */
-void 
+void
 _ecore_x_dnd_send_finished(void)
 {
    XEvent   xev;
===================================================================
RCS file: 
/cvsroot/enlightenment/e17/libs/ecore/src/lib/ecore_x/ecore_x_events.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -3 -r1.41 -r1.42
--- ecore_x_events.c    2 Mar 2005 07:06:44 -0000       1.41
+++ ecore_x_events.c    22 Mar 2005 21:59:34 -0000      1.42
@@ -982,7 +982,7 @@
    Ecore_X_Event_Selection_Clear *e;
    Atom sel;
 
-   if(!(d = _ecore_x_selection_get(xevent->xselectionclear.selection)))
+   if (!(d = _ecore_x_selection_get(xevent->xselectionclear.selection)))
       return;
    if (xevent->xselectionclear.time > d->time)
    {
@@ -1073,6 +1073,8 @@
       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
===================================================================
RCS file: 
/cvsroot/enlightenment/e17/libs/ecore/src/lib/ecore_x/ecore_x_private.h,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -3 -r1.36 -r1.37
--- ecore_x_private.h   10 Jan 2005 13:11:49 -0000      1.36
+++ ecore_x_private.h   22 Mar 2005 21:59:34 -0000      1.37
@@ -90,9 +90,9 @@
    } pos;
    
    Time time;
-   
-   Atom *types;
-   Atom action, accepted_action;
+
+   Ecore_X_Atom *types;
+   Ecore_X_Atom action, accepted_action;
    int num_types;
    
    int will_accept;
===================================================================
RCS file: 
/cvsroot/enlightenment/e17/libs/ecore/src/lib/ecore_x/ecore_x_selection.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -3 -r1.19 -r1.20
--- ecore_x_selection.c 2 Mar 2005 07:06:44 -0000       1.19
+++ ecore_x_selection.c 22 Mar 2005 21:59:35 -0000      1.20
@@ -7,7 +7,7 @@
 #include "Ecore_X_Atoms.h"
 
 static Ecore_X_Selection_Data selections[3];
-static Ecore_X_Selection_Data request_data[3];
+static Ecore_X_Selection_Data request_data[4];
 static Ecore_X_Selection_Converter *converters = NULL;
 
 static int _ecore_x_selection_converter_text(char *target, void *data, int 
size, void **data_ret, int *size_ret);
@@ -59,8 +59,10 @@
       i = 0;
    else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
       i = 1;
-   else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+   else if (selection == ECORE_X_ATOM_SELECTION_XDND)
       i = 2;
+   else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+      i = 3;
    else
       return;
 
@@ -109,6 +111,21 @@
 }
 
 /**
+ * Fetch the data returned by a XDND selection request.
+ * @param buf A pointer to hold the selection data
+ * @param len The size of the data
+ *
+ * Get the converted data from a previous XDND selection
+ * request. The buffer must be freed when done with.
+ */
+void
+ecore_x_selection_xdnd_request_data_get(void **buf, int *len)
+{
+   _ecore_x_selection_request_data_get(ECORE_X_ATOM_SELECTION_XDND,
+                                       buf, len);
+}
+
+/**
  * Fetch the data returned by a CLIPBOARD selection request.
  * @param buf A pointer to hold the selection data
  * @param len The size of the data
@@ -131,8 +148,10 @@
       i = 0;
    else if (data.selection == ECORE_X_ATOM_SELECTION_SECONDARY)
       i = 1;
-   else if (data.selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+   else if (data.selection == ECORE_X_ATOM_SELECTION_XDND)
       i = 2;
+   else if (data.selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+      i = 3;
    else
       return;
 




-------------------------------------------------------
This SF.net email is sponsored by: 2005 Windows Mobile Application Contest
Submit applications for Windows Mobile(tm)-based Pocket PCs or Smartphones
for the chance to win $25,000 and application distribution. Enter today at
http://ads.osdn.com/?ad_id=6882&alloc_id=15148&op=click
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to