mirror of
https://github.com/gnustep/libs-back.git
synced 2025-05-30 17:00:52 +00:00
Add more EWMH methods and helper methods.
Simplify dragging support code. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@25389 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
0dd2da6751
commit
32d116c7b2
3 changed files with 1198 additions and 783 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2007-08-15 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
|
* Source/x11/XGServerWindow.m: Add more EWMH methods and helper
|
||||||
|
methods for them.
|
||||||
|
* Tools/xpbs.m: Simplify dragging support code.
|
||||||
|
|
||||||
2007-08-13 Fred Kiefer <FredKiefer@gmx.de>
|
2007-08-13 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
* Source/art/ftfont.m (-coveredCharacterSet): Correct code.
|
* Source/art/ftfont.m (-coveredCharacterSet): Correct code.
|
||||||
|
|
File diff suppressed because it is too large
Load diff
621
Tools/xpbs.m
621
Tools/xpbs.m
|
@ -34,7 +34,7 @@
|
||||||
/*
|
/*
|
||||||
* Non-predefined atoms that are used in the X selection mechanism
|
* Non-predefined atoms that are used in the X selection mechanism
|
||||||
*/
|
*/
|
||||||
static char* atom_names[] = {
|
static char *atom_names[] = {
|
||||||
"CHARACTER_POSITION",
|
"CHARACTER_POSITION",
|
||||||
"CLIENT_WINDOW",
|
"CLIENT_WINDOW",
|
||||||
"HOST_NAME",
|
"HOST_NAME",
|
||||||
|
@ -54,7 +54,17 @@ static char* atom_names[] = {
|
||||||
"UTF8_STRING",
|
"UTF8_STRING",
|
||||||
"MULTIPLE",
|
"MULTIPLE",
|
||||||
"COMPOUND_TEXT",
|
"COMPOUND_TEXT",
|
||||||
"INCR"
|
"INCR",
|
||||||
|
|
||||||
|
// MIME types
|
||||||
|
"text/plain",
|
||||||
|
"text/uri-list",
|
||||||
|
"application/postscript",
|
||||||
|
"text/tab-separated-values",
|
||||||
|
"text/richtext",
|
||||||
|
"image/tiff",
|
||||||
|
"application/octet-stream",
|
||||||
|
"application/x-rootwindow-drop"
|
||||||
};
|
};
|
||||||
static Atom atoms[sizeof(atom_names)/sizeof(char*)];
|
static Atom atoms[sizeof(atom_names)/sizeof(char*)];
|
||||||
|
|
||||||
|
@ -82,6 +92,8 @@ static Atom atoms[sizeof(atom_names)/sizeof(char*)];
|
||||||
#define XG_MULTIPLE atoms[17]
|
#define XG_MULTIPLE atoms[17]
|
||||||
#define XG_COMPOUND_TEXT atoms[18]
|
#define XG_COMPOUND_TEXT atoms[18]
|
||||||
#define XG_INCR atoms[19]
|
#define XG_INCR atoms[19]
|
||||||
|
#define XG_MIME_PLAIN atoms[20]
|
||||||
|
#define XG_MIME_URI atoms[21]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -274,38 +286,38 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
||||||
while ((count = XPending(xDisplay)) > 0)
|
while ((count = XPending(xDisplay)) > 0)
|
||||||
{
|
{
|
||||||
while (count-- > 0)
|
while (count-- > 0)
|
||||||
{
|
{
|
||||||
XEvent xEvent;
|
XEvent xEvent;
|
||||||
|
|
||||||
XNextEvent(xDisplay, &xEvent);
|
XNextEvent(xDisplay, &xEvent);
|
||||||
|
|
||||||
|
switch (xEvent.type)
|
||||||
|
{
|
||||||
|
case PropertyNotify:
|
||||||
|
[self xPropertyNotify: (XPropertyEvent*)&xEvent];
|
||||||
|
NSDebugLLog(@"Pbs", @"PropertyNotify.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SelectionNotify:
|
||||||
|
[self xSelectionNotify: (XSelectionEvent*)&xEvent];
|
||||||
|
NSDebugLLog(@"Pbs", @"SelectionNotify.");
|
||||||
|
break;
|
||||||
|
|
||||||
switch (xEvent.type)
|
case SelectionClear:
|
||||||
{
|
[self xSelectionClear: (XSelectionClearEvent*)&xEvent];
|
||||||
case PropertyNotify:
|
NSDebugLLog(@"Pbs", @"SelectionClear.");
|
||||||
[self xPropertyNotify: (XPropertyEvent*)&xEvent];
|
break;
|
||||||
NSDebugLLog(@"Pbs", @"PropertyNotify.");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SelectionNotify:
|
case SelectionRequest:
|
||||||
[self xSelectionNotify: (XSelectionEvent*)&xEvent];
|
[self xSelectionRequest: (XSelectionRequestEvent*)&xEvent];
|
||||||
NSDebugLLog(@"Pbs", @"SelectionNotify.");
|
NSDebugLLog(@"Pbs", @"SelectionRequest.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SelectionClear:
|
default:
|
||||||
[self xSelectionClear: (XSelectionClearEvent*)&xEvent];
|
NSDebugLLog(@"Pbs", @"Unexpected X event.");
|
||||||
NSDebugLLog(@"Pbs", @"SelectionClear.");
|
break;
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
case SelectionRequest:
|
|
||||||
[self xSelectionRequest: (XSelectionRequestEvent*)&xEvent];
|
|
||||||
NSDebugLLog(@"Pbs", @"SelectionRequest.");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
NSDebugLLog(@"Pbs", @"Unexpected X event.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +344,7 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
||||||
char *name = XGetAtomName(xDisplay, xEvent->selection);
|
char *name = XGetAtomName(xDisplay, xEvent->selection);
|
||||||
|
|
||||||
NSDebugLLog(@"Pbs", @"Selection clear for unknown selection - '%s'.",
|
NSDebugLLog(@"Pbs", @"Selection clear for unknown selection - '%s'.",
|
||||||
name);
|
name);
|
||||||
XFree(name);
|
XFree(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -355,7 +367,7 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
||||||
{
|
{
|
||||||
char *name = XGetAtomName(xDisplay, xEvent->atom);
|
char *name = XGetAtomName(xDisplay, xEvent->atom);
|
||||||
NSDebugLLog(@"Pbs", @"Property notify for unknown property - '%s'.",
|
NSDebugLLog(@"Pbs", @"Property notify for unknown property - '%s'.",
|
||||||
name);
|
name);
|
||||||
XFree(name);
|
XFree(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -374,14 +386,14 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
||||||
|
|
||||||
+ (void) xSelectionNotify: (XSelectionEvent*)xEvent
|
+ (void) xSelectionNotify: (XSelectionEvent*)xEvent
|
||||||
{
|
{
|
||||||
XPbOwner *o;
|
XPbOwner *o;
|
||||||
|
|
||||||
o = [self ownerByXPb: xEvent->selection];
|
o = [self ownerByXPb: xEvent->selection];
|
||||||
if (o == nil)
|
if (o == nil)
|
||||||
{
|
{
|
||||||
char *name = XGetAtomName(xDisplay, xEvent->selection);
|
char *name = XGetAtomName(xDisplay, xEvent->selection);
|
||||||
NSDebugLLog(@"Pbs", @"Selection notify for unknown selection - '%s'.",
|
NSDebugLLog(@"Pbs", @"Selection notify for unknown selection - '%s'.",
|
||||||
name);
|
name);
|
||||||
XFree(name);
|
XFree(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -393,19 +405,19 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *sel_name = XGetAtomName(xDisplay, xEvent->selection);
|
char *sel_name = XGetAtomName(xDisplay, xEvent->selection);
|
||||||
char *pro_name;
|
char *pro_name;
|
||||||
|
|
||||||
|
if (xEvent->property == None)
|
||||||
|
pro_name = NULL;
|
||||||
|
else
|
||||||
|
pro_name = XGetAtomName(xDisplay, xEvent->property);
|
||||||
|
|
||||||
if (xEvent->property == None)
|
NSDebugLLog(@"Pbs", @"Selection (%s) notify - '%s'.", sel_name,
|
||||||
pro_name = NULL;
|
pro_name? pro_name : "None");
|
||||||
else
|
XFree(sel_name);
|
||||||
pro_name = XGetAtomName(xDisplay, xEvent->property);
|
if (pro_name)
|
||||||
|
XFree(pro_name);
|
||||||
NSDebugLLog(@"Pbs", @"Selection (%s) notify - '%s'.", sel_name,
|
|
||||||
pro_name? pro_name : "None");
|
|
||||||
XFree(sel_name);
|
|
||||||
if (pro_name)
|
|
||||||
XFree(pro_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[o xSelectionNotify: xEvent];
|
[o xSelectionNotify: xEvent];
|
||||||
|
@ -420,7 +432,7 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
||||||
{
|
{
|
||||||
char *name = XGetAtomName(xDisplay, xEvent->selection);
|
char *name = XGetAtomName(xDisplay, xEvent->selection);
|
||||||
NSDebugLLog(@"Pbs", @"Selection request for unknown selection - '%s'.",
|
NSDebugLLog(@"Pbs", @"Selection request for unknown selection - '%s'.",
|
||||||
name);
|
name);
|
||||||
XFree(name);
|
XFree(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -505,7 +517,7 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
||||||
|
|
||||||
- (void) requestData: (Atom)xType
|
- (void) requestData: (Atom)xType
|
||||||
{
|
{
|
||||||
Time whenRequested;
|
Time whenRequested;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do a nul append to a property to get a timestamp, if it returns the
|
* Do a nul append to a property to get a timestamp, if it returns the
|
||||||
|
@ -514,7 +526,7 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
||||||
whenRequested = [self xTimeByAppending];
|
whenRequested = [self xTimeByAppending];
|
||||||
if (whenRequested != CurrentTime)
|
if (whenRequested != CurrentTime)
|
||||||
{
|
{
|
||||||
NSDate *limit;
|
NSDate *limit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ok - we got a timestamp, so we can ask the selection system for
|
* Ok - we got a timestamp, so we can ask the selection system for
|
||||||
|
@ -523,7 +535,7 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
||||||
* appropriate property of our application root window.
|
* appropriate property of our application root window.
|
||||||
*/
|
*/
|
||||||
XConvertSelection(xDisplay, [self xPb], xType,
|
XConvertSelection(xDisplay, [self xPb], xType,
|
||||||
[self xPb], xAppWin, whenRequested);
|
[self xPb], xAppWin, whenRequested);
|
||||||
XFlush(xDisplay);
|
XFlush(xDisplay);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -534,19 +546,19 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
||||||
[self setWaitingForSelection: whenRequested];
|
[self setWaitingForSelection: whenRequested];
|
||||||
while ([self waitingForSelection] == whenRequested)
|
while ([self waitingForSelection] == whenRequested)
|
||||||
{
|
{
|
||||||
[[NSRunLoop currentRunLoop] runMode: xWaitMode
|
[[NSRunLoop currentRunLoop] runMode: xWaitMode
|
||||||
beforeDate: limit];
|
beforeDate: limit];
|
||||||
if ([limit timeIntervalSinceNow] <= 0.0)
|
if ([limit timeIntervalSinceNow] <= 0.0)
|
||||||
break; /* Timeout */
|
break; /* Timeout */
|
||||||
}
|
}
|
||||||
if ([self waitingForSelection] != 0)
|
if ([self waitingForSelection] != 0)
|
||||||
{
|
{
|
||||||
char *name = XGetAtomName(xDisplay, xType);
|
char *name = XGetAtomName(xDisplay, xType);
|
||||||
|
|
||||||
[self setWaitingForSelection: 0];
|
[self setWaitingForSelection: 0];
|
||||||
NSLog(@"Timed out waiting for X selection '%s'", name);
|
NSLog(@"Timed out waiting for X selection '%s'", name);
|
||||||
XFree(name);
|
XFree(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,8 +575,13 @@ static NSString *xWaitMode = @"XPasteboardWaitMode";
|
||||||
{
|
{
|
||||||
[self requestData: XG_UTF8_STRING];
|
[self requestData: XG_UTF8_STRING];
|
||||||
if ([self data] == nil)
|
if ([self data] == nil)
|
||||||
[self requestData: XA_STRING];
|
[self requestData: XA_STRING];
|
||||||
}
|
}
|
||||||
|
else if ([type isEqual: NSFilenamesPboardType])
|
||||||
|
{
|
||||||
|
[self requestData: XG_FILE_NAME];
|
||||||
|
}
|
||||||
|
// FIXME: Support more types
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSLog(@"Request for non-string info from X pasteboard: %@", type);
|
NSLog(@"Request for non-string info from X pasteboard: %@", type);
|
||||||
|
@ -630,7 +647,7 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSMutableData*) getSelectionData: (XSelectionEvent*)xEvent
|
- (NSMutableData*) getSelectionData: (XSelectionEvent*)xEvent
|
||||||
type: (Atom*)type
|
type: (Atom*)type
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
@ -649,51 +666,51 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
status = XGetWindowProperty(xDisplay,
|
status = XGetWindowProperty(xDisplay,
|
||||||
xEvent->requestor,
|
xEvent->requestor,
|
||||||
xEvent->property,
|
xEvent->property,
|
||||||
long_offset, // offset
|
long_offset, // offset
|
||||||
long_length,
|
long_length,
|
||||||
True, // Delete prop when read.
|
True, // Delete prop when read.
|
||||||
req_type,
|
req_type,
|
||||||
&actual_type,
|
&actual_type,
|
||||||
&actual_format,
|
&actual_format,
|
||||||
&number_items,
|
&number_items,
|
||||||
&bytes_remaining,
|
&bytes_remaining,
|
||||||
&data);
|
&data);
|
||||||
|
|
||||||
if ((status == Success) && (number_items > 0))
|
if ((status == Success) && (number_items > 0))
|
||||||
{
|
{
|
||||||
long count = number_items * actual_format / 8;
|
long count = number_items * actual_format / 8;
|
||||||
|
|
||||||
if (md == nil)
|
if (md == nil)
|
||||||
{
|
{
|
||||||
md = [[NSMutableData alloc] initWithBytes: (void *)data
|
md = [[NSMutableData alloc] initWithBytes: (void *)data
|
||||||
length: count];
|
length: count];
|
||||||
req_type = actual_type;
|
req_type = actual_type;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (req_type != actual_type)
|
if (req_type != actual_type)
|
||||||
{
|
{
|
||||||
char *req_name = XGetAtomName(xDisplay, req_type);
|
char *req_name = XGetAtomName(xDisplay, req_type);
|
||||||
char *act_name = XGetAtomName(xDisplay, actual_type);
|
char *act_name = XGetAtomName(xDisplay, actual_type);
|
||||||
|
|
||||||
NSLog(@"Selection changed type from %s to %s.",
|
NSLog(@"Selection changed type from %s to %s.",
|
||||||
req_name, act_name);
|
req_name, act_name);
|
||||||
XFree(req_name);
|
XFree(req_name);
|
||||||
XFree(act_name);
|
XFree(act_name);
|
||||||
RELEASE(md);
|
RELEASE(md);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
[md appendBytes: (void *)data length: count];
|
[md appendBytes: (void *)data length: count];
|
||||||
}
|
}
|
||||||
|
|
||||||
long_offset += count / 4;
|
long_offset += count / 4;
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
XFree(data);
|
XFree(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while ((status == Success) && (bytes_remaining > 0));
|
while ((status == Success) && (bytes_remaining > 0));
|
||||||
|
|
||||||
|
@ -733,79 +750,99 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
||||||
if (md != nil)
|
if (md != nil)
|
||||||
{
|
{
|
||||||
if (actual_type == XG_INCR)
|
if (actual_type == XG_INCR)
|
||||||
{
|
{
|
||||||
XEvent event;
|
XEvent event;
|
||||||
NSMutableData *imd = nil;
|
NSMutableData *imd = nil;
|
||||||
BOOL wait = YES;
|
BOOL wait = YES;
|
||||||
|
|
||||||
md = nil;
|
md = nil;
|
||||||
while (wait)
|
while (wait)
|
||||||
{
|
{
|
||||||
XNextEvent(xDisplay, &event);
|
XNextEvent(xDisplay, &event);
|
||||||
|
|
||||||
if (event.type == PropertyNotify)
|
if (event.type == PropertyNotify)
|
||||||
{
|
{
|
||||||
if (event.xproperty.state != PropertyNewValue) continue;
|
if (event.xproperty.state != PropertyNewValue) continue;
|
||||||
|
|
||||||
imd = [self getSelectionData: xEvent type: &actual_type];
|
imd = [self getSelectionData: xEvent type: &actual_type];
|
||||||
if (imd != nil)
|
if (imd != nil)
|
||||||
{
|
{
|
||||||
if (md == nil)
|
if (md == nil)
|
||||||
{
|
{
|
||||||
md = imd;
|
md = imd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[md appendData: imd];
|
[md appendData: imd];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wait = NO;
|
wait = NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (md != nil)
|
if (md != nil)
|
||||||
{
|
{
|
||||||
// Convert data to text string.
|
// Convert data to text string.
|
||||||
if (actual_type == XG_UTF8_STRING)
|
if (actual_type == XG_UTF8_STRING)
|
||||||
{
|
{
|
||||||
NSString *s;
|
NSString *s;
|
||||||
NSData *d;
|
NSData *d;
|
||||||
|
|
||||||
s = [[NSString alloc] initWithData: md
|
s = [[NSString alloc] initWithData: md
|
||||||
encoding: NSUTF8StringEncoding];
|
encoding: NSUTF8StringEncoding];
|
||||||
if (s != nil)
|
if (s != nil)
|
||||||
{
|
{
|
||||||
d = [NSSerializer serializePropertyList: s];
|
d = [NSSerializer serializePropertyList: s];
|
||||||
RELEASE(s);
|
RELEASE(s);
|
||||||
[self setData: d];
|
[self setData: d];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (actual_type == XA_STRING)
|
else if (actual_type == XA_STRING)
|
||||||
{
|
{
|
||||||
NSString *s;
|
NSString *s;
|
||||||
NSData *d;
|
NSData *d;
|
||||||
|
|
||||||
|
s = [[NSString alloc] initWithData: md
|
||||||
|
encoding: NSISOLatin1StringEncoding];
|
||||||
|
if (s != nil)
|
||||||
|
{
|
||||||
|
d = [NSSerializer serializePropertyList: s];
|
||||||
|
RELEASE(s);
|
||||||
|
[self setData: d];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (actual_type == XG_FILE_NAME)
|
||||||
|
{
|
||||||
|
NSArray *names;
|
||||||
|
NSData *d;
|
||||||
|
NSString *s;
|
||||||
|
NSURL *url;
|
||||||
|
|
||||||
s = [[NSString alloc] initWithData: md
|
s = [[NSString alloc] initWithData: md
|
||||||
encoding: NSISOLatin1StringEncoding];
|
encoding: NSUTF8StringEncoding];
|
||||||
if (s != nil)
|
url = [[NSURL alloc] initWithString: s];
|
||||||
{
|
RELEASE(s);
|
||||||
d = [NSSerializer serializePropertyList: s];
|
if ([url isFileURL])
|
||||||
RELEASE(s);
|
{
|
||||||
[self setData: d];
|
s = [url path];
|
||||||
}
|
names = [NSArray arrayWithObject: s];
|
||||||
}
|
d = [NSSerializer serializePropertyList: names];
|
||||||
|
[self setData: d];
|
||||||
|
}
|
||||||
|
RELEASE(url);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *name = XGetAtomName(xDisplay, actual_type);
|
char *name = XGetAtomName(xDisplay, actual_type);
|
||||||
|
|
||||||
NSLog(@"Unsupported data type '%s' from X selection.", name);
|
NSLog(@"Unsupported data type '%s' from X selection.", name);
|
||||||
XFree(name);
|
XFree(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -873,16 +910,16 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
||||||
|
|
||||||
if ([types containsObject: NSStringPboardType])
|
if ([types containsObject: NSStringPboardType])
|
||||||
{
|
{
|
||||||
xTypes[numTypes++] = XG_UTF8_STRING;
|
xTypes[numTypes++] = XG_UTF8_STRING;
|
||||||
xTypes[numTypes++] = XG_COMPOUND_TEXT;
|
xTypes[numTypes++] = XG_COMPOUND_TEXT;
|
||||||
xTypes[numTypes++] = XA_STRING;
|
xTypes[numTypes++] = XA_STRING;
|
||||||
xTypes[numTypes++] = XG_TEXT;
|
xTypes[numTypes++] = XG_TEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([types containsObject: NSFilenamesPboardType])
|
if ([types containsObject: NSFilenamesPboardType])
|
||||||
{
|
{
|
||||||
xTypes[numTypes++] = XG_FILE_NAME;
|
xTypes[numTypes++] = XG_FILE_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
xType = XA_ATOM;
|
xType = XA_ATOM;
|
||||||
format = 32;
|
format = 32;
|
||||||
|
@ -906,59 +943,59 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
||||||
*/
|
*/
|
||||||
if ([types containsObject: NSStringPboardType])
|
if ([types containsObject: NSStringPboardType])
|
||||||
{
|
{
|
||||||
xEvent->target = XG_UTF8_STRING;
|
xEvent->target = XG_UTF8_STRING;
|
||||||
[self xProvideSelection: xEvent];
|
[self xProvideSelection: xEvent];
|
||||||
}
|
}
|
||||||
else if ([types containsObject: NSFilenamesPboardType])
|
else if ([types containsObject: NSFilenamesPboardType])
|
||||||
{
|
{
|
||||||
xEvent->target = XG_FILE_NAME;
|
xEvent->target = XG_FILE_NAME;
|
||||||
[self xProvideSelection: xEvent];
|
[self xProvideSelection: xEvent];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (xEvent->target == XG_MULTIPLE)
|
else if (xEvent->target == XG_MULTIPLE)
|
||||||
{
|
{
|
||||||
if (xEvent->property != None)
|
if (xEvent->property != None)
|
||||||
{
|
{
|
||||||
Atom *multipleAtoms= NULL;
|
Atom *multipleAtoms= NULL;
|
||||||
int actual_format;
|
int actual_format;
|
||||||
Atom actual_type;
|
Atom actual_type;
|
||||||
unsigned long number_items, bytes_remaining;
|
unsigned long number_items, bytes_remaining;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = XGetWindowProperty(xDisplay,
|
status = XGetWindowProperty(xDisplay,
|
||||||
xEvent->requestor,
|
xEvent->requestor,
|
||||||
xEvent->property,
|
xEvent->property,
|
||||||
0,
|
0,
|
||||||
100,
|
100,
|
||||||
False,
|
False,
|
||||||
AnyPropertyType,
|
AnyPropertyType,
|
||||||
&actual_type,
|
&actual_type,
|
||||||
&actual_format,
|
&actual_format,
|
||||||
&number_items,
|
&number_items,
|
||||||
&bytes_remaining,
|
&bytes_remaining,
|
||||||
(unsigned char **)&multipleAtoms);
|
(unsigned char **)&multipleAtoms);
|
||||||
if ((status == Success) && (bytes_remaining == 0) &&
|
if ((status == Success) && (bytes_remaining == 0) &&
|
||||||
(actual_format == 32) && (actual_type == XA_ATOM))
|
(actual_format == 32) && (actual_type == XA_ATOM))
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
XSelectionRequestEvent requestEvent;
|
XSelectionRequestEvent requestEvent;
|
||||||
|
|
||||||
memcpy(&requestEvent, xEvent, sizeof(XSelectionRequestEvent));
|
memcpy(&requestEvent, xEvent, sizeof(XSelectionRequestEvent));
|
||||||
for (i = 0; i < number_items; i += 2)
|
for (i = 0; i < number_items; i += 2)
|
||||||
{
|
{
|
||||||
requestEvent.target= multipleAtoms[i];
|
requestEvent.target= multipleAtoms[i];
|
||||||
requestEvent.property= multipleAtoms[i+1];
|
requestEvent.property= multipleAtoms[i+1];
|
||||||
if (requestEvent.target != None)
|
if (requestEvent.target != None)
|
||||||
{
|
{
|
||||||
// Recursive call to this method for each pair.
|
// Recursive call to this method for each pair.
|
||||||
if (![self xProvideSelection: &requestEvent])
|
if (![self xProvideSelection: &requestEvent])
|
||||||
{
|
{
|
||||||
multipleAtoms[i+1]= None;
|
multipleAtoms[i+1]= None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FIXME: Should we call XChangeProperty to set the invalid types?
|
// FIXME: Should we call XChangeProperty to set the invalid types?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((xEvent->target == XG_COMPOUND_TEXT) &&
|
else if ((xEvent->target == XG_COMPOUND_TEXT) &&
|
||||||
|
@ -973,25 +1010,25 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
||||||
d = [s cString];
|
d = [s cString];
|
||||||
if (d)
|
if (d)
|
||||||
{
|
{
|
||||||
char *list[]= {(char *)d, NULL};
|
char *list[]= {(char *)d, NULL};
|
||||||
XTextProperty textProperty;
|
XTextProperty textProperty;
|
||||||
|
|
||||||
status = XmbTextListToTextProperty(xEvent->display, list, 1,
|
status = XmbTextListToTextProperty(xEvent->display, list, 1,
|
||||||
XCompoundTextStyle, &textProperty);
|
XCompoundTextStyle, &textProperty);
|
||||||
if (status == Success)
|
if (status == Success)
|
||||||
{
|
{
|
||||||
NSAssert(textProperty.format == 8, @"textProperty.format == 8");
|
NSAssert(textProperty.format == 8, @"textProperty.format == 8");
|
||||||
numItems = textProperty.nitems;
|
numItems = textProperty.nitems;
|
||||||
data = malloc(numItems + 1);
|
data = malloc(numItems + 1);
|
||||||
memcpy(data, textProperty.value, numItems + 1);
|
memcpy(data, textProperty.value, numItems + 1);
|
||||||
XFree((void *)textProperty.value);
|
XFree((void *)textProperty.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (((xEvent->target == XG_UTF8_STRING) ||
|
else if (((xEvent->target == XG_UTF8_STRING) ||
|
||||||
(xEvent->target == XA_STRING) ||
|
(xEvent->target == XA_STRING) ||
|
||||||
(xEvent->target == XG_TEXT)) &&
|
(xEvent->target == XG_TEXT)) &&
|
||||||
[types containsObject: NSStringPboardType])
|
[types containsObject: NSStringPboardType])
|
||||||
{
|
{
|
||||||
NSString *s = [_pb stringForType: NSStringPboardType];
|
NSString *s = [_pb stringForType: NSStringPboardType];
|
||||||
NSData *d = nil;
|
NSData *d = nil;
|
||||||
|
@ -1005,24 +1042,43 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
||||||
*/
|
*/
|
||||||
if (xType == XG_UTF8_STRING)
|
if (xType == XG_UTF8_STRING)
|
||||||
{
|
{
|
||||||
d = [s dataUsingEncoding: NSUTF8StringEncoding];
|
d = [s dataUsingEncoding: NSUTF8StringEncoding];
|
||||||
}
|
}
|
||||||
else if ((xType == XA_STRING) || (xType == XG_TEXT))
|
else if ((xType == XA_STRING) || (xType == XG_TEXT))
|
||||||
{
|
{
|
||||||
d = [s dataUsingEncoding: NSISOLatin1StringEncoding];
|
d = [s dataUsingEncoding: NSISOLatin1StringEncoding];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d != nil)
|
if (d != nil)
|
||||||
{
|
{
|
||||||
numItems = [d length];
|
numItems = [d length];
|
||||||
data = malloc(numItems + 1);
|
data = malloc(numItems + 1);
|
||||||
if (data)
|
if (data)
|
||||||
[d getBytes: data];
|
[d getBytes: data];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((xEvent->target == XG_FILE_NAME) &&
|
else if ((xEvent->target == XG_FILE_NAME) &&
|
||||||
[types containsObject: NSFilenamesPboardType])
|
[types containsObject: NSFilenamesPboardType])
|
||||||
{
|
{
|
||||||
|
NSArray *names = [_pb propertyListForType: NSFilenamesPboardType];
|
||||||
|
NSString *file = [[names lastObject] stringByStandardizingPath];
|
||||||
|
NSURL *url = [[NSURL alloc] initWithScheme: NSURLFileScheme
|
||||||
|
host: @"localhost"
|
||||||
|
path: file];
|
||||||
|
NSString *s = [url absoluteString];
|
||||||
|
NSData *d;
|
||||||
|
|
||||||
|
xType = xEvent->target;
|
||||||
|
format = 8;
|
||||||
|
RELEASE(url);
|
||||||
|
d = [s dataUsingEncoding: NSISOLatin1StringEncoding];
|
||||||
|
if (d != nil)
|
||||||
|
{
|
||||||
|
numItems = [d length];
|
||||||
|
data = malloc(numItems + 1);
|
||||||
|
if (data)
|
||||||
|
[d getBytes: data];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1034,12 +1090,12 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return [self xSendData: data format: format items: numItems type: xType
|
return [self xSendData: data format: format items: numItems type: xType
|
||||||
to: xEvent->requestor property: xEvent->property];
|
to: xEvent->requestor property: xEvent->property];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) xSendData: (unsigned char*) data format: (int) format
|
- (BOOL) xSendData: (unsigned char*) data format: (int) format
|
||||||
items: (int) numItems type: (Atom) xType
|
items: (int) numItems type: (Atom) xType
|
||||||
to: (Window) window property: (Atom) property
|
to: (Window) window property: (Atom) property
|
||||||
{
|
{
|
||||||
BOOL status = NO;
|
BOOL status = NO;
|
||||||
|
|
||||||
|
@ -1061,23 +1117,23 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
||||||
oldHandler = XSetErrorHandler(xErrorHandler);
|
oldHandler = XSetErrorHandler(xErrorHandler);
|
||||||
|
|
||||||
while (appendFailure == NO && pos < numItems)
|
while (appendFailure == NO && pos < numItems)
|
||||||
{
|
{
|
||||||
if (pos + maxItems > numItems)
|
if (pos + maxItems > numItems)
|
||||||
{
|
{
|
||||||
maxItems = numItems - pos;
|
maxItems = numItems - pos;
|
||||||
}
|
}
|
||||||
XChangeProperty(xDisplay, window, property,
|
XChangeProperty(xDisplay, window, property,
|
||||||
xType, format, mode, &data[pos*format/8], maxItems);
|
xType, format, mode, &data[pos*format/8], maxItems);
|
||||||
mode = PropModeAppend;
|
mode = PropModeAppend;
|
||||||
pos += maxItems;
|
pos += maxItems;
|
||||||
XSync(xDisplay, False);
|
XSync(xDisplay, False);
|
||||||
}
|
}
|
||||||
free(data);
|
free(data);
|
||||||
XSetErrorHandler(oldHandler);
|
XSetErrorHandler(oldHandler);
|
||||||
if (appendFailure == NO)
|
if (appendFailure == NO)
|
||||||
{
|
{
|
||||||
status = YES;
|
status = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -1125,7 +1181,7 @@ xErrorHandler(Display *d, XErrorEvent *e)
|
||||||
[[NSRunLoop currentRunLoop] runMode: xWaitMode
|
[[NSRunLoop currentRunLoop] runMode: xWaitMode
|
||||||
beforeDate: limit];
|
beforeDate: limit];
|
||||||
if ([limit timeIntervalSinceNow] <= 0.0)
|
if ([limit timeIntervalSinceNow] <= 0.0)
|
||||||
break; /* Timeout */
|
break; /* Timeout */
|
||||||
}
|
}
|
||||||
if ((whenRequested = [self timeOfLastAppend]) == 0)
|
if ((whenRequested = [self timeOfLastAppend]) == 0)
|
||||||
{
|
{
|
||||||
|
@ -1204,12 +1260,7 @@ static DndClass dnd;
|
||||||
NSArray *types;
|
NSArray *types;
|
||||||
Atom *typelist;
|
Atom *typelist;
|
||||||
|
|
||||||
// Some GNUstep application did grap the drag pasteboard. Report this to X.
|
[super pasteboardChangedOwner: sender];
|
||||||
if (xdnd_set_selection_owner(&dnd, xAppWin, None))
|
|
||||||
{
|
|
||||||
NSLog(@"Failed to set X drag selection owner to the pasteboard server.");
|
|
||||||
}
|
|
||||||
[self setOwnedByOpenStep: YES];
|
|
||||||
|
|
||||||
// We also have to set the supported types for our window
|
// We also have to set the supported types for our window
|
||||||
types = [_pb types];
|
types = [_pb types];
|
||||||
|
@ -1237,35 +1288,9 @@ static DndClass dnd;
|
||||||
{
|
{
|
||||||
NSString *mime = [NSPasteboard mimeTypeForPasteboardType: type];
|
NSString *mime = [NSPasteboard mimeTypeForPasteboardType: type];
|
||||||
Atom mType = XInternAtom(xDisplay, [mime cString], False);
|
Atom mType = XInternAtom(xDisplay, [mime cString], False);
|
||||||
Window window;
|
|
||||||
Time whenRequested = CurrentTime;
|
|
||||||
NSDate *limit;
|
|
||||||
|
|
||||||
[self setData: nil];
|
[self setData: nil];
|
||||||
// How can we get the selection owner?
|
[self requestData: mType];
|
||||||
window = XGetSelectionOwner(xDisplay, dnd.XdndSelection);
|
|
||||||
|
|
||||||
xdnd_convert_selection(&dnd, window, xAppWin, mType);
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
[pb setData: [self data] forType: type];
|
[pb setData: [self data] forType: type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue