ecore-x now supports XPRESENT

see http://cgit.freedesktop.org/xorg/proto/presentproto/plain/presentproto.txt
This commit is contained in:
Mike Blumenkrantz 2014-01-10 02:26:06 -05:00
parent 384783a896
commit 131e0e1983
11 changed files with 514 additions and 13 deletions

View File

@ -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"],

View File

@ -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 \

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -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;
}

View File

@ -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);