added missing files from previous submit.
This commit is contained in:
parent
854d2c7fbf
commit
56d7271bc1
|
@ -0,0 +1,169 @@
|
|||
#include "CXWindowsUtil.h"
|
||||
#include "CLog.h"
|
||||
#include "CThread.h"
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
bool CXWindowsUtil::getWindowProperty(
|
||||
Display* display,
|
||||
Window window, Atom property,
|
||||
CString* data, Atom* type,
|
||||
int* format, bool deleteProperty)
|
||||
{
|
||||
assert(display != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
Atom actualType;
|
||||
int actualDatumSize;
|
||||
|
||||
// read the property
|
||||
const long length = XMaxRequestSize(display);
|
||||
long offset = 0;
|
||||
unsigned long bytesLeft = 1;
|
||||
while (bytesLeft != 0) {
|
||||
// get more data
|
||||
unsigned long numItems;
|
||||
unsigned char* rawData;
|
||||
const int result = XGetWindowProperty(display, window, property,
|
||||
offset, length, False, AnyPropertyType,
|
||||
&actualType, &actualDatumSize,
|
||||
&numItems, &bytesLeft, &rawData);
|
||||
if (result != Success || actualType == None || actualDatumSize == 0) {
|
||||
// failed
|
||||
return false;
|
||||
}
|
||||
|
||||
// compute bytes read and advance offset
|
||||
unsigned long numBytes;
|
||||
switch (actualDatumSize) {
|
||||
case 8:
|
||||
default:
|
||||
numBytes = numItems;
|
||||
offset += numItems / 4;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
numBytes = 2 * numItems;
|
||||
offset += numItems / 2;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
numBytes = 4 * numItems;
|
||||
offset += numItems;
|
||||
break;
|
||||
}
|
||||
|
||||
// append data
|
||||
data->append((char*)rawData, numBytes);
|
||||
|
||||
// done with returned data
|
||||
XFree(rawData);
|
||||
}
|
||||
|
||||
// delete the property if requested
|
||||
if (deleteProperty) {
|
||||
XDeleteProperty(display, window, property);
|
||||
}
|
||||
|
||||
// save property info
|
||||
if (type != NULL) {
|
||||
*type = actualType;
|
||||
}
|
||||
if (format != NULL) {
|
||||
*format = static_cast<SInt32>(actualDatumSize);
|
||||
}
|
||||
|
||||
log((CLOG_DEBUG1 "read property %d on window 0x%08x: bytes=%d", property, window, data->size()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CXWindowsUtil::setWindowProperty(
|
||||
Display* display,
|
||||
Window window, Atom property,
|
||||
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);
|
||||
|
||||
// how much data to send in first chunk?
|
||||
UInt32 chunkSize = size;
|
||||
if (chunkSize > length)
|
||||
chunkSize = length;
|
||||
|
||||
// send first chunk
|
||||
XChangeProperty(display, window, property,
|
||||
type, format, PropModeReplace,
|
||||
data, chunkSize / datumSize);
|
||||
|
||||
// append remaining chunks
|
||||
data += chunkSize;
|
||||
size -= chunkSize;
|
||||
while (size > 0) {
|
||||
chunkSize = size;
|
||||
if (chunkSize > length)
|
||||
chunkSize = length;
|
||||
XChangeProperty(display, window, property,
|
||||
type, format, PropModeAppend,
|
||||
data, chunkSize / datumSize);
|
||||
data += chunkSize;
|
||||
size -= chunkSize;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Time CXWindowsUtil::getCurrentTime(
|
||||
Display* display, Window window)
|
||||
{
|
||||
// select property events on window
|
||||
XWindowAttributes attr;
|
||||
XGetWindowAttributes(display, window, &attr);
|
||||
XSelectInput(display, window, attr.your_event_mask | PropertyChangeMask);
|
||||
|
||||
// make a property name to receive dummy change
|
||||
Atom atom = XInternAtom(display, "TIMESTAMP", False);
|
||||
|
||||
// do a zero-length append to get the current time
|
||||
unsigned char dummy;
|
||||
XChangeProperty(display, window, atom,
|
||||
XA_INTEGER, 8,
|
||||
PropModeAppend,
|
||||
&dummy, 0);
|
||||
|
||||
// look for property notify events with the following
|
||||
CPropertyNotifyPredicateInfo filter;
|
||||
filter.m_window = window;
|
||||
filter.m_property = atom;
|
||||
|
||||
// wait for reply
|
||||
XEvent xevent;
|
||||
while (XCheckIfEvent(display, &xevent,
|
||||
&CXWindowsUtil::propertyNotifyPredicate,
|
||||
(XPointer)&filter) != True) {
|
||||
// wait a bit
|
||||
CThread::sleep(0.05);
|
||||
}
|
||||
assert(xevent.type == PropertyNotify);
|
||||
assert(xevent.xproperty.window == window);
|
||||
assert(xevent.xproperty.atom == atom);
|
||||
|
||||
// restore event mask
|
||||
XSelectInput(display, window, attr.your_event_mask);
|
||||
|
||||
return xevent.xproperty.time;
|
||||
}
|
||||
|
||||
Bool CXWindowsUtil::propertyNotifyPredicate(
|
||||
Display*, XEvent* xevent, XPointer arg)
|
||||
{
|
||||
CPropertyNotifyPredicateInfo* filter =
|
||||
reinterpret_cast<CPropertyNotifyPredicateInfo*>(arg);
|
||||
return (xevent->type == PropertyNotify &&
|
||||
xevent->xproperty.window == filter->m_window &&
|
||||
xevent->xproperty.atom == filter->m_property &&
|
||||
xevent->xproperty.state == PropertyNewValue) ? True : False;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef CXWINDOWSUTIL_H
|
||||
#define CXWINDOWSUTIL_H
|
||||
|
||||
#include "BasicTypes.h"
|
||||
#include "CString.h"
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
class CXWindowsUtil {
|
||||
public:
|
||||
static bool getWindowProperty(Display*,
|
||||
Window window, Atom property,
|
||||
CString* data, Atom* type,
|
||||
SInt32* format, bool deleteProperty);
|
||||
static bool setWindowProperty(Display*,
|
||||
Window window, Atom property,
|
||||
const void* data, UInt32 size,
|
||||
Atom type, SInt32 format);
|
||||
static Time getCurrentTime(Display*, Window);
|
||||
|
||||
private:
|
||||
class CPropertyNotifyPredicateInfo {
|
||||
public:
|
||||
Window m_window;
|
||||
Atom m_property;
|
||||
};
|
||||
|
||||
static Bool propertyNotifyPredicate(Display*,
|
||||
XEvent* xevent, XPointer arg);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue