diff options
Diffstat (limited to 'libdrm')
| -rw-r--r-- | libdrm/xf86drm.h | 19 | ||||
| -rw-r--r-- | libdrm/xf86drmMode.c | 43 | 
2 files changed, 62 insertions, 0 deletions
| diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index c1d173c4..2cb9c9e9 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -271,6 +271,7 @@ typedef struct _drmTextureRegion {  typedef enum {      DRM_VBLANK_ABSOLUTE = 0x0,	/**< Wait for specific vblank sequence number */      DRM_VBLANK_RELATIVE = 0x1,	/**< Wait for given number of vblanks */ +    DRM_VBLANK_EVENT = 0x4000000,	/**< Send event instead of blocking */      DRM_VBLANK_FLIP = 0x8000000,	/**< Scheduled buffer swap should flip */      DRM_VBLANK_NEXTONMISS = 0x10000000,	/**< If missed, wait for next vblank */      DRM_VBLANK_SECONDARY = 0x20000000,	/**< Secondary display controller */ @@ -667,4 +668,22 @@ extern void drmMsg(const char *format, ...);  extern int drmSetMaster(int fd);  extern int drmDropMaster(int fd); +#define DRM_EVENT_CONTEXT_VERSION 1 + +typedef struct _drmEventContext { + +	/* This struct is versioned so we can add more pointers if we +	 * add more events. */ +	int version; + +	void (*vblank_handler)(int fd, +			       unsigned int sequence,  +			       unsigned int tv_sec, +			       unsigned int tv_usec, +			       void *user_data); + +} drmEventContext, *drmEventContextPtr; + +extern int drmHandleEvent(int fd, drmEventContextPtr evctx); +  #endif diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index 88b4fe3a..6d85113a 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -46,6 +46,7 @@  #include <drm.h>  #include <string.h>  #include <dirent.h> +#include <unistd.h>  #include <errno.h>  #define U642VOID(x) ((void *)(unsigned long)(x)) @@ -667,3 +668,45 @@ int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,  	return 0;  } + +int drmHandleEvent(int fd, drmEventContextPtr evctx) +{ +	char buffer[1024]; +	int len, i; +	struct drm_event *e; +	struct drm_event_vblank *vblank; +	 +	/* The DRM read semantics guarantees that we always get only +	 * complete events. */ + +	len = read(fd, buffer, sizeof buffer); +	if (len == 0) +		return 0; +	if (len < sizeof *e) +		return -1; + +	i = 0; +	while (i < len) { +		e = (struct drm_event *) &buffer[i]; +		switch (e->type) { +		case DRM_EVENT_VBLANK: +			if (evctx->version < 1 || +			    evctx->vblank_handler == NULL) +				break; +			vblank = (struct drm_event_vblank *) e; +			evctx->vblank_handler(fd, +					      vblank->sequence,  +					      vblank->tv_sec, +					      vblank->tv_usec, +					      U642VOID (vblank->user_data)); +			break; +			 +		default: +			break; +		} +		i += e->length; +	} + +	return 0; +} + | 
