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
|
||||
context->winsys.event_filters = NULL;
|
||||
|
||||
context->winsys.trap_state = NULL;
|
||||
#endif
|
||||
|
||||
_cogl_winsys_features_init (context);
|
||||
|
@ -24,11 +24,31 @@
|
||||
#ifndef __COGL_CONTEXT_WINSYS_H
|
||||
#define __COGL_CONTEXT_WINSYS_H
|
||||
|
||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COGL_WINSYS_FEATURE_STUB /* no features are defined yet */
|
||||
} 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
|
||||
{
|
||||
/* 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 */
|
||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||
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
|
||||
|
||||
/* 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
|
||||
|
||||
#include "cogl.h"
|
||||
#include "cogl-context-winsys.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
typedef struct _CoglXlibFilterClosure CoglXlibFilterClosure;
|
||||
|
||||
@ -34,4 +37,30 @@ struct _CoglXlibFilterClosure
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user