forked from Mirrors/openclonk
win32: Copy, paste and type arbitrary Unicode characters
parent
0a932c656f
commit
9494b90fe8
|
@ -101,10 +101,7 @@ LRESULT APIENTRY FullScreenWinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
|
|||
{
|
||||
// UTF-8 has 1 to 4 data bytes, and we need a terminating \0
|
||||
char c[5] = {0};
|
||||
WCHAR wc[1] = {0};
|
||||
if(!MultiByteToWideChar(CP_ACP, 0L, reinterpret_cast<LPCSTR>(&wParam), 1, wc, 1))
|
||||
return 0;
|
||||
if(!WideCharToMultiByte(CP_UTF8, 0L, wc, 1, c, 4, 0, 0))
|
||||
if(!WideCharToMultiByte(CP_UTF8, 0L, reinterpret_cast<LPCWSTR>(&wParam), 1, c, 4, 0, 0))
|
||||
return 0;
|
||||
// GUI: forward
|
||||
if (::pGUI)
|
||||
|
@ -155,7 +152,7 @@ LRESULT APIENTRY FullScreenWinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
|
|||
}
|
||||
break;
|
||||
}
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
#elif defined(USE_X11)
|
||||
|
|
|
@ -223,7 +223,7 @@ StdStrBuf C4RankSystem::GetRankName(int iRank, bool fReturnLastIfOver)
|
|||
sprintf(keyname,"Rank%03d",iRank+1);
|
||||
if (GetRegistryString(Register,keyname,RankName,C4MaxName+1))
|
||||
return StdStrBuf(RankName);
|
||||
if (!fReturnLastIfOver) return StdStrBuf(NULL);
|
||||
if (!fReturnLastIfOver) return StdStrBuf();
|
||||
--iRank;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -279,42 +279,16 @@ namespace C4GUI
|
|||
|
||||
bool Edit::Copy()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// get selected range
|
||||
int32_t iSelBegin = Min(iSelectionStart, iSelectionEnd), iSelEnd = Max(iSelectionStart, iSelectionEnd);
|
||||
if (iSelBegin == iSelEnd) return false;
|
||||
// 2do: move clipboard functionality to Standard
|
||||
// gain clipboard ownership
|
||||
if (!OpenClipboard(Application.GetWindowHandle())) return false;
|
||||
// must empty the global clipboard, so the application clipboard equals the Windows clipboard
|
||||
EmptyClipboard();
|
||||
StdStrBuf buf;
|
||||
// allocate a global memory object for the text.
|
||||
int32_t iTextLen = iSelEnd-iSelBegin;
|
||||
HANDLE hglbCopy = GlobalAlloc(GMEM_MOVEABLE, iTextLen+1);
|
||||
if (hglbCopy == NULL) { CloseClipboard(); return false; }
|
||||
// lock the handle and copy the text to the buffer.
|
||||
char *szCopyChar = (char *) GlobalLock(hglbCopy);
|
||||
if (!cPasswordMask)
|
||||
SCopy(Text+iSelBegin, szCopyChar, iTextLen);
|
||||
else
|
||||
memset(szCopyChar, cPasswordMask, iTextLen);
|
||||
szCopyChar[iTextLen]=0;
|
||||
GlobalUnlock(hglbCopy);
|
||||
// place the handle on the clipboard.
|
||||
bool fSuccess = !!SetClipboardData(CF_TEXT, hglbCopy);
|
||||
// close clipboard
|
||||
CloseClipboard();
|
||||
// return whether copying was successful
|
||||
return fSuccess;
|
||||
#else
|
||||
static StdStrBuf buf;
|
||||
buf.Clear();
|
||||
int iSelBegin = Min(iSelectionStart, iSelectionEnd);
|
||||
int iSelEnd = Max(iSelectionStart, iSelectionEnd);
|
||||
buf.Append(Text+iSelBegin, iSelEnd-iSelBegin);
|
||||
Application.Copy(buf);
|
||||
return true;
|
||||
#endif
|
||||
if (cPasswordMask)
|
||||
memset(buf.getMData(), cPasswordMask, buf.getLength());
|
||||
|
||||
return Application.Copy(buf);
|
||||
}
|
||||
|
||||
bool Edit::Cut()
|
||||
|
@ -330,58 +304,38 @@ namespace C4GUI
|
|||
bool Edit::Paste()
|
||||
{
|
||||
bool fSuccess = false;
|
||||
// 2do: move clipboard functionality to Standard
|
||||
#ifdef _WIN32
|
||||
// check clipboard contents
|
||||
if (!IsClipboardFormatAvailable(CF_TEXT)) return false;
|
||||
// open clipboard
|
||||
if (!OpenClipboard(NULL)) return false;
|
||||
// get text from clipboard
|
||||
HANDLE hglb = GetClipboardData(CF_TEXT);
|
||||
if (hglb != NULL)
|
||||
if(!Application.IsClipboardFull()) return false;
|
||||
StdStrBuf text(Application.Paste());
|
||||
char * szText = text.getMData();
|
||||
if (text)
|
||||
{
|
||||
char *szText = (char *) GlobalLock(hglb);
|
||||
if (szText != NULL)
|
||||
fSuccess = !!*szText;
|
||||
// replace any '|'
|
||||
int32_t iLBPos=0, iLBPos2;
|
||||
// caution when inserting line breaks: Those must be stripped, and sent as Enter-commands
|
||||
iLBPos=0;
|
||||
for (;;)
|
||||
{
|
||||
fSuccess = !!*szText;
|
||||
// replace any '|'
|
||||
int32_t iLBPos=0, iLBPos2;
|
||||
while ((iLBPos = SCharPos('|', szText, iLBPos))>=0) szText[iLBPos]='l';
|
||||
// caution when inserting line breaks: Those must be stripped, and sent as Enter-commands
|
||||
iLBPos = SCharPos(0x0d, szText);
|
||||
iLBPos2 = SCharPos(0x0a, szText);
|
||||
if (iLBPos<0 && iLBPos2<0) break; // no more linebreaks
|
||||
if (iLBPos2>=0 && (iLBPos2<iLBPos || iLBPos<0)) iLBPos = iLBPos2;
|
||||
if (!iLBPos) { ++szText; continue; } // empty line
|
||||
szText[iLBPos]=0x00;
|
||||
if (!InsertText(szText, true)) fSuccess=false; // if the buffer was too long, still try to insert following stuff (don't abort just b/c one line was too long)
|
||||
szText += iLBPos+1;
|
||||
iLBPos=0;
|
||||
for (;;)
|
||||
if (!DoFinishInput(true, !!*szText))
|
||||
{
|
||||
iLBPos = SCharPos(0x0d, szText);
|
||||
iLBPos2 = SCharPos(0x0a, szText);
|
||||
if (iLBPos<0 && iLBPos2<0) break; // no more linebreaks
|
||||
if (iLBPos2>=0 && (iLBPos2<iLBPos || iLBPos<0)) iLBPos = iLBPos2;
|
||||
if (!iLBPos) { ++szText; continue; } // empty line
|
||||
szText[iLBPos]=0x00;
|
||||
if (!InsertText(szText, true)) fSuccess=false; // if the buffer was too long, still try to insert following stuff (don't abort just b/c one line was too long)
|
||||
szText += iLBPos+1;
|
||||
iLBPos=0;
|
||||
if (!DoFinishInput(true, !!*szText))
|
||||
{
|
||||
// cleanup
|
||||
GlobalUnlock(hglb); CloseClipboard();
|
||||
// safety...
|
||||
if (!IsGUIValid()) return false;
|
||||
// k, pasted
|
||||
return true;
|
||||
}
|
||||
// k, pasted
|
||||
return true;
|
||||
}
|
||||
// insert new text (may fail due to overfull buffer, in which case parts of the text will be inserted)
|
||||
if (*szText) fSuccess = fSuccess && InsertText(szText, true);
|
||||
}
|
||||
// unlock mem
|
||||
GlobalUnlock(hglb);
|
||||
// insert new text (may fail due to overfull buffer, in which case parts of the text will be inserted)
|
||||
if (*szText) fSuccess = fSuccess && InsertText(szText, true);
|
||||
}
|
||||
// close clipboard
|
||||
CloseClipboard();
|
||||
// return whether insertion was successful
|
||||
#else
|
||||
InsertText(Application.Paste().getData(), true);
|
||||
#endif
|
||||
return fSuccess;
|
||||
}
|
||||
|
||||
|
@ -693,11 +647,7 @@ namespace C4GUI
|
|||
pCtx->AddItem(LoadResStr("IDS_DLG_CUT"), LoadResStr("IDS_DLGTIP_CUT"), Ico_None, new CBMenuHandler<Edit>(this, &Edit::OnCtxCut));
|
||||
pCtx->AddItem(LoadResStr("IDS_DLG_COPY"), LoadResStr("IDS_DLGTIP_COPY"), Ico_None, new CBMenuHandler<Edit>(this, &Edit::OnCtxCopy));
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if (IsClipboardFormatAvailable(CF_TEXT))
|
||||
#else
|
||||
if (Application.IsClipboardFull())
|
||||
#endif
|
||||
pCtx->AddItem(LoadResStr("IDS_DLG_PASTE"), LoadResStr("IDS_DLGTIP_PASTE"), Ico_None, new CBMenuHandler<Edit>(this, &Edit::OnCtxPaste));
|
||||
|
||||
if (fAnythingSelected)
|
||||
|
|
|
@ -434,6 +434,15 @@ public:
|
|||
: StdBuf(pData, pData ? strlen(pData) + 1 : 0, fCopy)
|
||||
{ }
|
||||
|
||||
#ifdef _WIN32
|
||||
explicit StdStrBuf(const wchar_t * utf16)
|
||||
{
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, 0, 0);
|
||||
SetSize(len);
|
||||
WideCharToMultiByte(CP_UTF8, 0, utf16, -1, getMData(), getSize(), 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// As previous constructor, but set length manually.
|
||||
StdStrBuf(const char *pData, long int iLength)
|
||||
: StdBuf(pData, pData ? iLength + 1 : 0, false)
|
||||
|
|
|
@ -299,7 +299,7 @@ HANDLE C4FileMonitor::GetEvent()
|
|||
void C4FileMonitor::HandleNotify(const char *szDir, const _FILE_NOTIFY_INFORMATION *pNotify)
|
||||
{
|
||||
// Get filename length
|
||||
UINT iCodePage = CP_ACP /* future: CP_UTF8 */;
|
||||
UINT iCodePage = CP_UTF8;
|
||||
int iFileNameBytes = WideCharToMultiByte(iCodePage, 0,
|
||||
pNotify->FileName, pNotify->FileNameLength / 2, NULL, 0, NULL, NULL);
|
||||
// Set up filename buffer
|
||||
|
|
|
@ -24,13 +24,15 @@
|
|||
#include <C4Include.h>
|
||||
#include <StdWindow.h>
|
||||
|
||||
void CStdApp::Copy(const StdStrBuf & text, bool fClipboard) {
|
||||
bool CStdApp::Copy(const StdStrBuf & text, bool fClipboard) {
|
||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||
[pasteboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
|
||||
NSString* string = [NSString stringWithCString:text.getData() encoding:NSUTF8StringEncoding];
|
||||
if (![pasteboard setString:string forType:NSStringPboardType]) {
|
||||
NSLog(@"Writing to Cocoa pasteboard failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
StdStrBuf CStdApp::Paste(bool fClipboard) {
|
||||
|
|
|
@ -175,7 +175,7 @@ void CStdApp::RestoreVideoMode()
|
|||
#ifndef __APPLE__
|
||||
|
||||
// stubs
|
||||
void CStdApp::Copy(const StdStrBuf & text, bool fClipboard)
|
||||
bool CStdApp::Copy(const StdStrBuf & text, bool fClipboard)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#include "resource.h"
|
||||
#include "C4Version.h"
|
||||
|
||||
#define C4FullScreenClassName "C4FullScreen"
|
||||
#define C4FullScreenClassName L"C4FullScreen"
|
||||
LRESULT APIENTRY FullScreenWinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
CStdWindow::CStdWindow (): Active(false), pSurface(0), hWindow(0)
|
||||
|
@ -62,7 +62,7 @@ CStdWindow::~CStdWindow ()
|
|||
|
||||
BOOL CStdWindow::RegisterWindowClass(HINSTANCE hInst)
|
||||
{
|
||||
WNDCLASSEX WndClass = {0};
|
||||
WNDCLASSEXW WndClass = {0};
|
||||
WndClass.cbSize = sizeof(WNDCLASSEX);
|
||||
WndClass.style = CS_DBLCLKS;
|
||||
WndClass.lpfnWndProc = FullScreenWinProc;
|
||||
|
@ -71,9 +71,12 @@ BOOL CStdWindow::RegisterWindowClass(HINSTANCE hInst)
|
|||
WndClass.lpszClassName = C4FullScreenClassName;
|
||||
WndClass.hIcon = LoadIcon (hInst, MAKEINTRESOURCE (IDI_00_C4X) );
|
||||
WndClass.hIconSm = LoadIcon (hInst, MAKEINTRESOURCE (IDI_00_C4X) );
|
||||
return RegisterClassEx(&WndClass);
|
||||
return RegisterClassExW(&WndClass);
|
||||
}
|
||||
|
||||
#define ADDL2(s) L##s
|
||||
#define ADDL(s) ADDL2(s)
|
||||
|
||||
CStdWindow * CStdWindow::Init(CStdApp * pApp)
|
||||
{
|
||||
Active = true;
|
||||
|
@ -82,10 +85,10 @@ CStdWindow * CStdWindow::Init(CStdApp * pApp)
|
|||
if (!RegisterWindowClass(pApp->hInstance)) return NULL;
|
||||
|
||||
// Create window
|
||||
hWindow = CreateWindowEx (
|
||||
hWindow = CreateWindowExW (
|
||||
0,
|
||||
C4FullScreenClassName,
|
||||
C4ENGINENAME,
|
||||
ADDL(C4ENGINENAME),
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT,CW_USEDEFAULT,0,0,
|
||||
NULL,NULL,pApp->hInstance,NULL);
|
||||
|
@ -430,3 +433,53 @@ void CStdApp::MessageDialog(const char * message)
|
|||
{
|
||||
MessageBox(0, message, C4ENGINECAPTION, MB_ICONERROR);
|
||||
}
|
||||
|
||||
// Clipboard functions
|
||||
bool CStdApp::Copy(const StdStrBuf & text, bool fClipboard)
|
||||
{
|
||||
if (!fClipboard) return false;
|
||||
bool fSuccess = true;
|
||||
// gain clipboard ownership
|
||||
if (!OpenClipboard(GetWindowHandle())) return false;
|
||||
// must empty the global clipboard, so the application clipboard equals the Windows clipboard
|
||||
EmptyClipboard();
|
||||
int size = MultiByteToWideChar(CP_UTF8, 0, text.getData(), text.getSize(), 0, 0);
|
||||
HANDLE hglbCopy = GlobalAlloc(GMEM_MOVEABLE, size * sizeof(wchar_t));
|
||||
if (hglbCopy == NULL) { CloseClipboard(); return false; }
|
||||
// lock the handle and copy the text to the buffer.
|
||||
wchar_t *szCopyChar = (wchar_t *) GlobalLock(hglbCopy);
|
||||
fSuccess = !!MultiByteToWideChar(CP_UTF8, 0, text.getData(), text.getSize(), szCopyChar, size);
|
||||
GlobalUnlock(hglbCopy);
|
||||
// place the handle on the clipboard.
|
||||
fSuccess = fSuccess && !!SetClipboardData(CF_UNICODETEXT, hglbCopy);
|
||||
// close clipboard
|
||||
CloseClipboard();
|
||||
// return whether copying was successful
|
||||
return fSuccess;
|
||||
}
|
||||
|
||||
StdStrBuf CStdApp::Paste(bool fClipboard)
|
||||
{
|
||||
if (!fClipboard) return StdStrBuf();
|
||||
// open clipboard
|
||||
if (!OpenClipboard(NULL)) return StdStrBuf();
|
||||
// get text from clipboard
|
||||
HANDLE hglb = GetClipboardData(CF_UNICODETEXT);
|
||||
if (!hglb) return StdStrBuf();
|
||||
StdStrBuf text((LPCWSTR) GlobalLock(hglb));
|
||||
// unlock mem
|
||||
GlobalUnlock(hglb);
|
||||
// close clipboard
|
||||
CloseClipboard();
|
||||
return text;
|
||||
}
|
||||
|
||||
bool CStdApp::IsClipboardFull(bool fClipboard)
|
||||
{
|
||||
if (!fClipboard) return false;
|
||||
return !!IsClipboardFormatAvailable(CF_UNICODETEXT);
|
||||
}
|
||||
|
||||
void CStdApp::ClearClipboard(bool fClipboard)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -402,7 +402,7 @@ public:
|
|||
bool fQuitMsgReceived; // if true, a quit message has been received and the application should terminate
|
||||
|
||||
// Copy the text to the clipboard or the primary selection
|
||||
void Copy(const StdStrBuf & text, bool fClipboard = true);
|
||||
bool Copy(const StdStrBuf & text, bool fClipboard = true);
|
||||
// Paste the text from the clipboard or the primary selection
|
||||
StdStrBuf Paste(bool fClipboard = true);
|
||||
// Is there something in the clipboard?
|
||||
|
|
|
@ -568,15 +568,17 @@ void CStdAppPrivate::SwitchToDesktop(CStdApp * pApp, Window wnd)
|
|||
}
|
||||
|
||||
// Copy the text to the clipboard or the primary selection
|
||||
void CStdApp::Copy(const StdStrBuf & text, bool fClipboard)
|
||||
bool CStdApp::Copy(const StdStrBuf & text, bool fClipboard)
|
||||
{
|
||||
CStdAppPrivate::ClipboardData & d = fClipboard ? Priv->ClipboardSelection : Priv->PrimarySelection;
|
||||
XSetSelectionOwner(dpy, fClipboard ? XInternAtom(dpy,"CLIPBOARD",false) : XA_PRIMARY, pWindow->wnd, Priv->LastEventTime);
|
||||
Window owner = XGetSelectionOwner(dpy, fClipboard ? XInternAtom(dpy,"CLIPBOARD",false) : XA_PRIMARY);
|
||||
if (owner != pWindow->wnd) return;
|
||||
if (owner != pWindow->wnd) return false;
|
||||
d.Text.Copy(text);
|
||||
d.AcquirationTime = Priv->LastEventTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Paste the text from the clipboard or the primary selection
|
||||
StdStrBuf CStdApp::Paste(bool fClipboard)
|
||||
{
|
||||
|
@ -614,11 +616,13 @@ StdStrBuf CStdApp::Paste(bool fClipboard)
|
|||
XFree (data);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Is there something in the clipboard?
|
||||
bool CStdApp::IsClipboardFull(bool fClipboard)
|
||||
{
|
||||
return None != XGetSelectionOwner (dpy, fClipboard ? XInternAtom(dpy,"CLIPBOARD",false) : XA_PRIMARY);
|
||||
}
|
||||
|
||||
// Give up Selection ownership
|
||||
void CStdApp::ClearClipboard(bool fClipboard)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue