44 changed files with 6366 additions and 0 deletions
@ -0,0 +1,4 @@ |
|||
build |
|||
|
|||
Avalonia.Native.OSX.xcodeproj/xcuserdata |
|||
Avalonia.Native.OSX.xcodeproj/project.xcworkspace/xcuserdata |
|||
@ -0,0 +1,328 @@ |
|||
// !$*UTF8*$! |
|||
{ |
|||
archiveVersion = 1; |
|||
classes = { |
|||
}; |
|||
objectVersion = 46; |
|||
objects = { |
|||
|
|||
/* Begin PBXBuildFile section */ |
|||
37A517B32159597E00FBA241 /* Screens.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A517B22159597E00FBA241 /* Screens.mm */; }; |
|||
37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C09D8721580FE4006A6758 /* SystemDialogs.mm */; }; |
|||
37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37E2330E21583241000CB7E2 /* KeyTransform.mm */; }; |
|||
5B21A982216530F500CEE36E /* cursor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B21A981216530F500CEE36E /* cursor.mm */; }; |
|||
5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; }; |
|||
AB00E4F72147CA920032A60A /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB00E4F62147CA920032A60A /* main.mm */; }; |
|||
AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB1E522B217613570091CD71 /* OpenGL.framework */; }; |
|||
AB573DC4217605E400D389A2 /* gl.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB573DC3217605E400D389A2 /* gl.mm */; }; |
|||
AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB661C1D2148230F00291242 /* AppKit.framework */; }; |
|||
AB661C202148286E00291242 /* window.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB661C1F2148286E00291242 /* window.mm */; }; |
|||
AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */; }; |
|||
/* End PBXBuildFile section */ |
|||
|
|||
/* Begin PBXFileReference section */ |
|||
379860FE214DA0C000CD0246 /* KeyTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyTransform.h; sourceTree = "<group>"; }; |
|||
37A4E71A2178846A00EACBCD /* headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = headers; path = ../Avalonia.Native/headers; sourceTree = "<group>"; }; |
|||
37A517B22159597E00FBA241 /* Screens.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Screens.mm; sourceTree = "<group>"; }; |
|||
37C09D8721580FE4006A6758 /* SystemDialogs.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SystemDialogs.mm; sourceTree = "<group>"; }; |
|||
37C09D8A21581EF2006A6758 /* window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = window.h; sourceTree = "<group>"; }; |
|||
37E2330E21583241000CB7E2 /* KeyTransform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyTransform.mm; sourceTree = "<group>"; }; |
|||
5B21A981216530F500CEE36E /* cursor.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cursor.mm; sourceTree = "<group>"; }; |
|||
5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard.mm; sourceTree = "<group>"; }; |
|||
5BF943652167AD1D009CAE35 /* cursor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = "<group>"; }; |
|||
AB00E4F62147CA920032A60A /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; }; |
|||
AB1E522B217613570091CD71 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; |
|||
AB573DC3217605E400D389A2 /* gl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = gl.mm; sourceTree = "<group>"; }; |
|||
AB661C1D2148230F00291242 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; |
|||
AB661C1F2148286E00291242 /* window.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = window.mm; sourceTree = "<group>"; }; |
|||
AB661C212148288600291242 /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; }; |
|||
AB7A61EF2147C815003C5833 /* libAvalonia.Native.OSX.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libAvalonia.Native.OSX.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; |
|||
AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = platformthreading.mm; sourceTree = "<group>"; }; |
|||
/* End PBXFileReference section */ |
|||
|
|||
/* Begin PBXFrameworksBuildPhase section */ |
|||
AB7A61EC2147C814003C5833 /* Frameworks */ = { |
|||
isa = PBXFrameworksBuildPhase; |
|||
buildActionMask = 2147483647; |
|||
files = ( |
|||
AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */, |
|||
AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */, |
|||
); |
|||
runOnlyForDeploymentPostprocessing = 0; |
|||
}; |
|||
/* End PBXFrameworksBuildPhase section */ |
|||
|
|||
/* Begin PBXGroup section */ |
|||
AB661C1C2148230E00291242 /* Frameworks */ = { |
|||
isa = PBXGroup; |
|||
children = ( |
|||
AB1E522B217613570091CD71 /* OpenGL.framework */, |
|||
AB661C1D2148230F00291242 /* AppKit.framework */, |
|||
); |
|||
name = Frameworks; |
|||
sourceTree = "<group>"; |
|||
}; |
|||
AB7A61E62147C814003C5833 = { |
|||
isa = PBXGroup; |
|||
children = ( |
|||
37A4E71A2178846A00EACBCD /* headers */, |
|||
AB573DC3217605E400D389A2 /* gl.mm */, |
|||
5BF943652167AD1D009CAE35 /* cursor.h */, |
|||
5B21A981216530F500CEE36E /* cursor.mm */, |
|||
5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */, |
|||
AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */, |
|||
AB661C212148288600291242 /* common.h */, |
|||
379860FE214DA0C000CD0246 /* KeyTransform.h */, |
|||
37E2330E21583241000CB7E2 /* KeyTransform.mm */, |
|||
AB661C1F2148286E00291242 /* window.mm */, |
|||
37C09D8A21581EF2006A6758 /* window.h */, |
|||
AB00E4F62147CA920032A60A /* main.mm */, |
|||
37A517B22159597E00FBA241 /* Screens.mm */, |
|||
37C09D8721580FE4006A6758 /* SystemDialogs.mm */, |
|||
AB7A61F02147C815003C5833 /* Products */, |
|||
AB661C1C2148230E00291242 /* Frameworks */, |
|||
); |
|||
sourceTree = "<group>"; |
|||
}; |
|||
AB7A61F02147C815003C5833 /* Products */ = { |
|||
isa = PBXGroup; |
|||
children = ( |
|||
AB7A61EF2147C815003C5833 /* libAvalonia.Native.OSX.dylib */, |
|||
); |
|||
name = Products; |
|||
sourceTree = "<group>"; |
|||
}; |
|||
/* End PBXGroup section */ |
|||
|
|||
/* Begin PBXHeadersBuildPhase section */ |
|||
AB7A61ED2147C814003C5833 /* Headers */ = { |
|||
isa = PBXHeadersBuildPhase; |
|||
buildActionMask = 2147483647; |
|||
files = ( |
|||
); |
|||
runOnlyForDeploymentPostprocessing = 0; |
|||
}; |
|||
/* End PBXHeadersBuildPhase section */ |
|||
|
|||
/* Begin PBXNativeTarget section */ |
|||
AB7A61EE2147C814003C5833 /* Avalonia.Native.OSX */ = { |
|||
isa = PBXNativeTarget; |
|||
buildConfigurationList = AB7A61F82147C815003C5833 /* Build configuration list for PBXNativeTarget "Avalonia.Native.OSX" */; |
|||
buildPhases = ( |
|||
AB7A61EB2147C814003C5833 /* Sources */, |
|||
AB7A61EC2147C814003C5833 /* Frameworks */, |
|||
AB7A61ED2147C814003C5833 /* Headers */, |
|||
); |
|||
buildRules = ( |
|||
); |
|||
dependencies = ( |
|||
); |
|||
name = Avalonia.Native.OSX; |
|||
productName = Avalonia.Native.OSX; |
|||
productReference = AB7A61EF2147C815003C5833 /* libAvalonia.Native.OSX.dylib */; |
|||
productType = "com.apple.product-type.library.dynamic"; |
|||
}; |
|||
/* End PBXNativeTarget section */ |
|||
|
|||
/* Begin PBXProject section */ |
|||
AB7A61E72147C814003C5833 /* Project object */ = { |
|||
isa = PBXProject; |
|||
attributes = { |
|||
LastUpgradeCheck = 1000; |
|||
ORGANIZATIONNAME = Avalonia; |
|||
TargetAttributes = { |
|||
AB7A61EE2147C814003C5833 = { |
|||
CreatedOnToolsVersion = 8.3.2; |
|||
ProvisioningStyle = Automatic; |
|||
}; |
|||
}; |
|||
}; |
|||
buildConfigurationList = AB7A61EA2147C814003C5833 /* Build configuration list for PBXProject "Avalonia.Native.OSX" */; |
|||
compatibilityVersion = "Xcode 3.2"; |
|||
developmentRegion = English; |
|||
hasScannedForEncodings = 0; |
|||
knownRegions = ( |
|||
en, |
|||
); |
|||
mainGroup = AB7A61E62147C814003C5833; |
|||
productRefGroup = AB7A61F02147C815003C5833 /* Products */; |
|||
projectDirPath = ""; |
|||
projectRoot = ""; |
|||
targets = ( |
|||
AB7A61EE2147C814003C5833 /* Avalonia.Native.OSX */, |
|||
); |
|||
}; |
|||
/* End PBXProject section */ |
|||
|
|||
/* Begin PBXSourcesBuildPhase section */ |
|||
AB7A61EB2147C814003C5833 /* Sources */ = { |
|||
isa = PBXSourcesBuildPhase; |
|||
buildActionMask = 2147483647; |
|||
files = ( |
|||
5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */, |
|||
5B21A982216530F500CEE36E /* cursor.mm in Sources */, |
|||
AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */, |
|||
37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */, |
|||
37A517B32159597E00FBA241 /* Screens.mm in Sources */, |
|||
AB00E4F72147CA920032A60A /* main.mm in Sources */, |
|||
37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */, |
|||
AB573DC4217605E400D389A2 /* gl.mm in Sources */, |
|||
AB661C202148286E00291242 /* window.mm in Sources */, |
|||
); |
|||
runOnlyForDeploymentPostprocessing = 0; |
|||
}; |
|||
/* End PBXSourcesBuildPhase section */ |
|||
|
|||
/* Begin XCBuildConfiguration section */ |
|||
AB7A61F62147C815003C5833 /* Debug */ = { |
|||
isa = XCBuildConfiguration; |
|||
buildSettings = { |
|||
ALWAYS_SEARCH_USER_PATHS = NO; |
|||
CLANG_ANALYZER_NONNULL = YES; |
|||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; |
|||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; |
|||
CLANG_CXX_LIBRARY = "libc++"; |
|||
CLANG_ENABLE_MODULES = YES; |
|||
CLANG_ENABLE_OBJC_ARC = YES; |
|||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; |
|||
CLANG_WARN_BOOL_CONVERSION = YES; |
|||
CLANG_WARN_COMMA = YES; |
|||
CLANG_WARN_CONSTANT_CONVERSION = YES; |
|||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; |
|||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; |
|||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES; |
|||
CLANG_WARN_EMPTY_BODY = YES; |
|||
CLANG_WARN_ENUM_CONVERSION = YES; |
|||
CLANG_WARN_INFINITE_RECURSION = YES; |
|||
CLANG_WARN_INT_CONVERSION = YES; |
|||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; |
|||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; |
|||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; |
|||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; |
|||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; |
|||
CLANG_WARN_STRICT_PROTOTYPES = YES; |
|||
CLANG_WARN_SUSPICIOUS_MOVE = YES; |
|||
CLANG_WARN_UNREACHABLE_CODE = YES; |
|||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; |
|||
CODE_SIGN_IDENTITY = "-"; |
|||
COPY_PHASE_STRIP = NO; |
|||
DEBUG_INFORMATION_FORMAT = dwarf; |
|||
ENABLE_STRICT_OBJC_MSGSEND = YES; |
|||
ENABLE_TESTABILITY = YES; |
|||
GCC_C_LANGUAGE_STANDARD = gnu99; |
|||
GCC_DYNAMIC_NO_PIC = NO; |
|||
GCC_NO_COMMON_BLOCKS = YES; |
|||
GCC_OPTIMIZATION_LEVEL = 0; |
|||
GCC_PREPROCESSOR_DEFINITIONS = ( |
|||
"DEBUG=1", |
|||
"$(inherited)", |
|||
); |
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; |
|||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; |
|||
GCC_WARN_UNDECLARED_SELECTOR = YES; |
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
|||
GCC_WARN_UNUSED_FUNCTION = YES; |
|||
GCC_WARN_UNUSED_VARIABLE = YES; |
|||
MACOSX_DEPLOYMENT_TARGET = 10.12; |
|||
MTL_ENABLE_DEBUG_INFO = YES; |
|||
ONLY_ACTIVE_ARCH = YES; |
|||
SDKROOT = macosx; |
|||
}; |
|||
name = Debug; |
|||
}; |
|||
AB7A61F72147C815003C5833 /* Release */ = { |
|||
isa = XCBuildConfiguration; |
|||
buildSettings = { |
|||
ALWAYS_SEARCH_USER_PATHS = NO; |
|||
CLANG_ANALYZER_NONNULL = YES; |
|||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; |
|||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; |
|||
CLANG_CXX_LIBRARY = "libc++"; |
|||
CLANG_ENABLE_MODULES = YES; |
|||
CLANG_ENABLE_OBJC_ARC = YES; |
|||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; |
|||
CLANG_WARN_BOOL_CONVERSION = YES; |
|||
CLANG_WARN_COMMA = YES; |
|||
CLANG_WARN_CONSTANT_CONVERSION = YES; |
|||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; |
|||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; |
|||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES; |
|||
CLANG_WARN_EMPTY_BODY = YES; |
|||
CLANG_WARN_ENUM_CONVERSION = YES; |
|||
CLANG_WARN_INFINITE_RECURSION = YES; |
|||
CLANG_WARN_INT_CONVERSION = YES; |
|||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; |
|||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; |
|||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; |
|||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; |
|||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; |
|||
CLANG_WARN_STRICT_PROTOTYPES = YES; |
|||
CLANG_WARN_SUSPICIOUS_MOVE = YES; |
|||
CLANG_WARN_UNREACHABLE_CODE = YES; |
|||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; |
|||
CODE_SIGN_IDENTITY = "-"; |
|||
COPY_PHASE_STRIP = NO; |
|||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; |
|||
ENABLE_NS_ASSERTIONS = NO; |
|||
ENABLE_STRICT_OBJC_MSGSEND = YES; |
|||
GCC_C_LANGUAGE_STANDARD = gnu99; |
|||
GCC_NO_COMMON_BLOCKS = YES; |
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; |
|||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; |
|||
GCC_WARN_UNDECLARED_SELECTOR = YES; |
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
|||
GCC_WARN_UNUSED_FUNCTION = YES; |
|||
GCC_WARN_UNUSED_VARIABLE = YES; |
|||
MACOSX_DEPLOYMENT_TARGET = 10.12; |
|||
MTL_ENABLE_DEBUG_INFO = NO; |
|||
SDKROOT = macosx; |
|||
}; |
|||
name = Release; |
|||
}; |
|||
AB7A61F92147C815003C5833 /* Debug */ = { |
|||
isa = XCBuildConfiguration; |
|||
buildSettings = { |
|||
DYLIB_COMPATIBILITY_VERSION = 1; |
|||
DYLIB_CURRENT_VERSION = 1; |
|||
EXECUTABLE_PREFIX = lib; |
|||
HEADER_SEARCH_PATHS = ../Avalonia.Native/headers; |
|||
PRODUCT_NAME = "$(TARGET_NAME)"; |
|||
}; |
|||
name = Debug; |
|||
}; |
|||
AB7A61FA2147C815003C5833 /* Release */ = { |
|||
isa = XCBuildConfiguration; |
|||
buildSettings = { |
|||
DYLIB_COMPATIBILITY_VERSION = 1; |
|||
DYLIB_CURRENT_VERSION = 1; |
|||
EXECUTABLE_PREFIX = lib; |
|||
HEADER_SEARCH_PATHS = ../Avalonia.Native/headers; |
|||
PRODUCT_NAME = "$(TARGET_NAME)"; |
|||
}; |
|||
name = Release; |
|||
}; |
|||
/* End XCBuildConfiguration section */ |
|||
|
|||
/* Begin XCConfigurationList section */ |
|||
AB7A61EA2147C814003C5833 /* Build configuration list for PBXProject "Avalonia.Native.OSX" */ = { |
|||
isa = XCConfigurationList; |
|||
buildConfigurations = ( |
|||
AB7A61F62147C815003C5833 /* Debug */, |
|||
AB7A61F72147C815003C5833 /* Release */, |
|||
); |
|||
defaultConfigurationIsVisible = 0; |
|||
defaultConfigurationName = Release; |
|||
}; |
|||
AB7A61F82147C815003C5833 /* Build configuration list for PBXNativeTarget "Avalonia.Native.OSX" */ = { |
|||
isa = XCConfigurationList; |
|||
buildConfigurations = ( |
|||
AB7A61F92147C815003C5833 /* Debug */, |
|||
AB7A61FA2147C815003C5833 /* Release */, |
|||
); |
|||
defaultConfigurationIsVisible = 0; |
|||
defaultConfigurationName = Release; |
|||
}; |
|||
/* End XCConfigurationList section */ |
|||
}; |
|||
rootObject = AB7A61E72147C814003C5833 /* Project object */; |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<Workspace |
|||
version = "1.0"> |
|||
<FileRef |
|||
location = "self:Avalonia.Native.OSX.xcodeproj"> |
|||
</FileRef> |
|||
</Workspace> |
|||
@ -0,0 +1,91 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<Scheme |
|||
LastUpgradeVersion = "1000" |
|||
version = "1.3"> |
|||
<BuildAction |
|||
parallelizeBuildables = "YES" |
|||
buildImplicitDependencies = "YES"> |
|||
<BuildActionEntries> |
|||
<BuildActionEntry |
|||
buildForTesting = "YES" |
|||
buildForRunning = "YES" |
|||
buildForProfiling = "YES" |
|||
buildForArchiving = "YES" |
|||
buildForAnalyzing = "YES"> |
|||
<BuildableReference |
|||
BuildableIdentifier = "primary" |
|||
BlueprintIdentifier = "AB7A61EE2147C814003C5833" |
|||
BuildableName = "libAvalonia.Native.OSX.dylib" |
|||
BlueprintName = "Avalonia.Native.OSX" |
|||
ReferencedContainer = "container:Avalonia.Native.OSX.xcodeproj"> |
|||
</BuildableReference> |
|||
</BuildActionEntry> |
|||
</BuildActionEntries> |
|||
</BuildAction> |
|||
<TestAction |
|||
buildConfiguration = "Debug" |
|||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
|||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
|||
shouldUseLaunchSchemeArgsEnv = "YES"> |
|||
<Testables> |
|||
</Testables> |
|||
<AdditionalOptions> |
|||
</AdditionalOptions> |
|||
</TestAction> |
|||
<LaunchAction |
|||
buildConfiguration = "Debug" |
|||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
|||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
|||
launchStyle = "0" |
|||
useCustomWorkingDirectory = "YES" |
|||
customWorkingDirectory = "$PROJECT_DIR/../../samples/ControlCatalog" |
|||
ignoresPersistentStateOnLaunch = "NO" |
|||
debugDocumentVersioning = "YES" |
|||
debugServiceExtension = "internal" |
|||
allowLocationSimulation = "YES"> |
|||
<PathRunnable |
|||
runnableDebuggingMode = "0" |
|||
FilePath = "/usr/local/share/dotnet/dotnet"> |
|||
</PathRunnable> |
|||
<MacroExpansion> |
|||
<BuildableReference |
|||
BuildableIdentifier = "primary" |
|||
BlueprintIdentifier = "AB7A61EE2147C814003C5833" |
|||
BuildableName = "libAvalonia.Native.OSX.dylib" |
|||
BlueprintName = "Avalonia.Native.OSX" |
|||
ReferencedContainer = "container:Avalonia.Native.OSX.xcodeproj"> |
|||
</BuildableReference> |
|||
</MacroExpansion> |
|||
<CommandLineArguments> |
|||
<CommandLineArgument |
|||
argument = "bin/Debug/netcoreapp2.0/ControlCatalog.dll" |
|||
isEnabled = "YES"> |
|||
</CommandLineArgument> |
|||
</CommandLineArguments> |
|||
<AdditionalOptions> |
|||
</AdditionalOptions> |
|||
</LaunchAction> |
|||
<ProfileAction |
|||
buildConfiguration = "Release" |
|||
shouldUseLaunchSchemeArgsEnv = "YES" |
|||
savedToolIdentifier = "" |
|||
useCustomWorkingDirectory = "NO" |
|||
debugDocumentVersioning = "YES"> |
|||
<MacroExpansion> |
|||
<BuildableReference |
|||
BuildableIdentifier = "primary" |
|||
BlueprintIdentifier = "AB7A61EE2147C814003C5833" |
|||
BuildableName = "libAvalonia.Native.OSX.dylib" |
|||
BlueprintName = "Avalonia.Native.OSX" |
|||
ReferencedContainer = "container:Avalonia.Native.OSX.xcodeproj"> |
|||
</BuildableReference> |
|||
</MacroExpansion> |
|||
</ProfileAction> |
|||
<AnalyzeAction |
|||
buildConfiguration = "Debug"> |
|||
</AnalyzeAction> |
|||
<ArchiveAction |
|||
buildConfiguration = "Release" |
|||
revealArchiveInOrganizer = "YES"> |
|||
</ArchiveAction> |
|||
</Scheme> |
|||
@ -0,0 +1,12 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
#ifndef keytransform_h |
|||
#define keytransform_h |
|||
#include "common.h" |
|||
#include "key.h" |
|||
#include <map> |
|||
|
|||
extern std::map<int, AvnKey> s_KeyMap; |
|||
|
|||
#endif |
|||
@ -0,0 +1,241 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved. |
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information. |
|||
|
|||
#include "KeyTransform.h" |
|||
|
|||
const int kVK_ANSI_A = 0x00; |
|||
const int kVK_ANSI_S = 0x01; |
|||
const int kVK_ANSI_D = 0x02; |
|||
const int kVK_ANSI_F = 0x03; |
|||
const int kVK_ANSI_H = 0x04; |
|||
const int kVK_ANSI_G = 0x05; |
|||
const int kVK_ANSI_Z = 0x06; |
|||
const int kVK_ANSI_X = 0x07; |
|||
const int kVK_ANSI_C = 0x08; |
|||
const int kVK_ANSI_V = 0x09; |
|||
const int kVK_ANSI_B = 0x0B; |
|||
const int kVK_ANSI_Q = 0x0C; |
|||
const int kVK_ANSI_W = 0x0D; |
|||
const int kVK_ANSI_E = 0x0E; |
|||
const int kVK_ANSI_R = 0x0F; |
|||
const int kVK_ANSI_Y = 0x10; |
|||
const int kVK_ANSI_T = 0x11; |
|||
const int kVK_ANSI_1 = 0x12; |
|||
const int kVK_ANSI_2 = 0x13; |
|||
const int kVK_ANSI_3 = 0x14; |
|||
const int kVK_ANSI_4 = 0x15; |
|||
const int kVK_ANSI_6 = 0x16; |
|||
const int kVK_ANSI_5 = 0x17; |
|||
//const int kVK_ANSI_Equal = 0x18; |
|||
const int kVK_ANSI_9 = 0x19; |
|||
const int kVK_ANSI_7 = 0x1A; |
|||
const int kVK_ANSI_Minus = 0x1B; |
|||
const int kVK_ANSI_8 = 0x1C; |
|||
const int kVK_ANSI_0 = 0x1D; |
|||
const int kVK_ANSI_RightBracket = 0x1E; |
|||
const int kVK_ANSI_O = 0x1F; |
|||
const int kVK_ANSI_U = 0x20; |
|||
const int kVK_ANSI_LeftBracket = 0x21; |
|||
const int kVK_ANSI_I = 0x22; |
|||
const int kVK_ANSI_P = 0x23; |
|||
const int kVK_ANSI_L = 0x25; |
|||
const int kVK_ANSI_J = 0x26; |
|||
const int kVK_ANSI_Quote = 0x27; |
|||
const int kVK_ANSI_K = 0x28; |
|||
const int kVK_ANSI_Semicolon = 0x29; |
|||
const int kVK_ANSI_Backslash = 0x2A; |
|||
const int kVK_ANSI_Comma = 0x2B; |
|||
//const int kVK_ANSI_Slash = 0x2C; |
|||
const int kVK_ANSI_N = 0x2D; |
|||
const int kVK_ANSI_M = 0x2E; |
|||
const int kVK_ANSI_Period = 0x2F; |
|||
//const int kVK_ANSI_Grave = 0x32; |
|||
const int kVK_ANSI_KeypadDecimal = 0x41; |
|||
const int kVK_ANSI_KeypadMultiply = 0x43; |
|||
const int kVK_ANSI_KeypadPlus = 0x45; |
|||
const int kVK_ANSI_KeypadClear = 0x47; |
|||
const int kVK_ANSI_KeypadDivide = 0x4B; |
|||
const int kVK_ANSI_KeypadEnter = 0x4C; |
|||
const int kVK_ANSI_KeypadMinus = 0x4E; |
|||
//const int kVK_ANSI_KeypadEquals = 0x51; |
|||
const int kVK_ANSI_Keypad0 = 0x52; |
|||
const int kVK_ANSI_Keypad1 = 0x53; |
|||
const int kVK_ANSI_Keypad2 = 0x54; |
|||
const int kVK_ANSI_Keypad3 = 0x55; |
|||
const int kVK_ANSI_Keypad4 = 0x56; |
|||
const int kVK_ANSI_Keypad5 = 0x57; |
|||
const int kVK_ANSI_Keypad6 = 0x58; |
|||
const int kVK_ANSI_Keypad7 = 0x59; |
|||
const int kVK_ANSI_Keypad8 = 0x5B; |
|||
const int kVK_ANSI_Keypad9 = 0x5C; |
|||
const int kVK_Return = 0x24; |
|||
const int kVK_Tab = 0x30; |
|||
const int kVK_Space = 0x31; |
|||
const int kVK_Delete = 0x33; |
|||
const int kVK_Escape = 0x35; |
|||
const int kVK_Command = 0x37; |
|||
const int kVK_Shift = 0x38; |
|||
const int kVK_CapsLock = 0x39; |
|||
const int kVK_Option = 0x3A; |
|||
const int kVK_Control = 0x3B; |
|||
const int kVK_RightCommand = 0x36; |
|||
const int kVK_RightShift = 0x3C; |
|||
const int kVK_RightOption = 0x3D; |
|||
const int kVK_RightControl = 0x3E; |
|||
//const int kVK_Function = 0x3F; |
|||
const int kVK_F17 = 0x40; |
|||
const int kVK_VolumeUp = 0x48; |
|||
const int kVK_VolumeDown = 0x49; |
|||
const int kVK_Mute = 0x4A; |
|||
const int kVK_F18 = 0x4F; |
|||
const int kVK_F19 = 0x50; |
|||
const int kVK_F20 = 0x5A; |
|||
const int kVK_F5 = 0x60; |
|||
const int kVK_F6 = 0x61; |
|||
const int kVK_F7 = 0x62; |
|||
const int kVK_F3 = 0x63; |
|||
const int kVK_F8 = 0x64; |
|||
const int kVK_F9 = 0x65; |
|||
const int kVK_F11 = 0x67; |
|||
const int kVK_F13 = 0x69; |
|||
const int kVK_F16 = 0x6A; |
|||
const int kVK_F14 = 0x6B; |
|||
const int kVK_F10 = 0x6D; |
|||
const int kVK_F12 = 0x6F; |
|||
const int kVK_F15 = 0x71; |
|||
const int kVK_Help = 0x72; |
|||
const int kVK_Home = 0x73; |
|||
const int kVK_PageUp = 0x74; |
|||
const int kVK_ForwardDelete = 0x75; |
|||
const int kVK_F4 = 0x76; |
|||
const int kVK_End = 0x77; |
|||
const int kVK_F2 = 0x78; |
|||
const int kVK_PageDown = 0x79; |
|||
const int kVK_F1 = 0x7A; |
|||
const int kVK_LeftArrow = 0x7B; |
|||
const int kVK_RightArrow = 0x7C; |
|||
const int kVK_DownArrow = 0x7D; |
|||
const int kVK_UpArrow = 0x7E; |
|||
//const int kVK_ISO_Section = 0x0A; |
|||
//const int kVK_JIS_Yen = 0x5D; |
|||
//const int kVK_JIS_Underscore = 0x5E; |
|||
//const int kVK_JIS_KeypadComma = 0x5F; |
|||
//const int kVK_JIS_Eisu = 0x66; |
|||
//const int kVK_JIS_Kana = 0x68; |
|||
|
|||
std::map<int, AvnKey> s_KeyMap = |
|||
{ |
|||
{kVK_ANSI_A, A}, |
|||
{kVK_ANSI_S, S}, |
|||
{kVK_ANSI_D, D}, |
|||
{kVK_ANSI_F, F}, |
|||
{kVK_ANSI_H, H}, |
|||
{kVK_ANSI_G, G}, |
|||
{kVK_ANSI_Z, Z}, |
|||
{kVK_ANSI_X, X}, |
|||
{kVK_ANSI_C, C}, |
|||
{kVK_ANSI_V, V}, |
|||
{kVK_ANSI_B, B}, |
|||
{kVK_ANSI_Q, Q}, |
|||
{kVK_ANSI_W, W}, |
|||
{kVK_ANSI_E, E}, |
|||
{kVK_ANSI_R, R}, |
|||
{kVK_ANSI_Y, Y}, |
|||
{kVK_ANSI_T, T}, |
|||
{kVK_ANSI_1, D1}, |
|||
{kVK_ANSI_2, D2}, |
|||
{kVK_ANSI_3, D3}, |
|||
{kVK_ANSI_4, D4}, |
|||
{kVK_ANSI_6, D6}, |
|||
{kVK_ANSI_5, D5}, |
|||
//{kVK_ANSI_Equal, ?}, |
|||
{kVK_ANSI_9, D9}, |
|||
{kVK_ANSI_7, D7}, |
|||
{kVK_ANSI_Minus, OemMinus}, |
|||
{kVK_ANSI_8, D8}, |
|||
{kVK_ANSI_0, D0}, |
|||
{kVK_ANSI_RightBracket, OemCloseBrackets}, |
|||
{kVK_ANSI_O, O}, |
|||
{kVK_ANSI_U, U}, |
|||
{kVK_ANSI_LeftBracket, OemOpenBrackets}, |
|||
{kVK_ANSI_I, I}, |
|||
{kVK_ANSI_P, P}, |
|||
{kVK_ANSI_L, L}, |
|||
{kVK_ANSI_J, J}, |
|||
{kVK_ANSI_Quote, OemQuotes}, |
|||
{kVK_ANSI_K, AvnKeyK}, |
|||
{kVK_ANSI_Semicolon, OemSemicolon}, |
|||
{kVK_ANSI_Backslash, OemBackslash}, |
|||
{kVK_ANSI_Comma, OemComma}, |
|||
//{kVK_ANSI_Slash, ?}, |
|||
{kVK_ANSI_N, N}, |
|||
{kVK_ANSI_M, M}, |
|||
{kVK_ANSI_Period, OemPeriod}, |
|||
//{kVK_ANSI_Grave, ?}, |
|||
{kVK_ANSI_KeypadDecimal, Decimal}, |
|||
{kVK_ANSI_KeypadMultiply, Multiply}, |
|||
{kVK_ANSI_KeypadPlus, OemPlus}, |
|||
{kVK_ANSI_KeypadClear, AvnKeyClear}, |
|||
{kVK_ANSI_KeypadDivide, Divide}, |
|||
{kVK_ANSI_KeypadEnter, AvnKeyEnter}, |
|||
{kVK_ANSI_KeypadMinus, OemMinus}, |
|||
//{kVK_ANSI_KeypadEquals, ?}, |
|||
{kVK_ANSI_Keypad0, NumPad0}, |
|||
{kVK_ANSI_Keypad1, NumPad1}, |
|||
{kVK_ANSI_Keypad2, NumPad2}, |
|||
{kVK_ANSI_Keypad3, NumPad3}, |
|||
{kVK_ANSI_Keypad4, NumPad4}, |
|||
{kVK_ANSI_Keypad5, NumPad5}, |
|||
{kVK_ANSI_Keypad6, NumPad6}, |
|||
{kVK_ANSI_Keypad7, NumPad7}, |
|||
{kVK_ANSI_Keypad8, NumPad8}, |
|||
{kVK_ANSI_Keypad9, NumPad9}, |
|||
{kVK_Return, AvnKeyReturn}, |
|||
{kVK_Tab, AvnKeyTab}, |
|||
{kVK_Space, Space}, |
|||
{kVK_Delete, AvnKeyBack}, |
|||
{kVK_Escape, Escape}, |
|||
{kVK_Command, LWin}, |
|||
{kVK_Shift, LeftShift}, |
|||
{kVK_CapsLock, AvnKeyCapsLock}, |
|||
{kVK_Option, LeftAlt}, |
|||
{kVK_Control, LeftCtrl}, |
|||
{kVK_RightCommand, RWin}, |
|||
{kVK_RightShift, RightShift}, |
|||
{kVK_RightOption, RightAlt}, |
|||
{kVK_RightControl, RightCtrl}, |
|||
//{kVK_Function, ?}, |
|||
{kVK_F17, F17}, |
|||
{kVK_VolumeUp, VolumeUp}, |
|||
{kVK_VolumeDown, VolumeDown}, |
|||
{kVK_Mute, VolumeMute}, |
|||
{kVK_F18, F18}, |
|||
{kVK_F19, F19}, |
|||
{kVK_F20, F20}, |
|||
{kVK_F5, F5}, |
|||
{kVK_F6, F6}, |
|||
{kVK_F7, F7}, |
|||
{kVK_F3, F3}, |
|||
{kVK_F8, F8}, |
|||
{kVK_F9, F9}, |
|||
{kVK_F11, F11}, |
|||
{kVK_F13, F13}, |
|||
{kVK_F16, F16}, |
|||
{kVK_F14, F14}, |
|||
{kVK_F10, F10}, |
|||
{kVK_F12, F12}, |
|||
{kVK_F15, F15}, |
|||
{kVK_Help, Help}, |
|||
{kVK_Home, Home}, |
|||
{kVK_PageUp, PageUp}, |
|||
{kVK_ForwardDelete, Delete}, |
|||
{kVK_F4, F4}, |
|||
{kVK_End, End}, |
|||
{kVK_F2, F2}, |
|||
{kVK_PageDown, PageDown}, |
|||
{kVK_F1, F1}, |
|||
{kVK_LeftArrow, Left}, |
|||
{kVK_RightArrow, Right}, |
|||
{kVK_DownArrow, Down}, |
|||
{kVK_UpArrow, Up} |
|||
}; |
|||
@ -0,0 +1,51 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved. |
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information. |
|||
|
|||
#include "common.h" |
|||
|
|||
class Screens : public ComSingleObject<IAvnScreens, &IID_IAvnScreens> |
|||
{ |
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
virtual HRESULT GetScreenCount (int* ret) |
|||
{ |
|||
@autoreleasepool |
|||
{ |
|||
*ret = (int)[NSScreen screens].count; |
|||
|
|||
return S_OK; |
|||
} |
|||
} |
|||
|
|||
virtual HRESULT GetScreen (int index, AvnScreen* ret) |
|||
{ |
|||
@autoreleasepool |
|||
{ |
|||
if(index < 0 || index >= [NSScreen screens].count) |
|||
{ |
|||
return E_INVALIDARG; |
|||
} |
|||
|
|||
auto screen = [[NSScreen screens] objectAtIndex:index]; |
|||
|
|||
ret->Bounds.X = [screen frame].origin.x; |
|||
ret->Bounds.Y = [screen frame].origin.y; |
|||
ret->Bounds.Height = [screen frame].size.height; |
|||
ret->Bounds.Width = [screen frame].size.width; |
|||
|
|||
ret->WorkingArea.X = [screen visibleFrame].origin.x; |
|||
ret->WorkingArea.Y = [screen visibleFrame].origin.y; |
|||
ret->WorkingArea.Height = [screen visibleFrame].size.height; |
|||
ret->WorkingArea.Width = [screen visibleFrame].size.width; |
|||
|
|||
ret->Primary = index == 0; |
|||
|
|||
return S_OK; |
|||
} |
|||
} |
|||
}; |
|||
|
|||
extern IAvnScreens* CreateScreens() |
|||
{ |
|||
return new Screens(); |
|||
} |
|||
@ -0,0 +1,262 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved. |
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information. |
|||
|
|||
#include "common.h" |
|||
#include "window.h" |
|||
|
|||
class SystemDialogs : public ComSingleObject<IAvnSystemDialogs, &IID_IAvnSystemDialogs> |
|||
{ |
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
virtual void SelectFolderDialog (IAvnWindow* parentWindowHandle, |
|||
IAvnSystemDialogEvents* events, |
|||
const char* title, |
|||
const char* initialDirectory) |
|||
{ |
|||
@autoreleasepool |
|||
{ |
|||
auto panel = [NSOpenPanel openPanel]; |
|||
|
|||
panel.canChooseDirectories = true; |
|||
panel.canCreateDirectories = true; |
|||
panel.canChooseFiles = false; |
|||
|
|||
if(title != nullptr) |
|||
{ |
|||
panel.title = [NSString stringWithUTF8String:title]; |
|||
} |
|||
|
|||
if(initialDirectory != nullptr) |
|||
{ |
|||
auto directoryString = [NSString stringWithUTF8String:initialDirectory]; |
|||
panel.directoryURL = [NSURL fileURLWithPath:directoryString]; |
|||
} |
|||
|
|||
auto handler = ^(NSModalResponse result) { |
|||
if(result == NSFileHandlingPanelOKButton) |
|||
{ |
|||
auto urls = [panel URLs]; |
|||
|
|||
if(urls.count > 0) |
|||
{ |
|||
void* strings[urls.count]; |
|||
|
|||
for(int i = 0; i < urls.count; i++) |
|||
{ |
|||
auto url = [urls objectAtIndex:i]; |
|||
|
|||
auto string = [url absoluteString]; |
|||
string = [string substringFromIndex:7]; |
|||
|
|||
strings[i] = (void*)[string UTF8String]; |
|||
} |
|||
|
|||
events->OnCompleted((int)urls.count, &strings[0]); |
|||
|
|||
[panel orderOut:panel]; |
|||
|
|||
if(parentWindowHandle != nullptr) |
|||
{ |
|||
auto windowHolder = dynamic_cast<INSWindowHolder*>(parentWindowHandle); |
|||
[windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()]; |
|||
} |
|||
|
|||
return; |
|||
} |
|||
} |
|||
|
|||
events->OnCompleted(0, nullptr); |
|||
|
|||
}; |
|||
|
|||
if(parentWindowHandle != nullptr) |
|||
{ |
|||
auto windowBase = dynamic_cast<INSWindowHolder*>(parentWindowHandle); |
|||
|
|||
[panel beginSheetModalForWindow:windowBase->GetNSWindow() completionHandler:handler]; |
|||
} |
|||
else |
|||
{ |
|||
[panel beginWithCompletionHandler: handler]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
virtual void OpenFileDialog (IAvnWindow* parentWindowHandle, |
|||
IAvnSystemDialogEvents* events, |
|||
bool allowMultiple, |
|||
const char* title, |
|||
const char* initialDirectory, |
|||
const char* initialFile, |
|||
const char* filters) |
|||
{ |
|||
@autoreleasepool |
|||
{ |
|||
auto panel = [NSOpenPanel openPanel]; |
|||
|
|||
panel.allowsMultipleSelection = allowMultiple; |
|||
|
|||
if(title != nullptr) |
|||
{ |
|||
panel.title = [NSString stringWithUTF8String:title]; |
|||
} |
|||
|
|||
if(initialDirectory != nullptr) |
|||
{ |
|||
auto directoryString = [NSString stringWithUTF8String:initialDirectory]; |
|||
panel.directoryURL = [NSURL fileURLWithPath:directoryString]; |
|||
} |
|||
|
|||
if(initialFile != nullptr) |
|||
{ |
|||
panel.nameFieldStringValue = [NSString stringWithUTF8String:initialFile]; |
|||
} |
|||
|
|||
if(filters != nullptr) |
|||
{ |
|||
auto filtersString = [NSString stringWithUTF8String:filters]; |
|||
|
|||
if(filtersString.length > 0) |
|||
{ |
|||
auto allowedTypes = [filtersString componentsSeparatedByString:@";"]; |
|||
|
|||
panel.allowedFileTypes = allowedTypes; |
|||
} |
|||
} |
|||
|
|||
auto handler = ^(NSModalResponse result) { |
|||
if(result == NSFileHandlingPanelOKButton) |
|||
{ |
|||
auto urls = [panel URLs]; |
|||
|
|||
if(urls.count > 0) |
|||
{ |
|||
void* strings[urls.count]; |
|||
|
|||
for(int i = 0; i < urls.count; i++) |
|||
{ |
|||
auto url = [urls objectAtIndex:i]; |
|||
|
|||
auto string = [url absoluteString]; |
|||
string = [string substringFromIndex:7]; |
|||
|
|||
strings[i] = (void*)[string UTF8String]; |
|||
} |
|||
|
|||
events->OnCompleted((int)urls.count, &strings[0]); |
|||
|
|||
[panel orderOut:panel]; |
|||
|
|||
if(parentWindowHandle != nullptr) |
|||
{ |
|||
auto windowHolder = dynamic_cast<INSWindowHolder*>(parentWindowHandle); |
|||
[windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()]; |
|||
} |
|||
|
|||
return; |
|||
} |
|||
} |
|||
|
|||
events->OnCompleted(0, nullptr); |
|||
|
|||
}; |
|||
|
|||
if(parentWindowHandle != nullptr) |
|||
{ |
|||
auto windowHolder = dynamic_cast<INSWindowHolder*>(parentWindowHandle); |
|||
|
|||
[panel beginSheetModalForWindow:windowHolder->GetNSWindow() completionHandler:handler]; |
|||
} |
|||
else |
|||
{ |
|||
[panel beginWithCompletionHandler: handler]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
virtual void SaveFileDialog (IAvnWindow* parentWindowHandle, |
|||
IAvnSystemDialogEvents* events, |
|||
const char* title, |
|||
const char* initialDirectory, |
|||
const char* initialFile, |
|||
const char* filters) |
|||
{ |
|||
@autoreleasepool |
|||
{ |
|||
auto panel = [NSSavePanel savePanel]; |
|||
|
|||
if(title != nullptr) |
|||
{ |
|||
panel.title = [NSString stringWithUTF8String:title]; |
|||
} |
|||
|
|||
if(initialDirectory != nullptr) |
|||
{ |
|||
auto directoryString = [NSString stringWithUTF8String:initialDirectory]; |
|||
panel.directoryURL = [NSURL fileURLWithPath:directoryString]; |
|||
} |
|||
|
|||
if(initialFile != nullptr) |
|||
{ |
|||
panel.nameFieldStringValue = [NSString stringWithUTF8String:initialFile]; |
|||
} |
|||
|
|||
if(filters != nullptr) |
|||
{ |
|||
auto filtersString = [NSString stringWithUTF8String:filters]; |
|||
|
|||
if(filtersString.length > 0) |
|||
{ |
|||
auto allowedTypes = [filtersString componentsSeparatedByString:@";"]; |
|||
|
|||
panel.allowedFileTypes = allowedTypes; |
|||
} |
|||
} |
|||
|
|||
auto handler = ^(NSModalResponse result) { |
|||
if(result == NSFileHandlingPanelOKButton) |
|||
{ |
|||
void* strings[1]; |
|||
|
|||
auto url = [panel URL]; |
|||
|
|||
auto string = [url absoluteString]; |
|||
string = [string substringFromIndex:7]; |
|||
strings[0] = (void*)[string UTF8String]; |
|||
|
|||
events->OnCompleted(1, &strings[0]); |
|||
|
|||
[panel orderOut:panel]; |
|||
|
|||
if(parentWindowHandle != nullptr) |
|||
{ |
|||
auto windowHolder = dynamic_cast<INSWindowHolder*>(parentWindowHandle); |
|||
[windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()]; |
|||
} |
|||
|
|||
return; |
|||
} |
|||
|
|||
events->OnCompleted(0, nullptr); |
|||
|
|||
}; |
|||
|
|||
if(parentWindowHandle != nullptr) |
|||
{ |
|||
auto windowBase = dynamic_cast<INSWindowHolder*>(parentWindowHandle); |
|||
|
|||
[panel beginSheetModalForWindow:windowBase->GetNSWindow() completionHandler:handler]; |
|||
} |
|||
else |
|||
{ |
|||
[panel beginWithCompletionHandler: handler]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
}; |
|||
|
|||
extern IAvnSystemDialogs* CreateSystemDialogs() |
|||
{ |
|||
return new SystemDialogs(); |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved. |
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information. |
|||
|
|||
#include "common.h" |
|||
|
|||
class Clipboard : public ComSingleObject<IAvnClipboard, &IID_IAvnClipboard> |
|||
{ |
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
virtual HRESULT GetText (void** retOut) |
|||
{ |
|||
@autoreleasepool |
|||
{ |
|||
NSString *str = [[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString]; |
|||
*retOut = (void *)str.UTF8String; |
|||
} |
|||
|
|||
return S_OK; |
|||
} |
|||
|
|||
virtual HRESULT SetText (char* text) |
|||
{ |
|||
@autoreleasepool |
|||
{ |
|||
NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; |
|||
[pasteBoard clearContents]; |
|||
[pasteBoard setString:@(text) forType:NSPasteboardTypeString]; |
|||
} |
|||
|
|||
return S_OK; |
|||
} |
|||
|
|||
virtual HRESULT Clear() |
|||
{ |
|||
@autoreleasepool |
|||
{ |
|||
[[NSPasteboard generalPasteboard] clearContents]; |
|||
} |
|||
|
|||
return S_OK; |
|||
} |
|||
}; |
|||
|
|||
extern IAvnClipboard* CreateClipboard() |
|||
{ |
|||
return new Clipboard(); |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
#ifndef common_h |
|||
#define common_h |
|||
#include "comimpl.h" |
|||
#include "avalonia-native.h" |
|||
#include <stdio.h> |
|||
#import <Foundation/Foundation.h> |
|||
#import <AppKit/AppKit.h> |
|||
#include <pthread.h> |
|||
|
|||
extern IAvnPlatformThreadingInterface* CreatePlatformThreading(); |
|||
extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events); |
|||
extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events); |
|||
extern IAvnSystemDialogs* CreateSystemDialogs(); |
|||
extern IAvnScreens* CreateScreens(); |
|||
extern IAvnClipboard* CreateClipboard(); |
|||
extern IAvnCursorFactory* CreateCursorFactory(); |
|||
extern IAvnGlFeature* GetGlFeature(); |
|||
extern IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(NSWindow* window, NSView* view); |
|||
|
|||
extern NSPoint ToNSPoint (AvnPoint p); |
|||
extern AvnPoint ToAvnPoint (NSPoint p); |
|||
extern AvnPoint ConvertPointY (AvnPoint p); |
|||
extern NSSize ToNSSize (AvnSize s); |
|||
|
|||
#ifdef DEBUG |
|||
#define NSDebugLog(...) NSLog(__VA_ARGS__) |
|||
#else |
|||
#define NSDebugLog(...) (void)0 |
|||
#endif |
|||
|
|||
#endif |
|||
@ -0,0 +1,29 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
#ifndef cursor_h |
|||
#define cursor_h |
|||
|
|||
#include "common.h" |
|||
#include <map> |
|||
|
|||
class Cursor : public ComSingleObject<IAvnCursor, &IID_IAvnCursor> |
|||
{ |
|||
private: |
|||
NSCursor * _native; |
|||
|
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
Cursor(NSCursor * cursor) |
|||
{ |
|||
_native = cursor; |
|||
} |
|||
|
|||
NSCursor* GetNative() |
|||
{ |
|||
return _native; |
|||
} |
|||
}; |
|||
|
|||
extern std::map<AvnStandardCursorType, Cursor*> s_cursorMap; |
|||
#endif /* cursor_h */ |
|||
@ -0,0 +1,73 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved. |
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information. |
|||
|
|||
#include "common.h" |
|||
#include "cursor.h" |
|||
#include <map> |
|||
|
|||
class CursorFactory : public ComSingleObject<IAvnCursorFactory, &IID_IAvnCursorFactory> |
|||
{ |
|||
Cursor* arrowCursor = new Cursor([NSCursor arrowCursor]); |
|||
Cursor* crossCursor = new Cursor([NSCursor crosshairCursor]); |
|||
Cursor* resizeUpCursor = new Cursor([NSCursor resizeUpCursor]); |
|||
Cursor* resizeDownCursor = new Cursor([NSCursor resizeDownCursor]); |
|||
Cursor* resizeUpDownCursor = new Cursor([NSCursor resizeUpDownCursor]); |
|||
Cursor* dragCopyCursor = new Cursor([NSCursor dragCopyCursor]); |
|||
Cursor* dragLinkCursor = new Cursor([NSCursor dragLinkCursor]); |
|||
Cursor* pointingHandCursor = new Cursor([NSCursor pointingHandCursor]); |
|||
Cursor* contextualMenuCursor = new Cursor([NSCursor contextualMenuCursor]); |
|||
Cursor* IBeamCursor = new Cursor([NSCursor IBeamCursor]); |
|||
Cursor* resizeLeftCursor = new Cursor([NSCursor resizeLeftCursor]); |
|||
Cursor* resizeRightCursor = new Cursor([NSCursor resizeRightCursor]); |
|||
Cursor* resizeWestEastCursor = new Cursor([NSCursor resizeLeftRightCursor]); |
|||
Cursor* operationNotAllowedCursor = new Cursor([NSCursor operationNotAllowedCursor]); |
|||
|
|||
std::map<AvnStandardCursorType, Cursor*> s_cursorMap = |
|||
{ |
|||
{ CursorArrow, arrowCursor }, |
|||
{ CursorAppStarting, arrowCursor }, |
|||
{ CursorWait, arrowCursor }, |
|||
{ CursorTopLeftCorner, crossCursor }, |
|||
{ CursorTopRightCorner, crossCursor }, |
|||
{ CursorBottomLeftCorner, crossCursor }, |
|||
{ CursorBottomRightCorner, crossCursor }, |
|||
{ CursorCross, crossCursor }, |
|||
{ CursorSizeAll, crossCursor }, |
|||
{ CursorSizeNorthSouth, resizeUpDownCursor}, |
|||
{ CursorSizeWestEast, resizeWestEastCursor}, |
|||
{ CursorTopSide, resizeUpCursor }, |
|||
{ CursorUpArrow, resizeUpCursor }, |
|||
{ CursorBottomSize, resizeDownCursor }, |
|||
{ CursorDragCopy, dragCopyCursor }, |
|||
{ CursorDragMove, dragCopyCursor }, |
|||
{ CursorDragLink, dragLinkCursor }, |
|||
{ CursorHand, pointingHandCursor }, |
|||
{ CursorHelp, contextualMenuCursor }, |
|||
{ CursorIbeam, IBeamCursor }, |
|||
{ CursorLeftSide, resizeLeftCursor }, |
|||
{ CursorRightSide, resizeRightCursor }, |
|||
{ CursorNo, operationNotAllowedCursor } |
|||
}; |
|||
|
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut) |
|||
{ |
|||
*retOut = s_cursorMap[cursorType]; |
|||
|
|||
if(*retOut != nullptr) |
|||
{ |
|||
(*retOut)->AddRef(); |
|||
} |
|||
|
|||
return S_OK; |
|||
} |
|||
}; |
|||
|
|||
extern IAvnCursorFactory* CreateCursorFactory() |
|||
{ |
|||
@autoreleasepool |
|||
{ |
|||
return new CursorFactory(); |
|||
} |
|||
} |
|||
@ -0,0 +1,255 @@ |
|||
#include "common.h" |
|||
#include <OpenGL/gl.h> |
|||
#include <dlfcn.h> |
|||
|
|||
template <typename T, size_t N> char (&ArrayCounter(T (&a)[N]))[N]; |
|||
#define ARRAY_COUNT(a) (sizeof(ArrayCounter(a))) |
|||
|
|||
NSOpenGLPixelFormat* CreateFormat() |
|||
{ |
|||
NSOpenGLPixelFormatAttribute attribs[] = |
|||
{ |
|||
NSOpenGLPFADoubleBuffer, |
|||
NSOpenGLPFAColorSize, 32, |
|||
NSOpenGLPFAStencilSize, 8, |
|||
NSOpenGLPFADepthSize, 8, |
|||
0 |
|||
}; |
|||
return [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; |
|||
} |
|||
|
|||
class AvnGlContext : public virtual ComSingleObject<IAvnGlContext, &IID_IAvnGlContext> |
|||
{ |
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
NSOpenGLContext* GlContext; |
|||
GLuint Framebuffer, RenderBuffer, StencilBuffer; |
|||
AvnGlContext(NSOpenGLContext* gl, bool offscreen) |
|||
{ |
|||
Framebuffer = 0; |
|||
RenderBuffer = 0; |
|||
StencilBuffer = 0; |
|||
GlContext = gl; |
|||
if(offscreen) |
|||
{ |
|||
[GlContext makeCurrentContext]; |
|||
|
|||
glGenFramebuffersEXT(1, &Framebuffer); |
|||
glBindFramebufferEXT(GL_FRAMEBUFFER, Framebuffer); |
|||
glGenRenderbuffersEXT(1, &RenderBuffer); |
|||
glGenRenderbuffersEXT(1, &StencilBuffer); |
|||
|
|||
glBindRenderbufferEXT(GL_RENDERBUFFER, StencilBuffer); |
|||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, StencilBuffer); |
|||
glBindRenderbufferEXT(GL_RENDERBUFFER, RenderBuffer); |
|||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, RenderBuffer); |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
virtual HRESULT MakeCurrent() |
|||
{ |
|||
[GlContext makeCurrentContext];/* |
|||
glBindFramebufferEXT(GL_FRAMEBUFFER, Framebuffer); |
|||
glBindRenderbufferEXT(GL_RENDERBUFFER, RenderBuffer); |
|||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, RenderBuffer); |
|||
glBindRenderbufferEXT(GL_RENDERBUFFER, StencilBuffer); |
|||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, StencilBuffer);*/ |
|||
return S_OK; |
|||
} |
|||
}; |
|||
|
|||
class AvnGlDisplay : public virtual ComSingleObject<IAvnGlDisplay, &IID_IAvnGlDisplay> |
|||
{ |
|||
int _sampleCount, _stencilSize; |
|||
void* _libgl; |
|||
|
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
|
|||
AvnGlDisplay(int sampleCount, int stencilSize) |
|||
{ |
|||
_sampleCount = sampleCount; |
|||
_stencilSize = stencilSize; |
|||
_libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib", RTLD_LAZY); |
|||
} |
|||
|
|||
virtual HRESULT GetSampleCount(int* ret) |
|||
{ |
|||
*ret = _sampleCount; |
|||
return S_OK; |
|||
} |
|||
virtual HRESULT GetStencilSize(int* ret) |
|||
{ |
|||
*ret = _stencilSize; |
|||
return S_OK; |
|||
} |
|||
|
|||
virtual HRESULT ClearContext() |
|||
{ |
|||
[NSOpenGLContext clearCurrentContext]; |
|||
return S_OK; |
|||
} |
|||
|
|||
virtual void* GetProcAddress(char* proc) |
|||
{ |
|||
return dlsym(_libgl, proc); |
|||
} |
|||
}; |
|||
|
|||
|
|||
class GlFeature : public virtual ComSingleObject<IAvnGlFeature, &IID_IAvnGlFeature> |
|||
{ |
|||
IAvnGlDisplay* _display; |
|||
AvnGlContext *_immediate; |
|||
NSOpenGLContext* _shared; |
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
NSOpenGLPixelFormat* _format; |
|||
GlFeature(IAvnGlDisplay* display, AvnGlContext* immediate, NSOpenGLPixelFormat* format) |
|||
{ |
|||
_display = display; |
|||
_immediate = immediate; |
|||
_format = format; |
|||
_shared = [[NSOpenGLContext alloc] initWithFormat:_format shareContext:_immediate->GlContext]; |
|||
} |
|||
|
|||
NSOpenGLContext* CreateContext() |
|||
{ |
|||
return _shared; |
|||
//return [[NSOpenGLContext alloc] initWithFormat:_format shareContext:nil]; |
|||
} |
|||
|
|||
virtual HRESULT ObtainDisplay(IAvnGlDisplay**retOut) |
|||
{ |
|||
*retOut = _display; |
|||
_display->AddRef(); |
|||
return S_OK; |
|||
} |
|||
|
|||
virtual HRESULT ObtainImmediateContext(IAvnGlContext**retOut) |
|||
{ |
|||
*retOut = _immediate; |
|||
_immediate->AddRef(); |
|||
return S_OK; |
|||
} |
|||
}; |
|||
|
|||
static GlFeature* Feature; |
|||
|
|||
GlFeature* CreateGlFeature() |
|||
{ |
|||
auto format = CreateFormat(); |
|||
if(format == nil) |
|||
{ |
|||
NSLog(@"Unable to choose pixel format"); |
|||
return NULL; |
|||
} |
|||
|
|||
auto immediateContext = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nil]; |
|||
if(immediateContext == nil) |
|||
{ |
|||
NSLog(@"Unable to create NSOpenGLContext"); |
|||
return NULL; |
|||
} |
|||
|
|||
int stencilBits = 0, sampleCount = 0; |
|||
|
|||
auto fmt = CGLGetPixelFormat([immediateContext CGLContextObj]); |
|||
CGLDescribePixelFormat(fmt, 0, kCGLPFASamples, &sampleCount); |
|||
CGLDescribePixelFormat(fmt, 0, kCGLPFAStencilSize, &stencilBits); |
|||
|
|||
auto offscreen = new AvnGlContext(immediateContext, true); |
|||
auto display = new AvnGlDisplay(sampleCount, stencilBits); |
|||
|
|||
return new GlFeature(display, offscreen, format); |
|||
} |
|||
|
|||
|
|||
static GlFeature* GetFeature() |
|||
{ |
|||
if(Feature == nil) |
|||
Feature = CreateGlFeature(); |
|||
return Feature; |
|||
} |
|||
|
|||
extern IAvnGlFeature* GetGlFeature() |
|||
{ |
|||
return GetFeature(); |
|||
} |
|||
|
|||
class AvnGlRenderingSession : public ComSingleObject<IAvnGlSurfaceRenderingSession, &IID_IAvnGlSurfaceRenderingSession> |
|||
{ |
|||
NSView* _view; |
|||
NSWindow* _window; |
|||
NSOpenGLContext* _context; |
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
AvnGlRenderingSession(NSWindow*window, NSView* view, NSOpenGLContext* context) |
|||
{ |
|||
_context = context; |
|||
_window = window; |
|||
_view = view; |
|||
} |
|||
|
|||
virtual HRESULT GetPixelSize(AvnPixelSize* ret) |
|||
{ |
|||
auto fsize = [_view convertSizeToBacking: [_view frame].size]; |
|||
ret->Width = (int)fsize.width; |
|||
ret->Height = (int)fsize.height; |
|||
return S_OK; |
|||
} |
|||
virtual HRESULT GetScaling(double* ret) |
|||
{ |
|||
*ret = [_window backingScaleFactor]; |
|||
return S_OK; |
|||
} |
|||
|
|||
virtual ~AvnGlRenderingSession() |
|||
{ |
|||
glFlush(); |
|||
[_context flushBuffer]; |
|||
[_context setView:nil]; |
|||
CGLUnlockContext([_context CGLContextObj]); |
|||
[_view unlockFocus]; |
|||
} |
|||
}; |
|||
|
|||
class AvnGlRenderTarget : public ComSingleObject<IAvnGlSurfaceRenderTarget, &IID_IAvnGlSurfaceRenderTarget> |
|||
{ |
|||
NSView* _view; |
|||
NSWindow* _window; |
|||
NSOpenGLContext* _context; |
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
AvnGlRenderTarget(NSWindow* window, NSView*view) |
|||
{ |
|||
_window = window; |
|||
_view = view; |
|||
_context = GetFeature()->CreateContext(); |
|||
} |
|||
|
|||
virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) |
|||
{ |
|||
auto f = GetFeature(); |
|||
if(f == NULL) |
|||
return E_FAIL; |
|||
if(![_view lockFocusIfCanDraw]) |
|||
return E_ABORT; |
|||
|
|||
auto gl = _context; |
|||
CGLLockContext([_context CGLContextObj]); |
|||
[gl setView: _view]; |
|||
[gl makeCurrentContext]; |
|||
auto frame = [_view frame]; |
|||
|
|||
*ret = new AvnGlRenderingSession(_window, _view, gl); |
|||
return S_OK; |
|||
} |
|||
}; |
|||
|
|||
extern IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(NSWindow* window, NSView* view) |
|||
{ |
|||
return new AvnGlRenderTarget(window, view); |
|||
} |
|||
@ -0,0 +1,178 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved. |
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information. |
|||
|
|||
//This file will contain actual IID structures |
|||
#define COM_GUIDS_MATERIALIZE |
|||
#include "common.h" |
|||
|
|||
static BOOL ShowInDock = 1; |
|||
|
|||
static void SetActivationPolicy() |
|||
{ |
|||
[[NSApplication sharedApplication] setActivationPolicy: (ShowInDock ? NSApplicationActivationPolicyRegular : NSApplicationActivationPolicyAccessory)]; |
|||
} |
|||
|
|||
class MacOptions : public ComSingleObject<IAvnMacOptions, &IID_IAvnMacOptions> |
|||
{ |
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
virtual HRESULT SetShowInDock(int show) |
|||
{ |
|||
ShowInDock = show; |
|||
SetActivationPolicy(); |
|||
return S_OK; |
|||
} |
|||
}; |
|||
|
|||
|
|||
|
|||
/// See "Using POSIX Threads in a Cocoa Application" section here: |
|||
/// https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html#//apple_ref/doc/uid/20000738-125024 |
|||
@interface ThreadingInitializer : NSObject |
|||
- (void) do; |
|||
@end |
|||
@implementation ThreadingInitializer |
|||
|
|||
pthread_mutex_t mutex; |
|||
pthread_cond_t cond; |
|||
|
|||
- (void) runOnce |
|||
{ |
|||
pthread_mutex_lock(&mutex); |
|||
pthread_cond_signal(&cond); |
|||
pthread_mutex_unlock(&mutex); |
|||
} |
|||
|
|||
- (void) do |
|||
{ |
|||
pthread_mutex_init(&mutex, NULL); |
|||
pthread_cond_init(&cond, NULL); |
|||
[[[NSThread alloc] initWithTarget:self selector:@selector(runOnce) object:nil] start]; |
|||
pthread_mutex_lock(&mutex); |
|||
pthread_cond_wait(&cond, &mutex); |
|||
pthread_mutex_unlock(&mutex); |
|||
pthread_cond_destroy(&cond); |
|||
pthread_mutex_destroy(&mutex); |
|||
} |
|||
|
|||
|
|||
@end |
|||
|
|||
|
|||
class AvaloniaNative : public ComSingleObject<IAvaloniaNativeFactory, &IID_IAvaloniaNativeFactory> |
|||
{ |
|||
|
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
virtual HRESULT Initialize() |
|||
{ |
|||
@autoreleasepool{ |
|||
[[ThreadingInitializer new] do]; |
|||
return S_OK; |
|||
} |
|||
}; |
|||
|
|||
virtual IAvnMacOptions* GetMacOptions() |
|||
{ |
|||
return (IAvnMacOptions*)new MacOptions(); |
|||
} |
|||
|
|||
virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv) |
|||
{ |
|||
if(cb == nullptr || ppv == nullptr) |
|||
return E_POINTER; |
|||
*ppv = CreateAvnWindow(cb); |
|||
return S_OK; |
|||
}; |
|||
|
|||
virtual HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnPopup** ppv) |
|||
{ |
|||
if(cb == nullptr || ppv == nullptr) |
|||
return E_POINTER; |
|||
|
|||
*ppv = CreateAvnPopup(cb); |
|||
return S_OK; |
|||
} |
|||
|
|||
virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) |
|||
{ |
|||
*ppv = CreatePlatformThreading(); |
|||
return S_OK; |
|||
} |
|||
|
|||
virtual HRESULT CreateSystemDialogs(IAvnSystemDialogs** ppv) |
|||
{ |
|||
*ppv = ::CreateSystemDialogs(); |
|||
return S_OK; |
|||
} |
|||
|
|||
virtual HRESULT CreateScreens (IAvnScreens** ppv) |
|||
{ |
|||
*ppv = ::CreateScreens (); |
|||
return S_OK; |
|||
} |
|||
|
|||
virtual HRESULT CreateClipboard(IAvnClipboard** ppv) |
|||
{ |
|||
*ppv = ::CreateClipboard (); |
|||
return S_OK; |
|||
} |
|||
|
|||
virtual HRESULT CreateCursorFactory(IAvnCursorFactory** ppv) |
|||
{ |
|||
*ppv = ::CreateCursorFactory(); |
|||
return S_OK; |
|||
} |
|||
|
|||
virtual HRESULT ObtainGlFeature(IAvnGlFeature** ppv) |
|||
{ |
|||
auto rv = ::GetGlFeature(); |
|||
if(rv == NULL) |
|||
return E_FAIL; |
|||
rv->AddRef(); |
|||
*ppv = rv; |
|||
return S_OK; |
|||
} |
|||
}; |
|||
|
|||
extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative() |
|||
{ |
|||
return new AvaloniaNative(); |
|||
}; |
|||
|
|||
NSSize ToNSSize (AvnSize s) |
|||
{ |
|||
NSSize result; |
|||
result.width = s.Width; |
|||
result.height = s.Height; |
|||
|
|||
return result; |
|||
} |
|||
|
|||
NSPoint ToNSPoint (AvnPoint p) |
|||
{ |
|||
NSPoint result; |
|||
result.x = p.X; |
|||
result.y = p.Y; |
|||
|
|||
return result; |
|||
} |
|||
|
|||
AvnPoint ToAvnPoint (NSPoint p) |
|||
{ |
|||
AvnPoint result; |
|||
result.X = p.x; |
|||
result.Y = p.y; |
|||
|
|||
return result; |
|||
} |
|||
|
|||
AvnPoint ConvertPointY (AvnPoint p) |
|||
{ |
|||
auto sw = [NSScreen.screens objectAtIndex:0].frame; |
|||
|
|||
auto t = MAX(sw.origin.y, sw.origin.y + sw.size.height); |
|||
p.Y = t - p.Y; |
|||
|
|||
return p; |
|||
} |
|||
@ -0,0 +1,190 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved. |
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information. |
|||
|
|||
#include "common.h" |
|||
|
|||
class PlatformThreadingInterface; |
|||
@interface Signaler : NSObject |
|||
-(void) setParent: (PlatformThreadingInterface*)parent; |
|||
-(void) signal: (int) priority; |
|||
-(Signaler*) init; |
|||
@end |
|||
|
|||
|
|||
@interface ActionCallback : NSObject |
|||
- (ActionCallback*) initWithCallback: (IAvnActionCallback*) callback; |
|||
- (void) action; |
|||
@end |
|||
|
|||
@implementation ActionCallback |
|||
{ |
|||
ComPtr<IAvnActionCallback> _callback; |
|||
|
|||
} |
|||
- (ActionCallback*) initWithCallback: (IAvnActionCallback*) callback |
|||
{ |
|||
_callback = callback; |
|||
return self; |
|||
} |
|||
|
|||
- (void) action |
|||
{ |
|||
_callback->Run(); |
|||
} |
|||
|
|||
|
|||
@end |
|||
|
|||
class TimerWrapper : public ComUnknownObject |
|||
{ |
|||
NSTimer* _timer; |
|||
public: |
|||
TimerWrapper(IAvnActionCallback* callback, int ms) |
|||
{ |
|||
auto cb = [[ActionCallback alloc] initWithCallback:callback]; |
|||
_timer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)(double)ms/1000 target:cb selector:@selector(action) userInfo:nullptr repeats:true]; |
|||
} |
|||
|
|||
virtual ~TimerWrapper() |
|||
{ |
|||
[_timer invalidate]; |
|||
} |
|||
}; |
|||
|
|||
|
|||
|
|||
class PlatformThreadingInterface : public ComSingleObject<IAvnPlatformThreadingInterface, &IID_IAvnPlatformThreadingInterface> |
|||
{ |
|||
private: |
|||
Signaler* _signaler; |
|||
|
|||
class LoopCancellation : public ComSingleObject<IAvnLoopCancellation, &IID_IAvnLoopCancellation> |
|||
{ |
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
bool Cancelled = 0; |
|||
virtual void Cancel() |
|||
{ |
|||
Cancelled = 1; |
|||
} |
|||
}; |
|||
|
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
ComPtr<IAvnSignaledCallback> SignaledCallback; |
|||
|
|||
PlatformThreadingInterface() |
|||
{ |
|||
_signaler = [Signaler new]; |
|||
[_signaler setParent:this]; |
|||
} |
|||
|
|||
~PlatformThreadingInterface() |
|||
{ |
|||
if(_signaler) |
|||
[_signaler setParent: NULL]; |
|||
_signaler = NULL; |
|||
} |
|||
|
|||
virtual bool GetCurrentThreadIsLoopThread() |
|||
{ |
|||
return [[NSThread currentThread] isMainThread]; |
|||
} |
|||
virtual void SetSignaledCallback(IAvnSignaledCallback* cb) |
|||
{ |
|||
SignaledCallback = cb; |
|||
} |
|||
virtual IAvnLoopCancellation* CreateLoopCancellation() |
|||
{ |
|||
return new LoopCancellation(); |
|||
} |
|||
|
|||
virtual void RunLoop(IAvnLoopCancellation* cancel) |
|||
{ |
|||
@autoreleasepool { |
|||
auto can = dynamic_cast<LoopCancellation*>(cancel); |
|||
[[NSApplication sharedApplication] activateIgnoringOtherApps:true]; |
|||
while(true) |
|||
{ |
|||
@autoreleasepool |
|||
{ |
|||
if(can != NULL && can->Cancelled) |
|||
return; |
|||
NSEvent* ev = [[NSApplication sharedApplication] |
|||
nextEventMatchingMask:NSEventMaskAny |
|||
untilDate: [NSDate dateWithTimeIntervalSinceNow:1] |
|||
inMode:NSDefaultRunLoopMode |
|||
dequeue:true]; |
|||
if(can != NULL && can->Cancelled) |
|||
return; |
|||
if(ev != NULL) |
|||
[[NSApplication sharedApplication] sendEvent:ev]; |
|||
} |
|||
} |
|||
NSDebugLog(@"RunLoop exited"); |
|||
} |
|||
} |
|||
|
|||
virtual void Signal(int priority) |
|||
{ |
|||
[_signaler signal:priority]; |
|||
} |
|||
|
|||
virtual IUnknown* StartTimer(int priority, int ms, IAvnActionCallback* callback) |
|||
{ |
|||
@autoreleasepool { |
|||
|
|||
return new TimerWrapper(callback, ms); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
@implementation Signaler |
|||
|
|||
PlatformThreadingInterface* _parent = 0; |
|||
bool _signaled = 0; |
|||
NSArray<NSString*>* _modes; |
|||
|
|||
-(Signaler*) init |
|||
{ |
|||
if(self = [super init]) |
|||
{ |
|||
_modes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, NSRunLoopCommonModes, NSConnectionReplyMode, nil]; |
|||
} |
|||
return self; |
|||
} |
|||
|
|||
-(void) perform |
|||
{ |
|||
@synchronized (self) { |
|||
_signaled = false; |
|||
if(_parent != NULL && _parent->SignaledCallback != NULL) |
|||
_parent->SignaledCallback->Signaled(0, false); |
|||
} |
|||
} |
|||
|
|||
-(void) setParent:(PlatformThreadingInterface *)parent |
|||
{ |
|||
@synchronized (self) { |
|||
_parent = parent; |
|||
} |
|||
} |
|||
|
|||
-(void) signal: (int) priority |
|||
{ |
|||
|
|||
@synchronized (self) { |
|||
if(_signaled) |
|||
return; |
|||
_signaled = true; |
|||
[self performSelector:@selector(perform) onThread:[NSThread mainThread] withObject:NULL waitUntilDone:false modes:_modes]; |
|||
} |
|||
|
|||
} |
|||
@end |
|||
|
|||
|
|||
extern IAvnPlatformThreadingInterface* CreatePlatformThreading() |
|||
{ |
|||
return new PlatformThreadingInterface(); |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
#ifndef window_h |
|||
#define window_h |
|||
|
|||
class WindowBaseImpl; |
|||
|
|||
@interface AvnView : NSView<NSTextInputClient> |
|||
-(AvnView* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent; |
|||
-(NSEvent* _Nonnull) lastMouseDownEvent; |
|||
-(AvnPoint) translateLocalPoint:(AvnPoint)pt; |
|||
-(void) setSwRenderedFrame: (AvnFramebuffer* _Nonnull) fb dispose: (IUnknown* _Nonnull) dispose; |
|||
-(void) onClosed; |
|||
@end |
|||
|
|||
@interface AvnWindow : NSWindow <NSWindowDelegate> |
|||
-(AvnWindow* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent; |
|||
-(void) setCanBecomeKeyAndMain; |
|||
-(void) pollModalSession: (NSModalSession _Nonnull) session; |
|||
@end |
|||
|
|||
struct INSWindowHolder |
|||
{ |
|||
virtual AvnWindow* _Nonnull GetNSWindow () = 0; |
|||
}; |
|||
|
|||
struct IWindowStateChanged |
|||
{ |
|||
virtual void WindowStateChanged () = 0; |
|||
}; |
|||
|
|||
#endif /* window_h */ |
|||
File diff suppressed because it is too large
@ -0,0 +1 @@ |
|||
Generated |
|||
@ -0,0 +1,31 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<CastXmlPath>/usr/local/bin/castxml</CastXmlPath> |
|||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
|||
<SharpGenGeneratedCodeFolder>$(MSBuildThisFileDirectory)/Generated</SharpGenGeneratedCodeFolder> |
|||
</PropertyGroup> |
|||
<ItemGroup> |
|||
<PackageReference Include="SharpGenTools.Sdk" Version="1.1.2" PrivateAssets="all" /> |
|||
<PackageReference Include="SharpGen.Runtime.Com" Version="1.1.0" /> |
|||
<PackageReference Include="Avalonia" Version="0.6.2-build6362-beta" /> |
|||
<SharpGenMapping Include="Mappings.xml" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Compile Remove="Generated\LocalInterop.cs" /> |
|||
<Compile Remove="Generated\Structures.cs" /> |
|||
<Compile Remove="Generated\Functions.cs" /> |
|||
<Compile Remove="Generated\Interfaces.cs" /> |
|||
<Compile Remove="Generated\LocalInterop.cs" /> |
|||
<Compile Remove="Generated\Structures.cs" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup Condition="'$(Configuration)' == 'Release'"> |
|||
<Content Include="../../Build/Products/Release/libAvalonia.Native.OSX.dylib"> |
|||
<PackagePath>runtimes/osx/native/libAvaloniaNative.dylib</PackagePath> |
|||
<Pack>true</Pack> |
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
|||
</Content> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<None Include="$(MSBuildThisFileDirectory)..\..\runtimes\osx-x64\native\libAvalonia.Native.OSX.dylib"> |
|||
<Link>libAvalonia.Native.OSX.dylib</Link> |
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
|||
</None> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -0,0 +1,133 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Diagnostics.Contracts; |
|||
using System.Runtime.InteropServices; |
|||
using Avalonia.Controls.Platform; |
|||
using Avalonia.Input; |
|||
using Avalonia.Input.Platform; |
|||
using Avalonia.Native.Interop; |
|||
using Avalonia.OpenGL; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Rendering; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
class AvaloniaNativePlatform : IPlatformSettings, IWindowingPlatform |
|||
{ |
|||
private readonly IAvaloniaNativeFactory _factory; |
|||
|
|||
[DllImport("libAvaloniaNative")] |
|||
static extern IntPtr CreateAvaloniaNative(); |
|||
|
|||
internal static readonly MouseDevice MouseDevice = new MouseDevice(); |
|||
internal static readonly KeyboardDevice KeyboardDevice = new KeyboardDevice(); |
|||
|
|||
public Size DoubleClickSize => new Size(4, 4); |
|||
|
|||
public TimeSpan DoubleClickTime => TimeSpan.FromMilliseconds(500); //TODO
|
|||
|
|||
public static void Initialize(IntPtr factory, Action<AvaloniaNativeOptions> configure) |
|||
{ |
|||
new AvaloniaNativePlatform(new IAvaloniaNativeFactory(factory)) |
|||
.DoInitialize(configure); |
|||
} |
|||
|
|||
delegate IntPtr CreateAvaloniaNativeDelegate(); |
|||
|
|||
public static void Initialize(string library, Action<AvaloniaNativeOptions> configure) |
|||
{ |
|||
var loader = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) |
|||
? (IDynLoader)new Win32Loader() : new UnixLoader(); |
|||
var lib = loader.LoadLibrary(library); |
|||
var proc = loader.GetProcAddress(lib, "CreateAvaloniaNative", false); |
|||
var d = Marshal.GetDelegateForFunctionPointer<CreateAvaloniaNativeDelegate>(proc); |
|||
|
|||
|
|||
Initialize(d(), configure); |
|||
} |
|||
|
|||
public static void Initialize(Action<AvaloniaNativeOptions> configure) |
|||
{ |
|||
Initialize(CreateAvaloniaNative(), configure); |
|||
} |
|||
|
|||
private AvaloniaNativePlatform(IAvaloniaNativeFactory factory) |
|||
{ |
|||
_factory = factory; |
|||
} |
|||
|
|||
void DoInitialize(Action<AvaloniaNativeOptions> configure) |
|||
{ |
|||
var opts = new AvaloniaNativeOptions(_factory); |
|||
configure?.Invoke(opts); |
|||
_factory.Initialize(); |
|||
|
|||
AvaloniaLocator.CurrentMutable |
|||
.Bind<IPlatformThreadingInterface>().ToConstant(new PlatformThreadingInterface(_factory.CreatePlatformThreadingInterface())) |
|||
.Bind<IStandardCursorFactory>().ToConstant(new CursorFactory(_factory.CreateCursorFactory())) |
|||
.Bind<IPlatformIconLoader>().ToSingleton<IconLoader>() |
|||
.Bind<IKeyboardDevice>().ToConstant(KeyboardDevice) |
|||
.Bind<IMouseDevice>().ToConstant(MouseDevice) |
|||
.Bind<IPlatformSettings>().ToConstant(this) |
|||
.Bind<IWindowingPlatform>().ToConstant(this) |
|||
.Bind<IClipboard>().ToConstant(new ClipboardImpl(_factory.CreateClipboard())) |
|||
.Bind<IRenderLoop>().ToConstant(new RenderLoop()) |
|||
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60)) |
|||
.Bind<ISystemDialogImpl>().ToConstant(new SystemDialogs(_factory.CreateSystemDialogs())) |
|||
.Bind<IWindowingPlatformGlFeature>().ToConstant(new GlPlatformFeature(_factory.ObtainGlFeature())) |
|||
.Bind<AvaloniaNativeOptions>().ToConstant(opts); |
|||
} |
|||
|
|||
public IWindowImpl CreateWindow() |
|||
{ |
|||
return new WindowImpl(_factory); |
|||
} |
|||
|
|||
public IEmbeddableWindowImpl CreateEmbeddableWindow() |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public IPopupImpl CreatePopup() |
|||
{ |
|||
return new PopupImpl(_factory); |
|||
} |
|||
} |
|||
|
|||
public class AvaloniaNativeMacOptions |
|||
{ |
|||
private readonly IAvnMacOptions _opts; |
|||
private bool _showInDock; |
|||
internal AvaloniaNativeMacOptions(IAvnMacOptions opts) |
|||
{ |
|||
_opts = opts; |
|||
ShowInDock = true; |
|||
} |
|||
|
|||
public bool ShowInDock |
|||
{ |
|||
get => _showInDock; |
|||
set |
|||
{ |
|||
_showInDock = value; |
|||
_opts.ShowInDock = value ? 1 : 0; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public class AvaloniaNativeOptions |
|||
{ |
|||
public AvaloniaNativeMacOptions MacOptions { get; set; } |
|||
public bool UseDeferredRendering { get; set; } = true; |
|||
public bool UseGpu { get; set; } = false; |
|||
internal AvaloniaNativeOptions(IAvaloniaNativeFactory factory) |
|||
{ |
|||
var mac = factory.GetMacOptions(); |
|||
if (mac != null) |
|||
MacOptions = new AvaloniaNativeMacOptions(mac); |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Native; |
|||
|
|||
namespace Avalonia |
|||
{ |
|||
public static class AvaloniaNativePlatformExtensions |
|||
{ |
|||
public static T UseAvaloniaNative<T>(this T builder, |
|||
string libraryPath = null, |
|||
Action<AvaloniaNativeOptions> configure = null) |
|||
where T : AppBuilderBase<T>, new() |
|||
{ |
|||
if (libraryPath == null) |
|||
{ |
|||
builder.UseWindowingSubsystem(() => AvaloniaNativePlatform.Initialize(configure)); |
|||
} |
|||
else |
|||
{ |
|||
builder.UseWindowingSubsystem(() => AvaloniaNativePlatform.Initialize(libraryPath, configure)); |
|||
} |
|||
|
|||
return builder; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,80 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using SharpGen.Runtime; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
public class CallbackBase : SharpGen.Runtime.IUnknown |
|||
{ |
|||
private uint _refCount; |
|||
private bool _disposed; |
|||
private readonly object _lock = new object(); |
|||
private ShadowContainer _shadow; |
|||
|
|||
public CallbackBase() |
|||
{ |
|||
_refCount = 1; |
|||
} |
|||
|
|||
public ShadowContainer Shadow |
|||
{ |
|||
get => _shadow; |
|||
set |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
if (_disposed && value != null) |
|||
{ |
|||
throw new ObjectDisposedException("CallbackBase"); |
|||
} |
|||
|
|||
_shadow = value; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public uint AddRef() |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
return ++_refCount; |
|||
} |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
if (!_disposed) |
|||
{ |
|||
_disposed = true; |
|||
Release(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public uint Release() |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
_refCount--; |
|||
|
|||
if (_refCount == 0) |
|||
{ |
|||
Shadow?.Dispose(); |
|||
Shadow = null; |
|||
Destroyed(); |
|||
} |
|||
|
|||
return _refCount; |
|||
} |
|||
} |
|||
|
|||
protected virtual void Destroyed() |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System.Threading.Tasks; |
|||
using System.Runtime.InteropServices; |
|||
using Avalonia.Input.Platform; |
|||
using Avalonia.Native.Interop; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
class ClipboardImpl : IClipboard |
|||
{ |
|||
private IAvnClipboard _native; |
|||
|
|||
public ClipboardImpl(IAvnClipboard native) |
|||
{ |
|||
_native = native; |
|||
} |
|||
|
|||
public Task ClearAsync() |
|||
{ |
|||
_native.Clear(); |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
public Task<string> GetTextAsync() |
|||
{ |
|||
var outPtr = _native.GetText(); |
|||
var text = Marshal.PtrToStringAnsi(outPtr); |
|||
|
|||
return Task.FromResult(text); |
|||
} |
|||
|
|||
public Task SetTextAsync(string text) |
|||
{ |
|||
_native.Clear(); |
|||
|
|||
if (text != null) |
|||
{ |
|||
_native.SetText(text); |
|||
} |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Avalonia.Input; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Native.Interop; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
class AvaloniaNativeCursor : IPlatformHandle, IDisposable |
|||
{ |
|||
public IAvnCursor Cursor { get; private set; } |
|||
public IntPtr Handle => IntPtr.Zero; |
|||
|
|||
public string HandleDescriptor => "<none>"; |
|||
|
|||
public AvaloniaNativeCursor(IAvnCursor cursor) |
|||
{ |
|||
Cursor = cursor; |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
Cursor.Dispose(); |
|||
Cursor = null; |
|||
} |
|||
} |
|||
|
|||
class CursorFactory : IStandardCursorFactory |
|||
{ |
|||
IAvnCursorFactory _native; |
|||
|
|||
public CursorFactory(IAvnCursorFactory native) |
|||
{ |
|||
_native = native; |
|||
} |
|||
|
|||
public IPlatformHandle GetCursor(StandardCursorType cursorType) |
|||
{ |
|||
var cursor = _native.GetCursor((AvnStandardCursorType)cursorType); |
|||
return new AvaloniaNativeCursor( cursor ); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,87 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
using Avalonia.Native.Interop; |
|||
using Avalonia.Platform; |
|||
using SharpGen.Runtime; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
public class DeferredFramebuffer : ILockedFramebuffer |
|||
{ |
|||
private readonly Func<Action<IAvnWindowBase>, bool> _lockWindow; |
|||
|
|||
public DeferredFramebuffer(Func<Action<IAvnWindowBase>, bool> lockWindow, |
|||
int width, int height, Vector dpi) |
|||
{ |
|||
_lockWindow = lockWindow; |
|||
Address = Marshal.AllocHGlobal(width * height * 4); |
|||
Width = width; |
|||
Height = height; |
|||
RowBytes = width * 4; |
|||
Dpi = dpi; |
|||
Format = PixelFormat.Rgba8888; |
|||
} |
|||
|
|||
public IntPtr Address { get; set; } |
|||
public int Width { get; set; } |
|||
public int Height { get; set; } |
|||
public int RowBytes { get; set; } |
|||
public Vector Dpi { get; set; } |
|||
public PixelFormat Format { get; set; } |
|||
|
|||
class Disposer : CallbackBase |
|||
{ |
|||
private IntPtr _ptr; |
|||
|
|||
public Disposer(IntPtr ptr) |
|||
{ |
|||
_ptr = ptr; |
|||
} |
|||
|
|||
protected override void Destroyed() |
|||
{ |
|||
if(_ptr != IntPtr.Zero) |
|||
{ |
|||
Marshal.FreeHGlobal(_ptr); |
|||
_ptr = IntPtr.Zero; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
if (Address == IntPtr.Zero) |
|||
return; |
|||
|
|||
if (!_lockWindow(win => |
|||
{ |
|||
var fb = new AvnFramebuffer |
|||
{ |
|||
Data = Address, |
|||
Dpi = new AvnVector |
|||
{ |
|||
X = Dpi.X, |
|||
Y = Dpi.Y |
|||
}, |
|||
Width = Width, |
|||
Height = Height, |
|||
PixelFormat = (AvnPixelFormat)Format, |
|||
Stride = RowBytes |
|||
}; |
|||
|
|||
using (var d = new Disposer(Address)) |
|||
{ |
|||
win.ThreadSafeSetSwRenderedFrame(ref fb, d); |
|||
} |
|||
})) |
|||
{ |
|||
Marshal.FreeHGlobal(Address); |
|||
} |
|||
|
|||
Address = IntPtr.Zero; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,108 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Avalonia.Native.Interop; |
|||
using Avalonia.Rendering; |
|||
using Avalonia.VisualTree; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
public class DeferredRendererProxy : IRenderer, IRenderLoopTask, IRenderLoop |
|||
{ |
|||
public DeferredRendererProxy(IRenderRoot root, IAvnWindowBase window) |
|||
{ |
|||
if (window != null) |
|||
{ |
|||
_useLock = true; |
|||
window.AddRef(); |
|||
_window = new IAvnWindowBase(window.NativePointer); |
|||
} |
|||
_renderer = new DeferredRenderer(root, this); |
|||
_rendererTask = (IRenderLoopTask)_renderer; |
|||
} |
|||
|
|||
void IRenderLoop.Add(IRenderLoopTask i) |
|||
{ |
|||
AvaloniaLocator.Current.GetService<IRenderLoop>().Add(this); |
|||
} |
|||
|
|||
void IRenderLoop.Remove(IRenderLoopTask i) |
|||
{ |
|||
AvaloniaLocator.Current.GetService<IRenderLoop>().Remove(this); |
|||
} |
|||
|
|||
private DeferredRenderer _renderer; |
|||
private IRenderLoopTask _rendererTask; |
|||
private IAvnWindowBase _window; |
|||
private bool _useLock; |
|||
|
|||
public bool DrawFps{ |
|||
get => _renderer.DrawFps; |
|||
set => _renderer.DrawFps = value; |
|||
} |
|||
public bool DrawDirtyRects |
|||
{ |
|||
get => _renderer.DrawDirtyRects; |
|||
set => _renderer.DrawDirtyRects = value; |
|||
} |
|||
|
|||
public bool NeedsUpdate => _rendererTask.NeedsUpdate; |
|||
|
|||
public void AddDirty(IVisual visual) => _renderer.AddDirty(visual); |
|||
|
|||
public void Dispose() |
|||
{ |
|||
_renderer.Dispose(); |
|||
_window?.Dispose(); |
|||
_window = null; |
|||
} |
|||
public IEnumerable<IVisual> HitTest(Point p, IVisual root, Func<IVisual, bool> filter) |
|||
{ |
|||
return _renderer.HitTest(p, root, filter); |
|||
} |
|||
|
|||
public void Paint(Rect rect) |
|||
{ |
|||
if (NeedsUpdate) |
|||
{ |
|||
Update(TimeSpan.FromMilliseconds(Environment.TickCount)); |
|||
} |
|||
|
|||
Render(); |
|||
} |
|||
|
|||
public void Resized(Size size) => _renderer.Resized(size); |
|||
|
|||
public void Start() => _renderer.Start(); |
|||
|
|||
public void Stop() => _renderer.Stop(); |
|||
|
|||
public void Update(TimeSpan time) |
|||
{ |
|||
_rendererTask.Update(time); |
|||
} |
|||
|
|||
public void Render() |
|||
{ |
|||
if(_useLock) |
|||
{ |
|||
_rendererTask.Render(); |
|||
return; |
|||
} |
|||
if (_window == null) |
|||
return; |
|||
if (!_window.TryLock()) |
|||
return; |
|||
try |
|||
{ |
|||
_rendererTask.Render(); |
|||
} |
|||
finally |
|||
{ |
|||
_window.Unlock(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,128 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
/* |
|||
* Source code imported from https://github.com/kekekeks/evhttp-sharp
|
|||
* Source is provided under MIT license for Avalonia project and derived works |
|||
*/ |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
internal interface IDynLoader |
|||
{ |
|||
IntPtr LoadLibrary(string dll); |
|||
IntPtr GetProcAddress(IntPtr dll, string proc, bool optional); |
|||
|
|||
} |
|||
|
|||
class UnixLoader : IDynLoader |
|||
{ |
|||
// ReSharper disable InconsistentNaming
|
|||
static class LinuxImports |
|||
{ |
|||
[DllImport("libdl.so.2")] |
|||
private static extern IntPtr dlopen(string path, int flags); |
|||
|
|||
[DllImport("libdl.so.2")] |
|||
private static extern IntPtr dlsym(IntPtr handle, string symbol); |
|||
|
|||
[DllImport("libdl.so.2")] |
|||
private static extern IntPtr dlerror(); |
|||
|
|||
public static void Init() |
|||
{ |
|||
DlOpen = dlopen; |
|||
DlSym = dlsym; |
|||
DlError = dlerror; |
|||
} |
|||
} |
|||
|
|||
static class OsXImports |
|||
{ |
|||
[DllImport("/usr/lib/libSystem.dylib")] |
|||
private static extern IntPtr dlopen(string path, int flags); |
|||
|
|||
[DllImport("/usr/lib/libSystem.dylib")] |
|||
private static extern IntPtr dlsym(IntPtr handle, string symbol); |
|||
|
|||
[DllImport("/usr/lib/libSystem.dylib")] |
|||
private static extern IntPtr dlerror(); |
|||
|
|||
public static void Init() |
|||
{ |
|||
DlOpen = dlopen; |
|||
DlSym = dlsym; |
|||
DlError = dlerror; |
|||
} |
|||
|
|||
} |
|||
|
|||
[DllImport("libc")] |
|||
static extern int uname(IntPtr buf); |
|||
|
|||
static UnixLoader() |
|||
{ |
|||
var buffer = Marshal.AllocHGlobal(0x1000); |
|||
uname(buffer); |
|||
var unixName = Marshal.PtrToStringAnsi(buffer); |
|||
Marshal.FreeHGlobal(buffer); |
|||
if (unixName == "Darwin") |
|||
OsXImports.Init(); |
|||
else |
|||
LinuxImports.Init(); |
|||
} |
|||
|
|||
private static Func<string, int, IntPtr> DlOpen; |
|||
private static Func<IntPtr, string, IntPtr> DlSym; |
|||
private static Func<IntPtr> DlError; |
|||
// ReSharper restore InconsistentNaming
|
|||
|
|||
static string DlErrorString() => Marshal.PtrToStringAnsi(DlError()); |
|||
|
|||
public IntPtr LoadLibrary(string dll) |
|||
{ |
|||
var handle = DlOpen(dll, 1); |
|||
if (handle == IntPtr.Zero) |
|||
throw new Exception(DlErrorString()); |
|||
return handle; |
|||
} |
|||
|
|||
public IntPtr GetProcAddress(IntPtr dll, string proc, bool optional) |
|||
{ |
|||
var ptr = DlSym(dll, proc); |
|||
if (ptr == IntPtr.Zero && !optional) |
|||
throw new Exception(DlErrorString()); |
|||
return ptr; |
|||
} |
|||
} |
|||
|
|||
internal class Win32Loader : IDynLoader |
|||
{ |
|||
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] |
|||
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); |
|||
|
|||
[DllImport("kernel32", EntryPoint = "LoadLibraryW", SetLastError = true, CharSet = CharSet.Unicode)] |
|||
private static extern IntPtr LoadLibrary(string lpszLib); |
|||
|
|||
IntPtr IDynLoader.LoadLibrary(string dll) |
|||
{ |
|||
var handle = LoadLibrary(dll); |
|||
if (handle != IntPtr.Zero) |
|||
return handle; |
|||
var err = Marshal.GetLastWin32Error(); |
|||
|
|||
throw new Exception("Error loading " + dll + " error " + err); |
|||
} |
|||
|
|||
IntPtr IDynLoader.GetProcAddress(IntPtr dll, string proc, bool optional) |
|||
{ |
|||
var ptr = GetProcAddress(dll, proc); |
|||
if (ptr == IntPtr.Zero && !optional) |
|||
throw new Exception("Error " + Marshal.GetLastWin32Error()); |
|||
return ptr; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,134 @@ |
|||
using System; |
|||
using Avalonia.OpenGL; |
|||
using Avalonia.Native.Interop; |
|||
using System.Drawing; |
|||
using Avalonia.Threading; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
class GlPlatformFeature : IWindowingPlatformGlFeature |
|||
{ |
|||
|
|||
public GlPlatformFeature(IAvnGlFeature feature) |
|||
{ |
|||
Display = new GlDisplay(feature.ObtainDisplay()); |
|||
ImmediateContext = new GlContext(Display, feature.ObtainImmediateContext()); |
|||
} |
|||
|
|||
public IGlContext ImmediateContext { get; } |
|||
public GlDisplay Display { get; } |
|||
} |
|||
|
|||
class GlDisplay : IGlDisplay |
|||
{ |
|||
private readonly IAvnGlDisplay _display; |
|||
|
|||
public GlDisplay(IAvnGlDisplay display) |
|||
{ |
|||
_display = display; |
|||
GlInterface = new GlInterface((name, optional) => |
|||
{ |
|||
var rv = _display.GetProcAddress(name); |
|||
if (rv == IntPtr.Zero && !optional) |
|||
throw new OpenGlException($"{name} not found in system OpenGL"); |
|||
return rv; |
|||
}); |
|||
} |
|||
|
|||
public GlDisplayType Type => GlDisplayType.OpenGL2; |
|||
|
|||
public GlInterface GlInterface { get; } |
|||
|
|||
public int SampleCount => _display.GetSampleCount(); |
|||
|
|||
public int StencilSize => _display.GetStencilSize(); |
|||
|
|||
public void ClearContext() => _display.ClearContext(); |
|||
} |
|||
|
|||
class GlContext : IGlContext |
|||
{ |
|||
public IAvnGlContext Context { get; } |
|||
|
|||
public GlContext(GlDisplay display, IAvnGlContext context) |
|||
{ |
|||
Display = display; |
|||
Context = context; |
|||
} |
|||
|
|||
public IGlDisplay Display { get; } |
|||
|
|||
public void MakeCurrent(IGlSurface surface) |
|||
{ |
|||
if (surface != null) |
|||
throw new ArgumentException(nameof(surface)); |
|||
Context.MakeCurrent(); |
|||
} |
|||
} |
|||
|
|||
|
|||
class GlPlatformSurfaceRenderTarget : IGlPlatformSurfaceRenderTarget |
|||
{ |
|||
private IAvnGlSurfaceRenderTarget _target; |
|||
public GlPlatformSurfaceRenderTarget(IAvnGlSurfaceRenderTarget target) |
|||
{ |
|||
_target = target; |
|||
} |
|||
|
|||
public IGlPlatformSurfaceRenderingSession BeginDraw() |
|||
{ |
|||
var feature = (GlPlatformFeature)AvaloniaLocator.Current.GetService<IWindowingPlatformGlFeature>(); |
|||
return new GlPlatformSurfaceRenderingSession(feature.Display, _target.BeginDrawing()); |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
_target?.Dispose(); |
|||
_target = null; |
|||
} |
|||
} |
|||
|
|||
class GlPlatformSurfaceRenderingSession : IGlPlatformSurfaceRenderingSession |
|||
{ |
|||
private IAvnGlSurfaceRenderingSession _session; |
|||
|
|||
public GlPlatformSurfaceRenderingSession(GlDisplay display, IAvnGlSurfaceRenderingSession session) |
|||
{ |
|||
Display = display; |
|||
_session = session; |
|||
} |
|||
|
|||
public IGlDisplay Display { get; } |
|||
|
|||
public System.Drawing.Size PixelSize |
|||
{ |
|||
get |
|||
{ |
|||
var s = _session.GetPixelSize(); |
|||
return new System.Drawing.Size(s.Width, s.Height); |
|||
} |
|||
} |
|||
|
|||
public double Scaling => _session.GetScaling(); |
|||
|
|||
public void Dispose() |
|||
{ |
|||
_session?.Dispose(); |
|||
_session = null; |
|||
} |
|||
} |
|||
|
|||
class GlPlatformSurface : IGlPlatformSurface |
|||
{ |
|||
private readonly IAvnWindowBase _window; |
|||
|
|||
public GlPlatformSurface(IAvnWindowBase window) |
|||
{ |
|||
_window = window; |
|||
} |
|||
public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() |
|||
{ |
|||
return new GlPlatformSurfaceRenderTarget(_window.CreateGlRenderTarget()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using Avalonia.Native.Interop; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
public static class Helpers |
|||
{ |
|||
public static Point ToAvaloniaPoint (this AvnPoint pt) |
|||
{ |
|||
return new Point(pt.X, pt.Y); |
|||
} |
|||
|
|||
public static AvnPoint ToAvnPoint (this Point pt) |
|||
{ |
|||
return new AvnPoint { X = pt.X, Y = pt.Y }; |
|||
} |
|||
|
|||
public static AvnSize ToAvnSize (this Size size) |
|||
{ |
|||
return new AvnSize { Height = size.Height, Width = size.Width }; |
|||
} |
|||
|
|||
public static Size ToAvaloniaSize (this AvnSize size) |
|||
{ |
|||
return new Size(size.Width, size.Height); |
|||
} |
|||
|
|||
public static Rect ToAvaloniaRect (this AvnRect rect) |
|||
{ |
|||
return new Rect(rect.X, rect.Y, rect.Width, rect.Height); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System.IO; |
|||
using Avalonia.Platform; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
// OSX doesn't have a concept of *window* icon.
|
|||
// Icons in the title bar are only shown if there is
|
|||
// an opened file (on disk) associated with the current window
|
|||
// see http://stackoverflow.com/a/7038671/2231814
|
|||
class IconLoader : IPlatformIconLoader |
|||
{ |
|||
class IconStub : IWindowIconImpl |
|||
{ |
|||
private readonly IBitmapImpl _bitmap; |
|||
|
|||
public IconStub(IBitmapImpl bitmap) |
|||
{ |
|||
_bitmap = bitmap; |
|||
} |
|||
|
|||
public void Save(Stream outputStream) |
|||
{ |
|||
_bitmap.Save(outputStream); |
|||
} |
|||
} |
|||
|
|||
public IWindowIconImpl LoadIcon(string fileName) |
|||
{ |
|||
return new IconStub( |
|||
AvaloniaLocator.Current.GetService<IPlatformRenderInterface>().LoadBitmap(fileName)); |
|||
} |
|||
|
|||
public IWindowIconImpl LoadIcon(Stream stream) |
|||
{ |
|||
return new IconStub( |
|||
AvaloniaLocator.Current.GetService<IPlatformRenderInterface>().LoadBitmap(stream)); |
|||
} |
|||
|
|||
public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) |
|||
{ |
|||
var ms = new MemoryStream(); |
|||
bitmap.Save(ms); |
|||
ms.Seek(0, SeekOrigin.Begin); |
|||
return LoadIcon(ms); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<config id="AvaloniaNative" xmlns="urn:SharpGen.Config"> |
|||
<assembly>Avalonia.Native</assembly> |
|||
<namespace>Avalonia.Native.Interop</namespace> |
|||
<depends>SharpGen.Runtime.COM</depends> |
|||
<include-dir>$(THIS_CONFIG_PATH)/headers</include-dir> |
|||
<include file="avalonia-native.h" |
|||
namespace="Avalonia.Native.Interop" |
|||
attach="true" |
|||
pre="#define COM_GUIDS_MATERIALIZE\n"/> |
|||
<include file="com.h" |
|||
namespace="Avalonia.Native.Interop" |
|||
attach="true" |
|||
pre="#define COM_GUIDS_MATERIALIZE\n"/> |
|||
<bindings> |
|||
<bind from="HRESULT" to="SharpGen.Runtime.Result"/> |
|||
<bind from="HRESULT" to="SharpGen.Runtime.Result"/> |
|||
</bindings> |
|||
<mapping> |
|||
<remove function=".*" /> |
|||
<map interface="*.Events" callback="true" autogen-shadow="true"/> |
|||
<map interface="*.Callback" callback="true" autogen-shadow="true"/> |
|||
<map param=".*::.*::ppv" return="true"/> |
|||
<map param=".*::.*::ret" return="true"/> |
|||
<map param=".*::.*::retOut" attribute="out" return="true"/> |
|||
</mapping> |
|||
</config> |
|||
@ -0,0 +1,101 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Threading; |
|||
using Avalonia.Native.Interop; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Threading; |
|||
using SharpGen.Runtime; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
public class PlatformThreadingInterface : IPlatformThreadingInterface |
|||
{ |
|||
class TimerCallback : CallbackBase, IAvnActionCallback |
|||
{ |
|||
readonly Action _tick; |
|||
|
|||
public TimerCallback(Action tick) |
|||
{ |
|||
_tick = tick; |
|||
} |
|||
|
|||
public void Run() |
|||
{ |
|||
_tick(); |
|||
} |
|||
} |
|||
|
|||
class SignaledCallback : CallbackBase, IAvnSignaledCallback |
|||
{ |
|||
readonly PlatformThreadingInterface _parent; |
|||
|
|||
public SignaledCallback(PlatformThreadingInterface parent) |
|||
{ |
|||
_parent = parent; |
|||
} |
|||
|
|||
public void Signaled(int priority, bool priorityContainsMeaningfulValue) |
|||
{ |
|||
_parent.Signaled?.Invoke(priorityContainsMeaningfulValue ? (DispatcherPriority?)priority : null); |
|||
} |
|||
} |
|||
|
|||
readonly IAvnPlatformThreadingInterface _native; |
|||
|
|||
public PlatformThreadingInterface(IAvnPlatformThreadingInterface native) |
|||
{ |
|||
_native = native; |
|||
using (var cb = new SignaledCallback(this)) |
|||
_native.SignaledCallback = cb; |
|||
} |
|||
|
|||
public bool CurrentThreadIsLoopThread => _native.CurrentThreadIsLoopThread; |
|||
|
|||
public event Action<DispatcherPriority?> Signaled; |
|||
|
|||
public void RunLoop(CancellationToken cancellationToken) |
|||
{ |
|||
if (cancellationToken.CanBeCanceled == false) |
|||
_native.RunLoop(null); |
|||
else |
|||
{ |
|||
var l = new object(); |
|||
var cancellation = _native.CreateLoopCancellation(); |
|||
cancellationToken.Register(() => |
|||
{ |
|||
lock (l) |
|||
{ |
|||
cancellation?.Cancel(); |
|||
cancellation?.Dispose(); |
|||
cancellation = null; |
|||
} |
|||
}); |
|||
try |
|||
{ |
|||
_native.RunLoop(cancellation); |
|||
} |
|||
finally |
|||
{ |
|||
lock(l) |
|||
{ |
|||
cancellation?.Dispose(); |
|||
cancellation = null; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
public void Signal(DispatcherPriority priority) |
|||
{ |
|||
_native.Signal((int)priority); |
|||
} |
|||
|
|||
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick) |
|||
{ |
|||
using (var cb = new TimerCallback(tick)) |
|||
return _native.StartTimer((int)priority, (int)interval.TotalMilliseconds, cb); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Avalonia.Native.Interop; |
|||
using Avalonia.Platform; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
public class PopupImpl : WindowBaseImpl, IPopupImpl |
|||
{ |
|||
public PopupImpl(IAvaloniaNativeFactory factory) |
|||
{ |
|||
using (var e = new PopupEvents(this)) |
|||
{ |
|||
Init(factory.CreatePopup(e), factory.CreateScreens()); |
|||
} |
|||
} |
|||
|
|||
class PopupEvents : WindowBaseEvents, IAvnWindowEvents |
|||
{ |
|||
readonly PopupImpl _parent; |
|||
|
|||
public PopupEvents(PopupImpl parent) : base(parent) |
|||
{ |
|||
_parent = parent; |
|||
} |
|||
|
|||
bool IAvnWindowEvents.Closing() |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
void IAvnWindowEvents.WindowStateChanged(AvnWindowState state) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Avalonia.Native.Interop; |
|||
using Avalonia.Platform; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
class ScreenImpl : IScreenImpl, IDisposable |
|||
{ |
|||
private IAvnScreens _native; |
|||
|
|||
public ScreenImpl(IAvnScreens native) |
|||
{ |
|||
_native = native; |
|||
} |
|||
|
|||
public int ScreenCount => _native.GetScreenCount(); |
|||
|
|||
public Screen[] AllScreens |
|||
{ |
|||
get |
|||
{ |
|||
var count = ScreenCount; |
|||
var result = new Screen[count]; |
|||
|
|||
for(int i = 0; i < count; i++) |
|||
{ |
|||
var screen = _native.GetScreen(i); |
|||
|
|||
result[i] = new Screen(screen.Bounds.ToAvaloniaRect(), screen.WorkingArea.ToAvaloniaRect(), screen.Primary); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
|
|||
public void Dispose () |
|||
{ |
|||
_native.Dispose(); |
|||
_native = null; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Linq; |
|||
using System.Runtime.InteropServices; |
|||
using System.Threading.Tasks; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Controls.Platform; |
|||
using Avalonia.Native.Interop; |
|||
using Avalonia.Platform; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
public class SystemDialogs : ISystemDialogImpl |
|||
{ |
|||
IAvnSystemDialogs _native; |
|||
|
|||
public SystemDialogs(IAvnSystemDialogs native) |
|||
{ |
|||
_native = native; |
|||
} |
|||
|
|||
public Task<string[]> ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent) |
|||
{ |
|||
var events = new SystemDialogEvents(); |
|||
|
|||
if (dialog is OpenFileDialog ofd) |
|||
{ |
|||
_native.OpenFileDialog((parent as WindowImpl)?.Native, |
|||
events, ofd.AllowMultiple, |
|||
ofd.Title ?? "", |
|||
ofd.InitialDirectory ?? "", |
|||
ofd.InitialFileName ?? "", |
|||
string.Join(";", dialog.Filters.SelectMany(f => f.Extensions))); |
|||
} |
|||
else |
|||
{ |
|||
_native.SaveFileDialog((parent as WindowImpl)?.Native, |
|||
events, |
|||
dialog.Title ?? "", |
|||
dialog.InitialDirectory ?? "", |
|||
dialog.InitialFileName ?? "", |
|||
string.Join(";", dialog.Filters.SelectMany(f => f.Extensions))); |
|||
} |
|||
|
|||
return events.Task.ContinueWith(t => { events.Dispose(); return t.Result; }); |
|||
} |
|||
|
|||
public Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent) |
|||
{ |
|||
var events = new SystemDialogEvents(); |
|||
|
|||
_native.SelectFolderDialog((parent as WindowImpl)?.Native, events, dialog.Title ?? "", dialog.InitialDirectory ?? ""); |
|||
|
|||
return events.Task.ContinueWith(t => { events.Dispose(); return t.Result.FirstOrDefault(); }); |
|||
} |
|||
} |
|||
|
|||
public class SystemDialogEvents : CallbackBase, IAvnSystemDialogEvents |
|||
{ |
|||
private TaskCompletionSource<string[]> _tcs; |
|||
|
|||
public SystemDialogEvents() |
|||
{ |
|||
_tcs = new TaskCompletionSource<string[]>(); |
|||
} |
|||
|
|||
public Task<string[]> Task => _tcs.Task; |
|||
|
|||
public void OnCompleted(int numResults, IntPtr trFirstResultRef) |
|||
{ |
|||
string[] results = new string[numResults]; |
|||
|
|||
unsafe |
|||
{ |
|||
var ptr = (IntPtr*)trFirstResultRef.ToPointer(); |
|||
|
|||
for (int i = 0; i < numResults; i++) |
|||
{ |
|||
results[i] = Marshal.PtrToStringAnsi(*ptr); |
|||
|
|||
ptr++; |
|||
} |
|||
} |
|||
|
|||
_tcs.SetResult(results); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,100 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Native.Interop; |
|||
using Avalonia.Platform; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
public class WindowImpl : WindowBaseImpl, IWindowImpl |
|||
{ |
|||
IAvnWindow _native; |
|||
public WindowImpl(IAvaloniaNativeFactory factory) |
|||
{ |
|||
using (var e = new WindowEvents(this)) |
|||
{ |
|||
Init(_native = factory.CreateWindow(e), factory.CreateScreens()); |
|||
} |
|||
} |
|||
|
|||
class WindowEvents : WindowBaseEvents, IAvnWindowEvents |
|||
{ |
|||
readonly WindowImpl _parent; |
|||
|
|||
public WindowEvents(WindowImpl parent) : base(parent) |
|||
{ |
|||
_parent = parent; |
|||
} |
|||
|
|||
bool IAvnWindowEvents.Closing() |
|||
{ |
|||
if(_parent.Closing != null) |
|||
{ |
|||
return _parent.Closing(); |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
void IAvnWindowEvents.WindowStateChanged(AvnWindowState state) |
|||
{ |
|||
_parent.WindowStateChanged?.Invoke((WindowState)state); |
|||
} |
|||
} |
|||
|
|||
public IAvnWindow Native => _native; |
|||
|
|||
public IDisposable ShowDialog() |
|||
{ |
|||
return _native.ShowDialog(); |
|||
} |
|||
|
|||
public void CanResize(bool value) |
|||
{ |
|||
_native.CanResize = value; |
|||
} |
|||
|
|||
public void SetSystemDecorations(bool enabled) |
|||
{ |
|||
_native.HasDecorations = enabled; |
|||
} |
|||
|
|||
public void SetTitleBarColor (Avalonia.Media.Color color) |
|||
{ |
|||
_native.SetTitleBarColor(new AvnColor { Alpha = color.A, Red = color.R, Green = color.G, Blue = color.B }); |
|||
} |
|||
|
|||
public void SetTitle(string title) |
|||
{ |
|||
_native.SetTitle(title); |
|||
} |
|||
|
|||
public WindowState WindowState |
|||
{ |
|||
get |
|||
{ |
|||
return (WindowState)_native.GetWindowState(); |
|||
} |
|||
set |
|||
{ |
|||
_native.SetWindowState((AvnWindowState)value); |
|||
} |
|||
} |
|||
|
|||
public Action<WindowState> WindowStateChanged { get; set; } |
|||
|
|||
public void ShowTaskbarIcon(bool value) |
|||
{ |
|||
// NO OP On OSX
|
|||
} |
|||
|
|||
public void SetIcon(IWindowIconImpl icon) |
|||
{ |
|||
// NO OP on OSX
|
|||
} |
|||
|
|||
public Func<bool> Closing { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,351 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Controls.Platform.Surfaces; |
|||
using Avalonia.Input; |
|||
using Avalonia.Input.Raw; |
|||
using Avalonia.Native.Interop; |
|||
using Avalonia.OpenGL; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Rendering; |
|||
using Avalonia.Threading; |
|||
|
|||
namespace Avalonia.Native |
|||
{ |
|||
public class WindowBaseImpl : IWindowBaseImpl, |
|||
IFramebufferPlatformSurface |
|||
{ |
|||
IInputRoot _inputRoot; |
|||
IAvnWindowBase _native; |
|||
private object _syncRoot = new object(); |
|||
private bool _deferredRendering = false; |
|||
private bool _gpu = false; |
|||
private readonly IMouseDevice _mouse; |
|||
private readonly IKeyboardDevice _keyboard; |
|||
private readonly IStandardCursorFactory _cursorFactory; |
|||
private Size _savedLogicalSize; |
|||
private Size _lastRenderedLogicalSize; |
|||
private double _savedScaling; |
|||
private GlPlatformSurface _glSurface; |
|||
|
|||
public WindowBaseImpl() |
|||
{ |
|||
var opts = AvaloniaLocator.Current.GetService<AvaloniaNativeOptions>(); |
|||
|
|||
_gpu = opts.UseGpu; |
|||
_deferredRendering = opts.UseDeferredRendering; |
|||
|
|||
_keyboard = AvaloniaLocator.Current.GetService<IKeyboardDevice>(); |
|||
_mouse = AvaloniaLocator.Current.GetService<IMouseDevice>(); |
|||
_cursorFactory = AvaloniaLocator.Current.GetService<IStandardCursorFactory>(); |
|||
} |
|||
|
|||
protected void Init(IAvnWindowBase window, IAvnScreens screens) |
|||
{ |
|||
_native = window; |
|||
_glSurface = new GlPlatformSurface(window); |
|||
Screen = new ScreenImpl(screens); |
|||
_savedLogicalSize = ClientSize; |
|||
_savedScaling = Scaling; |
|||
} |
|||
|
|||
public Size ClientSize |
|||
{ |
|||
get |
|||
{ |
|||
var s = _native.GetClientSize(); |
|||
return new Size(s.Width, s.Height); |
|||
} |
|||
} |
|||
|
|||
public IEnumerable<object> Surfaces => new[] { |
|||
(_gpu ? _glSurface : (object)null), |
|||
this |
|||
}; |
|||
|
|||
public ILockedFramebuffer Lock() |
|||
{ |
|||
if(_deferredRendering) |
|||
{ |
|||
var w = _savedLogicalSize.Width * _savedScaling; |
|||
var h = _savedLogicalSize.Height * _savedScaling; |
|||
var dpi = _savedScaling * 96; |
|||
return new DeferredFramebuffer(cb => |
|||
{ |
|||
lock (_syncRoot) |
|||
{ |
|||
if (_native == null) |
|||
return false; |
|||
cb(_native); |
|||
_lastRenderedLogicalSize = _savedLogicalSize; |
|||
return true; |
|||
} |
|||
}, (int)w, (int)h, new Vector(dpi, dpi)); |
|||
} |
|||
|
|||
return new FramebufferWrapper(_native.GetSoftwareFramebuffer()); |
|||
} |
|||
|
|||
public Action<Rect> Paint { get; set; } |
|||
public Action<Size> Resized { get; set; } |
|||
public Action Closed { get; set; } |
|||
public IMouseDevice MouseDevice => AvaloniaNativePlatform.MouseDevice; |
|||
|
|||
|
|||
class FramebufferWrapper : ILockedFramebuffer |
|||
{ |
|||
public FramebufferWrapper(AvnFramebuffer fb) |
|||
{ |
|||
Address = fb.Data; |
|||
Width = fb.Width; |
|||
Height = fb.Height; |
|||
RowBytes = fb.Stride; |
|||
Dpi = new Vector(fb.Dpi.X, fb.Dpi.Y); |
|||
Format = (PixelFormat)fb.PixelFormat; |
|||
} |
|||
public IntPtr Address { get; set; } |
|||
public int Width { get; set; } |
|||
public int Height { get; set; } |
|||
public int RowBytes {get;set;} |
|||
public Vector Dpi { get; set; } |
|||
public PixelFormat Format { get; } |
|||
public void Dispose() |
|||
{ |
|||
// Do nothing
|
|||
} |
|||
} |
|||
|
|||
protected class WindowBaseEvents : CallbackBase, IAvnWindowBaseEvents |
|||
{ |
|||
private readonly WindowBaseImpl _parent; |
|||
|
|||
public WindowBaseEvents(WindowBaseImpl parent) |
|||
{ |
|||
_parent = parent; |
|||
} |
|||
|
|||
void IAvnWindowBaseEvents.Closed() |
|||
{ |
|||
var n = _parent._native; |
|||
_parent._native = null; |
|||
try |
|||
{ |
|||
_parent?.Closed?.Invoke(); |
|||
} |
|||
finally |
|||
{ |
|||
n?.Dispose(); |
|||
} |
|||
} |
|||
|
|||
void IAvnWindowBaseEvents.Activated() => _parent.Activated?.Invoke(); |
|||
|
|||
void IAvnWindowBaseEvents.Deactivated() => _parent.Deactivated?.Invoke(); |
|||
|
|||
void IAvnWindowBaseEvents.Paint() |
|||
{ |
|||
Dispatcher.UIThread.RunJobs(DispatcherPriority.Render); |
|||
var s = _parent.ClientSize; |
|||
_parent.Paint?.Invoke(new Rect(0, 0, s.Width, s.Height)); |
|||
} |
|||
|
|||
void IAvnWindowBaseEvents.Resized(AvnSize size) |
|||
{ |
|||
var s = new Size(size.Width, size.Height); |
|||
_parent._savedLogicalSize = s; |
|||
_parent.Resized?.Invoke(s); |
|||
} |
|||
|
|||
void IAvnWindowBaseEvents.PositionChanged(AvnPoint position) |
|||
{ |
|||
_parent.PositionChanged?.Invoke(position.ToAvaloniaPoint()); |
|||
} |
|||
|
|||
void IAvnWindowBaseEvents.RawMouseEvent(AvnRawMouseEventType type, uint timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta) |
|||
{ |
|||
_parent.RawMouseEvent(type, timeStamp, modifiers, point, delta); |
|||
} |
|||
|
|||
bool IAvnWindowBaseEvents.RawKeyEvent(AvnRawKeyEventType type, uint timeStamp, AvnInputModifiers modifiers, uint key) |
|||
{ |
|||
return _parent.RawKeyEvent(type, timeStamp, modifiers, key); |
|||
} |
|||
|
|||
bool IAvnWindowBaseEvents.RawTextInputEvent(uint timeStamp, string text) |
|||
{ |
|||
return _parent.RawTextInputEvent(timeStamp, text); |
|||
} |
|||
|
|||
|
|||
void IAvnWindowBaseEvents.ScalingChanged(double scaling) |
|||
{ |
|||
_parent._savedScaling = scaling; |
|||
_parent.ScalingChanged?.Invoke(scaling); |
|||
} |
|||
|
|||
void IAvnWindowBaseEvents.RunRenderPriorityJobs() |
|||
{ |
|||
if (_parent._deferredRendering |
|||
&& _parent._lastRenderedLogicalSize != _parent.ClientSize) |
|||
// Hack to trigger Paint event on the renderer
|
|||
_parent.Paint?.Invoke(new Rect()); |
|||
Dispatcher.UIThread.RunJobs(DispatcherPriority.Render); |
|||
} |
|||
} |
|||
|
|||
public void Activate() |
|||
{ |
|||
_native.Activate(); |
|||
} |
|||
|
|||
public bool RawTextInputEvent(uint timeStamp, string text) |
|||
{ |
|||
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1); |
|||
|
|||
var args = new RawTextInputEventArgs(_keyboard, timeStamp, text); |
|||
|
|||
Input?.Invoke(args); |
|||
|
|||
return args.Handled; |
|||
} |
|||
|
|||
public bool RawKeyEvent(AvnRawKeyEventType type, uint timeStamp, AvnInputModifiers modifiers, uint key) |
|||
{ |
|||
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1); |
|||
|
|||
var args = new RawKeyEventArgs(_keyboard, timeStamp, (RawKeyEventType)type, (Key)key, (InputModifiers)modifiers); |
|||
|
|||
Input?.Invoke(args); |
|||
|
|||
return args.Handled; |
|||
} |
|||
|
|||
public void RawMouseEvent(AvnRawMouseEventType type, uint timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta) |
|||
{ |
|||
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1); |
|||
|
|||
switch (type) |
|||
{ |
|||
case AvnRawMouseEventType.Wheel: |
|||
Input?.Invoke(new RawMouseWheelEventArgs(_mouse, timeStamp, _inputRoot, point.ToAvaloniaPoint(), new Vector(delta.X, delta.Y), (InputModifiers)modifiers)); |
|||
break; |
|||
|
|||
default: |
|||
Input?.Invoke(new RawMouseEventArgs(_mouse, timeStamp, _inputRoot, (RawMouseEventType)type, point.ToAvaloniaPoint(), (InputModifiers)modifiers)); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
public void Resize(Size clientSize) |
|||
{ |
|||
_native.Resize(clientSize.Width, clientSize.Height); |
|||
} |
|||
|
|||
public IRenderer CreateRenderer(IRenderRoot root) |
|||
{ |
|||
if (_deferredRendering) |
|||
return new DeferredRendererProxy(root, _gpu ? _native : null); |
|||
return new ImmediateRenderer(root); |
|||
} |
|||
|
|||
public virtual void Dispose() |
|||
{ |
|||
_native?.Close(); |
|||
_native?.Dispose(); |
|||
_native = null; |
|||
|
|||
(Screen as ScreenImpl)?.Dispose(); |
|||
} |
|||
|
|||
|
|||
public void Invalidate(Rect rect) |
|||
{ |
|||
if (!_deferredRendering && _native != null) |
|||
_native.Invalidate(new AvnRect { Height = rect.Height, Width = rect.Width, X = rect.X, Y = rect.Y }); |
|||
} |
|||
|
|||
public void SetInputRoot(IInputRoot inputRoot) |
|||
{ |
|||
_inputRoot = inputRoot; |
|||
} |
|||
|
|||
|
|||
public void Show() |
|||
{ |
|||
_native.Show(); |
|||
} |
|||
|
|||
|
|||
public Point Position |
|||
{ |
|||
get => _native.GetPosition().ToAvaloniaPoint(); |
|||
set => _native.SetPosition(value.ToAvnPoint()); |
|||
} |
|||
|
|||
public Point PointToClient(Point point) |
|||
{ |
|||
return _native.PointToClient(point.ToAvnPoint()).ToAvaloniaPoint(); |
|||
} |
|||
|
|||
public Point PointToScreen(Point point) |
|||
{ |
|||
return _native.PointToScreen(point.ToAvnPoint()).ToAvaloniaPoint(); |
|||
} |
|||
|
|||
public void Hide() |
|||
{ |
|||
_native.Hide(); |
|||
} |
|||
|
|||
public void BeginMoveDrag() |
|||
{ |
|||
_native.BeginMoveDrag(); |
|||
} |
|||
|
|||
public Size MaxClientSize => _native.GetMaxClientSize().ToAvaloniaSize(); |
|||
|
|||
public void SetTopmost(bool value) |
|||
{ |
|||
_native.SetTopMost(value); |
|||
} |
|||
|
|||
public double Scaling => _native.GetScaling(); |
|||
|
|||
public Action Deactivated { get; set; } |
|||
public Action Activated { get; set; } |
|||
|
|||
public void SetCursor(IPlatformHandle cursor) |
|||
{ |
|||
var newCursor = cursor as AvaloniaNativeCursor; |
|||
newCursor = newCursor ?? (_cursorFactory.GetCursor(StandardCursorType.Arrow) as AvaloniaNativeCursor); |
|||
_native.Cursor = newCursor.Cursor; |
|||
} |
|||
|
|||
public Action<Point> PositionChanged { get; set; } |
|||
|
|||
public Action<RawInputEventArgs> Input { get; set; } |
|||
|
|||
Action<double> ScalingChanged { get; set; } |
|||
|
|||
Action<double> ITopLevelImpl.ScalingChanged { get; set; } |
|||
|
|||
public IScreenImpl Screen { get; private set; } |
|||
|
|||
// TODO
|
|||
|
|||
public void SetMinMaxSize(Size minSize, Size maxSize) |
|||
{ |
|||
_native.SetMinMaxSize(minSize.ToAvnSize(), maxSize.ToAvnSize()); |
|||
} |
|||
|
|||
public void BeginResizeDrag(WindowEdge edge) |
|||
{ |
|||
|
|||
} |
|||
|
|||
public IPlatformHandle Handle => new PlatformHandle(IntPtr.Zero, "NOT SUPPORTED"); |
|||
} |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
#define COM_GUIDS_MATERIALIZE |
|||
#include "avalonia-native.h" |
|||
@ -0,0 +1,363 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
#include "com.h" |
|||
#include "key.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 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; |
|||
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, |
|||
Move, |
|||
Wheel, |
|||
NonClientLeftButtonDown |
|||
}; |
|||
|
|||
enum AvnRawKeyEventType |
|||
{ |
|||
KeyDown, |
|||
KeyUp |
|||
}; |
|||
|
|||
enum AvnInputModifiers |
|||
{ |
|||
AvnInputModifiersNone = 0, |
|||
Alt = 1, |
|||
Control = 2, |
|||
Shift = 4, |
|||
Windows = 8, |
|||
LeftMouseButton = 16, |
|||
RightMouseButton = 32, |
|||
MiddleMouseButton = 64 |
|||
}; |
|||
|
|||
enum AvnWindowState |
|||
{ |
|||
Normal, |
|||
Minimized, |
|||
Maximized, |
|||
}; |
|||
|
|||
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, |
|||
}; |
|||
|
|||
enum AvnWindowEdge |
|||
{ |
|||
WindowEdgeNorthWest, |
|||
WindowEdgeNorth, |
|||
WindowEdgeNorthEast, |
|||
WindowEdgeWest, |
|||
WindowEdgeEast, |
|||
WindowEdgeSouthWest, |
|||
WindowEdgeSouth, |
|||
WindowEdgeSouthEast |
|||
}; |
|||
|
|||
AVNCOM(IAvaloniaNativeFactory, 01) : IUnknown |
|||
{ |
|||
public: |
|||
virtual HRESULT Initialize() = 0; |
|||
virtual IAvnMacOptions* GetMacOptions() = 0; |
|||
virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv) = 0; |
|||
virtual HRESULT CreatePopup (IAvnWindowEvents* cb, 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 CreateCursorFactory(IAvnCursorFactory** ppv) = 0; |
|||
virtual HRESULT ObtainGlFeature(IAvnGlFeature** ppv) = 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 GetMaxClientSize(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 GetSoftwareFramebuffer(AvnFramebuffer*ret) = 0; |
|||
virtual bool TryLock() = 0; |
|||
virtual void Unlock() = 0; |
|||
}; |
|||
|
|||
AVNCOM(IAvnPopup, 03) : virtual IAvnWindowBase |
|||
{ |
|||
|
|||
}; |
|||
|
|||
AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase |
|||
{ |
|||
virtual HRESULT ShowDialog (IUnknown**ppv) = 0; |
|||
virtual HRESULT SetCanResize(bool value) = 0; |
|||
virtual HRESULT SetHasDecorations(bool value) = 0; |
|||
virtual HRESULT SetTitle (const char* title) = 0; |
|||
virtual HRESULT SetTitleBarColor (AvnColor color) = 0; |
|||
virtual HRESULT SetWindowState(AvnWindowState state) = 0; |
|||
virtual HRESULT GetWindowState(AvnWindowState*ret) = 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; |
|||
}; |
|||
|
|||
|
|||
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; |
|||
}; |
|||
|
|||
AVNCOM(IAvnMacOptions, 07) : IUnknown |
|||
{ |
|||
virtual HRESULT SetShowInDock(int show) = 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 void 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 (void** retOut) = 0; |
|||
virtual HRESULT SetText (char* text) = 0; |
|||
virtual HRESULT Clear() = 0; |
|||
}; |
|||
|
|||
AVNCOM(IAvnCursor, 10) : IUnknown |
|||
{ |
|||
}; |
|||
|
|||
AVNCOM(IAvnCursorFactory, 11) : IUnknown |
|||
{ |
|||
virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut) = 0; |
|||
}; |
|||
|
|||
|
|||
AVNCOM(IAvnGlFeature, 12) : IUnknown |
|||
{ |
|||
virtual HRESULT ObtainDisplay(IAvnGlDisplay**retOut) = 0; |
|||
virtual HRESULT ObtainImmediateContext(IAvnGlContext**retOut) = 0; |
|||
}; |
|||
|
|||
AVNCOM(IAvnGlDisplay, 13) : IUnknown |
|||
{ |
|||
virtual HRESULT GetSampleCount(int* ret) = 0; |
|||
virtual HRESULT GetStencilSize(int* ret) = 0; |
|||
virtual HRESULT ClearContext() = 0; |
|||
virtual void* GetProcAddress(char* proc) = 0; |
|||
}; |
|||
|
|||
AVNCOM(IAvnGlContext, 14) : IUnknown |
|||
{ |
|||
virtual HRESULT MakeCurrent() = 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; |
|||
}; |
|||
|
|||
extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative(); |
|||
@ -0,0 +1,57 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
#pragma clang diagnostic push |
|||
#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" |
|||
#ifndef COM_H_INCLUDED |
|||
#define COM_H_INCLUDED |
|||
|
|||
|
|||
typedef struct _GUID { |
|||
unsigned int Data1; |
|||
unsigned short Data2; |
|||
unsigned short Data3; |
|||
unsigned char Data4[ 8 ]; |
|||
} GUID; |
|||
typedef GUID IID; |
|||
typedef const IID* REFIID; |
|||
typedef unsigned int HRESULT; |
|||
typedef unsigned int DWORD; |
|||
typedef DWORD ULONG; |
|||
|
|||
#define STDMETHODCALLTYPE |
|||
|
|||
#define S_OK 0x0L |
|||
|
|||
#define E_NOTIMPL 0x80004001L |
|||
#define E_NOINTERFACE 0x80004002L |
|||
#define E_POINTER 0x80004003L |
|||
#define E_ABORT 0x80004004L |
|||
#define E_FAIL 0x80004005L |
|||
#define E_UNEXPECTED 0x8000FFFFL |
|||
#define E_HANDLE 0x80070006L |
|||
#define E_INVALIDARG 0x80070057L |
|||
|
|||
struct IUnknown |
|||
{ |
|||
virtual HRESULT STDMETHODCALLTYPE QueryInterface( |
|||
REFIID riid, |
|||
void **ppvObject) = 0; |
|||
|
|||
virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0; |
|||
|
|||
virtual ULONG STDMETHODCALLTYPE Release( void) = 0; |
|||
|
|||
}; |
|||
|
|||
#ifdef COM_GUIDS_MATERIALIZE |
|||
#define __IID_DEF(name,d1,d2,d3, d41, d42, d43, d44, d45, d46, d47, d48) extern "C" const GUID IID_ ## name = {0x ## d1, 0x ## d2, 0x ## d3, \ |
|||
{0x ## d41, 0x ## d42, 0x ## d42, 0x ## d42, 0x ## d42, 0x ## d42, 0x ## d42, 0x ## d42 } }; |
|||
#else |
|||
#define __IID_DEF(name,d1,d2,d3, d41, d42, d43, d44, d45, d46, d47, d48) extern "C" const GUID IID_ ## name; |
|||
#endif |
|||
#define COMINTERFACE(name,d1,d2,d3, d41, d42, d43, d44, d45, d46, d47, d48) __IID_DEF(name,d1,d2,d3, d41, d42, d43, d44, d45, d46, d47, d48) \ |
|||
struct __attribute__((annotate("uuid(" #d1 "-" #d2 "-" #d3 "-" #d41 #d42 "-" #d43 #d44 #d45 #d46 #d47 #d48 ")" ))) name |
|||
|
|||
#endif // COM_H_INCLUDED
|
|||
#pragma clang diagnostic pop |
|||
@ -0,0 +1,183 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
#include "com.h" |
|||
#pragma clang diagnostic push |
|||
#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" |
|||
#ifndef COMIMPL_H_INCLUDED |
|||
#define COMIMPL_H_INCLUDED |
|||
|
|||
#include <cstring> |
|||
|
|||
__IID_DEF(IUnknown, 0, 0, 0, C0, 00, 00, 00, 00, 00, 00, 46); |
|||
|
|||
class ComObject : public virtual IUnknown |
|||
{ |
|||
private: |
|||
unsigned int _refCount; |
|||
public: |
|||
|
|||
virtual ULONG AddRef() |
|||
{ |
|||
_refCount++; |
|||
return _refCount; |
|||
} |
|||
|
|||
|
|||
virtual ULONG Release() |
|||
{ |
|||
_refCount--; |
|||
ULONG rv = _refCount; |
|||
if(_refCount == 0) |
|||
delete(this); |
|||
return rv; |
|||
} |
|||
|
|||
ComObject() |
|||
{ |
|||
_refCount = 1; |
|||
|
|||
} |
|||
virtual ~ComObject() |
|||
{ |
|||
} |
|||
|
|||
|
|||
virtual ::HRESULT STDMETHODCALLTYPE QueryInterfaceImpl(REFIID riid, void **ppvObject) = 0; |
|||
|
|||
virtual ::HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, |
|||
void **ppvObject) |
|||
{ |
|||
if(0 == memcmp(riid, &IID_IUnknown, sizeof(GUID))) |
|||
*ppvObject = (IUnknown*)this; |
|||
else |
|||
{ |
|||
auto rv = QueryInterfaceImpl(riid, ppvObject); |
|||
if(rv != S_OK) |
|||
return rv; |
|||
} |
|||
_refCount++; |
|||
return S_OK; |
|||
} |
|||
|
|||
}; |
|||
|
|||
|
|||
#define FORWARD_IUNKNOWN() \ |
|||
virtual ULONG Release(){ \ |
|||
return ComObject::Release(); \ |
|||
} \ |
|||
virtual ULONG AddRef() \ |
|||
{ \ |
|||
return ComObject::AddRef(); \ |
|||
} \ |
|||
virtual HRESULT QueryInterface(REFIID riid, void **ppvObject) \ |
|||
{ \ |
|||
return ComObject::QueryInterface(riid, ppvObject); \ |
|||
} |
|||
|
|||
#define BEGIN_INTERFACE_MAP() public: virtual HRESULT STDMETHODCALLTYPE QueryInterfaceImpl(REFIID riid, void **ppvObject){ |
|||
#define INTERFACE_MAP_ENTRY(TInterface, IID) if(0 == memcmp(riid, &IID, sizeof(GUID))) { TInterface* casted = this; *ppvObject = casted; return S_OK; } |
|||
#define END_INTERFACE_MAP() return E_NOINTERFACE; } |
|||
#define INHERIT_INTERFACE_MAP(TBase) if(TBase::QueryInterfaceImpl(riid, ppvObject) == S_OK) return S_OK; |
|||
|
|||
|
|||
|
|||
class ComUnknownObject : public ComObject |
|||
{ |
|||
public: |
|||
FORWARD_IUNKNOWN() |
|||
virtual ::HRESULT STDMETHODCALLTYPE QueryInterfaceImpl(REFIID riid, void **ppvObject) override |
|||
{ |
|||
return E_NOINTERFACE; |
|||
}; |
|||
virtual ~ComUnknownObject(){} |
|||
}; |
|||
|
|||
template<class TInterface, GUID const* TIID> class ComSingleObject : public ComObject, public virtual TInterface |
|||
{ |
|||
BEGIN_INTERFACE_MAP() |
|||
INTERFACE_MAP_ENTRY(TInterface, *TIID) |
|||
END_INTERFACE_MAP() |
|||
|
|||
public: |
|||
virtual ~ComSingleObject(){} |
|||
}; |
|||
|
|||
template<class TInterface> |
|||
class ComPtr |
|||
{ |
|||
private: |
|||
TInterface* _obj; |
|||
public: |
|||
ComPtr() |
|||
{ |
|||
_obj = 0; |
|||
} |
|||
|
|||
ComPtr(TInterface* pObj) |
|||
{ |
|||
_obj = 0; |
|||
|
|||
if (pObj) |
|||
{ |
|||
_obj = pObj; |
|||
_obj->AddRef(); |
|||
} |
|||
} |
|||
|
|||
ComPtr(const ComPtr& ptr) |
|||
{ |
|||
_obj = 0; |
|||
|
|||
if (ptr._obj) |
|||
{ |
|||
_obj = ptr._obj; |
|||
_obj->AddRef(); |
|||
} |
|||
|
|||
} |
|||
|
|||
ComPtr& operator=(ComPtr other) |
|||
{ |
|||
if(_obj != NULL) |
|||
_obj->Release(); |
|||
_obj = other._obj; |
|||
if(_obj != NULL) |
|||
_obj->AddRef(); |
|||
return *this; |
|||
} |
|||
|
|||
~ComPtr() |
|||
{ |
|||
if (_obj) |
|||
{ |
|||
_obj->Release(); |
|||
_obj = 0; |
|||
} |
|||
} |
|||
|
|||
TInterface* getRaw() |
|||
{ |
|||
return _obj; |
|||
} |
|||
|
|||
operator TInterface*() const |
|||
{ |
|||
return _obj; |
|||
} |
|||
TInterface& operator*() const |
|||
{ |
|||
return *_obj; |
|||
} |
|||
TInterface** operator&() |
|||
{ |
|||
return &_obj; |
|||
} |
|||
TInterface* operator->() const |
|||
{ |
|||
return _obj; |
|||
} |
|||
}; |
|||
|
|||
#endif // COMIMPL_H_INCLUDED
|
|||
#pragma clang diagnostic pop |
|||
File diff suppressed because it is too large
@ -0,0 +1,2 @@ |
|||
#!/bin/sh |
|||
dotnet msbuild /t:Clean,GenerateSharpGenBindings |
|||
Loading…
Reference in new issue