removed getEventMask() from primary screen. added a class to

CXWindowsUtil that installs/uninstalls an X error hander.
using that in primary screen, clipboard, and util to ensure
that certain errors don't kill the app.
This commit is contained in:
crs
2002-05-27 18:30:13 +00:00
parent 7cf20d9ad0
commit 189537b8b9
6 changed files with 133 additions and 20 deletions

View File

@@ -1,8 +1,13 @@
#include "CXWindowsUtil.h"
#include "CLog.h"
#include "CThread.h"
#include <assert.h>
#include <X11/Xatom.h>
//
// CXWindowsUtil
//
bool CXWindowsUtil::getWindowProperty(
Display* display,
Window window, Atom property,
@@ -15,6 +20,9 @@ bool CXWindowsUtil::getWindowProperty(
Atom actualType;
int actualDatumSize;
// ignore errors. XGetWindowProperty() will report failure.
CXWindowsUtil::CErrorLock lock;
// read the property
const long length = XMaxRequestSize(display);
long offset = 0;
@@ -82,13 +90,14 @@ bool CXWindowsUtil::setWindowProperty(
const void* vdata, UInt32 size,
Atom type, SInt32 format)
{
// FIXME -- must catch Alloc errors (using XSetErrorHandler()) and
// report failure to caller.
const UInt32 length = 4 * XMaxRequestSize(display);
const unsigned char* data = reinterpret_cast<const unsigned char*>(vdata);
const UInt32 datumSize = static_cast<UInt32>(format / 8);
// save errors
bool error = false;
CXWindowsUtil::CErrorLock lock(&error);
// how much data to send in first chunk?
UInt32 chunkSize = size;
if (chunkSize > length)
@@ -102,7 +111,7 @@ bool CXWindowsUtil::setWindowProperty(
// append remaining chunks
data += chunkSize;
size -= chunkSize;
while (size > 0) {
while (!error && size > 0) {
chunkSize = size;
if (chunkSize > length)
chunkSize = length;
@@ -113,7 +122,7 @@ bool CXWindowsUtil::setWindowProperty(
size -= chunkSize;
}
return true;
return !error;
}
Time CXWindowsUtil::getCurrentTime(
@@ -167,3 +176,63 @@ Bool CXWindowsUtil::propertyNotifyPredicate(
xevent->xproperty.atom == filter->m_property &&
xevent->xproperty.state == PropertyNewValue) ? True : False;
}
//
// CXWindowsUtil::CErrorLock
//
CXWindowsUtil::CErrorLock* CXWindowsUtil::CErrorLock::s_top = NULL;
CXWindowsUtil::CErrorLock::CErrorLock()
{
install(&CXWindowsUtil::CErrorLock::ignoreHandler, NULL);
}
CXWindowsUtil::CErrorLock::CErrorLock(bool* flag)
{
install(&CXWindowsUtil::CErrorLock::saveHandler, flag);
}
CXWindowsUtil::CErrorLock::CErrorLock(ErrorHandler handler, void* data)
{
install(handler, data);
}
CXWindowsUtil::CErrorLock::~CErrorLock()
{
XSetErrorHandler(m_oldXHandler);
s_top = m_next;
}
void CXWindowsUtil::CErrorLock::install(
ErrorHandler handler, void* data)
{
m_handler = handler;
m_userData = data;
m_oldXHandler = XSetErrorHandler(
&CXWindowsUtil::CErrorLock::internalHandler);
m_next = s_top;
s_top = this;
}
int CXWindowsUtil::CErrorLock::internalHandler(
Display* display, XErrorEvent* event)
{
if (s_top != NULL && s_top->m_handler != NULL) {
s_top->m_handler(display, event, s_top->m_userData);
}
return 0;
}
void CXWindowsUtil::CErrorLock::ignoreHandler(
Display*, XErrorEvent*, void*)
{
// do nothing
}
void CXWindowsUtil::CErrorLock::saveHandler(
Display*, XErrorEvent*, void* flag)
{
*reinterpret_cast<bool*>(flag) = true;
}