committed by
GitHub
103 changed files with 6790 additions and 4942 deletions
@ -1,5 +1,3 @@ |
|||||
<ProjectConfiguration> |
<ProjectConfiguration> |
||||
<Settings> |
<Settings /> |
||||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|
||||
</Settings> |
|
||||
</ProjectConfiguration> |
</ProjectConfiguration> |
||||
@ -0,0 +1,5 @@ |
|||||
|
<ProjectConfiguration> |
||||
|
<Settings> |
||||
|
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
||||
|
</Settings> |
||||
|
</ProjectConfiguration> |
||||
@ -1,5 +1,5 @@ |
|||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="ReactiveUI" Version="11.5.17" /> |
<PackageReference Include="ReactiveUI" Version="12.1.1" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
</Project> |
</Project> |
||||
|
|||||
@ -0,0 +1 @@ |
|||||
|
avalonia-native.h |
||||
@ -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(); |
|
||||
@ -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)); |
||||
|
}); |
||||
|
} |
||||
@ -0,0 +1,130 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
using Mono.Cecil; |
||||
|
using Mono.Cecil.Cil; |
||||
|
using XamlX.TypeSystem; |
||||
|
using MethodAttributes = Mono.Cecil.MethodAttributes; |
||||
|
|
||||
|
namespace Avalonia.Build.Tasks |
||||
|
{ |
||||
|
static class ComInteropHelper |
||||
|
{ |
||||
|
public static void PatchAssembly(AssemblyDefinition asm, CecilTypeSystem typeSystem) |
||||
|
{ |
||||
|
var classToRemoveList = new List<TypeDefinition>(); |
||||
|
var initializers = new List<MethodDefinition>(); |
||||
|
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 == "<Module>"); |
||||
|
|
||||
|
// 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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Patches the type.
|
||||
|
/// </summary>
|
||||
|
/// <param name="type">The type.</param>
|
||||
|
static void PatchType(TypeDefinition type, List<TypeDefinition> 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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {InputModifiers} from "./InputModifiers"; |
||||
|
import {getModifiers} from "./MouseEventHelpers"; |
||||
|
|
||||
|
export abstract class InputEventMessageBase { |
||||
|
public readonly modifiers : Array<InputModifiers>; |
||||
|
|
||||
|
protected constructor(e: React.MouseEvent) { |
||||
|
this.modifiers = getModifiers(e); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
export enum InputModifiers { |
||||
|
Alt, |
||||
|
Control, |
||||
|
Shift, |
||||
|
Windows, |
||||
|
LeftMouseButton, |
||||
|
RightMouseButton, |
||||
|
MiddleMouseButton, |
||||
|
} |
||||
@ -0,0 +1,6 @@ |
|||||
|
export enum MouseButton { |
||||
|
None, |
||||
|
Left, |
||||
|
Right, |
||||
|
Middle, |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {InputModifiers} from "./InputModifiers"; |
||||
|
import {MouseButton} from "./MouseButton"; |
||||
|
|
||||
|
export function getModifiers(e: React.MouseEvent): Array<InputModifiers> { |
||||
|
|
||||
|
let modifiers : Array<InputModifiers> = []; |
||||
|
|
||||
|
if (e.altKey) |
||||
|
modifiers.push(InputModifiers.Alt); |
||||
|
if (e.ctrlKey) |
||||
|
modifiers.push(InputModifiers.Control); |
||||
|
if (e.shiftKey) |
||||
|
modifiers.push(InputModifiers.Shift); |
||||
|
if (e.metaKey) |
||||
|
modifiers.push(InputModifiers.Windows); |
||||
|
if (e.buttons != 0) { |
||||
|
if ((e.buttons & 1) != 0) |
||||
|
modifiers.push(InputModifiers.LeftMouseButton); |
||||
|
if ((e.buttons & 2) != 0) |
||||
|
modifiers.push(InputModifiers.RightMouseButton); |
||||
|
if ((e.buttons & 4) != 0) |
||||
|
modifiers.push(InputModifiers.MiddleMouseButton); |
||||
|
} |
||||
|
|
||||
|
return modifiers; |
||||
|
} |
||||
|
|
||||
|
export function getMouseButton(e: React.MouseEvent) : MouseButton { |
||||
|
if (e.button == 0) { |
||||
|
return MouseButton.Left; |
||||
|
} else if (e.button == 1) { |
||||
|
return MouseButton.Middle; |
||||
|
} else if (e.button == 2) { |
||||
|
return MouseButton.Right; |
||||
|
} else { |
||||
|
return MouseButton.None; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {InputEventMessageBase} from "./InputEventMessageBase"; |
||||
|
|
||||
|
export abstract class PointerEventMessageBase extends InputEventMessageBase { |
||||
|
public readonly x: number; |
||||
|
public readonly y: number; |
||||
|
|
||||
|
protected constructor(e: React.MouseEvent) { |
||||
|
super(e); |
||||
|
this.x = e.clientX; |
||||
|
this.y = e.clientY; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {PointerEventMessageBase} from "./PointerEventMessageBase"; |
||||
|
|
||||
|
export class PointerMovedEventMessage extends PointerEventMessageBase { |
||||
|
constructor(e: React.MouseEvent) { |
||||
|
super(e); |
||||
|
} |
||||
|
|
||||
|
public toString = () : string => { |
||||
|
return `pointer-moved:${this.modifiers}:${this.x}:${this.y}`; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {PointerEventMessageBase} from "./PointerEventMessageBase"; |
||||
|
import {MouseButton} from "./MouseButton"; |
||||
|
import {getMouseButton} from "./MouseEventHelpers"; |
||||
|
|
||||
|
export class PointerPressedEventMessage extends PointerEventMessageBase { |
||||
|
public readonly button: MouseButton |
||||
|
|
||||
|
constructor(e: React.MouseEvent) { |
||||
|
super(e); |
||||
|
this.button = getMouseButton(e); |
||||
|
} |
||||
|
|
||||
|
public toString = () : string => { |
||||
|
return `pointer-pressed:${this.modifiers}:${this.x}:${this.y}:${this.button}`; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {PointerEventMessageBase} from "./PointerEventMessageBase"; |
||||
|
import {MouseButton} from "./MouseButton"; |
||||
|
import {getMouseButton} from "./MouseEventHelpers"; |
||||
|
|
||||
|
export class PointerReleasedEventMessage extends PointerEventMessageBase { |
||||
|
public readonly button: MouseButton |
||||
|
|
||||
|
constructor(e: React.MouseEvent) { |
||||
|
super(e); |
||||
|
this.button = getMouseButton(e); |
||||
|
} |
||||
|
|
||||
|
public toString = () : string => { |
||||
|
return `pointer-released:${this.modifiers}:${this.x}:${this.y}:${this.button}`; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {PointerEventMessageBase} from "./PointerEventMessageBase"; |
||||
|
|
||||
|
export class ScrollEventMessage extends PointerEventMessageBase { |
||||
|
public readonly deltaX: number; |
||||
|
public readonly deltaY: number; |
||||
|
|
||||
|
constructor(e: React.WheelEvent) { |
||||
|
super(e); |
||||
|
this.deltaX = -e.deltaX; |
||||
|
this.deltaY = -e.deltaY; |
||||
|
} |
||||
|
|
||||
|
public toString = () : string => { |
||||
|
return `scroll:${this.modifiers}:${this.x}:${this.y}:${this.deltaX}:${this.deltaY}`; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,4 @@ |
|||||
|
Compat issues with assembly Avalonia.Input: |
||||
|
InterfacesShouldHaveSameMembers : Interface member 'public System.Boolean Avalonia.Input.IInputElement.IsKeyboardFocusWithin' is present in the implementation but not in the contract. |
||||
|
InterfacesShouldHaveSameMembers : Interface member 'public System.Boolean Avalonia.Input.IInputElement.IsKeyboardFocusWithin.get()' is present in the implementation but not in the contract. |
||||
|
Total Issues: 2 |
||||
@ -0,0 +1,16 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup> |
||||
|
<_AvaloniaPatchComInterop>true</_AvaloniaPatchComInterop> |
||||
|
</PropertyGroup> |
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Avalonia.Build.Tasks\Avalonia.Build.Tasks.csproj"> |
||||
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly> |
||||
|
<ExcludeAssets>all</ExcludeAssets> |
||||
|
</ProjectReference> |
||||
|
</ItemGroup> |
||||
|
<Import Project="..\..\build\BuildTargets.targets" /> |
||||
|
</Project> |
||||
@ -0,0 +1,9 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Avalonia.MicroCom |
||||
|
{ |
||||
|
public interface IMicroComExceptionCallback |
||||
|
{ |
||||
|
void RaiseException(Exception e); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
namespace Avalonia.MicroCom |
||||
|
{ |
||||
|
public interface IMicroComShadowContainer |
||||
|
{ |
||||
|
MicroComShadow Shadow { get; set; } |
||||
|
void OnReferencedFromNative(); |
||||
|
void OnUnreferencedFromNative(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Avalonia.MicroCom |
||||
|
{ |
||||
|
public interface IUnknown : IDisposable |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Avalonia.MicroCom |
||||
|
{ |
||||
|
unsafe class LocalInterop |
||||
|
{ |
||||
|
public static unsafe void CalliStdCallvoid(void* thisObject, void* methodPtr) |
||||
|
{ |
||||
|
throw null; |
||||
|
} |
||||
|
|
||||
|
public static unsafe int CalliStdCallint(void* thisObject, Guid* guid, IntPtr* ppv, void* methodPtr) |
||||
|
{ |
||||
|
throw null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,110 @@ |
|||||
|
using System; |
||||
|
using System.Runtime.ConstrainedExecution; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Threading; |
||||
|
|
||||
|
namespace Avalonia.MicroCom |
||||
|
{ |
||||
|
public unsafe class MicroComProxyBase : CriticalFinalizerObject, IUnknown |
||||
|
{ |
||||
|
private IntPtr _nativePointer; |
||||
|
private bool _ownsHandle; |
||||
|
private SynchronizationContext _synchronizationContext; |
||||
|
|
||||
|
public IntPtr NativePointer |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if (_nativePointer == IntPtr.Zero) |
||||
|
throw new ObjectDisposedException(this.GetType().FullName); |
||||
|
return _nativePointer; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void*** PPV => (void***)NativePointer; |
||||
|
|
||||
|
public MicroComProxyBase(IntPtr nativePointer, bool ownsHandle) |
||||
|
{ |
||||
|
_nativePointer = nativePointer; |
||||
|
_ownsHandle = ownsHandle; |
||||
|
_synchronizationContext = SynchronizationContext.Current; |
||||
|
if(!_ownsHandle) |
||||
|
GC.SuppressFinalize(this); |
||||
|
} |
||||
|
|
||||
|
protected virtual int VTableSize => 3; |
||||
|
|
||||
|
public void AddRef() |
||||
|
{ |
||||
|
LocalInterop.CalliStdCallvoid(PPV, (*PPV)[1]); |
||||
|
} |
||||
|
|
||||
|
public void Release() |
||||
|
{ |
||||
|
LocalInterop.CalliStdCallvoid(PPV, (*PPV)[2]); |
||||
|
} |
||||
|
|
||||
|
public int QueryInterface(Guid guid, out IntPtr ppv) |
||||
|
{ |
||||
|
IntPtr r = default; |
||||
|
var rv = LocalInterop.CalliStdCallint(PPV, &guid, &r, (*PPV)[0]); |
||||
|
ppv = r; |
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
public T QueryInterface<T>() where T : IUnknown |
||||
|
{ |
||||
|
var guid = MicroComRuntime.GetGuidFor(typeof(T)); |
||||
|
var rv = QueryInterface(guid, out var ppv); |
||||
|
if (rv != 0) |
||||
|
return (T)MicroComRuntime.CreateProxyFor(typeof(T), ppv, true); |
||||
|
throw new COMException("QueryInterface failed", rv); |
||||
|
} |
||||
|
|
||||
|
public bool IsDisposed => _nativePointer == IntPtr.Zero; |
||||
|
|
||||
|
protected virtual void Dispose(bool disposing) |
||||
|
{ |
||||
|
if(_nativePointer == null) |
||||
|
return; |
||||
|
if (_ownsHandle) |
||||
|
{ |
||||
|
Release(); |
||||
|
_ownsHandle = false; |
||||
|
} |
||||
|
_nativePointer = IntPtr.Zero; |
||||
|
GC.SuppressFinalize(this); |
||||
|
} |
||||
|
|
||||
|
public void Dispose() => Dispose(true); |
||||
|
|
||||
|
public bool OwnsHandle => _ownsHandle; |
||||
|
|
||||
|
public void EnsureOwned() |
||||
|
{ |
||||
|
if (!_ownsHandle) |
||||
|
{ |
||||
|
GC.ReRegisterForFinalize(true); |
||||
|
AddRef(); |
||||
|
_ownsHandle = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static readonly SendOrPostCallback _disposeDelegate = DisposeOnContext; |
||||
|
|
||||
|
private static void DisposeOnContext(object state) |
||||
|
{ |
||||
|
(state as MicroComProxyBase)?.Dispose(false); |
||||
|
} |
||||
|
|
||||
|
~MicroComProxyBase() |
||||
|
{ |
||||
|
if(!_ownsHandle) |
||||
|
return; |
||||
|
if (_synchronizationContext == null) |
||||
|
Dispose(); |
||||
|
else |
||||
|
_synchronizationContext.Post(_disposeDelegate, this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,98 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Concurrent; |
||||
|
using System.Runtime.InteropServices; |
||||
|
|
||||
|
namespace Avalonia.MicroCom |
||||
|
{ |
||||
|
public static unsafe class MicroComRuntime |
||||
|
{ |
||||
|
private static ConcurrentDictionary<Type, IntPtr> _vtables = new ConcurrentDictionary<Type, IntPtr>(); |
||||
|
|
||||
|
private static ConcurrentDictionary<Type, Func<IntPtr, bool, object>> _factories = |
||||
|
new ConcurrentDictionary<Type, Func<IntPtr, bool, object>>(); |
||||
|
private static ConcurrentDictionary<Type, Guid> _guids = new ConcurrentDictionary<Type, Guid>(); |
||||
|
private static ConcurrentDictionary<Guid, Type> _guidsToTypes = new ConcurrentDictionary<Guid, Type>(); |
||||
|
|
||||
|
static MicroComRuntime() |
||||
|
{ |
||||
|
Register(typeof(IUnknown), new Guid("00000000-0000-0000-C000-000000000046"), |
||||
|
(ppv, owns) => new MicroComProxyBase(ppv, owns)); |
||||
|
RegisterVTable(typeof(IUnknown), MicroComVtblBase.Vtable); |
||||
|
} |
||||
|
|
||||
|
public static void RegisterVTable(Type t, IntPtr vtable) |
||||
|
{ |
||||
|
_vtables[t] = vtable; |
||||
|
} |
||||
|
|
||||
|
public static void Register(Type t, Guid guid, Func<IntPtr, bool, object> proxyFactory) |
||||
|
{ |
||||
|
_factories[t] = proxyFactory; |
||||
|
_guids[t] = guid; |
||||
|
_guidsToTypes[guid] = t; |
||||
|
} |
||||
|
|
||||
|
public static Guid GetGuidFor(Type type) => _guids[type]; |
||||
|
|
||||
|
public static T CreateProxyFor<T>(void* pObject, bool ownsHandle) => (T)CreateProxyFor(typeof(T), new IntPtr(pObject), ownsHandle); |
||||
|
public static T CreateProxyFor<T>(IntPtr pObject, bool ownsHandle) => (T)CreateProxyFor(typeof(T), pObject, ownsHandle); |
||||
|
|
||||
|
public static object CreateProxyFor(Type type, IntPtr pObject, bool ownsHandle) => _factories[type](pObject, ownsHandle); |
||||
|
|
||||
|
public static void* GetNativePointer<T>(T obj, bool owned = false) where T : IUnknown |
||||
|
{ |
||||
|
if (obj == null) |
||||
|
return null; |
||||
|
if (obj is MicroComProxyBase proxy) |
||||
|
return (void*)proxy.NativePointer; |
||||
|
if (obj is IMicroComShadowContainer container) |
||||
|
{ |
||||
|
container.Shadow ??= new MicroComShadow(container); |
||||
|
void* ptr = null; |
||||
|
var res = container.Shadow.GetOrCreateNativePointer(typeof(T), &ptr); |
||||
|
if (res != 0) |
||||
|
throw new COMException( |
||||
|
"Unable to create native callable wrapper for type " + typeof(T) + " for instance of type " + |
||||
|
obj.GetType(), |
||||
|
res); |
||||
|
if (owned) |
||||
|
container.Shadow.AddRef((Ccw*)ptr); |
||||
|
return ptr; |
||||
|
} |
||||
|
throw new ArgumentException("Unable to get a native pointer for " + obj); |
||||
|
} |
||||
|
|
||||
|
public static object GetObjectFromCcw(IntPtr ccw) |
||||
|
{ |
||||
|
var ptr = (Ccw*)ccw; |
||||
|
var shadow = (MicroComShadow)GCHandle.FromIntPtr(ptr->GcShadowHandle).Target; |
||||
|
return shadow.Target; |
||||
|
} |
||||
|
|
||||
|
public static bool TryGetTypeForGuid(Guid guid, out Type t) => _guidsToTypes.TryGetValue(guid, out t); |
||||
|
|
||||
|
public static bool GetVtableFor(Type type, out IntPtr ptr) => _vtables.TryGetValue(type, out ptr); |
||||
|
|
||||
|
public static void UnhandledException(object target, Exception e) |
||||
|
{ |
||||
|
if (target is IMicroComExceptionCallback cb) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
cb.RaiseException(e); |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
// We've tried
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public static T CloneReference<T>(T iface) where T : IUnknown |
||||
|
{ |
||||
|
var ownedPointer = GetNativePointer(iface, true); |
||||
|
return CreateProxyFor<T>(ownedPointer, true); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,171 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Threading; |
||||
|
|
||||
|
namespace Avalonia.MicroCom |
||||
|
{ |
||||
|
public unsafe class MicroComShadow : IDisposable |
||||
|
{ |
||||
|
private readonly object _lock = new object(); |
||||
|
private readonly Dictionary<Type, IntPtr> _shadows = new Dictionary<Type, IntPtr>(); |
||||
|
private readonly Dictionary<IntPtr, Type> _backShadows = new Dictionary<IntPtr, Type>(); |
||||
|
private GCHandle? _handle; |
||||
|
private volatile int _refCount; |
||||
|
internal IMicroComShadowContainer Target { get; } |
||||
|
internal MicroComShadow(IMicroComShadowContainer target) |
||||
|
{ |
||||
|
Target = target; |
||||
|
Target.Shadow = this; |
||||
|
} |
||||
|
|
||||
|
internal int QueryInterface(Ccw* ccw, Guid* guid, void** ppv) |
||||
|
{ |
||||
|
if (MicroComRuntime.TryGetTypeForGuid(*guid, out var type)) |
||||
|
return QueryInterface(type, ppv); |
||||
|
else |
||||
|
return unchecked((int)0x80004002u); |
||||
|
} |
||||
|
|
||||
|
internal int QueryInterface(Type type, void** ppv) |
||||
|
{ |
||||
|
if (!type.IsInstanceOfType(Target)) |
||||
|
return unchecked((int)0x80004002u); |
||||
|
|
||||
|
var rv = GetOrCreateNativePointer(type, ppv); |
||||
|
if (rv == 0) |
||||
|
AddRef((Ccw*)*ppv); |
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
internal int GetOrCreateNativePointer(Type type, void** ppv) |
||||
|
{ |
||||
|
if (!MicroComRuntime.GetVtableFor(type, out var vtable)) |
||||
|
return unchecked((int)0x80004002u); |
||||
|
lock (_lock) |
||||
|
{ |
||||
|
|
||||
|
if (_shadows.TryGetValue(type, out var shadow)) |
||||
|
{ |
||||
|
var targetCcw = (Ccw*)shadow; |
||||
|
AddRef(targetCcw); |
||||
|
*ppv = targetCcw; |
||||
|
return 0; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var intPtr = Marshal.AllocHGlobal(Marshal.SizeOf<Ccw>()); |
||||
|
var targetCcw = (Ccw*)intPtr; |
||||
|
*targetCcw = default; |
||||
|
targetCcw->RefCount = 0; |
||||
|
targetCcw->VTable = vtable; |
||||
|
if (_handle == null) |
||||
|
_handle = GCHandle.Alloc(this); |
||||
|
targetCcw->GcShadowHandle = GCHandle.ToIntPtr(_handle.Value); |
||||
|
_shadows[type] = intPtr; |
||||
|
_backShadows[intPtr] = type; |
||||
|
*ppv = targetCcw; |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
internal int AddRef(Ccw* ccw) |
||||
|
{ |
||||
|
if (Interlocked.Increment(ref _refCount) == 1) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
Target.OnReferencedFromNative(); |
||||
|
} |
||||
|
catch (Exception e) |
||||
|
{ |
||||
|
MicroComRuntime.UnhandledException(Target, e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return Interlocked.Increment(ref ccw->RefCount); |
||||
|
} |
||||
|
|
||||
|
internal int Release(Ccw* ccw) |
||||
|
{ |
||||
|
Interlocked.Decrement(ref _refCount); |
||||
|
var cnt = Interlocked.Decrement(ref ccw->RefCount); |
||||
|
if (cnt == 0) |
||||
|
return FreeCcw(ccw); |
||||
|
|
||||
|
return cnt; |
||||
|
} |
||||
|
|
||||
|
int FreeCcw(Ccw* ccw) |
||||
|
{ |
||||
|
lock (_lock) |
||||
|
{ |
||||
|
// Shadow got resurrected by a call to QueryInterface from another thread
|
||||
|
if (ccw->RefCount != 0) |
||||
|
return ccw->RefCount; |
||||
|
|
||||
|
var intPtr = new IntPtr(ccw); |
||||
|
var type = _backShadows[intPtr]; |
||||
|
_backShadows.Remove(intPtr); |
||||
|
_shadows.Remove(type); |
||||
|
Marshal.FreeHGlobal(intPtr); |
||||
|
if (_shadows.Count == 0) |
||||
|
{ |
||||
|
_handle?.Free(); |
||||
|
_handle = null; |
||||
|
try |
||||
|
{ |
||||
|
Target.OnUnreferencedFromNative(); |
||||
|
} |
||||
|
catch(Exception e) |
||||
|
{ |
||||
|
MicroComRuntime.UnhandledException(Target, e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
Needs to be called to support the following scenario: |
||||
|
1) Object created |
||||
|
2) Object passed to native code, shadow is created, CCW is created |
||||
|
3) Native side has never called AddRef |
||||
|
|
||||
|
In that case the GC handle to the shadow object is still alive |
||||
|
*/ |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
lock (_lock) |
||||
|
{ |
||||
|
List<IntPtr> toRemove = null; |
||||
|
foreach (var kv in _backShadows) |
||||
|
{ |
||||
|
var ccw = (Ccw*)kv.Key; |
||||
|
if (ccw->RefCount == 0) |
||||
|
{ |
||||
|
toRemove ??= new List<IntPtr>(); |
||||
|
toRemove.Add(kv.Key); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if(toRemove != null) |
||||
|
foreach (var intPtr in toRemove) |
||||
|
FreeCcw((Ccw*)intPtr); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[StructLayout(LayoutKind.Sequential)] |
||||
|
struct Ccw |
||||
|
{ |
||||
|
public IntPtr VTable; |
||||
|
public IntPtr GcShadowHandle; |
||||
|
public volatile int RefCount; |
||||
|
public MicroComShadow GetShadow() => (MicroComShadow)GCHandle.FromIntPtr(GcShadowHandle).Target; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Runtime.InteropServices; |
||||
|
|
||||
|
namespace Avalonia.MicroCom |
||||
|
{ |
||||
|
public unsafe class MicroComVtblBase |
||||
|
{ |
||||
|
private List<IntPtr> _methods = new List<IntPtr>(); |
||||
|
[UnmanagedFunctionPointerAttribute(CallingConvention.ThisCall)] |
||||
|
private delegate int AddRefDelegate(Ccw* ccw); |
||||
|
|
||||
|
[UnmanagedFunctionPointerAttribute(CallingConvention.ThisCall)] |
||||
|
private delegate int QueryInterfaceDelegate(Ccw* ccw, Guid* guid, void** ppv); |
||||
|
|
||||
|
public static IntPtr Vtable { get; } = new MicroComVtblBase().CreateVTable(); |
||||
|
public MicroComVtblBase() |
||||
|
{ |
||||
|
AddMethod((QueryInterfaceDelegate)QueryInterface); |
||||
|
AddMethod((AddRefDelegate)AddRef); |
||||
|
AddMethod((AddRefDelegate)Release); |
||||
|
} |
||||
|
|
||||
|
protected void AddMethod(Delegate d) |
||||
|
{ |
||||
|
GCHandle.Alloc(d); |
||||
|
_methods.Add(Marshal.GetFunctionPointerForDelegate(d)); |
||||
|
} |
||||
|
|
||||
|
protected unsafe IntPtr CreateVTable() |
||||
|
{ |
||||
|
var ptr = (IntPtr*)Marshal.AllocHGlobal((IntPtr.Size + 1) * _methods.Count); |
||||
|
for (var c = 0; c < _methods.Count; c++) |
||||
|
ptr[c] = _methods[c]; |
||||
|
return new IntPtr(ptr); |
||||
|
} |
||||
|
|
||||
|
static int QueryInterface(Ccw* ccw, Guid* guid, void** ppv) => ccw->GetShadow().QueryInterface(ccw, guid, ppv); |
||||
|
static int AddRef(Ccw* ccw) => ccw->GetShadow().AddRef(ccw); |
||||
|
static int Release(Ccw* ccw) => ccw->GetShadow().Release(ccw); |
||||
|
} |
||||
|
} |
||||
@ -1 +1,2 @@ |
|||||
Generated/*.cs |
Generated/*.cs |
||||
|
*.Generated.cs |
||||
|
|||||
@ -1,628 +0,0 @@ |
|||||
// <auto-generated/>
|
|
||||
|
|
||||
namespace Avalonia.Native.Interop |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnDragDropEffects</unmanaged>
|
|
||||
/// <unmanaged-short>AvnDragDropEffects</unmanaged-short>
|
|
||||
public enum AvnDragDropEffects : System.Int32 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>None</unmanaged>
|
|
||||
/// <unmanaged-short>None</unmanaged-short>
|
|
||||
None = unchecked ((System.Int32)(0)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Copy</unmanaged>
|
|
||||
/// <unmanaged-short>Copy</unmanaged-short>
|
|
||||
Copy = unchecked ((System.Int32)(1)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Move</unmanaged>
|
|
||||
/// <unmanaged-short>Move</unmanaged-short>
|
|
||||
Move = unchecked ((System.Int32)(2)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Link</unmanaged>
|
|
||||
/// <unmanaged-short>Link</unmanaged-short>
|
|
||||
Link = unchecked ((System.Int32)(4))} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnDragEventType</unmanaged>
|
|
||||
/// <unmanaged-short>AvnDragEventType</unmanaged-short>
|
|
||||
public enum AvnDragEventType : System.Int32 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Enter</unmanaged>
|
|
||||
/// <unmanaged-short>Enter</unmanaged-short>
|
|
||||
Enter = unchecked ((System.Int32)(0)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Over</unmanaged>
|
|
||||
/// <unmanaged-short>Over</unmanaged-short>
|
|
||||
Over = unchecked ((System.Int32)(1)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Leave</unmanaged>
|
|
||||
/// <unmanaged-short>Leave</unmanaged-short>
|
|
||||
Leave = unchecked ((System.Int32)(2)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Drop</unmanaged>
|
|
||||
/// <unmanaged-short>Drop</unmanaged-short>
|
|
||||
Drop = unchecked ((System.Int32)(3))} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnExtendClientAreaChromeHints</unmanaged>
|
|
||||
/// <unmanaged-short>AvnExtendClientAreaChromeHints</unmanaged-short>
|
|
||||
public enum AvnExtendClientAreaChromeHints : System.Int32 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnNoChrome</unmanaged>
|
|
||||
/// <unmanaged-short>AvnNoChrome</unmanaged-short>
|
|
||||
AvnNoChrome = unchecked ((System.Int32)(0)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnSystemChrome</unmanaged>
|
|
||||
/// <unmanaged-short>AvnSystemChrome</unmanaged-short>
|
|
||||
AvnSystemChrome = unchecked ((System.Int32)(1)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnPreferSystemChrome</unmanaged>
|
|
||||
/// <unmanaged-short>AvnPreferSystemChrome</unmanaged-short>
|
|
||||
AvnPreferSystemChrome = unchecked ((System.Int32)(2)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnOSXThickTitleBar</unmanaged>
|
|
||||
/// <unmanaged-short>AvnOSXThickTitleBar</unmanaged-short>
|
|
||||
AvnOSXThickTitleBar = unchecked ((System.Int32)(8)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnDefaultChrome</unmanaged>
|
|
||||
/// <unmanaged-short>AvnDefaultChrome</unmanaged-short>
|
|
||||
AvnDefaultChrome = unchecked ((System.Int32)(1))} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnInputModifiers</unmanaged>
|
|
||||
/// <unmanaged-short>AvnInputModifiers</unmanaged-short>
|
|
||||
public enum AvnInputModifiers : System.Int32 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnInputModifiersNone</unmanaged>
|
|
||||
/// <unmanaged-short>AvnInputModifiersNone</unmanaged-short>
|
|
||||
AvnInputModifiersNone = unchecked ((System.Int32)(0)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Alt</unmanaged>
|
|
||||
/// <unmanaged-short>Alt</unmanaged-short>
|
|
||||
Alt = unchecked ((System.Int32)(1)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Control</unmanaged>
|
|
||||
/// <unmanaged-short>Control</unmanaged-short>
|
|
||||
Control = unchecked ((System.Int32)(2)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Shift</unmanaged>
|
|
||||
/// <unmanaged-short>Shift</unmanaged-short>
|
|
||||
Shift = unchecked ((System.Int32)(4)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Windows</unmanaged>
|
|
||||
/// <unmanaged-short>Windows</unmanaged-short>
|
|
||||
Windows = unchecked ((System.Int32)(8)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>LeftMouseButton</unmanaged>
|
|
||||
/// <unmanaged-short>LeftMouseButton</unmanaged-short>
|
|
||||
LeftMouseButton = unchecked ((System.Int32)(16)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>RightMouseButton</unmanaged>
|
|
||||
/// <unmanaged-short>RightMouseButton</unmanaged-short>
|
|
||||
RightMouseButton = unchecked ((System.Int32)(32)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>MiddleMouseButton</unmanaged>
|
|
||||
/// <unmanaged-short>MiddleMouseButton</unmanaged-short>
|
|
||||
MiddleMouseButton = unchecked ((System.Int32)(64)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>XButton1MouseButton</unmanaged>
|
|
||||
/// <unmanaged-short>XButton1MouseButton</unmanaged-short>
|
|
||||
XButton1MouseButton = unchecked ((System.Int32)(128)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>XButton2MouseButton</unmanaged>
|
|
||||
/// <unmanaged-short>XButton2MouseButton</unmanaged-short>
|
|
||||
XButton2MouseButton = unchecked ((System.Int32)(256))} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnMenuItemToggleType</unmanaged>
|
|
||||
/// <unmanaged-short>AvnMenuItemToggleType</unmanaged-short>
|
|
||||
public enum AvnMenuItemToggleType : System.Int32 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>None</unmanaged>
|
|
||||
/// <unmanaged-short>None</unmanaged-short>
|
|
||||
None = unchecked ((System.Int32)(0)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CheckMark</unmanaged>
|
|
||||
/// <unmanaged-short>CheckMark</unmanaged-short>
|
|
||||
CheckMark = unchecked ((System.Int32)(1)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Radio</unmanaged>
|
|
||||
/// <unmanaged-short>Radio</unmanaged-short>
|
|
||||
Radio = unchecked ((System.Int32)(2))} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnPixelFormat</unmanaged>
|
|
||||
/// <unmanaged-short>AvnPixelFormat</unmanaged-short>
|
|
||||
public enum AvnPixelFormat : System.Int32 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>kAvnRgb565</unmanaged>
|
|
||||
/// <unmanaged-short>kAvnRgb565</unmanaged-short>
|
|
||||
KAvnRgb565 = unchecked ((System.Int32)(0)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>kAvnRgba8888</unmanaged>
|
|
||||
/// <unmanaged-short>kAvnRgba8888</unmanaged-short>
|
|
||||
KAvnRgba8888 = unchecked ((System.Int32)(1)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>kAvnBgra8888</unmanaged>
|
|
||||
/// <unmanaged-short>kAvnBgra8888</unmanaged-short>
|
|
||||
KAvnBgra8888 = unchecked ((System.Int32)(2))} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnRawKeyEventType</unmanaged>
|
|
||||
/// <unmanaged-short>AvnRawKeyEventType</unmanaged-short>
|
|
||||
public enum AvnRawKeyEventType : System.Int32 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>KeyDown</unmanaged>
|
|
||||
/// <unmanaged-short>KeyDown</unmanaged-short>
|
|
||||
KeyDown = unchecked ((System.Int32)(0)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>KeyUp</unmanaged>
|
|
||||
/// <unmanaged-short>KeyUp</unmanaged-short>
|
|
||||
KeyUp = unchecked ((System.Int32)(1))} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnRawMouseEventType</unmanaged>
|
|
||||
/// <unmanaged-short>AvnRawMouseEventType</unmanaged-short>
|
|
||||
public enum AvnRawMouseEventType : System.Int32 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>LeaveWindow</unmanaged>
|
|
||||
/// <unmanaged-short>LeaveWindow</unmanaged-short>
|
|
||||
LeaveWindow = unchecked ((System.Int32)(0)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>LeftButtonDown</unmanaged>
|
|
||||
/// <unmanaged-short>LeftButtonDown</unmanaged-short>
|
|
||||
LeftButtonDown = unchecked ((System.Int32)(1)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>LeftButtonUp</unmanaged>
|
|
||||
/// <unmanaged-short>LeftButtonUp</unmanaged-short>
|
|
||||
LeftButtonUp = unchecked ((System.Int32)(2)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>RightButtonDown</unmanaged>
|
|
||||
/// <unmanaged-short>RightButtonDown</unmanaged-short>
|
|
||||
RightButtonDown = unchecked ((System.Int32)(3)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>RightButtonUp</unmanaged>
|
|
||||
/// <unmanaged-short>RightButtonUp</unmanaged-short>
|
|
||||
RightButtonUp = unchecked ((System.Int32)(4)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>MiddleButtonDown</unmanaged>
|
|
||||
/// <unmanaged-short>MiddleButtonDown</unmanaged-short>
|
|
||||
MiddleButtonDown = unchecked ((System.Int32)(5)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>MiddleButtonUp</unmanaged>
|
|
||||
/// <unmanaged-short>MiddleButtonUp</unmanaged-short>
|
|
||||
MiddleButtonUp = unchecked ((System.Int32)(6)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>XButton1Down</unmanaged>
|
|
||||
/// <unmanaged-short>XButton1Down</unmanaged-short>
|
|
||||
XButton1Down = unchecked ((System.Int32)(7)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>XButton1Up</unmanaged>
|
|
||||
/// <unmanaged-short>XButton1Up</unmanaged-short>
|
|
||||
XButton1Up = unchecked ((System.Int32)(8)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>XButton2Down</unmanaged>
|
|
||||
/// <unmanaged-short>XButton2Down</unmanaged-short>
|
|
||||
XButton2Down = unchecked ((System.Int32)(9)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>XButton2Up</unmanaged>
|
|
||||
/// <unmanaged-short>XButton2Up</unmanaged-short>
|
|
||||
XButton2Up = unchecked ((System.Int32)(10)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Move</unmanaged>
|
|
||||
/// <unmanaged-short>Move</unmanaged-short>
|
|
||||
Move = unchecked ((System.Int32)(11)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Wheel</unmanaged>
|
|
||||
/// <unmanaged-short>Wheel</unmanaged-short>
|
|
||||
Wheel = unchecked ((System.Int32)(12)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>NonClientLeftButtonDown</unmanaged>
|
|
||||
/// <unmanaged-short>NonClientLeftButtonDown</unmanaged-short>
|
|
||||
NonClientLeftButtonDown = unchecked ((System.Int32)(13)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>TouchBegin</unmanaged>
|
|
||||
/// <unmanaged-short>TouchBegin</unmanaged-short>
|
|
||||
TouchBegin = unchecked ((System.Int32)(14)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>TouchUpdate</unmanaged>
|
|
||||
/// <unmanaged-short>TouchUpdate</unmanaged-short>
|
|
||||
TouchUpdate = unchecked ((System.Int32)(15)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>TouchEnd</unmanaged>
|
|
||||
/// <unmanaged-short>TouchEnd</unmanaged-short>
|
|
||||
TouchEnd = unchecked ((System.Int32)(16)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>TouchCancel</unmanaged>
|
|
||||
/// <unmanaged-short>TouchCancel</unmanaged-short>
|
|
||||
TouchCancel = unchecked ((System.Int32)(17))} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnStandardCursorType</unmanaged>
|
|
||||
/// <unmanaged-short>AvnStandardCursorType</unmanaged-short>
|
|
||||
public enum AvnStandardCursorType : System.Int32 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorArrow</unmanaged>
|
|
||||
/// <unmanaged-short>CursorArrow</unmanaged-short>
|
|
||||
CursorArrow = unchecked ((System.Int32)(0)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorIbeam</unmanaged>
|
|
||||
/// <unmanaged-short>CursorIbeam</unmanaged-short>
|
|
||||
CursorIbeam = unchecked ((System.Int32)(1)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorWait</unmanaged>
|
|
||||
/// <unmanaged-short>CursorWait</unmanaged-short>
|
|
||||
CursorWait = unchecked ((System.Int32)(2)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorCross</unmanaged>
|
|
||||
/// <unmanaged-short>CursorCross</unmanaged-short>
|
|
||||
CursorCross = unchecked ((System.Int32)(3)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorUpArrow</unmanaged>
|
|
||||
/// <unmanaged-short>CursorUpArrow</unmanaged-short>
|
|
||||
CursorUpArrow = unchecked ((System.Int32)(4)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorSizeWestEast</unmanaged>
|
|
||||
/// <unmanaged-short>CursorSizeWestEast</unmanaged-short>
|
|
||||
CursorSizeWestEast = unchecked ((System.Int32)(5)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorSizeNorthSouth</unmanaged>
|
|
||||
/// <unmanaged-short>CursorSizeNorthSouth</unmanaged-short>
|
|
||||
CursorSizeNorthSouth = unchecked ((System.Int32)(6)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorSizeAll</unmanaged>
|
|
||||
/// <unmanaged-short>CursorSizeAll</unmanaged-short>
|
|
||||
CursorSizeAll = unchecked ((System.Int32)(7)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorNo</unmanaged>
|
|
||||
/// <unmanaged-short>CursorNo</unmanaged-short>
|
|
||||
CursorNo = unchecked ((System.Int32)(8)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorHand</unmanaged>
|
|
||||
/// <unmanaged-short>CursorHand</unmanaged-short>
|
|
||||
CursorHand = unchecked ((System.Int32)(9)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorAppStarting</unmanaged>
|
|
||||
/// <unmanaged-short>CursorAppStarting</unmanaged-short>
|
|
||||
CursorAppStarting = unchecked ((System.Int32)(10)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorHelp</unmanaged>
|
|
||||
/// <unmanaged-short>CursorHelp</unmanaged-short>
|
|
||||
CursorHelp = unchecked ((System.Int32)(11)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorTopSide</unmanaged>
|
|
||||
/// <unmanaged-short>CursorTopSide</unmanaged-short>
|
|
||||
CursorTopSide = unchecked ((System.Int32)(12)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorBottomSize</unmanaged>
|
|
||||
/// <unmanaged-short>CursorBottomSize</unmanaged-short>
|
|
||||
CursorBottomSize = unchecked ((System.Int32)(13)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorLeftSide</unmanaged>
|
|
||||
/// <unmanaged-short>CursorLeftSide</unmanaged-short>
|
|
||||
CursorLeftSide = unchecked ((System.Int32)(14)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorRightSide</unmanaged>
|
|
||||
/// <unmanaged-short>CursorRightSide</unmanaged-short>
|
|
||||
CursorRightSide = unchecked ((System.Int32)(15)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorTopLeftCorner</unmanaged>
|
|
||||
/// <unmanaged-short>CursorTopLeftCorner</unmanaged-short>
|
|
||||
CursorTopLeftCorner = unchecked ((System.Int32)(16)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorTopRightCorner</unmanaged>
|
|
||||
/// <unmanaged-short>CursorTopRightCorner</unmanaged-short>
|
|
||||
CursorTopRightCorner = unchecked ((System.Int32)(17)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorBottomLeftCorner</unmanaged>
|
|
||||
/// <unmanaged-short>CursorBottomLeftCorner</unmanaged-short>
|
|
||||
CursorBottomLeftCorner = unchecked ((System.Int32)(18)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorBottomRightCorner</unmanaged>
|
|
||||
/// <unmanaged-short>CursorBottomRightCorner</unmanaged-short>
|
|
||||
CursorBottomRightCorner = unchecked ((System.Int32)(19)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorDragMove</unmanaged>
|
|
||||
/// <unmanaged-short>CursorDragMove</unmanaged-short>
|
|
||||
CursorDragMove = unchecked ((System.Int32)(20)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorDragCopy</unmanaged>
|
|
||||
/// <unmanaged-short>CursorDragCopy</unmanaged-short>
|
|
||||
CursorDragCopy = unchecked ((System.Int32)(21)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorDragLink</unmanaged>
|
|
||||
/// <unmanaged-short>CursorDragLink</unmanaged-short>
|
|
||||
CursorDragLink = unchecked ((System.Int32)(22)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>CursorNone</unmanaged>
|
|
||||
/// <unmanaged-short>CursorNone</unmanaged-short>
|
|
||||
CursorNone = unchecked ((System.Int32)(23))} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnWindowEdge</unmanaged>
|
|
||||
/// <unmanaged-short>AvnWindowEdge</unmanaged-short>
|
|
||||
public enum AvnWindowEdge : System.Int32 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>WindowEdgeNorthWest</unmanaged>
|
|
||||
/// <unmanaged-short>WindowEdgeNorthWest</unmanaged-short>
|
|
||||
WindowEdgeNorthWest = unchecked ((System.Int32)(0)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>WindowEdgeNorth</unmanaged>
|
|
||||
/// <unmanaged-short>WindowEdgeNorth</unmanaged-short>
|
|
||||
WindowEdgeNorth = unchecked ((System.Int32)(1)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>WindowEdgeNorthEast</unmanaged>
|
|
||||
/// <unmanaged-short>WindowEdgeNorthEast</unmanaged-short>
|
|
||||
WindowEdgeNorthEast = unchecked ((System.Int32)(2)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>WindowEdgeWest</unmanaged>
|
|
||||
/// <unmanaged-short>WindowEdgeWest</unmanaged-short>
|
|
||||
WindowEdgeWest = unchecked ((System.Int32)(3)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>WindowEdgeEast</unmanaged>
|
|
||||
/// <unmanaged-short>WindowEdgeEast</unmanaged-short>
|
|
||||
WindowEdgeEast = unchecked ((System.Int32)(4)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>WindowEdgeSouthWest</unmanaged>
|
|
||||
/// <unmanaged-short>WindowEdgeSouthWest</unmanaged-short>
|
|
||||
WindowEdgeSouthWest = unchecked ((System.Int32)(5)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>WindowEdgeSouth</unmanaged>
|
|
||||
/// <unmanaged-short>WindowEdgeSouth</unmanaged-short>
|
|
||||
WindowEdgeSouth = unchecked ((System.Int32)(6)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>WindowEdgeSouthEast</unmanaged>
|
|
||||
/// <unmanaged-short>WindowEdgeSouthEast</unmanaged-short>
|
|
||||
WindowEdgeSouthEast = unchecked ((System.Int32)(7))} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnWindowState</unmanaged>
|
|
||||
/// <unmanaged-short>AvnWindowState</unmanaged-short>
|
|
||||
public enum AvnWindowState : System.Int32 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Normal</unmanaged>
|
|
||||
/// <unmanaged-short>Normal</unmanaged-short>
|
|
||||
Normal = unchecked ((System.Int32)(0)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Minimized</unmanaged>
|
|
||||
/// <unmanaged-short>Minimized</unmanaged-short>
|
|
||||
Minimized = unchecked ((System.Int32)(1)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Maximized</unmanaged>
|
|
||||
/// <unmanaged-short>Maximized</unmanaged-short>
|
|
||||
Maximized = unchecked ((System.Int32)(2)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>FullScreen</unmanaged>
|
|
||||
/// <unmanaged-short>FullScreen</unmanaged-short>
|
|
||||
FullScreen = unchecked ((System.Int32)(3))} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>SystemDecorations</unmanaged>
|
|
||||
/// <unmanaged-short>SystemDecorations</unmanaged-short>
|
|
||||
public enum SystemDecorations : System.Int32 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>SystemDecorationsNone</unmanaged>
|
|
||||
/// <unmanaged-short>SystemDecorationsNone</unmanaged-short>
|
|
||||
SystemDecorationsNone = unchecked ((System.Int32)(0)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>SystemDecorationsBorderOnly</unmanaged>
|
|
||||
/// <unmanaged-short>SystemDecorationsBorderOnly</unmanaged-short>
|
|
||||
SystemDecorationsBorderOnly = unchecked ((System.Int32)(1)), |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>SystemDecorationsFull</unmanaged>
|
|
||||
/// <unmanaged-short>SystemDecorationsFull</unmanaged-short>
|
|
||||
SystemDecorationsFull = unchecked ((System.Int32)(2))} |
|
||||
} |
|
||||
@ -1,5 +0,0 @@ |
|||||
// <auto-generated/>
|
|
||||
|
|
||||
namespace Avalonia.Native.Interop |
|
||||
{ |
|
||||
} |
|
||||
File diff suppressed because it is too large
@ -1,202 +0,0 @@ |
|||||
// <auto-generated/>
|
|
||||
|
|
||||
namespace Avalonia.Native |
|
||||
{ |
|
||||
internal static partial class LocalInterop |
|
||||
{ |
|
||||
public static unsafe int CalliThisCallint(void *thisObject, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid(void *thisObject, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid(void *thisObject, void *param0, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid0(void *thisObject, Avalonia.Native.Interop.AvnPoint param0, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid0(void *thisObject, int param0, System.UInt32 param1, int param2, Avalonia.Native.Interop.AvnPoint param3, Avalonia.Native.Interop.AvnVector param4, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe System.Byte CalliThisCallSystemByte(void *thisObject, int param0, System.UInt32 param1, int param2, System.UInt32 param3, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe System.Byte CalliThisCallSystemByte(void *thisObject, System.UInt32 param0, void *param1, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid(void *thisObject, double param0, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe Avalonia.Native.Interop.AvnDragDropEffects CalliThisCallAvaloniaNativeInteropAvnDragDropEffects0(void *thisObject, int param0, Avalonia.Native.Interop.AvnPoint param1, int param2, int param3, void *param4, void *param5, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe System.Byte CalliThisCallSystemByte(void *thisObject, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid(void *thisObject, int param0, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint(void *thisObject, void *param0, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint0(void *thisObject, Avalonia.Native.Interop.AvnSize param0, Avalonia.Native.Interop.AvnSize param1, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint(void *thisObject, double param0, double param1, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint0(void *thisObject, Avalonia.Native.Interop.AvnRect param0, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint(void *thisObject, int param0, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint0(void *thisObject, Avalonia.Native.Interop.AvnPoint param0, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint0(void *thisObject, Avalonia.Native.Interop.AvnPoint param0, void *param1, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint(void *thisObject, void *param0, void *param1, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint(void *thisObject, System.Byte param0, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint0(void *thisObject, int param0, Avalonia.Native.Interop.AvnPoint param1, void *param2, void *param3, void *param4, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint0(void *thisObject, Avalonia.Native.Interop.AvnColor param0, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint(void *thisObject, double param0, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe System.IntPtr CalliThisCallSystemIntPtr(void *thisObject, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe System.IntPtr CalliThisCallSystemIntPtr(void *thisObject, int param0, int param1, void *param2, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid(void *thisObject, int param0, void *param1, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid(void *thisObject, void *param0, void *param1, void *param2, void *param3, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid(void *thisObject, void *param0, void *param1, System.Byte param2, void *param3, void *param4, void *param5, void *param6, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid(void *thisObject, void *param0, void *param1, void *param2, void *param3, void *param4, void *param5, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint(void *thisObject, int param0, void *param1, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint(void *thisObject, void *param0, void *param1, int param2, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe System.IntPtr CalliThisCallSystemIntPtr(void *thisObject, void *param0, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint(void *thisObject, void *param0, int param1, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe System.UInt32 CalliThisCallSystemUInt32(void *thisObject, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint(void *thisObject, System.UInt32 param0, void *param1, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid(void *thisObject, float param0, float param1, float param2, float param3, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid(void *thisObject, float param0, float param1, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe int CalliThisCallint(void *thisObject, void *param0, void *param1, void *param2, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
|
|
||||
public static unsafe void CalliThisCallvoid(void *thisObject, int param0, System.Byte param1, void *methodPtr) |
|
||||
{ |
|
||||
throw null; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,246 +0,0 @@ |
|||||
// <auto-generated/>
|
|
||||
|
|
||||
namespace Avalonia.Native.Interop |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnColor</unmanaged>
|
|
||||
/// <unmanaged-short>AvnColor</unmanaged-short>
|
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 0, CharSet = System.Runtime.InteropServices.CharSet.Unicode)] |
|
||||
public partial struct AvnColor |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Alpha</unmanaged>
|
|
||||
/// <unmanaged-short>Alpha</unmanaged-short>
|
|
||||
public System.Byte Alpha; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Red</unmanaged>
|
|
||||
/// <unmanaged-short>Red</unmanaged-short>
|
|
||||
public System.Byte Red; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Green</unmanaged>
|
|
||||
/// <unmanaged-short>Green</unmanaged-short>
|
|
||||
public System.Byte Green; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Blue</unmanaged>
|
|
||||
/// <unmanaged-short>Blue</unmanaged-short>
|
|
||||
public System.Byte Blue; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnFramebuffer</unmanaged>
|
|
||||
/// <unmanaged-short>AvnFramebuffer</unmanaged-short>
|
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 0, CharSet = System.Runtime.InteropServices.CharSet.Unicode)] |
|
||||
public partial struct AvnFramebuffer |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Data</unmanaged>
|
|
||||
/// <unmanaged-short>Data</unmanaged-short>
|
|
||||
public System.IntPtr Data; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Width</unmanaged>
|
|
||||
/// <unmanaged-short>Width</unmanaged-short>
|
|
||||
public System.Int32 Width; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Height</unmanaged>
|
|
||||
/// <unmanaged-short>Height</unmanaged-short>
|
|
||||
public System.Int32 Height; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Stride</unmanaged>
|
|
||||
/// <unmanaged-short>Stride</unmanaged-short>
|
|
||||
public System.Int32 Stride; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Dpi</unmanaged>
|
|
||||
/// <unmanaged-short>Dpi</unmanaged-short>
|
|
||||
public Avalonia.Native.Interop.AvnVector Dpi; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>PixelFormat</unmanaged>
|
|
||||
/// <unmanaged-short>PixelFormat</unmanaged-short>
|
|
||||
public Avalonia.Native.Interop.AvnPixelFormat PixelFormat; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnPixelSize</unmanaged>
|
|
||||
/// <unmanaged-short>AvnPixelSize</unmanaged-short>
|
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 0, CharSet = System.Runtime.InteropServices.CharSet.Unicode)] |
|
||||
public partial struct AvnPixelSize |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Width</unmanaged>
|
|
||||
/// <unmanaged-short>Width</unmanaged-short>
|
|
||||
public System.Int32 Width; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Height</unmanaged>
|
|
||||
/// <unmanaged-short>Height</unmanaged-short>
|
|
||||
public System.Int32 Height; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnPoint</unmanaged>
|
|
||||
/// <unmanaged-short>AvnPoint</unmanaged-short>
|
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 0, CharSet = System.Runtime.InteropServices.CharSet.Unicode)] |
|
||||
public partial struct AvnPoint |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>X</unmanaged>
|
|
||||
/// <unmanaged-short>X</unmanaged-short>
|
|
||||
public System.Double X; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Y</unmanaged>
|
|
||||
/// <unmanaged-short>Y</unmanaged-short>
|
|
||||
public System.Double Y; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnRect</unmanaged>
|
|
||||
/// <unmanaged-short>AvnRect</unmanaged-short>
|
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 0, CharSet = System.Runtime.InteropServices.CharSet.Unicode)] |
|
||||
public partial struct AvnRect |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>X</unmanaged>
|
|
||||
/// <unmanaged-short>X</unmanaged-short>
|
|
||||
public System.Double X; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Y</unmanaged>
|
|
||||
/// <unmanaged-short>Y</unmanaged-short>
|
|
||||
public System.Double Y; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Width</unmanaged>
|
|
||||
/// <unmanaged-short>Width</unmanaged-short>
|
|
||||
public System.Double Width; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Height</unmanaged>
|
|
||||
/// <unmanaged-short>Height</unmanaged-short>
|
|
||||
public System.Double Height; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnScreen</unmanaged>
|
|
||||
/// <unmanaged-short>AvnScreen</unmanaged-short>
|
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 0, CharSet = System.Runtime.InteropServices.CharSet.Unicode)] |
|
||||
public partial struct AvnScreen |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Bounds</unmanaged>
|
|
||||
/// <unmanaged-short>Bounds</unmanaged-short>
|
|
||||
public Avalonia.Native.Interop.AvnRect Bounds; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>WorkingArea</unmanaged>
|
|
||||
/// <unmanaged-short>WorkingArea</unmanaged-short>
|
|
||||
public Avalonia.Native.Interop.AvnRect WorkingArea; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>PixelDensity</unmanaged>
|
|
||||
/// <unmanaged-short>PixelDensity</unmanaged-short>
|
|
||||
public System.Single PixelDensity; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Primary</unmanaged>
|
|
||||
/// <unmanaged-short>Primary</unmanaged-short>
|
|
||||
public bool Primary |
|
||||
{ |
|
||||
get => 0 != _Primary; |
|
||||
set => _Primary = (System.Byte)(value ? 1 : 0); |
|
||||
} |
|
||||
|
|
||||
internal System.Byte _Primary; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnSize</unmanaged>
|
|
||||
/// <unmanaged-short>AvnSize</unmanaged-short>
|
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 0, CharSet = System.Runtime.InteropServices.CharSet.Unicode)] |
|
||||
public partial struct AvnSize |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Width</unmanaged>
|
|
||||
/// <unmanaged-short>Width</unmanaged-short>
|
|
||||
public System.Double Width; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Height</unmanaged>
|
|
||||
/// <unmanaged-short>Height</unmanaged-short>
|
|
||||
public System.Double Height; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>AvnVector</unmanaged>
|
|
||||
/// <unmanaged-short>AvnVector</unmanaged-short>
|
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 0, CharSet = System.Runtime.InteropServices.CharSet.Unicode)] |
|
||||
public partial struct AvnVector |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>X</unmanaged>
|
|
||||
/// <unmanaged-short>X</unmanaged-short>
|
|
||||
public System.Double X; |
|
||||
/// <summary>
|
|
||||
/// No documentation.
|
|
||||
/// </summary>
|
|
||||
/// <unmanaged>Y</unmanaged>
|
|
||||
/// <unmanaged-short>Y</unmanaged-short>
|
|
||||
public System.Double Y; |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,522 @@ |
|||||
|
@clr-namespace Avalonia.Native.Interop |
||||
|
@clr-access internal |
||||
|
@cpp-preamble @@ |
||||
|
#include "com.h" |
||||
|
#include "key.h" |
||||
|
#include "stddef.h" |
||||
|
@@ |
||||
|
|
||||
|
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 |
||||
|
{ |
||||
|
byte Alpha; |
||||
|
byte Red; |
||||
|
byte Green; |
||||
|
byte 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 |
||||
|
} |
||||
|
|
||||
|
[class-enum] |
||||
|
enum AvnDragDropEffects |
||||
|
{ |
||||
|
None = 0, |
||||
|
Copy = 1, |
||||
|
Move = 2, |
||||
|
Link = 4, |
||||
|
} |
||||
|
|
||||
|
[class-enum] |
||||
|
enum 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, |
||||
|
} |
||||
|
|
||||
|
[uuid(809c652e-7396-11d2-9771-00a0c9b4d50c)] |
||||
|
interface IAvaloniaNativeFactory : IUnknown |
||||
|
{ |
||||
|
HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator); |
||||
|
IAvnMacOptions* GetMacOptions(); |
||||
|
HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnWindow** ppv); |
||||
|
HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnPopup** ppv); |
||||
|
HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv); |
||||
|
HRESULT CreateSystemDialogs(IAvnSystemDialogs** ppv); |
||||
|
HRESULT CreateScreens(IAvnScreens** ppv); |
||||
|
HRESULT CreateClipboard(IAvnClipboard** ppv); |
||||
|
HRESULT CreateDndClipboard(IAvnClipboard** ppv); |
||||
|
HRESULT CreateCursorFactory(IAvnCursorFactory** ppv); |
||||
|
HRESULT ObtainGlDisplay(IAvnGlDisplay** ppv); |
||||
|
HRESULT SetAppMenu(IAvnMenu* menu); |
||||
|
HRESULT CreateMenu(IAvnMenuEvents* cb, IAvnMenu** ppv); |
||||
|
HRESULT CreateMenuItem(IAvnMenuItem** ppv); |
||||
|
HRESULT CreateMenuItemSeperator(IAvnMenuItem** ppv); |
||||
|
} |
||||
|
|
||||
|
[uuid(233e094f-9b9f-44a3-9a6e-6948bbdd9fb1)] |
||||
|
interface IAvnString : IUnknown |
||||
|
{ |
||||
|
HRESULT Pointer(void**retOut); |
||||
|
HRESULT Length(int*ret); |
||||
|
} |
||||
|
|
||||
|
[uuid(e5aca675-02b7-4129-aa79-d6e417210bda)] |
||||
|
interface IAvnWindowBase : IUnknown |
||||
|
{ |
||||
|
HRESULT Show(); |
||||
|
HRESULT Hide(); |
||||
|
HRESULT Close(); |
||||
|
HRESULT Activate(); |
||||
|
HRESULT GetClientSize(AvnSize*ret); |
||||
|
HRESULT GetScaling(double*ret); |
||||
|
HRESULT SetMinMaxSize(AvnSize minSize, AvnSize maxSize); |
||||
|
HRESULT Resize(double width, double height); |
||||
|
HRESULT Invalidate(AvnRect rect); |
||||
|
HRESULT BeginMoveDrag(); |
||||
|
HRESULT BeginResizeDrag(AvnWindowEdge edge); |
||||
|
HRESULT GetPosition(AvnPoint*ret); |
||||
|
HRESULT SetPosition(AvnPoint point); |
||||
|
HRESULT PointToClient(AvnPoint point, AvnPoint*ret); |
||||
|
HRESULT PointToScreen(AvnPoint point, AvnPoint*ret); |
||||
|
HRESULT ThreadSafeSetSwRenderedFrame(AvnFramebuffer* fb, IUnknown* dispose); |
||||
|
HRESULT SetTopMost(bool value); |
||||
|
HRESULT SetCursor(IAvnCursor* cursor); |
||||
|
HRESULT CreateGlRenderTarget(IAvnGlSurfaceRenderTarget** ret); |
||||
|
HRESULT SetMainMenu(IAvnMenu* menu); |
||||
|
HRESULT ObtainNSWindowHandle([intptr]void** retOut); |
||||
|
HRESULT ObtainNSWindowHandleRetained([intptr]void** retOut); |
||||
|
HRESULT ObtainNSViewHandle([intptr]void** retOut); |
||||
|
HRESULT ObtainNSViewHandleRetained([intptr]void** retOut); |
||||
|
HRESULT CreateNativeControlHost(IAvnNativeControlHost** retOut); |
||||
|
HRESULT BeginDragAndDropOperation(AvnDragDropEffects effects, AvnPoint point, |
||||
|
IAvnClipboard* clipboard, IAvnDndResultCallback* cb, [intptr]void* sourceHandle); |
||||
|
HRESULT SetBlurEnabled(bool enable); |
||||
|
} |
||||
|
|
||||
|
[uuid(83e588f3-6981-4e48-9ea0-e1e569f79a91), cpp-virtual-inherits] |
||||
|
interface IAvnPopup : IAvnWindowBase |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
[uuid(cab661de-49d6-4ead-b59c-eac9b2b6c28d), cpp-virtual-inherits] |
||||
|
interface IAvnWindow : IAvnWindowBase |
||||
|
{ |
||||
|
HRESULT SetEnabled(bool enable); |
||||
|
HRESULT SetParent(IAvnWindow* parent); |
||||
|
HRESULT SetCanResize(bool value); |
||||
|
HRESULT SetDecorations(SystemDecorations value); |
||||
|
HRESULT SetTitle(char* utf8Title); |
||||
|
HRESULT SetTitleBarColor(AvnColor color); |
||||
|
HRESULT SetWindowState(AvnWindowState state); |
||||
|
HRESULT GetWindowState(AvnWindowState*ret); |
||||
|
HRESULT TakeFocusFromChildren(); |
||||
|
HRESULT SetExtendClientArea(bool enable); |
||||
|
HRESULT SetExtendClientAreaHints(AvnExtendClientAreaChromeHints hints); |
||||
|
HRESULT GetExtendTitleBarHeight(double*ret); |
||||
|
HRESULT SetExtendTitleBarHeight(double value); |
||||
|
} |
||||
|
|
||||
|
[uuid(939b6599-40a8-4710-a4c8-5d72d8f174fb)] |
||||
|
interface IAvnWindowBaseEvents : IUnknown |
||||
|
{ |
||||
|
HRESULT Paint(); |
||||
|
void Closed(); |
||||
|
void Activated(); |
||||
|
void Deactivated(); |
||||
|
void Resized([const] AvnSize& size); |
||||
|
void PositionChanged(AvnPoint position); |
||||
|
void RawMouseEvent(AvnRawMouseEventType type, |
||||
|
uint timeStamp, |
||||
|
AvnInputModifiers modifiers, |
||||
|
AvnPoint point, |
||||
|
AvnVector delta); |
||||
|
bool RawKeyEvent(AvnRawKeyEventType type, uint timeStamp, AvnInputModifiers modifiers, uint key); |
||||
|
bool RawTextInputEvent(uint timeStamp, [const] char* text); |
||||
|
void ScalingChanged(double scaling); |
||||
|
void RunRenderPriorityJobs(); |
||||
|
void LostFocus(); |
||||
|
AvnDragDropEffects DragEvent(AvnDragEventType type, AvnPoint position, |
||||
|
AvnInputModifiers modifiers, AvnDragDropEffects effects, |
||||
|
IAvnClipboard* clipboard, [intptr]void* dataObjectHandle); |
||||
|
} |
||||
|
|
||||
|
[uuid(1ae178ee-1fcc-447f-b6dd-b7bb727f934c)] |
||||
|
interface IAvnWindowEvents : IAvnWindowBaseEvents |
||||
|
{ |
||||
|
/** |
||||
|
* Closing Event |
||||
|
* Called when the user presses the OS window close button. |
||||
|
* return true to allow the close, return false to prevent close. |
||||
|
*/ |
||||
|
bool Closing(); |
||||
|
|
||||
|
void WindowStateChanged(AvnWindowState state); |
||||
|
|
||||
|
void GotInputWhenDisabled(); |
||||
|
} |
||||
|
|
||||
|
[uuid(e34ae0f8-18b4-48a3-b09d-2e6b19a3cf5e)] |
||||
|
interface IAvnMacOptions : IUnknown |
||||
|
{ |
||||
|
HRESULT SetShowInDock(int show); |
||||
|
HRESULT SetApplicationTitle(char* utf8string); |
||||
|
} |
||||
|
|
||||
|
[uuid(04c1b049-1f43-418a-9159-cae627ec1367)] |
||||
|
interface IAvnActionCallback : IUnknown |
||||
|
{ |
||||
|
void Run(); |
||||
|
} |
||||
|
|
||||
|
[uuid(6df4d2db-0b80-4f59-ad88-0baa5e21eb14)] |
||||
|
interface IAvnSignaledCallback : IUnknown |
||||
|
{ |
||||
|
void Signaled(int priority, bool priorityContainsMeaningfulValue); |
||||
|
} |
||||
|
|
||||
|
[uuid(97330f88-c22b-4a8e-a130-201520091b01)] |
||||
|
interface IAvnLoopCancellation : IUnknown |
||||
|
{ |
||||
|
void Cancel(); |
||||
|
} |
||||
|
|
||||
|
[uuid(fbc06f3d-7860-42df-83fd-53c4b02dd9c3)] |
||||
|
interface IAvnPlatformThreadingInterface : IUnknown |
||||
|
{ |
||||
|
bool GetCurrentThreadIsLoopThread(); |
||||
|
void SetSignaledCallback(IAvnSignaledCallback* cb); |
||||
|
IAvnLoopCancellation* CreateLoopCancellation(); |
||||
|
HRESULT RunLoop(IAvnLoopCancellation* cancel); |
||||
|
// Can't pass int* to sharpgentools for some reason |
||||
|
void Signal(int priority); |
||||
|
IUnknown* StartTimer(int priority, int ms, IAvnActionCallback* callback); |
||||
|
} |
||||
|
|
||||
|
[uuid(6c621a6e-e4c1-4ae3-9749-83eeeffa09b6)] |
||||
|
interface IAvnSystemDialogEvents : IUnknown |
||||
|
{ |
||||
|
void OnCompleted(int numResults, void* ptrFirstResult); |
||||
|
} |
||||
|
|
||||
|
[uuid(4d7a47db-a944-4061-abe7-62cb6aa0ffd5)] |
||||
|
interface IAvnSystemDialogs : IUnknown |
||||
|
{ |
||||
|
void SelectFolderDialog(IAvnWindow* parentWindowHandle, |
||||
|
IAvnSystemDialogEvents* events, |
||||
|
[const] char* title, |
||||
|
[const] char* initialPath); |
||||
|
|
||||
|
void OpenFileDialog(IAvnWindow* parentWindowHandle, |
||||
|
IAvnSystemDialogEvents* events, |
||||
|
bool allowMultiple, |
||||
|
[const] char* title, |
||||
|
[const] char* initialDirectory, |
||||
|
[const] char* initialFile, |
||||
|
[const] char* filters); |
||||
|
|
||||
|
void SaveFileDialog(IAvnWindow* parentWindowHandle, |
||||
|
IAvnSystemDialogEvents* events, |
||||
|
[const] char* title, |
||||
|
[const] char* initialDirectory, |
||||
|
[const] char* initialFile, |
||||
|
[const] char* filters); |
||||
|
} |
||||
|
|
||||
|
[uuid(9a52bc7a-d8c7-4230-8d34-704a0b70a933)] |
||||
|
interface IAvnScreens : IUnknown |
||||
|
{ |
||||
|
HRESULT GetScreenCount(int* ret); |
||||
|
HRESULT GetScreen(int index, AvnScreen* ret); |
||||
|
} |
||||
|
|
||||
|
[uuid(792b1bd4-76cc-46ea-bfd0-9d642154b1b3)] |
||||
|
interface IAvnClipboard : IUnknown |
||||
|
{ |
||||
|
HRESULT GetText(char* type, IAvnString**ppv); |
||||
|
HRESULT SetText(char* type, char* utf8Text); |
||||
|
HRESULT ObtainFormats(IAvnStringArray**ppv); |
||||
|
HRESULT GetStrings(char* type, IAvnStringArray**ppv); |
||||
|
HRESULT SetBytes(char* type, void* utf8Text, int len); |
||||
|
HRESULT GetBytes(char* type, IAvnString**ppv); |
||||
|
|
||||
|
HRESULT Clear(); |
||||
|
} |
||||
|
|
||||
|
[uuid(3f998545-f027-4d4d-bd2a-1a80926d984e)] |
||||
|
interface IAvnCursor : IUnknown |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
[uuid(51ecfb12-c427-4757-a2c9-1596bfce53ef)] |
||||
|
interface IAvnCursorFactory : IUnknown |
||||
|
{ |
||||
|
HRESULT GetCursor(AvnStandardCursorType cursorType, IAvnCursor** retOut); |
||||
|
} |
||||
|
|
||||
|
[uuid(60452465-8616-40af-bc00-042e69828ce7)] |
||||
|
interface IAvnGlDisplay : IUnknown |
||||
|
{ |
||||
|
HRESULT CreateContext(IAvnGlContext* share, IAvnGlContext**ppv); |
||||
|
void LegacyClearCurrentContext(); |
||||
|
HRESULT WrapContext([intptr]void* native, IAvnGlContext**ppv); |
||||
|
[intptr]void* GetProcAddress(char* proc); |
||||
|
} |
||||
|
|
||||
|
[uuid(78c5711e-2a98-40d2-bac4-0cc9a49dc4f3)] |
||||
|
interface IAvnGlContext : IUnknown |
||||
|
{ |
||||
|
HRESULT MakeCurrent(IUnknown** ppv); |
||||
|
HRESULT LegacyMakeCurrent(); |
||||
|
int GetSampleCount(); |
||||
|
int GetStencilSize(); |
||||
|
[intptr]void* GetNativeHandle(); |
||||
|
} |
||||
|
|
||||
|
[uuid(931062d2-5bc8-4062-8588-83dd8deb99c2)] |
||||
|
interface IAvnGlSurfaceRenderTarget : IUnknown |
||||
|
{ |
||||
|
HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret); |
||||
|
} |
||||
|
|
||||
|
[uuid(e625b406-f04c-484e-946a-4abd2c6015ad)] |
||||
|
interface IAvnGlSurfaceRenderingSession : IUnknown |
||||
|
{ |
||||
|
HRESULT GetPixelSize(AvnPixelSize* ret); |
||||
|
HRESULT GetScaling(double* ret); |
||||
|
} |
||||
|
|
||||
|
[uuid(a7724dc1-cf6b-4fa8-9d23-228bf2593edc)] |
||||
|
interface IAvnMenu : IUnknown |
||||
|
{ |
||||
|
HRESULT InsertItem(int index, IAvnMenuItem* item); |
||||
|
HRESULT RemoveItem(IAvnMenuItem* item); |
||||
|
HRESULT SetTitle(char* utf8String); |
||||
|
HRESULT Clear(); |
||||
|
} |
||||
|
|
||||
|
[uuid(59e0586d-bd1c-4b85-9882-80d448b0fed9)] |
||||
|
interface IAvnPredicateCallback : IUnknown |
||||
|
{ |
||||
|
bool Evaluate(); |
||||
|
} |
||||
|
|
||||
|
[uuid(f890219a-1720-4cd5-9a26-cd95fccbf53c)] |
||||
|
interface IAvnMenuItem : IUnknown |
||||
|
{ |
||||
|
HRESULT SetSubMenu(IAvnMenu* menu); |
||||
|
HRESULT SetTitle(char* utf8String); |
||||
|
HRESULT SetGesture(char* utf8String, AvnInputModifiers modifiers); |
||||
|
HRESULT SetAction(IAvnPredicateCallback* predicate, IAvnActionCallback* callback); |
||||
|
HRESULT SetIsChecked(bool isChecked); |
||||
|
HRESULT SetToggleType(AvnMenuItemToggleType toggleType); |
||||
|
HRESULT SetIcon(void* data, size_t length); |
||||
|
} |
||||
|
|
||||
|
[uuid(0af7df53-7632-42f4-a650-0992c361b477)] |
||||
|
interface IAvnMenuEvents : IUnknown |
||||
|
{ |
||||
|
/** |
||||
|
* NeedsUpdate |
||||
|
*/ |
||||
|
void NeedsUpdate(); |
||||
|
} |
||||
|
|
||||
|
[uuid(5142bb41-66ab-49e7-bb37-cd079c000f27)] |
||||
|
interface IAvnStringArray : IUnknown |
||||
|
{ |
||||
|
uint GetCount(); |
||||
|
HRESULT Get(uint index, IAvnString**ppv); |
||||
|
} |
||||
|
|
||||
|
[uuid(a13d2382-3b3a-4d1c-9b27-8f34653d3f01)] |
||||
|
interface IAvnDndResultCallback : IUnknown |
||||
|
{ |
||||
|
void OnDragAndDropComplete(AvnDragDropEffects effecct); |
||||
|
} |
||||
|
|
||||
|
[uuid(f07c608e-52e9-422d-836e-c70f6e9b80f5)] |
||||
|
interface IAvnGCHandleDeallocatorCallback : IUnknown |
||||
|
{ |
||||
|
void FreeGCHandle([intptr]void* handle); |
||||
|
} |
||||
|
|
||||
|
[uuid(91c7f677-f26b-4ff3-93cc-cf15aa966ffa)] |
||||
|
interface IAvnNativeControlHost : IUnknown |
||||
|
{ |
||||
|
HRESULT CreateDefaultChild([intptr]void* parent, [intptr]void** retOut); |
||||
|
IAvnNativeControlHostTopLevelAttachment* CreateAttachment(); |
||||
|
void DestroyDefaultChild([intptr]void* child); |
||||
|
} |
||||
|
|
||||
|
[uuid(14a9e164-1aae-4271-bb78-7b5230999b52)] |
||||
|
interface IAvnNativeControlHostTopLevelAttachment : IUnknown |
||||
|
{ |
||||
|
[intptr]void* GetParentHandle(); |
||||
|
HRESULT InitializeWithChildHandle([intptr]void* child); |
||||
|
HRESULT AttachTo(IAvnNativeControlHost* host); |
||||
|
void ShowInBounds(float x, float y, float width, float height); |
||||
|
void HideWithSize(float width, float height); |
||||
|
void ReleaseChild(); |
||||
|
} |
||||
@ -0,0 +1,241 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
|
||||
|
namespace MicroComGenerator.Ast |
||||
|
{ |
||||
|
public class AstAttributeNode |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
public string Value { get; set; } |
||||
|
|
||||
|
public AstAttributeNode(string name, string value) |
||||
|
{ |
||||
|
Name = name; |
||||
|
Value = value; |
||||
|
} |
||||
|
|
||||
|
public override string ToString() => $"{Name} = {Value}"; |
||||
|
public AstAttributeNode Clone() => new AstAttributeNode(Name, Value); |
||||
|
} |
||||
|
|
||||
|
public class AstAttributes : List<AstAttributeNode> |
||||
|
{ |
||||
|
public bool HasAttribute(string a) => this.Any(x => x.Name == a); |
||||
|
|
||||
|
public AstAttributes Clone() |
||||
|
{ |
||||
|
var rv= new AstAttributes(); |
||||
|
rv.AddRange(this.Select(x => x.Clone())); |
||||
|
return rv; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public interface IAstNodeWithAttributes |
||||
|
{ |
||||
|
public AstAttributes Attributes { get; set; } |
||||
|
} |
||||
|
|
||||
|
public class AstEnumNode : List<AstEnumMemberNode>, IAstNodeWithAttributes |
||||
|
{ |
||||
|
public AstAttributes Attributes { get; set; } = new AstAttributes(); |
||||
|
public string Name { get; set; } |
||||
|
public override string ToString() => "Enum " + Name; |
||||
|
|
||||
|
public AstEnumNode Clone() |
||||
|
{ |
||||
|
var rv = new AstEnumNode { Name = Name, Attributes = Attributes.Clone() }; |
||||
|
rv.AddRange(this.Select(x => x.Clone())); |
||||
|
return rv; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class AstEnumMemberNode |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
public string Value { get; set; } |
||||
|
|
||||
|
public AstEnumMemberNode(string name, string value) |
||||
|
{ |
||||
|
Name = name; |
||||
|
Value = value; |
||||
|
} |
||||
|
|
||||
|
public override string ToString() => $"Enum member {Name} = {Value}"; |
||||
|
public AstEnumMemberNode Clone() => new AstEnumMemberNode(Name, Value); |
||||
|
} |
||||
|
|
||||
|
public class AstStructNode : List<AstStructMemberNode>, IAstNodeWithAttributes |
||||
|
{ |
||||
|
public AstAttributes Attributes { get; set; } = new AstAttributes(); |
||||
|
public string Name { get; set; } |
||||
|
public override string ToString() => "Struct " + Name; |
||||
|
|
||||
|
public AstStructNode Clone() |
||||
|
{ |
||||
|
var rv = new AstStructNode { Name = Name, Attributes = Attributes.Clone() }; |
||||
|
rv.AddRange(this.Select(x => x.Clone())); |
||||
|
return rv; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class AstTypeNode |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
public int PointerLevel { get; set; } |
||||
|
public bool IsLink { get; set; } |
||||
|
|
||||
|
public string Format() => Name + new string('*', PointerLevel) |
||||
|
+ (IsLink ? "&" : ""); |
||||
|
public override string ToString() => Format(); |
||||
|
public AstTypeNode Clone() => new AstTypeNode() { |
||||
|
Name = Name, |
||||
|
PointerLevel = PointerLevel, |
||||
|
IsLink = IsLink |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public class AstStructMemberNode : IAstNodeWithAttributes |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
public AstTypeNode Type { get; set; } |
||||
|
|
||||
|
public override string ToString() => $"Struct member {Type.Format()} {Name}"; |
||||
|
public AstStructMemberNode Clone() => new AstStructMemberNode() { Name = Name, Type = Type.Clone() }; |
||||
|
public AstAttributes Attributes { get; set; } = new AstAttributes(); |
||||
|
} |
||||
|
|
||||
|
public class AstInterfaceNode : List<AstInterfaceMemberNode>, IAstNodeWithAttributes |
||||
|
{ |
||||
|
public AstAttributes Attributes { get; set; } = new AstAttributes(); |
||||
|
public string Name { get; set; } |
||||
|
public string Inherits { get; set; } |
||||
|
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
if (Inherits == null) |
||||
|
return Name; |
||||
|
return $"Interface {Name} : {Inherits}"; |
||||
|
} |
||||
|
public AstInterfaceNode Clone() |
||||
|
{ |
||||
|
var rv = new AstInterfaceNode { Name = Name, Inherits = Inherits, Attributes = Attributes.Clone() }; |
||||
|
rv.AddRange(this.Select(x => x.Clone())); |
||||
|
return rv; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class AstInterfaceMemberNode : List<AstInterfaceMemberArgumentNode>, IAstNodeWithAttributes |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
public AstTypeNode ReturnType { get; set; } |
||||
|
public AstAttributes Attributes { get; set; } = new AstAttributes(); |
||||
|
|
||||
|
public AstInterfaceMemberNode Clone() |
||||
|
{ |
||||
|
var rv = new AstInterfaceMemberNode() |
||||
|
{ |
||||
|
Name = Name, Attributes = Attributes.Clone(), ReturnType = ReturnType |
||||
|
}; |
||||
|
rv.AddRange(this.Select(x => x.Clone())); |
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
public override string ToString() => |
||||
|
$"Interface member {ReturnType.Format()} {Name} ({string.Join(", ", this.Select(x => x.Format()))})"; |
||||
|
} |
||||
|
|
||||
|
public class AstInterfaceMemberArgumentNode : IAstNodeWithAttributes |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
public AstTypeNode Type { get; set; } |
||||
|
public AstAttributes Attributes { get; set; } = new AstAttributes(); |
||||
|
|
||||
|
|
||||
|
public string Format() => $"{Type.Format()} {Name}"; |
||||
|
public override string ToString() => "Argument " + Format(); |
||||
|
|
||||
|
public AstInterfaceMemberArgumentNode Clone() => new AstInterfaceMemberArgumentNode |
||||
|
{ |
||||
|
Name = Name, Type = Type.Clone(), Attributes = Attributes.Clone() |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public static class AstExtensions |
||||
|
{ |
||||
|
public static bool HasAttribute(this IAstNodeWithAttributes node, string s) => node.Attributes.HasAttribute(s); |
||||
|
|
||||
|
public static string GetAttribute(this IAstNodeWithAttributes node, string s) |
||||
|
{ |
||||
|
var value = node.Attributes.FirstOrDefault(a => a.Name == s)?.Value; |
||||
|
if (value == null) |
||||
|
throw new CodeGenException("Expected attribute " + s + " for node " + node); |
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
public static string GetAttributeOrDefault(this IAstNodeWithAttributes node, string s) |
||||
|
=> node.Attributes.FirstOrDefault(a => a.Name == s)?.Value; |
||||
|
} |
||||
|
|
||||
|
class AstVisitor |
||||
|
{ |
||||
|
protected virtual void VisitType(AstTypeNode type) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
protected virtual void VisitArgument(AstInterfaceMemberArgumentNode argument) |
||||
|
{ |
||||
|
VisitType(argument.Type); |
||||
|
} |
||||
|
|
||||
|
protected virtual void VisitInterfaceMember(AstInterfaceMemberNode member) |
||||
|
{ |
||||
|
foreach(var a in member) |
||||
|
VisitArgument(a); |
||||
|
VisitType(member.ReturnType); |
||||
|
} |
||||
|
|
||||
|
protected virtual void VisitInterface(AstInterfaceNode iface) |
||||
|
{ |
||||
|
foreach(var m in iface) |
||||
|
VisitInterfaceMember(m); |
||||
|
} |
||||
|
|
||||
|
protected virtual void VisitStructMember(AstStructMemberNode member) |
||||
|
{ |
||||
|
VisitType(member.Type); |
||||
|
} |
||||
|
|
||||
|
protected virtual void VisitStruct(AstStructNode node) |
||||
|
{ |
||||
|
foreach(var m in node) |
||||
|
VisitStructMember(m); |
||||
|
} |
||||
|
|
||||
|
public virtual void VisitAst(AstIdlNode ast) |
||||
|
{ |
||||
|
foreach(var iface in ast.Interfaces) |
||||
|
VisitInterface(iface); |
||||
|
foreach (var s in ast.Structs) |
||||
|
VisitStruct(s); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
public class AstIdlNode : IAstNodeWithAttributes |
||||
|
{ |
||||
|
public AstAttributes Attributes { get; set; } = new AstAttributes(); |
||||
|
public List<AstEnumNode> Enums { get; set; } = new List<AstEnumNode>(); |
||||
|
public List<AstStructNode> Structs { get; set; } = new List<AstStructNode>(); |
||||
|
public List<AstInterfaceNode> Interfaces { get; set; } = new List<AstInterfaceNode>(); |
||||
|
|
||||
|
public AstIdlNode Clone() => new AstIdlNode() |
||||
|
{ |
||||
|
Attributes = Attributes.Clone(), |
||||
|
Enums = Enums.Select(x => x.Clone()).ToList(), |
||||
|
Structs = Structs.Select(x => x.Clone()).ToList(), |
||||
|
Interfaces = Interfaces.Select(x => x.Clone()).ToList() |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,231 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using MicroComGenerator.Ast; |
||||
|
|
||||
|
namespace MicroComGenerator |
||||
|
{ |
||||
|
public class AstParser |
||||
|
{ |
||||
|
public static AstIdlNode Parse(string source) |
||||
|
{ |
||||
|
var parser = new TokenParser(source); |
||||
|
var idl = new AstIdlNode { Attributes = ParseGlobalAttributes(ref parser) }; |
||||
|
|
||||
|
while (!parser.Eof) |
||||
|
{ |
||||
|
var attrs = ParseLocalAttributes(ref parser); |
||||
|
|
||||
|
if (parser.TryParseKeyword("enum")) |
||||
|
idl.Enums.Add(ParseEnum(attrs, ref parser)); |
||||
|
else if (parser.TryParseKeyword("struct")) |
||||
|
idl.Structs.Add(ParseStruct(attrs, ref parser)); |
||||
|
else if (parser.TryParseKeyword("interface")) |
||||
|
idl.Interfaces.Add(ParseInterface(attrs, ref parser)); |
||||
|
else |
||||
|
throw new ParseException("Unexpected character", ref parser); |
||||
|
} |
||||
|
|
||||
|
return idl; |
||||
|
} |
||||
|
|
||||
|
static AstAttributes ParseGlobalAttributes(ref TokenParser parser) |
||||
|
{ |
||||
|
var rv = new AstAttributes(); |
||||
|
while (!parser.Eof) |
||||
|
{ |
||||
|
parser.SkipWhitespace(); |
||||
|
if (parser.TryConsume('@')) |
||||
|
{ |
||||
|
var ident = parser.ParseIdentifier("-"); |
||||
|
var value = parser.ReadToEol().Trim(); |
||||
|
if (value == "@@") |
||||
|
{ |
||||
|
parser.Advance(1); |
||||
|
value = ""; |
||||
|
while (true) |
||||
|
{ |
||||
|
var l = parser.ReadToEol(); |
||||
|
if (l == "@@") |
||||
|
break; |
||||
|
else |
||||
|
value = value.Length == 0 ? l : (value + "\n" + l); |
||||
|
parser.Advance(1); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
rv.Add(new AstAttributeNode(ident, value)); |
||||
|
} |
||||
|
else |
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
static AstAttributes ParseLocalAttributes(ref TokenParser parser) |
||||
|
{ |
||||
|
var rv = new AstAttributes(); |
||||
|
if (parser.TryConsume("[")) |
||||
|
{ |
||||
|
while (!parser.TryConsume("]") && !parser.Eof) |
||||
|
{ |
||||
|
if (parser.TryConsume(',')) |
||||
|
continue; |
||||
|
|
||||
|
// Get identifier
|
||||
|
var ident = parser.ParseIdentifier("-"); |
||||
|
|
||||
|
// No value, end of attribute list
|
||||
|
if (parser.TryConsume(']')) |
||||
|
{ |
||||
|
rv.Add(new AstAttributeNode(ident, null)); |
||||
|
return rv; |
||||
|
} |
||||
|
// No value, next attribute
|
||||
|
else if (parser.TryConsume(',')) |
||||
|
rv.Add(new AstAttributeNode(ident, null)); |
||||
|
// Has value
|
||||
|
else if (parser.TryConsume('(')) |
||||
|
{ |
||||
|
var value = parser.ReadTo(')'); |
||||
|
parser.Consume(')'); |
||||
|
rv.Add(new AstAttributeNode(ident, value)); |
||||
|
} |
||||
|
else |
||||
|
throw new ParseException("Unexpected character", ref parser); |
||||
|
} |
||||
|
|
||||
|
if (parser.Eof) |
||||
|
throw new ParseException("Unexpected EOF", ref parser); |
||||
|
} |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
static void EnsureOpenBracket(ref TokenParser parser) |
||||
|
{ |
||||
|
if (!parser.TryConsume('{')) |
||||
|
throw new ParseException("{ expected", ref parser); |
||||
|
} |
||||
|
|
||||
|
static AstEnumNode ParseEnum(AstAttributes attrs, ref TokenParser parser) |
||||
|
{ |
||||
|
var name = parser.ParseIdentifier(); |
||||
|
EnsureOpenBracket(ref parser); |
||||
|
var rv = new AstEnumNode { Name = name, Attributes = attrs }; |
||||
|
while (!parser.TryConsume('}') && !parser.Eof) |
||||
|
{ |
||||
|
if (parser.TryConsume(',')) |
||||
|
continue; |
||||
|
|
||||
|
var ident = parser.ParseIdentifier(); |
||||
|
|
||||
|
// Automatic value
|
||||
|
if (parser.TryConsume(',') || parser.Peek == '}') |
||||
|
{ |
||||
|
rv.Add(new AstEnumMemberNode(ident, null)); |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (!parser.TryConsume('=')) |
||||
|
throw new ParseException("Unexpected character", ref parser); |
||||
|
|
||||
|
var value = parser.ReadToAny(",}").Trim(); |
||||
|
rv.Add(new AstEnumMemberNode(ident, value)); |
||||
|
|
||||
|
if (parser.Eof) |
||||
|
throw new ParseException("Unexpected EOF", ref parser); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
static AstTypeNode ParseType(ref TokenParser parser) |
||||
|
{ |
||||
|
var ident = parser.ParseIdentifier(); |
||||
|
var t = new AstTypeNode { Name = ident }; |
||||
|
while (parser.TryConsume('*')) |
||||
|
t.PointerLevel++; |
||||
|
if (parser.TryConsume("&")) |
||||
|
t.IsLink = true; |
||||
|
return t; |
||||
|
} |
||||
|
|
||||
|
static AstStructNode ParseStruct(AstAttributes attrs, ref TokenParser parser) |
||||
|
{ |
||||
|
var name = parser.ParseIdentifier(); |
||||
|
EnsureOpenBracket(ref parser); |
||||
|
var rv = new AstStructNode { Name = name, Attributes = attrs }; |
||||
|
while (!parser.TryConsume('}') && !parser.Eof) |
||||
|
{ |
||||
|
var memberAttrs = ParseLocalAttributes(ref parser); |
||||
|
var t = ParseType(ref parser); |
||||
|
bool parsedAtLeastOneMember = false; |
||||
|
while (!parser.TryConsume(';')) |
||||
|
{ |
||||
|
// Skip any ,
|
||||
|
while (parser.TryConsume(',')) { } |
||||
|
|
||||
|
var ident = parser.ParseIdentifier(); |
||||
|
parsedAtLeastOneMember = true; |
||||
|
rv.Add(new AstStructMemberNode { Name = ident, Type = t, Attributes = memberAttrs}); |
||||
|
} |
||||
|
|
||||
|
if (!parsedAtLeastOneMember) |
||||
|
throw new ParseException("Expected at least one enum member with declared type " + t, ref parser); |
||||
|
} |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
static AstInterfaceNode ParseInterface(AstAttributes interfaceAttrs, ref TokenParser parser) |
||||
|
{ |
||||
|
var interfaceName = parser.ParseIdentifier(); |
||||
|
string inheritsFrom = null; |
||||
|
if (parser.TryConsume(":")) |
||||
|
inheritsFrom = parser.ParseIdentifier(); |
||||
|
|
||||
|
EnsureOpenBracket(ref parser); |
||||
|
var rv = new AstInterfaceNode |
||||
|
{ |
||||
|
Name = interfaceName, Attributes = interfaceAttrs, Inherits = inheritsFrom |
||||
|
}; |
||||
|
while (!parser.TryConsume('}') && !parser.Eof) |
||||
|
{ |
||||
|
var memberAttrs = ParseLocalAttributes(ref parser); |
||||
|
var returnType = ParseType(ref parser); |
||||
|
var name = parser.ParseIdentifier(); |
||||
|
var member = new AstInterfaceMemberNode |
||||
|
{ |
||||
|
Name = name, ReturnType = returnType, Attributes = memberAttrs |
||||
|
}; |
||||
|
rv.Add(member); |
||||
|
|
||||
|
parser.Consume('('); |
||||
|
while (true) |
||||
|
{ |
||||
|
if (parser.TryConsume(')')) |
||||
|
break; |
||||
|
|
||||
|
var argumentAttrs = ParseLocalAttributes(ref parser); |
||||
|
var type = ParseType(ref parser); |
||||
|
var argName = parser.ParseIdentifier(); |
||||
|
member.Add(new AstInterfaceMemberArgumentNode |
||||
|
{ |
||||
|
Name = argName, Type = type, Attributes = argumentAttrs |
||||
|
}); |
||||
|
|
||||
|
if (parser.TryConsume(')')) |
||||
|
break; |
||||
|
if (parser.TryConsume(',')) |
||||
|
continue; |
||||
|
throw new ParseException("Unexpected character", ref parser); |
||||
|
} |
||||
|
|
||||
|
parser.Consume(';'); |
||||
|
} |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,459 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using MicroComGenerator.Ast; |
||||
|
using Microsoft.CodeAnalysis; |
||||
|
using Microsoft.CodeAnalysis.CSharp; |
||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax; |
||||
|
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; |
||||
|
|
||||
|
// ReSharper disable CoVariantArrayConversion
|
||||
|
|
||||
|
// HERE BE DRAGONS
|
||||
|
|
||||
|
namespace MicroComGenerator |
||||
|
{ |
||||
|
public partial class CSharpGen |
||||
|
{ |
||||
|
abstract class Arg |
||||
|
{ |
||||
|
public string Name; |
||||
|
public string NativeType; |
||||
|
|
||||
|
public virtual StatementSyntax CreateFixed(StatementSyntax inner) => inner; |
||||
|
|
||||
|
public virtual void PreMarshal(List<StatementSyntax> body) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public virtual void PreMarshalForReturn(List<StatementSyntax> body) => |
||||
|
throw new InvalidOperationException("Don't know how to use " + NativeType + " as HRESULT-return"); |
||||
|
|
||||
|
public virtual ExpressionSyntax Value(bool isHresultReturn) => ParseExpression(Name); |
||||
|
public abstract string ManagedType { get; } |
||||
|
public virtual string ReturnManagedType => ManagedType; |
||||
|
|
||||
|
public virtual StatementSyntax[] ReturnMarshalResult() => new[] { ParseStatement("return " + Name + ";") }; |
||||
|
|
||||
|
|
||||
|
public virtual void BackPreMarshal(List<StatementSyntax> body) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public virtual ExpressionSyntax BackMarshalValue() => ParseExpression(Name); |
||||
|
public virtual ExpressionSyntax BackMarshalReturn(string resultVar) => ParseExpression(resultVar); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
class InterfaceReturnArg : Arg |
||||
|
{ |
||||
|
public string InterfaceType; |
||||
|
public override ExpressionSyntax Value(bool isHresultReturn) => ParseExpression("&" + PName); |
||||
|
public override string ManagedType => InterfaceType; |
||||
|
|
||||
|
private string PName => "__marshal_" + Name; |
||||
|
|
||||
|
public override void PreMarshalForReturn(List<StatementSyntax> body) |
||||
|
{ |
||||
|
body.Add(ParseStatement("void* " + PName + " = null;")); |
||||
|
} |
||||
|
|
||||
|
public override StatementSyntax[] ReturnMarshalResult() => new[] |
||||
|
{ |
||||
|
ParseStatement("return Avalonia.MicroCom.MicroComRuntime.CreateProxyFor<" + InterfaceType + ">(" + |
||||
|
PName + ", true);") |
||||
|
}; |
||||
|
|
||||
|
public override ExpressionSyntax BackMarshalValue() |
||||
|
{ |
||||
|
return ParseExpression("INVALID"); |
||||
|
} |
||||
|
|
||||
|
public override ExpressionSyntax BackMarshalReturn(string resultVar) |
||||
|
{ |
||||
|
return ParseExpression($"Avalonia.MicroCom.MicroComRuntime.GetNativePointer({resultVar}, true)"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class InterfaceArg : Arg |
||||
|
{ |
||||
|
public string InterfaceType; |
||||
|
|
||||
|
public override ExpressionSyntax Value(bool isHresultReturn) => |
||||
|
ParseExpression("Avalonia.MicroCom.MicroComRuntime.GetNativePointer(" + Name + ")"); |
||||
|
|
||||
|
public override string ManagedType => InterfaceType; |
||||
|
|
||||
|
public override StatementSyntax[] ReturnMarshalResult() => new[] |
||||
|
{ |
||||
|
ParseStatement("return Avalonia.MicroCom.MicroComRuntime.CreateProxyFor<" + InterfaceType + ">(" + |
||||
|
Name + ", true);") |
||||
|
}; |
||||
|
|
||||
|
public override ExpressionSyntax BackMarshalValue() |
||||
|
{ |
||||
|
return ParseExpression("Avalonia.MicroCom.MicroComRuntime.CreateProxyFor<" + InterfaceType + ">(" + |
||||
|
Name + ", false)"); |
||||
|
} |
||||
|
|
||||
|
public override ExpressionSyntax BackMarshalReturn(string resultVar) |
||||
|
{ |
||||
|
return ParseExpression($"Avalonia.MicroCom.MicroComRuntime.GetNativePointer({resultVar}, true)"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class BypassArg : Arg |
||||
|
{ |
||||
|
public string Type { get; set; } |
||||
|
public int PointerLevel; |
||||
|
public override string ManagedType => Type + new string('*', PointerLevel); |
||||
|
public override string ReturnManagedType => Type + new string('*', PointerLevel - 1); |
||||
|
|
||||
|
public override ExpressionSyntax Value(bool isHresultReturn) |
||||
|
{ |
||||
|
if (isHresultReturn) |
||||
|
return ParseExpression("&" + Name); |
||||
|
return base.Value(false); |
||||
|
} |
||||
|
|
||||
|
public override void PreMarshalForReturn(List<StatementSyntax> body) |
||||
|
{ |
||||
|
if (PointerLevel == 0) |
||||
|
base.PreMarshalForReturn(body); |
||||
|
else |
||||
|
body.Add(ParseStatement(Type + new string('*', PointerLevel - 1) + " " + Name + "=default;")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class StringArg : Arg |
||||
|
{ |
||||
|
private string BName => "__bytemarshal_" + Name; |
||||
|
private string FName => "__fixedmarshal_" + Name; |
||||
|
|
||||
|
public override void PreMarshal(List<StatementSyntax> body) |
||||
|
{ |
||||
|
body.Add(ParseStatement($"var {BName} = new byte[System.Text.Encoding.UTF8.GetByteCount({Name})+1];")); |
||||
|
body.Add(ParseStatement($"System.Text.Encoding.UTF8.GetBytes({Name}, 0, {Name}.Length, {BName}, 0);")); |
||||
|
} |
||||
|
|
||||
|
public override StatementSyntax CreateFixed(StatementSyntax inner) |
||||
|
{ |
||||
|
return FixedStatement(DeclareVar("byte*", FName, ParseExpression(BName)), inner); |
||||
|
} |
||||
|
|
||||
|
public override ExpressionSyntax Value(bool isHresultReturn) => ParseExpression(FName); |
||||
|
public override string ManagedType => "string"; |
||||
|
public override ExpressionSyntax BackMarshalValue() |
||||
|
{ |
||||
|
return ParseExpression( |
||||
|
$"({Name} == null ? null : System.Runtime.InteropServices.Marshal.PtrToStringAnsi(new IntPtr(" + Name + ")))"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
string ConvertNativeType(string type) |
||||
|
{ |
||||
|
if (type == "size_t") |
||||
|
return "System.IntPtr"; |
||||
|
if (type == "HRESULT") |
||||
|
return "int"; |
||||
|
return type; |
||||
|
} |
||||
|
|
||||
|
Arg ConvertArg(string name, AstTypeNode type) |
||||
|
{ |
||||
|
type = new AstTypeNode { Name = ConvertNativeType(type.Name), PointerLevel = type.PointerLevel }; |
||||
|
|
||||
|
if (type.PointerLevel == 2) |
||||
|
{ |
||||
|
if (IsInterface(type)) |
||||
|
return new InterfaceReturnArg { Name = name, InterfaceType = type.Name, NativeType = "void**" }; |
||||
|
} |
||||
|
else if (type.PointerLevel == 1) |
||||
|
{ |
||||
|
if (IsInterface(type)) |
||||
|
return new InterfaceArg { Name = name, InterfaceType = type.Name, NativeType = "void*" }; |
||||
|
if (type.Name == "char") |
||||
|
return new StringArg { Name = name, NativeType = "byte*" }; |
||||
|
} |
||||
|
|
||||
|
return new BypassArg |
||||
|
{ |
||||
|
Name = name, Type = type.Name, PointerLevel = type.PointerLevel, NativeType = type.ToString() |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void GenerateInterfaceMember(AstInterfaceMemberNode member, ref InterfaceDeclarationSyntax iface, |
||||
|
ref ClassDeclarationSyntax proxy, ref ClassDeclarationSyntax vtbl, |
||||
|
List<StatementSyntax> vtblCtor, int num) |
||||
|
{ |
||||
|
// Prepare method information
|
||||
|
var args = member.Select(a => ConvertArg(a.Name, a.Type)).ToList(); |
||||
|
var returnArg = ConvertArg("__result", member.ReturnType); |
||||
|
bool isHresult = member.ReturnType.Name == "HRESULT"; |
||||
|
bool isHresultLastArgumentReturn = isHresult |
||||
|
&& args.Count > 0 |
||||
|
&& (args.Last().Name == "ppv" || args.Last().Name == "retOut" || args.Last().Name == "ret") |
||||
|
&& ((member.Last().Type.PointerLevel > 0 |
||||
|
&& !IsInterface(member.Last().Type)) |
||||
|
|| member.Last().Type.PointerLevel == 2); |
||||
|
|
||||
|
bool isVoidReturn = member.ReturnType.Name == "void" && member.ReturnType.PointerLevel == 0; |
||||
|
|
||||
|
|
||||
|
// Generate method signature
|
||||
|
MethodDeclarationSyntax GenerateManagedSig(string returnType, string name, |
||||
|
IEnumerable<(string n, string t)> args) |
||||
|
=> MethodDeclaration(ParseTypeName(returnType), name).WithParameterList( |
||||
|
ParameterList( |
||||
|
SeparatedList(args.Select(x => Parameter(Identifier(x.n)).WithType(ParseTypeName(x.t)))))); |
||||
|
|
||||
|
var managedSig = |
||||
|
isHresult ? |
||||
|
GenerateManagedSig(isHresultLastArgumentReturn ? args.Last().ReturnManagedType : "void", |
||||
|
member.Name, |
||||
|
(isHresultLastArgumentReturn ? args.SkipLast(1) : args).Select(a => (a.Name, a.ManagedType))) : |
||||
|
GenerateManagedSig(returnArg.ManagedType, member.Name, args.Select(a => (a.Name, a.ManagedType))); |
||||
|
|
||||
|
iface = iface.AddMembers(managedSig.WithSemicolonToken(Semicolon())); |
||||
|
|
||||
|
// Prepare args for marshaling
|
||||
|
var preMarshal = new List<StatementSyntax>(); |
||||
|
if (!isVoidReturn) |
||||
|
preMarshal.Add(ParseStatement(returnArg.NativeType + " __result;")); |
||||
|
|
||||
|
for (var idx = 0; idx < args.Count; idx++) |
||||
|
{ |
||||
|
if (isHresultLastArgumentReturn && idx == args.Count - 1) |
||||
|
args[idx].PreMarshalForReturn(preMarshal); |
||||
|
else |
||||
|
args[idx].PreMarshal(preMarshal); |
||||
|
} |
||||
|
|
||||
|
// Generate call expression
|
||||
|
ExpressionSyntax callExpr = InvocationExpression(_localInterop.GetCaller(returnArg.NativeType, |
||||
|
args.Select(x => x.NativeType).ToList())) |
||||
|
.AddArgumentListArguments(Argument(ParseExpression("PPV"))) |
||||
|
.AddArgumentListArguments(args |
||||
|
.Select((a, i) => Argument(a.Value(isHresultLastArgumentReturn && i == args.Count - 1))).ToArray()) |
||||
|
.AddArgumentListArguments(Argument(ParseExpression("(*PPV)[base.VTableSize + " + num + "]"))); |
||||
|
|
||||
|
if (!isVoidReturn) |
||||
|
callExpr = CastExpression(ParseTypeName(returnArg.NativeType), callExpr); |
||||
|
|
||||
|
// Save call result if needed
|
||||
|
if (!isVoidReturn) |
||||
|
callExpr = AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, ParseExpression("__result"), |
||||
|
callExpr); |
||||
|
|
||||
|
|
||||
|
// Wrap call into fixed() blocks
|
||||
|
StatementSyntax callStatement = ExpressionStatement(callExpr); |
||||
|
foreach (var arg in args) |
||||
|
callStatement = arg.CreateFixed(callStatement); |
||||
|
|
||||
|
// Build proxy body
|
||||
|
var proxyBody = Block() |
||||
|
.AddStatements(preMarshal.ToArray()) |
||||
|
.AddStatements(callStatement); |
||||
|
|
||||
|
// Process return value
|
||||
|
if (!isVoidReturn) |
||||
|
{ |
||||
|
if (isHresult) |
||||
|
{ |
||||
|
proxyBody = proxyBody.AddStatements( |
||||
|
ParseStatement( |
||||
|
$"if(__result != 0) throw new System.Runtime.InteropServices.COMException(\"{member.Name} failed\", __result);")); |
||||
|
|
||||
|
if (isHresultLastArgumentReturn) |
||||
|
proxyBody = proxyBody.AddStatements(args.Last().ReturnMarshalResult()); |
||||
|
} |
||||
|
else |
||||
|
proxyBody = proxyBody.AddStatements(returnArg.ReturnMarshalResult()); |
||||
|
} |
||||
|
|
||||
|
// Add the proxy method
|
||||
|
proxy = proxy.AddMembers(managedSig.AddModifiers(SyntaxKind.PublicKeyword) |
||||
|
.WithBody(proxyBody)); |
||||
|
|
||||
|
|
||||
|
// Generate VTable method
|
||||
|
var shadowDelegate = DelegateDeclaration(ParseTypeName(returnArg.NativeType), member.Name + "Delegate") |
||||
|
.AddParameterListParameters(Parameter(Identifier("@this")).WithType(ParseTypeName("IntPtr"))) |
||||
|
.AddParameterListParameters(args.Select(x => |
||||
|
Parameter(Identifier(x.Name)).WithType(ParseTypeName(x.NativeType))).ToArray()) |
||||
|
.AddAttribute("System.Runtime.InteropServices.UnmanagedFunctionPointer", |
||||
|
"System.Runtime.InteropServices.CallingConvention.StdCall"); |
||||
|
|
||||
|
var shadowMethod = MethodDeclaration(shadowDelegate.ReturnType, member.Name) |
||||
|
.WithParameterList(shadowDelegate.ParameterList) |
||||
|
.AddModifiers(Token(SyntaxKind.StaticKeyword)); |
||||
|
|
||||
|
var backPreMarshal = new List<StatementSyntax>(); |
||||
|
foreach (var arg in args) |
||||
|
arg.BackPreMarshal(backPreMarshal); |
||||
|
|
||||
|
backPreMarshal.Add( |
||||
|
ParseStatement($"__target = ({iface.Identifier.Text})Avalonia.MicroCom.MicroComRuntime.GetObjectFromCcw(@this);")); |
||||
|
|
||||
|
var isBackVoidReturn = isVoidReturn || (isHresult && !isHresultLastArgumentReturn); |
||||
|
|
||||
|
StatementSyntax backCallStatement; |
||||
|
|
||||
|
var backCallExpr = |
||||
|
IsPropertyRewriteCandidate(managedSig) ? |
||||
|
ParseExpression("__target." + member.Name.Substring(3)) : |
||||
|
InvocationExpression(ParseExpression("__target." + member.Name)) |
||||
|
.WithArgumentList(ArgumentList(SeparatedList( |
||||
|
(isHresultLastArgumentReturn ? args.SkipLast(1) : args) |
||||
|
.Select(a => |
||||
|
Argument(a.BackMarshalValue()))))); |
||||
|
|
||||
|
if (isBackVoidReturn) |
||||
|
backCallStatement = ExpressionStatement(backCallExpr); |
||||
|
else |
||||
|
{ |
||||
|
backCallStatement = LocalDeclarationStatement(DeclareVar("var", "__result", backCallExpr)); |
||||
|
if (isHresultLastArgumentReturn) |
||||
|
{ |
||||
|
backCallStatement = Block(backCallStatement, |
||||
|
ExpressionStatement(AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, |
||||
|
ParseExpression("*" + args.Last().Name), |
||||
|
args.Last().BackMarshalReturn("__result") |
||||
|
))); |
||||
|
|
||||
|
} |
||||
|
else |
||||
|
backCallStatement = Block(backCallStatement, |
||||
|
ReturnStatement(returnArg.BackMarshalReturn("__result"))); |
||||
|
} |
||||
|
|
||||
|
BlockSyntax backBodyBlock = Block().AddStatements(backPreMarshal.ToArray()).AddStatements(backCallStatement); |
||||
|
|
||||
|
|
||||
|
backBodyBlock = Block( |
||||
|
TryStatement( |
||||
|
SingletonList(CatchClause( |
||||
|
CatchDeclaration(ParseTypeName("System.Exception"), Identifier("__exception__")), null, |
||||
|
Block( |
||||
|
ParseStatement( |
||||
|
"Avalonia.MicroCom.MicroComRuntime.UnhandledException(__target, __exception__);"), |
||||
|
isHresult ? ParseStatement("return unchecked((int)0x80004005u);") |
||||
|
: isVoidReturn ? EmptyStatement() : ParseStatement("return default;") |
||||
|
)))) |
||||
|
.WithBlock(Block(backBodyBlock)) |
||||
|
); |
||||
|
if (isHresult) |
||||
|
backBodyBlock = backBodyBlock.AddStatements(ParseStatement("return 0;")); |
||||
|
|
||||
|
|
||||
|
backBodyBlock = Block() |
||||
|
.AddStatements(ParseStatement($"{iface.Identifier.Text} __target = null;")) |
||||
|
.AddStatements(backBodyBlock.Statements.ToArray()); |
||||
|
|
||||
|
shadowMethod = shadowMethod.WithBody(backBodyBlock); |
||||
|
|
||||
|
vtbl = vtbl.AddMembers(shadowDelegate).AddMembers(shadowMethod); |
||||
|
vtblCtor.Add(ParseStatement("base.AddMethod((" + shadowDelegate.Identifier.Text + ")" + |
||||
|
shadowMethod.Identifier.Text + ");")); |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
class LocalInteropHelper |
||||
|
{ |
||||
|
public ClassDeclarationSyntax Class { get; private set; } = ClassDeclaration("LocalInterop"); |
||||
|
private HashSet<string> _existing = new HashSet<string>(); |
||||
|
|
||||
|
public ExpressionSyntax GetCaller(string returnType, List<string> args) |
||||
|
{ |
||||
|
string ConvertType(string t) => t.EndsWith("*") ? "void*" : t; |
||||
|
returnType = ConvertType(returnType); |
||||
|
args = args.Select(ConvertType).ToList(); |
||||
|
|
||||
|
var name = "CalliStdCall" + returnType.Replace("*", "_ptr"); |
||||
|
var signature = returnType + "::" + name + "::" + string.Join("::", args); |
||||
|
if (_existing.Add(signature)) |
||||
|
{ |
||||
|
Class = Class.AddMembers(MethodDeclaration(ParseTypeName(returnType), name) |
||||
|
.AddModifiers(SyntaxKind.StaticKeyword, SyntaxKind.UnsafeKeyword, SyntaxKind.PublicKeyword) |
||||
|
.AddParameterListParameters(Parameter(Identifier("thisObj")).WithType(ParseTypeName("void*"))) |
||||
|
.AddParameterListParameters(args.Select((x, i) => |
||||
|
Parameter(Identifier("arg" + i)).WithType(ParseTypeName(x))).ToArray()) |
||||
|
.AddParameterListParameters(Parameter(Identifier("methodPtr")).WithType(ParseTypeName("void*"))) |
||||
|
.WithBody(Block(ExpressionStatement(ThrowExpression(ParseExpression("null")))))); |
||||
|
} |
||||
|
|
||||
|
return ParseExpression("LocalInterop." + name); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void GenerateInterface(ref NamespaceDeclarationSyntax ns, ref NamespaceDeclarationSyntax implNs, |
||||
|
AstInterfaceNode iface) |
||||
|
{ |
||||
|
var guidString = iface.GetAttribute("uuid"); |
||||
|
var inheritsUnknown = iface.Inherits == null || iface.Inherits == "IUnknown"; |
||||
|
|
||||
|
var ifaceDec = InterfaceDeclaration(iface.Name) |
||||
|
.WithBaseType(inheritsUnknown ? "Avalonia.MicroCom.IUnknown" : iface.Inherits) |
||||
|
.AddModifiers(Token(_visibility), Token(SyntaxKind.UnsafeKeyword), Token(SyntaxKind.PartialKeyword)); |
||||
|
|
||||
|
var proxyClassName = "__MicroCom" + iface.Name + "Proxy"; |
||||
|
var proxy = ClassDeclaration(proxyClassName) |
||||
|
.AddModifiers(Token(SyntaxKind.UnsafeKeyword), Token(_visibility), Token(SyntaxKind.PartialKeyword)) |
||||
|
.WithBaseType(inheritsUnknown ? |
||||
|
"Avalonia.MicroCom.MicroComProxyBase" : |
||||
|
("__MicroCom" + iface.Inherits + "Proxy")) |
||||
|
.AddBaseListTypes(SimpleBaseType(ParseTypeName(iface.Name))); |
||||
|
|
||||
|
|
||||
|
// Generate vtable
|
||||
|
var vtbl = ClassDeclaration("__MicroCom" + iface.Name + "VTable") |
||||
|
.AddModifiers(Token(SyntaxKind.UnsafeKeyword)); |
||||
|
|
||||
|
vtbl = vtbl.WithBaseType(inheritsUnknown ? |
||||
|
"Avalonia.MicroCom.MicroComVtblBase" : |
||||
|
"__MicroCom" + iface.Inherits + "VTable"); |
||||
|
|
||||
|
var vtblCtor = new List<StatementSyntax>(); |
||||
|
for (var idx = 0; idx < iface.Count; idx++) |
||||
|
GenerateInterfaceMember(iface[idx], ref ifaceDec, ref proxy, ref vtbl, vtblCtor, idx); |
||||
|
|
||||
|
vtbl = vtbl.AddMembers( |
||||
|
ConstructorDeclaration(vtbl.Identifier.Text) |
||||
|
.AddModifiers(Token(SyntaxKind.PublicKeyword)) |
||||
|
.WithBody(Block(vtblCtor)) |
||||
|
) |
||||
|
.AddMembers(MethodDeclaration(ParseTypeName("void"), "__MicroComModuleInit") |
||||
|
.AddModifiers(Token(SyntaxKind.StaticKeyword), Token(SyntaxKind.InternalKeyword)) |
||||
|
.WithExpressionBody(ArrowExpressionClause( |
||||
|
ParseExpression("Avalonia.MicroCom.MicroComRuntime.RegisterVTable(typeof(" + |
||||
|
iface.Name + "), new " + vtbl.Identifier.Text + "().CreateVTable())"))) |
||||
|
.WithSemicolonToken(Semicolon())); |
||||
|
|
||||
|
|
||||
|
// Finalize proxy code
|
||||
|
proxy = proxy.AddMembers( |
||||
|
MethodDeclaration(ParseTypeName("void"), "__MicroComModuleInit") |
||||
|
.AddModifiers(Token(SyntaxKind.StaticKeyword), Token(SyntaxKind.InternalKeyword)) |
||||
|
.WithBody(Block( |
||||
|
ParseStatement("Avalonia.MicroCom.MicroComRuntime.Register(typeof(" + |
||||
|
iface.Name + "), new Guid(\"" + guidString + "\"), (p, owns) => new " + |
||||
|
proxyClassName + "(p, owns));") |
||||
|
))) |
||||
|
.AddMembers(ParseMemberDeclaration("public " + proxyClassName + |
||||
|
"(IntPtr nativePointer, bool ownsHandle) : base(nativePointer, ownsHandle) {}")) |
||||
|
.AddMembers(ParseMemberDeclaration("protected override int VTableSize => base.VTableSize + " + |
||||
|
iface.Count + ";")); |
||||
|
|
||||
|
ns = ns.AddMembers(RewriteMethodsToProperties(ifaceDec)); |
||||
|
implNs = implNs.AddMembers(RewriteMethodsToProperties(proxy), RewriteMethodsToProperties(vtbl)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,110 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using MicroComGenerator.Ast; |
||||
|
using Microsoft.CodeAnalysis; |
||||
|
using Microsoft.CodeAnalysis.CSharp; |
||||
|
using Microsoft.CodeAnalysis.CSharp.Formatting; |
||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax; |
||||
|
|
||||
|
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; |
||||
|
namespace MicroComGenerator |
||||
|
{ |
||||
|
public partial class CSharpGen |
||||
|
{ |
||||
|
|
||||
|
CompilationUnitSyntax Unit() |
||||
|
=> CompilationUnit().WithUsings(List(new[] |
||||
|
{ |
||||
|
"System", "System.Text", "System.Collections", "System.Collections.Generic", "Avalonia.MicroCom" |
||||
|
} |
||||
|
.Concat(_extraUsings).Select(u => UsingDirective(IdentifierName(u))))); |
||||
|
|
||||
|
string Format(CompilationUnitSyntax unit) |
||||
|
{ |
||||
|
var cw = new AdhocWorkspace(); |
||||
|
return |
||||
|
"#pragma warning disable 108\n" + |
||||
|
Microsoft.CodeAnalysis.Formatting.Formatter.Format(unit.NormalizeWhitespace(), cw, cw.Options |
||||
|
.WithChangedOption(CSharpFormattingOptions.NewLineForMembersInObjectInit, true) |
||||
|
.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, |
||||
|
true) |
||||
|
.WithChangedOption(CSharpFormattingOptions.NewLineForMembersInAnonymousTypes, true) |
||||
|
.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInMethods, true) |
||||
|
|
||||
|
).ToFullString(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
SyntaxToken Semicolon() => Token(SyntaxKind.SemicolonToken); |
||||
|
|
||||
|
static VariableDeclarationSyntax DeclareVar(string type, string name, |
||||
|
ExpressionSyntax? initializer = null) |
||||
|
=> VariableDeclaration(ParseTypeName(type), |
||||
|
SingletonSeparatedList(VariableDeclarator(name) |
||||
|
.WithInitializer(initializer == null ? null : EqualsValueClause(initializer)))); |
||||
|
|
||||
|
FieldDeclarationSyntax DeclareConstant(string type, string name, LiteralExpressionSyntax value) |
||||
|
=> FieldDeclaration( |
||||
|
VariableDeclaration(ParseTypeName(type), |
||||
|
SingletonSeparatedList( |
||||
|
VariableDeclarator(name).WithInitializer(EqualsValueClause(value)) |
||||
|
)) |
||||
|
).WithSemicolonToken(Semicolon()) |
||||
|
.WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.ConstKeyword))); |
||||
|
|
||||
|
FieldDeclarationSyntax DeclareField(string type, string name, params SyntaxKind[] modifiers) => |
||||
|
DeclareField(type, name, null, modifiers); |
||||
|
|
||||
|
FieldDeclarationSyntax DeclareField(string type, string name, EqualsValueClauseSyntax initializer, |
||||
|
params SyntaxKind[] modifiers) => |
||||
|
FieldDeclaration( |
||||
|
VariableDeclaration(ParseTypeName(type), |
||||
|
SingletonSeparatedList( |
||||
|
VariableDeclarator(name).WithInitializer(initializer)))) |
||||
|
.WithSemicolonToken(Semicolon()) |
||||
|
.WithModifiers(TokenList(modifiers.Select(x => Token(x)))); |
||||
|
|
||||
|
bool IsPropertyRewriteCandidate(MethodDeclarationSyntax method) |
||||
|
{ |
||||
|
if(method.Identifier.Text.Contains("GetScaling")) |
||||
|
Console.WriteLine(); |
||||
|
return (method.Identifier.Text.StartsWith("Get") && |
||||
|
method.ParameterList.Parameters.Count == 0); |
||||
|
} |
||||
|
|
||||
|
TypeDeclarationSyntax RewriteMethodsToProperties<T>(T decl) where T : TypeDeclarationSyntax |
||||
|
{ |
||||
|
var replace = new Dictionary<MethodDeclarationSyntax, PropertyDeclarationSyntax>(); |
||||
|
foreach (var method in decl.Members.OfType<MethodDeclarationSyntax>().ToList()) |
||||
|
{ |
||||
|
if (IsPropertyRewriteCandidate(method)) |
||||
|
{ |
||||
|
var getter = AccessorDeclaration(SyntaxKind.GetAccessorDeclaration); |
||||
|
if (method.Body != null) |
||||
|
getter = getter.WithBody(method.Body); |
||||
|
else |
||||
|
getter = getter.WithSemicolonToken(Semicolon()); |
||||
|
|
||||
|
replace[method] = PropertyDeclaration(method.ReturnType, |
||||
|
method.Identifier.Text.Substring(3)) |
||||
|
.WithModifiers(method.Modifiers).AddAccessorListAccessors(getter); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return decl.ReplaceNodes(replace.Keys, (m, m2) => replace[m]); |
||||
|
} |
||||
|
|
||||
|
bool IsInterface(string name) |
||||
|
{ |
||||
|
if (name == "IUnknown") |
||||
|
return true; |
||||
|
return _idl.Interfaces.Any(i => i.Name == name); |
||||
|
} |
||||
|
|
||||
|
private bool IsInterface(AstTypeNode type) => IsInterface(type.Name); |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,133 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using MicroComGenerator.Ast; |
||||
|
using Microsoft.CodeAnalysis; |
||||
|
using Microsoft.CodeAnalysis.CSharp; |
||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax; |
||||
|
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; |
||||
|
// ReSharper disable CoVariantArrayConversion
|
||||
|
|
||||
|
namespace MicroComGenerator |
||||
|
{ |
||||
|
public partial class CSharpGen |
||||
|
{ |
||||
|
private readonly AstIdlNode _idl; |
||||
|
private List<string> _extraUsings; |
||||
|
private string _namespace; |
||||
|
private SyntaxKind _visibility; |
||||
|
private LocalInteropHelper _localInterop = new LocalInteropHelper(); |
||||
|
|
||||
|
public CSharpGen(AstIdlNode idl) |
||||
|
{ |
||||
|
_idl = idl.Clone(); |
||||
|
new AstRewriter().VisitAst(_idl); |
||||
|
_extraUsings = _idl.Attributes.Where(u => u.Name == "clr-using").Select(u => u.Value).ToList(); |
||||
|
_namespace = _idl.GetAttribute("clr-namespace"); |
||||
|
var visibilityString = _idl.GetAttribute("clr-access"); |
||||
|
|
||||
|
if (visibilityString == "internal") |
||||
|
_visibility = SyntaxKind.InternalKeyword; |
||||
|
else if (visibilityString == "public") |
||||
|
_visibility = SyntaxKind.PublicKeyword; |
||||
|
else |
||||
|
throw new CodeGenException("Invalid clr-access attribute"); |
||||
|
} |
||||
|
|
||||
|
class AstRewriter : AstVisitor |
||||
|
{ |
||||
|
void ConvertIntPtr(AstTypeNode type) |
||||
|
{ |
||||
|
if (type.Name == "void" && type.PointerLevel > 0) |
||||
|
{ |
||||
|
type.Name = "IntPtr"; |
||||
|
type.PointerLevel--; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected override void VisitStructMember(AstStructMemberNode member) |
||||
|
{ |
||||
|
if (member.HasAttribute("intptr")) |
||||
|
ConvertIntPtr(member.Type); |
||||
|
base.VisitStructMember(member); |
||||
|
} |
||||
|
|
||||
|
protected override void VisitType(AstTypeNode type) |
||||
|
{ |
||||
|
if (type.IsLink) |
||||
|
{ |
||||
|
type.PointerLevel++; |
||||
|
type.IsLink = false; |
||||
|
} |
||||
|
|
||||
|
base.VisitType(type); |
||||
|
} |
||||
|
|
||||
|
protected override void VisitArgument(AstInterfaceMemberArgumentNode argument) |
||||
|
{ |
||||
|
if (argument.HasAttribute("intptr")) |
||||
|
{ |
||||
|
if(argument.Name == "retOut") |
||||
|
Console.WriteLine(); |
||||
|
ConvertIntPtr(argument.Type); |
||||
|
} |
||||
|
|
||||
|
base.VisitArgument(argument); |
||||
|
} |
||||
|
|
||||
|
protected override void VisitInterfaceMember(AstInterfaceMemberNode member) |
||||
|
{ |
||||
|
if (member.HasAttribute("intptr")) |
||||
|
ConvertIntPtr(member.ReturnType); |
||||
|
base.VisitInterfaceMember(member); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public string Generate() |
||||
|
{ |
||||
|
var ns = NamespaceDeclaration(ParseName(_namespace)); |
||||
|
var implNs = NamespaceDeclaration(ParseName(_namespace + ".Impl"));
|
||||
|
ns = GenerateEnums(ns); |
||||
|
ns = GenerateStructs(ns); |
||||
|
foreach (var i in _idl.Interfaces) |
||||
|
GenerateInterface(ref ns, ref implNs, i); |
||||
|
|
||||
|
implNs = implNs.AddMembers(_localInterop.Class); |
||||
|
var unit = Unit().AddMembers(ns, implNs); |
||||
|
|
||||
|
return Format(unit); |
||||
|
} |
||||
|
|
||||
|
NamespaceDeclarationSyntax GenerateEnums(NamespaceDeclarationSyntax ns) |
||||
|
{ |
||||
|
return ns.AddMembers(_idl.Enums.Select(e => |
||||
|
EnumDeclaration(e.Name) |
||||
|
.WithModifiers(TokenList(Token(_visibility))) |
||||
|
.WithMembers(SeparatedList(e.Select(m => |
||||
|
{ |
||||
|
var member = EnumMemberDeclaration(m.Name); |
||||
|
if (m.Value != null) |
||||
|
return member.WithEqualsValue(EqualsValueClause(ParseExpression(m.Value))); |
||||
|
return member; |
||||
|
}))) |
||||
|
).ToArray()); |
||||
|
} |
||||
|
|
||||
|
NamespaceDeclarationSyntax GenerateStructs(NamespaceDeclarationSyntax ns) |
||||
|
{ |
||||
|
return ns.AddMembers(_idl.Structs.Select(e => |
||||
|
StructDeclaration(e.Name) |
||||
|
.WithModifiers(TokenList(Token(_visibility))) |
||||
|
.AddAttribute("System.Runtime.InteropServices.StructLayout", "System.Runtime.InteropServices.LayoutKind.Sequential") |
||||
|
.AddModifiers(Token(SyntaxKind.UnsafeKeyword)) |
||||
|
.WithMembers(new SyntaxList<MemberDeclarationSyntax>(SeparatedList(e.Select(m => |
||||
|
DeclareField(m.Type.ToString(), m.Name, SyntaxKind.PublicKeyword))))) |
||||
|
).ToArray()); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,116 @@ |
|||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using MicroComGenerator.Ast; |
||||
|
|
||||
|
namespace MicroComGenerator |
||||
|
{ |
||||
|
public class CppGen |
||||
|
{ |
||||
|
static string ConvertType(AstTypeNode type) |
||||
|
{ |
||||
|
var name = type.Name; |
||||
|
if (name == "byte") |
||||
|
name = "unsigned char"; |
||||
|
else if(name == "uint") |
||||
|
name = "unsigned int"; |
||||
|
return name + new string('*', type.PointerLevel); |
||||
|
} |
||||
|
|
||||
|
public static string GenerateCpp(AstIdlNode idl) |
||||
|
{ |
||||
|
var sb = new StringBuilder(); |
||||
|
var preamble = idl.GetAttributeOrDefault("cpp-preamble"); |
||||
|
if (preamble != null) |
||||
|
sb.AppendLine(preamble); |
||||
|
|
||||
|
foreach (var s in idl.Structs) |
||||
|
sb.AppendLine("struct " + s.Name + ";"); |
||||
|
|
||||
|
foreach (var s in idl.Interfaces) |
||||
|
sb.AppendLine("struct " + s.Name + ";"); |
||||
|
|
||||
|
foreach (var en in idl.Enums) |
||||
|
{ |
||||
|
sb.Append("enum "); |
||||
|
if (en.Attributes.Any(a => a.Name == "class-enum")) |
||||
|
sb.Append("class "); |
||||
|
sb.AppendLine(en.Name).AppendLine("{"); |
||||
|
|
||||
|
foreach (var m in en) |
||||
|
{ |
||||
|
sb.Append(" ").Append(m.Name); |
||||
|
if (m.Value != null) |
||||
|
sb.Append(" = ").Append(m.Value); |
||||
|
sb.AppendLine(","); |
||||
|
} |
||||
|
|
||||
|
sb.AppendLine("};"); |
||||
|
} |
||||
|
|
||||
|
foreach (var s in idl.Structs) |
||||
|
{ |
||||
|
sb.Append("struct ").AppendLine(s.Name).AppendLine("{"); |
||||
|
foreach (var m in s) |
||||
|
sb.Append(" ").Append(ConvertType(m.Type)).Append(" ").Append(m.Name).AppendLine(";"); |
||||
|
|
||||
|
sb.AppendLine("};"); |
||||
|
} |
||||
|
|
||||
|
foreach (var i in idl.Interfaces) |
||||
|
{ |
||||
|
var guidString = i.GetAttribute("uuid"); |
||||
|
var guid = Guid.Parse(guidString).ToString().Replace("-", ""); |
||||
|
|
||||
|
|
||||
|
sb.Append("COMINTERFACE(").Append(i.Name).Append(", ") |
||||
|
.Append(guid.Substring(0, 8)).Append(", ") |
||||
|
.Append(guid.Substring(8, 4)).Append(", ") |
||||
|
.Append(guid.Substring(12, 4)); |
||||
|
for (var c = 0; c < 8; c++) |
||||
|
{ |
||||
|
sb.Append(", ").Append(guid.Substring(16 + c * 2, 2)); |
||||
|
} |
||||
|
|
||||
|
sb.Append(") : "); |
||||
|
if (i.HasAttribute("cpp-virtual-inherits")) |
||||
|
sb.Append("virtual "); |
||||
|
sb.AppendLine(i.Inherits ?? "IUnknown") |
||||
|
.AppendLine("{"); |
||||
|
|
||||
|
foreach (var m in i) |
||||
|
{ |
||||
|
sb.Append(" ") |
||||
|
.Append("virtual ") |
||||
|
.Append(ConvertType(m.ReturnType)) |
||||
|
.Append(" ").Append(m.Name).Append(" ("); |
||||
|
if (m.Count == 0) |
||||
|
sb.AppendLine(") = 0;"); |
||||
|
else |
||||
|
{ |
||||
|
sb.AppendLine(); |
||||
|
for (var c = 0; c < m.Count; c++) |
||||
|
{ |
||||
|
var arg = m[c]; |
||||
|
sb.Append(" "); |
||||
|
if (arg.Attributes.Any(a => a.Name == "const")) |
||||
|
sb.Append("const "); |
||||
|
sb.Append(ConvertType(arg.Type)) |
||||
|
.Append(" ") |
||||
|
.Append(arg.Name); |
||||
|
if (c != m.Count - 1) |
||||
|
sb.Append(", "); |
||||
|
sb.AppendLine(); |
||||
|
} |
||||
|
|
||||
|
sb.AppendLine(" ) = 0;"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
sb.AppendLine("};"); |
||||
|
} |
||||
|
|
||||
|
return sb.ToString(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,97 @@ |
|||||
|
|
||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using Microsoft.CodeAnalysis; |
||||
|
using Microsoft.CodeAnalysis.CSharp; |
||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax; |
||||
|
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; |
||||
|
namespace MicroComGenerator |
||||
|
{ |
||||
|
public static class Extensions |
||||
|
{ |
||||
|
public static ClassDeclarationSyntax AddModifiers(this ClassDeclarationSyntax cl, params SyntaxKind[] modifiers) |
||||
|
{ |
||||
|
if (modifiers == null) |
||||
|
return cl; |
||||
|
return cl.AddModifiers(modifiers.Select(x => SyntaxFactory.Token(x)).ToArray()); |
||||
|
} |
||||
|
|
||||
|
public static MethodDeclarationSyntax AddModifiers(this MethodDeclarationSyntax cl, params SyntaxKind[] modifiers) |
||||
|
{ |
||||
|
if (modifiers == null) |
||||
|
return cl; |
||||
|
return cl.AddModifiers(modifiers.Select(x => SyntaxFactory.Token(x)).ToArray()); |
||||
|
} |
||||
|
|
||||
|
public static PropertyDeclarationSyntax AddModifiers(this PropertyDeclarationSyntax cl, params SyntaxKind[] modifiers) |
||||
|
{ |
||||
|
if (modifiers == null) |
||||
|
return cl; |
||||
|
return cl.AddModifiers(modifiers.Select(x => SyntaxFactory.Token(x)).ToArray()); |
||||
|
} |
||||
|
|
||||
|
public static ConstructorDeclarationSyntax AddModifiers(this ConstructorDeclarationSyntax cl, params SyntaxKind[] modifiers) |
||||
|
{ |
||||
|
if (modifiers == null) |
||||
|
return cl; |
||||
|
return cl.AddModifiers(modifiers.Select(x => SyntaxFactory.Token(x)).ToArray()); |
||||
|
} |
||||
|
|
||||
|
public static AccessorDeclarationSyntax AddModifiers(this AccessorDeclarationSyntax cl, params SyntaxKind[] modifiers) |
||||
|
{ |
||||
|
if (modifiers == null) |
||||
|
return cl; |
||||
|
return cl.AddModifiers(modifiers.Select(x => SyntaxFactory.Token(x)).ToArray()); |
||||
|
} |
||||
|
|
||||
|
public static string WithLowerFirst(this string s) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(s)) |
||||
|
return s; |
||||
|
return char.ToLowerInvariant(s[0]) + s.Substring(1); |
||||
|
} |
||||
|
|
||||
|
public static ExpressionSyntax MemberAccess(params string[] identifiers) |
||||
|
{ |
||||
|
if (identifiers == null || identifiers.Length == 0) |
||||
|
throw new ArgumentException(); |
||||
|
var expr = (ExpressionSyntax)IdentifierName(identifiers[0]); |
||||
|
for (var c = 1; c < identifiers.Length; c++) |
||||
|
expr = MemberAccess(expr, identifiers[c]); |
||||
|
return expr; |
||||
|
} |
||||
|
|
||||
|
public static ExpressionSyntax MemberAccess(ExpressionSyntax expr, params string[] identifiers) |
||||
|
{ |
||||
|
foreach (var i in identifiers) |
||||
|
expr = MemberAccess(expr, i); |
||||
|
return expr; |
||||
|
} |
||||
|
|
||||
|
public static MemberAccessExpressionSyntax MemberAccess(ExpressionSyntax expr, string identifier) => |
||||
|
MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, expr, IdentifierName(identifier)); |
||||
|
|
||||
|
public static ClassDeclarationSyntax WithBaseType(this ClassDeclarationSyntax cl, string bt) |
||||
|
{ |
||||
|
return cl.AddBaseListTypes(SimpleBaseType(SyntaxFactory.ParseTypeName(bt))); |
||||
|
} |
||||
|
|
||||
|
public static InterfaceDeclarationSyntax WithBaseType(this InterfaceDeclarationSyntax cl, string bt) |
||||
|
{ |
||||
|
return cl.AddBaseListTypes(SimpleBaseType(SyntaxFactory.ParseTypeName(bt))); |
||||
|
} |
||||
|
|
||||
|
public static T AddAttribute<T>(this T member, string attribute, params string[] args) where T : MemberDeclarationSyntax |
||||
|
{ |
||||
|
return (T)member.AddAttributeLists(AttributeList(SingletonSeparatedList( |
||||
|
Attribute(ParseName(attribute), AttributeArgumentList( |
||||
|
SeparatedList(args.Select(a => AttributeArgument(ParseExpression(a))))))))); |
||||
|
} |
||||
|
|
||||
|
public static string StripPrefix(this string s, string prefix) => string.IsNullOrEmpty(s) |
||||
|
? s |
||||
|
: s.StartsWith(prefix) |
||||
|
? s.Substring(prefix.Length) |
||||
|
: s; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
<PropertyGroup> |
||||
|
<OutputType>Exe</OutputType> |
||||
|
<TargetFramework>netcoreapp3.1</TargetFramework> |
||||
|
</PropertyGroup> |
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="CommandLineParser" Version="2.8.0" /> |
||||
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.7.0" /> |
||||
|
</ItemGroup> |
||||
|
</Project> |
||||
@ -0,0 +1,27 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace MicroComGenerator |
||||
|
{ |
||||
|
class ParseException : Exception |
||||
|
{ |
||||
|
public int Line { get; } |
||||
|
public int Position { get; } |
||||
|
|
||||
|
public ParseException(string message, int line, int position) : base(message) |
||||
|
{ |
||||
|
Line = line; |
||||
|
Position = position; |
||||
|
} |
||||
|
|
||||
|
public ParseException(string message, ref TokenParser parser) : this(message, parser.Line, parser.Position) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class CodeGenException : Exception |
||||
|
{ |
||||
|
public CodeGenException(string message) : base(message) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
using System; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using CommandLine; |
||||
|
|
||||
|
namespace MicroComGenerator |
||||
|
{ |
||||
|
class Program |
||||
|
{ |
||||
|
public class Options |
||||
|
{ |
||||
|
[Option('i', "input", Required = true, HelpText = "Input IDL file")] |
||||
|
public string Input { get; set; } |
||||
|
|
||||
|
[Option("cpp", Required = false, HelpText = "C++ output file")] |
||||
|
public string CppOutput { get; set; } |
||||
|
|
||||
|
[Option("cs", Required = false, HelpText = "C# output file")] |
||||
|
public string CSharpOutput { get; set; } |
||||
|
|
||||
|
} |
||||
|
|
||||
|
static int Main(string[] args) |
||||
|
{ |
||||
|
var p = Parser.Default.ParseArguments<Options>(args); |
||||
|
if (p is NotParsed<Options>) |
||||
|
{ |
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
var opts = ((Parsed<Options>)p).Value; |
||||
|
|
||||
|
var text = File.ReadAllText(opts.Input); |
||||
|
var ast = AstParser.Parse(text); |
||||
|
|
||||
|
if (opts.CppOutput != null) |
||||
|
File.WriteAllText(opts.CppOutput, CppGen.GenerateCpp(ast)); |
||||
|
if (opts.CSharpOutput != null) |
||||
|
File.WriteAllText(opts.CSharpOutput, new CSharpGen(ast).Generate()); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,417 @@ |
|||||
|
using System; |
||||
|
using System.Globalization; |
||||
|
using System.IO; |
||||
|
|
||||
|
namespace MicroComGenerator |
||||
|
{ |
||||
|
internal ref struct TokenParser |
||||
|
{ |
||||
|
private ReadOnlySpan<char> _s; |
||||
|
public int Position { get; private set; } |
||||
|
public int Line { get; private set; } |
||||
|
public TokenParser(ReadOnlySpan<char> s) |
||||
|
{ |
||||
|
_s = s; |
||||
|
Position = 0; |
||||
|
Line = 0; |
||||
|
} |
||||
|
|
||||
|
public void SkipWhitespace() |
||||
|
{ |
||||
|
while (true) |
||||
|
{ |
||||
|
if(_s.Length == 0) |
||||
|
return; |
||||
|
if (char.IsWhiteSpace(_s[0])) |
||||
|
Advance(1); |
||||
|
else if (_s[0] == '/' && _s.Length>1) |
||||
|
{ |
||||
|
if (_s[1] == '/') |
||||
|
SkipOneLineComment(); |
||||
|
else if (_s[1] == '*') |
||||
|
SkipMultiLineComment(); |
||||
|
else |
||||
|
return; |
||||
|
} |
||||
|
else |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void SkipOneLineComment() |
||||
|
{ |
||||
|
while (true) |
||||
|
{ |
||||
|
if (_s.Length > 0 && _s[0] != '\n' && _s[0] != '\r') |
||||
|
Advance(1); |
||||
|
else |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void SkipMultiLineComment() |
||||
|
{ |
||||
|
var l = Line; |
||||
|
var p = Position; |
||||
|
while (true) |
||||
|
{ |
||||
|
if (_s.Length == 0) |
||||
|
throw new ParseException("No matched */ found for /*", l, p); |
||||
|
|
||||
|
if (_s[0] == '*' && _s.Length > 1 && _s[1] == '/') |
||||
|
{ |
||||
|
Advance(2); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
Advance(1); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static bool IsAlphaNumeric(char ch) => (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || |
||||
|
(ch >= 'A' && ch <= 'Z'); |
||||
|
|
||||
|
public void Consume(char c) |
||||
|
{ |
||||
|
if (!TryConsume(c)) |
||||
|
throw new ParseException("Expected " + c, Line, Position); |
||||
|
} |
||||
|
public bool TryConsume(char c) |
||||
|
{ |
||||
|
SkipWhitespace(); |
||||
|
if (_s.Length == 0 || _s[0] != c) |
||||
|
return false; |
||||
|
|
||||
|
Advance(1); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public bool TryConsume(string s) |
||||
|
{ |
||||
|
SkipWhitespace(); |
||||
|
if (_s.Length < s.Length) |
||||
|
return false; |
||||
|
for (var c = 0; c < s.Length; c++) |
||||
|
{ |
||||
|
if (_s[c] != s[c]) |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
Advance(s.Length); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public bool TryConsumeAny(ReadOnlySpan<char> chars, out char token) |
||||
|
{ |
||||
|
SkipWhitespace(); |
||||
|
token = default; |
||||
|
if (_s.Length == 0) |
||||
|
return false; |
||||
|
|
||||
|
foreach (var c in chars) |
||||
|
{ |
||||
|
if (c == _s[0]) |
||||
|
{ |
||||
|
token = c; |
||||
|
Advance(1); |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public bool TryParseKeyword(string keyword) |
||||
|
{ |
||||
|
SkipWhitespace(); |
||||
|
if (keyword.Length > _s.Length) |
||||
|
return false; |
||||
|
for(var c=0; c<keyword.Length;c++) |
||||
|
if (keyword[c] != _s[c]) |
||||
|
return false; |
||||
|
|
||||
|
if (_s.Length > keyword.Length && IsAlphaNumeric(_s[keyword.Length])) |
||||
|
return false; |
||||
|
|
||||
|
Advance(keyword.Length); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public bool TryParseKeywordLowerCase(string keywordInLowerCase) |
||||
|
{ |
||||
|
SkipWhitespace(); |
||||
|
if (keywordInLowerCase.Length > _s.Length) |
||||
|
return false; |
||||
|
for(var c=0; c<keywordInLowerCase.Length;c++) |
||||
|
if (keywordInLowerCase[c] != char.ToLowerInvariant(_s[c])) |
||||
|
return false; |
||||
|
|
||||
|
if (_s.Length > keywordInLowerCase.Length && IsAlphaNumeric(_s[keywordInLowerCase.Length])) |
||||
|
return false; |
||||
|
|
||||
|
Advance(keywordInLowerCase.Length); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public void Advance(int c) |
||||
|
{ |
||||
|
while (c > 0) |
||||
|
{ |
||||
|
if (_s[0] == '\n') |
||||
|
{ |
||||
|
Line++; |
||||
|
Position = 0; |
||||
|
} |
||||
|
else |
||||
|
Position++; |
||||
|
|
||||
|
_s = _s.Slice(1); |
||||
|
c--; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public int Length => _s.Length; |
||||
|
public bool Eof |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
SkipWhitespace(); |
||||
|
return Length == 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public char Peek |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if (_s.Length == 0) |
||||
|
throw new ParseException("Unexpected EOF", Line, Position); |
||||
|
return _s[0]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public string ParseIdentifier(ReadOnlySpan<char> extraValidChars) |
||||
|
{ |
||||
|
if (!TryParseIdentifier(extraValidChars, out var ident)) |
||||
|
throw new ParseException("Identifier expected", Line, Position); |
||||
|
return ident.ToString(); |
||||
|
} |
||||
|
|
||||
|
public string ParseIdentifier() |
||||
|
{ |
||||
|
if (!TryParseIdentifier(out var ident)) |
||||
|
throw new ParseException("Identifier expected", Line, Position); |
||||
|
return ident.ToString(); |
||||
|
} |
||||
|
|
||||
|
public bool TryParseIdentifier(ReadOnlySpan<char> extraValidChars, out ReadOnlySpan<char> res) |
||||
|
{ |
||||
|
res = ReadOnlySpan<char>.Empty; |
||||
|
SkipWhitespace(); |
||||
|
if (_s.Length == 0) |
||||
|
return false; |
||||
|
var first = _s[0]; |
||||
|
if (!((first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z') || first == '_')) |
||||
|
return false; |
||||
|
int len = 1; |
||||
|
for (var c = 1; c < _s.Length; c++) |
||||
|
{ |
||||
|
var ch = _s[c]; |
||||
|
if (IsAlphaNumeric(ch) || ch == '_') |
||||
|
len++; |
||||
|
else |
||||
|
{ |
||||
|
var found = false; |
||||
|
foreach(var vc in extraValidChars) |
||||
|
if (vc == ch) |
||||
|
{ |
||||
|
found = true; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
if (found) |
||||
|
len++; |
||||
|
else |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
res = _s.Slice(0, len); |
||||
|
Advance(len); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public bool TryParseIdentifier(out ReadOnlySpan<char> res) |
||||
|
{ |
||||
|
res = ReadOnlySpan<char>.Empty; |
||||
|
SkipWhitespace(); |
||||
|
if (_s.Length == 0) |
||||
|
return false; |
||||
|
var first = _s[0]; |
||||
|
if (!((first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z') || first == '_')) |
||||
|
return false; |
||||
|
int len = 1; |
||||
|
for (var c = 1; c < _s.Length; c++) |
||||
|
{ |
||||
|
var ch = _s[c]; |
||||
|
if (IsAlphaNumeric(ch) || ch == '_') |
||||
|
len++; |
||||
|
else |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
res = _s.Slice(0, len); |
||||
|
Advance(len); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public string ReadToEol() |
||||
|
{ |
||||
|
var initial = _s; |
||||
|
var len = 0; |
||||
|
while (true) |
||||
|
{ |
||||
|
if (_s.Length > 0 && _s[0] != '\n' && _s[0] != '\r') |
||||
|
{ |
||||
|
len++; |
||||
|
Advance(1); |
||||
|
} |
||||
|
else |
||||
|
return initial.Slice(0, len).ToString(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public string ReadTo(char c) |
||||
|
{ |
||||
|
var initial = _s; |
||||
|
var len = 0; |
||||
|
var l = Line; |
||||
|
var p = Position; |
||||
|
while (true) |
||||
|
{ |
||||
|
if (_s.Length == 0) |
||||
|
throw new ParseException("Expected " + c + " before EOF", l, p); |
||||
|
|
||||
|
if (_s[0] != c) |
||||
|
{ |
||||
|
len++; |
||||
|
Advance(1); |
||||
|
} |
||||
|
else |
||||
|
return initial.Slice(0, len).ToString(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public string ReadToAny(ReadOnlySpan<char> chars) |
||||
|
{ |
||||
|
var initial = _s; |
||||
|
var len = 0; |
||||
|
var l = Line; |
||||
|
var p = Position; |
||||
|
while (true) |
||||
|
{ |
||||
|
if (_s.Length == 0) |
||||
|
throw new ParseException("Expected any of '" + chars.ToString() + "' before EOF", l, p); |
||||
|
|
||||
|
var foundTerminator = false; |
||||
|
foreach (var term in chars) |
||||
|
{ |
||||
|
if (_s[0] == term) |
||||
|
{ |
||||
|
foundTerminator = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (!foundTerminator) |
||||
|
{ |
||||
|
len++; |
||||
|
Advance(1); |
||||
|
} |
||||
|
else |
||||
|
return initial.Slice(0, len).ToString(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public bool TryParseCall(out ReadOnlySpan<char> res) |
||||
|
{ |
||||
|
res = ReadOnlySpan<char>.Empty; |
||||
|
SkipWhitespace(); |
||||
|
if (_s.Length == 0) |
||||
|
return false; |
||||
|
var first = _s[0]; |
||||
|
if (!((first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z'))) |
||||
|
return false; |
||||
|
int len = 1; |
||||
|
for (var c = 1; c < _s.Length; c++) |
||||
|
{ |
||||
|
var ch = _s[c]; |
||||
|
if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch<= 'Z') || ch == '.') |
||||
|
len++; |
||||
|
else |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
res = _s.Slice(0, len); |
||||
|
|
||||
|
// Find '('
|
||||
|
for (var c = len; c < _s.Length; c++) |
||||
|
{ |
||||
|
if(char.IsWhiteSpace(_s[c])) |
||||
|
continue; |
||||
|
if(_s[c]=='(') |
||||
|
{ |
||||
|
Advance(c + 1); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
public bool TryParseFloat(out float res) |
||||
|
{ |
||||
|
res = 0; |
||||
|
SkipWhitespace(); |
||||
|
if (_s.Length == 0) |
||||
|
return false; |
||||
|
|
||||
|
var len = 0; |
||||
|
var dotCount = 0; |
||||
|
for (var c = 0; c < _s.Length; c++) |
||||
|
{ |
||||
|
var ch = _s[c]; |
||||
|
if (ch >= '0' && ch <= '9') |
||||
|
len = c + 1; |
||||
|
else if (ch == '.' && dotCount == 0) |
||||
|
{ |
||||
|
len = c + 1; |
||||
|
dotCount++; |
||||
|
} |
||||
|
else |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
var span = _s.Slice(0, len); |
||||
|
|
||||
|
#if NETSTANDARD2_0
|
||||
|
if (!float.TryParse(span.ToString(), NumberStyles.Number, CultureInfo.InvariantCulture, out res)) |
||||
|
return false; |
||||
|
#else
|
||||
|
if (!float.TryParse(span, NumberStyles.Number, CultureInfo.InvariantCulture, out res)) |
||||
|
return false; |
||||
|
#endif
|
||||
|
Advance(len); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public override string ToString() => _s.ToString(); |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
build |
||||
|
node_modules |
||||
|
.nyc_output |
||||
@ -0,0 +1,94 @@ |
|||||
|
import { describe } from 'mocha'; |
||||
|
import { expect } from 'chai'; |
||||
|
import { Mock } from "moq.ts"; |
||||
|
import { MouseEvent, WheelEvent } from "react"; |
||||
|
import { InputModifiers } from "../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/InputModifiers"; |
||||
|
import { MouseButton } from "../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/MouseButton"; |
||||
|
import { PointerMovedEventMessage } from "../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/PointerMovedEventMessage"; |
||||
|
import { PointerPressedEventMessage } from "../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/PointerPressedEventMessage"; |
||||
|
import { PointerReleasedEventMessage } from "../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/PointerReleasedEventMessage"; |
||||
|
import { ScrollEventMessage } from "../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/ScrollEventMessage"; |
||||
|
import { getModifiers, getMouseButton } from '../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/MouseEventHelpers'; |
||||
|
|
||||
|
describe("Input event tests", () => { |
||||
|
describe("Helpers", () => { |
||||
|
it("getModifiers", () => { |
||||
|
const event = new Mock<MouseEvent>() |
||||
|
.setup(x => x.altKey).returns(false) |
||||
|
.setup(x => x.ctrlKey).returns(true) |
||||
|
.setup(x => x.shiftKey).returns(false) |
||||
|
.setup(x => x.metaKey).returns(false) |
||||
|
.setup(x => x.buttons).returns(1) |
||||
|
.object() |
||||
|
var actual = getModifiers(event) |
||||
|
|
||||
|
expect(actual) |
||||
|
.eql([InputModifiers.Control, InputModifiers.LeftMouseButton]) |
||||
|
}) |
||||
|
it("getMouseButton", () => { |
||||
|
const event = new Mock<MouseEvent>() |
||||
|
.setup(x => x.button).returns(1) |
||||
|
.object() |
||||
|
var actual = getMouseButton(event) |
||||
|
|
||||
|
expect(actual) |
||||
|
.equal(MouseButton.Middle) |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
describe("Messages", () => { |
||||
|
const x = .3 |
||||
|
const y = .42 |
||||
|
const modifiers = "0,1,2,3,4,5,6" |
||||
|
|
||||
|
const button = "1" |
||||
|
|
||||
|
const deltaX = -3. |
||||
|
const deltaY = -3. |
||||
|
|
||||
|
const mouseEvent = new Mock<MouseEvent>() |
||||
|
.setup(x => x.altKey).returns(true) |
||||
|
.setup(x => x.ctrlKey).returns(true) |
||||
|
.setup(x => x.shiftKey).returns(true) |
||||
|
.setup(x => x.metaKey).returns(true) |
||||
|
.setup(x => x.buttons).returns(7) |
||||
|
.setup(x => x.button).returns(0) |
||||
|
.setup(x => x.clientX).returns(x) |
||||
|
.setup(x => x.clientY).returns(y) |
||||
|
.object() |
||||
|
|
||||
|
it("PointerMovedEventMessage", () => { |
||||
|
const message = new PointerMovedEventMessage(mouseEvent) |
||||
|
expect(message.toString()) |
||||
|
.equal(`pointer-moved:${modifiers}:${x}:${y}`) |
||||
|
}) |
||||
|
it("PointerPressedEventMessage", () => { |
||||
|
const message = new PointerPressedEventMessage(mouseEvent) |
||||
|
expect(message.toString()) |
||||
|
.equal(`pointer-pressed:${modifiers}:${x}:${y}:${button}`) |
||||
|
}) |
||||
|
it("PointerReleasedEventMessage", () => { |
||||
|
const message = new PointerReleasedEventMessage(mouseEvent) |
||||
|
expect(message.toString()) |
||||
|
.equal(`pointer-released:${modifiers}:${x}:${y}:${button}`) |
||||
|
}) |
||||
|
|
||||
|
it("ScrollEventMessage", () => { |
||||
|
const wheelEvent = new Mock<WheelEvent>() |
||||
|
.setup(x => x.altKey).returns(true) |
||||
|
.setup(x => x.ctrlKey).returns(true) |
||||
|
.setup(x => x.shiftKey).returns(true) |
||||
|
.setup(x => x.metaKey).returns(true) |
||||
|
.setup(x => x.buttons).returns(7) |
||||
|
.setup(x => x.clientX).returns(x) |
||||
|
.setup(x => x.clientY).returns(y) |
||||
|
.setup(x => x.deltaX).returns(-deltaX) |
||||
|
.setup(x => x.deltaY).returns(-deltaY) |
||||
|
.object() |
||||
|
const message = new ScrollEventMessage(wheelEvent) |
||||
|
|
||||
|
expect(message.toString()) |
||||
|
.equal(`scroll:${modifiers}:${x}:${y}:${deltaX}:${deltaY}`) |
||||
|
}) |
||||
|
}) |
||||
|
}) |
||||
File diff suppressed because it is too large
@ -0,0 +1,26 @@ |
|||||
|
{ |
||||
|
"name": "simple-test", |
||||
|
"version": "1.0.0", |
||||
|
"main": "index.js", |
||||
|
"scripts": { |
||||
|
"test": "mocha -r ts-node/register ./**/*Tests.ts", |
||||
|
"coverage": "nyc -r text -e .ts -x \"./*Tests.ts\" npm run test" |
||||
|
}, |
||||
|
"type": "module", |
||||
|
"keywords": [], |
||||
|
"author": "", |
||||
|
"license": "MIT", |
||||
|
"dependencies": {}, |
||||
|
"devDependencies": { |
||||
|
"@types/chai": "4.2.12", |
||||
|
"@types/mocha": "8.0.3", |
||||
|
"@types/react": "^16.3.14", |
||||
|
"chai": "^4.2.0", |
||||
|
"mocha": "^8.1.3", |
||||
|
"moq.ts": "^6.4.0", |
||||
|
"nyc": "^15.1.0", |
||||
|
"react": "^16.3.2", |
||||
|
"ts-node": "^9.0.0", |
||||
|
"typescript": "^4.0.2" |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue