diff --git a/include/SFML/Window.hpp b/include/SFML/Window.hpp index eefe2678..9fd13b30 100644 --- a/include/SFML/Window.hpp +++ b/include/SFML/Window.hpp @@ -30,6 +30,7 @@ //////////////////////////////////////////////////////////// #include +#include #include #include #include diff --git a/include/SFML/Window/Clipboard.hpp b/include/SFML/Window/Clipboard.hpp new file mode 100644 index 00000000..696d8a0e --- /dev/null +++ b/include/SFML/Window/Clipboard.hpp @@ -0,0 +1,108 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_CLIPBOARD_HPP +#define SFML_CLIPBOARD_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// \brief Give access to the system clipboard +/// +//////////////////////////////////////////////////////////// +class SFML_WINDOW_API Clipboard +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Get the content of the clipboard as string data + /// + /// This function returns the content of the clipboard + /// as a string. If the clipboard does not contain string + /// it returns an empty sf::String object. + /// + /// \return Clipboard contents as sf::String object + /// + //////////////////////////////////////////////////////////// + static String getString(); + + //////////////////////////////////////////////////////////// + /// \brief Set the content of the clipboard as string data + /// + /// This function sets the content of the clipboard as a + /// string. + /// + /// \param text sf::String containing the data to be sent + /// to the clipboard + /// + //////////////////////////////////////////////////////////// + static void setString(const String& text); +}; + +} // namespace sf + + +#endif // SFML_CLIPBOARD_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::Clipboard +/// \ingroup window +/// +/// sf::Clipboard provides an interface for getting and +/// setting the contents of the system clipboard. +/// +/// Usage example: +/// \code +/// // get the clipboard content as a string +/// sf::String string = sf::Clipboard::getString(); +/// +/// // or use it in the event loop +/// sf::Event event; +/// while(window.pollEvent(event)) +/// { +/// if(event.type == sf::Event::Closed) +/// window.close(); +/// if(event.type == sf::Event::KeyPressed) +/// { +/// // Using Ctrl + V to paste a string into SFML +/// if(event.key.control && event.key.code == sf::Keyboard::V) +/// string = sf::Clipboard::getString(); +/// } +/// } +/// +/// // set the clipboard to a string +/// sf::Clipboard::setString("Hello World!"); +/// \endcode +/// +/// \see sf::String, sf::Event +/// +//////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/Android/ClipboardImpl.cpp b/src/SFML/Window/Android/ClipboardImpl.cpp new file mode 100644 index 00000000..47ed608f --- /dev/null +++ b/src/SFML/Window/Android/ClipboardImpl.cpp @@ -0,0 +1,127 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include + +namespace sf +{ +namespace priv +{ +//////////////////////////////////////////////////////////// +String ClipboardImpl::getString() +{ + String content; + + ActivityStates* states = getActivity(NULL); + Lock lock(states->mutex); + + // Initializes JNI + jint lResult; + jint lFlags = 0; + + JavaVM* lJavaVM = states->activity->vm; + JNIEnv* lJNIEnv = states->activity->env; + + JavaVMAttachArgs lJavaVMAttachArgs; + lJavaVMAttachArgs.version = JNI_VERSION_1_6; + lJavaVMAttachArgs.name = "NativeThread"; + lJavaVMAttachArgs.group = NULL; + + lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs); + + if (lResult == JNI_ERR) + err() << "Failed to initialize JNI, couldn't switch the keyboard visibility" << std::endl; + + // Retrieves NativeActivity + jobject lNativeActivity = states->activity->clazz; + jclass ClassNativeActivity = lJNIEnv->GetObjectClass(lNativeActivity); + + // Retrieves Context.CLIPBOARD_SERVICE + jclass ClassContext = lJNIEnv->FindClass("android/content/Context"); + jfieldID FieldCLIPBOARD_SERVICE = lJNIEnv->GetStaticFieldID(ClassContext, + "CLIPBOARD_SERVICE", "Ljava/lang/String;"); + jobject CLIPBOARD_SERVICE = lJNIEnv->GetStaticObjectField(ClassContext, + FieldCLIPBOARD_SERVICE); + lJNIEnv->DeleteLocalRef(ClassContext); + + // Runs getSystemService(Context.CLIPBOARD_SERVICE) + jclass ClassInputMethodManager = + lJNIEnv->FindClass("android/view/inputmethod/InputMethodManager"); + jmethodID MethodGetSystemService = lJNIEnv->GetMethodID(ClassNativeActivity, + "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"); + jobject lInputMethodManager = lJNIEnv->CallObjectMethod(lNativeActivity, + MethodGetSystemService, CLIPBOARD_SERVICE); + lJNIEnv->DeleteLocalRef(CLIPBOARD_SERVICE); + + /*if (visible) + { + // Runs lInputMethodManager.showSoftInput(...) + jmethodID MethodShowSoftInput = lJNIEnv->GetMethodID(ClassInputMethodManager, + "showSoftInput", "(Landroid/view/View;I)Z"); + jboolean lResult = lJNIEnv->CallBooleanMethod(lInputMethodManager, + MethodShowSoftInput, lDecorView, lFlags); + } + else + { + // Runs lWindow.getViewToken() + jclass ClassView = lJNIEnv->FindClass("android/view/View"); + jmethodID MethodGetWindowToken = lJNIEnv->GetMethodID(ClassView, + "getWindowToken", "()Landroid/os/IBinder;"); + jobject lBinder = lJNIEnv->CallObjectMethod(lDecorView, + MethodGetWindowToken); + lJNIEnv->DeleteLocalRef(ClassView); + + // lInputMethodManager.hideSoftInput(...) + jmethodID MethodHideSoftInput = lJNIEnv->GetMethodID(ClassInputMethodManager, + "hideSoftInputFromWindow", "(Landroid/os/IBinder;I)Z"); + jboolean lRes = lJNIEnv->CallBooleanMethod(lInputMethodManager, + MethodHideSoftInput, lBinder, lFlags); + lJNIEnv->DeleteLocalRef(lBinder); + }*/ + lJNIEnv->DeleteLocalRef(ClassNativeActivity); + lJNIEnv->DeleteLocalRef(ClassInputMethodManager); + + // Finished with the JVM + lJavaVM->DetachCurrentThread(); + + return content; +} + + +//////////////////////////////////////////////////////////// +void ClipboardImpl::setString(const String& text) +{ + sf::err() << "Clipboard API not implemented for Android.\n"; +} + +} // namespace priv + +} // namespace sf diff --git a/src/SFML/Window/Android/ClipboardImpl.hpp b/src/SFML/Window/Android/ClipboardImpl.hpp new file mode 100644 index 00000000..f661bed5 --- /dev/null +++ b/src/SFML/Window/Android/ClipboardImpl.hpp @@ -0,0 +1,76 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_CLIPBOARDIMPLANDROID_HPP +#define SFML_CLIPBOARDIMPLANDROID_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +namespace sf +{ +namespace priv +{ +//////////////////////////////////////////////////////////// +/// \brief Give access to the system clipboard +/// +//////////////////////////////////////////////////////////// +class ClipboardImpl +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Get the content of the clipboard as string data + /// + /// This function returns the content of the clipboard + /// as a string. If the clipboard does not contain string + /// it returns an empty sf::String object. + /// + /// \return Current content of the clipboard + /// + //////////////////////////////////////////////////////////// + static String getString(); + + //////////////////////////////////////////////////////////// + /// \brief Set the content of the clipboard as string data + /// + /// This function sets the content of the clipboard as a + /// string. + /// + /// \param text sf::String object containing the data to be sent + /// to the clipboard + /// + //////////////////////////////////////////////////////////// + static void setString(const String& text); +}; + +} // namespace priv + +} // namespace sf + + +#endif // SFML_CLIPBOARDIMPLANDROID_HPP diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index a887766e..17efded0 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -4,6 +4,9 @@ set(SRCROOT ${PROJECT_SOURCE_DIR}/src/SFML/Window) # all source files set(SRC + ${INCROOT}/Clipboard.hpp + ${SRCROOT}/Clipboard.cpp + ${SRCROOT}/ClipboardImpl.hpp ${SRCROOT}/Context.cpp ${INCROOT}/Context.hpp ${INCROOT}/Export.hpp @@ -51,6 +54,8 @@ source_group("" FILES ${SRC}) # add platform specific sources if(SFML_OS_WINDOWS) set(PLATFORM_SRC + ${SRCROOT}/Win32/ClipboardImpl.hpp + ${SRCROOT}/Win32/ClipboardImpl.cpp ${SRCROOT}/Win32/WglContext.cpp ${SRCROOT}/Win32/WglContext.hpp ${SRCROOT}/Win32/WglExtensions.cpp @@ -71,6 +76,8 @@ if(SFML_OS_WINDOWS) add_definitions(-DUNICODE -D_UNICODE) elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD) set(PLATFORM_SRC + ${SRCROOT}/Unix/ClipboardImpl.hpp + ${SRCROOT}/Unix/ClipboardImpl.cpp ${SRCROOT}/Unix/Display.cpp ${SRCROOT}/Unix/Display.hpp ${SRCROOT}/Unix/InputImpl.cpp @@ -110,6 +117,8 @@ elseif(SFML_OS_MACOSX) ${SRCROOT}/OSX/cpp_objc_conversion.mm ${SRCROOT}/OSX/cg_sf_conversion.hpp ${SRCROOT}/OSX/cg_sf_conversion.mm + ${SRCROOT}/OSX/ClipboardImpl.hpp + ${SRCROOT}/OSX/ClipboardImpl.mm ${SRCROOT}/OSX/InputImpl.mm ${SRCROOT}/OSX/InputImpl.hpp ${SRCROOT}/OSX/HIDInputManager.hpp @@ -155,6 +164,8 @@ elseif(SFML_OS_MACOSX) source_group("mac" FILES ${PLATFORM_SRC}) elseif(SFML_OS_IOS) set(PLATFORM_SRC + ${SRCROOT}/iOS/ClipboardImpl.mm + ${SRCROOT}/iOS/ClipboardImpl.hpp ${SRCROOT}/iOS/EaglContext.mm ${SRCROOT}/iOS/EaglContext.hpp ${SRCROOT}/iOS/InputImpl.mm @@ -179,6 +190,8 @@ elseif(SFML_OS_IOS) source_group("ios" FILES ${PLATFORM_SRC}) elseif(SFML_OS_ANDROID) set(PLATFORM_SRC + ${SRCROOT}/Android/ClipboardImpl.hpp + ${SRCROOT}/Android/ClipboardImpl.cpp ${SRCROOT}/Android/WindowImplAndroid.hpp ${SRCROOT}/Android/WindowImplAndroid.cpp ${SRCROOT}/Android/VideoModeImpl.cpp diff --git a/src/SFML/Window/Clipboard.cpp b/src/SFML/Window/Clipboard.cpp new file mode 100644 index 00000000..ee7b8456 --- /dev/null +++ b/src/SFML/Window/Clipboard.cpp @@ -0,0 +1,48 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +String Clipboard::getString() +{ + return priv::ClipboardImpl::getString(); +} + + +//////////////////////////////////////////////////////////// +void Clipboard::setString(const String& text) +{ + return priv::ClipboardImpl::setString(text); +} + +} // namespace sf diff --git a/src/SFML/Window/ClipboardImpl.hpp b/src/SFML/Window/ClipboardImpl.hpp new file mode 100644 index 00000000..4d9c9196 --- /dev/null +++ b/src/SFML/Window/ClipboardImpl.hpp @@ -0,0 +1,45 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_CLIPBOARDIMPL_HPP +#define SFML_CLIPBOARDIMPL_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#if defined(SFML_SYSTEM_WINDOWS) + #include +#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) + #include +#elif defined(SFML_SYSTEM_MACOS) + #include +#elif defined(SFML_SYSTEM_IOS) + #include +#elif defined(SFML_SYSTEM_ANDROID) + #include +#endif + +#endif // SFML_CLIPBOARDIMPL_HPP diff --git a/src/SFML/Window/OSX/ClipboardImpl.hpp b/src/SFML/Window/OSX/ClipboardImpl.hpp new file mode 100644 index 00000000..65f55784 --- /dev/null +++ b/src/SFML/Window/OSX/ClipboardImpl.hpp @@ -0,0 +1,78 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_CLIPBOARDIMPLCOCOA_HPP +#define SFML_CLIPBOARDIMPLCOCOA_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +namespace sf +{ +namespace priv +{ + +//////////////////////////////////////////////////////////// +/// \brief Give access to the system clipboard +/// +//////////////////////////////////////////////////////////// +class ClipboardImpl +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Get the content of the clipboard as string data + /// + /// This function returns the content of the clipboard + /// as a string. If the clipboard does not contain string + /// it returns an empty sf::String object. + /// + /// \return Current content of the clipboard + /// + //////////////////////////////////////////////////////////// + static String getString(); + + //////////////////////////////////////////////////////////// + /// \brief Set the content of the clipboard as string data + /// + /// This function sets the content of the clipboard as a + /// string. + /// + /// \param text sf::String object containing the data to be sent + /// to the clipboard + /// + //////////////////////////////////////////////////////////// + static void setString(const String& text); +}; + +} // namespace priv + +} // namespace sf + + +#endif // SFML_CLIPBOARDIMPLCOCOA_HPP + diff --git a/src/SFML/Window/OSX/ClipboardImpl.mm b/src/SFML/Window/OSX/ClipboardImpl.mm new file mode 100644 index 00000000..49709982 --- /dev/null +++ b/src/SFML/Window/OSX/ClipboardImpl.mm @@ -0,0 +1,68 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#import + +namespace sf +{ +namespace priv +{ + +//////////////////////////////////////////////////////////// +String ClipboardImpl::getString() +{ + NSPasteboard* pboard = [NSPasteboard generalPasteboard]; + NSString* data = [pboard stringForType:NSPasteboardTypeString]; + + char const* utf8 = [data cStringUsingEncoding:NSUTF8StringEncoding]; + NSUInteger length = [data lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + return String::fromUtf8(utf8, utf8 + length); +} + + +//////////////////////////////////////////////////////////// +void ClipboardImpl::setString(const String& text) +{ + std::basic_string utf8 = text.toUtf8(); + NSString* data = [[NSString alloc] initWithBytes:utf8.data() + length:utf8.length() + encoding:NSUTF8StringEncoding]; + + NSPasteboard* pboard = [NSPasteboard generalPasteboard]; + [pboard declareTypes:@[NSPasteboardTypeString] owner:nil]; + BOOL ok = [pboard setString:data forType:NSPasteboardTypeString]; + + [data release]; +} + +} // namespace priv + +} // namespace sf + diff --git a/src/SFML/Window/Unix/ClipboardImpl.cpp b/src/SFML/Window/Unix/ClipboardImpl.cpp new file mode 100644 index 00000000..3069e07a --- /dev/null +++ b/src/SFML/Window/Unix/ClipboardImpl.cpp @@ -0,0 +1,261 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include +#include +#include + + +namespace +{ +//////////////////////////////////////////////////////////// +void initClipboard(); +void* hostSelection(void*); + +sf::String string; + +pthread_mutex_t mutex; +pthread_t host_thread; + +bool is_fail = false; +bool is_init = false; +bool is_host = false; + +Display* display = NULL; +Window window = 0; + +Atom selection = 0; +Atom atom_targ = 0; +Atom atom_text = 0; +Atom utf8_text = 0; +int xa_string = 31; +int xa_atom = 4; + +//////////////////////////////////////////////////////////// +void initClipboard() +{ + is_init = true; + + display = XOpenDisplay(NULL); + int screen = DefaultScreen(display); + window = XCreateSimpleWindow(display, RootWindow(display, screen), + 0, 0, 1, 1, 0, BlackPixel(display, screen), WhitePixel(display, screen)); + + selection = XInternAtom(display, "CLIPBOARD", false); + atom_targ = XInternAtom(display, "TARGETS", false); + atom_text = XInternAtom(display, "TEXT", false); + utf8_text = XInternAtom(display, "UTF8_STRING", true); + + if(utf8_text == None) + { + std::cerr << "UTF-8 format unavailable on clipboard." << std::endl; + utf8_text = xa_string; + } + + if(pthread_mutex_init(&mutex, NULL)) + { + is_fail = true; + std::cerr << "Unable to initialize mutex. Failed to initialize clipboard." << std::endl; + return; + } + + if(pthread_create(&host_thread, NULL, hostSelection, NULL)) + { + is_fail = true; + std::cerr << "Unable to create host thread. Failed to initialize clipboard." << std::endl; + return; + } +} + +//////////////////////////////////////////////////////////// +void* hostSelection(void*) +{ + while(true) + { + if(XPending(display) && is_host) + { + XEvent event; + + pthread_mutex_lock(&mutex); + XNextEvent(display, &event); + pthread_mutex_unlock(&mutex); + + switch(event.type) + { + case SelectionClear: + { + pthread_mutex_lock(&mutex); + is_host = false; + pthread_mutex_unlock(&mutex); + + break; + } + case SelectionRequest: + { + if(event.xselectionrequest.selection == selection) + { + XSelectionRequestEvent* sel_req_event = &event.xselectionrequest; + XSelectionEvent sel_event = {0}; + + int result = 0; + sel_event.type = SelectionNotify, + sel_event.display = sel_req_event->display, + sel_event.requestor = sel_req_event->requestor, + sel_event.selection = sel_req_event->selection, + sel_event.time = sel_req_event->time, + sel_event.target = sel_req_event->target, + sel_event.property = sel_req_event->property; + + std::basic_string str = string.toUtf8(); + + if(sel_event.target == atom_targ) + result = XChangeProperty(sel_event.display, sel_event.requestor, + sel_event.property, xa_atom, 32, PropModeReplace, + reinterpret_cast(&utf8_text), 1); + else if(sel_event.target == xa_string || sel_event.target == atom_text) + result = XChangeProperty(sel_event.display, sel_event.requestor, + sel_event.property, xa_string, 8, PropModeReplace, + reinterpret_cast(&str[0]), str.size()); + else if(sel_event.target == utf8_text) + result = XChangeProperty(sel_event.display, sel_event.requestor, + sel_event.property, utf8_text, 8, PropModeReplace, + reinterpret_cast(&str[0]), str.size()); + else + sel_event.property = None; + + if((result & 2) == 0) + XSendEvent(display, sel_event.requestor, 0, 0, + reinterpret_cast(&sel_event)); + } + break; + } + default: break; + } + } + else + sf::sleep(sf::milliseconds(20)); + } +} +} + +namespace sf +{ +namespace priv +{ + +//////////////////////////////////////////////////////////// +String ClipboardImpl::getString() +{ + if(!is_init) + initClipboard(); + + if(is_fail || is_host) + return string; + + // Dangerous! Wipes all previous events! + XSync(display, true); + XConvertSelection(display, selection, utf8_text, atom_text, window, CurrentTime); + + XEvent event; + + pthread_mutex_lock(&mutex); + XNextEvent(display, &event); + pthread_mutex_unlock(&mutex); + + if(event.type == SelectionNotify) + { + if(event.xselection.selection != selection || event.xselection.target != utf8_text) + { + std::cerr << "Failed to convert selection." << std::endl; + return string; + } + + if(event.xselection.property) + { + Atom target; + int format; + unsigned long size; + unsigned long byte_left; + unsigned char* data; + + XGetWindowProperty(event.xselection.display, + event.xselection.requestor, event.xselection.property, + 0L, (~0L), false, AnyPropertyType, + &target, &format, &size, &byte_left, &data); + + if(target == utf8_text) + { + std::basic_string str(data, size); + string = sf::String::fromUtf8(str.begin(), str.end()); + + XFree(data); + } + + XDeleteProperty(event.xselection.display, event.xselection.requestor, event.xselection.property); + } + } + + return string; +} + + +//////////////////////////////////////////////////////////// +void ClipboardImpl::setString(const String& text) +{ + if(!is_init) + initClipboard(); + + if(is_fail) + return; + + if(!is_host) + { + XSetSelectionOwner(display, selection, window, CurrentTime); + + if(XGetSelectionOwner(display, selection) != window) + { + std::cerr << "Unable to get ownership of selection." << std::endl; + return; + } + + pthread_mutex_lock(&mutex); + is_host = true; + pthread_mutex_unlock(&mutex); + } + + pthread_mutex_lock(&mutex); + string = text; + pthread_mutex_unlock(&mutex); +} + +} // namespace priv + +} // namespace sf diff --git a/src/SFML/Window/Unix/ClipboardImpl.hpp b/src/SFML/Window/Unix/ClipboardImpl.hpp new file mode 100644 index 00000000..2dd27a3c --- /dev/null +++ b/src/SFML/Window/Unix/ClipboardImpl.hpp @@ -0,0 +1,77 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_CLIPBOARDIMPLX11_HPP +#define SFML_CLIPBOARDIMPLX11_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +namespace sf +{ +namespace priv +{ + +//////////////////////////////////////////////////////////// +/// \brief Give access to the system clipboard +/// +//////////////////////////////////////////////////////////// +class ClipboardImpl +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Get the content of the clipboard as string data + /// + /// This function returns the content of the clipboard + /// as a string. If the clipboard does not contain string + /// it returns an empty sf::String object. + /// + /// \return Current content of the clipboard + /// + //////////////////////////////////////////////////////////// + static String getString(); + + //////////////////////////////////////////////////////////// + /// \brief Set the content of the clipboard as string data + /// + /// This function sets the content of the clipboard as a + /// string. + /// + /// \param text sf::String object containing the data to be sent + /// to the clipboard + /// + //////////////////////////////////////////////////////////// + static void setString(const String& text); +}; + +} // namespace priv + +} // namespace sf + + +#endif // SFML_CLIPBOARDIMPLX11_HPP diff --git a/src/SFML/Window/Win32/ClipboardImpl.cpp b/src/SFML/Window/Win32/ClipboardImpl.cpp new file mode 100644 index 00000000..4f518ab9 --- /dev/null +++ b/src/SFML/Window/Win32/ClipboardImpl.cpp @@ -0,0 +1,103 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include + + +namespace sf +{ +namespace priv +{ +//////////////////////////////////////////////////////////// +String ClipboardImpl::getString() +{ + String text; + + if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) + { + std::cerr << "Failed to get the clipboard data in Unicode format." << std::endl; + return text; + } + + if (!OpenClipboard(NULL)) + { + std::cerr << "Failed to open the Win32 clipboard." << std::endl; + return text; + } + + HANDLE clipboard_handle = GetClipboardData(CF_UNICODETEXT); + + if (!clipboard_handle) + { + std::cerr << "Failed to get Win32 handle for clipboard content." << std::endl; + CloseClipboard(); + return text; + } + + text = String(static_cast(GlobalLock(clipboard_handle))); + GlobalUnlock(clipboard_handle); + + CloseClipboard(); + return text; +} + + +//////////////////////////////////////////////////////////// +void ClipboardImpl::setString(const String& text) +{ + if (!OpenClipboard(NULL)) + { + std::cerr << "Failed to open the Win32 clipboard." << std::endl; + return; + } + + if (!EmptyClipboard()) + { + std::cerr << "Failed to empty the Win32 clipboard." << std::endl; + return; + } + + // Create a Win32-compatible string + size_t string_size = (text.getSize() + 1) * sizeof(WCHAR); + HANDLE string_handle = GlobalAlloc(GMEM_MOVEABLE, string_size); + + if (string_handle) + { + memcpy(GlobalLock(string_handle), text.toWideString().data(), string_size); + GlobalUnlock(string_handle); + SetClipboardData(CF_UNICODETEXT, string_handle); + } + + CloseClipboard(); +} + +} // namespace priv + +} // namespace sf diff --git a/src/SFML/Window/Win32/ClipboardImpl.hpp b/src/SFML/Window/Win32/ClipboardImpl.hpp new file mode 100644 index 00000000..0eee3418 --- /dev/null +++ b/src/SFML/Window/Win32/ClipboardImpl.hpp @@ -0,0 +1,76 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_CLIPBOARDIMPLWIN32_HPP +#define SFML_CLIPBOARDIMPLWIN32_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +namespace sf +{ +namespace priv +{ +//////////////////////////////////////////////////////////// +/// \brief Give access to the system clipboard +/// +//////////////////////////////////////////////////////////// +class ClipboardImpl +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Get the content of the clipboard as string data + /// + /// This function returns the content of the clipboard + /// as a string. If the clipboard does not contain string + /// it returns an empty sf::String object. + /// + /// \return Current content of the clipboard + /// + //////////////////////////////////////////////////////////// + static String getString(); + + //////////////////////////////////////////////////////////// + /// \brief Set the content of the clipboard as string data + /// + /// This function sets the content of the clipboard as a + /// string. + /// + /// \param text sf::String object containing the data to be sent + /// to the clipboard + /// + //////////////////////////////////////////////////////////// + static void setString(const String& text); +}; + +} // namespace priv + +} // namespace sf + + +#endif // SFML_CLIPBOARDIMPLWIN32_HPP diff --git a/src/SFML/Window/iOS/ClipboardImpl.hpp b/src/SFML/Window/iOS/ClipboardImpl.hpp new file mode 100644 index 00000000..1eb45145 --- /dev/null +++ b/src/SFML/Window/iOS/ClipboardImpl.hpp @@ -0,0 +1,78 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_CLIPBOARDIMPLIOS_HPP +#define SFML_CLIPBOARDIMPLIOS_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +namespace sf +{ +namespace priv +{ + +//////////////////////////////////////////////////////////// +/// \brief Give access to the system clipboard +/// +//////////////////////////////////////////////////////////// +class ClipboardImpl +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Get the content of the clipboard as string data + /// + /// This function returns the content of the clipboard + /// as a string. If the clipboard does not contain string + /// it returns an empty sf::String object. + /// + /// \return Current content of the clipboard + /// + //////////////////////////////////////////////////////////// + static String getString(); + + //////////////////////////////////////////////////////////// + /// \brief Set the content of the clipboard as string data + /// + /// This function sets the content of the clipboard as a + /// string. + /// + /// \param text sf::String object containing the data to be sent + /// to the clipboard + /// + //////////////////////////////////////////////////////////// + static void setString(const String& text); +}; + +} // namespace priv + +} // namespace sf + + +#endif // SFML_CLIPBOARDIMPLIOS_HPP + diff --git a/src/SFML/Window/iOS/ClipboardImpl.mm b/src/SFML/Window/iOS/ClipboardImpl.mm new file mode 100644 index 00000000..74ace07c --- /dev/null +++ b/src/SFML/Window/iOS/ClipboardImpl.mm @@ -0,0 +1,72 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +@import UIKit + +namespace sf +{ +namespace priv +{ + +//////////////////////////////////////////////////////////// +String ClipboardImpl::getString() +{ + UIPasteboard* pboard = [UIPasteboard generalPasteboard]; + if (pboard.hasStrings) + { + NSString* data = pboard.string + + char const* utf8 = [data cStringUsingEncoding:NSUTF8StringEncoding]; + NSUInteger length = [data lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + return String::fromUtf8(utf8, utf8 + length); + } + else + { + return String(); + } +} + + +//////////////////////////////////////////////////////////// +void ClipboardImpl::setString(const String& text) +{ + std::basic_string utf8 = text.toUtf8(); + NSString* data = [[NSString alloc] initWithBytes:utf8.data() + length:utf8.length() + encoding:NSUTF8StringEncoding]; + + UIPasteboard* pboard = [UIPasteboard generalPasteboard]; + pboard.string = data; +} + +} // namespace priv + +} // namespace sf +