From 95a1ce8798fc77cd72fc876b29b0e2638542a508 Mon Sep 17 00:00:00 2001 From: crs Date: Sat, 22 Jun 2002 19:47:27 +0000 Subject: [PATCH] CXWindowsUtil::CErrorLock wasn't XSync()'ing the display before installing and uninstalling the new error handler, causing errors before the lock to be caught and errors during the lock to not be caught. had to add Display* as argument to c'tor. --- platform/CXWindowsClipboard.cpp | 8 ++++---- platform/CXWindowsScreenSaver.cpp | 12 ++++++------ platform/CXWindowsUtil.cpp | 29 +++++++++++++++++++++-------- platform/CXWindowsUtil.h | 7 ++++--- server/CXWindowsPrimaryScreen.cpp | 2 +- 5 files changed, 36 insertions(+), 22 deletions(-) diff --git a/platform/CXWindowsClipboard.cpp b/platform/CXWindowsClipboard.cpp index f894789b..08cb1f98 100644 --- a/platform/CXWindowsClipboard.cpp +++ b/platform/CXWindowsClipboard.cpp @@ -800,7 +800,7 @@ CXWindowsClipboard::insertReply(CReply* reply) if (newWindow) { // note errors while we adjust event masks bool error = false; - CXWindowsUtil::CErrorLock lock(&error); + CXWindowsUtil::CErrorLock lock(m_display, &error); // get and save the current event mask XWindowAttributes attr; @@ -852,7 +852,7 @@ CXWindowsClipboard::pushReplies(CReplyMap::iterator mapIndex, // if there are no more replies in the list then remove the list // and stop watching the requestor for events. if (replies.empty()) { - CXWindowsUtil::CErrorLock lock; + CXWindowsUtil::CErrorLock lock(m_display); Window requestor = mapIndex->first; XSelectInput(m_display, requestor, m_eventMasks[requestor]); m_replies.erase(mapIndex); @@ -926,7 +926,7 @@ CXWindowsClipboard::sendReply(CReply* reply) log((CLOG_DEBUG1 "clipboard: sending failure to 0x%08x,%d,%d", reply->m_requestor, reply->m_target, reply->m_property)); reply->m_done = true; if (reply->m_property != None) { - CXWindowsUtil::CErrorLock lock; + CXWindowsUtil::CErrorLock lock(m_display); XDeleteProperty(m_display, reply->m_requestor, reply->m_property); } @@ -1016,7 +1016,7 @@ CXWindowsClipboard::sendNotify(Window requestor, event.xselection.target = target; event.xselection.property = property; event.xselection.time = time; - CXWindowsUtil::CErrorLock lock; + CXWindowsUtil::CErrorLock lock(m_display); XSendEvent(m_display, requestor, False, 0, &event); } diff --git a/platform/CXWindowsScreenSaver.cpp b/platform/CXWindowsScreenSaver.cpp index 89070e3a..f197b88a 100644 --- a/platform/CXWindowsScreenSaver.cpp +++ b/platform/CXWindowsScreenSaver.cpp @@ -24,7 +24,7 @@ CXWindowsScreenSaver::CXWindowsScreenSaver(Display* display) : // watch top-level windows for changes { bool error = false; - CXWindowsUtil::CErrorLock lock(&error); + CXWindowsUtil::CErrorLock lock(m_display, &error); Window root = DefaultRootWindow(m_display); XWindowAttributes attr; XGetWindowAttributes(m_display, root, &attr); @@ -46,7 +46,7 @@ CXWindowsScreenSaver::CXWindowsScreenSaver(Display* display) : CXWindowsScreenSaver::~CXWindowsScreenSaver() { // stop watching root for events - CXWindowsUtil::CErrorLock lock; + CXWindowsUtil::CErrorLock lock(m_display); Window root = DefaultRootWindow(m_display); XSelectInput(m_display, root, m_rootEventMask); } @@ -179,7 +179,7 @@ CXWindowsScreenSaver::sendNotify(bool activated) event.xclient.data.l[3] = 0; event.xclient.data.l[4] = 0; - CXWindowsUtil::CErrorLock lock; + CXWindowsUtil::CErrorLock lock(m_display); XSendEvent(m_display, m_notify, False, 0, &event); } } @@ -202,7 +202,7 @@ CXWindowsScreenSaver::updateXScreenSaver() } // find top-level window with m_atomScreenSaverVersion string property - CXWindowsUtil::CErrorLock lock; + CXWindowsUtil::CErrorLock lock(m_display); Window root = DefaultRootWindow(m_display); Window rw, pw, *cw; unsigned int nc; @@ -224,7 +224,7 @@ CXWindowsScreenSaver::updateXScreenSaver() // see if xscreensaver is active if (m_xscreensaver != None) { bool error = false; - CXWindowsUtil::CErrorLock lock(&error); + CXWindowsUtil::CErrorLock lock(m_display, &error); XWindowAttributes attr; XGetWindowAttributes(m_display, m_xscreensaver, &attr); setXScreenSaver(!error && attr.map_state != IsUnmapped); @@ -250,6 +250,6 @@ CXWindowsScreenSaver::sendXScreenSaverCommand( event.xclient.data.l[3] = 0; event.xclient.data.l[4] = 0; - CXWindowsUtil::CErrorLock lock; + CXWindowsUtil::CErrorLock lock(m_display); XSendEvent(m_display, m_xscreensaver, False, 0, &event); } diff --git a/platform/CXWindowsUtil.cpp b/platform/CXWindowsUtil.cpp index d7b9ba4c..8279d084 100644 --- a/platform/CXWindowsUtil.cpp +++ b/platform/CXWindowsUtil.cpp @@ -19,7 +19,7 @@ CXWindowsUtil::getWindowProperty(Display* display, Window window, int actualDatumSize; // ignore errors. XGetWindowProperty() will report failure. - CXWindowsUtil::CErrorLock lock; + CXWindowsUtil::CErrorLock lock(display); // read the property const long length = XMaxRequestSize(display); @@ -93,7 +93,7 @@ CXWindowsUtil::setWindowProperty(Display* display, Window window, // save errors bool error = false; - CXWindowsUtil::CErrorLock lock(&error); + CXWindowsUtil::CErrorLock lock(display, &error); // how much data to send in first chunk? UInt32 chunkSize = size; @@ -179,23 +179,31 @@ CXWindowsUtil::propertyNotifyPredicate(Display*, XEvent* xevent, XPointer arg) CXWindowsUtil::CErrorLock* CXWindowsUtil::CErrorLock::s_top = NULL; -CXWindowsUtil::CErrorLock::CErrorLock() +CXWindowsUtil::CErrorLock::CErrorLock(Display* display) : + m_display(display) { install(&CXWindowsUtil::CErrorLock::ignoreHandler, NULL); } -CXWindowsUtil::CErrorLock::CErrorLock(bool* flag) +CXWindowsUtil::CErrorLock::CErrorLock(Display* display, bool* flag) : + m_display(display) { install(&CXWindowsUtil::CErrorLock::saveHandler, flag); } -CXWindowsUtil::CErrorLock::CErrorLock(ErrorHandler handler, void* data) +CXWindowsUtil::CErrorLock::CErrorLock(Display* display, + ErrorHandler handler, void* data) : + m_display(display) { install(handler, data); } CXWindowsUtil::CErrorLock::~CErrorLock() { + // make sure everything finishes before uninstalling handler + XSync(m_display, False); + + // restore old handler XSetErrorHandler(m_oldXHandler); s_top = m_next; } @@ -203,6 +211,10 @@ CXWindowsUtil::CErrorLock::~CErrorLock() void CXWindowsUtil::CErrorLock::install(ErrorHandler handler, void* data) { + // make sure everything finishes before installing handler + XSync(m_display, False); + + // install handler m_handler = handler; m_userData = data; m_oldXHandler = XSetErrorHandler( @@ -221,13 +233,14 @@ CXWindowsUtil::CErrorLock::internalHandler(Display* display, XErrorEvent* event) } void -CXWindowsUtil::CErrorLock::ignoreHandler(Display*, XErrorEvent*, void*) +CXWindowsUtil::CErrorLock::ignoreHandler(Display*, XErrorEvent* e, void*) { - // do nothing + log((CLOG_DEBUG "ignoring X error: %d", e->error_code)); } void -CXWindowsUtil::CErrorLock::saveHandler(Display*, XErrorEvent*, void* flag) +CXWindowsUtil::CErrorLock::saveHandler(Display*, XErrorEvent* e, void* flag) { + log((CLOG_DEBUG "flagging X error: %d", e->error_code)); *reinterpret_cast(flag) = true; } diff --git a/platform/CXWindowsUtil.h b/platform/CXWindowsUtil.h index 9e8add53..fefcc92a 100644 --- a/platform/CXWindowsUtil.h +++ b/platform/CXWindowsUtil.h @@ -30,9 +30,9 @@ public: class CErrorLock { public: typedef void (*ErrorHandler)(Display*, XErrorEvent*, void* userData); - CErrorLock(); - CErrorLock(bool* errorFlag); - CErrorLock(ErrorHandler, void* userData); + CErrorLock(Display*); + CErrorLock(Display*, bool* errorFlag); + CErrorLock(Display*, ErrorHandler, void* userData); ~CErrorLock(); private: @@ -44,6 +44,7 @@ public: private: typedef int (*XErrorHandler)(Display*, XErrorEvent*); + Display* m_display; ErrorHandler m_handler; void* m_userData; XErrorHandler m_oldXHandler; diff --git a/server/CXWindowsPrimaryScreen.cpp b/server/CXWindowsPrimaryScreen.cpp index a500e545..1537af18 100644 --- a/server/CXWindowsPrimaryScreen.cpp +++ b/server/CXWindowsPrimaryScreen.cpp @@ -617,7 +617,7 @@ CXWindowsPrimaryScreen::selectEvents(Display* display, Window w) const // ignore errors while we adjust event masks. windows could be // destroyed at any time after the XQueryTree() in doSelectEvents() // so we must ignore BadWindow errors. - CXWindowsUtil::CErrorLock lock; + CXWindowsUtil::CErrorLock lock(display); // adjust event masks doSelectEvents(display, w);