discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=131e0e19837b56ef7887ef3c447e64789b480afb

commit 131e0e19837b56ef7887ef3c447e64789b480afb
Author: Mike Blumenkrantz <zm...@samsung.com>
Date:   Fri Jan 10 02:26:06 2014 -0500

    ecore-x now supports XPRESENT
    
    see 
http://cgit.freedesktop.org/xorg/proto/presentproto/plain/presentproto.txt
---
 configure.ac                               |  24 +++-
 src/Makefile_Ecore_X.am                    |   2 +
 src/lib/ecore_x/Ecore_X.h                  |  78 ++++++++++++
 src/lib/ecore_x/xcb/ecore_xcb_events.c     |  16 +++
 src/lib/ecore_x/xcb/ecore_xcb_extensions.c |   3 +
 src/lib/ecore_x/xcb/ecore_xcb_present.c    | 194 +++++++++++++++++++++++++++++
 src/lib/ecore_x/xcb/ecore_xcb_private.h    |   5 +
 src/lib/ecore_x/xlib/ecore_x.c             |   5 +
 src/lib/ecore_x/xlib/ecore_x_events.c      |  22 ++--
 src/lib/ecore_x/xlib/ecore_x_present.c     | 169 +++++++++++++++++++++++++
 src/lib/ecore_x/xlib/ecore_x_private.h     |   9 ++
 11 files changed, 514 insertions(+), 13 deletions(-)

diff --git a/configure.ac b/configure.ac
index 8f99186..62ed2c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2697,6 +2697,17 @@ AC_ARG_ENABLE([gesture],
    ],
    [want_gesture="no"])
 
+AC_ARG_ENABLE([xpresent],
+   [AC_HELP_STRING([--enable-xpresent], [enable X11 XPresent extension 
support])],
+   [
+    if test "x${enableval}" = "xyes" ; then
+       want_xpresent="yes"
+    else
+       want_xpresent="no"
+    fi
+   ],
+   [want_xpresent="no"])
+
 AC_ARG_ENABLE([xinput2],
    [AC_HELP_STRING([--disable-xinput2], [disable X11 XInput v2.x support])],
    [
@@ -2861,6 +2872,11 @@ if test "x${want_x11_xlib}" = "xyes" ; then
    ECORE_CHECK_X_EXTENSION([Xtest], [XTest.h], [Xtst], [XTestFakeKeyEvent])
    ECORE_CHECK_X_EXTENSION([Xss], [scrnsaver.h], [Xss], 
[XScreenSaverSelectInput])
 
+   if test "${want_xpresent}" = "yes"; then
+      ECORE_CHECK_X_EXTENSION([Xpresent], [Xpresent.h], [Xpresent], 
[XPresentQueryExtension])
+   fi
+   EFL_ADD_FEATURE([ECORE_X], [xpresent])
+
    if test "${want_gesture}" = "yes"; then
       ECORE_CHECK_X_EXTENSION([Xgesture], [gesture.h], [Xgesture], 
[XGestureQueryExtension])
    fi
@@ -2888,7 +2904,7 @@ fi
 if test "${want_x11_xcb}" = "yes"; then
 dnl note: added pixman-1 as ecore_xcb_region uses that
    EFL_DEPEND_PKG([ECORE_X], [ECORE_X_XCB],
-      [x11-xcb xcb xcb-shm xcb-event xcb-icccm >= 0.3.8 xcb-util >= 0.3.8 
xcb-image xcb-keysyms >= 0.3.8 xcb-composite xcb-damage xcb-dpms xcb-randr 
xcb-render xcb-screensaver xcb-shape xcb-sync xcb-xfixes xcb-xinerama 
xcb-xprint xcb-xtest xcb-renderutil pixman-1])
+      [x11-xcb xcb xcb-shm xcb-event xcb-icccm >= 0.3.8 xcb-util >= 0.3.8 
xcb-image xcb-keysyms >= 0.3.8 xcb-composite xcb-present xcb-damage xcb-dpms 
xcb-randr xcb-render xcb-screensaver xcb-shape xcb-sync xcb-xfixes xcb-xinerama 
xcb-xprint xcb-xtest xcb-renderutil pixman-1])
 
 dnl TODO: remove these ifdefs from code!
    AC_DEFINE([ECORE_XCB_COMPOSITE], [1], [Build support for XCB composite])
@@ -2905,6 +2921,12 @@ dnl TODO: remove these ifdefs from code!
    AC_DEFINE([ECORE_XCB_XTEST], [1], [Build support for XCB xtest])
    AC_DEFINE([ECORE_XCB_CURSOR], [1], [Build support for XCB cursor])
 
+   EFL_OPTIONAL_DEPEND_PKG([ECORE_X], [${want_xpresent}], [ECORE_XCB_XPRESENT],
+      [xcb-present])
+   AC_DEFINE_IF([ECORE_XCB_XPRESENT], [test "${want_xpresent}" = "yes"],
+      [1], [Build support for XCB Present])
+   EFL_ADD_FEATURE([ECORE_X], [xpresent])
+
    EFL_OPTIONAL_DEPEND_PKG([ECORE_X], [${want_gesture}], [ECORE_XCB_GESTURE],
       [xcb-gesture])
    AC_DEFINE_IF([ECORE_XCB_XGESTURE], [test "${want_gesture}" = "yes"],
diff --git a/src/Makefile_Ecore_X.am b/src/Makefile_Ecore_X.am
index d0c6e85..0b6d390 100644
--- a/src/Makefile_Ecore_X.am
+++ b/src/Makefile_Ecore_X.am
@@ -38,6 +38,7 @@ lib/ecore_x/xcb/ecore_xcb_input.c \
 lib/ecore_x/xcb/ecore_xcb_gesture.c \
 lib/ecore_x/xcb/ecore_xcb_mwm.c \
 lib/ecore_x/xcb/ecore_xcb_pixmap.c \
+lib/ecore_x/xcb/ecore_xcb_present.c \
 lib/ecore_x/xcb/ecore_xcb_region.c \
 lib/ecore_x/xcb/ecore_xcb_selection.c \
 lib/ecore_x/xcb/ecore_xcb_textlist.c \
@@ -75,6 +76,7 @@ lib/ecore_x/xlib/ecore_x_window.c \
 lib/ecore_x/xlib/ecore_x_window_prop.c \
 lib/ecore_x/xlib/ecore_x_window_shape.c \
 lib/ecore_x/xlib/ecore_x_pixmap.c \
+lib/ecore_x/xlib/ecore_x_present.c \
 lib/ecore_x/xlib/ecore_x_gc.c \
 lib/ecore_x/xlib/ecore_x_xinerama.c \
 lib/ecore_x/xlib/ecore_x_screensaver.c \
diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h
index f7c0e77..6dbed60 100644
--- a/src/lib/ecore_x/Ecore_X.h
+++ b/src/lib/ecore_x/Ecore_X.h
@@ -94,6 +94,7 @@ typedef void           Ecore_X_Connection;
 typedef void           Ecore_X_Screen;
 typedef Ecore_X_ID     Ecore_X_Sync_Counter;
 typedef Ecore_X_ID     Ecore_X_Sync_Alarm;
+typedef Ecore_X_ID     Ecore_X_Sync_Fence; /**< @since 1.9 */
 typedef void           Ecore_X_XRegion;
 
 typedef Ecore_X_ID     Ecore_X_Randr_Output;
@@ -489,12 +490,18 @@ typedef struct _Ecore_X_Event_Startup_Sequence            
 Ecore_X_Event_Startup
 
 typedef struct _Ecore_X_Event_Generic                      
Ecore_X_Event_Generic;
 
+
+typedef struct Ecore_X_Event_Present_Configure             
Ecore_X_Event_Present_Configure; /**< @since 1.9 */
+typedef struct Ecore_X_Event_Present_Complete              
Ecore_X_Event_Present_Complete; /**< @since 1.9 */
+typedef struct Ecore_X_Event_Present_Idle                  
Ecore_X_Event_Present_Idle; /**< @since 1.9 */
+
 typedef struct _Ecore_X_Randr_Screen_Size                  
Ecore_X_Randr_Screen_Size;
 typedef struct _Ecore_X_Randr_Screen_Size_MM               
Ecore_X_Randr_Screen_Size_MM;
 typedef struct _Ecore_X_Randr_Crtc_Info                    
Ecore_X_Randr_Crtc_Info; /**< @since 1.8 */
 
 typedef struct _Ecore_X_Xdnd_Position                      
Ecore_X_Xdnd_Position;
 
+
 struct _Ecore_X_Event_Mouse_In
 {
    int                  modifiers;
@@ -1053,6 +1060,59 @@ struct _Ecore_X_Event_Generic
    void        *data;
 };
 
+typedef enum Ecore_X_Present_Event_Mask
+{
+    ECORE_X_PRESENT_EVENT_MASK_NO_EVENT = 0,
+    ECORE_X_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY = 1,
+    ECORE_X_PRESENT_EVENT_MASK_COMPLETE_NOTIFY = 2,
+    ECORE_X_PRESENT_EVENT_MASK_IDLE_NOTIFY = 4,
+} Ecore_X_Present_Event_Mask; /**< @since 1.9 */
+
+typedef struct Ecore_X_Present
+{
+   Ecore_X_Window win;
+   unsigned int serial;
+} Ecore_X_Present; /**< @since 1.9 */
+
+struct Ecore_X_Event_Present_Configure
+{
+   Ecore_X_Window win;
+
+   int x, y;
+   unsigned int width, height;
+   int off_x, off_y;
+   int pixmap_width, pixmap_height;
+   long pixmap_flags;
+}; /**< @since 1.9 */
+
+typedef enum
+{
+   ECORE_X_PRESENT_COMPLETE_MODE_COPY,
+   ECORE_X_PRESENT_COMPLETE_MODE_FLIP,
+   ECORE_X_PRESENT_COMPLETE_MODE_SKIP,
+} Ecore_X_Present_Complete_Mode;
+
+struct Ecore_X_Event_Present_Complete
+{
+   Ecore_X_Window win;
+
+   unsigned int serial; // value provided when generating request
+   unsigned long long ust; // system time of presentation
+   unsigned long long msc; // frame count at time of presentation
+   Eina_Bool kind : 1; /* 0 for PresentCompleteKindPixmap (PresentPixmap 
completion),
+                          1 for PresentCompleteKindNotifyMsc (PresentNotifyMSC 
completion) */
+   Ecore_X_Present_Complete_Mode mode;
+}; /**< @since 1.9 */
+
+struct Ecore_X_Event_Present_Idle
+{
+   Ecore_X_Window win;
+
+   unsigned int serial;
+   Ecore_X_Pixmap pixmap;
+   Ecore_X_Sync_Fence idle_fence;
+}; /**< @since 1.9 */
+
 EAPI extern int ECORE_X_EVENT_ANY; /**< low level event dependent on
                                         backend in use, if Xlib will be 
XEvent, if XCB will be xcb_generic_event_t.
                                         @warning avoid using it.
@@ -1118,6 +1178,10 @@ EAPI extern int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY; /** 
@since 1.7 */
 
 EAPI extern int ECORE_X_EVENT_GENERIC;
 
+EAPI extern int ECORE_X_EVENT_PRESENT_CONFIGURE; /**< @since 1.9 */
+EAPI extern int ECORE_X_EVENT_PRESENT_COMPLETE; /**< @since 1.9 */
+EAPI extern int ECORE_X_EVENT_PRESENT_IDLE; /**< @since 1.9 */
+
 EAPI extern int ECORE_X_EVENT_XDND_ENTER;
 EAPI extern int ECORE_X_EVENT_XDND_POSITION;
 EAPI extern int ECORE_X_EVENT_XDND_STATUS;
@@ -2356,6 +2420,20 @@ EAPI void               
ecore_x_composite_window_events_enable(Ecore_X_Window wi
 EAPI Ecore_X_Window     ecore_x_composite_render_window_enable(Ecore_X_Window 
root);
 EAPI void               ecore_x_composite_render_window_disable(Ecore_X_Window 
root);
 
+/* XPresent Extension Support */
+/** @since 1.9 */
+EAPI void ecore_x_present_select_events(Ecore_X_Window win, unsigned int 
events);
+/** @since 1.9 */
+EAPI void ecore_x_present_notify_msc(Ecore_X_Window win, unsigned int serial, 
unsigned long long target_msc, unsigned long long divisor, unsigned long long 
remainder);
+/** @since 1.9 */
+EAPI void ecore_x_present_pixmap(Ecore_X_Window win, Ecore_X_Pixmap pixmap, 
unsigned int serial, Ecore_X_Region valid,
+                                 Ecore_X_Region update, int x_off, int y_off, 
Ecore_X_Randr_Crtc target_crtc,
+                                 Ecore_X_Sync_Fence wait_fence, 
Ecore_X_Sync_Fence idle_fence, unsigned int options,
+                                 unsigned long long target_msc, unsigned long 
long divisor, unsigned long long remainder,
+                                 Ecore_X_Present *notifies, int num_notifies);
+/** @since 1.9 */
+EAPI Eina_Bool ecore_x_present_exists(void);
+
 /* XDamage Extension Support */
 typedef Ecore_X_ID Ecore_X_Damage;
 
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_events.c 
b/src/lib/ecore_x/xcb/ecore_xcb_events.c
index 7f76d7a..adee7ce 100644
--- a/src/lib/ecore_x/xcb/ecore_xcb_events.c
+++ b/src/lib/ecore_x/xcb/ecore_xcb_events.c
@@ -18,6 +18,9 @@
 # ifdef ECORE_XCB_XFIXES
 #  include <xcb/xfixes.h>
 # endif
+# ifdef ECORE_XCB_XPRESENT
+#  include <xcb/present.h>
+# endif
 # ifdef ECORE_XCB_XGESTURE
 #  include <xcb/gesture.h>
 # endif
@@ -184,6 +187,10 @@ EAPI int ECORE_X_EVENT_XKB_STATE_NOTIFY = 0;
 EAPI int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = 0;
 EAPI int ECORE_X_EVENT_GENERIC = 0;
 
+EAPI int ECORE_X_EVENT_PRESENT_CONFIGURE = 0;
+EAPI int ECORE_X_EVENT_PRESENT_COMPLETE = 0;
+EAPI int ECORE_X_EVENT_PRESENT_IDLE = 0;
+
 EAPI int ECORE_X_RAW_BUTTON_PRESS = 0;
 EAPI int ECORE_X_RAW_BUTTON_RELEASE = 0;
 EAPI int ECORE_X_RAW_MOTION = 0;
@@ -253,6 +260,10 @@ _ecore_xcb_events_init(void)
         ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = ecore_event_type_new();
         ECORE_X_EVENT_GENERIC = ecore_event_type_new();
 
+        ECORE_X_EVENT_PRESENT_CONFIGURE = ecore_event_type_new();
+        ECORE_X_EVENT_PRESENT_COMPLETE = ecore_event_type_new();
+        ECORE_X_EVENT_PRESENT_IDLE = ecore_event_type_new();
+
        ECORE_X_RAW_BUTTON_PRESS = ecore_event_type_new();
        ECORE_X_RAW_BUTTON_RELEASE = ecore_event_type_new();
        ECORE_X_RAW_MOTION = ecore_event_type_new();
@@ -2303,6 +2314,11 @@ 
_ecore_xcb_event_handle_generic_event(xcb_generic_event_t *event)
 // FIXME: should we generate generic events as WELL as input events?
 //        return;
      }
+   else if (ev->pad0 == _ecore_xcb_event_xpresent)
+     {
+        _ecore_xcb_event_handle_present_event((xcb_ge_event_t*)event);
+        return;
+     }
 
    if (!(e = calloc(1, sizeof(Ecore_X_Event_Generic))))
      return;
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_extensions.c 
b/src/lib/ecore_x/xcb/ecore_xcb_extensions.c
index 40c10ac..2e3577b 100644
--- a/src/lib/ecore_x/xcb/ecore_xcb_extensions.c
+++ b/src/lib/ecore_x/xcb/ecore_xcb_extensions.c
@@ -64,6 +64,8 @@ _ecore_xcb_extensions_init(void)
    _ecore_xcb_gesture_init();
 #endif
 
+   _ecore_xcb_present_init();
+
 /* #ifdef ECORE_XCB_DRI */
 /*    _ecore_xcb_dri_init(); */
 /* #endif */
@@ -135,6 +137,7 @@ _ecore_xcb_extensions_finalize(void)
    _ecore_xcb_gesture_finalize();
 #endif
 
+   _ecore_xcb_present_finalize();
 /* #ifdef ECORE_XCB_DRI */
 /*    _ecore_xcb_dri_finalize(); */
 /* #endif */
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_present.c 
b/src/lib/ecore_x/xcb/ecore_xcb_present.c
new file mode 100644
index 0000000..b5b426b
--- /dev/null
+++ b/src/lib/ecore_x/xcb/ecore_xcb_present.c
@@ -0,0 +1,194 @@
+#include "ecore_xcb_private.h"
+# ifdef ECORE_XCB_XPRESENT
+#  include <xcb/present.h>
+# endif
+
+/* local variables */
+static Eina_Bool _xpresent_avail = EINA_FALSE;
+
+/* external variables */
+int _ecore_xcb_event_xpresent = -1;
+
+void
+_ecore_xcb_xpresent_init(void)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_XPRESENT
+   xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_present_id);
+#endif
+}
+
+void
+_ecore_xcb_xpresent_finalize(void)
+{
+#ifdef ECORE_XCB_XPRESENT
+   const xcb_query_extension_reply_t *ext_reply;
+#endif
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ECORE_XCB_XPRESENT
+   ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_present_id);
+   if ((ext_reply) && (ext_reply->present))
+     {
+        xcb_present_query_version_cookie_t cookie;
+        xcb_present_query_version_reply_t *reply;
+
+        cookie =
+          xcb_present_query_version_unchecked(_ecore_xcb_conn,
+                                             XCB_PRESENT_MAJOR_VERSION,
+                                             XCB_PRESENT_MINOR_VERSION);
+        reply = xcb_present_query_version_reply(_ecore_xcb_conn, cookie, NULL);
+        if (reply)
+          {
+                _xpresent_avail = EINA_TRUE;
+                free(reply);
+          }
+
+        if (_xpresent_avail)
+          _ecore_xcb_event_xpresent = ext_reply->first_event;
+     }
+#endif
+}
+
+#ifdef ECORE_XCB_XPRESENT
+#define SET(X) e->X = ev->X
+
+static void
+_present_configure(xcb_present_configure_notify_event_t *ev)
+{
+   Ecore_X_Event_Present_Configure *e;
+
+   e = calloc(1, sizeof(Ecore_X_Event_Present_Configure));
+   if (!e) return;
+
+   e->win = ev->window;
+   SET(x), SET(y);
+   SET(width), SET(height);
+   SET(off_x), SET(off_y);
+   SET(pixmap_width), SET(pixmap_height);
+   SET(pixmap_flags);
+
+   ecore_event_add(ECORE_X_EVENT_PRESENT_CONFIGURE, e, NULL, NULL);
+}
+
+static void
+_present_complete(xcb_present_complete_notify_event_t *ev)
+{
+   unsigned int mode[] =
+   {
+    [XCB_PRESENT_COMPLETE_MODE_COPY] = ECORE_X_PRESENT_COMPLETE_MODE_COPY,
+    [XCB_PRESENT_COMPLETE_MODE_FLIP] = ECORE_X_PRESENT_COMPLETE_MODE_FLIP,
+    [XCB_PRESENT_COMPLETE_MODE_SKIP] = ECORE_X_PRESENT_COMPLETE_MODE_SKIP,
+   };
+   Ecore_X_Event_Present_Complete *e;
+
+   e = calloc(1, sizeof(Ecore_X_Event_Present_Complete));
+   if (!e) return;
+
+   e->win = ev->window;
+   SET(serial);
+   SET(ust), SET(msc);
+   e->kind = (ev->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC);
+   e->mode = mode[ev->mode];
+   ecore_event_add(ECORE_X_EVENT_PRESENT_COMPLETE, e, NULL, NULL);
+}
+
+static void
+_present_idle(xcb_present_idle_notify_event_t *ev)
+{
+   Ecore_X_Event_Present_Idle *e;
+
+   e = calloc(1, sizeof(Ecore_X_Event_Present_Idle));
+   if (!e) return;
+
+   e->win = ev->window;
+   SET(serial);
+   SET(pixmap);
+   SET(idle_fence);
+   ecore_event_add(ECORE_X_EVENT_PRESENT_IDLE, e, NULL, NULL);
+}
+#undef SET
+
+void
+_ecore_xcb_event_handle_present_event(xcb_ge_event_t *ev)
+{
+   switch (ev->event_type)
+     {
+      case XCB_PRESENT_EVENT_CONFIGURE_NOTIFY:
+        
_present_configure((xcb_present_configure_notify_event_t*)(long)ev->pad1);
+        break;
+      case XCB_PRESENT_EVENT_COMPLETE_NOTIFY:
+        
_present_complete((xcb_present_complete_notify_event_t*)(long)ev->pad1);
+        break;
+      case XCB_PRESENT_EVENT_IDLE_NOTIFY:
+        _present_idle((xcb_present_idle_notify_event_t*)(long)ev->pad1);
+        break;
+      default: break;
+     }
+}
+#endif
+
+
+EAPI void
+ecore_x_present_select_events(Ecore_X_Window win, unsigned int events)
+{
+#ifdef ECORE_XCB_XPRESENT
+   xcb_present_select_input(_ecore_xcb_conn, _ecore_xcb_event_xpresent, win, 
events);
+#else
+   (void)win;
+   (void)events;
+#endif
+}
+
+EAPI void
+ecore_x_present_notify_msc(Ecore_X_Window win, unsigned int serial, unsigned 
long long target_msc, unsigned long long divisor, unsigned long long remainder)
+{
+#ifdef ECORE_XCB_XPRESENT
+   xcb_present_notify_msc(_ecore_xcb_conn, win, serial, target_msc, divisor, 
remainder);
+#else
+   (void)win;
+   (void)serial;
+   (void)target_msc;
+   (void)divisor;
+   (void)remainder;
+#endif
+}
+
+EAPI void
+ecore_x_present_pixmap(Ecore_X_Window win, Ecore_X_Pixmap pixmap, unsigned int 
serial, Ecore_X_Region valid,
+                       Ecore_X_Region update, int x_off, int y_off, 
Ecore_X_Randr_Crtc target_crtc,
+                       Ecore_X_Sync_Fence wait_fence, Ecore_X_Sync_Fence 
idle_fence, unsigned int options,
+                       unsigned long long target_msc, unsigned long long 
divisor, unsigned long long remainder,
+                       Ecore_X_Present *notifies, int num_notifies)
+{
+#ifdef ECORE_XCB_XPRESENT
+   xcb_present_pixmap(_ecore_xcb_conn, win, pixmap, serial, valid, update,
+                  x_off, y_off, target_crtc, wait_fence, idle_fence, options, 
target_msc,
+                  divisor, remainder, num_notifies, 
(xcb_present_notify_t*)notifies);
+#else
+   (void)win;
+   (void)pixmap;
+   (void)serial;
+   (void)valid;
+   (void)update;
+   (void)x_off;
+   (void)y_off;
+   (void)target_crtc;
+   (void)wait_fence;
+   (void)idle_fence;
+   (void)options;
+   (void)target_msc;
+   (void)divisor;
+   (void)remainder;
+   (void)notifies;
+   (void)num_notifies;
+#endif
+}
+
+EAPI Eina_Bool
+ecore_x_present_exists(void)
+{
+   return _xpresent_avail;
+}
diff --git a/src/lib/ecore_x/xcb/ecore_xcb_private.h 
b/src/lib/ecore_x/xcb/ecore_xcb_private.h
index d578a97..61452f2 100644
--- a/src/lib/ecore_x/xcb/ecore_xcb_private.h
+++ b/src/lib/ecore_x/xcb/ecore_xcb_private.h
@@ -278,6 +278,11 @@ void                _ecore_xcb_damage_finalize(void);
 void                _ecore_xcb_composite_init(void);
 void                _ecore_xcb_composite_finalize(void);
 
+void                _ecore_xcb_present_init(void);
+void                _ecore_xcb_present_finalize(void);
+void                _ecore_xcb_event_handle_present_event(xcb_ge_event_t *ev);
+extern int _ecore_xcb_event_xpresent;
+
 void                _ecore_xcb_dpms_init(void);
 void                _ecore_xcb_dpms_finalize(void);
 
diff --git a/src/lib/ecore_x/xlib/ecore_x.c b/src/lib/ecore_x/xlib/ecore_x.c
index 501bc7a..a9be6b6 100644
--- a/src/lib/ecore_x/xlib/ecore_x.c
+++ b/src/lib/ecore_x/xlib/ecore_x.c
@@ -148,6 +148,10 @@ EAPI int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = 0;
 
 EAPI int ECORE_X_EVENT_GENERIC = 0;
 
+EAPI int ECORE_X_EVENT_PRESENT_CONFIGURE = 0;
+EAPI int ECORE_X_EVENT_PRESENT_COMPLETE = 0;
+EAPI int ECORE_X_EVENT_PRESENT_IDLE = 0;
+
 EAPI int ECORE_X_MODIFIER_SHIFT = 0;
 EAPI int ECORE_X_MODIFIER_CTRL = 0;
 EAPI int ECORE_X_MODIFIER_ALT = 0;
@@ -665,6 +669,7 @@ ecore_x_init(const char *name)
    _ecore_x_fixes_init();
    _ecore_x_damage_init();
    _ecore_x_composite_init();
+   _ecore_x_present_init();
    _ecore_x_dpms_init();
    _ecore_x_randr_init();
    _ecore_x_gesture_init();
diff --git a/src/lib/ecore_x/xlib/ecore_x_events.c 
b/src/lib/ecore_x/xlib/ecore_x_events.c
index ac1e475..467cbcd 100644
--- a/src/lib/ecore_x/xlib/ecore_x_events.c
+++ b/src/lib/ecore_x/xlib/ecore_x_events.c
@@ -2270,7 +2270,6 @@ static void
 _ecore_x_event_free_generic_event(void *data,
                                   void *ev)
 {
-#ifdef ECORE_XI2
    Ecore_X_Event_Generic *e = (Ecore_X_Event_Generic *)ev;
 
    if (data)
@@ -2280,16 +2279,11 @@ _ecore_x_event_free_generic_event(void *data,
         free(data);
      }
    free(e);
-#else
-   return;
-   data = NULL; ev = NULL;
-#endif /* ifdef ECORE_XI2 */
 }
 
 void
 _ecore_x_event_handle_generic_event(XEvent *event)
 {
-#ifdef ECORE_XI2
    XGenericEvent *generic_event;
    Ecore_X_Event_Generic *e;
    XGenericEventCookie *data;
@@ -2297,6 +2291,14 @@ _ecore_x_event_handle_generic_event(XEvent *event)
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
    generic_event = (XGenericEvent *)event;
 
+#ifdef ECORE_XPRESENT
+   if (generic_event->extension == _ecore_x_present_major)
+     {
+        _ecore_x_present_handler(generic_event);
+        return;
+     }
+#endif
+
    e = calloc(1, sizeof(Ecore_X_Event_Generic));
    if (!e)
      return;
@@ -2314,20 +2316,16 @@ _ecore_x_event_handle_generic_event(XEvent *event)
 
    e->extension = generic_event->extension;
    e->evtype = generic_event->evtype;
-
+#ifdef ECORE_XI2
    if (e->extension == _ecore_x_xi2_opcode)
      _ecore_x_input_handler(event);
-
+#endif /* ifdef ECORE_XI2 */
    data = malloc(sizeof(XGenericEventCookie));
    if (data) memcpy(data, &(event->xcookie), sizeof(XGenericEventCookie));
    ecore_event_add(ECORE_X_EVENT_GENERIC,
                    e,
                    _ecore_x_event_free_generic_event,
                    data);
-#else
-   return;
-   event = NULL;
-#endif /* ifdef ECORE_XI2 */
 }
 
 #ifdef ECORE_XGESTURE
diff --git a/src/lib/ecore_x/xlib/ecore_x_present.c 
b/src/lib/ecore_x/xlib/ecore_x_present.c
new file mode 100644
index 0000000..9e6a398
--- /dev/null
+++ b/src/lib/ecore_x/xlib/ecore_x_present.c
@@ -0,0 +1,169 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+int _ecore_x_present_major = 0;
+static Eina_Bool _ecore_x_present_exists = EINA_FALSE;
+
+void
+_ecore_x_present_init(void)
+{
+   ECORE_X_EVENT_PRESENT_CONFIGURE = ecore_event_type_new();
+   ECORE_X_EVENT_PRESENT_COMPLETE = ecore_event_type_new();
+   ECORE_X_EVENT_PRESENT_IDLE = ecore_event_type_new();
+#ifdef ECORE_XPRESENT
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+   _ecore_x_present_exists = XPresentQueryExtension(_ecore_x_disp, 
&_ecore_x_present_major, NULL, NULL);
+#endif
+}
+
+#ifdef ECORE_XPRESENT
+#define SET(X) e->X = ev->X
+
+static void
+_present_configure(XPresentConfigureNotifyEvent *ev)
+{
+   Ecore_X_Event_Present_Configure *e;
+
+   e = calloc(1, sizeof(Ecore_X_Event_Present_Configure));
+   if (!e) return;
+
+   e->win = ev->window;
+   SET(x), SET(y);
+   SET(width), SET(height);
+   SET(off_x), SET(off_y);
+   SET(pixmap_width), SET(pixmap_height);
+   SET(pixmap_flags);
+
+   ecore_event_add(ECORE_X_EVENT_PRESENT_CONFIGURE, e, NULL, NULL);
+}
+
+static void
+_present_complete(XPresentCompleteNotifyEvent *ev)
+{
+   unsigned int mode[] =
+   {
+    [PresentCompleteModeCopy] = ECORE_X_PRESENT_COMPLETE_MODE_COPY,
+    [PresentCompleteModeFlip] = ECORE_X_PRESENT_COMPLETE_MODE_FLIP,
+    [PresentCompleteModeSkip] = ECORE_X_PRESENT_COMPLETE_MODE_SKIP,
+   };
+   Ecore_X_Event_Present_Complete *e;
+
+   e = calloc(1, sizeof(Ecore_X_Event_Present_Complete));
+   if (!e) return;
+
+   e->win = ev->window;
+   e->serial = ev->serial_number;
+   SET(ust), SET(msc);
+   e->kind = (ev->kind == 1); //libXpresent doesn't expose this...
+   e->mode = mode[ev->mode];
+   ecore_event_add(ECORE_X_EVENT_PRESENT_COMPLETE, e, NULL, NULL);
+}
+
+static void
+_present_idle(XPresentIdleNotifyEvent *ev)
+{
+   Ecore_X_Event_Present_Idle *e;
+
+   e = calloc(1, sizeof(Ecore_X_Event_Present_Idle));
+   if (!e) return;
+
+   e->win = ev->window;
+   e->serial = ev->serial_number;
+   SET(pixmap);
+   SET(idle_fence);
+   ecore_event_add(ECORE_X_EVENT_PRESENT_IDLE, e, NULL, NULL);
+}
+#undef SET
+
+void
+_ecore_x_present_handler(XGenericEvent *ge)
+{
+   XGenericEventCookie *gec = (XGenericEventCookie*)ge;
+
+   if (XGetEventData(_ecore_x_disp, gec))
+     {
+        switch (gec->evtype)
+          {
+           case PresentConfigureNotify:
+             _present_configure(gec->data);
+             break;
+           case PresentCompleteNotify:
+             _present_complete(gec->data);
+             break;
+           case PresentIdleNotify:
+             _present_idle(gec->data);
+             break;
+           default: break;
+          }
+     }
+   XFreeEventData(_ecore_x_disp, gec);
+}
+#endif
+
+EAPI void
+ecore_x_present_select_events(Ecore_X_Window win, unsigned int events)
+{
+#ifdef ECORE_XPRESENT
+   XPresentSelectInput(_ecore_x_disp, win, events);
+#else
+   (void)win;
+   (void)events;
+#endif
+}
+
+EAPI void
+ecore_x_present_notify_msc(Ecore_X_Window win, unsigned int serial, unsigned 
long long target_msc, unsigned long long divisor, unsigned long long remainder)
+{
+#ifdef ECORE_XPRESENT
+   XPresentNotifyMSC(_ecore_x_disp, win, serial, target_msc, divisor, 
remainder);
+#else
+   (void)win;
+   (void)serial;
+   (void)target_msc;
+   (void)divisor;
+   (void)remainder;
+#endif
+}
+
+EAPI void
+ecore_x_present_pixmap(Ecore_X_Window win, Ecore_X_Pixmap pixmap, unsigned int 
serial, Ecore_X_Region valid,
+                       Ecore_X_Region update, int x_off, int y_off, 
Ecore_X_Randr_Crtc target_crtc,
+                       Ecore_X_Sync_Fence wait_fence, Ecore_X_Sync_Fence 
idle_fence, unsigned int options,
+                       unsigned long long target_msc, unsigned long long 
divisor, unsigned long long remainder,
+                       Ecore_X_Present *notifies, int num_notifies)
+{
+#ifdef ECORE_XPRESENT
+   XPresentPixmap(_ecore_x_disp, win, pixmap, serial, valid, update,
+                  x_off, y_off, target_crtc, wait_fence, idle_fence, options, 
target_msc,
+                  divisor, remainder, (XPresentNotify*)notifies, num_notifies);
+#else
+   (void)win;
+   (void)pixmap;
+   (void)serial;
+   (void)valid;
+   (void)update,
+   (void)x_off;
+   (void)y_off;
+   (void)target_crtc;
+   (void)wait_fence;
+   (void)idle_fence;
+   (void)options;
+   (void)target_msc,
+   (void)divisor;
+   (void)remainder;
+   (void)notifies;
+   (void)num_notifies;
+#endif
+}
+
+EAPI Eina_Bool
+ecore_x_present_exists(void)
+{
+   return _ecore_x_present_exists;
+}
diff --git a/src/lib/ecore_x/xlib/ecore_x_private.h 
b/src/lib/ecore_x/xlib/ecore_x_private.h
index 815e081..94a3db8 100644
--- a/src/lib/ecore_x/xlib/ecore_x_private.h
+++ b/src/lib/ecore_x/xlib/ecore_x_private.h
@@ -40,6 +40,9 @@
 #ifdef ECORE_XCOMPOSITE
 #include <X11/extensions/Xcomposite.h>
 #endif /* ifdef ECORE_XCOMPOSITE */
+#ifdef ECORE_XPRESENT
+#include <X11/extensions/Xpresent.h>
+#endif /* ifdef ECORE_XPRESENT */
 #ifdef ECORE_XDAMAGE
 #include <X11/extensions/Xdamage.h>
 #endif /* ifdef ECORE_XDAMAGE */
@@ -264,6 +267,10 @@ void   _ecore_x_event_handle_xkb(XEvent *xevent);
 #endif  /* ifdef ECORE_XKB */
 void      _ecore_x_event_handle_generic_event(XEvent *xevent);
 
+#ifdef ECORE_XPRESENT
+void      _ecore_x_present_handler(XGenericEvent *ge);
+#endif
+
 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);
@@ -308,12 +315,14 @@ int                  
_ecore_x_netwm_startup_info(Ecore_X_Window win,
 void _ecore_x_fixes_init(void);
 void _ecore_x_damage_init(void);
 void _ecore_x_composite_init(void);
+void _ecore_x_present_init(void);
 void _ecore_x_dpms_init(void);
 void _ecore_x_randr_init(void);
 void _ecore_x_gesture_init(void);
 
 void _ecore_x_atoms_init(void);
 
+extern int _ecore_x_present_major;
 extern int _ecore_x_xi2_opcode;
 
 void _ecore_x_events_init(void);

-- 


Reply via email to