cogl: Add _cogl_xlib_{,un}trap_errors
This is similar to clutter_x11_{,un}trap_errors except that it stores the previous trap state in a caller-allocated struct so that it can be re-entrant. Make _cogl_xlib_trap_errors re-entrant (this will be squashed into an earlier commit)
This commit is contained in:
parent
6ad668c76b
commit
16c7d12e6c
@ -94,6 +94,8 @@ _cogl_create_context_winsys (CoglContext *context)
|
|||||||
{
|
{
|
||||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||||
context->winsys.event_filters = NULL;
|
context->winsys.event_filters = NULL;
|
||||||
|
|
||||||
|
context->winsys.trap_state = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_cogl_winsys_features_init (context);
|
_cogl_winsys_features_init (context);
|
||||||
|
@ -24,11 +24,31 @@
|
|||||||
#ifndef __COGL_CONTEXT_WINSYS_H
|
#ifndef __COGL_CONTEXT_WINSYS_H
|
||||||
#define __COGL_CONTEXT_WINSYS_H
|
#define __COGL_CONTEXT_WINSYS_H
|
||||||
|
|
||||||
|
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
COGL_WINSYS_FEATURE_STUB /* no features are defined yet */
|
COGL_WINSYS_FEATURE_STUB /* no features are defined yet */
|
||||||
} CoglWinsysFeatureFlags;
|
} CoglWinsysFeatureFlags;
|
||||||
|
|
||||||
|
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||||
|
|
||||||
|
typedef struct _CoglXlibTrapState CoglXlibTrapState;
|
||||||
|
|
||||||
|
struct _CoglXlibTrapState
|
||||||
|
{
|
||||||
|
/* These values are intended to be internal to
|
||||||
|
_cogl_xlib_{un,}trap_errors but they need to be in the header so
|
||||||
|
that the struct can be allocated on the stack */
|
||||||
|
int (* old_error_handler) (Display *, XErrorEvent *);
|
||||||
|
int trapped_error_code;
|
||||||
|
CoglXlibTrapState *old_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/* These are specific to winsys backends supporting Xlib. This
|
/* These are specific to winsys backends supporting Xlib. This
|
||||||
@ -36,6 +56,9 @@ typedef struct
|
|||||||
to Xlib when Cogl gains a more complete winsys abstraction */
|
to Xlib when Cogl gains a more complete winsys abstraction */
|
||||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||||
GSList *event_filters;
|
GSList *event_filters;
|
||||||
|
/* Current top of the XError trap state stack. The actual memory for
|
||||||
|
these is expected to be allocated on the stack by the caller */
|
||||||
|
CoglXlibTrapState *trap_state;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Function pointers for winsys specific extensions */
|
/* Function pointers for winsys specific extensions */
|
||||||
|
@ -129,3 +129,42 @@ _cogl_xlib_remove_filter (CoglXlibFilterFunc func,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
error_handler (Display *xdpy,
|
||||||
|
XErrorEvent *error)
|
||||||
|
{
|
||||||
|
_COGL_GET_CONTEXT (ctxt, 0);
|
||||||
|
|
||||||
|
g_assert (ctxt->winsys.trap_state);
|
||||||
|
|
||||||
|
ctxt->winsys.trap_state->trapped_error_code = error->error_code;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_xlib_trap_errors (CoglXlibTrapState *state)
|
||||||
|
{
|
||||||
|
_COGL_GET_CONTEXT (ctxt, NO_RETVAL);
|
||||||
|
|
||||||
|
state->trapped_error_code = 0;
|
||||||
|
state->old_error_handler = XSetErrorHandler (error_handler);
|
||||||
|
|
||||||
|
state->old_state = ctxt->winsys.trap_state;
|
||||||
|
ctxt->winsys.trap_state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_cogl_xlib_untrap_errors (CoglXlibTrapState *state)
|
||||||
|
{
|
||||||
|
_COGL_GET_CONTEXT (ctxt, 0);
|
||||||
|
|
||||||
|
g_assert (state == ctxt->winsys.trap_state);
|
||||||
|
|
||||||
|
XSetErrorHandler (state->old_error_handler);
|
||||||
|
|
||||||
|
ctxt->winsys.trap_state = state->old_state;
|
||||||
|
|
||||||
|
return state->trapped_error_code;
|
||||||
|
}
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
#define __COGL_XLIB_H
|
#define __COGL_XLIB_H
|
||||||
|
|
||||||
#include "cogl.h"
|
#include "cogl.h"
|
||||||
|
#include "cogl-context-winsys.h"
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
typedef struct _CoglXlibFilterClosure CoglXlibFilterClosure;
|
typedef struct _CoglXlibFilterClosure CoglXlibFilterClosure;
|
||||||
|
|
||||||
@ -34,4 +37,30 @@ struct _CoglXlibFilterClosure
|
|||||||
gpointer data;
|
gpointer data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _cogl_xlib_trap_errors:
|
||||||
|
* @state: A temporary place to store data for the trap.
|
||||||
|
*
|
||||||
|
* Traps every X error until _cogl_xlib_untrap_errors() called. You
|
||||||
|
* should allocate an uninitialised CoglXlibTrapState struct on the
|
||||||
|
* stack to pass to this function. The same pointer should later be
|
||||||
|
* passed to _cogl_xlib_untrap_errors(). Calls to
|
||||||
|
* _cogl_xlib_trap_errors() can be nested as long as
|
||||||
|
* _cogl_xlib_untrap_errors() is called with the corresponding state
|
||||||
|
* pointers in reverse order.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_cogl_xlib_trap_errors (CoglXlibTrapState *state);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _cogl_xlib_untrap_errors:
|
||||||
|
* @state: The state that was passed to _cogl_xlib_trap_errors().
|
||||||
|
*
|
||||||
|
* Removes the X error trap and returns the current status.
|
||||||
|
*
|
||||||
|
* Return value: the trapped error code, or 0 for success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
_cogl_xlib_untrap_errors (CoglXlibTrapState *state);
|
||||||
|
|
||||||
#endif /* __COGL_XLIB_H */
|
#endif /* __COGL_XLIB_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user