/** * Inspect the global pasteboard for new content. Check if there is some type * that is supported by vbox and return it. * * @param pPasteboardRef Reference to the global pasteboard. * @param pfFormats Pointer for the bit combination of the * supported types. * @param pbChanged True if something has changed after the * last call. * * @returns IPRT status code. (Always VINF_SUCCESS atm.) */ int queryNewPasteboardFormats(PasteboardRef pPasteboard, uint32_t *pfFormats, bool *pfChanged) { Log(("queryNewPasteboardFormats\n")); OSStatus err = noErr; *pfChanged = true; PasteboardSyncFlags syncFlags; /* Make sure all is in sync */ syncFlags = PasteboardSynchronize(pPasteboard); /* If nothing changed return */ if (!(syncFlags & kPasteboardModified)) { *pfChanged = false; return VINF_SUCCESS; } /* Are some items in the pasteboard? */ ItemCount itemCount; err = PasteboardGetItemCount(pPasteboard, &itemCount); if (itemCount < 1) return VINF_SUCCESS; /* The id of the first element in the pasteboard */ int rc = VINF_SUCCESS; PasteboardItemID itemID; if (!(err = PasteboardGetItemIdentifier(pPasteboard, 1, &itemID))) { /* Retrieve all flavors in the pasteboard, maybe there * is something we can use. */ CFArrayRef flavorTypeArray; if (!(err = PasteboardCopyItemFlavors(pPasteboard, itemID, &flavorTypeArray))) { CFIndex flavorCount; flavorCount = CFArrayGetCount(flavorTypeArray); for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++) { CFStringRef flavorType; flavorType = static_cast <CFStringRef>(CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex)); /* Currently only unicode supported */ if (UTTypeConformsTo(flavorType, kUTTypeUTF8PlainText) || UTTypeConformsTo(flavorType, kUTTypeUTF16PlainText)) { Log(("Unicode flavor detected.\n")); *pfFormats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; } else if (UTTypeConformsTo(flavorType, kUTTypeBMP)) { Log(("BMP flavor detected.\n")); *pfFormats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; } } CFRelease(flavorTypeArray); } } Log(("queryNewPasteboardFormats: rc = %02X\n", rc)); return rc; }
bool QMacPasteboard::hasFlavor(QString c_flavor) const { if (!paste) return false; sync(); ItemCount cnt = 0; if(PasteboardGetItemCount(paste, &cnt) || !cnt) return false; #ifdef DEBUG_PASTEBOARD qDebug("PasteBoard: hasFlavor [%s]", qPrintable(c_flavor)); #endif for(uint index = 1; index <= cnt; ++index) { PasteboardItemID id; if(PasteboardGetItemIdentifier(paste, index, &id) != noErr) return false; PasteboardFlavorFlags flags; if(PasteboardGetItemFlavorFlags(paste, id, QCFString(c_flavor), &flags) == noErr) { #ifdef DEBUG_PASTEBOARD qDebug(" - Found!"); #endif return true; } } #ifdef DEBUG_PASTEBOARD qDebug(" - NotFound!"); #endif return false; }
char* _applegetsnarf(void) { char *s, *t; CFArrayRef flavors; CFDataRef data; CFIndex nflavor, ndata, j; CFStringRef type; ItemCount nitem; PasteboardItemID id; PasteboardSyncFlags flags; UInt32 i; /* fprint(2, "applegetsnarf\n"); */ qlock(&clip.lk); if(clip.apple == nil){ if(PasteboardCreate(kPasteboardClipboard, &clip.apple) != noErr){ fprint(2, "apple pasteboard create failed\n"); qunlock(&clip.lk); return nil; } } flags = PasteboardSynchronize(clip.apple); if(flags&kPasteboardClientIsOwner){ s = strdup(clip.buf); qunlock(&clip.lk); return s; } if(PasteboardGetItemCount(clip.apple, &nitem) != noErr){ fprint(2, "apple pasteboard get item count failed\n"); qunlock(&clip.lk); return nil; } for(i=1; i<=nitem; i++){ if(PasteboardGetItemIdentifier(clip.apple, i, &id) != noErr) continue; if(PasteboardCopyItemFlavors(clip.apple, id, &flavors) != noErr) continue; nflavor = CFArrayGetCount(flavors); for(j=0; j<nflavor; j++){ type = (CFStringRef)CFArrayGetValueAtIndex(flavors, j); if(!UTTypeConformsTo(type, CFSTR("public.utf16-plain-text"))) continue; if(PasteboardCopyItemFlavorData(clip.apple, id, type, &data) != noErr) continue; ndata = CFDataGetLength(data); qunlock(&clip.lk); s = smprint("%.*S", ndata/2, (Rune*)CFDataGetBytePtr(data)); CFRelease(flavors); CFRelease(data); for(t=s; *t; t++) if(*t == '\r') *t = '\n'; return s; } CFRelease(flavors); } qunlock(&clip.lk); return nil; }
bool wxDataObject::HasDataInPasteboard( 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; bool hasData = 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; !hasData && i < formatcount; i++) { // go through the data in our order of preference wxDataFormat dataFormat = array[ i ]; for( UInt32 itemIndex = 1; itemIndex <= itemCount && hasData == 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; !hasData && flavorIndex < flavorCount ; flavorIndex++ ) { CFStringRef flavorType; flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex ); wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); if ( dataFormat == flavorFormat || dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) { hasData = true; } } CFRelease( flavorTypeArray ); } } } return hasData; }
bool wxDataObject::IsFormatInPasteboard( void * pb, const wxDataFormat &dataFormat ) { PasteboardRef pasteboard = (PasteboardRef) pb; bool hasData = false; OSStatus err = noErr; ItemCount itemCount; // we synchronize here once again, so we don't mind which flags get returned PasteboardSynchronize( pasteboard ); err = PasteboardGetItemCount( pasteboard, &itemCount ); if ( err == noErr ) { for( UInt32 itemIndex = 1; itemIndex <= itemCount && hasData == false ; itemIndex++ ) { PasteboardItemID itemID; CFArrayRef flavorTypeArray; CFIndex flavorCount; 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; flavorIndex < flavorCount && hasData == false ; flavorIndex++ ) { CFStringRef flavorType; flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex ); wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); if ( dataFormat == flavorFormat ) hasData = true; else if ( dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) hasData = true; } CFRelease (flavorTypeArray); } } return hasData; }
std::string copy_from_clipboard(const bool) { OSStatus err = noErr; PasteboardRef clipboard; PasteboardSyncFlags syncFlags; ItemCount count; err = PasteboardCreate(kPasteboardClipboard, &clipboard); if (err != noErr) return ""; syncFlags = PasteboardSynchronize(clipboard); if (syncFlags&kPasteboardModified) return ""; err = PasteboardGetItemCount(clipboard, &count); if (err != noErr) return ""; for (UInt32 k = 1; k <= count; k++) { PasteboardItemID itemID; CFArrayRef flavorTypeArray; CFIndex flavorCount; err = PasteboardGetItemIdentifier(clipboard, k, &itemID); if (err != noErr) return ""; err = PasteboardCopyItemFlavors(clipboard, itemID, &flavorTypeArray); if (err != noErr) return ""; flavorCount = CFArrayGetCount(flavorTypeArray); for (CFIndex j = 0; j < flavorCount; j++) { CFStringRef flavorType; CFDataRef flavorData; CFIndex flavorDataSize; flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, j); if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text"))) { err = PasteboardCopyItemFlavorData(clipboard, itemID, flavorType, &flavorData); if (err != noErr) { CFRelease(flavorTypeArray); return ""; } flavorDataSize = CFDataGetLength(flavorData); std::string str; str.reserve(flavorDataSize); str.resize(flavorDataSize); CFDataGetBytes(flavorData, CFRangeMake(0, flavorDataSize), (UInt8 *)str.data()); for (unsigned int i = 0; i < str.size(); ++i) { if (str[i] == '\r') str[i] = '\n'; } return str; } } } return ""; }
QStringList QMacPasteboard::formats() const { if (!paste) return QStringList(); sync(); QStringList ret; ItemCount cnt = 0; if(PasteboardGetItemCount(paste, &cnt) || !cnt) return ret; #ifdef DEBUG_PASTEBOARD qDebug("PasteBoard: Formats [%d]", (int)cnt); #endif 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) { const QString flavor = QCFString::toQString((CFStringRef)CFArrayGetValueAtIndex(types, i)); #ifdef DEBUG_PASTEBOARD qDebug(" -%s", qPrintable(QString(flavor))); #endif QString mimeType = QMacPasteboardMime::flavorToMime(mime_type, flavor); if(!mimeType.isEmpty() && !ret.contains(mimeType)) { #ifdef DEBUG_PASTEBOARD qDebug(" -<%d> %s [%s]", ret.size(), qPrintable(mimeType), qPrintable(QString(flavor))); #endif ret << mimeType; } } } return ret; }
bool QMacPasteboard::hasOSType(int c_flavor) const { if (!paste) return false; sync(); ItemCount cnt = 0; if(PasteboardGetItemCount(paste, &cnt) || !cnt) return false; #ifdef DEBUG_PASTEBOARD qDebug("PasteBoard: hasOSType [%c%c%c%c]", (c_flavor>>24)&0xFF, (c_flavor>>16)&0xFF, (c_flavor>>8)&0xFF, (c_flavor>>0)&0xFF); #endif for(uint index = 1; index <= cnt; ++index) { PasteboardItemID id; if(PasteboardGetItemIdentifier(paste, index, &id) != noErr) return false; QCFType<CFArrayRef> types; if(PasteboardCopyItemFlavors(paste, id, &types ) != noErr) return false; const int type_count = CFArrayGetCount(types); for(int i = 0; i < type_count; ++i) { CFStringRef flavor = (CFStringRef)CFArrayGetValueAtIndex(types, i); const int os_flavor = UTGetOSTypeFromString(UTTypeCopyPreferredTagWithClass(flavor, kUTTagClassOSType)); if(os_flavor == c_flavor) { #ifdef DEBUG_PASTEBOARD qDebug(" - Found!"); #endif return true; } } } #ifdef DEBUG_PASTEBOARD qDebug(" - NotFound!"); #endif return false; }
bool QMacPasteboard::hasFormat(const QString &format) const { if (!paste) return false; sync(); ItemCount cnt = 0; if(PasteboardGetItemCount(paste, &cnt) || !cnt) return false; #ifdef DEBUG_PASTEBOARD qDebug("PasteBoard: hasFormat [%s]", qPrintable(format)); #endif 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) { const QString flavor = QCFString::toQString((CFStringRef)CFArrayGetValueAtIndex(types, i)); #ifdef DEBUG_PASTEBOARD qDebug(" -%s [0x%x]", qPrintable(QString(flavor)), mime_type); #endif QString mimeType = QMacPasteboardMime::flavorToMime(mime_type, flavor); #ifdef DEBUG_PASTEBOARD if(!mimeType.isEmpty()) qDebug(" - %s", qPrintable(mimeType)); #endif if(mimeType == format) return true; } } return false; }
char *TCOD_sys_clipboard_get() { PasteboardSyncFlags syncFlags; ItemCount itemCount; PasteboardRef clipboard; UInt32 itemIndex; if (PasteboardCreate(kPasteboardClipboard, &clipboard) != noErr) return NULL; syncFlags = PasteboardSynchronize(clipboard); if (PasteboardGetItemCount(clipboard, &itemCount) != noErr) return NULL; if (itemCount == 0) return NULL; for(itemIndex = 1; itemIndex <= itemCount; itemIndex++) { PasteboardItemID itemID; CFArrayRef flavorTypeArray; CFIndex flavorCount; CFIndex flavorIndex; if (PasteboardGetItemIdentifier(clipboard, itemIndex, &itemID ) != noErr) return NULL; if (PasteboardCopyItemFlavors(clipboard, itemID, &flavorTypeArray) != noErr) return NULL; flavorCount = CFArrayGetCount(flavorTypeArray); for(flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++) { CFStringRef flavorType; CFDataRef flavorData; CFIndex flavorDataSize; flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex); if (UTTypeConformsTo(flavorType, CFSTR("public.plain-text"))) { if (PasteboardCopyItemFlavorData(clipboard, itemID, flavorType, &flavorData) != noErr) { CFRelease(flavorData); return NULL; } flavorDataSize = CFDataGetLength( flavorData ); flavorDataSize = (flavorDataSize<254) ? flavorDataSize : 254; short dataIndex; for(dataIndex = 0; dataIndex <= flavorDataSize; dataIndex++) { clipboardText[dataIndex] = *(CFDataGetBytePtr(flavorData) + dataIndex); } clipboardText[flavorDataSize] = '\0'; clipboardText[flavorDataSize+1] = '\n'; CFRelease (flavorData); } } } return clipboardText; }
string ClipBoard::getText() { #ifdef TARGET_OSX OSStatus err = noErr; ItemCount itemCount; PasteboardSyncFlags syncFlags; static PasteboardRef inPasteboard = NULL; PasteboardCreate( kPasteboardClipboard, &inPasteboard ); char* data; data = NULL; syncFlags = PasteboardSynchronize( inPasteboard ); err = badPasteboardSyncErr; err = PasteboardGetItemCount( inPasteboard, &itemCount ); require_noerr( err, CantGetPasteboardItemCount ); for( int itemIndex = 1; itemIndex <= itemCount; itemIndex++ ) { PasteboardItemID itemID; CFDataRef flavorData; err = PasteboardGetItemIdentifier( inPasteboard, itemIndex, &itemID ); require_noerr( err, CantGetPasteboardItemIdentifier ); err = PasteboardCopyItemFlavorData( inPasteboard, itemID, CFSTR("public.utf8-plain-text"), &flavorData ); data = (char*)CFDataGetBytePtr(flavorData); CantGetPasteboardItemIdentifier: ; } CantGetPasteboardItemCount: return (string) data; #else ofLog(OF_LOG_WARNING, "ofxGLEditor: sorry, copying to the system clipboard is not supported on your OS yet"); return ""; #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 }
/** * 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; }
/** * Search for content of specified type in guest clipboard buffer and put * it into newly allocated buffer. * * @param pPasteboard Guest PasteBoard reference. * @param fFormat Data formats we are looking for. * @param ppvData Where to return pointer to the received data. M * @param pcbData Where to return the size of the data. * @param pcbAlloc Where to return the size of the memory block * *ppvData pointes to. (Usually greater than *cbData * because the allocation is page aligned.) * @returns IPRT status code. */ static int vbclClipboardReadGuestData(PasteboardRef pPasteboard, CFStringRef sFormat, void **ppvData, uint32_t *pcbData, uint32_t *pcbAlloc) { ItemCount cItems, iItem; OSStatus rc; void *pvData = NULL; uint32_t cbData = 0; uint32_t cbAlloc = 0; AssertPtrReturn(ppvData, VERR_INVALID_POINTER); AssertPtrReturn(pcbData, VERR_INVALID_POINTER); AssertPtrReturn(pcbAlloc, VERR_INVALID_POINTER); rc = PasteboardGetItemCount(pPasteboard, &cItems); AssertReturn(rc == noErr, VERR_INVALID_PARAMETER); AssertReturn(cItems > 0, VERR_INVALID_PARAMETER); /* Walk through all the items in PasteBoard in order to find that one that correcponds to requested data format. */ for (iItem = 1; iItem <= cItems; iItem++) { PasteboardItemID iItemID; CFDataRef flavorData; /* Now, get the item's flavors that corresponds to requested type. */ rc = PasteboardGetItemIdentifier(pPasteboard, iItem, &iItemID); AssertReturn(rc == noErr, VERR_INVALID_PARAMETER); rc = PasteboardCopyItemFlavorData(pPasteboard, iItemID, sFormat, &flavorData); if (rc == noErr) { void *flavorDataPtr = (void *)CFDataGetBytePtr(flavorData); cbData = CFDataGetLength(flavorData); if (flavorDataPtr && cbData > 0) { cbAlloc = RT_ALIGN_32(cbData, PAGE_SIZE); pvData = RTMemPageAllocZ(cbAlloc); if (pvData) memcpy(pvData, flavorDataPtr, cbData); } CFRelease(flavorData); /* Found first matching item, no more search. */ break; } } /* Found match */ if (pvData) { *ppvData = pvData; *pcbData = cbData; *pcbAlloc = cbAlloc; return VINF_SUCCESS; } return VERR_INVALID_PARAMETER; }
/** * Read content from the host clipboard and write it to the internal clipboard * structure for further processing. * * @param pPasteboardRef Reference to the global pasteboard. * @param fFormats The format type which should be read. * @param pv The destination buffer. * @param cb The size of the destination buffer. * @param pcbActual The size which is needed to transfer the content. * * @returns IPRT status code. */ int readFromPasteboard(PasteboardRef pPasteboard, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcbActual) { Log(("readFromPasteboard: fFormat = %02X\n", fFormat)); OSStatus err = noErr; /* Make sure all is in sync */ PasteboardSynchronize(pPasteboard); /* Are some items in the pasteboard? */ ItemCount itemCount; err = PasteboardGetItemCount(pPasteboard, &itemCount); if (itemCount < 1) return VINF_SUCCESS; /* The id of the first element in the pasteboard */ int rc = VERR_NOT_SUPPORTED; PasteboardItemID itemID; if (!(err = PasteboardGetItemIdentifier(pPasteboard, 1, &itemID))) { /* The guest request unicode */ if (fFormat & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) { CFDataRef outData; PRTUTF16 pwszTmp = NULL; /* Try utf-16 first */ if (!(err = PasteboardCopyItemFlavorData(pPasteboard, itemID, kUTTypeUTF16PlainText, &outData))) { Log(("Clipboard content is utf-16\n")); PRTUTF16 pwszString = (PRTUTF16)CFDataGetBytePtr(outData); if (pwszString) rc = RTUtf16DupEx(&pwszTmp, pwszString, 0); else rc = VERR_INVALID_PARAMETER; } /* Second try is utf-8 */ else if (!(err = PasteboardCopyItemFlavorData(pPasteboard, itemID, kUTTypeUTF8PlainText, &outData))) { Log(("readFromPasteboard: clipboard content is utf-8\n")); const char *pszString = (const char *)CFDataGetBytePtr(outData); if (pszString) rc = RTStrToUtf16(pszString, &pwszTmp); else rc = VERR_INVALID_PARAMETER; } if (pwszTmp) { /* Check how much longer will the converted text will be. */ size_t cwSrc = RTUtf16Len(pwszTmp); size_t cwDest; rc = vboxClipboardUtf16GetWinSize(pwszTmp, cwSrc, &cwDest); if (RT_FAILURE(rc)) { RTUtf16Free(pwszTmp); Log(("readFromPasteboard: clipboard conversion failed. vboxClipboardUtf16GetWinSize returned %Rrc. Abandoning.\n", rc)); AssertRCReturn(rc, rc); } /* Set the actually needed data size */ *pcbActual = cwDest * 2; /* Return success state */ rc = VINF_SUCCESS; /* Do not copy data if the dst buffer is not big enough. */ if (*pcbActual <= cb) { rc = vboxClipboardUtf16LinToWin(pwszTmp, RTUtf16Len(pwszTmp), static_cast <PRTUTF16>(pv), cb / 2); if (RT_FAILURE(rc)) { RTUtf16Free(pwszTmp); Log(("readFromPasteboard: clipboard conversion failed. vboxClipboardUtf16LinToWin() returned %Rrc. Abandoning.\n", rc)); AssertRCReturn(rc, rc); } #ifdef SHOW_CLIPBOARD_CONTENT Log(("readFromPasteboard: clipboard content: %ls\n", static_cast <PRTUTF16>(pv))); #endif } /* Free the temp string */ RTUtf16Free(pwszTmp); } } /* The guest request BITMAP */ else if (fFormat & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) { CFDataRef outData; const void *pTmp = NULL; size_t cbTmpSize; /* Get the data from the pasteboard */ if (!(err = PasteboardCopyItemFlavorData(pPasteboard, itemID, kUTTypeBMP, &outData))) { Log(("Clipboard content is BMP\n")); pTmp = CFDataGetBytePtr(outData); cbTmpSize = CFDataGetLength(outData); } if (pTmp) { const void *pDib; size_t cbDibSize; rc = vboxClipboardBmpGetDib(pTmp, cbTmpSize, &pDib, &cbDibSize); if (RT_FAILURE(rc)) { rc = VERR_NOT_SUPPORTED; Log(("readFromPasteboard: unknown bitmap format. vboxClipboardBmpGetDib returned %Rrc. Abandoning.\n", rc)); AssertRCReturn(rc, rc); } *pcbActual = cbDibSize; /* Return success state */ rc = VINF_SUCCESS; /* Do not copy data if the dst buffer is not big enough. */ if (*pcbActual <= cb) { memcpy(pv, pDib, cbDibSize); #ifdef SHOW_CLIPBOARD_CONTENT Log(("readFromPasteboard: clipboard content bitmap %d bytes\n", cbDibSize)); #endif } } } } Log(("readFromPasteboard: rc = %02X\n", rc)); return rc; }
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; } } } // Linux clipboard implementation #elif __linux__ // Paste into UI from linux buffer SetText(__LinuxClipboard); SetCursorPos((int)strlen(__LinuxClipboard)); #endif }
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; }
void AuthKeyWindow::PasteFromClipboard() { bool gotClipboardText = false; // Read key into clipboard #ifdef TARGET_MSVC bool opened = OpenClipboard(NULL); if( opened ) { bool textAvailable = IsClipboardFormatAvailable(CF_TEXT); if( textAvailable ) { HANDLE clipTextHandle = GetClipboardData(CF_TEXT); if( clipTextHandle ) { char *text = (char *) GlobalLock(clipTextHandle); if(clipTextHandle) { strncpy( m_key, text, AUTHENTICATION_KEYLEN-1 ); m_key[AUTHENTICATION_KEYLEN] = '\0'; gotClipboardText = true; GlobalUnlock(text); } } } CloseClipboard(); } #elif TARGET_OS_MACOSX PasteboardRef clipboard = NULL; ItemCount numItems = 0; CFDataRef clipboardData = NULL; CFStringRef clipboardString; PasteboardCreate(kPasteboardClipboard, &clipboard); if ( clipboard ) { PasteboardGetItemCount(clipboard, &numItems); // Use the first item, if it exists. Multiple items are only for drag-and-drop, AFAIK if ( numItems > 0 ) { PasteboardItemID firstItem; PasteboardGetItemIdentifier( clipboard, 1, &firstItem ); PasteboardCopyItemFlavorData( clipboard, firstItem, CFSTR("public.utf16-plain-text"), &clipboardData); if ( clipboardData ) { clipboardString = CFStringCreateWithBytes(NULL, CFDataGetBytePtr(clipboardData), CFDataGetLength(clipboardData), kCFStringEncodingUnicode, false); // Convert to Latin 1 encoding, and copy as much as will fit memset(m_key, 0, sizeof(m_key)); CFStringGetBytes(clipboardString, CFRangeMake(0, CFStringGetLength(clipboardString)), kCFStringEncodingWindowsLatin1, 0, false, (UInt8 *)m_key, AUTHENTICATION_KEYLEN-1, NULL); gotClipboardText = true; CFRelease(clipboardString); CFRelease(clipboardData); } } } CFRelease( clipboard ); #endif // platform specific // Cross-platform code, once we've gotten the clipboard contents into m_key // if ( gotClipboardText ) { strupr( m_key ); Authentication_SetKey( m_key ); Authentication_SaveKey( m_key, App::GetAuthKeyPath() ); } }
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); }
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(); }
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); }
//****************************************************************************** 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 }
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; }
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; }
// 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; }