Copy/Paste should work on OSX now. (Thanks AndrewPH)

This commit is contained in:
UnknownShadow200 2016-04-16 14:17:24 +10:00
parent 5e9f401449
commit e5b77528ff
4 changed files with 115 additions and 13 deletions

View File

@ -53,7 +53,7 @@ namespace ClassicalSharp.Gui {
string part = new String( value, start, pos + 1 - start );
List<string> matches = new List<string>();
game.Chat.Add( null, MessageType.ClientStatus5 );
game.Chat.Add( null, MessageType.ClientStatus5 );
bool extList = game.Network.UsingExtPlayerList;
CpeListInfo[] info = game.CpePlayersList;
@ -222,23 +222,37 @@ namespace ClassicalSharp.Gui {
bool OtherKey( Key key ) {
if( key == Key.V && chatInputText.Length < TotalChars ) {
string text = game.window.ClipboardText;
string text = null;
try {
text = game.window.ClipboardText;
} catch( Exception ex ) {
ErrorHandler.LogError( "Paste from clipboard", ex );
const string warning = "&cError while trying to paste from clipboard.";
game.Chat.Add( warning, MessageType.ClientStatus4 );
return true;
}
if( String.IsNullOrEmpty( text ) ) return true;
game.Chat.Add( null, MessageType.ClientStatus4 );
for( int i = 0; i < text.Length; i++ ) {
if( !IsValidInputChar( text[i] ) ) {
const string warning = "&eClipboard contained some characters that can't be sent.";
game.Chat.Add( warning, MessageType.ClientStatus4 );
text = RemoveInvalidChars( text );
break;
}
if( IsValidInputChar( text[i] ) ) continue;
const string warning = "&eClipboard contained some characters that can't be sent.";
game.Chat.Add( warning, MessageType.ClientStatus4 );
text = RemoveInvalidChars( text );
break;
}
AppendText( text );
return true;
} else if( key == Key.C ) {
if( !chatInputText.Empty )
if( chatInputText.Empty ) return true;
try {
game.window.ClipboardText = chatInputText.ToString();
} catch( Exception ex ) {
ErrorHandler.LogError( "Copy to clipboard", ex );
const string warning = "&cError while trying to copy to clipboard.";
game.Chat.Add( warning, MessageType.ClientStatus4 );
}
return true;
}
return false;

View File

@ -82,8 +82,18 @@ namespace ClassicalSharp {
// TODO: retry when clipboard returns null.
public string ClipboardText {
get { return Clipboard.GetText(); }
set { Clipboard.SetText( value ); }
get {
if ( OpenTK.Configuration.RunningOnMacOS )
return GetClipboardText();
else
return Clipboard.GetText();
}
set {
if ( OpenTK.Configuration.RunningOnMacOS )
SetClipboardText( value );
else
Clipboard.SetText( value );
}
}
}
}

View File

@ -779,6 +779,29 @@ namespace OpenTK.Platform.MacOS.Carbon
public extern static OSStatus QDBeginCGContext( IntPtr port, ref IntPtr context );
[DllImport(carbon)]
public extern static OSStatus QDEndCGContext( IntPtr port, ref IntPtr context );
#endregion
#region --- Clipboard ---
[DllImport (carbon)]
public static extern IntPtr CFDataCreate(IntPtr allocator, IntPtr buf, Int32 length);
[DllImport (carbon)]
public static extern IntPtr CFDataGetBytePtr(IntPtr data);
[DllImport (carbon)]
public static extern int PasteboardSynchronize(IntPtr pbref);
[DllImport (carbon)]
public static extern OSStatus PasteboardClear(IntPtr pbref);
[DllImport (carbon)]
public static extern OSStatus PasteboardCreate(IntPtr str, out IntPtr pbref);
[DllImport (carbon)]
public static extern OSStatus PasteboardCopyItemFlavorData(IntPtr pbref, UInt32 itemid, IntPtr key, out IntPtr data);
[DllImport (carbon)]
public static extern OSStatus PasteboardGetItemCount(IntPtr pbref, out UInt32 count);
[DllImport (carbon)]
public static extern OSStatus PasteboardGetItemIdentifier(IntPtr pbref, UInt32 itemindex, out UInt32 itemid);
[DllImport (carbon)]
public static extern OSStatus PasteboardPutItemFlavor(IntPtr pbref, UInt32 itemid, IntPtr key, IntPtr data, UInt32 flags);
#endregion
[DllImport(carbon)]

View File

@ -29,6 +29,7 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using OpenTK.Graphics;
using OpenTK.Platform.MacOS.Carbon;
using OpenTK.Input;
@ -556,9 +557,63 @@ namespace OpenTK.Platform.MacOS
#region INativeWindow Members
public string GetClipboardText() { return ""; }
IntPtr pbStr, utf16, utf8;
public string GetClipboardText() {
IntPtr pbRef = GetPasteboard();
API.PasteboardSynchronize( pbRef );
uint itemCount;
OSStatus err = API.PasteboardGetItemCount( pbRef, out itemCount );
if( err != OSStatus.NoError )
throw new MacOSException( err, "Getting item count from Pasteboard." );
if( itemCount < 1 ) return "";
uint itemID;
err = API.PasteboardGetItemIdentifier( pbRef, 1, out itemID );
if( err != OSStatus.NoError )
throw new MacOSException( err, "Getting item identifier from Pasteboard." );
IntPtr outData;
if ( (err = API.PasteboardCopyItemFlavorData( pbRef, itemID, utf16, out outData )) == OSStatus.NoError ) {
IntPtr ptr = API.CFDataGetBytePtr( outData );
if( ptr == IntPtr.Zero )
throw new InvalidOperationException( "CFDataGetBytePtr() returned null pointer." );
return Marshal.PtrToStringUni( ptr );
}
// TODO: UTF 8
return "";
}
public void SetClipboardText( string value ) { }
public void SetClipboardText( string value ) {
IntPtr pbRef = GetPasteboard();
OSStatus err = API.PasteboardClear( pbRef );
if( err != OSStatus.NoError )
throw new MacOSException( err, "Cleaing Pasteboard." );
API.PasteboardSynchronize( pbRef );
IntPtr ptr = Marshal.StringToHGlobalUni( value );
IntPtr cfData = API.CFDataCreate( IntPtr.Zero, ptr, (value.Length + 1) * 2 );
if( cfData == IntPtr.Zero )
throw new InvalidOperationException( "CFDataCreate() returned null pointer." );
API.PasteboardPutItemFlavor( pbRef, 1, utf16, cfData, 0 );
Marshal.FreeHGlobal( ptr );
}
IntPtr GetPasteboard() {
if( pbStr == IntPtr.Zero ) {
pbStr = CF.CFSTR( "com.apple.pasteboard.clipboard" );
utf16 = CF.CFSTR( "public.utf16-plain-text" );
utf8 = CF.CFSTR( "public.utf8-plain-text" );
}
IntPtr pbRef;
OSStatus err = API.PasteboardCreate( pbStr, out pbRef );
if( err != OSStatus.NoError )
throw new MacOSException( err, "Creating Pasteboard reference." );
API.PasteboardSynchronize( pbRef );
return pbRef;
}
public void ProcessEvents()
{