mirror of
https://github.com/gnustep/libs-back.git
synced 2025-02-24 04:11:28 +00:00
Made all calls to XGetAtomName() free their memory later on.
Removed function osTypeToX(). Extracted method [getSelectionData:type:] from [xSelectionNotify:]. [xSelectionNotify:] now supports incremental data transfer and is save against failing string conversions. Complete rewrite of [xProvideSelection:] to better follow the ICCCM specification. This now implements TIMESTAMP, MULTIPLE and COMPOUND_TEXT (all untested!) git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@17606 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
e45bf12265
commit
a8d30770bb
1 changed files with 299 additions and 205 deletions
438
Tools/xpbs.m
438
Tools/xpbs.m
|
@ -31,8 +31,6 @@
|
|||
#include <X11/Xutil.h>
|
||||
#include <x11/xdnd.h>
|
||||
|
||||
static Atom osTypeToX(NSString *t);
|
||||
|
||||
/*
|
||||
* Non-predefined atoms that are used in the X selection mechanism
|
||||
*/
|
||||
|
@ -53,7 +51,10 @@ static char* atom_names[] = {
|
|||
"NULL",
|
||||
"FILE_NAME",
|
||||
"CLIPBOARD",
|
||||
"UTF8_STRING"
|
||||
"UTF8_STRING",
|
||||
"MULTIPLE",
|
||||
"COMPOUND_TEXT",
|
||||
"INCR"
|
||||
};
|
||||
static Atom atoms[sizeof(atom_names)/sizeof(char*)];
|
||||
|
||||
|
@ -78,45 +79,9 @@ static Atom atoms[sizeof(atom_names)/sizeof(char*)];
|
|||
#define XG_FILE_NAME atoms[14]
|
||||
#define XA_CLIPBOARD atoms[15]
|
||||
#define XG_UTF8_STRING atoms[16]
|
||||
|
||||
|
||||
|
||||
static Atom
|
||||
osTypeToX(NSString *t)
|
||||
{
|
||||
if ([t isEqualToString: NSStringPboardType] == YES)
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
return XG_UTF8_STRING;
|
||||
#else
|
||||
return XA_STRING;
|
||||
#endif
|
||||
else if ([t isEqualToString: NSColorPboardType] == YES)
|
||||
return XG_NULL;
|
||||
else if ([t isEqualToString: NSFileContentsPboardType] == YES)
|
||||
return XG_NULL;
|
||||
else if ([t isEqualToString: NSFilenamesPboardType] == YES)
|
||||
return XG_FILE_NAME;
|
||||
else if ([t isEqualToString: NSFontPboardType] == YES)
|
||||
return XG_NULL;
|
||||
else if ([t isEqualToString: NSRulerPboardType] == YES)
|
||||
return XG_NULL;
|
||||
else if ([t isEqualToString: NSPostScriptPboardType] == YES)
|
||||
return XG_NULL;
|
||||
else if ([t isEqualToString: NSTabularTextPboardType] == YES)
|
||||
return XG_NULL;
|
||||
else if ([t isEqualToString: NSRTFPboardType] == YES)
|
||||
return XG_NULL;
|
||||
else if ([t isEqualToString: NSRTFDPboardType] == YES)
|
||||
return XG_NULL;
|
||||
else if ([t isEqualToString: NSTIFFPboardType] == YES)
|
||||
return XG_NULL;
|
||||
else if ([t isEqualToString: NSDataLinkPboardType] == YES)
|
||||
return XG_NULL;
|
||||
else if ([t isEqualToString: NSGeneralPboardType] == YES)
|
||||
return XG_NULL;
|
||||
else
|
||||
return XG_NULL;
|
||||
}
|
||||
#define XG_MULTIPLE atoms[17]
|
||||
#define XG_COMPOUND_TEXT atoms[18]
|
||||
#define XG_INCR atoms[19]
|
||||
|
||||
|
||||
|
||||
|
@ -128,6 +93,7 @@ osTypeToX(NSString *t)
|
|||
Atom _xPb;
|
||||
Time _waitingForSelection;
|
||||
Time _timeOfLastAppend;
|
||||
Time _timeOfSetSelectionOwner;
|
||||
BOOL _ownedByOpenStep;
|
||||
}
|
||||
|
||||
|
@ -162,7 +128,7 @@ osTypeToX(NSString *t)
|
|||
- (void) xSelectionNotify: (XSelectionEvent*)xEvent;
|
||||
- (void) xSelectionRequest: (XSelectionRequestEvent*)xEvent;
|
||||
- (BOOL) xProvideSelection: (XSelectionRequestEvent*)xEvent;
|
||||
- (Time) xTimeByAppending: (Atom) defaultType;
|
||||
- (Time) xTimeByAppending;
|
||||
- (BOOL) xSendData: (unsigned char*) data format: (int) format
|
||||
items: (int) numItems type: (Atom) xType
|
||||
to: (Window) window property: (Atom) property;
|
||||
|
@ -244,7 +210,6 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
|||
forMode: xWaitMode];
|
||||
|
||||
XSelectInput(xDisplay, xAppWin, PropertyChangeMask);
|
||||
|
||||
XFlush(xDisplay);
|
||||
}
|
||||
|
||||
|
@ -367,8 +332,11 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
|||
o = [self ownerByXPb: xEvent->selection];
|
||||
if (o == nil)
|
||||
{
|
||||
char *name = XGetAtomName(xDisplay, xEvent->selection);
|
||||
|
||||
NSDebugLLog(@"Pbs", @"Selection clear for unknown selection - '%s'.",
|
||||
XGetAtomName(xDisplay, xEvent->selection));
|
||||
name);
|
||||
XFree(name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -388,8 +356,10 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
|||
o = [self ownerByXPb: xEvent->atom];
|
||||
if (o == nil)
|
||||
{
|
||||
char *name = XGetAtomName(xDisplay, xEvent->atom);
|
||||
NSDebugLLog(@"Pbs", @"Property notify for unknown property - '%s'.",
|
||||
XGetAtomName(xDisplay, xEvent->atom));
|
||||
name);
|
||||
XFree(name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -412,8 +382,10 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
|||
o = [self ownerByXPb: xEvent->selection];
|
||||
if (o == nil)
|
||||
{
|
||||
char *name = XGetAtomName(xDisplay, xEvent->selection);
|
||||
NSDebugLLog(@"Pbs", @"Selection notify for unknown selection - '%s'.",
|
||||
XGetAtomName(xDisplay, xEvent->selection));
|
||||
name);
|
||||
XFree(name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -424,9 +396,13 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
|||
}
|
||||
else
|
||||
{
|
||||
NSDebugLLog(@"Pbs", @"Selection (%s) notify - '%s'.",
|
||||
XGetAtomName(xDisplay, xEvent->selection),
|
||||
XGetAtomName(xDisplay, xEvent->property));
|
||||
char *sel_name = XGetAtomName(xDisplay, xEvent->selection);
|
||||
char *pro_name = XGetAtomName(xDisplay, xEvent->property);
|
||||
|
||||
NSDebugLLog(@"Pbs", @"Selection (%s) notify - '%s'.", sel_name,
|
||||
pro_name);
|
||||
XFree(sel_name);
|
||||
XFree(pro_name);
|
||||
}
|
||||
|
||||
[o xSelectionNotify: xEvent];
|
||||
|
@ -439,8 +415,10 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
|||
o = [self ownerByXPb: xEvent->selection];
|
||||
if (o == nil)
|
||||
{
|
||||
char *name = XGetAtomName(xDisplay, xEvent->selection);
|
||||
NSDebugLLog(@"Pbs", @"Selection request for unknown selection - '%s'.",
|
||||
XGetAtomName(xDisplay, xEvent->selection));
|
||||
name);
|
||||
XFree(name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -508,11 +486,9 @@ 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.
|
||||
*/
|
||||
Atom defaultType = XG_UTF8_STRING;
|
||||
//Atom defaultType = XA_STRING;
|
||||
_timeOfSetSelectionOwner = [self xTimeByAppending];
|
||||
XSetSelectionOwner(xDisplay, _xPb, xAppWin, _timeOfSetSelectionOwner);
|
||||
|
||||
XSetSelectionOwner(xDisplay, _xPb, xAppWin,
|
||||
[self xTimeByAppending: defaultType]);
|
||||
w = XGetSelectionOwner(xDisplay, _xPb);
|
||||
if (w != xAppWin)
|
||||
{
|
||||
|
@ -532,7 +508,7 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
|||
* 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];
|
||||
whenRequested = [self xTimeByAppending];
|
||||
if (whenRequested != CurrentTime)
|
||||
{
|
||||
NSDate *limit;
|
||||
|
@ -562,9 +538,11 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
|||
}
|
||||
if ([self waitingForSelection] != 0)
|
||||
{
|
||||
char *name = XGetAtomName(xDisplay, xType);
|
||||
|
||||
[self setWaitingForSelection: 0];
|
||||
NSLog(@"Timed out waiting for X selection '%s'",
|
||||
XGetAtomName(xDisplay, xType));
|
||||
NSLog(@"Timed out waiting for X selection '%s'", name);
|
||||
XFree(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -648,7 +626,8 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
|||
[self setOwnedByOpenStep: NO];
|
||||
}
|
||||
|
||||
- (void) xSelectionNotify: (XSelectionEvent*)xEvent
|
||||
- (NSMutableData*) getSelectionData: (XSelectionEvent*)xEvent
|
||||
type: (Atom*)type
|
||||
{
|
||||
int status;
|
||||
unsigned char *data;
|
||||
|
@ -661,20 +640,6 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
|||
unsigned long number_items;
|
||||
NSMutableData *md = nil;
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
[self setWaitingForSelection: 0];
|
||||
|
||||
/*
|
||||
* Read data from property identified in SelectionNotify event.
|
||||
*/
|
||||
|
@ -707,9 +672,13 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
|||
{
|
||||
if (req_type != actual_type)
|
||||
{
|
||||
char *req_name = XGetAtomName(xDisplay, req_type);
|
||||
char *act_name = XGetAtomName(xDisplay, actual_type);
|
||||
|
||||
NSLog(@"Selection changed type from %s to %s.",
|
||||
XGetAtomName(xDisplay, req_type),
|
||||
XGetAtomName(xDisplay, actual_type));
|
||||
req_name, act_name);
|
||||
XFree(req_name);
|
||||
XFree(act_name);
|
||||
RELEASE(md);
|
||||
return;
|
||||
}
|
||||
|
@ -726,6 +695,77 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
|||
while ((status == Success) && (bytes_remaining > 0));
|
||||
|
||||
if (status == Success)
|
||||
{
|
||||
*type = actual_type;
|
||||
return AUTORELEASE(md);
|
||||
}
|
||||
else
|
||||
{
|
||||
RELEASE(md);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) xSelectionNotify: (XSelectionEvent*)xEvent
|
||||
{
|
||||
Atom actual_type;
|
||||
NSMutableData *md = nil;
|
||||
|
||||
if (xEvent->property == (Atom)None)
|
||||
{
|
||||
NSDebugLLog(@"Pbs", @"Owning program failed to convert data.");
|
||||
[self setWaitingForSelection: 0];
|
||||
return;
|
||||
}
|
||||
|
||||
if ([self waitingForSelection] > xEvent->time)
|
||||
{
|
||||
NSDebugLLog(@"Pbs", @"Unexpected selection notify - time %u.", xEvent->time);
|
||||
return;
|
||||
}
|
||||
[self setWaitingForSelection: 0];
|
||||
|
||||
md = [self getSelectionData: xEvent type: &actual_type];
|
||||
|
||||
if (md != nil)
|
||||
{
|
||||
if (actual_type == XG_INCR)
|
||||
{
|
||||
XEvent event;
|
||||
NSMutableData *imd = nil;
|
||||
BOOL wait = YES;
|
||||
|
||||
md = nil;
|
||||
while (wait)
|
||||
{
|
||||
XNextEvent(xDisplay, &event);
|
||||
|
||||
if (event.type == PropertyNotify)
|
||||
{
|
||||
if (event.xproperty.state != PropertyNewValue) continue;
|
||||
|
||||
imd = [self getSelectionData: xEvent type: &actual_type];
|
||||
if (imd != nil)
|
||||
{
|
||||
if (md == nil)
|
||||
{
|
||||
md = imd;
|
||||
}
|
||||
else
|
||||
{
|
||||
[md appendData: imd];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wait = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (md != nil)
|
||||
{
|
||||
// Convert data to text string.
|
||||
if (actual_type == XG_UTF8_STRING)
|
||||
|
@ -735,10 +775,13 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
|||
|
||||
s = [[NSString alloc] initWithData: md
|
||||
encoding: NSUTF8StringEncoding];
|
||||
if (s != nil)
|
||||
{
|
||||
d = [NSSerializer serializePropertyList: s];
|
||||
RELEASE(s);
|
||||
[self setData: d];
|
||||
}
|
||||
}
|
||||
else if (actual_type == XA_STRING)
|
||||
{
|
||||
NSString *s;
|
||||
|
@ -746,18 +789,21 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
|||
|
||||
s = [[NSString alloc] initWithData: md
|
||||
encoding: NSISOLatin1StringEncoding];
|
||||
if (s != nil)
|
||||
{
|
||||
d = [NSSerializer serializePropertyList: s];
|
||||
RELEASE(s);
|
||||
[self setData: d];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Unsupported data type '%s' from X selection.",
|
||||
XGetAtomName(xDisplay, actual_type));
|
||||
}
|
||||
}
|
||||
char *name = XGetAtomName(xDisplay, actual_type);
|
||||
|
||||
RELEASE(md);
|
||||
NSLog(@"Unsupported data type '%s' from X selection.", name);
|
||||
XFree(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) xSelectionRequest: (XSelectionRequestEvent*)xEvent
|
||||
|
@ -777,7 +823,15 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
|||
notify_event.selection = xEvent->selection;
|
||||
notify_event.target = xEvent->target;
|
||||
notify_event.time = xEvent->time;
|
||||
notify_event.send_event = True;
|
||||
if (xEvent->property == None)
|
||||
{
|
||||
notify_event.property = xEvent->target;
|
||||
}
|
||||
else
|
||||
{
|
||||
notify_event.property = xEvent->property;
|
||||
}
|
||||
|
||||
/*
|
||||
* If for any reason we cannot provide the data to the requestor, we must
|
||||
|
@ -805,125 +859,158 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
|||
if (xEvent->target == XG_TARGETS)
|
||||
{
|
||||
unsigned numTypes = 0;
|
||||
Atom xTypes[numOsTypes];
|
||||
Atom xTypes[10];
|
||||
|
||||
/*
|
||||
* The requestor wants a list of the types we can supply it with.
|
||||
*/
|
||||
for (i = 0; i < numOsTypes; i++)
|
||||
{
|
||||
NSString *type = [types objectAtIndex: i];
|
||||
Atom t;
|
||||
|
||||
t = osTypeToX(type);
|
||||
if (t != XG_NULL)
|
||||
{
|
||||
unsigned j;
|
||||
|
||||
for (j = 0; j < numTypes; j++)
|
||||
{
|
||||
if (xTypes[j] == t)
|
||||
break;
|
||||
}
|
||||
if (j == numTypes)
|
||||
{
|
||||
xTypes[numTypes++] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (numTypes > 0)
|
||||
{
|
||||
/*
|
||||
* We can supply one or more types of data to the requestor so
|
||||
* we will give it a list of the types supported.
|
||||
*/
|
||||
xTypes[numTypes++] = XG_TARGETS;
|
||||
xTypes[numTypes++] = XG_TIMESTAMP;
|
||||
xTypes[numTypes++] = XG_MULTIPLE;
|
||||
// FIXME: ICCCM requires even more types from us.
|
||||
|
||||
if ([types containsObject: NSStringPboardType])
|
||||
{
|
||||
xTypes[numTypes++] = XG_UTF8_STRING;
|
||||
xTypes[numTypes++] = XG_COMPOUND_TEXT;
|
||||
xTypes[numTypes++] = XA_STRING;
|
||||
xTypes[numTypes++] = XG_TEXT;
|
||||
}
|
||||
|
||||
if ([types containsObject: NSFilenamesPboardType])
|
||||
{
|
||||
xTypes[numTypes++] = XG_FILE_NAME;
|
||||
}
|
||||
|
||||
xType = XA_ATOM;
|
||||
format = 32;
|
||||
numItems = numTypes;
|
||||
data = malloc(numTypes*sizeof(Atom));
|
||||
memcpy(data, xTypes, numTypes*sizeof(Atom));
|
||||
numItems = numTypes;
|
||||
}
|
||||
else if (xEvent->target == XG_TIMESTAMP)
|
||||
{
|
||||
xType = XA_INTEGER;
|
||||
format = 32;
|
||||
numItems = 1;
|
||||
data = malloc(sizeof(int));
|
||||
memcpy(data, &_timeOfSetSelectionOwner, sizeof(int));
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* No OS types that are convertable to X types.
|
||||
*/
|
||||
xType = XG_NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xEvent->target == AnyPropertyType)
|
||||
else if (xEvent->target == AnyPropertyType)
|
||||
{
|
||||
/*
|
||||
* The requestor will accept any type of data - so we use the first
|
||||
* OpenStep type that corresponds to a known X type.
|
||||
*/
|
||||
for (i = 0; i < numOsTypes; i++)
|
||||
if ([types containsObject: NSStringPboardType])
|
||||
{
|
||||
NSString *type = [types objectAtIndex: i];
|
||||
Atom t = osTypeToX(type);
|
||||
xEvent->target = XG_UTF8_STRING;
|
||||
[self xProvideSelection: xEvent];
|
||||
}
|
||||
else if ([types containsObject: NSFilenamesPboardType])
|
||||
{
|
||||
xEvent->target = XG_FILE_NAME;
|
||||
[self xProvideSelection: xEvent];
|
||||
}
|
||||
}
|
||||
else if (xEvent->target == XG_MULTIPLE)
|
||||
{
|
||||
if (xEvent->property != None)
|
||||
{
|
||||
Atom *multipleAtoms= NULL;
|
||||
int actual_format;
|
||||
Atom actual_type;
|
||||
unsigned long number_items, bytes_remaining;
|
||||
int status;
|
||||
|
||||
if (t != XG_NULL)
|
||||
status = XGetWindowProperty(xDisplay,
|
||||
xEvent->requestor,
|
||||
xEvent->property,
|
||||
0,
|
||||
100,
|
||||
False,
|
||||
AnyPropertyType,
|
||||
&actual_type,
|
||||
&actual_format,
|
||||
&number_items,
|
||||
&bytes_remaining,
|
||||
(unsigned char **)&multipleAtoms);
|
||||
if ((status == Success) && (bytes_remaining == 0) &&
|
||||
(actual_format == 32) && (actual_type == XA_ATOM))
|
||||
{
|
||||
osType = type;
|
||||
xType = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
int i;
|
||||
XSelectionRequestEvent requestEvent;
|
||||
|
||||
memcpy(&requestEvent, xEvent, sizeof(XSelectionRequestEvent));
|
||||
for (i = 0; i < number_items; i += 2)
|
||||
{
|
||||
// A fixed type was requested.
|
||||
requestEvent.target= multipleAtoms[i];
|
||||
requestEvent.property= multipleAtoms[i+1];
|
||||
if (requestEvent.target != None)
|
||||
{
|
||||
// Recursive call to this method for each pair.
|
||||
if (![self xProvideSelection: &requestEvent])
|
||||
{
|
||||
multipleAtoms[i+1]= None;
|
||||
}
|
||||
}
|
||||
}
|
||||
// FIXME: Should we call XChangeProperty to set the invalid types?
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((xEvent->target == XG_COMPOUND_TEXT) &&
|
||||
[types containsObject: NSStringPboardType])
|
||||
{
|
||||
NSString *s = [_pb stringForType: NSStringPboardType];
|
||||
const char *d;
|
||||
int status;
|
||||
|
||||
xType = XG_COMPOUND_TEXT;
|
||||
format = 8;
|
||||
d = [s cString];
|
||||
if (d)
|
||||
{
|
||||
char *list[]= {(char *)d, NULL};
|
||||
XTextProperty textProperty;
|
||||
|
||||
status = XmbTextListToTextProperty(xEvent->display, list, 1,
|
||||
XCompoundTextStyle, &textProperty);
|
||||
if (status == Success)
|
||||
{
|
||||
numItems = textProperty.nitems;
|
||||
data = malloc(numItems);
|
||||
memcpy(data, textProperty.value, 1);
|
||||
XFree((void *)textProperty.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (((xEvent->target == XG_UTF8_STRING) ||
|
||||
(xEvent->target == XA_STRING) ||
|
||||
(xEvent->target == XG_TEXT)) &&
|
||||
[types containsObject: NSStringPboardType])
|
||||
{
|
||||
NSString *s = [_pb stringForType: NSStringPboardType];
|
||||
NSData *d;
|
||||
|
||||
xType = xEvent->target;
|
||||
/*
|
||||
* Find an available OpenStep pasteboard type that corresponds
|
||||
* to the requested X type.
|
||||
*/
|
||||
for (i = 0; i < numOsTypes; i++)
|
||||
{
|
||||
NSString *type = [types objectAtIndex: i];
|
||||
Atom t = osTypeToX(type);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
format = 8;
|
||||
|
||||
/*
|
||||
* Now we know what type of data is required - so get it from the
|
||||
* pasteboard and convert to a format X can understand.
|
||||
*/
|
||||
if (osType != nil)
|
||||
{
|
||||
if ([osType isEqualToString: NSStringPboardType])
|
||||
{
|
||||
NSString *s = [_pb stringForType: NSStringPboardType];
|
||||
NSData *d;
|
||||
|
||||
if (xType == XG_UTF8_STRING)
|
||||
{
|
||||
d = [s dataUsingEncoding: NSUTF8StringEncoding];
|
||||
}
|
||||
else
|
||||
else if ((xType == XA_STRING) || (xType == XG_TEXT))
|
||||
{
|
||||
d = [s dataUsingEncoding: NSISOLatin1StringEncoding];
|
||||
}
|
||||
|
||||
format = 8;
|
||||
if (d != nil)
|
||||
{
|
||||
numItems = [d length];
|
||||
|
@ -932,11 +1019,17 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
|||
[d getBytes: data];
|
||||
}
|
||||
}
|
||||
else if ((xEvent->target == XG_FILE_NAME) &&
|
||||
[types containsObject: NSFilenamesPboardType])
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Trying to convert from unsupported type - '%@'", osType);
|
||||
}
|
||||
}
|
||||
char *name = XGetAtomName(xDisplay, xEvent->target);
|
||||
|
||||
NSLog(@"Request for unsupported data type '%s'.", name);
|
||||
XFree(name);
|
||||
return NO;
|
||||
}
|
||||
|
||||
return [self xSendData: data format: format items: numItems type: xType
|
||||
|
@ -978,7 +1071,7 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
|||
pos += maxItems;
|
||||
XSync(xDisplay, False);
|
||||
}
|
||||
XFree(data);
|
||||
free(data);
|
||||
XSetErrorHandler(oldHandler);
|
||||
if (appendFailure == NO)
|
||||
{
|
||||
|
@ -988,7 +1081,7 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
|||
return status;
|
||||
}
|
||||
|
||||
- (Time) xTimeByAppending: (Atom)defaultType
|
||||
- (Time) xTimeByAppending
|
||||
{
|
||||
NSDate *limit;
|
||||
Time whenRequested;
|
||||
|
@ -1013,8 +1106,8 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
|||
* The property doesn't exist - so we will be creating a new (empty)
|
||||
* property.
|
||||
*/
|
||||
actualType = defaultType;
|
||||
actualFormat = 8;
|
||||
actualType = XA_ATOM;
|
||||
actualFormat = 32;
|
||||
}
|
||||
|
||||
XChangeProperty(xDisplay, xAppWin, [self xPb], actualType, actualFormat,
|
||||
|
@ -1082,6 +1175,7 @@ pasteboardTypeForMimeType(Display *xDisplay, NSZone *zone, Atom *typelist)
|
|||
{
|
||||
[newTypes addObject: [NSPasteboard pasteboardTypeForMimeType:
|
||||
[NSString stringWithCString: s]]];
|
||||
XFree(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue