diff --git a/.editorconfig b/.editorconfig
index f6bce9cb76..c7a381b730 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -156,6 +156,9 @@ indent_size = 2
[*.{props,targets,config,nuspec}]
indent_size = 2
+[*.json]
+indent_size = 2
+
# Shell scripts
[*.sh]
end_of_line = lf
diff --git a/Avalonia.sln b/Avalonia.sln
index 34ad19b41d..74a2dbb94b 100644
--- a/Avalonia.sln
+++ b/Avalonia.sln
@@ -226,6 +226,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI.Events"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sandbox", "samples\Sandbox\Sandbox.csproj", "{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MicroComGenerator", "src\tools\MicroComGenerator\MicroComGenerator.csproj", "{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.MicroCom", "src\Avalonia.MicroCom\Avalonia.MicroCom.csproj", "{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}"
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13
@@ -2064,6 +2068,54 @@ Global
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhone.Build.0 = Release|Any CPU
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|iPhone.Build.0 = Release|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|iPhone.Build.0 = Release|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -2123,6 +2175,7 @@ Global
{3C84E04B-36CF-4D0D-B965-C26DD649D1F3} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}
{909A8CBD-7D0E-42FD-B841-022AD8925820} = {8B6A8209-894F-4BA1-B880-965FD453982C}
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index e67fa14c57..ac1944b171 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -3,13 +3,6 @@ jobs:
pool:
vmImage: 'ubuntu-16.04'
steps:
- - task: CmdLine@2
- displayName: 'Install CastXML'
- inputs:
- script: |
- sudo apt-get update
- sudo apt-get install castxml
-
- task: CmdLine@2
displayName: 'Install Nuke'
inputs:
@@ -48,6 +41,12 @@ jobs:
curl -o ./mono.pkg https://download.mono-project.com/archive/5.18.0/macos-10-universal/MonoFramework-MDK-5.18.0.225.macos10.xamarin.universal.pkg
sudo installer -verbose -pkg ./mono.pkg -target /
+ - task: CmdLine@2
+ displayName: 'Generate avalonia-native'
+ inputs:
+ script: |
+ cd src/tools/MicroComGenerator; dotnet run -i ../../Avalonia.Native/avn.idl --cpp ../../../native/Avalonia.Native/inc/avalonia-native.h
+
- task: Xcode@5
inputs:
actions: 'build'
diff --git a/build.ps1 b/build.ps1
index 3672e82d3b..985e8abcee 100644
--- a/build.ps1
+++ b/build.ps1
@@ -43,7 +43,7 @@ if (Test-Path $DotNetGlobalFile) {
}
# If dotnet is installed locally, and expected version is not set or installation matches the expected version
-if ((Get-Command "dotnet" -ErrorAction SilentlyContinue) -ne $null -and `
+if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and `
(!(Test-Path variable:DotNetVersion) -or $(& dotnet --version) -eq $DotNetVersion)) {
$env:DOTNET_EXE = (Get-Command "dotnet").Path
}
@@ -53,7 +53,7 @@ else {
# Download install script
$DotNetInstallFile = "$TempDirectory\dotnet-install.ps1"
- md -force $TempDirectory > $null
+ mkdir -force $TempDirectory > $null
(New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile)
# Install by channel or version
diff --git a/build.sh b/build.sh
index a40e00f815..bd162fab9b 100755
--- a/build.sh
+++ b/build.sh
@@ -47,7 +47,7 @@ if [ -f "$DOTNET_GLOBAL_FILE" ]; then
fi
# If dotnet is installed locally, and expected version is not set or installation matches the expected version
-if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") ]]; then
+if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") || "$SKIP_DOTNET_DOWNLOAD" == "1" ]]; then
export DOTNET_EXE="$(command -v dotnet)"
else
DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix"
diff --git a/build/CoreLibraries.props b/build/CoreLibraries.props
index d17eec0135..fff00041c3 100644
--- a/build/CoreLibraries.props
+++ b/build/CoreLibraries.props
@@ -15,6 +15,7 @@
+
diff --git a/native/Avalonia.Native/inc/.gitignore b/native/Avalonia.Native/inc/.gitignore
new file mode 100644
index 0000000000..e7aa7fc6a5
--- /dev/null
+++ b/native/Avalonia.Native/inc/.gitignore
@@ -0,0 +1 @@
+avalonia-native.h
diff --git a/native/Avalonia.Native/inc/avalonia-native.h b/native/Avalonia.Native/inc/avalonia-native.h
deleted file mode 100644
index 9ff6130e5f..0000000000
--- a/native/Avalonia.Native/inc/avalonia-native.h
+++ /dev/null
@@ -1,516 +0,0 @@
-#include "com.h"
-#include "key.h"
-#include "stddef.h"
-
-#define AVNCOM(name, id) COMINTERFACE(name, 2e2cda0a, 9ae5, 4f1b, 8e, 20, 08, 1a, 04, 27, 9f, id)
-
-struct IAvnWindowEvents;
-struct IAvnWindow;
-struct IAvnPopup;
-struct IAvnMacOptions;
-struct IAvnPlatformThreadingInterface;
-struct IAvnSystemDialogEvents;
-struct IAvnSystemDialogs;
-struct IAvnScreens;
-struct IAvnClipboard;
-struct IAvnCursor;
-struct IAvnCursorFactory;
-struct IAvnGlFeature;
-struct IAvnGlContext;
-struct IAvnGlDisplay;
-struct IAvnGlSurfaceRenderTarget;
-struct IAvnGlSurfaceRenderingSession;
-struct IAvnMenu;
-struct IAvnMenuItem;
-struct IAvnStringArray;
-struct IAvnDndResultCallback;
-struct IAvnGCHandleDeallocatorCallback;
-struct IAvnMenuEvents;
-struct IAvnNativeControlHost;
-struct IAvnNativeControlHostTopLevelAttachment;
-enum SystemDecorations {
- SystemDecorationsNone = 0,
- SystemDecorationsBorderOnly = 1,
- SystemDecorationsFull = 2,
-};
-
-struct AvnSize
-{
- double Width, Height;
-};
-
-struct AvnPixelSize
-{
- int Width, Height;
-};
-
-struct AvnRect
-{
- double X, Y, Width, Height;
-};
-
-struct AvnVector
-{
- double X, Y;
-};
-
-struct AvnPoint
-{
- double X, Y;
-};
-
-struct AvnScreen
-{
- AvnRect Bounds;
- AvnRect WorkingArea;
- float PixelDensity;
- bool Primary;
-};
-
-enum AvnPixelFormat
-{
- kAvnRgb565,
- kAvnRgba8888,
- kAvnBgra8888
-};
-
-struct AvnFramebuffer
-{
- void* Data;
- int Width;
- int Height;
- int Stride;
- AvnVector Dpi;
- AvnPixelFormat PixelFormat;
-};
-
-struct AvnColor
-{
- unsigned char Alpha;
- unsigned char Red;
- unsigned char Green;
- unsigned char Blue;
-};
-
-enum AvnRawMouseEventType
-{
- LeaveWindow,
- LeftButtonDown,
- LeftButtonUp,
- RightButtonDown,
- RightButtonUp,
- MiddleButtonDown,
- MiddleButtonUp,
- XButton1Down,
- XButton1Up,
- XButton2Down,
- XButton2Up,
- Move,
- Wheel,
- NonClientLeftButtonDown,
- TouchBegin,
- TouchUpdate,
- TouchEnd,
- TouchCancel
-};
-
-enum AvnRawKeyEventType
-{
- KeyDown,
- KeyUp
-};
-
-enum AvnInputModifiers
-{
- AvnInputModifiersNone = 0,
- Alt = 1,
- Control = 2,
- Shift = 4,
- Windows = 8,
- LeftMouseButton = 16,
- RightMouseButton = 32,
- MiddleMouseButton = 64,
- XButton1MouseButton = 128,
- XButton2MouseButton = 256
-};
-
-enum class AvnDragDropEffects
-{
- None = 0,
- Copy = 1,
- Move = 2,
- Link = 4,
-};
-
-enum class AvnDragEventType
-{
- Enter,
- Over,
- Leave,
- Drop
-};
-
-enum AvnWindowState
-{
- Normal,
- Minimized,
- Maximized,
- FullScreen,
-};
-
-enum AvnStandardCursorType
-{
- CursorArrow,
- CursorIbeam,
- CursorWait,
- CursorCross,
- CursorUpArrow,
- CursorSizeWestEast,
- CursorSizeNorthSouth,
- CursorSizeAll,
- CursorNo,
- CursorHand,
- CursorAppStarting,
- CursorHelp,
- CursorTopSide,
- CursorBottomSize,
- CursorLeftSide,
- CursorRightSide,
- CursorTopLeftCorner,
- CursorTopRightCorner,
- CursorBottomLeftCorner,
- CursorBottomRightCorner,
- CursorDragMove,
- CursorDragCopy,
- CursorDragLink,
- CursorNone
-};
-
-enum AvnWindowEdge
-{
- WindowEdgeNorthWest,
- WindowEdgeNorth,
- WindowEdgeNorthEast,
- WindowEdgeWest,
- WindowEdgeEast,
- WindowEdgeSouthWest,
- WindowEdgeSouth,
- WindowEdgeSouthEast
-};
-
-enum AvnMenuItemToggleType
-{
- None,
- CheckMark,
- Radio
-};
-
-enum AvnExtendClientAreaChromeHints
-{
- AvnNoChrome = 0,
- AvnSystemChrome = 0x01,
- AvnPreferSystemChrome = 0x02,
- AvnOSXThickTitleBar = 0x08,
- AvnDefaultChrome = AvnSystemChrome,
-};
-
-AVNCOM(IAvaloniaNativeFactory, 01) : IUnknown
-{
-public:
- virtual HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator) = 0;
- virtual IAvnMacOptions* GetMacOptions() = 0;
- virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnWindow** ppv) = 0;
- virtual HRESULT CreatePopup (IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnPopup** ppv) = 0;
- virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) = 0;
- virtual HRESULT CreateSystemDialogs (IAvnSystemDialogs** ppv) = 0;
- virtual HRESULT CreateScreens (IAvnScreens** ppv) = 0;
- virtual HRESULT CreateClipboard(IAvnClipboard** ppv) = 0;
- virtual HRESULT CreateDndClipboard(IAvnClipboard** ppv) = 0;
- virtual HRESULT CreateCursorFactory(IAvnCursorFactory** ppv) = 0;
- virtual HRESULT ObtainGlDisplay(IAvnGlDisplay** ppv) = 0;
- virtual HRESULT SetAppMenu(IAvnMenu* menu) = 0;
- virtual HRESULT CreateMenu (IAvnMenuEvents* cb, IAvnMenu** ppv) = 0;
- virtual HRESULT CreateMenuItem (IAvnMenuItem** ppv) = 0;
- virtual HRESULT CreateMenuItemSeperator (IAvnMenuItem** ppv) = 0;
-};
-
-AVNCOM(IAvnString, 17) : IUnknown
-{
- virtual HRESULT Pointer(void**retOut) = 0;
- virtual HRESULT Length(int*ret) = 0;
-};
-
-AVNCOM(IAvnWindowBase, 02) : IUnknown
-{
- virtual HRESULT Show() = 0;
- virtual HRESULT Hide () = 0;
- virtual HRESULT Close() = 0;
- virtual HRESULT Activate () = 0;
- virtual HRESULT GetClientSize(AvnSize*ret) = 0;
- virtual HRESULT GetScaling(double*ret)=0;
- virtual HRESULT SetMinMaxSize(AvnSize minSize, AvnSize maxSize) = 0;
- virtual HRESULT Resize(double width, double height) = 0;
- virtual HRESULT Invalidate (AvnRect rect) = 0;
- virtual HRESULT BeginMoveDrag () = 0;
- virtual HRESULT BeginResizeDrag (AvnWindowEdge edge) = 0;
- virtual HRESULT GetPosition (AvnPoint*ret) = 0;
- virtual HRESULT SetPosition (AvnPoint point) = 0;
- virtual HRESULT PointToClient (AvnPoint point, AvnPoint*ret) = 0;
- virtual HRESULT PointToScreen (AvnPoint point, AvnPoint*ret) = 0;
- virtual HRESULT ThreadSafeSetSwRenderedFrame(AvnFramebuffer* fb, IUnknown* dispose) = 0;
- virtual HRESULT SetTopMost (bool value) = 0;
- virtual HRESULT SetCursor(IAvnCursor* cursor) = 0;
- virtual HRESULT CreateGlRenderTarget(IAvnGlSurfaceRenderTarget** ret) = 0;
- virtual HRESULT SetMainMenu(IAvnMenu* menu) = 0;
- virtual HRESULT ObtainNSWindowHandle(void** retOut) = 0;
- virtual HRESULT ObtainNSWindowHandleRetained(void** retOut) = 0;
- virtual HRESULT ObtainNSViewHandle(void** retOut) = 0;
- virtual HRESULT ObtainNSViewHandleRetained(void** retOut) = 0;
- virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost** retOut) = 0;
- virtual HRESULT BeginDragAndDropOperation(AvnDragDropEffects effects, AvnPoint point,
- IAvnClipboard* clipboard, IAvnDndResultCallback* cb, void* sourceHandle) = 0;
- virtual HRESULT SetBlurEnabled (bool enable) = 0;
-};
-
-AVNCOM(IAvnPopup, 03) : virtual IAvnWindowBase
-{
-
-};
-
-AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase
-{
- virtual HRESULT SetEnabled (bool enable) = 0;
- virtual HRESULT SetParent (IAvnWindow* parent) = 0;
- virtual HRESULT SetCanResize(bool value) = 0;
- virtual HRESULT SetDecorations(SystemDecorations value) = 0;
- virtual HRESULT SetTitle (void* utf8Title) = 0;
- virtual HRESULT SetTitleBarColor (AvnColor color) = 0;
- virtual HRESULT SetWindowState(AvnWindowState state) = 0;
- virtual HRESULT GetWindowState(AvnWindowState*ret) = 0;
- virtual HRESULT TakeFocusFromChildren() = 0;
- virtual HRESULT SetExtendClientArea (bool enable) = 0;
- virtual HRESULT SetExtendClientAreaHints (AvnExtendClientAreaChromeHints hints) = 0;
- virtual HRESULT GetExtendTitleBarHeight (double*ret) = 0;
- virtual HRESULT SetExtendTitleBarHeight (double value) = 0;
-};
-
-AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown
-{
- virtual HRESULT Paint() = 0;
- virtual void Closed() = 0;
- virtual void Activated() = 0;
- virtual void Deactivated() = 0;
- virtual void Resized(const AvnSize& size) = 0;
- virtual void PositionChanged (AvnPoint position) = 0;
- virtual void RawMouseEvent (AvnRawMouseEventType type,
- unsigned int timeStamp,
- AvnInputModifiers modifiers,
- AvnPoint point,
- AvnVector delta) = 0;
- virtual bool RawKeyEvent (AvnRawKeyEventType type, unsigned int timeStamp, AvnInputModifiers modifiers, unsigned int key) = 0;
- virtual bool RawTextInputEvent (unsigned int timeStamp, const char* text) = 0;
- virtual void ScalingChanged(double scaling) = 0;
- virtual void RunRenderPriorityJobs() = 0;
- virtual void LostFocus() = 0;
- virtual AvnDragDropEffects DragEvent(AvnDragEventType type, AvnPoint position,
- AvnInputModifiers modifiers, AvnDragDropEffects effects,
- IAvnClipboard* clipboard, void* dataObjectHandle) = 0;
-};
-
-
-AVNCOM(IAvnWindowEvents, 06) : IAvnWindowBaseEvents
-{
- /**
- * Closing Event
- * Called when the user presses the OS window close button.
- * return true to allow the close, return false to prevent close.
- */
- virtual bool Closing () = 0;
-
- virtual void WindowStateChanged (AvnWindowState state) = 0;
-
- virtual void GotInputWhenDisabled () = 0;
-};
-
-AVNCOM(IAvnMacOptions, 07) : IUnknown
-{
- virtual HRESULT SetShowInDock(int show) = 0;
- virtual HRESULT SetApplicationTitle (void* utf8string) = 0;
-};
-
-AVNCOM(IAvnActionCallback, 08) : IUnknown
-{
- virtual void Run() = 0;
-};
-
-AVNCOM(IAvnSignaledCallback, 09) : IUnknown
-{
- virtual void Signaled(int priority, bool priorityContainsMeaningfulValue) = 0;
-};
-
-AVNCOM(IAvnLoopCancellation, 0a) : IUnknown
-{
- virtual void Cancel() = 0;
-};
-
-AVNCOM(IAvnPlatformThreadingInterface, 0b) : IUnknown
-{
- virtual bool GetCurrentThreadIsLoopThread() = 0;
- virtual void SetSignaledCallback(IAvnSignaledCallback* cb) = 0;
- virtual IAvnLoopCancellation* CreateLoopCancellation() = 0;
- virtual HRESULT RunLoop(IAvnLoopCancellation* cancel) = 0;
- // Can't pass int* to sharpgentools for some reason
- virtual void Signal(int priority) = 0;
- virtual IUnknown* StartTimer(int priority, int ms, IAvnActionCallback* callback) = 0;
-};
-
-AVNCOM(IAvnSystemDialogEvents, 0c) : IUnknown
-{
- virtual void OnCompleted (int numResults, void* ptrFirstResult) = 0;
-};
-
-AVNCOM(IAvnSystemDialogs, 0d) : IUnknown
-{
- virtual void SelectFolderDialog (IAvnWindow* parentWindowHandle,
- IAvnSystemDialogEvents* events,
- const char* title,
- const char* initialPath) = 0;
-
- virtual void OpenFileDialog (IAvnWindow* parentWindowHandle,
- IAvnSystemDialogEvents* events,
- bool allowMultiple,
- const char* title,
- const char* initialDirectory,
- const char* initialFile,
- const char* filters) = 0;
-
- virtual void SaveFileDialog (IAvnWindow* parentWindowHandle,
- IAvnSystemDialogEvents* events,
- const char* title,
- const char* initialDirectory,
- const char* initialFile,
- const char* filters) = 0;
-};
-
-AVNCOM(IAvnScreens, 0e) : IUnknown
-{
- virtual HRESULT GetScreenCount (int* ret) = 0;
- virtual HRESULT GetScreen (int index, AvnScreen* ret) = 0;
-};
-
-AVNCOM(IAvnClipboard, 0f) : IUnknown
-{
- virtual HRESULT GetText (char* type, IAvnString**ppv) = 0;
- virtual HRESULT SetText (char* type, void* utf8Text) = 0;
- virtual HRESULT ObtainFormats(IAvnStringArray**ppv) = 0;
- virtual HRESULT GetStrings(char* type, IAvnStringArray**ppv) = 0;
- virtual HRESULT SetBytes(char* type, void* utf8Text, int len) = 0;
- virtual HRESULT GetBytes(char* type, IAvnString**ppv) = 0;
-
- virtual HRESULT Clear() = 0;
-};
-
-AVNCOM(IAvnCursor, 10) : IUnknown
-{
-};
-
-AVNCOM(IAvnCursorFactory, 11) : IUnknown
-{
- virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut) = 0;
-};
-
-AVNCOM(IAvnGlDisplay, 13) : IUnknown
-{
- virtual HRESULT CreateContext(IAvnGlContext* share, IAvnGlContext**ppv) = 0;
- virtual void LegacyClearCurrentContext() = 0;
- virtual HRESULT WrapContext(void* native, IAvnGlContext**ppv) = 0;
- virtual void* GetProcAddress(char* proc) = 0;
-};
-
-AVNCOM(IAvnGlContext, 14) : IUnknown
-{
- virtual HRESULT MakeCurrent(IUnknown** ppv) = 0;
- virtual HRESULT LegacyMakeCurrent() = 0;
- virtual int GetSampleCount() = 0;
- virtual int GetStencilSize() = 0;
- virtual void* GetNativeHandle() = 0;
-};
-
-AVNCOM(IAvnGlSurfaceRenderTarget, 15) : IUnknown
-{
- virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) = 0;
-};
-
-AVNCOM(IAvnGlSurfaceRenderingSession, 16) : IUnknown
-{
- virtual HRESULT GetPixelSize(AvnPixelSize* ret) = 0;
- virtual HRESULT GetScaling(double* ret) = 0;
-};
-
-AVNCOM(IAvnMenu, 17) : IUnknown
-{
- virtual HRESULT InsertItem (int index, IAvnMenuItem* item) = 0;
- virtual HRESULT RemoveItem (IAvnMenuItem* item) = 0;
- virtual HRESULT SetTitle (void* utf8String) = 0;
- virtual HRESULT Clear () = 0;
-};
-
-AVNCOM(IAvnPredicateCallback, 18) : IUnknown
-{
- virtual bool Evaluate() = 0;
-};
-
-AVNCOM(IAvnMenuItem, 19) : IUnknown
-{
- virtual HRESULT SetSubMenu (IAvnMenu* menu) = 0;
- virtual HRESULT SetTitle (void* utf8String) = 0;
- virtual HRESULT SetGesture (void* utf8String, AvnInputModifiers modifiers) = 0;
- virtual HRESULT SetAction (IAvnPredicateCallback* predicate, IAvnActionCallback* callback) = 0;
- virtual HRESULT SetIsChecked (bool isChecked) = 0;
- virtual HRESULT SetToggleType (AvnMenuItemToggleType toggleType) = 0;
- virtual HRESULT SetIcon (void* data, size_t length) = 0;
-};
-
-AVNCOM(IAvnMenuEvents, 1A) : IUnknown
-{
- /**
- * NeedsUpdate
- */
- virtual void NeedsUpdate () = 0;
-};
-
-AVNCOM(IAvnStringArray, 20) : IUnknown
-{
- virtual unsigned int GetCount() = 0;
- virtual HRESULT Get(unsigned int index, IAvnString**ppv) = 0;
-};
-
-AVNCOM(IAvnDndResultCallback, 21) : IUnknown
-{
- virtual void OnDragAndDropComplete(AvnDragDropEffects effecct) = 0;
-};
-
-AVNCOM(IAvnGCHandleDeallocatorCallback, 22) : IUnknown
-{
- virtual void FreeGCHandle(void* handle) = 0;
-};
-
-AVNCOM(IAvnNativeControlHost, 20) : IUnknown
-{
- virtual HRESULT CreateDefaultChild(void* parent, void** retOut) = 0;
- virtual IAvnNativeControlHostTopLevelAttachment* CreateAttachment() = 0;
- virtual void DestroyDefaultChild(void* child) = 0;
-};
-
-AVNCOM(IAvnNativeControlHostTopLevelAttachment, 21) : IUnknown
-{
- virtual void* GetParentHandle() = 0;
- virtual HRESULT InitializeWithChildHandle(void* child) = 0;
- virtual HRESULT AttachTo(IAvnNativeControlHost* host) = 0;
- virtual void ShowInBounds(float x, float y, float width, float height) = 0;
- virtual void HideWithSize(float width, float height) = 0;
- virtual void ReleaseChild() = 0;
-};
-
-
-extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative();
diff --git a/native/Avalonia.Native/src/OSX/clipboard.mm b/native/Avalonia.Native/src/OSX/clipboard.mm
index 116a08670e..303f727317 100644
--- a/native/Avalonia.Native/src/OSX/clipboard.mm
+++ b/native/Avalonia.Native/src/OSX/clipboard.mm
@@ -67,7 +67,7 @@ public:
}
}
- virtual HRESULT SetText (char* type, void* utf8String) override
+ virtual HRESULT SetText (char* type, char* utf8String) override
{
Clear();
@autoreleasepool
diff --git a/native/Avalonia.Native/src/OSX/main.mm b/native/Avalonia.Native/src/OSX/main.mm
index e6c4a861fd..cd6ef73826 100644
--- a/native/Avalonia.Native/src/OSX/main.mm
+++ b/native/Avalonia.Native/src/OSX/main.mm
@@ -104,9 +104,9 @@ class MacOptions : public ComSingleObject
public:
FORWARD_IUNKNOWN()
- virtual HRESULT SetApplicationTitle(void* utf8String) override
+ virtual HRESULT SetApplicationTitle(char* utf8String) override
{
- auto appTitle = [NSString stringWithUTF8String:(const char*)utf8String];
+ auto appTitle = [NSString stringWithUTF8String: utf8String];
[[NSProcessInfo processInfo] setProcessName:appTitle];
diff --git a/native/Avalonia.Native/src/OSX/menu.h b/native/Avalonia.Native/src/OSX/menu.h
index bfbc6801f8..0e43b22846 100644
--- a/native/Avalonia.Native/src/OSX/menu.h
+++ b/native/Avalonia.Native/src/OSX/menu.h
@@ -43,9 +43,9 @@ public:
virtual HRESULT SetSubMenu (IAvnMenu* menu) override;
- virtual HRESULT SetTitle (void* utf8String) override;
+ virtual HRESULT SetTitle (char* utf8String) override;
- virtual HRESULT SetGesture (void* key, AvnInputModifiers modifiers) override;
+ virtual HRESULT SetGesture (char* key, AvnInputModifiers modifiers) override;
virtual HRESULT SetAction (IAvnPredicateCallback* predicate, IAvnActionCallback* callback) override;
@@ -80,7 +80,7 @@ public:
virtual HRESULT RemoveItem (IAvnMenuItem* item) override;
- virtual HRESULT SetTitle (void* utf8String) override;
+ virtual HRESULT SetTitle (char* utf8String) override;
virtual HRESULT Clear () override;
};
diff --git a/native/Avalonia.Native/src/OSX/menu.mm b/native/Avalonia.Native/src/OSX/menu.mm
index dc1245cd23..1356388b85 100644
--- a/native/Avalonia.Native/src/OSX/menu.mm
+++ b/native/Avalonia.Native/src/OSX/menu.mm
@@ -109,7 +109,7 @@ HRESULT AvnAppMenuItem::SetSubMenu (IAvnMenu* menu)
}
}
-HRESULT AvnAppMenuItem::SetTitle (void* utf8String)
+HRESULT AvnAppMenuItem::SetTitle (char* utf8String)
{
@autoreleasepool
{
@@ -122,7 +122,7 @@ HRESULT AvnAppMenuItem::SetTitle (void* utf8String)
}
}
-HRESULT AvnAppMenuItem::SetGesture (void* key, AvnInputModifiers modifiers)
+HRESULT AvnAppMenuItem::SetGesture (char* key, AvnInputModifiers modifiers)
{
@autoreleasepool
{
@@ -296,7 +296,7 @@ HRESULT AvnAppMenu::RemoveItem (IAvnMenuItem* item)
}
}
-HRESULT AvnAppMenu::SetTitle (void* utf8String)
+HRESULT AvnAppMenu::SetTitle (char* utf8String)
{
@autoreleasepool
{
diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm
index 67b1ea50a6..e3996a1fae 100644
--- a/native/Avalonia.Native/src/OSX/window.mm
+++ b/native/Avalonia.Native/src/OSX/window.mm
@@ -768,7 +768,7 @@ private:
}
}
- virtual HRESULT SetTitle (void* utf8title) override
+ virtual HRESULT SetTitle (char* utf8title) override
{
@autoreleasepool
{
diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs
index 097815cc69..ecc01b4aab 100644
--- a/nukebuild/Build.cs
+++ b/nukebuild/Build.cs
@@ -233,6 +233,21 @@ partial class Build : NukeBuild
}
}
+ Target RunHtmlPreviewerTests => _ => _
+ .DependsOn(CompileHtmlPreviewer)
+ .OnlyWhenStatic(() => !(Parameters.SkipPreviewer || Parameters.SkipTests))
+ .Executes(() =>
+ {
+ var webappTestDir = RootDirectory / "tests" / "Avalonia.DesignerSupport.Tests" / "Remote" / "HtmlTransport" / "webapp";
+
+ NpmTasks.NpmInstall(c => c
+ .SetWorkingDirectory(webappTestDir)
+ .SetArgumentConfigurator(a => a.Add("--silent")));
+ NpmTasks.NpmRun(c => c
+ .SetWorkingDirectory(webappTestDir)
+ .SetCommand("test"));
+ });
+
Target RunCoreLibsTests => _ => _
.OnlyWhenStatic(() => !Parameters.SkipTests)
.DependsOn(Compile)
@@ -332,6 +347,7 @@ partial class Build : NukeBuild
.DependsOn(RunCoreLibsTests)
.DependsOn(RunRenderTests)
.DependsOn(RunDesignerTests)
+ .DependsOn(RunHtmlPreviewerTests)
.DependsOn(RunLeakTests);
Target Package => _ => _
diff --git a/nukebuild/BuildParameters.cs b/nukebuild/BuildParameters.cs
index a167e9d892..c76019d9eb 100644
--- a/nukebuild/BuildParameters.cs
+++ b/nukebuild/BuildParameters.cs
@@ -62,7 +62,7 @@ public partial class Build
public AbsolutePath ZipTargetControlCatalogDesktopDir { get; }
- public BuildParameters(Build b)
+ public BuildParameters(Build b)
{
// ARGUMENTS
Configuration = b.Configuration ?? "Release";
diff --git a/nukebuild/MicroComGen.cs b/nukebuild/MicroComGen.cs
new file mode 100644
index 0000000000..06c8acbf23
--- /dev/null
+++ b/nukebuild/MicroComGen.cs
@@ -0,0 +1,14 @@
+using System.IO;
+using MicroComGenerator;
+using Nuke.Common;
+
+partial class Build : NukeBuild
+{
+ Target GenerateCppHeaders => _ => _.Executes(() =>
+ {
+ var text = File.ReadAllText(RootDirectory / "src" / "Avalonia.Native" / "avn.idl");
+ var ast = AstParser.Parse(text);
+ File.WriteAllText(RootDirectory / "native" / "Avalonia.Native" / "inc" / "avalonia-native.h",
+ CppGen.GenerateCpp(ast));
+ });
+}
\ No newline at end of file
diff --git a/nukebuild/_build.csproj b/nukebuild/_build.csproj
index 77cfb83427..745c727be2 100644
--- a/nukebuild/_build.csproj
+++ b/nukebuild/_build.csproj
@@ -39,4 +39,8 @@
+
+
+
+
diff --git a/packages/Avalonia/Avalonia.csproj b/packages/Avalonia/Avalonia.csproj
index cd3ce9adcd..75ee4a05cb 100644
--- a/packages/Avalonia/Avalonia.csproj
+++ b/packages/Avalonia/Avalonia.csproj
@@ -5,9 +5,8 @@
-
+
-
@@ -15,9 +14,7 @@
-
+
<_PackageFiles Include="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/bin/$(Configuration)/netcoreapp2.0/Avalonia.Designer.HostApp.dll">
diff --git a/packages/Avalonia/AvaloniaBuildTasks.targets b/packages/Avalonia/AvaloniaBuildTasks.targets
index 612c368633..45a7f1aa44 100644
--- a/packages/Avalonia/AvaloniaBuildTasks.targets
+++ b/packages/Avalonia/AvaloniaBuildTasks.targets
@@ -3,6 +3,8 @@
<_AvaloniaUseExternalMSBuild>$(AvaloniaUseExternalMSBuild)
<_AvaloniaUseExternalMSBuild Condition="'$(_AvaloniaForceInternalMSBuild)' == 'true'">false
low
+ <_AvaloniaPatchComInterop Condition="'$(_AvaloniaPatchComInterop)' == ''">false
+ <_AvaloniaSkipXamlCompilation Condition="'$(_AvaloniaSkipXamlCompilation)' == ''">false
@@ -90,6 +92,8 @@
AssemblyOriginatorKeyFile="$(AssemblyOriginatorKeyFile)"
SignAssembly="$(SignAssembly)"
DelaySign="$(DelaySign)"
+ EnableComInteropPatching="$(_AvaloniaPatchComInterop)"
+ SkipXamlCompilation="$(_AvaloniaSkipXamlCompilation)"
/>
();
+ var initializers = new List();
+ foreach (var type in asm.MainModule.Types)
+ {
+ var i = type.Methods.FirstOrDefault(m => m.Name == "__MicroComModuleInit");
+ if (i != null)
+ initializers.Add(i);
+
+ PatchType(type, classToRemoveList);
+ }
+
+ // Remove All Interop classes
+ foreach (var type in classToRemoveList)
+ asm.MainModule.Types.Remove(type);
+
+
+ // Patch automatic registrations
+ if (initializers.Count != 0)
+ {
+ var moduleType = asm.MainModule.Types.First(x => x.Name == "");
+
+ // Needed for compatibility with upcoming .NET 5 feature, look for existing initializer first
+ var staticCtor = moduleType.Methods.FirstOrDefault(m => m.Name == ".cctor");
+ if (staticCtor == null)
+ {
+ // Create a new static ctor if none exists
+ staticCtor = new MethodDefinition(".cctor",
+ MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName |
+ MethodAttributes.Static | MethodAttributes.Private,
+ asm.MainModule.TypeSystem.Void);
+ staticCtor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
+ moduleType.Methods.Add(staticCtor);
+ }
+
+ foreach (var i in initializers)
+ staticCtor.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, i));
+ }
+
+ }
+
+
+
+ static void PatchMethod(MethodDefinition method)
+ {
+ if (method.HasBody)
+ {
+ var ilProcessor = method.Body.GetILProcessor();
+
+ var instructions = method.Body.Instructions;
+ for (int i = 0; i < instructions.Count; i++)
+ {
+ Instruction instruction = instructions[i];
+
+ if (instruction.OpCode == OpCodes.Call && instruction.Operand is MethodReference)
+ {
+ var methodDescription = (MethodReference)instruction.Operand;
+
+ if (methodDescription.Name.StartsWith("Calli") && methodDescription.DeclaringType.Name == "LocalInterop")
+ {
+ var callSite = new CallSite(methodDescription.ReturnType) { CallingConvention = MethodCallingConvention.StdCall };
+
+ if (methodDescription.Name.StartsWith("CalliCdecl"))
+ {
+ callSite.CallingConvention = MethodCallingConvention.C;
+ }
+ else if(methodDescription.Name.StartsWith("CalliThisCall"))
+ {
+ callSite.CallingConvention = MethodCallingConvention.ThisCall;
+ }
+ else if(methodDescription.Name.StartsWith("CalliStdCall"))
+ {
+ callSite.CallingConvention = MethodCallingConvention.StdCall;
+ }
+ else if(methodDescription.Name.StartsWith("CalliFastCall"))
+ {
+ callSite.CallingConvention = MethodCallingConvention.FastCall;
+ }
+
+ // Last parameter is the function ptr, so we don't add it as a parameter for calli
+ // as it is already an implicit parameter for calli
+ for (int j = 0; j < methodDescription.Parameters.Count - 1; j++)
+ {
+ var parameterDefinition = methodDescription.Parameters[j];
+ callSite.Parameters.Add(parameterDefinition);
+ }
+
+ // Create calli Instruction
+ var callIInstruction = ilProcessor.Create(OpCodes.Calli, callSite);
+
+ // Replace instruction
+ ilProcessor.Replace(instruction, callIInstruction);
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Patches the type.
+ ///
+ /// The type.
+ static void PatchType(TypeDefinition type, List classToRemoveList)
+ {
+ // Patch methods
+ foreach (var method in type.Methods)
+ PatchMethod(method);
+
+ if (type.Name == "LocalInterop")
+ classToRemoveList.Add(type);
+
+ // Patch nested types
+ foreach (var typeDefinition in type.NestedTypes)
+ PatchType(typeDefinition, classToRemoveList);
+ }
+ }
+}
diff --git a/src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs b/src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs
index 8e1f6c257d..b85991fb77 100644
--- a/src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs
+++ b/src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs
@@ -40,8 +40,8 @@ namespace Avalonia.Build.Tasks
var res = XamlCompilerTaskExecutor.Compile(BuildEngine, input,
File.ReadAllLines(ReferencesFilePath).Where(l => !string.IsNullOrWhiteSpace(l)).ToArray(),
ProjectDirectory, OutputPath, VerifyIl, outputImportance,
- (SignAssembly && !DelaySign) ? AssemblyOriginatorKeyFile : null
- );
+ (SignAssembly && !DelaySign) ? AssemblyOriginatorKeyFile : null,
+ EnableComInteropPatching, SkipXamlCompilation);
if (!res.Success)
return false;
if (!res.WrittenFile)
@@ -76,6 +76,9 @@ namespace Avalonia.Build.Tasks
public bool VerifyIl { get; set; }
+ public bool EnableComInteropPatching { get; set; }
+ public bool SkipXamlCompilation { get; set; }
+
public string AssemblyOriginatorKeyFile { get; set; }
public bool SignAssembly { get; set; }
public bool DelaySign { get; set; }
diff --git a/src/Avalonia.Build.Tasks/Program.cs b/src/Avalonia.Build.Tasks/Program.cs
index 1909c4c6ec..b18c19cd63 100644
--- a/src/Avalonia.Build.Tasks/Program.cs
+++ b/src/Avalonia.Build.Tasks/Program.cs
@@ -29,7 +29,8 @@ namespace Avalonia.Build.Tasks
OutputPath = args[2],
BuildEngine = new ConsoleBuildEngine(),
ProjectDirectory = Directory.GetCurrentDirectory(),
- VerifyIl = true
+ VerifyIl = true,
+ EnableComInteropPatching = true
}.Execute() ?
0 :
2;
diff --git a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
index 6b01af2ede..0b9b50e771 100644
--- a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
+++ b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
@@ -40,17 +40,48 @@ namespace Avalonia.Build.Tasks
WrittenFile = writtenFile;
}
}
+
+ public static CompileResult Compile(IBuildEngine engine, string input, string[] references,
+ string projectDirectory,
+ string output, bool verifyIl, MessageImportance logImportance, string strongNameKey, bool patchCom,
+ bool skipXamlCompilation)
+ {
+ var typeSystem = new CecilTypeSystem(references.Concat(new[] { input }), input);
+
+ var asm = typeSystem.TargetAssemblyDefinition;
+
+ if (!skipXamlCompilation)
+ {
+ var compileRes = CompileCore(engine, typeSystem, projectDirectory, verifyIl, logImportance);
+ if (compileRes == null && !patchCom)
+ return new CompileResult(true);
+ if (compileRes == false)
+ return new CompileResult(false);
+ }
+
+ if (patchCom)
+ ComInteropHelper.PatchAssembly(asm, typeSystem);
+
+ var writerParameters = new WriterParameters { WriteSymbols = asm.MainModule.HasSymbols };
+ if (!string.IsNullOrWhiteSpace(strongNameKey))
+ writerParameters.StrongNameKeyBlob = File.ReadAllBytes(strongNameKey);
+
+ asm.Write(output, writerParameters);
+
+ return new CompileResult(true, true);
+
+ }
- public static CompileResult Compile(IBuildEngine engine, string input, string[] references, string projectDirectory,
- string output, bool verifyIl, MessageImportance logImportance, string strongNameKey)
+ static bool? CompileCore(IBuildEngine engine, CecilTypeSystem typeSystem,
+ string projectDirectory, bool verifyIl,
+ MessageImportance logImportance)
{
- var typeSystem = new CecilTypeSystem(references.Concat(new[] {input}), input);
var asm = typeSystem.TargetAssemblyDefinition;
var emres = new EmbeddedResources(asm);
var avares = new AvaloniaResources(asm, projectDirectory);
if (avares.Resources.Count(CheckXamlName) == 0 && emres.Resources.Count(CheckXamlName) == 0)
// Nothing to do
- return new CompileResult(true);
+ return null;
var clrPropertiesDef = new TypeDefinition("CompiledAvaloniaXaml", "XamlIlHelpers",
TypeAttributes.Class, asm.MainModule.TypeSystem.Object);
@@ -364,25 +395,17 @@ namespace Avalonia.Build.Tasks
if (emres.Resources.Count(CheckXamlName) != 0)
if (!CompileGroup(emres))
- return new CompileResult(false);
+ return false;
if (avares.Resources.Count(CheckXamlName) != 0)
{
if (!CompileGroup(avares))
- return new CompileResult(false);
+ return false;
avares.Save();
}
loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldnull));
loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
-
-
- var writerParameters = new WriterParameters { WriteSymbols = asm.MainModule.HasSymbols };
- if (!string.IsNullOrWhiteSpace(strongNameKey))
- writerParameters.StrongNameKeyBlob = File.ReadAllBytes(strongNameKey);
-
- asm.Write(output, writerParameters);
-
- return new CompileResult(true, true);
+ return true;
}
}
diff --git a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs
index 03dcf85b87..804bb09510 100644
--- a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs
+++ b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
@@ -9,6 +10,7 @@ using System.Threading;
using System.Threading.Tasks;
using Avalonia.Remote.Protocol;
using Avalonia.Remote.Protocol.Viewport;
+using InputProtocol = Avalonia.Remote.Protocol.Input;
namespace Avalonia.DesignerSupport.Remote.HtmlTransport
{
@@ -115,14 +117,11 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport
while (true)
{
var msg = await socket.ReceiveMessage().ConfigureAwait(false);
- if(msg == null)
- return;
- if (msg.IsText)
+ if(msg != null && msg.IsText)
{
- var s = Encoding.UTF8.GetString(msg.Data);
- var parts = s.Split(':');
- if (parts[0] == "frame-received")
- _onMessage?.Invoke(this, new FrameReceivedMessage { SequenceId = long.Parse(parts[1]) });
+ var message = ParseMessage(msg.AsString());
+ if (message != null)
+ _onMessage?.Invoke(this, message);
}
}
}
@@ -181,7 +180,6 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport
_pendingSocket?.Dispose();
_simpleServer.Dispose();
}
-
public Task Send(object data)
{
@@ -264,5 +262,75 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport
_onException?.Invoke(this, ex);
}
#endregion
+
+ private static object ParseMessage(string message)
+ {
+ var parts = message.Split(':');
+ var key = parts[0];
+ if (key.Equals("frame-received", StringComparison.OrdinalIgnoreCase))
+ {
+ return new FrameReceivedMessage { SequenceId = long.Parse(parts[1]) };
+ }
+ else if (key.Equals("pointer-released", StringComparison.OrdinalIgnoreCase))
+ {
+ return new InputProtocol.PointerReleasedEventMessage
+ {
+ Modifiers = ParseInputModifiers(parts[1]),
+ X = ParseDouble(parts[2]),
+ Y = ParseDouble(parts[3]),
+ Button = ParseMouseButton(parts[4]),
+ };
+ }
+ else if (key.Equals("pointer-pressed", StringComparison.OrdinalIgnoreCase))
+ {
+ return new InputProtocol.PointerPressedEventMessage
+ {
+ Modifiers = ParseInputModifiers(parts[1]),
+ X = ParseDouble(parts[2]),
+ Y = ParseDouble(parts[3]),
+ Button = ParseMouseButton(parts[4]),
+ };
+ }
+ else if (key.Equals("pointer-moved", StringComparison.OrdinalIgnoreCase))
+ {
+ return new InputProtocol.PointerMovedEventMessage
+ {
+ Modifiers = ParseInputModifiers(parts[1]),
+ X = ParseDouble(parts[2]),
+ Y = ParseDouble(parts[3]),
+ };
+ }
+ else if (key.Equals("scroll", StringComparison.OrdinalIgnoreCase))
+ {
+ return new InputProtocol.ScrollEventMessage
+ {
+ Modifiers = ParseInputModifiers(parts[1]),
+ X = ParseDouble(parts[2]),
+ Y = ParseDouble(parts[3]),
+ DeltaX = ParseDouble(parts[4]),
+ DeltaY = ParseDouble(parts[5]),
+ };
+ }
+
+ return null;
+ }
+
+ private static InputProtocol.InputModifiers[] ParseInputModifiers(string modifiersText) =>
+ string.IsNullOrWhiteSpace(modifiersText)
+ ? null
+ : modifiersText
+ .Split(',')
+ .Select(x => (InputProtocol.InputModifiers)Enum.Parse(
+ typeof(InputProtocol.InputModifiers), x, true))
+ .ToArray();
+
+ private static InputProtocol.MouseButton ParseMouseButton(string buttonText) =>
+ string.IsNullOrWhiteSpace(buttonText)
+ ? InputProtocol.MouseButton.None
+ : (InputProtocol.MouseButton)Enum.Parse(
+ typeof(InputProtocol.MouseButton), buttonText, true);
+
+ private static double ParseDouble(string text) =>
+ double.Parse(text, NumberStyles.Float, CultureInfo.InvariantCulture);
}
}
diff --git a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/FramePresenter.tsx b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/FramePresenter.tsx
index 0059cfe683..96d2f45fdc 100644
--- a/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/FramePresenter.tsx
+++ b/src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/FramePresenter.tsx
@@ -1,5 +1,9 @@
-import {PreviewerFrame, PreviewerServerConnection} from "src/PreviewerServerConnection";
import * as React from "react";
+import {PreviewerFrame, PreviewerServerConnection} from "src/PreviewerServerConnection";
+import {PointerPressedEventMessage} from "src/Models/Input/PointerPressedEventMessage";
+import {PointerReleasedEventMessage} from "src/Models/Input/PointerReleasedEventMessage";
+import {PointerMovedEventMessage} from "src/Models/Input/PointerMovedEventMessage";
+import {ScrollEventMessage} from "src/Models/Input/ScrollEventMessage";
interface PreviewerPresenterProps {
conn: PreviewerServerConnection;
@@ -15,6 +19,11 @@ export class PreviewerPresenter extends React.Component
this.componentDidUpdate({
conn: null!
}, this.state);
+
+ this.handleMouseDown = this.handleMouseDown.bind(this);
+ this.handleMouseUp = this.handleMouseUp.bind(this);
+ this.handleMouseMove = this.handleMouseMove.bind(this);
+ this.handleWheel = this.handleWheel.bind(this);
}
componentDidMount(): void {
@@ -51,7 +60,35 @@ export class PreviewerPresenter extends React.Component
}
}
+ handleMouseDown(e: React.MouseEvent) {
+ e.preventDefault();
+ const pointerPressedEventMessage = new PointerPressedEventMessage(e);
+ this.props.conn.sendMouseEvent(pointerPressedEventMessage);
+ }
+
+ handleMouseUp(e: React.MouseEvent) {
+ e.preventDefault();
+ const pointerReleasedEventMessage = new PointerReleasedEventMessage(e);
+ this.props.conn.sendMouseEvent(pointerReleasedEventMessage);
+ }
+
+ handleMouseMove(e: React.MouseEvent) {
+ e.preventDefault();
+ const pointerMovedEventMessage = new PointerMovedEventMessage(e);
+ this.props.conn.sendMouseEvent(pointerMovedEventMessage);
+ }
+
+ handleWheel(e: React.WheelEvent) {
+ e.preventDefault();
+ const scrollEventMessage = new ScrollEventMessage(e);
+ this.props.conn.sendMouseEvent(scrollEventMessage);
+ }
+
render() {
- return