Reworked the X interaction so that both STRING and UTF8_STRING are

supported both ways.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@17460 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2003-08-08 22:59:37 +00:00
parent 5c6acf120f
commit afe960e235

View file

@ -58,9 +58,7 @@ static char* atom_names[] = {
"NULL",
"FILE_NAME",
"CLIPBOARD",
#ifdef X_HAVE_UTF8_STRING
"UTF8_STRING"
#endif
};
static Atom atoms[sizeof(atom_names)/sizeof(char*)];
@ -84,9 +82,7 @@ static Atom atoms[sizeof(atom_names)/sizeof(char*)];
#define XG_NULL atoms[13]
#define XG_FILE_NAME atoms[14]
#define XA_CLIPBOARD atoms[15]
#ifdef X_HAVE_UTF8_STRING
#define XG_UTF8_STRING atoms[16]
#endif
@ -130,13 +126,9 @@ osTypeToX(NSString *t)
static NSString*
xTypeToOs(Atom t)
{
#ifdef X_HAVE_UTF8_STRING
if (t == XG_UTF8_STRING)
#else
if (t == XA_STRING)
#endif
return NSStringPboardType;
else if (t == XG_TEXT)
if ((t == XG_UTF8_STRING) ||
(t == XG_TEXT) ||
(t == XA_STRING))
return NSStringPboardType;
else if (t == XG_FILE_NAME)
return NSFilenamesPboardType;
@ -146,41 +138,6 @@ xTypeToOs(Atom t)
static Bool xAppendProperty(Display* display,
Window window,
Atom property,
Atom target,
int format,
unsigned char* data,
int number_items)
{
// Ensure that the error handler is set up.
// xSetErrorHandler();
// Any routine that appends properties can generate a BadAlloc error.
// xResetErrorFlag();
if (number_items > 0)
{
XChangeProperty(display,
window,
property,
target,
format,
PropModeAppend,
data,
number_items);
XSync(display, False);
// Check if our write to a property generated an X error.
// if (xError())
// return False;
}
return True;
}
@interface XPbOwner : NSObject
{
NSPasteboard *_pb;
@ -223,7 +180,7 @@ static Bool xAppendProperty(Display* display,
- (void) xSelectionNotify: (XSelectionEvent*)xEvent;
- (void) xSelectionRequest: (XSelectionRequestEvent*)xEvent;
- (BOOL) xProvideSelection: (XSelectionRequestEvent*)xEvent;
- (Time) xTimeByAppending;
- (Time) xTimeByAppending: (Atom) defaultType;
- (BOOL) xSendData: (unsigned char*) data format: (int) format
items: (int) numItems type: (Atom) xType
to: (Window) window property: (Atom) property;
@ -483,12 +440,6 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
NSDebugLLog(@"Pbs", @"Selection notify for wrong (not our) window.");
return;
}
if (xEvent->property == (Atom)None)
{
NSLog(@"Owning program failed to convert data.");
return;
}
else
{
NSDebugLLog(@"Pbs", @"Selection (%s) notify - '%s'.",
@ -575,13 +526,67 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
* so we must tell the X server that we have the current selection.
* To conform to ICCCM we need to specify an up-to-date timestamp.
*/
XSetSelectionOwner(xDisplay, _xPb, xAppWin, [self xTimeByAppending]);
#ifdef X_HAVE_UTF8_STRING
Atom defaultType = XG_UTF8_STRING;
#else // X_HAVE_UTF8_STRING not defined
Atom defaultType = XA_STRING;
#endif // X_HAVE_UTF8_STRING not defined
XSetSelectionOwner(xDisplay, _xPb, xAppWin,
[self xTimeByAppending: defaultType]);
w = XGetSelectionOwner(xDisplay, _xPb);
if (w != xAppWin)
{
NSLog(@"Failed to set X selection owner to the pasteboard server.");
}
[self setOwnedByOpenStep: YES];
else
{
[self setOwnedByOpenStep: YES];
}
}
- (void) requestData: (Atom)xType
{
Time whenRequested;
/*
* Do a nul append to a property to get a timestamp, if it returns the
* 'CurrentTime' constant then we haven't been able to get one.
*/
whenRequested = [self xTimeByAppending: xType];
if (whenRequested != CurrentTime)
{
NSDate *limit;
/*
* Ok - we got a timestamp, so we can ask the selection system for
* the pasteboard data that was/is valid for theat time.
* Ask the X system to provide the pasteboard data in the
* appropriate property of our application root window.
*/
XConvertSelection(xDisplay, [self xPb], xType,
[self xPb], xAppWin, whenRequested);
XFlush(xDisplay);
/*
* Run an event loop to read X events until we have aquired the
* pasteboard data we need.
*/
limit = [NSDate dateWithTimeIntervalSinceNow: 20.0];
[self setWaitingForSelection: whenRequested];
while ([self waitingForSelection] == whenRequested)
{
[[NSRunLoop currentRunLoop] runMode: xWaitMode
beforeDate: limit];
if ([limit timeIntervalSinceNow] <= 0.0)
break; /* Timeout */
}
if ([self waitingForSelection] != 0)
{
[self setWaitingForSelection: 0];
NSLog(@"Timed out waiting for X selection");
}
}
}
- (void) pasteboard: (NSPasteboard*)pb provideDataForType: (NSString*)type
@ -595,51 +600,11 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
*/
if ([type isEqual: NSStringPboardType])
{
Time whenRequested;
/*
* Do a nul append to a property to get a timestamp, if it returns the
* 'CurrentTime' constant then we haven't been able to get one.
*/
whenRequested = [self xTimeByAppending];
if (whenRequested != CurrentTime)
{
NSDate *limit;
/*
* Ok - we got a timestamp, so we can ask the selection system for
* the pasteboard data that was/is valid for theat time.
* Ask the X system to provide the pasteboard data in the
* appropriate property of our application root window.
*/
#ifdef X_HAVE_UTF8_STRING
XConvertSelection(xDisplay, [self xPb], XG_UTF8_STRING,
[self xPb], xAppWin, whenRequested);
#else // X_HAVE_UTF8_STRING not defined
XConvertSelection(xDisplay, [self xPb], XA_STRING,
[self xPb], xAppWin, whenRequested);
[self requestData: XG_UTF8_STRING];
if ([self data] == nil)
#endif // X_HAVE_UTF8_STRING not defined
XFlush(xDisplay);
/*
* Run an event loop to read X events until we have aquired the
* pasteboard data we need.
*/
limit = [NSDate dateWithTimeIntervalSinceNow: 20.0];
[self setWaitingForSelection: whenRequested];
while ([self waitingForSelection] == whenRequested)
{
[[NSRunLoop currentRunLoop] runMode: xWaitMode
beforeDate: limit];
if ([limit timeIntervalSinceNow] <= 0.0)
break; /* Timeout */
}
if ([self waitingForSelection] != 0)
{
[self setWaitingForSelection: 0];
NSLog(@"Timed out waiting for X selection");
}
}
[self requestData: XA_STRING];
}
else
{
@ -710,15 +675,17 @@ xErrorHandler(Display *d, XErrorEvent *e)
int status;
unsigned char *data;
Atom actual_target;
#ifdef X_HAVE_UTF8_STRING
Atom new_target = XG_UTF8_STRING;
#else // X_HAVE_UTF8_STRING not defined
Atom new_target = XA_STRING;
#endif // X_HAVE_UTF8_STRING
int actual_format;
unsigned long bytes_remaining;
unsigned long number_items;
if (xEvent->property == (Atom)None)
{
NSDebugLLog(@"Pbs", @"Owning program failed to convert data.");
[self setWaitingForSelection: 0];
return;
}
if ([self waitingForSelection] > xEvent->time)
{
NSLog(@"Unexpected selection notify - time %u.", xEvent->time);
@ -735,7 +702,7 @@ xErrorHandler(Display *d, XErrorEvent *e)
0L, // offset
FULL_LENGTH,
True, // Delete prop when read.
new_target,
AnyPropertyType,
&actual_target,
&actual_format,
&number_items,
@ -744,10 +711,7 @@ xErrorHandler(Display *d, XErrorEvent *e)
if ((status == Success) && (number_items > 0))
{
// Convert data to text string.
// string = PropertyToString(xDisplay,new_target,number_items,(char*)data);
#ifdef X_HAVE_UTF8_STRING
// Convert data to text string.
if (actual_target == XG_UTF8_STRING)
{
NSData *d;
@ -762,8 +726,7 @@ xErrorHandler(Display *d, XErrorEvent *e)
RELEASE(s);
[self setData: d];
}
#else // X_HAVE_UTF8_STRING not defined
if (new_target == XA_STRING)
else if (actual_target == XA_STRING)
{
NSData *d;
NSString *s;
@ -777,7 +740,6 @@ xErrorHandler(Display *d, XErrorEvent *e)
RELEASE(s);
[self setData: d];
}
#endif // X_HAVE_UTF8_STRING not defined
else
{
NSLog(@"Unsupported data type from X selection.");
@ -902,6 +864,8 @@ xErrorHandler(Display *d, XErrorEvent *e)
}
else
{
// A fixed type was requested.
xType = xEvent->target;
/*
* Find an available OpenStep pasteboard type that corresponds
* to the requested X type.
@ -911,13 +875,22 @@ xErrorHandler(Display *d, XErrorEvent *e)
NSString *type = [types objectAtIndex: i];
Atom t = osTypeToX(type);
if (t == xEvent->target)
if (t == xType)
{
osType = type;
xType = t;
break;
}
}
// If UTF8 is the default we have to handle the case where the target
// applciaiton cannot handle this.
if ((osType == nil) &&
[types containsObject: NSStringPboardType] &&
((xType == XA_STRING) || (xType == XG_TEXT)))
{
osType = NSStringPboardType;
}
}
/*
@ -929,11 +902,16 @@ xErrorHandler(Display *d, XErrorEvent *e)
if ([osType isEqualToString: NSStringPboardType])
{
NSString *s = [_pb stringForType: NSStringPboardType];
#ifdef X_HAVE_UTF8_STRING
NSData *d = [s dataUsingEncoding: NSUTF8StringEncoding];
#else // X_HAVE_UTF8_STRING not defined
NSData *d = [s dataUsingEncoding: NSISOLatin1StringEncoding];
#endif // X_HAVE_UTF8_STRING not defined
NSData *d;
if (xType == XG_UTF8_STRING)
{
d = [s dataUsingEncoding: NSUTF8StringEncoding];
}
else
{
d = [s dataUsingEncoding: NSISOLatin1StringEncoding];
}
format = 8;
if (d != nil)
@ -1000,7 +978,7 @@ xErrorHandler(Display *d, XErrorEvent *e)
return status;
}
- (Time) xTimeByAppending
- (Time) xTimeByAppending: (Atom)defaultType
{
NSDate *limit;
Time whenRequested;
@ -1025,16 +1003,12 @@ xErrorHandler(Display *d, XErrorEvent *e)
* The property doesn't exist - so we will be creating a new (empty)
* property.
*/
#ifdef X_HAVE_UTF8_STRING
actualType = XG_UTF8_STRING;
#else // X_HAVE_UTF8_STRING not defined
actualType = XA_STRING;
#endif // X_HAVE_UTF8_STRING not defined
actualType = defaultType;
actualFormat = 8;
}
XChangeProperty(xDisplay, xAppWin, [self xPb], actualType, actualFormat,
PropModeAppend, 0, 0);
PropModeReplace, 0, 0);
XFlush(xDisplay);
limit = [NSDate dateWithTimeIntervalSinceNow: 3.0];
[self setTimeOfLastAppend: 0];