Index: source/gui/ObjectTypes/CInput.cpp =================================================================== --- source/gui/ObjectTypes/CInput.cpp +++ source/gui/ObjectTypes/CInput.cpp @@ -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" @@ -596,26 +595,28 @@ m_WantedX = 0.0f; - wchar_t* text = sys_clipboard_get(); + char* text = SDL_GetClipboardText(); if (text) { + std::wstring wstring = wstring_from_utf8(text); + const wchar_t* wtext = wstring.c_str(); if (SelectingText()) DeleteCurSelection(); if (m_iBufferPos == static_cast(m_Caption.length())) - m_Caption += text; + m_Caption += wtext; else m_Caption = - m_Caption.Left(m_iBufferPos) + text + + m_Caption.Left(m_iBufferPos) + wtext + m_Caption.Right(static_cast(m_Caption.length()) - m_iBufferPos); UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1); - m_iBufferPos += (int)wcslen(text); + m_iBufferPos += (int)wcslen(wtext); UpdateAutoScroll(); UpdateBufferPositionSetting(); - sys_clipboard_free(text); + SDL_free(text); SendEvent(GUIM_TEXTEDIT, "textedit"); } @@ -647,7 +648,7 @@ CStrW text = m_Caption.Left(virtualTo).Right(virtualTo - virtualFrom); - sys_clipboard_set(&text[0]); + SDL_SetClipboardText(text.ToUTF8().c_str()); if (hotkey == "cut") { Index: source/lib/sysdep/clipboard.h =================================================================== --- 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 Index: source/lib/sysdep/gfx.h =================================================================== --- source/lib/sysdep/gfx.h +++ source/lib/sysdep/gfx.h @@ -41,30 +41,6 @@ **/ LIB_API std::wstring DriverInfo(); -/** - * not implemented - **/ -LIB_API size_t MemorySizeMiB(); - -/** - * (useful for choosing a new video mode) - * - * @param xres, yres (optional out) resolution [pixels] - * @param bpp (optional out) bits per pixel - * @param freq (optional out) vertical refresh rate [Hz] - * @return Status (if negative, outputs were left unchanged) - **/ -LIB_API Status GetVideoMode(int* xres, int* yres, int* bpp, int* freq); - -/** - * (useful for determining aspect ratio) - * - * @param width_mm (out) screen width [mm] - * @param height_mm (out) screen height [mm] - * @return Status (if if negative, outputs were left unchanged) - **/ -LIB_API Status GetMonitorSize(int& width_mm, int& height_mm); - } // namespace gfx #endif // #ifndef INCLUDED_GFX Index: source/lib/sysdep/gfx.cpp =================================================================== --- source/lib/sysdep/gfx.cpp +++ source/lib/sysdep/gfx.cpp @@ -89,13 +89,4 @@ } -size_t MemorySizeMiB() -{ - // TODO: not implemented, SDL_GetVideoInfo only works on some platforms in SDL 1.2 - // and no replacement is available in SDL2, and it can crash with Nvidia Optimus - // see http://trac.wildfiregames.com/ticket/2145 - debug_warn(L"MemorySizeMiB not implemented"); - return 0; -} - } // namespace gfx Index: source/lib/sysdep/os/android/android.cpp =================================================================== --- source/lib/sysdep/os/android/android.cpp +++ /dev/null @@ -1,66 +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. - */ - -#include "precompiled.h" - -#include "lib/sysdep/sysdep.h" -#include "lib/sysdep/cursor.h" - -#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) -{ -#warning TODO: implement gfx::GetVideoMode properly for Android - - if(xres) - *xres = 800; - - if(yres) - *yres = 480; - - if(bpp) - *bpp = 32; - - if(freq) - *freq = 0; - - return INFO::OK; -} - -} Index: source/lib/sysdep/os/osx/osx.cpp =================================================================== --- source/lib/sysdep/os/osx/osx.cpp +++ source/lib/sysdep/os/osx/osx.cpp @@ -27,7 +27,6 @@ #include "lib/sysdep/gfx.h" #include "lib/utf8.h" #include "osx_bundle.h" -#include "osx_pasteboard.h" #include #include // MAC_OS_X_VERSION_MIN_REQUIRED @@ -38,125 +37,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) -{ - if(xres) - *xres = (int)CGDisplayPixelsWide(kCGDirectMainDisplay); - - if(yres) - *yres = (int)CGDisplayPixelsHigh(kCGDirectMainDisplay); - - if(bpp) - { -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 - // CGDisplayBitsPerPixel was deprecated in OS X 10.6 - if (CGDisplayCopyDisplayMode != NULL) - { - CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); - CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(currentMode); - if (CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - *bpp = 32; - else if (CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - *bpp = 16; - else if (CFStringCompare(pixelEncoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - *bpp = 8; - else // error - *bpp = 0; - - // We're responsible for this - CFRelease(pixelEncoding); - CGDisplayModeRelease(currentMode); - } - else - { -#endif // fallback to 10.5 API - CFDictionaryRef currentMode = CGDisplayCurrentMode(kCGDirectMainDisplay); - CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(currentMode, kCGDisplayBitsPerPixel); - CFNumberGetValue(num, kCFNumberIntType, bpp); -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 - } -#endif - } - - if(freq) - { -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 - if (CGDisplayCopyDisplayMode != NULL) - { - CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); - *freq = (int)CGDisplayModeGetRefreshRate(currentMode); - - // We're responsible for this - CGDisplayModeRelease(currentMode); - } - else - { -#endif // fallback to 10.5 API - CFDictionaryRef currentMode = CGDisplayCurrentMode(kCGDirectMainDisplay); - CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(currentMode, kCGDisplayRefreshRate); - CFNumberGetValue(num, kCFNumberIntType, freq); -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 - } -#endif - } - - return INFO::OK; -} - -Status GetMonitorSize(int& width_mm, int& height_mm) -{ - CGSize screenSize = CGDisplayScreenSize(kCGDirectMainDisplay); - - if (screenSize.width == 0 || screenSize.height == 0) - return ERR::FAIL; - - width_mm = screenSize.width; - height_mm = screenSize.height; - - return INFO::OK; -} - -} // namespace gfx - - OsPath sys_ExecutablePathname() { OsPath path; Index: source/lib/sysdep/os/osx/osx_pasteboard.h =================================================================== --- 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 Index: source/lib/sysdep/os/osx/osx_pasteboard.mm =================================================================== --- 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; -} Index: source/lib/sysdep/os/unix/x/x.cpp =================================================================== --- source/lib/sysdep/os/unix/x/x.cpp +++ /dev/null @@ -1,371 +0,0 @@ -/* Copyright (C) 2019 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. - */ - -// X Window System-specific code - -#include "precompiled.h" - -#if OS_LINUX || OS_BSD -# define HAVE_X 1 -#else -# define HAVE_X 0 -#endif - -#if HAVE_X - -#include "lib/debug.h" -#include "lib/utf8.h" -#include "lib/sysdep/gfx.h" - -#include "ps/VideoMode.h" - -#include -#include -#include - -#include "SDL.h" -#include "SDL_syswm.h" - -#include -#undef Status - -static Display *g_SDL_Display; -static Window g_SDL_Window; -static wchar_t *selection_data=NULL; -static size_t selection_size=0; - -namespace gfx { - -Status GetVideoMode(int* xres, int* yres, int* bpp, int* freq) -{ - Display* disp = XOpenDisplay(0); - if(!disp) - WARN_RETURN(ERR::FAIL); - - int screen = XDefaultScreen(disp); - - /* 2004-07-13 - NOTE: The XDisplayWidth/Height functions don't actually return the current - display mode - they return the size of the root window. This means that - users with "Virtual Desktops" bigger than what their monitors/graphics - card can handle will have to set their 0AD screen resolution manually. - - There's supposed to be an X extension that can give you the actual display - mode, probably including refresh rate info etc, but it's not worth - researching and implementing that at this stage. - */ - - if(xres) - *xres = XDisplayWidth(disp, screen); - if(yres) - *yres = XDisplayHeight(disp, screen); - if(bpp) - *bpp = XDefaultDepth(disp, screen); - if(freq) - *freq = 0; - XCloseDisplay(disp); - return INFO::OK; -} - - -Status GetMonitorSize(int& width_mm, int& height_mm) -{ - Display* disp = XOpenDisplay(0); - if(!disp) - WARN_RETURN(ERR::FAIL); - - int screen = XDefaultScreen(disp); - - width_mm = XDisplayWidthMM(disp, screen); - height_mm = XDisplayHeightMM(disp, screen); - - XCloseDisplay(disp); - return INFO::OK; -} - -} // namespace gfx - - -static bool get_wminfo(SDL_SysWMinfo& wminfo) -{ - SDL_VERSION(&wminfo.version); - - const int ret = SDL_GetWindowWMInfo(g_VideoMode.GetWindow(), &wminfo); - - if(ret == 1) - return true; - - if(ret == -1) - { - debug_printf("SDL_GetWMInfo failed\n"); - return false; - } - if(ret == 0) - { - debug_printf("SDL_GetWMInfo is not implemented on this platform\n"); - return false; - } - - debug_printf("SDL_GetWMInfo returned an unknown value: %d\n", ret); - 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 Index: source/lib/sysdep/os/win/wclipboard.cpp =================================================================== --- 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; -} Index: source/lib/sysdep/os/win/wgfx.cpp =================================================================== --- source/lib/sysdep/os/win/wgfx.cpp +++ source/lib/sysdep/os/win/wgfx.cpp @@ -143,45 +143,3 @@ AppendDriverVersionsFromKnownFiles(versionList); return versionList; } - - -//----------------------------------------------------------------------------- -// direct implementations of some gfx functions - -namespace gfx { - -Status GetVideoMode(int* xres, int* yres, int* bpp, int* freq) -{ - DEVMODE dm = { sizeof(dm) }; - - if(!EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &dm)) - WARN_RETURN(ERR::FAIL); - - // EnumDisplaySettings is documented to set the values of the following: - const DWORD expectedFlags = DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL|DM_DISPLAYFREQUENCY|DM_DISPLAYFLAGS; - ENSURE((dm.dmFields & expectedFlags) == expectedFlags); - - if(xres) - *xres = (int)dm.dmPelsWidth; - if(yres) - *yres = (int)dm.dmPelsHeight; - if(bpp) - *bpp = (int)dm.dmBitsPerPel; - if(freq) - *freq = (int)dm.dmDisplayFrequency; - - return INFO::OK; -} - - -Status GetMonitorSize(int& width_mm, int& height_mm) -{ - // (DC for the primary monitor's entire screen) - const HDC hDC = GetDC(0); - width_mm = GetDeviceCaps(hDC, HORZSIZE); - height_mm = GetDeviceCaps(hDC, VERTSIZE); - ReleaseDC(0, hDC); - return INFO::OK; -} - -} // namespace gfx Index: source/lib/sysdep/os/win/wsysdep.cpp =================================================================== --- source/lib/sysdep/os/win/wsysdep.cpp +++ source/lib/sysdep/os/win/wsysdep.cpp @@ -35,7 +35,6 @@ #include // message crackers #include -#include "lib/sysdep/clipboard.h" #include "lib/sysdep/os/win/error_dialog.h" #include "lib/sysdep/os/win/wutil.h" @@ -210,14 +209,6 @@ { switch(id) { - case IDC_COPY: - { - std::vector buf(128*KiB); // (too big for stack) - GetDlgItemTextW(hDlg, IDC_EDIT1, &buf[0], (int)buf.size()); - sys_clipboard_set(&buf[0]); - break; - } - case IDC_CONTINUE: EndDialog(hDlg, ERI_CONTINUE); break; Index: source/ps/CConsole.cpp =================================================================== --- source/ps/CConsole.cpp +++ source/ps/CConsole.cpp @@ -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" @@ -649,18 +648,20 @@ } 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(); + char* text = SDL_GetClipboardText(); if (text) { - for (wchar_t* c = text; *c; c++) - g_Console->InsertChar(0, *c); + std::wstring wtext = wstring_from_utf8(text); + for (wchar_t c : wtext) + g_Console->InsertChar(0, c); - sys_clipboard_free(text); + SDL_free(text); } return IN_HANDLED; } Index: source/ps/GameSetup/GameSetup.cpp =================================================================== --- source/ps/GameSetup/GameSetup.cpp +++ source/ps/GameSetup/GameSetup.cpp @@ -86,13 +86,6 @@ #include "tools/atlas/GameInterface/GameLoop.h" #include "tools/atlas/GameInterface/View.h" -#if !(OS_WIN || OS_MACOSX || OS_ANDROID) // assume all other platforms use X11 for wxWidgets -#define MUST_INIT_X11 1 -#include -#else -#define MUST_INIT_X11 0 -#endif - extern void RestartEngine(); #include @@ -882,17 +875,6 @@ FixLocales(); - // Because we do GL calls from a secondary thread, Xlib needs to - // be told to support multiple threads safely. - // This is needed for Atlas, but we have to call it before any other - // Xlib functions (e.g. the ones used when drawing the main menu - // before launching Atlas) -#if MUST_INIT_X11 - int status = XInitThreads(); - if (status == 0) - debug_printf("Error enabling thread-safety via XInitThreads\n"); -#endif - // Initialise the low-quality rand function srand(time(NULL)); // NOTE: this rand should *not* be used for simulation! } Index: source/ps/VideoMode.h =================================================================== --- source/ps/VideoMode.h +++ source/ps/VideoMode.h @@ -105,8 +105,8 @@ // Initial desktop settings int m_PreferredW; int m_PreferredH; - int m_PreferredBPP; - int m_PreferredFreq; + int m_PreferredBPP; // bits per pixels + int m_PreferredFreq; // In Hz // Config file settings (0 if unspecified) int m_ConfigW; Index: source/ps/VideoMode.cpp =================================================================== --- source/ps/VideoMode.cpp +++ source/ps/VideoMode.cpp @@ -165,6 +165,8 @@ bool CVideoMode::InitSDL() { + SDL_DisplayMode mode; + ENSURE(!m_IsInitialised); ReadConfig(); @@ -173,7 +175,14 @@ // preferred video mode = current desktop settings // (command line params may override these) - gfx::GetVideoMode(&m_PreferredW, &m_PreferredH, &m_PreferredBPP, &m_PreferredFreq); + // TODO: handle multi-screen properly + if (SDL_GetDesktopDisplayMode(0, &mode) == 0) + { + m_PreferredW = mode.w; + m_PreferredH = mode.h; + m_PreferredBPP = SDL_BITSPERPIXEL(mode.format); + m_PreferredFreq = mode.refresh_rate; + } int w = m_ConfigW; int h = m_ConfigH;