mirror of
https://github.com/mirror/libX11.git
synced 2026-05-28 01:44:57 +08:00
Fix 797755 Allow X*IfEvent() to reenter libX11
- the activation logic is reversed - there is also _XInternalLockDisplay() that needs protection - I've found cases (in fvwm2) where the callback calls XCheckIfEvent() recursively. So the flag needs to be a counter. Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
committed by
Alan Coopersmith
parent
bccd787a56
commit
a9e845809b
@@ -207,7 +207,7 @@ struct _XDisplay
|
||||
|
||||
XIOErrorExitHandler exit_handler;
|
||||
void *exit_handler_data;
|
||||
Bool in_ifevent;
|
||||
CARD32 in_ifevent;
|
||||
};
|
||||
|
||||
#define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n)
|
||||
|
||||
@@ -49,8 +49,8 @@ Bool XCheckIfEvent (
|
||||
unsigned long qe_serial = 0;
|
||||
int n; /* time through count */
|
||||
|
||||
dpy->in_ifevent++;
|
||||
LockDisplay(dpy);
|
||||
dpy->in_ifevent = True;
|
||||
prev = NULL;
|
||||
for (n = 3; --n >= 0;) {
|
||||
for (qelt = prev ? prev->next : dpy->head;
|
||||
@@ -80,7 +80,7 @@ Bool XCheckIfEvent (
|
||||
/* another thread has snatched this event */
|
||||
prev = NULL;
|
||||
}
|
||||
dpy->in_ifevent = False;
|
||||
dpy->in_ifevent--;
|
||||
UnlockDisplay(dpy);
|
||||
return False;
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ XIfEvent (
|
||||
register _XQEvent *qelt, *prev;
|
||||
unsigned long qe_serial = 0;
|
||||
|
||||
dpy->in_ifevent++;
|
||||
LockDisplay(dpy);
|
||||
dpy->in_ifevent = True;
|
||||
prev = NULL;
|
||||
while (1) {
|
||||
for (qelt = prev ? prev->next : dpy->head;
|
||||
@@ -60,7 +60,7 @@ XIfEvent (
|
||||
*event = qelt->event;
|
||||
_XDeq(dpy, prev, qelt);
|
||||
_XStoreEventCookie(dpy, event);
|
||||
dpy->in_ifevent = False;
|
||||
dpy->in_ifevent--;
|
||||
UnlockDisplay(dpy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ XOpenDisplay (
|
||||
dpy->xcmisc_opcode = 0;
|
||||
dpy->xkb_info = NULL;
|
||||
dpy->exit_handler_data = NULL;
|
||||
dpy->in_ifevent = False;
|
||||
dpy->in_ifevent = 0;
|
||||
|
||||
/*
|
||||
* Setup other information in this display structure.
|
||||
|
||||
@@ -49,8 +49,8 @@ XPeekIfEvent (
|
||||
register _XQEvent *prev, *qelt;
|
||||
unsigned long qe_serial = 0;
|
||||
|
||||
dpy->in_ifevent++;
|
||||
LockDisplay(dpy);
|
||||
dpy->in_ifevent = True;
|
||||
prev = NULL;
|
||||
while (1) {
|
||||
for (qelt = prev ? prev->next : dpy->head;
|
||||
@@ -64,7 +64,7 @@ XPeekIfEvent (
|
||||
_XStoreEventCookie(dpy, ©);
|
||||
*event = copy;
|
||||
}
|
||||
dpy->in_ifevent = False;
|
||||
dpy->in_ifevent--;
|
||||
UnlockDisplay(dpy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -465,17 +465,33 @@ static void _XIfEventLockDisplay(
|
||||
/* assert(dpy->in_ifevent); */
|
||||
}
|
||||
|
||||
static void _XInternalLockDisplay(
|
||||
Display *dpy,
|
||||
Bool wskip
|
||||
XTHREADS_FILE_LINE_ARGS
|
||||
);
|
||||
|
||||
static void _XIfEventInternalLockDisplay(
|
||||
Display *dpy,
|
||||
Bool wskip
|
||||
XTHREADS_FILE_LINE_ARGS
|
||||
)
|
||||
{
|
||||
/* assert(dpy->in_ifevent); */
|
||||
}
|
||||
|
||||
static void _XIfEventUnlockDisplay(
|
||||
Display *dpy
|
||||
XTHREADS_FILE_LINE_ARGS
|
||||
)
|
||||
{
|
||||
if (dpy->in_ifevent)
|
||||
if (dpy->in_ifevent == 0) {
|
||||
dpy->lock_fns->lock_display = _XLockDisplay;
|
||||
dpy->lock_fns->unlock_display = _XUnlockDisplay;
|
||||
dpy->lock->internal_lock_display = _XInternalLockDisplay;
|
||||
UnlockDisplay(dpy);
|
||||
} else
|
||||
return;
|
||||
|
||||
dpy->lock_fns->lock_display = _XLockDisplay;
|
||||
dpy->lock_fns->unlock_display = _XUnlockDisplay;
|
||||
UnlockDisplay(dpy);
|
||||
}
|
||||
|
||||
static void _XLockDisplay(
|
||||
@@ -507,6 +523,7 @@ static void _XLockDisplay(
|
||||
if (dpy->in_ifevent) {
|
||||
dpy->lock_fns->lock_display = _XIfEventLockDisplay;
|
||||
dpy->lock_fns->unlock_display = _XIfEventUnlockDisplay;
|
||||
dpy->lock->internal_lock_display = _XIfEventInternalLockDisplay;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user