Browse Source

initial work to fixing clipboard text encoding issues.

Dan Walmsley 7 years ago
parent
commit
779cdec093

+ 7 - 1
native/Avalonia.Native/inc/avalonia-native.h

@@ -173,6 +173,12 @@ public:
     virtual HRESULT ObtainGlFeature(IAvnGlFeature** ppv) = 0;
 };
 
+AVNCOM(IAvnString, 17) : IUnknown
+{
+    virtual HRESULT GetPointer(void**retOut) = 0;
+    virtual HRESULT GetLength(int*ret) = 0;
+};
+
 AVNCOM(IAvnWindowBase, 02) : IUnknown
 {
     virtual HRESULT Show() = 0;
@@ -315,7 +321,7 @@ AVNCOM(IAvnScreens, 0e) : IUnknown
 
 AVNCOM(IAvnClipboard, 0f) : IUnknown
 {
-    virtual HRESULT GetText (void** retOut) = 0;
+    virtual HRESULT GetText (IAvnString** ppv   ) = 0;
     virtual HRESULT SetText (char* text) = 0;
     virtual HRESULT Clear() = 0;
 };

+ 6 - 0
native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj

@@ -9,6 +9,7 @@
 /* Begin PBXBuildFile section */
 		37A517B32159597E00FBA241 /* Screens.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A517B22159597E00FBA241 /* Screens.mm */; };
 		37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C09D8721580FE4006A6758 /* SystemDialogs.mm */; };
+		37DDA9B0219330F8002E132B /* AvnString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37DDA9AF219330F8002E132B /* AvnString.mm */; };
 		37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37E2330E21583241000CB7E2 /* KeyTransform.mm */; };
 		5B21A982216530F500CEE36E /* cursor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B21A981216530F500CEE36E /* cursor.mm */; };
 		5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; };
@@ -26,6 +27,8 @@
 		37A517B22159597E00FBA241 /* Screens.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Screens.mm; sourceTree = "<group>"; };
 		37C09D8721580FE4006A6758 /* SystemDialogs.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SystemDialogs.mm; sourceTree = "<group>"; };
 		37C09D8A21581EF2006A6758 /* window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = window.h; sourceTree = "<group>"; };
+		37DDA9AF219330F8002E132B /* AvnString.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AvnString.mm; sourceTree = "<group>"; };
+		37DDA9B121933371002E132B /* AvnString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnString.h; sourceTree = "<group>"; };
 		37E2330E21583241000CB7E2 /* KeyTransform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyTransform.mm; sourceTree = "<group>"; };
 		5B21A981216530F500CEE36E /* cursor.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cursor.mm; sourceTree = "<group>"; };
 		5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard.mm; sourceTree = "<group>"; };
@@ -65,6 +68,8 @@
 		AB7A61E62147C814003C5833 = {
 			isa = PBXGroup;
 			children = (
+				37DDA9B121933371002E132B /* AvnString.h */,
+				37DDA9AF219330F8002E132B /* AvnString.mm */,
 				37A4E71A2178846A00EACBCD /* headers */,
 				AB573DC3217605E400D389A2 /* gl.mm */,
 				5BF943652167AD1D009CAE35 /* cursor.h */,
@@ -161,6 +166,7 @@
 			files = (
 				5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */,
 				5B21A982216530F500CEE36E /* cursor.mm in Sources */,
+				37DDA9B0219330F8002E132B /* AvnString.mm in Sources */,
 				AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */,
 				37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */,
 				37A517B32159597E00FBA241 /* Screens.mm in Sources */,

+ 14 - 0
native/Avalonia.Native/src/OSX/AvnString.h

@@ -0,0 +1,14 @@
+//
+//  AvnString.h
+//  Avalonia.Native.OSX
+//
+//  Created by Dan Walmsley on 07/11/2018.
+//  Copyright © 2018 Avalonia. All rights reserved.
+//
+
+#ifndef AvnString_h
+#define AvnString_h
+
+extern IAvnString* CreateAvnString(NSString* string);
+
+#endif /* AvnString_h */

+ 55 - 0
native/Avalonia.Native/src/OSX/AvnString.mm

@@ -0,0 +1,55 @@
+//
+//  AvnString.m
+//  Avalonia.Native.OSX
+//
+//  Created by Dan Walmsley on 07/11/2018.
+//  Copyright © 2018 Avalonia. All rights reserved.
+//
+
+#include "common.h"
+
+class AvnStringImpl : public virtual ComSingleObject<IAvnString, &IID_IAvnString>
+{
+private:
+    NSString* _string;
+    
+public:
+    FORWARD_IUNKNOWN()
+    
+    AvnStringImpl(NSString* string)
+    {
+        _string = string;
+    }
+    
+    virtual HRESULT GetPointer(void**retOut) override
+    {
+        @autoreleasepool
+        {
+            if(retOut == nullptr)
+            {
+                return E_POINTER;
+            }
+            
+            *retOut = (void*)_string.UTF8String;
+            
+            return S_OK;
+        }
+    }
+    
+    virtual HRESULT GetLength(int*retOut) override
+    {
+        if(retOut == nullptr)
+        {
+            return E_POINTER;
+        }
+        
+        *retOut = (int)_string.length;
+        
+        return S_OK;
+    }
+};
+
+IAvnString* CreateAvnString(NSString* string)
+{
+    return new AvnStringImpl(string);
+}

+ 10 - 5
native/Avalonia.Native/src/OSX/clipboard.mm

@@ -2,20 +2,25 @@
 // Licensed under the MIT license. See licence.md file in the project root for full license information.
 
 #include "common.h"
+#include "AvnString.h"
 
 class Clipboard : public ComSingleObject<IAvnClipboard, &IID_IAvnClipboard>
 {
 public:
     FORWARD_IUNKNOWN()
-    virtual HRESULT GetText (void** retOut) override
+    virtual HRESULT GetText (IAvnString** retOut) override
     {
         @autoreleasepool
         {
-            NSString *str = [[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString];
-            *retOut = (void *)str.UTF8String;
-        }
+            if(retOut == nullptr)
+            {
+                return E_POINTER;
+            }
+            
+            *retOut = CreateAvnString([[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString]);
         
-        return S_OK;
+            return S_OK;
+        }
     }
     
     virtual HRESULT SetText (char* text) override

+ 5 - 4
src/Avalonia.Native/ClipboardImpl.cs

@@ -24,12 +24,13 @@ namespace Avalonia.Native
             return Task.CompletedTask;
         }
 
-        public Task<string> GetTextAsync()
+        public unsafe Task<string> GetTextAsync()
         {
-            var outPtr = _native.GetText();
-            var text = Marshal.PtrToStringAnsi(outPtr);
+            var text = _native.GetText();
 
-            return Task.FromResult(text);
+            var result = System.Text.Encoding.UTF8.GetString((byte*)text.GetPointer(), text.GetLength());
+
+            return Task.FromResult(result);
         }
 
         public Task SetTextAsync(string text)