1
1
forked from 0ad/0ad

Removes obsolete clipboard, replaces by platform-agnostic SDL2`s APIs. Refs D2476.

Patch By: linkmauve
Tested By: bb, elexis, Stan
This was SVN commit r23624.
This commit is contained in:
Vladislav Belov 2020-05-05 11:18:00 +00:00
parent f558dbbd6f
commit 76909984b2
10 changed files with 38 additions and 628 deletions

View File

@ -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<int>(m_Caption.length()))
m_Caption += text;
else
m_Caption =
m_Caption.Left(m_iBufferPos) + text +
m_Caption.Right(static_cast<long>(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<int>(m_Caption.length()))
m_Caption += text;
else
m_Caption =
m_Caption.Left(m_iBufferPos) + text +
m_Caption.Right(static_cast<long>(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<int>(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")
{

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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 <AppKit/AppKit.h>
#import <AvailabilityMacros.h> // MAC_OS_X_VERSION_MIN_REQUIRED
#import <Foundation/Foundation.h>
#import <string>
#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;
}

View File

@ -113,242 +113,4 @@ static bool get_wminfo(SDL_SysWMinfo& wminfo)
return false;
}
/*
Oh, boy, this is heavy stuff...
<User-End Stuff - Definitions and Conventions>
http://www.freedesktop.org/standards/clipboards-spec/clipboards.txt
<Technical, API stuff>
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)
* <ul>
* <li>Store the selection text in a local buffer
* <li>Tell the X server that we want to own the selection
* <li>Listen for Selection events and respond to them as appropriate
* </ul>
*/
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

View File

@ -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;
}

View File

@ -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_clipboard.h> // SDL_SetClipboardText
#include <shlobj.h> // pick_dir
#include <shellapi.h> // open_url
#include <Wincrypt.h>
#include <WindowsX.h> // message crackers
#include <winhttp.h>
#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<wchar_t> 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;
}

View File

@ -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<int>(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;
}
}