Skip to content

Commit

Permalink
Add support for text/plain;charset=utf8 and improve debug logging for…
Browse files Browse the repository at this point in the history
… available types
  • Loading branch information
rfm committed Mar 5, 2024
1 parent 145ee71 commit b8933e4
Showing 1 changed file with 119 additions and 67 deletions.
186 changes: 119 additions & 67 deletions Tools/xpbs.m
Expand Up @@ -82,7 +82,8 @@
"image/png",
"image/svg",
"application/rtf",
"text/richtext"
"text/richtext",
"text/plain;charset=utf-8"
};
static Atom atoms[sizeof(atom_names)/sizeof(char*)];

Expand Down Expand Up @@ -126,6 +127,60 @@
#define XG_MIME_SVG atoms[33]
#define XG_MIME_APP_RTF atoms[34]
#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
}



Expand Down Expand Up @@ -767,6 +822,8 @@ - (void) pasteboard: (NSPasteboard*)pb provideDataForType: (NSString*)type
if ([type isEqual: NSStringPboardType])
{
[self requestData: XG_UTF8_STRING];
if ([self data] == nil)
[self requestData: XG_MIME_UTF8];
if ([self data] == nil)
[self requestData: XA_STRING];
if ([self data] == nil)
Expand Down Expand Up @@ -871,96 +928,88 @@ - (NSArray*) availableTypes
{
NSMutableArray *types;
NSData *data;
NSMutableString *txt = nil;
NSMutableString *rtf = nil;
NSMutableString *std = nil;
unsigned duplicates = 0;
unsigned standard = 0;
unsigned unsupported = 0;
NSMutableString *bad = nil;
unsigned int count;
unsigned int i;
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 requestData: XG_TARGETS];
data = [self data];
if (data == nil)
return [NSArray arrayWithObject: NSStringPboardType];
if (nil == data)
{
if (debug)
{
NSLog(@"%@ -availableTypes exit: 0", [[self osPb] name]);
}
return [NSArray array];
}

count = [data length] / sizeof(Atom);
targets = (Atom*)[data bytes];
types = [NSMutableArray arrayWithCapacity: count];

for (i = 0; i < count; i++)
{
NSString *pbType;
Atom type;
char *name;

type = targets[i];
name = XGetAtomName(xDisplay, type);

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))
pbType = NSPasteboardTypeFromAtom(type);
if ([pbType length] > 0)
{
// Standard types
if (nil == std)
std = [NSMutableString stringWithFormat: @"\n\tstandard:%s", name];
if ([types containsObject: pbType])
{
duplicates++;
}
else
[std appendFormat: @",%s", name];
}
// FIXME: Support more types
else
{
[types addObject: pbType];
}
}
else if (debug)
{
if (nil == bad)
if (nil == pbType)
{
bad = [NSMutableString stringWithFormat:
@"\n\tunsupported:%s", name];
char *name = XGetAtomName(xDisplay, type);

if (nil == bad)
{
bad = [NSMutableString stringWithFormat:
@"%s", name];
}
else
{
[bad appendFormat: @",%s", name];
}
XFree(name);
unsupported++;
}
else
[bad appendFormat: @",%s", name];
// FIXME: We should rather add this type to the
// pasteboard as a string.
{
standard++;
}
}
XFree(name);
}

NSDebugLLog(@"Pbs", @"%@ availableTypes: %d types\n\tavailable: %@%@%@%@%@",
[[self osPb] name], count, types,
(txt ? txt : @""), (rtf ? rtf : @""), (std ? std : @""), (bad ? bad : @""));
if (debug)
{
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;
}
Expand Down Expand Up @@ -1200,7 +1249,8 @@ - (void) xSelectionNotify: (XSelectionEvent*)xEvent
if ([md length] > 0)
{
// Convert data to text string.
if (actual_type == XG_UTF8_STRING)
if (actual_type == XG_UTF8_STRING
|| actual_type == XG_MIME_UTF8)
{
NSString *s;
NSData *d;
Expand Down Expand Up @@ -1339,7 +1389,7 @@ - (BOOL) xProvideSelection: (XSelectionRequestEvent*)xEvent
{
unsigned numTypes = 0;
// 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.
Expand All @@ -1360,6 +1410,7 @@ - (BOOL) xProvideSelection: (XSelectionRequestEvent*)xEvent
xTypes[numTypes++] = XG_COMPOUND_TEXT;
xTypes[numTypes++] = XA_STRING;
xTypes[numTypes++] = XG_TEXT;
xTypes[numTypes++] = XG_MIME_UTF8;
}

if ([types containsObject: NSFilenamesPboardType])
Expand Down Expand Up @@ -1547,7 +1598,8 @@ - (BOOL) xProvideSelection: (XSelectionRequestEvent*)xEvent
}
else if (((xEvent->target == XG_UTF8_STRING)
|| (xEvent->target == XA_STRING)
|| (xEvent->target == XG_TEXT))
|| (xEvent->target == XG_TEXT)
|| (xEvent->target == XG_MIME_UTF8))
&& [types containsObject: NSStringPboardType])
{
NSString *s = [_pb stringForType: NSStringPboardType];
Expand All @@ -1559,7 +1611,7 @@ - (BOOL) xProvideSelection: (XSelectionRequestEvent*)xEvent
* Now we know what type of data is required - so get it from the
* 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];
}
Expand Down

0 comments on commit b8933e4

Please sign in to comment.