committed by
GitHub
179 changed files with 2101 additions and 9500 deletions
@ -0,0 +1,133 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Controls.ApplicationLifetimes; |
||||
|
using Avalonia.Interactivity; |
||||
|
|
||||
|
namespace Avalonia.Controls.ApplicationLifetimes |
||||
|
{ |
||||
|
public class ClassicDesktopStyleApplicationLifetime : IClassicDesktopStyleApplicationLifetime, IDisposable |
||||
|
{ |
||||
|
private readonly Application _app; |
||||
|
private int _exitCode; |
||||
|
private CancellationTokenSource _cts; |
||||
|
private bool _isShuttingDown; |
||||
|
private HashSet<Window> _windows = new HashSet<Window>(); |
||||
|
|
||||
|
private static ClassicDesktopStyleApplicationLifetime _activeLifetime; |
||||
|
static ClassicDesktopStyleApplicationLifetime() |
||||
|
{ |
||||
|
Window.WindowOpenedEvent.AddClassHandler(typeof(Window), OnWindowOpened); |
||||
|
Window.WindowClosedEvent.AddClassHandler(typeof(Window), WindowClosedEvent); |
||||
|
} |
||||
|
|
||||
|
private static void WindowClosedEvent(object sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
_activeLifetime?._windows.Remove((Window)sender); |
||||
|
_activeLifetime?.HandleWindowClosed((Window)sender); |
||||
|
} |
||||
|
|
||||
|
private static void OnWindowOpened(object sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
_activeLifetime?._windows.Add((Window)sender); |
||||
|
} |
||||
|
|
||||
|
public ClassicDesktopStyleApplicationLifetime(Application app) |
||||
|
{ |
||||
|
if (_activeLifetime != null) |
||||
|
throw new InvalidOperationException( |
||||
|
"Can not have multiple active ClassicDesktopStyleApplicationLifetime instances and the previously created one was not disposed"); |
||||
|
_app = app; |
||||
|
_activeLifetime = this; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public event EventHandler<ControlledApplicationLifetimeStartupEventArgs> Startup; |
||||
|
/// <inheritdoc/>
|
||||
|
public event EventHandler<ControlledApplicationLifetimeExitEventArgs> Exit; |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public ShutdownMode ShutdownMode { get; set; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public Window MainWindow { get; set; } |
||||
|
|
||||
|
public IReadOnlyList<Window> Windows => _windows.ToList(); |
||||
|
|
||||
|
private void HandleWindowClosed(Window window) |
||||
|
{ |
||||
|
if (window == null) |
||||
|
return; |
||||
|
|
||||
|
if (_isShuttingDown) |
||||
|
return; |
||||
|
|
||||
|
if (ShutdownMode == ShutdownMode.OnLastWindowClose && _windows.Count == 0) |
||||
|
Shutdown(); |
||||
|
else if (ShutdownMode == ShutdownMode.OnMainWindowClose && window == MainWindow) |
||||
|
Shutdown(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
public void Shutdown(int exitCode = 0) |
||||
|
{ |
||||
|
if (_isShuttingDown) |
||||
|
throw new InvalidOperationException("Application is already shutting down."); |
||||
|
|
||||
|
_exitCode = exitCode; |
||||
|
_isShuttingDown = true; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
foreach (var w in Windows) |
||||
|
w.Close(); |
||||
|
var e = new ControlledApplicationLifetimeExitEventArgs(exitCode); |
||||
|
Exit?.Invoke(this, e); |
||||
|
_exitCode = e.ApplicationExitCode; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
_cts?.Cancel(); |
||||
|
_cts = null; |
||||
|
_isShuttingDown = false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public int Start(string[] args) |
||||
|
{ |
||||
|
Startup?.Invoke(this, new ControlledApplicationLifetimeStartupEventArgs(args)); |
||||
|
_cts = new CancellationTokenSource(); |
||||
|
MainWindow?.Show(); |
||||
|
_app.Run(_cts.Token); |
||||
|
Environment.ExitCode = _exitCode; |
||||
|
return _exitCode; |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
if (_activeLifetime == this) |
||||
|
_activeLifetime = null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
namespace Avalonia |
||||
|
{ |
||||
|
public static class ClassicDesktopStyleApplicationLifetimeExtensions |
||||
|
{ |
||||
|
public static int StartWithClassicDesktopLifetime<T>( |
||||
|
this T builder, string[] args, ShutdownMode shutdownMode = ShutdownMode.OnLastWindowClose) |
||||
|
where T : AppBuilderBase<T>, new() |
||||
|
{ |
||||
|
var lifetime = new ClassicDesktopStyleApplicationLifetime(builder.Instance) {ShutdownMode = shutdownMode}; |
||||
|
builder.Instance.ApplicationLifetime = lifetime; |
||||
|
builder.SetupWithoutStarting(); |
||||
|
return lifetime.Start(args); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace Avalonia.Controls.ApplicationLifetimes |
||||
|
{ |
||||
|
public interface IApplicationLifetime |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Avalonia.Controls.ApplicationLifetimes |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Controls application lifetime in classic desktop style
|
||||
|
/// </summary>
|
||||
|
public interface IClassicDesktopStyleApplicationLifetime : IControlledApplicationLifetime |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets or sets the <see cref="ShutdownMode"/>. This property indicates whether the application is shutdown explicitly or implicitly.
|
||||
|
/// If <see cref="ShutdownMode"/> is set to OnExplicitShutdown the application is only closes if Shutdown is called.
|
||||
|
/// The default is OnLastWindowClose
|
||||
|
/// </summary>
|
||||
|
/// <value>
|
||||
|
/// The shutdown mode.
|
||||
|
/// </value>
|
||||
|
ShutdownMode ShutdownMode { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the main window of the application.
|
||||
|
/// </summary>
|
||||
|
/// <value>
|
||||
|
/// The main window.
|
||||
|
/// </value>
|
||||
|
Window MainWindow { get; set; } |
||||
|
|
||||
|
IReadOnlyList<Window> Windows { get; } |
||||
|
} |
||||
|
} |
||||
@ -1,22 +1,19 @@ |
|||||
using System; |
using System; |
||||
|
|
||||
namespace Avalonia.Controls |
namespace Avalonia.Controls.ApplicationLifetimes |
||||
{ |
{ |
||||
/// <summary>
|
public interface IControlledApplicationLifetime : IApplicationLifetime |
||||
/// Sends events about the application lifecycle.
|
|
||||
/// </summary>
|
|
||||
public interface IApplicationLifecycle |
|
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// Sent when the application is starting up.
|
/// Sent when the application is starting up.
|
||||
/// </summary>
|
/// </summary>
|
||||
event EventHandler<StartupEventArgs> Startup; |
event EventHandler<ControlledApplicationLifetimeStartupEventArgs> Startup; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Sent when the application is exiting.
|
/// Sent when the application is exiting.
|
||||
/// </summary>
|
/// </summary>
|
||||
event EventHandler<ExitEventArgs> Exit; |
event EventHandler<ControlledApplicationLifetimeExitEventArgs> Exit; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Shuts down the application and sets the exit code that is returned to the operating system when the application exits.
|
/// Shuts down the application and sets the exit code that is returned to the operating system when the application exits.
|
||||
/// </summary>
|
/// </summary>
|
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace Avalonia.Controls.ApplicationLifetimes |
||||
|
{ |
||||
|
public interface ISingleViewApplicationLifetime : IApplicationLifetime |
||||
|
{ |
||||
|
Control MainView { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
// 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 System.Linq; |
||||
|
|
||||
|
namespace Avalonia.Controls.ApplicationLifetimes |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Contains the arguments for the <see cref="IClassicDesktopStyleApplicationLifetime.Startup"/> event.
|
||||
|
/// </summary>
|
||||
|
public class ControlledApplicationLifetimeStartupEventArgs : EventArgs |
||||
|
{ |
||||
|
public ControlledApplicationLifetimeStartupEventArgs(IEnumerable<string> args) |
||||
|
{ |
||||
|
Args = args?.ToArray() ?? Array.Empty<string>(); |
||||
|
} |
||||
|
|
||||
|
public string[] Args { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,67 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Input; |
||||
|
using Avalonia.Threading; |
||||
|
|
||||
|
namespace Avalonia.Controls |
||||
|
{ |
||||
|
public static class DesktopApplicationExtensions |
||||
|
{ |
||||
|
[Obsolete("Running application without a cancellation token and a lifetime is no longer supported, see https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes for details", true)] |
||||
|
public static void Run(this Application app) => throw new NotSupportedException(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// On desktop-style platforms runs the application's main loop until closable is closed
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// Consider using StartWithDesktopStyleLifetime instead, see https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes for details
|
||||
|
/// </remarks>
|
||||
|
public static void Run(this Application app, ICloseable closable) |
||||
|
{ |
||||
|
var cts = new CancellationTokenSource(); |
||||
|
closable.Closed += (s, e) => cts.Cancel(); |
||||
|
|
||||
|
app.Run(cts.Token); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// On desktop-style platforms runs the application's main loop until main window is closed
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// Consider using StartWithDesktopStyleLifetime instead, see https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes for details
|
||||
|
/// </remarks>
|
||||
|
public static void Run(this Application app, Window mainWindow) |
||||
|
{ |
||||
|
if (mainWindow == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(mainWindow)); |
||||
|
} |
||||
|
var cts = new CancellationTokenSource(); |
||||
|
mainWindow.Closed += (_, __) => cts.Cancel(); |
||||
|
if (!mainWindow.IsVisible) |
||||
|
{ |
||||
|
mainWindow.Show(); |
||||
|
} |
||||
|
app.Run(cts.Token); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// On desktop-style platforms runs the application's main loop with custom CancellationToken
|
||||
|
/// without setting a lifetime.
|
||||
|
/// </summary>
|
||||
|
/// <param name="token">The token to track.</param>
|
||||
|
public static void Run(this Application app, CancellationToken token) |
||||
|
{ |
||||
|
Dispatcher.UIThread.MainLoop(token); |
||||
|
} |
||||
|
|
||||
|
public static void RunWithMainWindow<TWindow>(this Application app) |
||||
|
where TWindow : Avalonia.Controls.Window, new() |
||||
|
{ |
||||
|
var window = new TWindow(); |
||||
|
window.Show(); |
||||
|
app.Run(window); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
@ -1,36 +0,0 @@ |
|||||
// 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 System.Linq; |
|
||||
|
|
||||
namespace Avalonia.Controls |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Contains the arguments for the <see cref="IApplicationLifecycle.Startup"/> event.
|
|
||||
/// </summary>
|
|
||||
public class StartupEventArgs : EventArgs |
|
||||
{ |
|
||||
private string[] _args; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the command line arguments that were passed to the application.
|
|
||||
/// </summary>
|
|
||||
public IReadOnlyList<string> Args => _args ?? (_args = GetArgs()); |
|
||||
|
|
||||
private static string[] GetArgs() |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
var args = Environment.GetCommandLineArgs(); |
|
||||
|
|
||||
return args.Length > 1 ? args.Skip(1).ToArray() : new string[0]; |
|
||||
} |
|
||||
catch (NotSupportedException) |
|
||||
{ |
|
||||
return new string[0]; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,134 +0,0 @@ |
|||||
// 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.Collections; |
|
||||
using System.Collections.Generic; |
|
||||
|
|
||||
using Avalonia.Controls; |
|
||||
|
|
||||
namespace Avalonia |
|
||||
{ |
|
||||
public class WindowCollection : IReadOnlyList<Window> |
|
||||
{ |
|
||||
private readonly Application _application; |
|
||||
private readonly List<Window> _windows = new List<Window>(); |
|
||||
|
|
||||
public WindowCollection(Application application) |
|
||||
{ |
|
||||
_application = application; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
/// <summary>
|
|
||||
/// Gets the number of elements in the collection.
|
|
||||
/// </summary>
|
|
||||
public int Count => _windows.Count; |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
/// <summary>
|
|
||||
/// Gets the <see cref="T:Avalonia.Controls.Window" /> at the specified index.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The <see cref="T:Avalonia.Controls.Window" />.
|
|
||||
/// </value>
|
|
||||
/// <param name="index">The index.</param>
|
|
||||
/// <returns></returns>
|
|
||||
public Window this[int index] => _windows[index]; |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
/// <summary>
|
|
||||
/// Returns an enumerator that iterates through the collection.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// An enumerator that can be used to iterate through the collection.
|
|
||||
/// </returns>
|
|
||||
public IEnumerator<Window> GetEnumerator() |
|
||||
{ |
|
||||
return _windows.GetEnumerator(); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
/// <summary>
|
|
||||
/// Returns an enumerator that iterates through a collection.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.
|
|
||||
/// </returns>
|
|
||||
IEnumerator IEnumerable.GetEnumerator() |
|
||||
{ |
|
||||
return GetEnumerator(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Adds the specified window.
|
|
||||
/// </summary>
|
|
||||
/// <param name="window">The window.</param>
|
|
||||
internal void Add(Window window) |
|
||||
{ |
|
||||
if (window == null) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
_windows.Add(window); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Removes the specified window.
|
|
||||
/// </summary>
|
|
||||
/// <param name="window">The window.</param>
|
|
||||
internal void Remove(Window window) |
|
||||
{ |
|
||||
if (window == null) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
_windows.Remove(window); |
|
||||
|
|
||||
OnRemoveWindow(window); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Closes all windows and removes them from the underlying collection.
|
|
||||
/// </summary>
|
|
||||
internal void Clear() |
|
||||
{ |
|
||||
while (_windows.Count > 0) |
|
||||
{ |
|
||||
_windows[0].Close(true); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private void OnRemoveWindow(Window window) |
|
||||
{ |
|
||||
if (window == null) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if (_application.IsShuttingDown) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
switch (_application.ShutdownMode) |
|
||||
{ |
|
||||
case ShutdownMode.OnLastWindowClose: |
|
||||
if (Count == 0) |
|
||||
{ |
|
||||
_application.Shutdown(); |
|
||||
} |
|
||||
|
|
||||
break; |
|
||||
case ShutdownMode.OnMainWindowClose: |
|
||||
if (window == _application.MainWindow) |
|
||||
{ |
|
||||
_application.Shutdown(); |
|
||||
} |
|
||||
|
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,11 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
|
||||
<PropertyGroup> |
|
||||
<TargetFramework>netstandard2.0</TargetFramework> |
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
|
||||
<DefineConstants>$(DefineConstants);GTK3_PINVOKE</DefineConstants> |
|
||||
<PackageId>Avalonia.Gtk3</PackageId> |
|
||||
</PropertyGroup> |
|
||||
<ItemGroup> |
|
||||
<ProjectReference Include="..\..\..\packages\Avalonia\Avalonia.csproj" /> |
|
||||
</ItemGroup> |
|
||||
</Project> |
|
||||
@ -1,51 +0,0 @@ |
|||||
using System; |
|
||||
using System.Runtime.InteropServices; |
|
||||
using System.Threading.Tasks; |
|
||||
using Avalonia.Gtk3.Interop; |
|
||||
using Avalonia.Input.Platform; |
|
||||
using Avalonia.Platform.Interop; |
|
||||
|
|
||||
namespace Avalonia.Gtk3 |
|
||||
{ |
|
||||
class ClipboardImpl : IClipboard |
|
||||
{ |
|
||||
|
|
||||
IntPtr GetClipboard() => Native.GtkClipboardGetForDisplay(Native.GdkGetDefaultDisplay(), IntPtr.Zero); |
|
||||
|
|
||||
static void OnText(IntPtr clipboard, IntPtr utf8string, IntPtr userdata) |
|
||||
{ |
|
||||
var handle = GCHandle.FromIntPtr(userdata); |
|
||||
|
|
||||
((TaskCompletionSource<string>) handle.Target) |
|
||||
.TrySetResult(Utf8Buffer.StringFromPtr(utf8string)); |
|
||||
handle.Free(); |
|
||||
} |
|
||||
|
|
||||
private static readonly Native.D.GtkClipboardTextReceivedFunc OnTextDelegate = OnText; |
|
||||
|
|
||||
static ClipboardImpl() |
|
||||
{ |
|
||||
GCHandle.Alloc(OnTextDelegate); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetTextAsync() |
|
||||
{ |
|
||||
var tcs = new TaskCompletionSource<string>(); |
|
||||
Native.GtkClipboardRequestText(GetClipboard(), OnTextDelegate, GCHandle.ToIntPtr(GCHandle.Alloc(tcs))); |
|
||||
return tcs.Task; |
|
||||
} |
|
||||
|
|
||||
public Task SetTextAsync(string text) |
|
||||
{ |
|
||||
using (var buf = new Utf8Buffer(text)) |
|
||||
Native.GtkClipboardSetText(GetClipboard(), buf, buf.ByteLen); |
|
||||
return Task.FromResult(0); |
|
||||
} |
|
||||
|
|
||||
public Task ClearAsync() |
|
||||
{ |
|
||||
Native.GtkClipboardRequestClear(GetClipboard()); |
|
||||
return Task.FromResult(0); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,84 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using Avalonia.Gtk3.Interop; |
|
||||
using Avalonia.Input; |
|
||||
using Avalonia.Platform; |
|
||||
using Avalonia.Platform.Interop; |
|
||||
using CursorType = Avalonia.Gtk3.GdkCursorType; |
|
||||
namespace Avalonia.Gtk3 |
|
||||
{ |
|
||||
class CursorFactory : IStandardCursorFactory |
|
||||
{ |
|
||||
private static readonly Dictionary<StandardCursorType, object> CursorTypeMapping = new Dictionary |
|
||||
<StandardCursorType, object> |
|
||||
{ |
|
||||
{StandardCursorType.None, CursorType.Blank}, |
|
||||
{StandardCursorType.AppStarting, CursorType.Watch}, |
|
||||
{StandardCursorType.Arrow, CursorType.LeftPtr}, |
|
||||
{StandardCursorType.Cross, CursorType.Cross}, |
|
||||
{StandardCursorType.Hand, CursorType.Hand1}, |
|
||||
{StandardCursorType.Ibeam, CursorType.Xterm}, |
|
||||
{StandardCursorType.No, "gtk-cancel"}, |
|
||||
{StandardCursorType.SizeAll, CursorType.Sizing}, |
|
||||
//{ StandardCursorType.SizeNorthEastSouthWest, 32643 },
|
|
||||
{StandardCursorType.SizeNorthSouth, CursorType.SbVDoubleArrow}, |
|
||||
//{ StandardCursorType.SizeNorthWestSouthEast, 32642 },
|
|
||||
{StandardCursorType.SizeWestEast, CursorType.SbHDoubleArrow}, |
|
||||
{StandardCursorType.UpArrow, CursorType.BasedArrowUp}, |
|
||||
{StandardCursorType.Wait, CursorType.Watch}, |
|
||||
{StandardCursorType.Help, "gtk-help"}, |
|
||||
{StandardCursorType.TopSide, CursorType.TopSide}, |
|
||||
{StandardCursorType.BottomSize, CursorType.BottomSide}, |
|
||||
{StandardCursorType.LeftSide, CursorType.LeftSide}, |
|
||||
{StandardCursorType.RightSide, CursorType.RightSide}, |
|
||||
{StandardCursorType.TopLeftCorner, CursorType.TopLeftCorner}, |
|
||||
{StandardCursorType.TopRightCorner, CursorType.TopRightCorner}, |
|
||||
{StandardCursorType.BottomLeftCorner, CursorType.BottomLeftCorner}, |
|
||||
{StandardCursorType.BottomRightCorner, CursorType.BottomRightCorner}, |
|
||||
{StandardCursorType.DragCopy, CursorType.CenterPtr}, |
|
||||
{StandardCursorType.DragMove, CursorType.Fleur}, |
|
||||
{StandardCursorType.DragLink, CursorType.Cross}, |
|
||||
}; |
|
||||
|
|
||||
private static readonly Dictionary<StandardCursorType, IPlatformHandle> Cache = |
|
||||
new Dictionary<StandardCursorType, IPlatformHandle>(); |
|
||||
|
|
||||
private IntPtr GetCursor(object desc) |
|
||||
{ |
|
||||
IntPtr rv; |
|
||||
var name = desc as string; |
|
||||
if (name != null) |
|
||||
{ |
|
||||
var theme = Native.GtkIconThemeGetDefault(); |
|
||||
IntPtr icon, error; |
|
||||
using (var u = new Utf8Buffer(name)) |
|
||||
icon = Native.GtkIconThemeLoadIcon(theme, u, 32, 0, out error); |
|
||||
rv = icon == IntPtr.Zero |
|
||||
? Native.GdkCursorNew(GdkCursorType.XCursor) |
|
||||
: Native.GdkCursorNewFromPixbuf(Native.GdkGetDefaultDisplay(), icon, 0, 0); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
rv = Native.GdkCursorNew((CursorType)desc); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
return rv; |
|
||||
} |
|
||||
|
|
||||
public IPlatformHandle GetCursor(StandardCursorType cursorType) |
|
||||
{ |
|
||||
IPlatformHandle rv; |
|
||||
if (!Cache.TryGetValue(cursorType, out rv)) |
|
||||
{ |
|
||||
Cache[cursorType] = |
|
||||
rv = |
|
||||
new PlatformHandle( |
|
||||
GetCursor(CursorTypeMapping[cursorType]), |
|
||||
"GTKCURSOR"); |
|
||||
} |
|
||||
|
|
||||
return rv; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,62 +0,0 @@ |
|||||
using System; |
|
||||
using Avalonia.Controls.Platform.Surfaces; |
|
||||
using Avalonia.Platform; |
|
||||
using Avalonia.Threading; |
|
||||
|
|
||||
namespace Avalonia.Gtk3 |
|
||||
{ |
|
||||
class FramebufferManager : IFramebufferPlatformSurface, IDisposable |
|
||||
{ |
|
||||
private readonly WindowBaseImpl _window; |
|
||||
public FramebufferManager(WindowBaseImpl window) |
|
||||
{ |
|
||||
_window = window; |
|
||||
} |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
//
|
|
||||
} |
|
||||
|
|
||||
public ILockedFramebuffer Lock() |
|
||||
{ |
|
||||
// This method may be called from non-UI thread, don't touch anything that calls back to GTK/GDK
|
|
||||
var s = _window.ClientSize; |
|
||||
var width = Math.Max(1, (int) s.Width); |
|
||||
var height = Math.Max(1, (int) s.Height); |
|
||||
|
|
||||
|
|
||||
if (!Dispatcher.UIThread.CheckAccess() && Gtk3Platform.DisplayClassName.ToLower().Contains("x11")) |
|
||||
{ |
|
||||
var x11 = LockX11Framebuffer(width, height); |
|
||||
if (x11 != null) |
|
||||
return x11; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
return new ImageSurfaceFramebuffer(_window, width, height, _window.LastKnownScaleFactor); |
|
||||
} |
|
||||
|
|
||||
private static int X11ErrorHandler(IntPtr d, ref X11.XErrorEvent e) |
|
||||
{ |
|
||||
return 0; |
|
||||
} |
|
||||
|
|
||||
private static X11.XErrorHandler X11ErrorHandlerDelegate = X11ErrorHandler; |
|
||||
|
|
||||
private static IntPtr X11Display; |
|
||||
private ILockedFramebuffer LockX11Framebuffer(int width, int height) |
|
||||
{ |
|
||||
if (!_window.GdkWindowHandle.HasValue) |
|
||||
return null; |
|
||||
if (X11Display == IntPtr.Zero) |
|
||||
{ |
|
||||
X11Display = X11.XOpenDisplay(IntPtr.Zero); |
|
||||
if (X11Display == IntPtr.Zero) |
|
||||
return null; |
|
||||
X11.XSetErrorHandler(X11ErrorHandlerDelegate); |
|
||||
} |
|
||||
return new X11Framebuffer(X11Display, _window.GdkWindowHandle.Value, width, height, _window.LastKnownScaleFactor); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,86 +0,0 @@ |
|||||
namespace Avalonia.Gtk3 |
|
||||
{ |
|
||||
enum GdkCursorType |
|
||||
{ |
|
||||
Blank = -2, |
|
||||
CursorIsPixmap = -1, |
|
||||
XCursor = 0, |
|
||||
Arrow = 2, |
|
||||
BasedArrowDown = 4, |
|
||||
BasedArrowUp = 6, |
|
||||
Boat = 8, |
|
||||
Bogosity = 10, |
|
||||
BottomLeftCorner = 12, |
|
||||
BottomRightCorner = 14, |
|
||||
BottomSide = 16, |
|
||||
BottomTee = 18, |
|
||||
BoxSpiral = 20, |
|
||||
CenterPtr = 22, |
|
||||
Circle = 24, |
|
||||
Clock = 26, |
|
||||
CoffeeMug = 28, |
|
||||
Cross = 30, |
|
||||
CrossReverse = 32, |
|
||||
Crosshair = 34, |
|
||||
DiamondCross = 36, |
|
||||
Dot = 38, |
|
||||
Dotbox = 40, |
|
||||
DoubleArrow = 42, |
|
||||
DraftLarge = 44, |
|
||||
DraftSmall = 46, |
|
||||
DrapedBox = 48, |
|
||||
Exchange = 50, |
|
||||
Fleur = 52, |
|
||||
Gobbler = 54, |
|
||||
Gumby = 56, |
|
||||
Hand1 = 58, |
|
||||
Hand2 = 60, |
|
||||
Heart = 62, |
|
||||
Icon = 64, |
|
||||
IronCross = 66, |
|
||||
LeftPtr = 68, |
|
||||
LeftSide = 70, |
|
||||
LeftTee = 72, |
|
||||
Leftbutton = 74, |
|
||||
LlAngle = 76, |
|
||||
LrAngle = 78, |
|
||||
Man = 80, |
|
||||
Middlebutton = 82, |
|
||||
Mouse = 84, |
|
||||
Pencil = 86, |
|
||||
Pirate = 88, |
|
||||
Plus = 90, |
|
||||
QuestionArrow = 92, |
|
||||
RightPtr = 94, |
|
||||
RightSide = 96, |
|
||||
RightTee = 98, |
|
||||
Rightbutton = 100, |
|
||||
RtlLogo = 102, |
|
||||
Sailboat = 104, |
|
||||
SbDownArrow = 106, |
|
||||
SbHDoubleArrow = 108, |
|
||||
SbLeftArrow = 110, |
|
||||
SbRightArrow = 112, |
|
||||
SbUpArrow = 114, |
|
||||
SbVDoubleArrow = 116, |
|
||||
Shuttle = 118, |
|
||||
Sizing = 120, |
|
||||
Spider = 122, |
|
||||
Spraycan = 124, |
|
||||
Star = 126, |
|
||||
Target = 128, |
|
||||
Tcross = 130, |
|
||||
TopLeftArrow = 132, |
|
||||
TopLeftCorner = 134, |
|
||||
TopRightCorner = 136, |
|
||||
TopSide = 138, |
|
||||
TopTee = 140, |
|
||||
Trek = 142, |
|
||||
UlAngle = 144, |
|
||||
Umbrella = 146, |
|
||||
UrAngle = 148, |
|
||||
Watch = 150, |
|
||||
Xterm = 152, |
|
||||
LastCursor = 153, |
|
||||
} |
|
||||
} |
|
||||
File diff suppressed because it is too large
@ -1,115 +0,0 @@ |
|||||
using System; |
|
||||
using System.Runtime.InteropServices; |
|
||||
using System.Threading; |
|
||||
using System.Threading.Tasks; |
|
||||
using Avalonia.Controls; |
|
||||
using Avalonia.Controls.Platform; |
|
||||
using Avalonia.Gtk3.Interop; |
|
||||
using Avalonia.Platform; |
|
||||
using Avalonia.Platform.Interop; |
|
||||
|
|
||||
namespace Avalonia.Gtk3 |
|
||||
{ |
|
||||
public class Gtk3ForeignX11SystemDialog : ISystemDialogImpl |
|
||||
{ |
|
||||
private Task<bool> _initialized; |
|
||||
private SystemDialogBase _inner = new SystemDialogBase(); |
|
||||
|
|
||||
|
|
||||
public async Task<string[]> ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent) |
|
||||
{ |
|
||||
await EnsureInitialized(); |
|
||||
var xid = parent.Handle.Handle; |
|
||||
return await await RunOnGtkThread( |
|
||||
() => _inner.ShowFileDialogAsync(dialog, GtkWindow.Null, chooser => UpdateParent(chooser, xid))); |
|
||||
} |
|
||||
|
|
||||
public async Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent) |
|
||||
{ |
|
||||
await EnsureInitialized(); |
|
||||
var xid = parent.Handle.Handle; |
|
||||
return await await RunOnGtkThread( |
|
||||
() => _inner.ShowFolderDialogAsync(dialog, GtkWindow.Null, chooser => UpdateParent(chooser, xid))); |
|
||||
} |
|
||||
|
|
||||
void UpdateParent(GtkFileChooser chooser, IntPtr xid) |
|
||||
{ |
|
||||
Native.GtkWidgetRealize(chooser); |
|
||||
var window = Native.GtkWidgetGetWindow(chooser); |
|
||||
var parent = Native.GdkWindowForeignNewForDisplay(GdkDisplay, xid); |
|
||||
if (window != IntPtr.Zero && parent != IntPtr.Zero) |
|
||||
Native.GdkWindowSetTransientFor(window, parent); |
|
||||
} |
|
||||
|
|
||||
async Task EnsureInitialized() |
|
||||
{ |
|
||||
if (_initialized == null) |
|
||||
{ |
|
||||
var tcs = new TaskCompletionSource<bool>(); |
|
||||
_initialized = tcs.Task; |
|
||||
new Thread(() => GtkThread(tcs)) |
|
||||
{ |
|
||||
IsBackground = true |
|
||||
}.Start(); |
|
||||
} |
|
||||
|
|
||||
if (!(await _initialized)) |
|
||||
throw new Exception("Unable to initialize GTK on separate thread"); |
|
||||
|
|
||||
} |
|
||||
|
|
||||
Task<T> RunOnGtkThread<T>(Func<T> action) |
|
||||
{ |
|
||||
var tcs = new TaskCompletionSource<T>(); |
|
||||
GlibTimeout.Add(0, 0, () => |
|
||||
{ |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
tcs.SetResult(action()); |
|
||||
} |
|
||||
catch (Exception e) |
|
||||
{ |
|
||||
tcs.TrySetException(e); |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
}); |
|
||||
return tcs.Task; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
void GtkThread(TaskCompletionSource<bool> tcs) |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
X11.XInitThreads(); |
|
||||
}catch{} |
|
||||
Resolver.Resolve(); |
|
||||
if (Native.GdkWindowForeignNewForDisplay == null) |
|
||||
throw new Exception("gdk_x11_window_foreign_new_for_display is not found in your libgdk-3.so"); |
|
||||
using (var backends = new Utf8Buffer("x11")) |
|
||||
Native.GdkSetAllowedBackends?.Invoke(backends); |
|
||||
if (!Native.GtkInitCheck(0, IntPtr.Zero)) |
|
||||
{ |
|
||||
tcs.SetResult(false); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
using (var utf = new Utf8Buffer($"avalonia.app.a{Guid.NewGuid().ToString("N")}")) |
|
||||
App = Native.GtkApplicationNew(utf, 0); |
|
||||
if (App == IntPtr.Zero) |
|
||||
{ |
|
||||
tcs.SetResult(false); |
|
||||
return; |
|
||||
} |
|
||||
GdkDisplay = Native.GdkGetDefaultDisplay(); |
|
||||
tcs.SetResult(true); |
|
||||
while (true) |
|
||||
Native.GtkMainIteration(); |
|
||||
} |
|
||||
|
|
||||
private IntPtr GdkDisplay { get; set; } |
|
||||
private IntPtr App { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,168 +0,0 @@ |
|||||
using System; |
|
||||
using System.Runtime.InteropServices; |
|
||||
using System.Threading; |
|
||||
using Avalonia.Controls; |
|
||||
using Avalonia.Controls.Platform; |
|
||||
using Avalonia.Gtk3; |
|
||||
using Avalonia.Gtk3.Interop; |
|
||||
using Avalonia.Input; |
|
||||
using Avalonia.Input.Platform; |
|
||||
using Avalonia.OpenGL; |
|
||||
using Avalonia.Platform; |
|
||||
using Avalonia.Platform.Interop; |
|
||||
using Avalonia.Rendering; |
|
||||
using Avalonia.Threading; |
|
||||
|
|
||||
namespace Avalonia.Gtk3 |
|
||||
{ |
|
||||
public class Gtk3Platform : IWindowingPlatform, IPlatformSettings, IPlatformThreadingInterface |
|
||||
{ |
|
||||
internal static readonly Gtk3Platform Instance = new Gtk3Platform(); |
|
||||
internal static readonly MouseDevice Mouse = new MouseDevice(); |
|
||||
internal static readonly KeyboardDevice Keyboard = new KeyboardDevice(); |
|
||||
internal static IntPtr App { get; set; } |
|
||||
internal static string DisplayClassName; |
|
||||
public static bool UseDeferredRendering = true; |
|
||||
private static bool s_gtkInitialized; |
|
||||
|
|
||||
static bool EnvOption(string option, bool def, bool? specified) |
|
||||
{ |
|
||||
bool? Parse(string env) |
|
||||
{ |
|
||||
var v = Environment.GetEnvironmentVariable("AVALONIA_GTK3_" + env); |
|
||||
if (v == null) |
|
||||
return null; |
|
||||
if (v.ToLowerInvariant() == "false" || v == "0") |
|
||||
return false; |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
var overridden = Parse(option + "_OVERRIDE"); |
|
||||
if (overridden.HasValue) |
|
||||
return overridden.Value; |
|
||||
if (specified.HasValue) |
|
||||
return specified.Value; |
|
||||
var envValue = Parse(option); |
|
||||
return envValue ?? def; |
|
||||
} |
|
||||
|
|
||||
public static void Initialize(Gtk3PlatformOptions options) |
|
||||
{ |
|
||||
Resolver.Custom = options.CustomResolver; |
|
||||
UseDeferredRendering = EnvOption("USE_DEFERRED_RENDERING", true, options.UseDeferredRendering); |
|
||||
var useGpu = EnvOption("USE_GPU", true, options.UseGpuAcceleration); |
|
||||
if (!s_gtkInitialized) |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
X11.XInitThreads(); |
|
||||
}catch{} |
|
||||
Resolver.Resolve(); |
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) |
|
||||
using (var backends = new Utf8Buffer("x11")) |
|
||||
Native.GdkSetAllowedBackends?.Invoke(backends); |
|
||||
Native.GtkInit(0, IntPtr.Zero); |
|
||||
var disp = Native.GdkGetDefaultDisplay(); |
|
||||
DisplayClassName = |
|
||||
Utf8Buffer.StringFromPtr(Native.GTypeName(Marshal.ReadIntPtr(Marshal.ReadIntPtr(disp)))); |
|
||||
|
|
||||
using (var utf = new Utf8Buffer($"avalonia.app.a{Guid.NewGuid().ToString("N")}")) |
|
||||
App = Native.GtkApplicationNew(utf, 0); |
|
||||
//Mark current thread as UI thread
|
|
||||
s_tlsMarker = true; |
|
||||
s_gtkInitialized = true; |
|
||||
} |
|
||||
AvaloniaLocator.CurrentMutable.Bind<IWindowingPlatform>().ToConstant(Instance) |
|
||||
.Bind<IClipboard>().ToSingleton<ClipboardImpl>() |
|
||||
.Bind<IStandardCursorFactory>().ToConstant(new CursorFactory()) |
|
||||
.Bind<IKeyboardDevice>().ToConstant(Keyboard) |
|
||||
.Bind<IPlatformSettings>().ToConstant(Instance) |
|
||||
.Bind<IPlatformThreadingInterface>().ToConstant(Instance) |
|
||||
.Bind<ISystemDialogImpl>().ToSingleton<SystemDialog>() |
|
||||
.Bind<IRenderLoop>().ToConstant(new RenderLoop()) |
|
||||
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60)) |
|
||||
.Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>() |
|
||||
.Bind<IPlatformIconLoader>().ToConstant(new PlatformIconLoader()); |
|
||||
if (useGpu) |
|
||||
EglGlPlatformFeature.TryInitialize(); |
|
||||
} |
|
||||
|
|
||||
public IWindowImpl CreateWindow() => new WindowImpl(); |
|
||||
|
|
||||
public IEmbeddableWindowImpl CreateEmbeddableWindow() |
|
||||
{ |
|
||||
throw new NotImplementedException(); |
|
||||
} |
|
||||
|
|
||||
public IPopupImpl CreatePopup() => new PopupImpl(); |
|
||||
|
|
||||
public Size DoubleClickSize => new Size(4, 4); |
|
||||
|
|
||||
public TimeSpan DoubleClickTime => TimeSpan.FromMilliseconds(100); //STUB
|
|
||||
public double RenderScalingFactor { get; } = 1; |
|
||||
public double LayoutScalingFactor { get; } = 1; |
|
||||
|
|
||||
public void RunLoop(CancellationToken cancellationToken) |
|
||||
{ |
|
||||
while (!cancellationToken.IsCancellationRequested) |
|
||||
Native.GtkMainIteration(); |
|
||||
} |
|
||||
|
|
||||
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick) |
|
||||
{ |
|
||||
var msec = interval.TotalMilliseconds; |
|
||||
var imsec = (uint) msec; |
|
||||
if (imsec == 0) |
|
||||
imsec = 1; |
|
||||
return GlibTimeout.StartTimer(GlibPriority.FromDispatcherPriority(priority), imsec, tick); |
|
||||
} |
|
||||
|
|
||||
private bool[] _signaled = new bool[(int) DispatcherPriority.MaxValue + 1]; |
|
||||
object _lock = new object(); |
|
||||
public void Signal(DispatcherPriority prio) |
|
||||
{ |
|
||||
var idx = (int) prio; |
|
||||
lock(_lock) |
|
||||
if (!_signaled[idx]) |
|
||||
{ |
|
||||
_signaled[idx] = true; |
|
||||
GlibTimeout.Add(GlibPriority.FromDispatcherPriority(prio), 0, () => |
|
||||
{ |
|
||||
lock (_lock) |
|
||||
{ |
|
||||
_signaled[idx] = false; |
|
||||
} |
|
||||
Signaled?.Invoke(prio); |
|
||||
return false; |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
public event Action<DispatcherPriority?> Signaled; |
|
||||
|
|
||||
|
|
||||
[ThreadStatic] |
|
||||
private static bool s_tlsMarker; |
|
||||
|
|
||||
public bool CurrentThreadIsLoopThread => s_tlsMarker; |
|
||||
} |
|
||||
|
|
||||
public class Gtk3PlatformOptions |
|
||||
{ |
|
||||
public bool? UseDeferredRendering { get; set; } |
|
||||
public bool? UseGpuAcceleration { get; set; } |
|
||||
public ICustomGtk3NativeLibraryResolver CustomResolver { get; set; } |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
namespace Avalonia |
|
||||
{ |
|
||||
public static class Gtk3AppBuilderExtensions |
|
||||
{ |
|
||||
public static T UseGtk3<T>(this AppBuilderBase<T> builder, Gtk3PlatformOptions options = null) |
|
||||
where T : AppBuilderBase<T>, new() |
|
||||
{ |
|
||||
return builder.UseWindowingSubsystem(() => Gtk3Platform.Initialize(options ?? new Gtk3PlatformOptions()), |
|
||||
"GTK3"); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,24 +0,0 @@ |
|||||
using Avalonia.Platform; |
|
||||
|
|
||||
namespace Avalonia.Gtk3 |
|
||||
{ |
|
||||
public class GtkScreen : Screen |
|
||||
{ |
|
||||
private readonly int _screenId; |
|
||||
|
|
||||
public GtkScreen(PixelRect bounds, PixelRect workingArea, bool primary, int screenId) : base(bounds, workingArea, primary) |
|
||||
{ |
|
||||
this._screenId = screenId; |
|
||||
} |
|
||||
|
|
||||
public override int GetHashCode() |
|
||||
{ |
|
||||
return _screenId; |
|
||||
} |
|
||||
|
|
||||
public override bool Equals(object obj) |
|
||||
{ |
|
||||
return (obj is GtkScreen screen) ? this._screenId == screen._screenId : base.Equals(obj); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,9 +0,0 @@ |
|||||
using System; |
|
||||
|
|
||||
namespace Avalonia.Gtk3 |
|
||||
{ |
|
||||
public interface IDeferredRenderOperation : IDisposable |
|
||||
{ |
|
||||
void RenderNow(IntPtr? ctx); |
|
||||
} |
|
||||
} |
|
||||
@ -1,144 +0,0 @@ |
|||||
using System; |
|
||||
using Avalonia.Gtk3.Interop; |
|
||||
using Avalonia.Platform; |
|
||||
using Avalonia.Threading; |
|
||||
|
|
||||
|
|
||||
namespace Avalonia.Gtk3 |
|
||||
{ |
|
||||
class ImageSurfaceFramebuffer : ILockedFramebuffer |
|
||||
{ |
|
||||
private readonly WindowBaseImpl _impl; |
|
||||
private readonly GtkWidget _widget; |
|
||||
private ManagedCairoSurface _surface; |
|
||||
private int _factor; |
|
||||
private object _lock = new object(); |
|
||||
public ImageSurfaceFramebuffer(WindowBaseImpl impl, int width, int height, int factor) |
|
||||
{ |
|
||||
_impl = impl; |
|
||||
_widget = impl.GtkWidget; |
|
||||
_factor = factor; |
|
||||
width *= _factor; |
|
||||
height *= _factor; |
|
||||
_surface = new ManagedCairoSurface(width, height); |
|
||||
|
|
||||
Size = new PixelSize(width, height); |
|
||||
Address = _surface.Buffer; |
|
||||
RowBytes = _surface.Stride; |
|
||||
Native.CairoSurfaceFlush(_surface.Surface); |
|
||||
} |
|
||||
|
|
||||
static void Draw(IntPtr context, CairoSurface surface, double factor) |
|
||||
{ |
|
||||
|
|
||||
Native.CairoSurfaceMarkDirty(surface); |
|
||||
Native.CairoScale(context, 1d / factor, 1d / factor); |
|
||||
Native.CairoSetSourceSurface(context, surface, 0, 0); |
|
||||
Native.CairoPaint(context); |
|
||||
|
|
||||
} |
|
||||
/* |
|
||||
static Stopwatch St =Stopwatch.StartNew(); |
|
||||
private static int _frames; |
|
||||
private static int _fps;*/ |
|
||||
static void DrawToWidget(GtkWidget widget, CairoSurface surface, int width, int height, double factor) |
|
||||
{ |
|
||||
if(surface == null || widget.IsClosed) |
|
||||
return; |
|
||||
var window = Native.GtkWidgetGetWindow(widget); |
|
||||
if(window == IntPtr.Zero) |
|
||||
return; |
|
||||
var rc = new GdkRectangle {Width = width, Height = height}; |
|
||||
Native.GdkWindowBeginPaintRect(window, ref rc); |
|
||||
var context = Native.GdkCairoCreate(window); |
|
||||
Draw(context, surface, factor); |
|
||||
/* |
|
||||
_frames++; |
|
||||
var el = St.Elapsed; |
|
||||
if (el.TotalSeconds > 1) |
|
||||
{ |
|
||||
_fps = (int) (_frames / el.TotalSeconds); |
|
||||
_frames = 0; |
|
||||
St = Stopwatch.StartNew(); |
|
||||
} |
|
||||
|
|
||||
Native.CairoSetSourceRgba(context, 1, 0, 0, 1); |
|
||||
Native.CairoMoveTo(context, 20, 20); |
|
||||
Native.CairoSetFontSize(context, 30); |
|
||||
using (var txt = new Utf8Buffer("FPS: " + _fps)) |
|
||||
Native.CairoShowText(context, txt); |
|
||||
*/ |
|
||||
|
|
||||
Native.CairoDestroy(context); |
|
||||
Native.GdkWindowEndPaint(window); |
|
||||
} |
|
||||
|
|
||||
class RenderOp : IDeferredRenderOperation |
|
||||
{ |
|
||||
private readonly GtkWidget _widget; |
|
||||
private ManagedCairoSurface _surface; |
|
||||
private readonly double _factor; |
|
||||
private readonly int _width; |
|
||||
private readonly int _height; |
|
||||
|
|
||||
public RenderOp(GtkWidget widget, ManagedCairoSurface surface, double factor, int width, int height) |
|
||||
{ |
|
||||
_widget = widget; |
|
||||
_surface = surface ?? throw new ArgumentNullException(nameof(surface)); |
|
||||
_factor = factor; |
|
||||
_width = width; |
|
||||
_height = height; |
|
||||
} |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
_surface?.Dispose(); |
|
||||
_surface = null; |
|
||||
} |
|
||||
|
|
||||
public void RenderNow(IntPtr? ctx) |
|
||||
{ |
|
||||
if(ctx.HasValue) |
|
||||
Draw(ctx.Value, _surface.Surface, _factor); |
|
||||
else |
|
||||
DrawToWidget(_widget, _surface.Surface, _width, _height, _factor); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
lock (_lock) |
|
||||
{ |
|
||||
if (Dispatcher.UIThread.CheckAccess()) |
|
||||
{ |
|
||||
if (_impl.CurrentCairoContext != IntPtr.Zero) |
|
||||
Draw(_impl.CurrentCairoContext, _surface.Surface, _factor); |
|
||||
else |
|
||||
DrawToWidget(_widget, _surface.Surface, Size.Width, Size.Height, _factor); |
|
||||
_surface.Dispose(); |
|
||||
} |
|
||||
else |
|
||||
_impl.SetNextRenderOperation(new RenderOp(_widget, _surface, _factor, Size.Width, Size.Height)); |
|
||||
_surface = null; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public IntPtr Address { get; } |
|
||||
public PixelSize Size { get; } |
|
||||
public int RowBytes { get; } |
|
||||
|
|
||||
|
|
||||
public Vector Dpi |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
return new Vector(96, 96) * _factor; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public PixelFormat Format => PixelFormat.Bgra8888; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
@ -1,20 +0,0 @@ |
|||||
using System; |
|
||||
using System.Runtime.InteropServices; |
|
||||
|
|
||||
namespace Avalonia.Gtk3.Interop |
|
||||
{ |
|
||||
class CairoSurface : SafeHandle |
|
||||
{ |
|
||||
public CairoSurface() : base(IntPtr.Zero, true) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
protected override bool ReleaseHandle() |
|
||||
{ |
|
||||
Native.CairoSurfaceDestroy(handle); |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
public override bool IsInvalid => handle == IntPtr.Zero; |
|
||||
} |
|
||||
} |
|
||||
@ -1,30 +0,0 @@ |
|||||
using System; |
|
||||
using System.Runtime.InteropServices; |
|
||||
using Avalonia.Platform.Interop; |
|
||||
|
|
||||
namespace Avalonia.Gtk3.Interop |
|
||||
{ |
|
||||
public class GException : Exception |
|
||||
{ |
|
||||
[StructLayout(LayoutKind.Sequential)] |
|
||||
struct GError |
|
||||
{ |
|
||||
UInt32 domain; |
|
||||
int code; |
|
||||
public IntPtr message; |
|
||||
}; |
|
||||
|
|
||||
static unsafe string GetError(IntPtr error) |
|
||||
{ |
|
||||
if (error == IntPtr.Zero) |
|
||||
return "Unknown error"; |
|
||||
return Utf8Buffer.StringFromPtr(((GError*) error)->message); |
|
||||
} |
|
||||
|
|
||||
public GException(IntPtr error) : base(GetError(error)) |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
@ -1,87 +0,0 @@ |
|||||
using System; |
|
||||
using System.Diagnostics; |
|
||||
using System.Runtime.InteropServices; |
|
||||
|
|
||||
namespace Avalonia.Gtk3.Interop |
|
||||
{ |
|
||||
class GObject : SafeHandle |
|
||||
{ |
|
||||
public GObject() : base(IntPtr.Zero, true) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public GObject(IntPtr handle, bool owned = true) : base(IntPtr.Zero, owned) |
|
||||
{ |
|
||||
this.handle = handle; |
|
||||
} |
|
||||
|
|
||||
protected override bool ReleaseHandle() |
|
||||
{ |
|
||||
if (handle != IntPtr.Zero) |
|
||||
{ |
|
||||
Debug.Assert(Native.GTypeCheckInstanceIsFundamentallyA(handle, new IntPtr(Native.G_TYPE_OBJECT)), |
|
||||
"Handle is not a GObject"); |
|
||||
Native.GObjectUnref(handle); |
|
||||
} |
|
||||
|
|
||||
handle = IntPtr.Zero; |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
public override bool IsInvalid => handle == IntPtr.Zero; |
|
||||
} |
|
||||
|
|
||||
class GInputStream : GObject |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
|
|
||||
class GtkWidget : GObject |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
|
|
||||
class GtkWindow : GtkWidget |
|
||||
{ |
|
||||
public static GtkWindow Null { get; } = new GtkWindow(); |
|
||||
} |
|
||||
|
|
||||
class GtkImContext : GObject |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
class GdkScreen : GObject |
|
||||
{ |
|
||||
public GdkScreen() : base(IntPtr.Zero, false) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public GdkScreen(IntPtr handle, bool owned = true) : base(handle, owned) |
|
||||
{ |
|
||||
this.handle = handle; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
class UnownedGdkScreen : GdkScreen |
|
||||
{ |
|
||||
public UnownedGdkScreen() : base(IntPtr.Zero, false) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public UnownedGdkScreen(IntPtr handle, bool owned = true) : base(IntPtr.Zero, false) |
|
||||
{ |
|
||||
this.handle = handle; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
class GtkDialog : GtkWindow |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
|
|
||||
class GtkFileChooser : GtkDialog |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@ -1,46 +0,0 @@ |
|||||
using System; |
|
||||
using Avalonia.Threading; |
|
||||
|
|
||||
namespace Avalonia.Gtk3.Interop |
|
||||
{ |
|
||||
static class GlibPriority |
|
||||
{ |
|
||||
public static int High = -100; |
|
||||
public static int Default = 0; |
|
||||
public static int HighIdle = 100; |
|
||||
public static int GtkResize = HighIdle + 10; |
|
||||
public static int GtkPaint = HighIdle + 20; |
|
||||
public static int DefaultIdle = 200; |
|
||||
public static int Low = 300; |
|
||||
public static int GdkEvents = Default; |
|
||||
public static int GdkRedraw = HighIdle + 20; |
|
||||
|
|
||||
public static int FromDispatcherPriority(DispatcherPriority prio) |
|
||||
{ |
|
||||
if (prio == DispatcherPriority.Send) |
|
||||
return High; |
|
||||
if (prio == DispatcherPriority.Normal) |
|
||||
return Default; |
|
||||
if (prio == DispatcherPriority.DataBind) |
|
||||
return Default + 1; |
|
||||
if (prio == DispatcherPriority.Layout) |
|
||||
return Default + 2; |
|
||||
if (prio == DispatcherPriority.Render) |
|
||||
return Default + 3; |
|
||||
if (prio == DispatcherPriority.Loaded) |
|
||||
return GtkPaint + 20; |
|
||||
if (prio == DispatcherPriority.Input) |
|
||||
return GtkPaint + 21; |
|
||||
if (prio == DispatcherPriority.Background) |
|
||||
return DefaultIdle + 1; |
|
||||
if (prio == DispatcherPriority.ContextIdle) |
|
||||
return DefaultIdle + 2; |
|
||||
if (prio == DispatcherPriority.ApplicationIdle) |
|
||||
return DefaultIdle + 3; |
|
||||
if (prio == DispatcherPriority.SystemIdle) |
|
||||
return DefaultIdle + 4; |
|
||||
throw new ArgumentException("Unknown priority"); |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,58 +0,0 @@ |
|||||
using System; |
|
||||
using System.Runtime.InteropServices; |
|
||||
|
|
||||
namespace Avalonia.Gtk3.Interop |
|
||||
{ |
|
||||
static class GlibTimeout |
|
||||
{ |
|
||||
static bool Handler(IntPtr data) |
|
||||
{ |
|
||||
var handle = GCHandle.FromIntPtr(data); |
|
||||
var cb = (Func<bool>) handle.Target; |
|
||||
if (!cb()) |
|
||||
{ |
|
||||
handle.Free(); |
|
||||
return false; |
|
||||
} |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
private static readonly Native.D.timeout_callback PinnedHandler; |
|
||||
static GlibTimeout() |
|
||||
{ |
|
||||
PinnedHandler = Handler; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
public static void Add(int priority, uint interval, Func<bool> callback) |
|
||||
{ |
|
||||
var handle = GCHandle.Alloc(callback); |
|
||||
Native.GTimeoutAddFull(priority, interval, PinnedHandler, GCHandle.ToIntPtr(handle), IntPtr.Zero); |
|
||||
} |
|
||||
|
|
||||
class Timer : IDisposable |
|
||||
{ |
|
||||
public bool Stopped; |
|
||||
public void Dispose() |
|
||||
{ |
|
||||
|
|
||||
Stopped = true; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public static IDisposable StartTimer(int priority, uint interval, Action tick) |
|
||||
{ |
|
||||
var timer = new Timer (); |
|
||||
GlibTimeout.Add(priority, interval, |
|
||||
() => |
|
||||
{ |
|
||||
if (timer.Stopped) |
|
||||
return false; |
|
||||
tick(); |
|
||||
return !timer.Stopped; |
|
||||
}); |
|
||||
|
|
||||
return timer; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,12 +0,0 @@ |
|||||
using Avalonia.Gtk3.Interop; |
|
||||
|
|
||||
namespace Avalonia.Gtk3 |
|
||||
{ |
|
||||
public interface ICustomGtk3NativeLibraryResolver |
|
||||
{ |
|
||||
string GetName(GtkDll dll); |
|
||||
string BasePath { get; } |
|
||||
bool TrySystemFirst { get; } |
|
||||
string Lookup(GtkDll dll); |
|
||||
} |
|
||||
} |
|
||||
@ -1,37 +0,0 @@ |
|||||
using System; |
|
||||
using Avalonia.Platform; |
|
||||
|
|
||||
namespace Avalonia.Gtk3.Interop |
|
||||
{ |
|
||||
class ManagedCairoSurface : IDisposable |
|
||||
{ |
|
||||
public IntPtr Buffer { get; private set; } |
|
||||
public CairoSurface Surface { get; private set; } |
|
||||
public int Stride { get; private set; } |
|
||||
private int _size; |
|
||||
private IRuntimePlatform _plat; |
|
||||
private IUnmanagedBlob _blob; |
|
||||
|
|
||||
public ManagedCairoSurface(int width, int height) |
|
||||
{ |
|
||||
_plat = AvaloniaLocator.Current.GetService<IRuntimePlatform>(); |
|
||||
Stride = width * 4; |
|
||||
_size = height * Stride; |
|
||||
_blob = _plat.AllocBlob(_size * 2); |
|
||||
Buffer = _blob.Address; |
|
||||
Surface = Native.CairoImageSurfaceCreateForData(Buffer, 1, width, height, Stride); |
|
||||
} |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
|
|
||||
if (Buffer != IntPtr.Zero) |
|
||||
{ |
|
||||
Surface.Dispose(); |
|
||||
_blob.Dispose(); |
|
||||
Buffer = IntPtr.Zero; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
@ -1,790 +0,0 @@ |
|||||
#pragma warning disable 649
|
|
||||
using System; |
|
||||
using System.Runtime.InteropServices; |
|
||||
using Avalonia.Controls; |
|
||||
using Avalonia.Platform.Interop; |
|
||||
using gdouble = System.Double; |
|
||||
using gint = System.Int32; |
|
||||
using gint16 = System.Int16; |
|
||||
using gint8 = System.Byte; |
|
||||
using guint = System.UInt32; |
|
||||
using guint16 = System.UInt16; |
|
||||
using guint32 = System.UInt32; |
|
||||
|
|
||||
namespace Avalonia.Gtk3.Interop |
|
||||
{ |
|
||||
static class Native |
|
||||
{ |
|
||||
public static class D |
|
||||
{ |
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate gint16 gdk_display_get_n_screens(IntPtr display); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate UnownedGdkScreen gdk_display_get_screen(IntPtr display, gint16 num); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate UnownedGdkScreen gdk_display_get_default_screen (IntPtr display); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate gint16 gdk_screen_get_n_monitors(GdkScreen screen); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate gint16 gdk_screen_get_primary_monitor(GdkScreen screen); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate void gdk_screen_get_monitor_geometry(GdkScreen screen, gint16 num, ref GdkRectangle rect); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate void gdk_screen_get_monitor_workarea(GdkScreen screen, gint16 num, ref GdkRectangle rect); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate IntPtr gtk_application_new(Utf8Buffer appId, int flags); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_main_iteration(); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate GtkWindow gtk_window_new(GtkWindowType windowType); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate IntPtr gtk_init(int argc, IntPtr argv); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate bool gtk_init_check(int argc, IntPtr argv); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk, optional: true)] |
|
||||
public delegate IntPtr gdk_set_allowed_backends (Utf8Buffer backends); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_present(GtkWindow gtkWindow); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_widget_hide(GtkWidget gtkWidget); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_widget_show(GtkWidget gtkWidget); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_set_icon(GtkWindow window, Pixbuf pixbuf); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_set_modal(GtkWindow window, bool modal); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_set_transient_for(GtkWindow window, IntPtr parent); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] //No manual import
|
|
||||
public delegate IntPtr gdk_get_native_handle(IntPtr gdkWindow); |
|
||||
|
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate IntPtr gtk_widget_get_window(GtkWidget gtkWidget); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk, optional: true)] |
|
||||
public delegate uint gtk_widget_get_scale_factor(GtkWidget gtkWidget); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate IntPtr gtk_widget_get_screen(GtkWidget gtkWidget); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate IntPtr gtk_widget_set_double_buffered(GtkWidget gtkWidget, bool value); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate IntPtr gtk_widget_set_events(GtkWidget gtkWidget, uint flags); |
|
||||
|
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate int gdk_screen_get_height(IntPtr screen); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate int gdk_screen_get_width(IntPtr screen); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate IntPtr gdk_display_get_default(); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate int gdk_window_get_origin(IntPtr gdkWindow, out int x, out int y); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate void gdk_window_resize(IntPtr gtkWindow, int width, int height); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate void gdk_window_set_override_redirect(IntPtr gdkWindow, bool value); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_widget_realize(GtkWidget gtkWidget); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_set_title(GtkWindow gtkWindow, Utf8Buffer title); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_set_resizable(GtkWindow gtkWindow, bool resizable); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_set_decorated(GtkWindow gtkWindow, bool decorated); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_set_skip_taskbar_hint(GtkWindow gtkWindow, bool setting); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate bool gtk_window_get_skip_taskbar_hint(GtkWindow gtkWindow); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_set_skip_pager_hint(GtkWindow gtkWindow, bool setting); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate bool gtk_window_get_skip_pager_hint(GtkWindow gtkWindow); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_get_size(GtkWindow gtkWindow, out int width, out int height); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_resize(GtkWindow gtkWindow, int width, int height); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_widget_set_size_request(GtkWidget widget, int width, int height); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_set_default_size(GtkWindow gtkWindow, int width, int height); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_get_position(GtkWindow gtkWindow, out int x, out int y); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_move(GtkWindow gtkWindow, int x, int y); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate GtkFileChooser gtk_file_chooser_dialog_new(Utf8Buffer title, GtkWindow parent, GtkFileChooserAction action, IntPtr ignore); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public unsafe delegate GSList* gtk_file_chooser_get_filenames(GtkFileChooser chooser); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_file_chooser_set_select_multiple(GtkFileChooser chooser, bool allow); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_file_chooser_set_filename(GtkFileChooser chooser, Utf8Buffer file); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_dialog_add_button(GtkDialog raw, Utf8Buffer button_text, GtkResponseType response_id); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate CairoSurface cairo_image_surface_create(int format, int width, int height); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate CairoSurface cairo_image_surface_create_for_data(IntPtr data, int format, int width, int height, int stride); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate IntPtr cairo_image_surface_get_data(CairoSurface surface); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate int cairo_image_surface_get_stride(CairoSurface surface); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_surface_mark_dirty(CairoSurface surface); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_surface_write_to_png(CairoSurface surface, Utf8Buffer path); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_surface_flush(CairoSurface surface); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_surface_destroy(IntPtr surface); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_set_source_surface(IntPtr cr, CairoSurface surface, double x, double y); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_set_source_rgba(IntPtr cr, double r, double g, double b, double a); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_scale(IntPtr context, double sx, double sy); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_paint(IntPtr context); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_show_text(IntPtr context, Utf8Buffer text); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_set_font_size(IntPtr context, double size); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_select_font_face(IntPtr context, Utf8Buffer face, int slant, int weight); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_move_to(IntPtr context, double x, double y); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] |
|
||||
public delegate void cairo_destroy(IntPtr context); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_widget_queue_draw_area(GtkWidget widget, int x, int y, int width, int height); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate uint gtk_widget_add_tick_callback(GtkWidget widget, TickCallback callback, IntPtr userData, IntPtr destroy); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate uint gtk_widget_remove_tick_callback(GtkWidget widget, uint id); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate GtkImContext gtk_im_multicontext_new(); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate IntPtr gtk_im_context_set_client_window(GtkImContext context, IntPtr window); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate bool gtk_im_context_filter_keypress(GtkImContext context, IntPtr ev); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_widget_activate(GtkWidget widget); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate IntPtr gdk_screen_get_root_window(IntPtr screen); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate IntPtr gdk_cursor_new(GdkCursorType type); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate IntPtr gdk_window_get_pointer(IntPtr raw, out int x, out int y, out int mask); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate GdkWindowState gdk_window_get_state(IntPtr window); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_iconify(GtkWindow window); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_deiconify(GtkWindow window); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_maximize(GtkWindow window); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_unmaximize(GtkWindow window); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_close(GtkWindow window); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_set_keep_above(GtkWindow gtkWindow, bool setting); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_window_set_geometry_hints(GtkWindow window, IntPtr geometry_widget, ref GdkGeometry geometry, GdkWindowHints geom_mask); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate void gdk_window_invalidate_rect(IntPtr window, ref GdkRectangle rect, bool invalidate_children); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate void gdk_window_begin_move_drag(IntPtr window, gint button, gint root_x, gint root_y, guint32 timestamp); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate void gdk_window_begin_resize_drag(IntPtr window, WindowEdge edge, gint button, gint root_x, gint root_y, guint32 timestamp); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate void gdk_window_process_updates(IntPtr window, bool updateChildren); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate void gdk_window_begin_paint_rect(IntPtr window, ref GdkRectangle rect); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate void gdk_window_end_paint(IntPtr window); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk, optional: true)] |
|
||||
public delegate IntPtr gdk_x11_window_foreign_new_for_display(IntPtr display, IntPtr xid); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate void gdk_window_set_transient_for(IntPtr window, IntPtr parent); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate void gdk_event_request_motions(IntPtr ev); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate IntPtr gtk_clipboard_get_for_display(IntPtr display, IntPtr atom); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_clipboard_request_text(IntPtr clipboard, GtkClipboardTextReceivedFunc callback, IntPtr user_data); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_clipboard_set_text(IntPtr clipboard, Utf8Buffer text, int len); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate void gtk_clipboard_clear(IntPtr clipboard); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.GdkPixBuf)] |
|
||||
public delegate IntPtr gdk_pixbuf_new_from_file(Utf8Buffer filename, out IntPtr error); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate IntPtr gtk_icon_theme_get_default(); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] |
|
||||
public delegate IntPtr gtk_icon_theme_load_icon(IntPtr icon_theme, Utf8Buffer icon_name, gint size, int flags,out IntPtr error); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate IntPtr gdk_cursor_new_from_pixbuf(IntPtr disp, IntPtr pixbuf, int x, int y); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate IntPtr gdk_window_set_cursor(IntPtr window, IntPtr cursor); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.GdkPixBuf)] |
|
||||
public delegate IntPtr gdk_pixbuf_new_from_stream(GInputStream stream, IntPtr cancel, out IntPtr error); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.GdkPixBuf)] |
|
||||
public delegate bool gdk_pixbuf_save_to_bufferv(Pixbuf pixbuf, out IntPtr buffer, out IntPtr buffer_size, |
|
||||
Utf8Buffer type, IntPtr option_keys, IntPtr option_values, out IntPtr error); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] |
|
||||
public delegate IntPtr gdk_cairo_create(IntPtr window); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] |
|
||||
public delegate void g_object_unref(IntPtr instance); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] |
|
||||
public delegate void g_object_ref(GObject instance); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] |
|
||||
public delegate IntPtr g_type_name(IntPtr instance); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] |
|
||||
public delegate ulong g_signal_connect_object(GObject instance, Utf8Buffer signal, IntPtr handler, IntPtr userData, int flags); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] |
|
||||
public delegate ulong g_signal_handler_disconnect(GObject instance, ulong connectionId); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)] |
|
||||
public delegate ulong g_timeout_add(uint interval, timeout_callback callback, IntPtr data); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)] |
|
||||
public delegate ulong g_timeout_add_full(int prio, uint interval, timeout_callback callback, IntPtr data, IntPtr destroy); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)] |
|
||||
public delegate ulong g_free(IntPtr data); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] |
|
||||
public delegate bool g_type_check_instance_is_fundamentally_a(IntPtr instance, IntPtr type); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)] |
|
||||
public unsafe delegate void g_slist_free(GSList* data); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gio)] |
|
||||
public delegate GInputStream g_memory_input_stream_new_from_data(IntPtr ptr, IntPtr len, IntPtr destroyCallback); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] |
|
||||
public delegate bool signal_widget_draw(IntPtr gtkWidget, IntPtr cairoContext, IntPtr userData); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] |
|
||||
public delegate bool signal_generic(IntPtr gtkWidget, IntPtr userData); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] |
|
||||
public delegate bool signal_dialog_response(IntPtr gtkWidget, GtkResponseType response, IntPtr userData); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] |
|
||||
public delegate bool signal_onevent(IntPtr gtkWidget, IntPtr ev, IntPtr userData); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] |
|
||||
public delegate void monitors_changed(IntPtr screen, IntPtr userData); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] |
|
||||
public delegate bool signal_commit(IntPtr gtkWidget, IntPtr utf8string, IntPtr userData); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] |
|
||||
public delegate bool timeout_callback(IntPtr data); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] |
|
||||
public delegate void GtkClipboardTextReceivedFunc(IntPtr clipboard, IntPtr utf8string, IntPtr userdata); |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] |
|
||||
public delegate bool TickCallback(IntPtr widget, IntPtr clock, IntPtr userdata); |
|
||||
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
public static D.gdk_display_get_n_screens GdkDisplayGetNScreens; |
|
||||
public static D.gdk_display_get_screen GdkDisplayGetScreen; |
|
||||
public static D.gdk_display_get_default_screen GdkDisplayGetDefaultScreen; |
|
||||
public static D.gdk_screen_get_n_monitors GdkScreenGetNMonitors; |
|
||||
public static D.gdk_screen_get_primary_monitor GdkScreenGetPrimaryMonitor; |
|
||||
public static D.gdk_screen_get_monitor_geometry GdkScreenGetMonitorGeometry; |
|
||||
public static D.gdk_screen_get_monitor_workarea GdkScreenGetMonitorWorkarea; |
|
||||
public static D.gtk_window_set_decorated GtkWindowSetDecorated; |
|
||||
public static D.gtk_window_set_resizable GtkWindowSetResizable; |
|
||||
public static D.gtk_window_set_skip_taskbar_hint GtkWindowSetSkipTaskbarHint; |
|
||||
public static D.gtk_window_get_skip_taskbar_hint GtkWindowGetSkipTaskbarHint; |
|
||||
public static D.gtk_window_set_skip_pager_hint GtkWindowSetSkipPagerHint; |
|
||||
public static D.gtk_window_get_skip_pager_hint GtkWindowGetSkipPagerHint; |
|
||||
public static D.gtk_window_set_title GtkWindowSetTitle; |
|
||||
public static D.gtk_application_new GtkApplicationNew; |
|
||||
public static D.gtk_main_iteration GtkMainIteration; |
|
||||
public static D.gtk_window_new GtkWindowNew; |
|
||||
public static D.gtk_window_set_icon GtkWindowSetIcon; |
|
||||
public static D.gtk_window_set_modal GtkWindowSetModal; |
|
||||
public static D.gtk_window_set_transient_for GtkWindowSetTransientFor; |
|
||||
public static D.gdk_set_allowed_backends GdkSetAllowedBackends; |
|
||||
public static D.gtk_init GtkInit; |
|
||||
public static D.gtk_init_check GtkInitCheck; |
|
||||
public static D.gtk_window_present GtkWindowPresent; |
|
||||
public static D.gtk_widget_hide GtkWidgetHide; |
|
||||
public static D.gtk_widget_show GtkWidgetShow; |
|
||||
public static D.gdk_get_native_handle GetNativeGdkWindowHandle; |
|
||||
public static D.gtk_widget_get_window GtkWidgetGetWindow; |
|
||||
public static D.gtk_widget_get_scale_factor GtkWidgetGetScaleFactor; |
|
||||
public static D.gtk_widget_get_screen GtkWidgetGetScreen; |
|
||||
public static D.gtk_widget_realize GtkWidgetRealize; |
|
||||
public static D.gtk_window_get_size GtkWindowGetSize; |
|
||||
public static D.gtk_window_resize GtkWindowResize; |
|
||||
public static D.gdk_window_resize GdkWindowResize; |
|
||||
public static D.gdk_window_set_override_redirect GdkWindowSetOverrideRedirect; |
|
||||
public static D.gtk_widget_set_size_request GtkWindowSetSizeRequest; |
|
||||
public static D.gtk_window_set_default_size GtkWindowSetDefaultSize; |
|
||||
public static D.gtk_window_set_geometry_hints GtkWindowSetGeometryHints; |
|
||||
public static D.gtk_window_get_position GtkWindowGetPosition; |
|
||||
public static D.gtk_window_move GtkWindowMove; |
|
||||
public static D.gtk_file_chooser_dialog_new GtkFileChooserDialogNew; |
|
||||
public static D.gtk_file_chooser_set_select_multiple GtkFileChooserSetSelectMultiple; |
|
||||
public static D.gtk_file_chooser_set_filename GtkFileChooserSetFilename; |
|
||||
public static D.gtk_file_chooser_get_filenames GtkFileChooserGetFilenames; |
|
||||
public static D.gtk_dialog_add_button GtkDialogAddButton; |
|
||||
public static D.g_object_unref GObjectUnref; |
|
||||
public static D.g_object_ref GObjectRef; |
|
||||
public static D.g_type_name GTypeName; |
|
||||
public static D.g_signal_connect_object GSignalConnectObject; |
|
||||
public static D.g_signal_handler_disconnect GSignalHandlerDisconnect; |
|
||||
public static D.g_timeout_add GTimeoutAdd; |
|
||||
public static D.g_timeout_add_full GTimeoutAddFull; |
|
||||
public static D.g_free GFree; |
|
||||
public static D.g_type_check_instance_is_fundamentally_a GTypeCheckInstanceIsFundamentallyA; |
|
||||
public static D.g_slist_free GSlistFree; |
|
||||
public static D.g_memory_input_stream_new_from_data GMemoryInputStreamNewFromData; |
|
||||
public static D.gtk_widget_set_double_buffered GtkWidgetSetDoubleBuffered; |
|
||||
public static D.gtk_widget_set_events GtkWidgetSetEvents; |
|
||||
public static D.gdk_window_invalidate_rect GdkWindowInvalidateRect; |
|
||||
public static D.gtk_widget_queue_draw_area GtkWidgetQueueDrawArea; |
|
||||
public static D.gtk_widget_add_tick_callback GtkWidgetAddTickCallback; |
|
||||
public static D.gtk_widget_remove_tick_callback GtkWidgetRemoveTickCallback; |
|
||||
public static D.gtk_widget_activate GtkWidgetActivate; |
|
||||
public static D.gtk_clipboard_get_for_display GtkClipboardGetForDisplay; |
|
||||
public static D.gtk_clipboard_request_text GtkClipboardRequestText; |
|
||||
public static D.gtk_clipboard_set_text GtkClipboardSetText; |
|
||||
public static D.gtk_clipboard_clear GtkClipboardRequestClear; |
|
||||
|
|
||||
public static D.gtk_im_multicontext_new GtkImMulticontextNew; |
|
||||
public static D.gtk_im_context_filter_keypress GtkImContextFilterKeypress; |
|
||||
public static D.gtk_im_context_set_client_window GtkImContextSetClientWindow; |
|
||||
|
|
||||
public static D.gdk_screen_get_height GdkScreenGetHeight; |
|
||||
public static D.gdk_display_get_default GdkGetDefaultDisplay; |
|
||||
public static D.gdk_screen_get_width GdkScreenGetWidth; |
|
||||
public static D.gdk_screen_get_root_window GdkScreenGetRootWindow; |
|
||||
public static D.gdk_cursor_new GdkCursorNew; |
|
||||
public static D.gdk_window_get_origin GdkWindowGetOrigin; |
|
||||
public static D.gdk_window_get_pointer GdkWindowGetPointer; |
|
||||
public static D.gdk_window_get_state GdkWindowGetState; |
|
||||
public static D.gtk_window_iconify GtkWindowIconify; |
|
||||
public static D.gtk_window_deiconify GtkWindowDeiconify; |
|
||||
public static D.gtk_window_maximize GtkWindowMaximize; |
|
||||
public static D.gtk_window_unmaximize GtkWindowUnmaximize; |
|
||||
public static D.gtk_window_close GtkWindowClose; |
|
||||
public static D.gtk_window_set_keep_above GtkWindowSetKeepAbove; |
|
||||
public static D.gdk_window_begin_move_drag GdkWindowBeginMoveDrag; |
|
||||
public static D.gdk_window_begin_resize_drag GdkWindowBeginResizeDrag; |
|
||||
public static D.gdk_event_request_motions GdkEventRequestMotions; |
|
||||
public static D.gdk_window_process_updates GdkWindowProcessUpdates; |
|
||||
public static D.gdk_window_begin_paint_rect GdkWindowBeginPaintRect; |
|
||||
public static D.gdk_window_end_paint GdkWindowEndPaint; |
|
||||
public static D.gdk_x11_window_foreign_new_for_display GdkWindowForeignNewForDisplay; |
|
||||
public static D.gdk_window_set_transient_for GdkWindowSetTransientFor; |
|
||||
|
|
||||
public static D.gdk_pixbuf_new_from_file GdkPixbufNewFromFile; |
|
||||
public static D.gtk_icon_theme_get_default GtkIconThemeGetDefault; |
|
||||
public static D.gtk_icon_theme_load_icon GtkIconThemeLoadIcon; |
|
||||
public static D.gdk_cursor_new_from_pixbuf GdkCursorNewFromPixbuf; |
|
||||
public static D.gdk_window_set_cursor GdkWindowSetCursor; |
|
||||
public static D.gdk_pixbuf_new_from_stream GdkPixbufNewFromStream; |
|
||||
public static D.gdk_pixbuf_save_to_bufferv GdkPixbufSaveToBufferv; |
|
||||
public static D.gdk_cairo_create GdkCairoCreate; |
|
||||
|
|
||||
public static D.cairo_image_surface_create CairoImageSurfaceCreate; |
|
||||
public static D.cairo_image_surface_create_for_data CairoImageSurfaceCreateForData; |
|
||||
public static D.cairo_image_surface_get_data CairoImageSurfaceGetData; |
|
||||
public static D.cairo_image_surface_get_stride CairoImageSurfaceGetStride; |
|
||||
public static D.cairo_surface_mark_dirty CairoSurfaceMarkDirty; |
|
||||
public static D.cairo_surface_write_to_png CairoSurfaceWriteToPng; |
|
||||
public static D.cairo_surface_flush CairoSurfaceFlush; |
|
||||
public static D.cairo_surface_destroy CairoSurfaceDestroy; |
|
||||
public static D.cairo_set_source_surface CairoSetSourceSurface; |
|
||||
public static D.cairo_set_source_rgba CairoSetSourceRgba; |
|
||||
public static D.cairo_scale CairoScale; |
|
||||
public static D.cairo_paint CairoPaint; |
|
||||
public static D.cairo_show_text CairoShowText; |
|
||||
public static D.cairo_select_font_face CairoSelectFontFace; |
|
||||
public static D.cairo_set_font_size CairoSetFontSize; |
|
||||
public static D.cairo_move_to CairoMoveTo; |
|
||||
public static D.cairo_destroy CairoDestroy; |
|
||||
|
|
||||
public const int G_TYPE_OBJECT = 80; |
|
||||
} |
|
||||
|
|
||||
public enum GtkWindowType |
|
||||
{ |
|
||||
TopLevel, |
|
||||
Popup |
|
||||
} |
|
||||
|
|
||||
[StructLayout(LayoutKind.Sequential)] |
|
||||
public struct GdkRectangle |
|
||||
{ |
|
||||
public int X, Y, Width, Height; |
|
||||
|
|
||||
public static GdkRectangle FromRect(Rect rect) |
|
||||
{ |
|
||||
return new GdkRectangle |
|
||||
{ |
|
||||
X = (int) rect.X, |
|
||||
Y = (int) rect.Y, |
|
||||
Width = (int) rect.Width, |
|
||||
Height = (int) rect.Height |
|
||||
}; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
enum GdkEventType |
|
||||
{ |
|
||||
Nothing = -1, |
|
||||
Delete = 0, |
|
||||
Destroy = 1, |
|
||||
Expose = 2, |
|
||||
MotionNotify = 3, |
|
||||
ButtonPress = 4, |
|
||||
TwoButtonPress = 5, |
|
||||
ThreeButtonPress = 6, |
|
||||
ButtonRelease = 7, |
|
||||
KeyPress = 8, |
|
||||
KeyRelease = 9, |
|
||||
EnterNotify = 10, |
|
||||
LeaveNotify = 11, |
|
||||
FocusChange = 12, |
|
||||
Configure = 13, |
|
||||
Map = 14, |
|
||||
Unmap = 15, |
|
||||
PropertyNotify = 16, |
|
||||
SelectionClear = 17, |
|
||||
SelectionRequest = 18, |
|
||||
SelectionNotify = 19, |
|
||||
ProximityIn = 20, |
|
||||
ProximityOut = 21, |
|
||||
DragEnter = 22, |
|
||||
DragLeave = 23, |
|
||||
DragMotion = 24, |
|
||||
DragStatus = 25, |
|
||||
DropStart = 26, |
|
||||
DropFinished = 27, |
|
||||
ClientEvent = 28, |
|
||||
VisibilityNotify = 29, |
|
||||
NoExpose = 30, |
|
||||
Scroll = 31, |
|
||||
WindowState = 32, |
|
||||
Setting = 33, |
|
||||
OwnerChange = 34, |
|
||||
GrabBroken = 35, |
|
||||
} |
|
||||
|
|
||||
enum GdkModifierType |
|
||||
{ |
|
||||
ShiftMask = 1, |
|
||||
LockMask = 2, |
|
||||
ControlMask = 4, |
|
||||
Mod1Mask = 8, |
|
||||
Mod2Mask = 16, |
|
||||
Mod3Mask = 32, |
|
||||
Mod4Mask = 64, |
|
||||
Mod5Mask = 128, |
|
||||
Button1Mask = 256, |
|
||||
Button2Mask = 512, |
|
||||
Button3Mask = 1024, |
|
||||
Button4Mask = 2048, |
|
||||
Button5Mask = 4096, |
|
||||
SuperMask = 67108864, |
|
||||
HyperMask = 134217728, |
|
||||
MetaMask = 268435456, |
|
||||
ReleaseMask = 1073741824, |
|
||||
ModifierMask = ReleaseMask | Button5Mask | Button4Mask | Button3Mask | Button2Mask | Button1Mask | Mod5Mask | Mod4Mask | Mod3Mask | Mod2Mask | Mod1Mask | ControlMask | LockMask | ShiftMask, |
|
||||
None = 0, |
|
||||
} |
|
||||
|
|
||||
enum GdkScrollDirection |
|
||||
{ |
|
||||
Up, |
|
||||
Down, |
|
||||
Left, |
|
||||
Right, |
|
||||
Smooth |
|
||||
} |
|
||||
|
|
||||
[StructLayout(LayoutKind.Sequential)] |
|
||||
unsafe struct GdkEventButton |
|
||||
{ |
|
||||
public GdkEventType type; |
|
||||
public IntPtr window; |
|
||||
public gint8 send_event; |
|
||||
public guint32 time; |
|
||||
public gdouble x; |
|
||||
public gdouble y; |
|
||||
public gdouble* axes; |
|
||||
public GdkModifierType state; |
|
||||
public guint button; |
|
||||
public IntPtr device; |
|
||||
public gdouble x_root, y_root; |
|
||||
} |
|
||||
|
|
||||
[StructLayout(LayoutKind.Sequential)] |
|
||||
unsafe struct GdkEventMotion |
|
||||
{ |
|
||||
public GdkEventType type; |
|
||||
public IntPtr window; |
|
||||
public gint8 send_event; |
|
||||
public guint32 time; |
|
||||
public gdouble x; |
|
||||
public gdouble y; |
|
||||
public gdouble* axes; |
|
||||
public GdkModifierType state; |
|
||||
public gint16 is_hint; |
|
||||
public IntPtr device; |
|
||||
public gdouble x_root, y_root; |
|
||||
} |
|
||||
|
|
||||
[StructLayout(LayoutKind.Sequential)] |
|
||||
unsafe struct GdkEventScroll |
|
||||
{ |
|
||||
public GdkEventType type; |
|
||||
public IntPtr window; |
|
||||
public gint8 send_event; |
|
||||
public guint32 time; |
|
||||
public gdouble x; |
|
||||
public gdouble y; |
|
||||
public GdkModifierType state; |
|
||||
public GdkScrollDirection direction; |
|
||||
public IntPtr device; |
|
||||
public gdouble x_root, y_root; |
|
||||
public gdouble delta_x; |
|
||||
public gdouble delta_y; |
|
||||
} |
|
||||
|
|
||||
[StructLayout(LayoutKind.Sequential)] |
|
||||
unsafe struct GdkEventCrossing |
|
||||
{ |
|
||||
public GdkEventType type; |
|
||||
public IntPtr window; |
|
||||
public gint8 send_event; |
|
||||
public IntPtr subwindow; |
|
||||
public guint32 time; |
|
||||
public gdouble x; |
|
||||
public gdouble y; |
|
||||
public gdouble x_root; |
|
||||
public gdouble y_root; |
|
||||
public int mode; |
|
||||
public int detail; |
|
||||
public bool focus; |
|
||||
public GdkModifierType state; |
|
||||
}; |
|
||||
|
|
||||
[StructLayout(LayoutKind.Sequential)] |
|
||||
unsafe struct GdkEventWindowState |
|
||||
{ |
|
||||
public GdkEventType type; |
|
||||
public IntPtr window; |
|
||||
gint8 send_event; |
|
||||
public GdkWindowState changed_mask; |
|
||||
public GdkWindowState new_window_state; |
|
||||
} |
|
||||
|
|
||||
[StructLayout(LayoutKind.Sequential)] |
|
||||
unsafe struct GdkEventKey |
|
||||
{ |
|
||||
public GdkEventType type; |
|
||||
public IntPtr window; |
|
||||
public gint8 send_event; |
|
||||
public guint32 time; |
|
||||
public guint state; |
|
||||
public guint keyval; |
|
||||
public gint length; |
|
||||
public IntPtr pstring; |
|
||||
public guint16 hardware_keycode; |
|
||||
public byte group; |
|
||||
public guint is_modifier; |
|
||||
} |
|
||||
|
|
||||
[StructLayout(LayoutKind.Sequential)] |
|
||||
unsafe struct GSList |
|
||||
{ |
|
||||
public IntPtr Data; |
|
||||
public GSList* Next; |
|
||||
} |
|
||||
|
|
||||
[Flags] |
|
||||
public enum GdkWindowState |
|
||||
{ |
|
||||
Withdrawn = 1, |
|
||||
Iconified = 2, |
|
||||
Maximized = 4, |
|
||||
Sticky = 8, |
|
||||
Fullscreen = 16, |
|
||||
Above = 32, |
|
||||
Below = 64, |
|
||||
Focused = 128, |
|
||||
Ttiled = 256 |
|
||||
} |
|
||||
|
|
||||
public enum GtkResponseType |
|
||||
{ |
|
||||
Help = -11, |
|
||||
Apply = -10, |
|
||||
No = -9, |
|
||||
Yes = -8, |
|
||||
Close = -7, |
|
||||
Cancel = -6, |
|
||||
Ok = -5, |
|
||||
DeleteEvent = -4, |
|
||||
Accept = -3, |
|
||||
Reject = -2, |
|
||||
None = -1, |
|
||||
} |
|
||||
|
|
||||
public enum GtkFileChooserAction |
|
||||
{ |
|
||||
Open, |
|
||||
Save, |
|
||||
SelectFolder, |
|
||||
CreateFolder, |
|
||||
} |
|
||||
|
|
||||
[StructLayout(LayoutKind.Sequential)] |
|
||||
public struct GdkGeometry |
|
||||
{ |
|
||||
public gint min_width; |
|
||||
public gint min_height; |
|
||||
public gint max_width; |
|
||||
public gint max_height; |
|
||||
public gint base_width; |
|
||||
public gint base_height; |
|
||||
public gint width_inc; |
|
||||
public gint height_inc; |
|
||||
public gdouble min_aspect; |
|
||||
public gdouble max_aspect; |
|
||||
public gint win_gravity; |
|
||||
} |
|
||||
|
|
||||
enum GdkWindowHints |
|
||||
{ |
|
||||
GDK_HINT_POS = 1 << 0, |
|
||||
GDK_HINT_MIN_SIZE = 1 << 1, |
|
||||
GDK_HINT_MAX_SIZE = 1 << 2, |
|
||||
GDK_HINT_BASE_SIZE = 1 << 3, |
|
||||
GDK_HINT_ASPECT = 1 << 4, |
|
||||
GDK_HINT_RESIZE_INC = 1 << 5, |
|
||||
GDK_HINT_WIN_GRAVITY = 1 << 6, |
|
||||
GDK_HINT_USER_POS = 1 << 7, |
|
||||
GDK_HINT_USER_SIZE = 1 << 8 |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
using System; |
|
||||
|
|
||||
namespace Avalonia.Gtk3.Interop |
|
||||
{ |
|
||||
public class NativeException : Exception |
|
||||
{ |
|
||||
public NativeException() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public NativeException(string message) : base(message) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public NativeException(string message, Exception inner) : base(message, inner) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
@ -1,65 +0,0 @@ |
|||||
using System; |
|
||||
using System.IO; |
|
||||
using System.Runtime.InteropServices; |
|
||||
using Avalonia.Platform; |
|
||||
using Avalonia.Platform.Interop; |
|
||||
|
|
||||
namespace Avalonia.Gtk3.Interop |
|
||||
{ |
|
||||
internal class Pixbuf : GObject, IWindowIconImpl |
|
||||
{ |
|
||||
Pixbuf(IntPtr handle) : base(handle) |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
|
|
||||
public static Pixbuf NewFromFile(string filename) |
|
||||
{ |
|
||||
using (var ub = new Utf8Buffer(filename)) |
|
||||
{ |
|
||||
IntPtr err; |
|
||||
var rv = Native.GdkPixbufNewFromFile(ub, out err); |
|
||||
if(rv != IntPtr.Zero) |
|
||||
return new Pixbuf(rv); |
|
||||
throw new GException(err); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public static unsafe Pixbuf NewFromBytes(byte[] data) |
|
||||
{ |
|
||||
fixed (void* bytes = data) |
|
||||
{ |
|
||||
using (var stream = Native.GMemoryInputStreamNewFromData(new IntPtr(bytes), new IntPtr(data.Length), IntPtr.Zero)) |
|
||||
{ |
|
||||
IntPtr err; |
|
||||
var rv = Native.GdkPixbufNewFromStream(stream, IntPtr.Zero, out err); |
|
||||
if (rv != IntPtr.Zero) |
|
||||
return new Pixbuf(rv); |
|
||||
throw new GException(err); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public static Pixbuf NewFromStream(Stream s) |
|
||||
{ |
|
||||
if (s is MemoryStream) |
|
||||
return NewFromBytes(((MemoryStream) s).ToArray()); |
|
||||
var ms = new MemoryStream(); |
|
||||
s.CopyTo(ms); |
|
||||
return NewFromBytes(ms.ToArray()); |
|
||||
} |
|
||||
|
|
||||
public void Save(Stream outputStream) |
|
||||
{ |
|
||||
IntPtr buffer, bufferLen, error; |
|
||||
using (var png = new Utf8Buffer("png")) |
|
||||
if (!Native.GdkPixbufSaveToBufferv(this, out buffer, out bufferLen, png, |
|
||||
IntPtr.Zero, IntPtr.Zero, out error)) |
|
||||
throw new GException(error); |
|
||||
var data = new byte[bufferLen.ToInt32()]; |
|
||||
Marshal.Copy(buffer, data, 0, bufferLen.ToInt32()); |
|
||||
Native.GFree(buffer); |
|
||||
outputStream.Write(data, 0, data.Length); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,156 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.IO; |
|
||||
using System.Linq; |
|
||||
using System.Reflection; |
|
||||
using System.Runtime.InteropServices; |
|
||||
using Avalonia.Platform; |
|
||||
using Avalonia.Platform.Interop; |
|
||||
|
|
||||
namespace Avalonia.Gtk3.Interop |
|
||||
{ |
|
||||
internal class GtkImportAttribute : Attribute |
|
||||
{ |
|
||||
public GtkDll Dll { get; set; } |
|
||||
public string Name { get; set; } |
|
||||
public bool Optional { get; set; } |
|
||||
|
|
||||
public GtkImportAttribute(GtkDll dll, string name = null, bool optional = false) |
|
||||
{ |
|
||||
Dll = dll; |
|
||||
Name = name; |
|
||||
Optional = optional; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public enum GtkDll |
|
||||
{ |
|
||||
Gdk, |
|
||||
Gtk, |
|
||||
Glib, |
|
||||
Gio, |
|
||||
Gobject, |
|
||||
Cairo, |
|
||||
GdkPixBuf |
|
||||
} |
|
||||
|
|
||||
static class Resolver |
|
||||
{ |
|
||||
private static Lazy<OperatingSystemType> Platform = |
|
||||
new Lazy<OperatingSystemType>( |
|
||||
() => AvaloniaLocator.Current.GetService<IRuntimePlatform>().GetRuntimeInfo().OperatingSystem); |
|
||||
|
|
||||
public static ICustomGtk3NativeLibraryResolver Custom { get; set; } |
|
||||
|
|
||||
|
|
||||
static string FormatName(string name, int version = 0) |
|
||||
{ |
|
||||
if (Platform.Value == OperatingSystemType.WinNT) |
|
||||
return "lib" + name + "-" + version + ".dll"; |
|
||||
if (Platform.Value == OperatingSystemType.Linux) |
|
||||
return "lib" + name + ".so" + "." + version; |
|
||||
if (Platform.Value == OperatingSystemType.OSX) |
|
||||
return "lib" + name + "." + version + ".dylib"; |
|
||||
throw new Exception("Unknown platform, use custom name resolver"); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
static string GetDllName(GtkDll dll) |
|
||||
{ |
|
||||
var name = Custom?.GetName(dll); |
|
||||
if (name != null) |
|
||||
return name; |
|
||||
|
|
||||
switch (dll) |
|
||||
{ |
|
||||
case GtkDll.Cairo: |
|
||||
return FormatName("cairo", 2); |
|
||||
case GtkDll.Gdk: |
|
||||
return FormatName("gdk-3"); |
|
||||
case GtkDll.Glib: |
|
||||
return FormatName("glib-2.0"); |
|
||||
case GtkDll.Gio: |
|
||||
return FormatName("gio-2.0"); |
|
||||
case GtkDll.Gtk: |
|
||||
return FormatName("gtk-3"); |
|
||||
case GtkDll.Gobject: |
|
||||
return FormatName("gobject-2.0"); |
|
||||
case GtkDll.GdkPixBuf: |
|
||||
return FormatName("gdk_pixbuf-2.0"); |
|
||||
default: |
|
||||
throw new ArgumentException("Unknown lib: " + dll); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
static IntPtr LoadDll(IDynamicLibraryLoader loader, GtkDll dll) |
|
||||
{ |
|
||||
|
|
||||
var exceptions = new List<Exception>(); |
|
||||
|
|
||||
var name = GetDllName(dll); |
|
||||
if (Custom?.TrySystemFirst != false) |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
return loader.LoadLibrary(name); |
|
||||
} |
|
||||
catch (Exception e) |
|
||||
{ |
|
||||
exceptions.Add(e); |
|
||||
} |
|
||||
} |
|
||||
var path = Custom?.Lookup(dll); |
|
||||
if (path == null && Custom?.BasePath != null) |
|
||||
path = Path.Combine(Custom.BasePath, name); |
|
||||
if (path != null) |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
return loader.LoadLibrary(path); |
|
||||
} |
|
||||
catch (Exception e) |
|
||||
{ |
|
||||
exceptions.Add(e); |
|
||||
} |
|
||||
} |
|
||||
throw new AggregateException("Unable to load " + dll, exceptions); |
|
||||
} |
|
||||
|
|
||||
public static void Resolve(string basePath = null) |
|
||||
{ |
|
||||
var loader = AvaloniaLocator.Current.GetService<IDynamicLibraryLoader>(); |
|
||||
|
|
||||
var dlls = Enum.GetValues(typeof(GtkDll)).Cast<GtkDll>().ToDictionary(x => x, x => LoadDll(loader, x)); |
|
||||
|
|
||||
foreach (var fieldInfo in typeof(Native).GetTypeInfo().DeclaredFields) |
|
||||
{ |
|
||||
var import = fieldInfo.FieldType.GetTypeInfo().GetCustomAttributes(typeof(GtkImportAttribute), true).Cast<GtkImportAttribute>().FirstOrDefault(); |
|
||||
if(import == null) |
|
||||
continue; |
|
||||
IntPtr lib = dlls[import.Dll]; |
|
||||
|
|
||||
var funcPtr = loader.GetProcAddress(lib, import.Name ?? fieldInfo.FieldType.Name, import.Optional); |
|
||||
|
|
||||
if (funcPtr != IntPtr.Zero) |
|
||||
fieldInfo.SetValue(null, Marshal.GetDelegateForFunctionPointer(funcPtr, fieldInfo.FieldType)); |
|
||||
} |
|
||||
|
|
||||
var nativeHandleNames = new[] { "gdk_win32_window_get_handle", "gdk_x11_window_get_xid", "gdk_quartz_window_get_nswindow" }; |
|
||||
foreach (var name in nativeHandleNames) |
|
||||
{ |
|
||||
var ptr = loader.GetProcAddress(dlls[GtkDll.Gdk], name, true); |
|
||||
if (ptr == IntPtr.Zero) |
|
||||
continue; |
|
||||
Native.GetNativeGdkWindowHandle = (Native.D.gdk_get_native_handle) Marshal |
|
||||
.GetDelegateForFunctionPointer(ptr, typeof(Native.D.gdk_get_native_handle)); |
|
||||
} |
|
||||
if (Native.GetNativeGdkWindowHandle == null) |
|
||||
throw new Exception($"Unable to locate any of [{string.Join(", ", nativeHandleNames)}] in libgdk"); |
|
||||
|
|
||||
} |
|
||||
|
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@ -1,47 +0,0 @@ |
|||||
using System; |
|
||||
using System.Runtime.InteropServices; |
|
||||
using Avalonia.Platform.Interop; |
|
||||
|
|
||||
namespace Avalonia.Gtk3.Interop |
|
||||
{ |
|
||||
class Signal |
|
||||
{ |
|
||||
class ConnectedSignal : IDisposable |
|
||||
{ |
|
||||
private readonly GObject _instance; |
|
||||
private GCHandle _handle; |
|
||||
private readonly ulong _id; |
|
||||
|
|
||||
public ConnectedSignal(GObject instance, GCHandle handle, ulong id) |
|
||||
{ |
|
||||
_instance = instance; |
|
||||
Native.GObjectRef(instance); |
|
||||
_handle = handle; |
|
||||
_id = id; |
|
||||
} |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
if (_handle.IsAllocated) |
|
||||
{ |
|
||||
Native.GObjectUnref(_instance.DangerousGetHandle()); |
|
||||
Native.GSignalHandlerDisconnect(_instance, _id); |
|
||||
_handle.Free(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public static IDisposable Connect<T>(GObject obj, string name, T handler) |
|
||||
{ |
|
||||
var handle = GCHandle.Alloc(handler); |
|
||||
var ptr = Marshal.GetFunctionPointerForDelegate((Delegate)(object)handler); |
|
||||
using (var utf = new Utf8Buffer(name)) |
|
||||
{ |
|
||||
var id = Native.GSignalConnectObject(obj, utf, ptr, IntPtr.Zero, 0); |
|
||||
if (id == 0) |
|
||||
throw new ArgumentException("Unable to connect to signal " + name); |
|
||||
return new ConnectedSignal(obj, handle, id); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue