summaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/copynpaste.cpp319
-rw-r--r--src/utils/copynpaste.h33
-rw-r--r--src/utils/mkdir.cpp101
-rw-r--r--src/utils/mkdir.h26
-rw-r--r--src/utils/specialfolder.cpp78
-rw-r--r--src/utils/specialfolder.h30
6 files changed, 587 insertions, 0 deletions
diff --git a/src/utils/copynpaste.cpp b/src/utils/copynpaste.cpp
new file mode 100644
index 00000000..31aa7bf9
--- /dev/null
+++ b/src/utils/copynpaste.cpp
@@ -0,0 +1,319 @@
+/*
+ * Retrieve string pasted depending on OS mechanisms.
+ * Copyright (C) 2001-2010 Wormux Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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);
+
+ 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__)
+
+#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 )
+{
+ 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;
+ }
+ }
+ printf("Timeout\n");
+ 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;
+}
+#else
+bool RetrieveBuffer(std::string&, std::string::size_type&) { return false; }
+#endif
diff --git a/src/utils/copynpaste.h b/src/utils/copynpaste.h
new file mode 100644
index 00000000..1a7c81d0
--- /dev/null
+++ b/src/utils/copynpaste.h
@@ -0,0 +1,33 @@
+/*
+ * Retrieve string pasted depending on OS mechanisms.
+ * Copyright (C) 2001-2010 Wormux Team
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string>
+
+/**
+ * Attempts to retrieve text from the clipboard buffer and inserts it in
+ * \a text at position \pos. The characters are encoded in utf-8.
+ *
+ * Implemented for Windows, X11 and Mac OS X.
+ *
+ * @return <code>true</code> when successful or <code>false</code> when there
+ * was a problem retrieving the clipboard buffer.
+ */
+bool RetrieveBuffer(std::string& text, std::string::size_type& pos);
+
diff --git a/src/utils/mkdir.cpp b/src/utils/mkdir.cpp
new file mode 100644
index 00000000..223abe71
--- /dev/null
+++ b/src/utils/mkdir.cpp
@@ -0,0 +1,101 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <climits>
+#include <cstring>
+#include <cerrno>
+
+#if defined WIN32
+#include <windows.h>
+#else
+#include <sys/stat.h>
+#endif
+
+#ifdef _MKDIR_TEST_
+// compile with -D_MKDIR_TEST_ to get a standalone binary
+#include <cstdio>
+#include <cstdlib>
+#endif
+
+#include "mkdir.h"
+
+int mkdir_r(const char *pathname) {
+ char tmp[PATH_MAX];
+ char *p;
+
+ if (strlen(pathname) >= PATH_MAX-2)
+ return -1;
+
+ strncpy(tmp, pathname, sizeof(tmp)-1);
+ tmp[PATH_MAX-1] = '\0';
+
+ int len=strlen(tmp);
+
+ // terminate the pathname with '/'
+ if (tmp[len-1] != '/') {
+ tmp[len] = '/';
+ tmp[len+1] = '\0';
+ }
+
+ for (p=tmp; *p; p++) {
+#if defined WIN32
+ if (*p == '/' || *p == '\\')
+#else
+ if (*p == '/')
+#endif
+ {
+ *p = '\0';
+ // ignore a slash at the beginning of a path
+ if (strlen(tmp) == 0){
+ *p = '/';
+ continue;
+ }
+#if defined WIN32
+ if (!CreateDirectory(tmp, 0) &&
+ GetLastError() != ERROR_ALREADY_EXISTS)
+#else
+ if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) &&
+ errno != EEXIST)
+#endif
+ {
+#if defined WIN32
+ // hack, hack. just assume that x: might be a drive
+ // letter, and try again
+ if (!(strlen(tmp) == 2 &&
+ !strcmp(tmp + 1, ":")))
+#endif
+ return -1;
+ }
+
+#ifdef _MKDIR_TEST_
+ printf("%s\n", tmp);
+#endif
+ *p = '/';
+ }
+ }
+ return 0;
+}
+
+#ifdef _MKDIR_TEST_
+int main(int argc, char** argv) {
+ if (argc < 2) exit(1);
+ mkdir_r(argv[1]);
+}
+#endif
diff --git a/src/utils/mkdir.h b/src/utils/mkdir.h
new file mode 100644
index 00000000..9369b4e7
--- /dev/null
+++ b/src/utils/mkdir.h
@@ -0,0 +1,26 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _MKDIR_H
+#define _MKDIR_H
+
+int mkdir_r(const char *pathname);
+
+#endif
diff --git a/src/utils/specialfolder.cpp b/src/utils/specialfolder.cpp
new file mode 100644
index 00000000..64607716
--- /dev/null
+++ b/src/utils/specialfolder.cpp
@@ -0,0 +1,78 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef WIN32
+#include "specialfolder.h"
+#include <windows.h>
+
+#ifdef _SPECIALFOLDERLOCATION_TEST_
+// compile with -D_SPECIALFOLDERLOCATION_TEST_ to get a standalone
+// binary for testing
+#include <iostream>
+#endif
+
+/*
+ * Retrieve the pathname of special folders on win32, or an empty string
+ * on error / if the folder does not exist.
+ * See http://msdn.microsoft.com/en-us/library/bb762494(VS.85).aspx for
+ * a list of folder ids
+ */
+std::string getSpecialFolderLocation(int folderId)
+{
+ std::string ret;
+ LPITEMIDLIST pItemIdList;
+ LPMALLOC pMalloc;
+ char szPath[_MAX_PATH];
+
+ // get the item ID list for folderId
+ HRESULT hr = SHGetSpecialFolderLocation(NULL, folderId, &pItemIdList);
+ if (hr != S_OK)
+ return ret;
+
+ // convert the ID list into a file system path
+ if (SHGetPathFromIDList(pItemIdList, szPath) == FALSE)
+ return ret;
+
+ // get the IMalloc pointer and free all resources we used
+ hr = SHGetMalloc(&pMalloc);
+ pMalloc->Free(pItemIdList);
+ pMalloc->Release();
+
+ ret = szPath;
+ return ret;
+}
+
+#ifdef _SPECIALFOLDERLOCATION_TEST_
+int main()
+{
+ std::cout << "APPDATA " << getSpecialFolderLocation(CSIDL_APPDATA)
+ << std::endl;
+ std::cout << "DESKTOP " << getSpecialFolderLocation(CSIDL_DESKTOP)
+ << std::endl;
+ std::cout << "LOCAL_APPDATA "
+ << getSpecialFolderLocation(CSIDL_LOCAL_APPDATA)
+ << std::endl;
+ std::cout << "MYPICTURES " << getSpecialFolderLocation(CSIDL_MYPICTURES)
+ << std::endl;
+ std::cout << "PERSONAL " << getSpecialFolderLocation(CSIDL_PERSONAL)
+ << std::endl;
+}
+#endif
+#endif
diff --git a/src/utils/specialfolder.h b/src/utils/specialfolder.h
new file mode 100644
index 00000000..c2c2e0be
--- /dev/null
+++ b/src/utils/specialfolder.h
@@ -0,0 +1,30 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SPECIALFOLDER_H
+#define _SPECIALFOLDER_H
+
+#ifdef WIN32
+#include <shlobj.h>
+#include <string>
+std::string getSpecialFolderLocation(int folderId);
+#endif
+
+#endif