QVariant QMacPasteboard::retrieveData(const QString &format, QVariant::Type) const { if (!paste) return QVariant(); sync(); ItemCount cnt = 0; if(PasteboardGetItemCount(paste, &cnt) || !cnt) return QByteArray(); #ifdef DEBUG_PASTEBOARD qDebug("Pasteboard: retrieveData [%s]", qPrintable(format)); #endif const QList<QMacPasteboardMime *> mimes = QMacPasteboardMime::all(mime_type); for(int mime = 0; mime < mimes.size(); ++mime) { QMacPasteboardMime *c = mimes.at(mime); QString c_flavor = c->flavorFor(format); if(!c_flavor.isEmpty()) { // Handle text/plain a little differently. Try handling Unicode first. bool checkForUtf16 = (c_flavor == QLatin1String("com.apple.traditional-mac-plain-text") || c_flavor == QLatin1String("public.utf8-plain-text")); if (checkForUtf16 || c_flavor == QLatin1String("public.utf16-plain-text")) { // Try to get the NSStringPboardType from NSPasteboard, newlines are mapped // correctly (as '\n') in this data. The 'public.utf16-plain-text' type // usually maps newlines to '\r' instead. QString str = qt_mac_get_pasteboardString(paste); if (!str.isEmpty()) return str; } if (checkForUtf16 && hasFlavor(QLatin1String("public.utf16-plain-text"))) c_flavor = QLatin1String("public.utf16-plain-text"); QVariant ret; QList<QByteArray> retList; for(uint index = 1; index <= cnt; ++index) { PasteboardItemID id; if(PasteboardGetItemIdentifier(paste, index, &id) != noErr) continue; QCFType<CFArrayRef> types; if(PasteboardCopyItemFlavors(paste, id, &types ) != noErr) continue; const int type_count = CFArrayGetCount(types); for(int i = 0; i < type_count; ++i) { CFStringRef flavor = static_cast<CFStringRef>(CFArrayGetValueAtIndex(types, i)); if(c_flavor == QCFString::toQString(flavor)) { QCFType<CFDataRef> macBuffer; if(PasteboardCopyItemFlavorData(paste, id, flavor, &macBuffer) == noErr) { QByteArray buffer((const char *)CFDataGetBytePtr(macBuffer), CFDataGetLength(macBuffer)); if(!buffer.isEmpty()) { #ifdef DEBUG_PASTEBOARD qDebug(" - %s [%s] (%s)", qPrintable(format), qPrintable(QCFString::toQString(flavor)), qPrintable(c->convertorName())); #endif buffer.detach(); //detach since we release the macBuffer retList.append(buffer); break; //skip to next element } } } else { #ifdef DEBUG_PASTEBOARD qDebug(" - NoMatch %s [%s] (%s)", qPrintable(c_flavor), qPrintable(QCFString::toQString(flavor)), qPrintable(c->convertorName())); #endif } } } if (!retList.isEmpty()) { ret = c->convertToMime(format, retList, c_flavor); return ret; } } } return QVariant(); }
oop QuartzWindow::get_scrap_text() { // See Pasteboard Manager Programming guide PasteboardRef clipboard; PasteboardSyncFlags syncFlags; CFDataRef textData = NULL; ItemCount itemCount; if ( PasteboardCreate(kPasteboardClipboard, &clipboard) != noErr || (PasteboardSynchronize(clipboard) & kPasteboardModified) || PasteboardGetItemCount(clipboard, &itemCount) != noErr ) return new_string("", 0); for( UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++ ) { PasteboardItemID itemID = 0; CFArrayRef flavorTypeArray = NULL; CFIndex flavorCount = 0; if (PasteboardGetItemIdentifier(clipboard, itemIndex, &itemID) != noErr) continue; if (PasteboardCopyItemFlavors(clipboard, itemID, &flavorTypeArray) != noErr) continue; flavorCount = CFArrayGetCount(flavorTypeArray); for(CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++) { CFStringRef flavorType; CFDataRef flavorData; CFIndex flavorDataSize; char flavorText[256]; flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray,// 6 flavorIndex ); if (UTTypeConformsTo(flavorType, kUTTypeOldMacText)) { if (PasteboardCopyItemFlavorData(clipboard, itemID, flavorType, &flavorData) != noErr) continue; flavorDataSize = CFDataGetLength(flavorData); // allocate new string. byteVectorOop r = Memory->byteVectorObj->cloneSize(flavorDataSize, CANFAIL); if (r->is_mark()) { CFRelease (flavorData); CFRelease (flavorTypeArray); return new_string("", 0); } // copy over CFDataGetBytes(flavorData, CFRangeMake(0,CFDataGetLength(flavorData)), (UInt8 *)r->bytes()); CFRelease(flavorData); CFRelease(flavorTypeArray); return r; } // else try next } CFRelease(flavorTypeArray); } }
bool wxDataObject::GetFromPasteboard( void * pb ) { PasteboardRef pasteboard = (PasteboardRef) pb; size_t formatcount = GetFormatCount() + 1; wxDataFormat *array = new wxDataFormat[ formatcount ]; array[0] = GetPreferredFormat(); GetAllFormats( &array[1] ); ItemCount itemCount = 0; wxString filenamesPassed; bool transferred = false; // we synchronize here once again, so we don't mind which flags get returned PasteboardSynchronize( pasteboard ); OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount ); if ( err == noErr ) { for (size_t i = 0; !transferred && i < formatcount; i++) { // go through the data in our order of preference wxDataFormat dataFormat = array[ i ]; for( UInt32 itemIndex = 1; itemIndex <= itemCount && transferred == false ; itemIndex++ ) { PasteboardItemID itemID = 0; CFArrayRef flavorTypeArray = NULL; CFIndex flavorCount = 0; err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); if ( err != noErr ) continue; err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); if ( err != noErr ) continue; flavorCount = CFArrayGetCount( flavorTypeArray ); for( CFIndex flavorIndex = 0; !transferred && flavorIndex < flavorCount ; flavorIndex++ ) { CFStringRef flavorType; CFDataRef flavorData; CFIndex flavorDataSize; flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex ); // avoid utf8 being treated closer to plain-text than unicode by forcing a conversion if ( UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text") ) ) { flavorType = CFSTR("public.utf16-plain-text"); } wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); if ( dataFormat == flavorFormat ) { err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType , &flavorData ); if ( err == noErr ) { flavorDataSize = CFDataGetLength( flavorData ); if (dataFormat.GetType() == wxDF_FILENAME ) { // revert the translation and decomposition to arrive at a proper utf8 string again CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, CFDataGetBytePtr( flavorData ), flavorDataSize, kCFStringEncodingUTF8, NULL ); CFStringRef cfString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle ); CFRelease( url ); CFMutableStringRef cfMutableString = CFStringCreateMutableCopy(NULL, 0, cfString); CFRelease( cfString ); CFStringNormalize(cfMutableString,kCFStringNormalizationFormC); wxString path = wxMacCFStringHolder(cfMutableString).AsString(); if (!path.empty()) filenamesPassed += path + wxT("\n"); } else { // because some data implementation expect trailing a trailing NUL, we add some headroom void *buf = malloc( flavorDataSize + 4 ); if ( buf ) { memset( buf, 0, flavorDataSize + 4 ); memcpy( buf, CFDataGetBytePtr( flavorData ), flavorDataSize ); if (dataFormat.GetType() == wxDF_TEXT) wxMacConvertNewlines10To13( (char*) buf ); SetData( flavorFormat, flavorDataSize, buf ); transferred = true; free( buf ); } } CFRelease (flavorData); } } else if ( dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) { err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType, &flavorData ); if ( err == noErr ) { flavorDataSize = CFDataGetLength( flavorData ); void *asciibuf = malloc( flavorDataSize + 1 ); if ( asciibuf ) { memset( asciibuf, 0, flavorDataSize + 1 ); memcpy( asciibuf, CFDataGetBytePtr( flavorData ), flavorDataSize ); CFRelease (flavorData); SetData( wxDF_TEXT, flavorDataSize, asciibuf ); transferred = true; free( asciibuf ); } else CFRelease (flavorData); } } } CFRelease( flavorTypeArray ); } if (filenamesPassed.length() > 0) { wxCharBuffer buf = filenamesPassed.fn_str(); SetData( wxDF_FILENAME, strlen( buf ), (const char*)buf ); transferred = true; } } } return transferred; }
/** * Walk through pasteboard items and report currently available item types. * * @param pPasteboard Reference to guest Pasteboard. * @returns Available formats bit field. */ uint32_t vbclClipboardGetAvailableFormats(PasteboardRef pPasteboard) { uint32_t fFormats = 0; ItemCount cItems = 0; ItemCount iItem; OSStatus rc; #define VBOXCL_ADD_FORMAT_IF_PRESENT(a_kDarwinFmt, a_fVBoxFmt) \ if (PasteboardCopyItemFlavorData(pPasteboard, iItemID, a_kDarwinFmt, &flavorData) == noErr) \ { \ fFormats |= (uint32_t)a_fVBoxFmt; \ CFRelease(flavorData); \ } rc = PasteboardGetItemCount(pPasteboard, &cItems); AssertReturn((rc == noErr) && (cItems > 0), fFormats); for (iItem = 1; iItem <= cItems; iItem++) { PasteboardItemID iItemID; CFDataRef flavorData; rc = PasteboardGetItemIdentifier(pPasteboard, iItem, &iItemID); if (rc == noErr) { VBOXCL_ADD_FORMAT_IF_PRESENT(kUTTypeUTF16PlainText, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT); VBOXCL_ADD_FORMAT_IF_PRESENT(kUTTypeUTF8PlainText, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT); VBOXCL_ADD_FORMAT_IF_PRESENT(kUTTypeBMP, VBOX_SHARED_CLIPBOARD_FMT_BITMAP ); VBOXCL_ADD_FORMAT_IF_PRESENT(kUTTypeHTML, VBOX_SHARED_CLIPBOARD_FMT_HTML ); #ifdef CLIPBOARD_DUMP_CONTENT_FORMATS CFArrayRef flavorTypeArray; CFIndex flavorCount; CFStringRef flavorType; rc = PasteboardCopyItemFlavors(pPasteboard, iItemID, &flavorTypeArray); if (rc == noErr) { VBoxClientVerbose(3, "SCAN..\n"); flavorCount = CFArrayGetCount(flavorTypeArray); VBoxClientVerbose(3, "SCAN (%d)..\n", (int)flavorCount); for(CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++) { VBoxClientVerbose(3, "SCAN #%d..\n", (int)flavorIndex); flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex); CFDataRef flavorData1; rc = PasteboardCopyItemFlavorData(pPasteboard, iItemID, flavorType, &flavorData1); if (rc == noErr) { VBoxClientVerbose(3, "Found: %s, size: %d\n", (char *)CFStringGetCStringPtr(flavorType, kCFStringEncodingMacRoman), (int)CFDataGetLength(flavorData1)); CFRelease(flavorData1); } } VBoxClientVerbose(3, "SCAN COMPLETE\n"); CFRelease(flavorTypeArray); } #endif /* CLIPBOARD_DUMP_CONTENT_FORMATS */ } } #undef VBOXCL_ADD_FORMAT_IF_PRESENT return fFormats; }
char *osd_get_clipboard_text(void) { char *result = NULL; /* core expects a malloced C string of uft8 data */ PasteboardRef pasteboard_ref; OSStatus err; PasteboardSyncFlags sync_flags; PasteboardItemID item_id; CFIndex flavor_count; CFArrayRef flavor_type_array; CFIndex flavor_index; ItemCount item_count; UInt32 item_index; Boolean success = false; err = PasteboardCreate(kPasteboardClipboard, &pasteboard_ref); if (!err) { sync_flags = PasteboardSynchronize( pasteboard_ref ); err = PasteboardGetItemCount(pasteboard_ref, &item_count ); for (item_index=1; item_index<=item_count; item_index++) { err = PasteboardGetItemIdentifier(pasteboard_ref, item_index, &item_id); if (!err) { err = PasteboardCopyItemFlavors(pasteboard_ref, item_id, &flavor_type_array); if (!err) { flavor_count = CFArrayGetCount(flavor_type_array); for (flavor_index = 0; flavor_index < flavor_count; flavor_index++) { CFStringRef flavor_type; CFDataRef flavor_data; CFStringEncoding encoding; CFStringRef string_ref; CFDataRef data_ref; CFIndex length; CFRange range; flavor_type = (CFStringRef)CFArrayGetValueAtIndex(flavor_type_array, flavor_index); if (UTTypeConformsTo (flavor_type, kUTTypeUTF16PlainText)) encoding = kCFStringEncodingUTF16; else if (UTTypeConformsTo (flavor_type, kUTTypeUTF8PlainText)) encoding = kCFStringEncodingUTF8; else if (UTTypeConformsTo (flavor_type, kUTTypePlainText)) encoding = kCFStringEncodingMacRoman; else continue; err = PasteboardCopyItemFlavorData(pasteboard_ref, item_id, flavor_type, &flavor_data); if( !err ) { string_ref = CFStringCreateFromExternalRepresentation (kCFAllocatorDefault, flavor_data, encoding); data_ref = CFStringCreateExternalRepresentation (kCFAllocatorDefault, string_ref, kCFStringEncodingUTF8, '?'); length = CFDataGetLength (data_ref); range = CFRangeMake (0,length); result = (char *)malloc (length+1); if (result != NULL) { CFDataGetBytes (data_ref, range, (unsigned char *)result); result[length] = 0; success = true; break; } CFRelease(data_ref); CFRelease(string_ref); CFRelease(flavor_data); } } CFRelease(flavor_type_array); } } if (success) break; } CFRelease(pasteboard_ref); } return result; }
static pascal OSStatus MultiCartPaneEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { OSStatus err, result = eventNotHandledErr; HIViewRef view; DragRef drag; PasteboardRef pasteboard; PasteboardItemID itemID; CFArrayRef array; CFStringRef flavorType; CFIndex numFlavors; ItemCount numItems; int index = *((int *) inUserData); switch (GetEventClass(inEvent)) { case kEventClassControl: { switch (GetEventKind(inEvent)) { case kEventControlDraw: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { CGContextRef ctx; err = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(CGContextRef), NULL, &ctx); if (err == noErr) { HIThemeFrameDrawInfo info; HIRect bounds, frame; HIViewGetBounds(view, &bounds); CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f); CGContextFillRect(ctx, bounds); info.version = 0; info.kind = kHIThemeFrameTextFieldSquare; info.state = kThemeStateInactive; info.isFocused = false; err = HIThemeDrawFrame(&bounds, &info, ctx, kHIThemeOrientationNormal); if (multiCartDragHilite == index && systemVersion >= 0x1040) { err = HIThemeSetStroke(kThemeBrushDragHilite, NULL, ctx, kHIThemeOrientationNormal); frame = CGRectInset(bounds, 1, 1); CGContextBeginPath(ctx); CGContextAddRect(ctx, frame); CGContextStrokePath(ctx); } } } result = noErr; break; } case kEventControlDragEnter: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag); if (err == noErr) { err = GetDragPasteboard(drag, &pasteboard); if (err == noErr) { err = PasteboardGetItemCount(pasteboard, &numItems); if (err == noErr && numItems == 1) { err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID); if (err == noErr) { err = PasteboardCopyItemFlavors(pasteboard, itemID, &array); if (err == noErr) { numFlavors = CFArrayGetCount(array); for (CFIndex i = 0; i < numFlavors; i++) { flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i); if (UTTypeConformsTo(flavorType, CFSTR("public.file-url"))) { Boolean accept = true; err = SetEventParameter(inEvent, kEventParamControlWouldAcceptDrop, typeBoolean, sizeof(Boolean), &accept); if (err == noErr) { multiCartDragHilite = index; HIViewSetNeedsDisplay(view, true); result = noErr; } } } CFRelease(array); } } } } } } break; } case kEventControlDragWithin: { result = noErr; break; } case kEventControlDragLeave: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { multiCartDragHilite = -1; HIViewSetNeedsDisplay(view, true); } result = noErr; break; } case kEventControlDragReceive: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag); if (err == noErr) { multiCartDragHilite = -1; HIViewSetNeedsDisplay(view, true); err = GetDragPasteboard(drag, &pasteboard); if (err == noErr) { err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID); if (err == noErr) { err = PasteboardCopyItemFlavors(pasteboard, itemID, &array); if (err == noErr) { numFlavors = CFArrayGetCount(array); for (CFIndex i = 0; i < numFlavors; i++) { flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i); if (UTTypeConformsTo(flavorType, CFSTR("public.file-url"))) { CFDataRef flavorData; err = PasteboardCopyItemFlavorData(pasteboard, itemID, flavorType, &flavorData); if (err == noErr) { CFIndex dataSize; UInt8 *data; dataSize = CFDataGetLength(flavorData); data = (UInt8 *) malloc(dataSize); if (data) { CFDataGetBytes(flavorData, CFRangeMake(0, dataSize), data); HIViewRef ctl; HIViewID cid; CFStringRef str; CFURLRef url; GetControlID(view, &cid); cid.signature = 'MNAM'; HIViewFindByID(view, cid, &ctl); url = CFURLCreateWithBytes(kCFAllocatorDefault, data, dataSize, kCFStringEncodingUTF8, NULL); str = CFURLCopyLastPathComponent(url); SetStaticTextCFString(ctl, str, true); CFRelease(str); str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); if (multiCartPath[cid.id]) CFRelease(multiCartPath[cid.id]); multiCartPath[cid.id] = str; CFRelease(url); result = noErr; free(data); } CFRelease(flavorData); } } } CFRelease(array); } } } } } } } } } return (result); }
char *osd_get_clipboard_text(void) { OSStatus err; PasteboardRef pasteboard_ref; err = PasteboardCreate(kPasteboardClipboard, &pasteboard_ref); if (err) return nullptr; PasteboardSynchronize(pasteboard_ref); ItemCount item_count; err = PasteboardGetItemCount(pasteboard_ref, &item_count); char *result = nullptr; // core expects a malloced C string of uft8 data for (UInt32 item_index = 1; (item_index <= item_count) && !result; item_index++) { PasteboardItemID item_id; err = PasteboardGetItemIdentifier(pasteboard_ref, item_index, &item_id); if (err) continue; CFArrayRef flavor_type_array; err = PasteboardCopyItemFlavors(pasteboard_ref, item_id, &flavor_type_array); if (err) continue; CFIndex const flavor_count = CFArrayGetCount(flavor_type_array); for (CFIndex flavor_index = 0; (flavor_index < flavor_count) && !result; flavor_index++) { CFStringRef const flavor_type = (CFStringRef)CFArrayGetValueAtIndex(flavor_type_array, flavor_index); CFStringEncoding encoding; if (UTTypeConformsTo(flavor_type, kUTTypeUTF16PlainText)) encoding = kCFStringEncodingUTF16; else if (UTTypeConformsTo (flavor_type, kUTTypeUTF8PlainText)) encoding = kCFStringEncodingUTF8; else if (UTTypeConformsTo (flavor_type, kUTTypePlainText)) encoding = kCFStringEncodingMacRoman; else continue; CFDataRef flavor_data; err = PasteboardCopyItemFlavorData(pasteboard_ref, item_id, flavor_type, &flavor_data); if (!err) { CFStringRef string_ref = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, flavor_data, encoding); CFDataRef data_ref = CFStringCreateExternalRepresentation (kCFAllocatorDefault, string_ref, kCFStringEncodingUTF8, '?'); CFRelease(string_ref); CFRelease(flavor_data); CFIndex const length = CFDataGetLength(data_ref); CFRange const range = CFRangeMake(0, length); result = reinterpret_cast<char *>(malloc(length + 1)); if (result) { CFDataGetBytes(data_ref, range, reinterpret_cast<unsigned char *>(result)); result[length] = 0; } CFRelease(data_ref); } } CFRelease(flavor_type_array); } CFRelease(pasteboard_ref); return result; }
bool wxDataObject::GetFromPasteboard( void * pb ) { PasteboardRef pasteboard = (PasteboardRef) pb; size_t formatcount = GetFormatCount(wxDataObject::Set); wxDataFormat *array = new wxDataFormat[ formatcount ]; GetAllFormats(array, wxDataObject::Set); ItemCount itemCount = 0; wxString filenamesPassed; bool transferred = false; bool pastelocationset = false; // we synchronize here once again, so we don't mind which flags get returned PasteboardSynchronize( pasteboard ); OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount ); if ( err == noErr ) { for (size_t i = 0; !transferred && i < formatcount; i++) { // go through the data in our order of preference wxDataFormat dataFormat = array[ i ]; for( UInt32 itemIndex = 1; itemIndex <= itemCount && transferred == false ; itemIndex++ ) { PasteboardItemID itemID = 0; CFArrayRef flavorTypeArray = NULL; CFIndex flavorCount = 0; err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); if ( err != noErr ) continue; err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); if ( err != noErr ) continue; flavorCount = CFArrayGetCount( flavorTypeArray ); for( CFIndex flavorIndex = 0; !transferred && flavorIndex < flavorCount ; flavorIndex++ ) { CFStringRef flavorType; CFDataRef flavorData; CFIndex flavorDataSize; flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex ); wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); if ( dataFormat == flavorFormat ) { if ( UTTypeConformsTo( (CFStringRef)flavorType, kPasteboardTypeFileURLPromise) ) { if ( !pastelocationset ) { wxString tempdir = wxFileName::GetTempDir() + wxFILE_SEP_PATH + "wxtemp.XXXXXX"; char* result = mkdtemp((char*)tempdir.fn_str().data()); if (!result) continue; wxCFRef<CFURLRef> dest(CFURLCreateFromFileSystemRepresentation(NULL,(const UInt8*)result,strlen(result),true)); PasteboardSetPasteLocation(pasteboard, dest); pastelocationset = true; } } else if ( flavorFormat.GetType() != wxDF_PRIVATE ) { // indicate the expected format for the type, benefiting from native conversions eg utf8 -> utf16 flavorType = (CFStringRef) wxDataFormat( flavorFormat.GetType()).GetFormatId(); } err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType , &flavorData ); if ( err == noErr ) { flavorDataSize = CFDataGetLength( flavorData ); if (dataFormat.GetType() == wxDF_FILENAME ) { // revert the translation and decomposition to arrive at a proper utf8 string again CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, CFDataGetBytePtr( flavorData ), flavorDataSize, kCFStringEncodingUTF8, NULL ); CFStringRef cfString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle ); CFRelease( url ); CFMutableStringRef cfMutableString = CFStringCreateMutableCopy(NULL, 0, cfString); CFRelease( cfString ); CFStringNormalize(cfMutableString,kCFStringNormalizationFormC); wxString path = wxCFStringRef(cfMutableString).AsString(); if (!path.empty()) filenamesPassed += path + wxT("\n"); } else { // because some data implementation expect trailing a trailing NUL, we add some headroom void *buf = malloc( flavorDataSize + 4 ); if ( buf ) { memset( buf, 0, flavorDataSize + 4 ); memcpy( buf, CFDataGetBytePtr( flavorData ), flavorDataSize ); if (dataFormat.GetType() == wxDF_TEXT) wxMacConvertNewlines10To13( (char*) buf ); SetData( flavorFormat, flavorDataSize, buf ); transferred = true; free( buf ); } } CFRelease (flavorData); } } else if ( dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) { err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType, &flavorData ); if ( err == noErr ) { flavorDataSize = CFDataGetLength( flavorData ); void *asciibuf = malloc( flavorDataSize + 1 ); if ( asciibuf ) { memset( asciibuf, 0, flavorDataSize + 1 ); memcpy( asciibuf, CFDataGetBytePtr( flavorData ), flavorDataSize ); CFRelease (flavorData); SetData( wxDF_TEXT, flavorDataSize, asciibuf ); transferred = true; free( asciibuf ); } else CFRelease (flavorData); } } } CFRelease( flavorTypeArray ); } if ( !filenamesPassed.empty() ) { wxCharBuffer buf = filenamesPassed.fn_str(); SetData( wxDF_FILENAME, strlen( buf ), (const char*)buf ); transferred = true; } } } return transferred; }
static void osx_driver_getclipboard_loop( struct ts_display_t *display, struct ts_display_t *to) { if (!clip) PasteboardCreate(kPasteboardClipboard, &clip); if (!clip) return; ts_clipboard_clear(&display->clipboard); CFDataRef cfdata; OSStatus err = noErr; ItemCount nItems; uint32_t i; PasteboardSynchronize(clip); if ((err = PasteboardGetItemCount(clip, &nItems)) != noErr) { V1("apple pasteboard GetItemCount failed\n"); return; } for (i = 1; i <= nItems; ++i) { PasteboardItemID itemID; CFArrayRef flavorTypeArray; CFIndex flavorCount; if ((err = PasteboardGetItemIdentifier(clip, i, &itemID)) != noErr) { V1("can't get pasteboard item identifier\n"); return; } if ((err = PasteboardCopyItemFlavors(clip, itemID, &flavorTypeArray)) != noErr) { V1("Can't copy pasteboard item flavors\n"); return; } flavorCount = CFArrayGetCount(flavorTypeArray); CFIndex flavorIndex; for (flavorIndex = 0; flavorIndex < flavorCount; ++flavorIndex) { CFStringRef flavorType; flavorType = (CFStringRef) CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex); if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text"))) { if ((err = PasteboardCopyItemFlavorData(clip, itemID, CFSTR("public.utf8-plain-text"), &cfdata)) != noErr) { V1("apple pasteboard CopyItem failed\n"); return; } CFIndex length = CFDataGetLength(cfdata); uint8_t * data = malloc(length + 1); CFDataGetBytes(cfdata, CFRangeMake(0, length), data); data[length] = 0; V1 ("%s DATA %d!! '%s'\n", __func__, (int)length, data); ts_clipboard_add(&display->clipboard, "text", data, length); CFRelease(cfdata); } } CFRelease(flavorTypeArray); } if (display->clipboard.flavorCount) ts_display_setclipboard( to, &display->clipboard); }
//****************************************************************************** bool CClipboard::GetString( //Copies the system clipboard string into sClip //Returns: true on success, false otherwise. // //Params: WSTRING& sClip) //(out) { #ifdef WIN32 if (!OpenClipboard(NULL)) return false; HGLOBAL global = GetClipboardData(CF_UNICODETEXT); if (global == NULL) { CloseClipboard(); return false; } LPWSTR data = (LPWSTR)GlobalLock(global); sClip = data; GlobalUnlock(global); CloseClipboard(); return true; #elif defined __APPLE__ PasteboardRef theClipboard; OSStatus err = PasteboardCreate(kPasteboardClipboard, &theClipboard); if (err != noErr) return false; ItemCount itemCount; PasteboardSynchronize(theClipboard); PasteboardGetItemCount(theClipboard, &itemCount); UInt32 itemIndex = 1; PasteboardItemID itemID; PasteboardGetItemIdentifier(theClipboard, itemIndex, &itemID); CFArrayRef flavorTypeArray; PasteboardCopyItemFlavors(theClipboard, itemID, &flavorTypeArray); CFIndex flavorCount = CFArrayGetCount(flavorTypeArray); for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++) { CFStringRef flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex); if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text"))) { CFDataRef flavorData; PasteboardCopyItemFlavorData(theClipboard, itemID, flavorType, &flavorData); //CFIndex flavorDataSize = CFDataGetLength(flavorData); const string str = (char*)CFDataGetBytePtr(flavorData); UTF8ToUCS2(str.c_str(), str.size(), sClip); CFRelease(flavorData); break; } } CFRelease (flavorTypeArray); return true; #elif defined(__linux__) || defined(__FreeBSD__) string u8clip; bool bSuccess; if ((bSuccess = GetStringUTF8(u8clip))) UTF8ToUCS2(u8clip.c_str(), u8clip.length(), sClip); return bSuccess; #elif defined(__native_client__) // Do nothing. return false; #else #error CClipboard::GetString -- Unicode not implemented #endif }
//****************************************************************************** bool CClipboard::GetString( //Copies the system clipboard string into sClip //Returns: true on success, false otherwise. // //Params: string& sClip) //(out) { #ifdef WIN32 if (!OpenClipboard(NULL)) return false; HGLOBAL global = GetClipboardData(CF_TEXT); if (global == NULL) { CloseClipboard(); return false; } LPSTR data = (LPSTR)GlobalLock(global); sClip = data; GlobalUnlock(global); CloseClipboard(); return true; #elif defined(__linux__) || defined(__FreeBSD__) string u8clip; bool bSuccess; if ((bSuccess = GetStringUTF8(u8clip))) UTF8ToAscii(u8clip.c_str(), u8clip.length(), sClip); return bSuccess; #elif defined __APPLE__ ItemCount itemCount; PasteboardRef theClipboard; OSStatus err = PasteboardCreate(kPasteboardClipboard, &theClipboard); if (err != noErr) return false; PasteboardSynchronize( theClipboard ); PasteboardGetItemCount( theClipboard, &itemCount ); UInt32 itemIndex = 1; // should be 1 or the itemCount? PasteboardItemID itemID; CFArrayRef flavorTypeArray; CFIndex flavorCount; PasteboardGetItemIdentifier( theClipboard, itemIndex, &itemID ); PasteboardCopyItemFlavors( theClipboard, itemID, &flavorTypeArray ); flavorCount = CFArrayGetCount( flavorTypeArray ); for(CFIndex flavorIndex = 0 ; flavorIndex < flavorCount; flavorIndex++ ) { CFStringRef flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex ); if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text"))) { CFDataRef flavorData; PasteboardCopyItemFlavorData( theClipboard, itemID,flavorType, &flavorData ); CFIndex flavorDataSize = CFDataGetLength( flavorData ); sClip.resize(flavorDataSize); memcpy(&sClip[0], flavorData, flavorDataSize); CFRelease (flavorData); break; } } CFRelease (flavorTypeArray); return true; #elif defined(__native_client__) return false; #else #warning How do you get system clipboard data on this system? return false; #endif }
// Sorry for the very long code, all nicer OS X APIs are coded in Objective C and not C! // Also it does very thorough error handling bool GetDataFromPasteboard( PasteboardRef inPasteboard, char* flavorText /* out */, const int bufSize ) { OSStatus err = noErr; PasteboardSyncFlags syncFlags; ItemCount itemCount; syncFlags = PasteboardSynchronize( inPasteboard ); //require_action( syncFlags & kPasteboardModified, PasteboardOutOfSync, // err = badPasteboardSyncErr ); err = PasteboardGetItemCount( inPasteboard, &itemCount ); require_noerr( err, CantGetPasteboardItemCount ); for (UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++) { PasteboardItemID itemID; CFArrayRef flavorTypeArray; CFIndex flavorCount; err = PasteboardGetItemIdentifier( inPasteboard, itemIndex, &itemID ); require_noerr( err, CantGetPasteboardItemIdentifier ); err = PasteboardCopyItemFlavors( inPasteboard, itemID, &flavorTypeArray ); require_noerr( err, CantCopyPasteboardItemFlavors ); flavorCount = CFArrayGetCount( flavorTypeArray ); for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++) { CFStringRef flavorType; CFDataRef flavorData; CFIndex flavorDataSize; flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex); // we're only interested by text... if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text"))) { err = PasteboardCopyItemFlavorData( inPasteboard, itemID, flavorType, &flavorData ); require_noerr( err, CantCopyFlavorData ); flavorDataSize = CFDataGetLength( flavorData ); flavorDataSize = (flavorDataSize<254) ? flavorDataSize : 254; if (flavorDataSize+2 > bufSize) { fprintf(stderr, "Cannot copy clipboard, contents is too big!\n"); return false; } for (short dataIndex = 0; dataIndex <= flavorDataSize; dataIndex++) { char byte = *(CFDataGetBytePtr( flavorData ) + dataIndex); flavorText[dataIndex] = byte; } flavorText[flavorDataSize] = '\0'; flavorText[flavorDataSize+1] = '\n'; CFRelease (flavorData); return true; } continue; CantCopyFlavorData: fprintf(stderr, "Cannot copy clipboard, CantCopyFlavorData!\n"); } CFRelease (flavorTypeArray); continue; CantCopyPasteboardItemFlavors: fprintf(stderr, "Cannot copy clipboard, CantCopyPasteboardItemFlavors!\n"); continue; CantGetPasteboardItemIdentifier: fprintf(stderr, "Cannot copy clipboard, CantGetPasteboardItemIdentifier!\n"); continue; } fprintf(stderr, "Cannot copy clipboard, found no acceptable flavour!\n"); return false; CantGetPasteboardItemCount: fprintf(stderr, "Cannot copy clipboard, CantGetPasteboardItemCount!\n"); return false; //PasteboardOutOfSync: fprintf(stderr, "Cannot copy clipboard, PasteboardOutOfSync!\n"); return false; }
void g2LabelEdit::PasteBuffer() { // Win32 implementation #ifdef _WIN32 // Attempt to open clipboard if(!OpenClipboard(GetForegroundWindow())) return; // Get the windows clipboard text buffer HGLOBAL ClipboardHandle = GetClipboardData(CF_TEXT); if(ClipboardHandle != NULL) { // Actually copy the text LPTSTR StringLock = (LPTSTR)GlobalLock(ClipboardHandle); if (StringLock != NULL) { // Copy as much as we can char TempClipBuffer[g2LabelEdit_TextBufferLength]; strncpy(TempClipBuffer, StringLock, g2LabelEdit_TextBufferLength - strlen(TextBuffer) - strlen(StringLock) - 1); // Copy the current text buffer char TempTextBuffer[g2LabelEdit_TextBufferLength]; strcpy(TempTextBuffer, TextBuffer); // Copy into the full buffer (only if text is small enough) if(strlen(TempTextBuffer) + strlen(TempClipBuffer) + 1 < g2LabelEdit_TextBufferLength) { char NewTextBuffer[g2LabelEdit_TextBufferLength]; sprintf(NewTextBuffer, "%s%s", TempTextBuffer, TempClipBuffer); SetText(NewTextBuffer); } // Release the lock GlobalUnlock(StringLock); } } // Close clipboard CloseClipboard(); // OSX implementation #elif __APPLE__ // Allocate or get a reference to the application's active clipboard PasteboardRef ClipboardHandle; if(PasteboardCreate(kPasteboardClipboard, &ClipboardHandle) != noErr) return; // Explicitly update (possibly not needed...) PasteboardSynchronize(ClipboardHandle); // Get the item count ItemCount ClipboardItems; if(PasteboardGetItemCount(ClipboardHandle, &ClipboardItems) != noErr) return; // Keep searching until we find valid text for(ItemCount ItemIndex = 1; ItemIndex <= ClipboardItems; ItemIndex++) { // Get item's ID PasteboardItemID ItemID; if(PasteboardGetItemIdentifier(ClipboardHandle, ItemIndex, &ItemID) != noErr) continue; // Get this item's data types CFArrayRef ItemTypes; if(PasteboardCopyItemFlavors(ClipboardHandle, ItemID, &ItemTypes) != noErr) continue; // For each data type for this clipboard item CFIndex ItemCount = CFArrayGetCount(ItemTypes); for(CFIndex ItemTypeIndex = 0; ItemTypeIndex < ItemCount; ItemTypeIndex++) { // Get the data type CFStringRef ItemType = (CFStringRef)CFArrayGetValueAtIndex(ItemTypes, ItemTypeIndex); // If we have any text-type, then paste and stop if(UTTypeConformsTo(ItemType, CFSTR("public.utf8-plain-text"))) { // Copy from clipboard CFDataRef ItemData; if(PasteboardCopyItemFlavorData(ClipboardHandle, ItemID, ItemType, &ItemData) != noErr) continue; // Paste into active buffer CFIndex DateLength = CFDataGetLength(ItemData); size_t StartIndex = strlen(TextBuffer); char NewTempBuffer[g2LabelEdit_TextBufferLength]; strcpy(NewTempBuffer, TextBuffer); for(CFIndex i = 0; (i < DateLength) && (StartIndex + i < g2LabelEdit_TextBufferLength); i++) { char byte = *(CFDataGetBytePtr(ItemData) + i); NewTempBuffer[StartIndex + i] = byte; } // Cap string and set to current buffer NewTempBuffer[StartIndex + DateLength] = '\0'; SetText(NewTempBuffer); SetCursorPos((int)strlen(NewTempBuffer)); // Release CFRelease(ItemData); // Pasted and done! return; } } } // Not a feature in Linux... #endif }