Add support for text/plain;charset=utf8 and improve debug logging for available types

This commit is contained in:
rfm 2024-03-05 11:36:45 +00:00
parent 145ee71f5c
commit b8933e4610

View file

@ -82,7 +82,8 @@ static char *atom_names[] = {
"image/png", "image/png",
"image/svg", "image/svg",
"application/rtf", "application/rtf",
"text/richtext" "text/richtext",
"text/plain;charset=utf-8"
}; };
static Atom atoms[sizeof(atom_names)/sizeof(char*)]; static Atom atoms[sizeof(atom_names)/sizeof(char*)];
@ -126,6 +127,60 @@ static Atom atoms[sizeof(atom_names)/sizeof(char*)];
#define XG_MIME_SVG atoms[33] #define XG_MIME_SVG atoms[33]
#define XG_MIME_APP_RTF atoms[34] #define XG_MIME_APP_RTF atoms[34]
#define XG_MIME_TEXT_RICHTEXT atoms[35] #define XG_MIME_TEXT_RICHTEXT atoms[35]
#define XG_MIME_UTF8 atoms[36]
/** Return the GNUstep pasteboard type corresponding to the given atom
* or nil if there is no corresponding type.
* As a special case, return an empty string for special pasteboard types
* that supply X system information.
*/
static NSString *
NSPasteboardTypeFromAtom(Atom type)
{
if (XG_UTF8_STRING == type
|| XA_STRING == type
|| XG_TEXT == type
|| XG_MIME_PLAIN == type
|| XG_MIME_UTF8 == type)
{
return NSStringPboardType;
}
if (XG_FILE_NAME == type)
{
return NSFilenamesPboardType;
}
if (XG_MIME_RTF == type
|| XG_MIME_APP_RTF == type
|| XG_MIME_TEXT_RICHTEXT == type)
{
return NSRTFPboardType;
}
if (XG_MIME_PNG == type)
{
return NSPasteboardTypePNG;
}
if (XG_MIME_TIFF == type)
{
return NSTIFFPboardType;
}
if (XG_TARGETS == type
|| XG_TIMESTAMP == type
|| XG_OWNER_OS == type
|| XG_USER == type
|| XG_HOST_NAME == type
|| XG_HOSTNAME == type
|| XG_MULTIPLE == type)
{
return @""; // X standard type
}
return nil; // Unsupported type
}
@ -767,6 +822,8 @@ static int xFixesEventBase;
if ([type isEqual: NSStringPboardType]) if ([type isEqual: NSStringPboardType])
{ {
[self requestData: XG_UTF8_STRING]; [self requestData: XG_UTF8_STRING];
if ([self data] == nil)
[self requestData: XG_MIME_UTF8];
if ([self data] == nil) if ([self data] == nil)
[self requestData: XA_STRING]; [self requestData: XA_STRING];
if ([self data] == nil) if ([self data] == nil)
@ -871,21 +928,31 @@ xErrorHandler(Display *d, XErrorEvent *e)
{ {
NSMutableArray *types; NSMutableArray *types;
NSData *data; NSData *data;
NSMutableString *txt = nil; unsigned duplicates = 0;
NSMutableString *rtf = nil; unsigned standard = 0;
NSMutableString *std = nil; unsigned unsupported = 0;
NSMutableString *bad = nil; NSMutableString *bad = nil;
unsigned int count; unsigned int count;
unsigned int i; unsigned int i;
Atom *targets; Atom *targets;
BOOL debug = GSDebugSet(@"Pbs");
NSDebugLLog(@"Pbs", @"%@ availableTypes called", [[self osPb] name]); if (debug)
{
NSLog(@"%@ -availableTypes entry", [[self osPb] name]);
}
[self setData: nil]; [self setData: nil];
[self requestData: XG_TARGETS]; [self requestData: XG_TARGETS];
data = [self data]; data = [self data];
if (data == nil) if (nil == data)
return [NSArray arrayWithObject: NSStringPboardType]; {
if (debug)
{
NSLog(@"%@ -availableTypes exit: 0", [[self osPb] name]);
}
return [NSArray array];
}
count = [data length] / sizeof(Atom); count = [data length] / sizeof(Atom);
targets = (Atom*)[data bytes]; targets = (Atom*)[data bytes];
@ -893,74 +960,56 @@ xErrorHandler(Display *d, XErrorEvent *e)
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
NSString *pbType;
Atom type; Atom type;
char *name;
type = targets[i]; type = targets[i];
name = XGetAtomName(xDisplay, type); pbType = NSPasteboardTypeFromAtom(type);
if ([pbType length] > 0)
if ((type == XG_UTF8_STRING)
|| (type == XA_STRING)
|| (type == XG_TEXT)
|| (type == XG_MIME_PLAIN))
{
if (nil == txt)
txt = [NSMutableString stringWithFormat: @"\n\tstring:%s", name];
else
[txt appendFormat: @",%s", name];
[types addObject: NSStringPboardType];
}
else if (type == XG_FILE_NAME)
{
[types addObject: NSFilenamesPboardType];
}
else if ((type == XG_MIME_RTF)
|| (type == XG_MIME_APP_RTF)
|| (type == XG_MIME_TEXT_RICHTEXT))
{
if (nil == rtf)
rtf = [NSMutableString stringWithFormat: @"\n\trich-text:%s", name];
else
[rtf appendFormat: @",%s", name];
[types addObject: NSRTFPboardType];
}
else if (type == XG_MIME_TIFF)
{
[types addObject: NSTIFFPboardType];
}
else if ((type == XG_TARGETS)
|| (type == XG_TIMESTAMP)
|| (type == XG_OWNER_OS)
|| (type == XG_USER)
|| (type == XG_HOST_NAME)
|| (type == XG_HOSTNAME)
|| (type == XG_MULTIPLE))
{ {
// Standard types if ([types containsObject: pbType])
if (nil == std)
std = [NSMutableString stringWithFormat: @"\n\tstandard:%s", name];
else
[std appendFormat: @",%s", name];
}
// FIXME: Support more types
else
{
if (nil == bad)
{ {
bad = [NSMutableString stringWithFormat: duplicates++;
@"\n\tunsupported:%s", name];
} }
else else
[bad appendFormat: @",%s", name]; {
// FIXME: We should rather add this type to the [types addObject: pbType];
// pasteboard as a string. }
}
else if (debug)
{
if (nil == pbType)
{
char *name = XGetAtomName(xDisplay, type);
if (nil == bad)
{
bad = [NSMutableString stringWithFormat:
@"%s", name];
}
else
{
[bad appendFormat: @",%s", name];
}
XFree(name);
unsupported++;
}
else
{
standard++;
}
} }
XFree(name);
} }
NSDebugLLog(@"Pbs", @"%@ availableTypes: %d types\n\tavailable: %@%@%@%@%@", if (debug)
[[self osPb] name], count, types, {
(txt ? txt : @""), (rtf ? rtf : @""), (std ? std : @""), (bad ? bad : @"")); NSLog(@"%@ -availableTypes exit: %u\n"
@"\tmapped: %u, duplicates: %u, standard: %u, unsupported: %u\n"
@"\tavailable: %@\n\tunsupported: (%@)",
[[self osPb] name], count,
(unsigned)[types count], duplicates, standard, unsupported,
types, bad ? (id)bad : (id)@"");
}
return types; return types;
} }
@ -1200,7 +1249,8 @@ xErrorHandler(Display *d, XErrorEvent *e)
if ([md length] > 0) if ([md length] > 0)
{ {
// Convert data to text string. // Convert data to text string.
if (actual_type == XG_UTF8_STRING) if (actual_type == XG_UTF8_STRING
|| actual_type == XG_MIME_UTF8)
{ {
NSString *s; NSString *s;
NSData *d; NSData *d;
@ -1339,7 +1389,7 @@ xErrorHandler(Display *d, XErrorEvent *e)
{ {
unsigned numTypes = 0; unsigned numTypes = 0;
// ATTENTION: Increase this array when adding more types // ATTENTION: Increase this array when adding more types
Atom xTypes[16]; Atom xTypes[17];
/* /*
* The requestor wants a list of the types we can supply it with. * The requestor wants a list of the types we can supply it with.
@ -1360,6 +1410,7 @@ xErrorHandler(Display *d, XErrorEvent *e)
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;
xTypes[numTypes++] = XG_MIME_UTF8;
} }
if ([types containsObject: NSFilenamesPboardType]) if ([types containsObject: NSFilenamesPboardType])
@ -1547,7 +1598,8 @@ xErrorHandler(Display *d, XErrorEvent *e)
} }
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)
|| (xEvent->target == XG_MIME_UTF8))
&& [types containsObject: NSStringPboardType]) && [types containsObject: NSStringPboardType])
{ {
NSString *s = [_pb stringForType: NSStringPboardType]; NSString *s = [_pb stringForType: NSStringPboardType];
@ -1559,7 +1611,7 @@ xErrorHandler(Display *d, XErrorEvent *e)
* Now we know what type of data is required - so get it from the * Now we know what type of data is required - so get it from the
* pasteboard and convert to a format X can understand. * pasteboard and convert to a format X can understand.
*/ */
if (xType == XG_UTF8_STRING) if (xType == XG_UTF8_STRING || xType == XG_MIME_UTF8)
{ {
data = [s dataUsingEncoding: NSUTF8StringEncoding]; data = [s dataUsingEncoding: NSUTF8StringEncoding];
} }