diff --git a/source/gui/ObjectTypes/CInput.cpp b/source/gui/ObjectTypes/CInput.cpp index 7dfabd62df..89c5383686 100644 --- a/source/gui/ObjectTypes/CInput.cpp +++ b/source/gui/ObjectTypes/CInput.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -24,7 +24,6 @@ #include "graphics/TextRenderer.h" #include "gui/CGUI.h" #include "gui/CGUIScrollBarVertical.h" -#include "lib/sysdep/clipboard.h" #include "lib/timer.h" #include "lib/utf8.h" #include "ps/ConfigDB.h" @@ -600,29 +599,30 @@ InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev) m_WantedX = 0.0f; - wchar_t* text = sys_clipboard_get(); - if (text) - { - if (SelectingText()) - DeleteCurSelection(); + char* utf8_text = SDL_GetClipboardText(); + if (!utf8_text) + return IN_HANDLED; - if (m_iBufferPos == static_cast(m_Caption.length())) - m_Caption += text; - else - m_Caption = - m_Caption.Left(m_iBufferPos) + text + - m_Caption.Right(static_cast(m_Caption.length()) - m_iBufferPos); + std::wstring text = wstring_from_utf8(utf8_text); + SDL_free(utf8_text); - UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1); + if (SelectingText()) + DeleteCurSelection(); - m_iBufferPos += (int)wcslen(text); - UpdateAutoScroll(); - UpdateBufferPositionSetting(); + if (m_iBufferPos == static_cast(m_Caption.length())) + m_Caption += text; + else + m_Caption = + m_Caption.Left(m_iBufferPos) + text + + m_Caption.Right(static_cast(m_Caption.length()) - m_iBufferPos); - sys_clipboard_free(text); + UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1); - SendEvent(GUIM_TEXTEDIT, EventNameTextEdit); - } + m_iBufferPos += static_cast(text.size()); + UpdateAutoScroll(); + UpdateBufferPositionSetting(); + + SendEvent(GUIM_TEXTEDIT, EventNameTextEdit); return IN_HANDLED; } @@ -651,7 +651,7 @@ InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev) CStrW text = m_Caption.Left(virtualTo).Right(virtualTo - virtualFrom); - sys_clipboard_set(&text[0]); + SDL_SetClipboardText(text.ToUTF8().c_str()); if (hotkey == "cut") { diff --git a/source/lib/sysdep/clipboard.h b/source/lib/sysdep/clipboard.h deleted file mode 100644 index 0eec802fd0..0000000000 --- a/source/lib/sysdep/clipboard.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2011 Wildfire Games. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef INCLUDED_SYSDEP_CLIPBOARD -#define INCLUDED_SYSDEP_CLIPBOARD - -// "copy" text into the clipboard. replaces previous contents. -extern Status sys_clipboard_set(const wchar_t* text); - -// allow "pasting" from clipboard. -// @return current clipboard text or 0 if not representable as text. -// callers are responsible for passing this pointer to sys_clipboard_free. -extern wchar_t* sys_clipboard_get(); - -// free memory returned by sys_clipboard_get. -// @param copy is ignored if 0. -extern Status sys_clipboard_free(wchar_t* copy); - -#endif // #ifndef INCLUDED_SYSDEP_CLIPBOARD diff --git a/source/lib/sysdep/os/android/android.cpp b/source/lib/sysdep/os/android/android.cpp index 5b3b714732..7efdc445ec 100644 --- a/source/lib/sysdep/os/android/android.cpp +++ b/source/lib/sysdep/os/android/android.cpp @@ -26,21 +26,6 @@ #include "lib/external_libraries/libsdl.h" -Status sys_clipboard_set(const wchar_t* UNUSED(text)) -{ - return INFO::OK; -} - -wchar_t* sys_clipboard_get() -{ - return NULL; -} - -Status sys_clipboard_free(wchar_t* UNUSED(copy)) -{ - return INFO::OK; -} - namespace gfx { Status GetVideoMode(int* xres, int* yres, int* bpp, int* freq) diff --git a/source/lib/sysdep/os/osx/osx.cpp b/source/lib/sysdep/os/osx/osx.cpp index c97f48b08c..042c43119e 100644 --- a/source/lib/sysdep/os/osx/osx.cpp +++ b/source/lib/sysdep/os/osx/osx.cpp @@ -38,42 +38,6 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -Status sys_clipboard_set(const wchar_t* text) -{ - Status ret = INFO::OK; - - std::string str = utf8_from_wstring(text); - bool ok = osx_SendStringToPasteboard(str); - if (!ok) - ret = ERR::FAIL; - return ret; -} - -wchar_t* sys_clipboard_get() -{ - wchar_t* ret = NULL; - std::string str; - bool ok = osx_GetStringFromPasteboard(str); - if (ok) - { - // TODO: this is yucky, why are we passing around wchar_t*? - std::wstring wstr = wstring_from_utf8(str); - size_t len = wcslen(wstr.c_str()); - ret = (wchar_t*)malloc((len+1)*sizeof(wchar_t)); - std::copy(wstr.c_str(), wstr.c_str()+len, ret); - ret[len] = 0; - } - - return ret; -} - -Status sys_clipboard_free(wchar_t* copy) -{ - free(copy); - return INFO::OK; -} - - namespace gfx { Status GetVideoMode(int* xres, int* yres, int* bpp, int* freq) @@ -143,7 +107,6 @@ Status GetVideoMode(int* xres, int* yres, int* bpp, int* freq) } // namespace gfx - OsPath sys_ExecutablePathname() { OsPath path; diff --git a/source/lib/sysdep/os/osx/osx_pasteboard.h b/source/lib/sysdep/os/osx/osx_pasteboard.h deleted file mode 100644 index 4642a8639f..0000000000 --- a/source/lib/sysdep/os/osx/osx_pasteboard.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 2012 Wildfire Games. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef OSX_PASTEBOARD_H -#define OSX_PASTEBOARD_H - -/** - * @file - * C++ interface to Cocoa implementation for pasteboards - */ - -/** - * Get a string from the pasteboard - * - * @param[out] out pasteboard string in UTF-8 encoding, if found - * @return true if string was found on pasteboard and successfully retrieved, false otherwise - */ -bool osx_GetStringFromPasteboard(std::string& out); - -/** - * Store a string on the pasteboard - * - * @param[in] string string to store in UTF-8 encoding - * @return true if string was successfully sent to pasteboard, false on error - */ -bool osx_SendStringToPasteboard(const std::string& string); - -#endif // OSX_PASTEBOARD_H diff --git a/source/lib/sysdep/os/osx/osx_pasteboard.mm b/source/lib/sysdep/os/osx/osx_pasteboard.mm deleted file mode 100644 index 9e45970c52..0000000000 --- a/source/lib/sysdep/os/osx/osx_pasteboard.mm +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (C) 2013 Wildfire Games. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#import -#import // MAC_OS_X_VERSION_MIN_REQUIRED -#import -#import - -#import "osx_pasteboard.h" - -bool osx_GetStringFromPasteboard(std::string& out) -{ - NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; - NSString* string = nil; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 - // As of 10.6, pasteboards can hold multiple items - if ([pasteboard respondsToSelector: @selector(readObjectsForClasses:)]) - { - NSArray* classes = [NSArray arrayWithObjects:[NSString class], nil]; - NSDictionary* options = [NSDictionary dictionary]; - NSArray* copiedItems = [pasteboard readObjectsForClasses:classes options:options]; - // We only need to support a single item, so grab the first string - if (copiedItems != nil && [copiedItems count] > 0) - string = [copiedItems objectAtIndex:0]; - else - return false; // No strings found on pasteboard - } - else - { -#endif // fallback to 10.5 API - // Verify that there is a string available for us - NSArray* types = [NSArray arrayWithObjects:NSStringPboardType, nil]; - if ([pasteboard availableTypeFromArray:types] != nil) - string = [pasteboard stringForType:NSStringPboardType]; - else - return false; // No strings found on pasteboard -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 - } -#endif - - if (string != nil) - out = std::string([string UTF8String]); - else - return false; // fail - - return true; // success -} - -bool osx_SendStringToPasteboard(const std::string& string) -{ - // We're only working with strings, so we don't need to lazily write - // anything (otherwise we'd need to set up an owner and data provider) - NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; - NSString* type; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 - if ([pasteboard respondsToSelector: @selector(clearContents)]) - { - type = NSPasteboardTypeString; - [pasteboard clearContents]; - } - else - { -#endif // fallback to 10.5 API - type = NSStringPboardType; - NSArray* types = [NSArray arrayWithObjects: type, nil]; - // Roughly equivalent to clearContents followed by addTypes:owner - [pasteboard declareTypes:types owner:nil]; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 - - } -#endif - - // May raise a NSPasteboardCommunicationException - BOOL ok = [pasteboard setString:[NSString stringWithUTF8String:string.c_str()] forType:type]; - return ok == YES; -} diff --git a/source/lib/sysdep/os/unix/x/x.cpp b/source/lib/sysdep/os/unix/x/x.cpp index 615bc758fa..8951f35f94 100644 --- a/source/lib/sysdep/os/unix/x/x.cpp +++ b/source/lib/sysdep/os/unix/x/x.cpp @@ -113,242 +113,4 @@ static bool get_wminfo(SDL_SysWMinfo& wminfo) return false; } -/* -Oh, boy, this is heavy stuff... - - -http://www.freedesktop.org/standards/clipboards-spec/clipboards.txt - -http://www.mail-archive.com/xfree86@xfree86.org/msg15594.html -http://michael.toren.net/mirrors/doc/X-copy+paste.txt -http://devdocs.wesnoth.org/clipboard_8cpp-source.html -http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html -http://www.jwz.org/doc/x-cut-and-paste.html - -The basic run-down on X Selection Handling: -* One window owns the "current selection" at any one time -* Accessing the Selection (i.e. "paste"), Step-by-step - * Ask the X server for the current selection owner - * Ask the selection owner window to convert the selection into a format - we can understand (XA_STRING - Latin-1 string - for now) - * The converted result is stored as a property of the *selection owner* - window. It is possible to specify the current application window as the - target - but that'd require some X message handling... easier to skip that.. - * The final step is to acquire the property value of the selection owner - window - -Notes: -An "Atom" is a server-side object that represents a string by an index into some -kind of table or something. Pretty much like a handle that refers to one unique -string. Atoms are used here to refer to property names and value formats. - -Expansions: -* Implement UTF-8 format support (should be interresting for international users) - -*/ -wchar_t *sys_clipboard_get() -{ - Display *disp=XOpenDisplay(NULL); - if(!disp) - return NULL; - - // We use CLIPBOARD as the default, since the CLIPBOARD semantics are much - // closer to windows semantics. - Atom selSource=XInternAtom(disp, "CLIPBOARD", False); - - Window selOwner=XGetSelectionOwner(disp, selSource); - if(selOwner == None) - { - // However, since many apps don't use CLIPBOARD, but use PRIMARY instead - // we use XA_PRIMARY as a fallback clipboard. This is true for xterm, - // for example. - selSource=XA_PRIMARY; - selOwner=XGetSelectionOwner(disp, selSource); - } - if(selOwner != None) { - Atom pty=XInternAtom(disp, "SelectionPropertyTemp", False); - XConvertSelection(disp, selSource, XA_STRING, pty, selOwner, CurrentTime); - XFlush(disp); - - Atom type; - int format=0, result=0; - unsigned long len=0, bytes_left=0, dummy=0; - u8 *data=NULL; - - // Get the length of the property and some attributes - // bytes_left will contain the length of the selection - result = XGetWindowProperty (disp, selOwner, pty, - 0, 0, // offset - len - 0, // Delete 0==FALSE - AnyPropertyType,//flag - &type, // return type - &format, // return format - &len, &bytes_left, - &data); - if(result != Success) - debug_printf("clipboard_get: XGetWindowProperty failed! result: %d type:%lu len:%lu format:%d bytes_left:%lu\n", - result, type, len, format, bytes_left); - if(result == Success && bytes_left > 0) - { - result = XGetWindowProperty (disp, selOwner, - pty, 0, bytes_left, 0, - AnyPropertyType, &type, &format, - &len, &dummy, &data); - - if(result == Success) - { - if(type == XA_STRING) //Latin-1: Just copy into low byte of wchar_t - { - wchar_t *ret=(wchar_t *)malloc((bytes_left+1)*sizeof(wchar_t)); - std::copy(data, data+bytes_left, ret); - ret[bytes_left]=0; - return ret; - } - // TODO: Handle UTF8 strings - } - else - { - debug_printf("clipboard_get: XGetWindowProperty failed!\n"); - return NULL; - } - } - } - - return NULL; -} - -Status sys_clipboard_free(wchar_t *clip_buf) -{ - free(clip_buf); - return INFO::OK; -} - -/** - * An SDL Event filter that intercepts other applications' requests for the - * X selection buffer. - * - * @see x11_clipboard_init - * @see sys_clipboard_set - */ -int clipboard_filter(void* UNUSED(userdata), SDL_Event* event) -{ - /* Pass on all non-window manager specific events immediately */ - /* And do nothing if we don't actually have a clip-out to send out */ - if(event->type != SDL_SYSWMEVENT || !selection_data) - return 1; - - /* Handle window-manager specific clipboard events */ - /* (Note: libsdl must be compiled with X11 support (SDL_VIDEO_DRIVER_X11 in SDL_config.h) - - else you'll get errors like "'struct SDL_SysWMmsg' has no member named 'xevent'") */ - XEvent* xevent = &event->syswm.msg->msg.x11.event; - switch(xevent->type) { - /* Copy the selection from our buffer to the requested property, and - convert to the requested target format */ - case SelectionRequest: { - XSelectionRequestEvent *req; - XEvent sevent; - - req = &xevent->xselectionrequest; - sevent.xselection.type = SelectionNotify; - sevent.xselection.display = req->display; - sevent.xselection.selection = req->selection; - sevent.xselection.target = req->target; - sevent.xselection.property = None; - sevent.xselection.requestor = req->requestor; - sevent.xselection.time = req->time; - // Simply strip all non-Latin1 characters and replace with '?' - // We should support XA_UTF8 - if(req->target == XA_STRING) - { - size_t size = wcslen(selection_data); - u8* buf = (u8*)alloca(size); - - for(size_t i = 0; i < size; i++) - { - buf[i] = selection_data[i] < 0x100 ? selection_data[i] : '?'; - } - - XChangeProperty(g_SDL_Display, req->requestor, req->property, - sevent.xselection.target, 8, PropModeReplace, - buf, size); - sevent.xselection.property = req->property; - } - // TODO Add more target formats - XSendEvent(g_SDL_Display, req->requestor, False, 0, &sevent); - XSync(g_SDL_Display, False); - } - break; - } - - return 1; -} - -/** - * Initialization for X clipboard handling, called on-demand by - * sys_clipboard_set. - */ -Status x11_clipboard_init() -{ - SDL_SysWMinfo info; - - if(get_wminfo(info)) - { - /* Save the information for later use */ - if(info.subsystem == SDL_SYSWM_X11) - { - g_SDL_Display = info.info.x11.display; - g_SDL_Window = info.info.x11.window; - - /* Enable the special window hook events */ - SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); - SDL_SetEventFilter(clipboard_filter, NULL); - - return INFO::OK; - } - else - { - return ERR::FAIL; - } - } - - return INFO::OK; -} - -/** - * Set the Selection (i.e. "copy") - * - * Step-by-step (X11) - *
    - *
  • Store the selection text in a local buffer - *
  • Tell the X server that we want to own the selection - *
  • Listen for Selection events and respond to them as appropriate - *
- */ -Status sys_clipboard_set(const wchar_t *str) -{ - ONCE(x11_clipboard_init()); - - if(selection_data) - { - free(selection_data); - selection_data = NULL; - } - - selection_size = (wcslen(str)+1)*sizeof(wchar_t); - selection_data = (wchar_t *)malloc(selection_size); - wcscpy(selection_data, str); - - // Like for the clipboard_get code above, we rather use CLIPBOARD than - // PRIMARY - more windows'y behaviour there. - Atom clipboard_atom = XInternAtom(g_SDL_Display, "CLIPBOARD", False); - XSetSelectionOwner(g_SDL_Display, clipboard_atom, g_SDL_Window, CurrentTime); - XSetSelectionOwner(g_SDL_Display, XA_PRIMARY, g_SDL_Window, CurrentTime); - - // SDL2 doesn't have a lockable event thread, so it just uses - // XSync directly instead of lock_func/unlock_func - XSync(g_SDL_Display, False); - - return INFO::OK; -} - #endif // #if HAVE_X diff --git a/source/lib/sysdep/os/win/wclipboard.cpp b/source/lib/sysdep/os/win/wclipboard.cpp deleted file mode 100644 index ee5602a8c3..0000000000 --- a/source/lib/sysdep/os/win/wclipboard.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* Copyright (C) 2010 Wildfire Games. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "precompiled.h" -#include "lib/sysdep/clipboard.h" - -#include "lib/sysdep/os/win/win.h" -#include "lib/sysdep/os/win/wutil.h" - - -// caller is responsible for freeing hMem. -static Status SetClipboardText(const wchar_t* text, HGLOBAL& hMem) -{ - const size_t numChars = wcslen(text); - hMem = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, (numChars + 1) * sizeof(wchar_t)); - if(!hMem) - WARN_RETURN(ERR::NO_MEM); - - wchar_t* lockedText = (wchar_t*)GlobalLock(hMem); - if(!lockedText) - WARN_RETURN(ERR::NO_MEM); - wcscpy_s(lockedText, numChars+1, text); - GlobalUnlock(hMem); - - HANDLE hData = SetClipboardData(CF_UNICODETEXT, hMem); - if(!hData) // failed - WARN_RETURN(ERR::FAIL); - - return INFO::OK; -} - - -// @return INFO::OK iff text has been assigned a pointer (which the -// caller must free via sys_clipboard_free) to the clipboard text. -static Status GetClipboardText(wchar_t*& text) -{ - // NB: Windows NT/2000+ auto convert CF_UNICODETEXT <-> CF_TEXT. - - if(!IsClipboardFormatAvailable(CF_UNICODETEXT)) - return INFO::CANNOT_HANDLE; - - HGLOBAL hMem = GetClipboardData(CF_UNICODETEXT); - if(!hMem) - WARN_RETURN(ERR::FAIL); - - const wchar_t* lockedText = (const wchar_t*)GlobalLock(hMem); - if(!lockedText) - WARN_RETURN(ERR::NO_MEM); - - const size_t size = GlobalSize(hMem); - text = (wchar_t*)malloc(size); - if(!text) - WARN_RETURN(ERR::NO_MEM); - wcscpy_s(text, size/sizeof(wchar_t), lockedText); - - (void)GlobalUnlock(hMem); - - return INFO::OK; -} - - -// OpenClipboard parameter. -// NB: using wutil_AppWindow() causes GlobalLock to fail. -static const HWND hWndNewOwner = 0; // MSDN: associate with "current task" - -Status sys_clipboard_set(const wchar_t* text) -{ - if(!OpenClipboard(hWndNewOwner)) - WARN_RETURN(ERR::FAIL); - - WARN_IF_FALSE(EmptyClipboard()); - - // NB: to enable copy/pasting something other than text, add - // message handlers for WM_RENDERFORMAT and WM_RENDERALLFORMATS. - HGLOBAL hMem; - Status ret = SetClipboardText(text, hMem); - - WARN_IF_FALSE(CloseClipboard()); // must happen before GlobalFree - - ENSURE(GlobalFree(hMem) == 0); // (0 indicates success) - - return ret; -} - - -wchar_t* sys_clipboard_get() -{ - if(!OpenClipboard(hWndNewOwner)) - return 0; - - wchar_t* text; - Status ret = GetClipboardText(text); - - WARN_IF_FALSE(CloseClipboard()); - - return (ret == INFO::OK)? text : 0; -} - - -Status sys_clipboard_free(wchar_t* text) -{ - free(text); - return INFO::OK; -} diff --git a/source/lib/sysdep/os/win/wsysdep.cpp b/source/lib/sysdep/os/win/wsysdep.cpp index 484fe923a3..ef4ba22f24 100644 --- a/source/lib/sysdep/os/win/wsysdep.cpp +++ b/source/lib/sysdep/os/win/wsysdep.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -29,13 +29,13 @@ #include "lib/alignment.h" #include "lib/sysdep/os/win/win.h" // includes windows.h; must come before shlobj +#include // SDL_SetClipboardText #include // pick_dir #include // open_url #include #include // message crackers #include -#include "lib/sysdep/clipboard.h" #include "lib/sysdep/os/win/error_dialog.h" #include "lib/sysdep/os/win/wutil.h" @@ -214,7 +214,8 @@ static void dlg_OnCommand(HWND hDlg, int id, HWND UNUSED(hWndCtl), UINT UNUSED(c { std::vector buf(128*KiB); // (too big for stack) GetDlgItemTextW(hDlg, IDC_EDIT1, &buf[0], (int)buf.size()); - sys_clipboard_set(&buf[0]); + std::string string = utf8_from_wstring(&buf[0]); + SDL_SetClipboardText(string.c_str()); break; } diff --git a/source/ps/CConsole.cpp b/source/ps/CConsole.cpp index d0c9131f78..4a7686a6b8 100644 --- a/source/ps/CConsole.cpp +++ b/source/ps/CConsole.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -31,7 +31,6 @@ #include "gui/GUIManager.h" #include "gui/GUIMatrix.h" #include "lib/ogl.h" -#include "lib/sysdep/clipboard.h" #include "lib/timer.h" #include "lib/utf8.h" #include "maths/MathUtil.h" @@ -531,7 +530,7 @@ void CConsole::SetBuffer(const wchar_t* szMessage) wcsncpy(m_szBuffer, szMessage, CONSOLE_BUFFER_SIZE); m_szBuffer[CONSOLE_BUFFER_SIZE-1] = 0; - m_iBufferLength = (int)wcslen(m_szBuffer); + m_iBufferLength = static_cast(wcslen(m_szBuffer)); m_iBufferPos = std::min(oldBufferPos, m_iBufferLength); } @@ -649,19 +648,22 @@ InReaction conInputHandler(const SDL_Event_* ev) } else if (g_Console->IsActive() && hotkey == "copy") { - sys_clipboard_set(g_Console->GetBuffer()); + std::string text = utf8_from_wstring(g_Console->GetBuffer()); + SDL_SetClipboardText(text.c_str()); return IN_HANDLED; } else if (g_Console->IsActive() && hotkey == "paste") { - wchar_t* text = sys_clipboard_get(); - if (text) - { - for (wchar_t* c = text; *c; c++) - g_Console->InsertChar(0, *c); + char* utf8_text = SDL_GetClipboardText(); + if (!utf8_text) + return IN_HANDLED; + + std::wstring text = wstring_from_utf8(utf8_text); + SDL_free(utf8_text); + + for (wchar_t c : text) + g_Console->InsertChar(0, c); - sys_clipboard_free(text); - } return IN_HANDLED; } }