typedef XID GLXPbuffer;
+/*
+** Events.
+** __GLX_NUMBER_EVENTS is set to 17 to account for the BufferClobberSGIX
+** event - this helps initialization if the server supports the pbuffer
+** extension and the client doesn't.
+*/
+#define GLX_PbufferClobber 0
+#define GLX_BufferSwapComplete 1
+
+#define __GLX_NUMBER_EVENTS 17
extern XVisualInfo* glXChooseVisual( Display *dpy, int screen,
int *attribList );
int count; /* if nonzero, at least this many more */
} GLXPbufferClobberEvent;
+typedef struct {
+ int event_type;
+ GLXDrawable drawable;
+ int64_t ust;
+ int64_t msc;
+ int64_t sbc;
+} GLXBufferSwapComplete;
+
typedef union __GLXEvent {
GLXPbufferClobberEvent glxpbufferclobber;
+ GLXBufferSwapComplete glxbufferswapcomplete;
long pad[24];
} GLXEvent;
typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member);
#endif
+#ifndef GLX_INTEL_swap_event
+#define GLX_INTEL_swap_event
+#define GLX_BUFFER_SWAP_COMPLETE_MASK 0x10000000
+#define GLX_EXCHANGE_COMPLETE 0x8024
+#define GLX_BLIT_COMPLETE 0x8025
+#define GLX_FLIP_COMPLETE 0x8026
+#endif
+
#ifndef GLX_SGIX_swap_barrier
#define GLX_SGIX_swap_barrier 1
#ifdef GLX_GLXEXT_PROTOTYPES
#include <X11/extensions/dri2proto.h>
#include "xf86drm.h"
#include "dri2.h"
+#include "glxclient.h"
+#include "GL/glxext.h"
/* Allow the build to work with an older versions of dri2proto.h and
* dri2tokens.h.
static XExtensionInfo *dri2Info;
static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
+static Bool
+DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire);
+static Status
+DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire);
+
static /* const */ XExtensionHooks dri2ExtensionHooks = {
NULL, /* create_gc */
NULL, /* copy_gc */
NULL, /* create_font */
NULL, /* free_font */
DRI2CloseDisplay, /* close_display */
- NULL, /* wire_to_event */
- NULL, /* event_to_wire */
+ DRI2WireToEvent, /* wire_to_event */
+ DRI2EventToWire, /* event_to_wire */
NULL, /* error */
NULL, /* error_string */
};
&dri2ExtensionHooks,
0, NULL)
+static Bool
+DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+
+ XextCheckExtension(dpy, info, dri2ExtensionName, False);
+
+ switch ((wire->u.u.type & 0x7f) - info->codes->first_event) {
+ case DRI2_BufferSwapComplete:
+ {
+ GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
+ xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire;
+ switch (awire->type) {
+ case DRI2_EXCHANGE_COMPLETE:
+ aevent->event_type = GLX_EXCHANGE_COMPLETE;
+ break;
+ case DRI2_BLIT_COMPLETE:
+ aevent->event_type = GLX_BLIT_COMPLETE;
+ break;
+ case DRI2_FLIP_COMPLETE:
+ aevent->event_type = GLX_FLIP_COMPLETE;
+ break;
+ default:
+ /* unknown swap completion type */
+ return False;
+ }
+ aevent->drawable = awire->drawable;
+ aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
+ aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
+ aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo;
+ return True;
+ }
+ default:
+ /* client doesn't support server event */
+ break;
+ }
+
+ return False;
+}
+
+/* We don't actually support this. It doesn't make sense for clients to
+ * send each other DRI2 events.
+ */
+static Status
+DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+
+ XextCheckExtension(dpy, info, dri2ExtensionName, False);
+
+ switch (event->type) {
+ default:
+ /* client doesn't support server event */
+ break;
+ }
+
+ return Success;
+}
+
Bool
DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase)
{
__glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
__glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
+ /* FIXME: if DRI2 version supports it... */
+ __glXEnableDirectExtension(psc, "INTEL_swap_event");
+
#ifdef __DRI2_FLUSH
if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) {
psc->f = (__DRI2flushExtension *) extensions[i];
static
XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName,
__GLX_NUMBER_ERRORS, error_list)
+static Bool
+__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire);
+static Status
+__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire);
static /* const */ XExtensionHooks __glXExtensionHooks = {
NULL, /* create_gc */
NULL, /* create_font */
NULL, /* free_font */
__glXCloseDisplay, /* close_display */
- NULL, /* wire_to_event */
- NULL, /* event_to_wire */
+ __glXWireToEvent, /* wire_to_event */
+ __glXEventToWire, /* event_to_wire */
NULL, /* error */
__glXErrorString, /* error_string */
};
__glXExtensionName, &__glXExtensionHooks,
__GLX_NUMBER_EVENTS, NULL)
+/*
+ * GLX events are a bit funky. We don't stuff the X event code into
+ * our user exposed (via XNextEvent) structure. Instead we use the GLX
+ * private event code namespace (and hope it doesn't conflict). Clients
+ * have to know that bit 15 in the event type field means they're getting
+ * a GLX event, and then handle the various sub-event types there, rather
+ * than simply checking the event code and handling it directly.
+ */
+
+static Bool
+__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
+{
+ XExtDisplayInfo *info = __glXFindDisplay(dpy);
+
+ XextCheckExtension(dpy, info, __glXExtensionName, False);
+
+ switch ((wire->u.u.type & 0x7f) - info->codes->first_event) {
+ case GLX_PbufferClobber:
+ {
+ GLXPbufferClobberEvent *aevent = (GLXPbufferClobberEvent *)event;
+ xGLXPbufferClobberEvent *awire = (xGLXPbufferClobberEvent *)wire;
+ aevent->event_type = awire->type;
+ aevent->serial = awire->sequenceNumber;
+ aevent->event_type = awire->event_type;
+ aevent->draw_type = awire->draw_type;
+ aevent->drawable = awire->drawable;
+ aevent->buffer_mask = awire->buffer_mask;
+ aevent->aux_buffer = awire->aux_buffer;
+ aevent->x = awire->x;
+ aevent->y = awire->y;
+ aevent->width = awire->width;
+ aevent->height = awire->height;
+ aevent->count = awire->count;
+ return True;
+ }
+ case GLX_BufferSwapComplete:
+ {
+ GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
+ xGLXBufferSwapComplete *awire = (xGLXBufferSwapComplete *)wire;
+ aevent->event_type = awire->event_type;
+ aevent->drawable = awire->drawable;
+ aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
+ aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
+ aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo;
+ return True;
+ }
+ default:
+ /* client doesn't support server event */
+ break;
+ }
+
+ return False;
+}
+
+/* We don't actually support this. It doesn't make sense for clients to
+ * send each other GLX events.
+ */
+static Status
+__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire)
+{
+ XExtDisplayInfo *info = __glXFindDisplay(dpy);
+
+ XextCheckExtension(dpy, info, __glXExtensionName, False);
+
+ switch (event->type) {
+ case GLX_DAMAGED:
+ break;
+ case GLX_SAVED:
+ break;
+ case GLX_EXCHANGE_COMPLETE:
+ break;
+ case GLX_BLIT_COMPLETE:
+ break;
+ case GLX_FLIP_COMPLETE:
+ break;
+ default:
+ /* client doesn't support server event */
+ break;
+ }
+
+ return Success;
+}
+
/************************************************************************/
/*
** Free the per screen configs data as well as the array of
{ GLX(SGIX_swap_group), VER(0,0), N, N, N, N },
{ GLX(SGIX_visual_select_group), VER(0,0), Y, Y, N, N },
{ GLX(EXT_texture_from_pixmap), VER(0,0), Y, N, N, N },
+ { GLX(INTEL_swap_event), VER(1,4), Y, Y, N, N },
{ NULL }
};
SGIX_swap_barrier_bit,
SGIX_swap_group_bit,
SGIX_visual_select_group_bit,
- EXT_texture_from_pixmap_bit
+ EXT_texture_from_pixmap_bit,
+ INTEL_swap_event_bit,
};
enum
#endif
#ifdef GLX_EXT_texture_from_pixmap
"GLX_EXT_texture_from_pixmap",
+#endif
+#ifdef GLX_INTEL_swap_event
+ "GLX_INTEL_swap_event",
#endif
NULL
};