2 * MACDRV Cocoa clipboard code
4 * Copyright 2012, 2013 Ken Thomases for CodeWeavers Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "macdrv_cocoa.h"
23 #import "cocoa_event.h"
26 static int owned_change_count = -1;
28 static NSArray* BitmapOutputTypes;
29 static NSDictionary* BitmapOutputTypeMap;
30 static dispatch_once_t BitmapOutputTypesInitOnce;
33 /***********************************************************************
34 * macdrv_is_pasteboard_owner
36 int macdrv_is_pasteboard_owner(void)
41 NSPasteboard* pb = [NSPasteboard generalPasteboard];
42 ret = ([pb changeCount] == owned_change_count);
49 /***********************************************************************
50 * macdrv_copy_pasteboard_types
52 * Returns an array of UTI strings for the types of data available on
53 * the pasteboard, or NULL on error. The caller is responsible for
54 * releasing the returned array with CFRelease().
56 CFArrayRef macdrv_copy_pasteboard_types(CFTypeRef pasteboard)
58 NSPasteboard* pb = (NSPasteboard*)pasteboard;
59 __block CFArrayRef ret = NULL;
60 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
62 dispatch_once(&BitmapOutputTypesInitOnce, ^{
63 NSArray* bitmapFileTypes = [NSArray arrayWithObjects:
64 [NSNumber numberWithUnsignedInteger:NSTIFFFileType],
65 [NSNumber numberWithUnsignedInteger:NSPNGFileType],
66 [NSNumber numberWithUnsignedInteger:NSBMPFileType],
67 [NSNumber numberWithUnsignedInteger:NSGIFFileType],
68 [NSNumber numberWithUnsignedInteger:NSJPEGFileType],
69 [NSNumber numberWithUnsignedInteger:NSJPEG2000FileType],
72 BitmapOutputTypes = [[NSArray alloc] initWithObjects:@"public.tiff", @"public.png",
73 @"com.microsoft.bmp", @"com.compuserve.gif", @"public.jpeg",
74 @"public.jpeg-2000", nil];
76 BitmapOutputTypeMap = [[NSDictionary alloc] initWithObjects:bitmapFileTypes
77 forKeys:BitmapOutputTypes];
83 NSPasteboard* local_pb = pb;
86 if (!local_pb) local_pb = [NSPasteboard generalPasteboard];
87 types = [local_pb types];
89 // If there are any types understood by NSBitmapImageRep, then we
90 // can offer all of the types that it can output, too. For example,
91 // if TIFF is on the pasteboard, we can offer PNG, BMP, etc. to the
92 // Windows program. We'll convert on demand.
93 if ([types firstObjectCommonWithArray:[NSBitmapImageRep imageTypes]] ||
94 [types firstObjectCommonWithArray:[NSBitmapImageRep imagePasteboardTypes]])
96 NSMutableArray* newTypes = [BitmapOutputTypes mutableCopy];
97 [newTypes removeObjectsInArray:types];
98 types = [types arrayByAddingObjectsFromArray:newTypes];
102 ret = (CFArrayRef)[types copy];
106 ERR(@"Exception discarded while copying pasteboard types: %@\n", e);
115 /***********************************************************************
116 * macdrv_copy_pasteboard_data
118 * Returns the pasteboard data for a specified type, or NULL on error or
119 * if there's no such type on the pasteboard. The caller is responsible
120 * for releasing the returned data object with CFRelease().
122 CFDataRef macdrv_copy_pasteboard_data(CFTypeRef pasteboard, CFStringRef type)
124 NSPasteboard* pb = (NSPasteboard*)pasteboard;
125 __block NSData* ret = nil;
130 NSPasteboard* local_pb = pb;
131 if (!local_pb) local_pb = [NSPasteboard generalPasteboard];
132 if ([local_pb availableTypeFromArray:[NSArray arrayWithObject:(NSString*)type]])
133 ret = [[local_pb dataForType:(NSString*)type] copy];
136 NSNumber* bitmapType = [BitmapOutputTypeMap objectForKey:(NSString*)type];
139 NSArray* reps = [NSBitmapImageRep imageRepsWithPasteboard:local_pb];
140 ret = [NSBitmapImageRep representationOfImageRepsInArray:reps
141 usingType:[bitmapType unsignedIntegerValue]
149 ERR(@"Exception discarded while copying pasteboard types: %@\n", e);
153 return (CFDataRef)ret;
157 /***********************************************************************
158 * macdrv_clear_pasteboard
160 * Takes ownership of the Mac pasteboard and clears it of all data types.
162 void macdrv_clear_pasteboard(void)
167 NSPasteboard* pb = [NSPasteboard generalPasteboard];
168 owned_change_count = [pb declareTypes:[NSArray array] owner:nil];
172 ERR(@"Exception discarded while clearing pasteboard: %@\n", e);
178 /***********************************************************************
179 * macdrv_set_pasteboard_data
181 * Sets the pasteboard data for a specified type. Replaces any data of
182 * that type already on the pasteboard. If data is NULL, promises the
185 * Returns 0 on error, non-zero on success.
187 int macdrv_set_pasteboard_data(CFStringRef type, CFDataRef data, macdrv_window w)
190 WineWindow* window = (WineWindow*)w;
195 NSPasteboard* pb = [NSPasteboard generalPasteboard];
196 NSInteger change_count = [pb addTypes:[NSArray arrayWithObject:(NSString*)type]
200 owned_change_count = change_count;
202 ret = [pb setData:(NSData*)data forType:(NSString*)type];
209 ERR(@"Exception discarded while copying pasteboard types: %@\n", e);