xserver: Branch 'xorg-server-1.4-apple'
George Peter Staplin
gstaplin at kemper.freedesktop.org
Mon Oct 27 15:41:06 PDT 2008
hw/xquartz/pbproxy/x-selection.h | 1
hw/xquartz/pbproxy/x-selection.m | 209 ++++++++++++++++++++++++++-------------
2 files changed, 141 insertions(+), 69 deletions(-)
New commits:
commit 8d048cfa956f4a0860250cc836a6748912b37ad8
Author: George Peter Staplin <gps at Georges-Workstation.local>
Date: Mon Oct 27 16:34:24 2008 -0600
XQuartz: pbproxy: Add code to handle PICT conversion to PNG and JPEG.
This may work, unfortunately I don't have test apps that fail.
The way it works is by using an NSImage class initWithPasteboard:
method, which we then get the TIFFRepresentation of, and convert
to PNG or JPEG.
The TIFFRepresentation uses NSTIFFCompressionNone; which should be
lossless.
diff --git a/hw/xquartz/pbproxy/x-selection.h b/hw/xquartz/pbproxy/x-selection.h
index 7a26a21..67170ac 100644
--- a/hw/xquartz/pbproxy/x-selection.h
+++ b/hw/xquartz/pbproxy/x-selection.h
@@ -107,6 +107,7 @@ struct atom_list {
- (void) reload_preferences;
- (BOOL) is_active;
+- (void) send_none:(XSelectionRequestEvent *)e;
@end
/* main.m */
diff --git a/hw/xquartz/pbproxy/x-selection.m b/hw/xquartz/pbproxy/x-selection.m
index f17970c..5290c8f 100644
--- a/hw/xquartz/pbproxy/x-selection.m
+++ b/hw/xquartz/pbproxy/x-selection.m
@@ -35,6 +35,8 @@
#include <stdlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
+#import <AppKit/NSGraphics.h>
+#import <AppKit/NSImage.h>
#import <AppKit/NSBitmapImageRep.h>
/*
@@ -58,15 +60,17 @@
/*
* TODO:
- * 1. handle MULTIPLE - I need to study the ICCCM further.
- * 2. Handle PICT images properly.
- * 3. Handle NSPasteboard updates immediately, not on active/inactive
+ * 1. handle MULTIPLE - I need to study the ICCCM further, and find a test app.
+ * 2. Handle NSPasteboard updates immediately, not on active/inactive
* - Open xterm, run 'cat readme.txt | pbcopy'
*/
static struct {
BOOL active ;
- BOOL primary_on_grab; // This is provided as an option for people who want it and has issues that won't ever be addressed to make it *always* work
+ BOOL primary_on_grab; /* This is provided as an option for people who
+ * want it and has issues that won't ever be
+ * addressed to make it *always* work.
+ */
BOOL clipboard_to_pasteboard;
BOOL pasteboard_to_primary;
BOOL pasteboard_to_clipboard;
@@ -410,7 +414,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
}
/* Called when the Edit/Copy item on the main X11 menubar is selected
- and no appkit window claims it. */
+ * and no appkit window claims it. */
- (void) x_copy:(Time)timestamp
{
Window w;
@@ -620,7 +624,8 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
* functionality in send_image.
*/
- if ([pbtypes containsObject:NSTIFFPboardType])
+ if ([pbtypes containsObject:NSPICTPboardType]
+ || [pbtypes containsObject:NSTIFFPboardType])
{
/* We can convert a TIFF to a PNG or JPEG. */
DB ("NSTIFFPboardType\n");
@@ -775,93 +780,159 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
[self send_reply:&reply];
}
+/* Return nil if an error occured. */
+/* DO NOT retain the encdata for longer than the length of an event response.
+ * The autorelease pool will reuse/free it.
+ */
+- (NSData *) encode_image_data:(NSData *)data type:(NSBitmapImageFileType)enctype
+{
+ NSBitmapImageRep *bmimage = nil;
+ NSData *encdata = nil;
+ NSDictionary *dict = nil;
-- (void) send_image:(XSelectionRequestEvent *)e pasteboard:(NSPasteboard *)pb
+ bmimage = [[NSBitmapImageRep alloc] initWithData:data];
+
+ if (nil == bmimage)
+ return nil;
+
+ dict = [[NSDictionary alloc] init];
+ encdata = [bmimage representationUsingType:enctype properties:dict];
+
+ if (nil == encdata)
+ {
+ [dict autorelease];
+ [bmimage autorelease];
+ return nil;
+ }
+
+ [dict autorelease];
+ [bmimage autorelease];
+
+ return encdata;
+}
+
+/* Return YES when an error has occured when trying to send the PICT. */
+/* The caller should send a default reponse with a property of None when an error occurs. */
+- (BOOL) send_image_pict_reply:(XSelectionRequestEvent *)e
+ pasteboard:(NSPasteboard *)pb
+ type:(NSBitmapImageFileType)imagetype
{
XEvent reply;
- NSArray *pbtypes;
- NSString *type = nil;
- NSBitmapImageFileType imagetype = /*quiet warning*/ NSPNGFileType;
- NSData *data;
+ NSImage *img = nil;
+ NSData *data = nil, *encdata = nil;
+ NSUInteger length;
+ const void *bytes = NULL;
+
+ img = [[NSImage alloc] initWithPasteboard:pb];
- TRACE ();
+ if (nil == img)
+ {
+ return YES;
+ }
+
+ data = [img TIFFRepresentation];
+
+ if (nil == data)
+ {
+ [img autorelease];
+ fprintf(stderr, "unable to convert PICT to TIFF!\n");
+ return YES;
+ }
+
+ encdata = [self encode_image_data:data type:imagetype];
+ if(nil == encdata)
+ {
+ [img autorelease];
+ return YES;
+ }
[self init_reply:&reply request:e];
- pbtypes = [pb types];
+ length = [encdata length];
+ bytes = [encdata bytes];
+
+ XChangeProperty (x_dpy, e->requestor, e->property, e->target,
+ 8, PropModeReplace, bytes, length);
+ reply.xselection.property = e->property;
- if (pbtypes)
- {
- if ([pbtypes containsObject:NSTIFFPboardType])
- type = NSTIFFPboardType;
+ [self send_reply:&reply];
- /* PICT is not yet supported by pbproxy.
- * The NSBitmapImageRep doesn't support it.
- else if ([pbtypes containsObject:NSPICTPboardType])
- type = NSPICTPboardType;
- */
- }
+ [img autorelease];
+
+ return NO; /*no error*/
+}
+
+/* Return YES if an error occured. */
+/* The caller should send a reply with a property of None when an error occurs. */
+- (BOOL) send_image_tiff_reply:(XSelectionRequestEvent *)e
+ pasteboard:(NSPasteboard *)pb
+ type:(NSBitmapImageFileType)imagetype
+{
+ XEvent reply;
+ NSData *data = nil;
+ NSData *encdata = nil;
+ NSUInteger length;
+ const void *bytes = NULL;
+
+ data = [pb dataForType:NSTIFFPboardType];
+
+ if (nil == data)
+ return YES;
+
+ encdata = [self encode_image_data:data type:imagetype];
+
+ if(nil == encdata)
+ return YES;
+
+ [self init_reply:&reply request:e];
+
+ length = [encdata length];
+ bytes = [encdata bytes];
+
+ XChangeProperty (x_dpy, e->requestor, e->property, e->target,
+ 8, PropModeReplace, bytes, length);
+ reply.xselection.property = e->property;
+
+ [self send_reply:&reply];
+
+ return NO; /*no error*/
+}
+
+- (void) send_image:(XSelectionRequestEvent *)e pasteboard:(NSPasteboard *)pb
+{
+ NSArray *pbtypes = nil;
+ NSBitmapImageFileType imagetype = NSPNGFileType;
+
+ TRACE ();
if (e->target == atoms->image_png)
imagetype = NSPNGFileType;
else if (e->target == atoms->image_jpeg)
imagetype = NSJPEGFileType;
-
-
- if (nil == type)
+ else
{
- [self send_reply:&reply];
- return;
+ fprintf(stderr, "internal failure in xpbproxy! imagetype being sent isn't PNG or JPEG.\n");
}
- data = [pb dataForType:type];
+ pbtypes = [pb types];
- if (nil == data)
- {
- [self send_reply:&reply];
- return;
- }
-
- if (NSTIFFPboardType == type)
+ if (pbtypes)
{
- NSBitmapImageRep *bmimage = [[NSBitmapImageRep alloc] initWithData:data];
- NSDictionary *dict;
- NSData *encdata;
-
- if (nil == bmimage)
+ if ([pbtypes containsObject:NSTIFFPboardType])
{
- [self send_reply:&reply];
- return;
- }
-
- DB ("bmimage retainCount after initWithData %u\n", [bmimage retainCount]);
-
- dict = [[NSDictionary alloc] init];
- encdata = [bmimage representationUsingType:imagetype properties:dict];
- if (encdata)
+ if (NO == [self send_image_tiff_reply:e pasteboard:pb type:imagetype])
+ return;
+ }
+ else if ([pbtypes containsObject:NSPICTPboardType])
{
- NSUInteger length;
- const void *bytes;
-
- length = [encdata length];
- bytes = [encdata bytes];
-
- XChangeProperty (x_dpy, e->requestor, e->property, e->target,
- 8, PropModeReplace, bytes, length);
- reply.xselection.property = e->property;
-
- DB ("changed property for %s\n", XGetAtomName (x_dpy, e->target));
- DB ("encdata retainCount %u\n", [encdata retainCount]);
- }
- DB ("dict retainCount before release %u\n", [dict retainCount]);
- [dict autorelease];
+ if (NO == [self send_image_pict_reply:e pasteboard:pb type:imagetype])
+ return;
- DB ("bmimage retainCount before release %u\n", [bmimage retainCount]);
-
- [bmimage autorelease];
+ /* Fall through intentionally to the send_none: */
+ }
}
- [self send_reply:&reply];
+ [self send_none:e];
}
- (void)send_none:(XSelectionRequestEvent *)e
More information about the xorg-commit
mailing list