diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2024-01-26 10:13:40 +0100 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2024-01-26 10:13:40 +0100 |
commit | eb2e62609992ab8b47f8805f2bc2cafce271b66f (patch) | |
tree | 58d6c387f910e3a3348a6528127f4216b524ec57 /src/utils/copynpaste.cpp | |
parent | 05dc1666dc794ed6aa7f6568b768c652f8922c4e (diff) | |
parent | 8d06606835e3d01f537ebe96de8b216e64a1f969 (diff) | |
download | mana-lpc2012.tar.gz mana-lpc2012.tar.bz2 mana-lpc2012.tar.xz mana-lpc2012.zip |
Merge branch 'master' into lpc2012lpc2012
Diffstat (limited to 'src/utils/copynpaste.cpp')
-rw-r--r-- | src/utils/copynpaste.cpp | 310 |
1 files changed, 13 insertions, 297 deletions
diff --git a/src/utils/copynpaste.cpp b/src/utils/copynpaste.cpp index 2bb8fb49..ccb36d79 100644 --- a/src/utils/copynpaste.cpp +++ b/src/utils/copynpaste.cpp @@ -1,7 +1,6 @@ /* - * Retrieve string pasted depending on OS mechanisms. - * Copyright (C) 2001-2010 Wormux Team - * Copyright (C) 2010-2012 The Mana Developers + * Clipboard Interaction. + * Copyright (C) 2010-2024 The Mana Developers * * This file is part of The Mana Client. * @@ -19,301 +18,18 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* - * IMPORTANT! - * - * This code was taken from Wormux svn trunk at Feb 25 2010. Please don't - * make any unnecessary modifications, and try to sync up modifications - * when possible. - */ - -#ifdef _MSC_VER -# include "msvc/config.h" -#elif defined(HAVE_CONFIG_H) -# include "config.h" -#endif - -#include <SDL_syswm.h> -#include "copynpaste.h" - -#ifdef _WIN32 -bool RetrieveBuffer(std::string& text, std::string::size_type& pos) -{ - bool ret = false; - - if (!OpenClipboard(NULL)) - return false; - - HANDLE h = GetClipboardData(CF_UNICODETEXT); - if (h) - { - LPCWSTR data = (LPCWSTR)GlobalLock(h); +#include "utils/copynpaste.h" - if (data) - { - int len = WideCharToMultiByte(CP_UTF8, 0, data, -1, NULL, 0, NULL, NULL); - if (len > 0) - { - // Convert from UTF-16 to UTF-8 - void *temp = malloc(len); - if (WideCharToMultiByte(CP_UTF8, 0, data, -1, (LPSTR)temp, len, NULL, NULL)) - { - text.insert(pos, (char*)temp); - pos += len-1; - } - free(temp); - ret = true; - } - } - GlobalUnlock(h); - } - else - { - h = GetClipboardData(CF_TEXT); - - if (h) - { - const char *data = (char*)GlobalLock(h); - if (data) - { - text.insert(pos, data); - pos += strlen(data); - ret = true; - } - GlobalUnlock(h); - } - } - - CloseClipboard(); - return ret; -} -#elif defined(__APPLE__) +#include <SDL.h> -#ifdef Status -#undef Status -#endif - -#include <Carbon/Carbon.h> - -// 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 ) +bool insertFromClipboard(std::string &text, std::string::size_type &pos) { - 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; -} - -bool getClipBoard(char* text /* out */, const int bufSize ) -{ - OSStatus err = noErr; - - PasteboardRef theClipboard; - err = PasteboardCreate( kPasteboardClipboard, &theClipboard ); - require_noerr( err, PasteboardCreateFailed ); - - if (!GetDataFromPasteboard(theClipboard, text, bufSize)) - { - fprintf(stderr, "Cannot copy clipboard, GetDataFromPasteboardFailed!\n"); - return false; - } - - CFRelease(theClipboard); - - return true; - - // ---- error handling - PasteboardCreateFailed: fprintf(stderr, "Cannot copy clipboard, PasteboardCreateFailed!\n"); - CFRelease(theClipboard); - return false; -} - -bool RetrieveBuffer(std::string& text, std::string::size_type& pos) -{ - const int bufSize = 512; - char buffer[bufSize]; - - if (getClipBoard(buffer, bufSize)) - { - text = buffer; - pos += strlen(buffer); - return true; - } - else - { - return false; - } -} - -#elif USE_X11 -static char* getSelection(Display *dpy, Window us, Atom selection) -{ - int max_events = 50; - Window owner = XGetSelectionOwner (dpy, selection); - int ret; - - //printf("XConvertSelection on %s\n", XGetAtomName(dpy, selection)); - if (owner == None) - { - //printf("No owner\n"); - return NULL; - } - XConvertSelection(dpy, selection, XA_STRING, XA_PRIMARY, us, CurrentTime); - XFlush(dpy); - - while (max_events--) - { - XEvent e; - - XNextEvent(dpy, &e); - if(e.type == SelectionNotify) - { - //printf("Received %s\n", XGetAtomName(dpy, e.xselection.selection)); - if(e.xselection.property == None) - { - //printf("Couldn't convert\n"); - return NULL; - } - - long unsigned len, left, dummy; - int format; - Atom type; - unsigned char *data = NULL; - - XGetWindowProperty(dpy, us, e.xselection.property, 0, 0, False, - AnyPropertyType, &type, &format, &len, &left, &data); - if (left < 1) - return NULL; - - ret = XGetWindowProperty(dpy, us, e.xselection.property, 0, left, False, - AnyPropertyType, &type, &format, &len, &dummy, &data); - if (ret != Success) - { - //printf("Failed to get property: %p on %lu\n", data, len); - return NULL; - } - - //printf(">>> Got %s: len=%lu left=%lu (event %i)\n", data, len, left, 50-max_events); - return (char*)data; - } - } - return NULL; -} - -bool RetrieveBuffer(std::string& text, std::string::size_type& pos) -{ - SDL_SysWMinfo info; - - //printf("Retrieving buffer...\n"); - SDL_VERSION(&info.version); - if ( SDL_GetWMInfo(&info) ) - { - Display *dpy = info.info.x11.display; - Window us = info.info.x11.window; - char *data = NULL; - - if (!data) - { - data = getSelection(dpy, us, XA_PRIMARY); - } - if (!data) - { - data = getSelection(dpy, us, XA_SECONDARY); - } - if (!data) - { - Atom XA_CLIPBOARD = XInternAtom(dpy, "CLIPBOARD", 0); - data = getSelection(dpy, us, XA_CLIPBOARD); - } - if (data) - { - // check cursor position - if (pos > text.size()) { - pos = text.size(); - } - - text.insert(pos, data); - pos += strlen(data); - XFree(data); - - return true; - } - } - return false; + char *buf = SDL_GetClipboardText(); + const size_t len = strlen(buf); + if (len > 0) { + text.insert(pos, buf); + pos += len; + } + SDL_free(buf); + return len > 0; } -#else -bool RetrieveBuffer(std::string&, std::string::size_type&) { return false; } -#endif |