Browse Source

Merge branch 'master' into droid-popup

pull/883/head
Jeremy Koritzinsky 9 years ago
committed by GitHub
parent
commit
b85e598152
  1. 2
      src/Gtk/Avalonia.Gtk3/FramebufferManager.cs
  2. 21
      src/Gtk/Avalonia.Gtk3/ImageSurfaceFramebuffer.cs
  3. 10
      src/Gtk/Avalonia.Gtk3/Interop/DynLoader.cs
  4. 30
      src/Gtk/Avalonia.Gtk3/Interop/Native.cs
  5. 10
      src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs
  6. 11
      src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs
  7. 41
      src/Gtk/Avalonia.Gtk3/WindowImpl.cs

2
src/Gtk/Avalonia.Gtk3/FramebufferManager.cs

@ -26,7 +26,7 @@ namespace Avalonia.Gtk3
throw new InvalidOperationException("Window is not in drawing state");
var width = (int) _window.ClientSize.Width;
var height = (int) _window.ClientSize.Height;
return new ImageSurfaceFramebuffer(_window.CurrentCairoContext, width, height);
return new ImageSurfaceFramebuffer(_window.CurrentCairoContext, _window.GtkWidget, width, height);
}
}
}

21
src/Gtk/Avalonia.Gtk3/ImageSurfaceFramebuffer.cs

@ -13,12 +13,19 @@ namespace Avalonia.Gtk3
class ImageSurfaceFramebuffer : ILockedFramebuffer
{
private IntPtr _context;
private readonly GtkWidget _widget;
private CairoSurface _surface;
private int _factor;
public ImageSurfaceFramebuffer(IntPtr context, int width, int height)
public ImageSurfaceFramebuffer(IntPtr context, GtkWidget widget, int width, int height)
{
_context = context;
_widget = widget;
_factor = (int)(Native.GtkWidgetGetScaleFactor?.Invoke(_widget) ?? 1u);
width *= _factor;
height *= _factor;
_surface = Native.CairoImageSurfaceCreate(1, width, height);
Width = width;
Height = height;
Address = Native.CairoImageSurfaceGetData(_surface);
@ -31,6 +38,7 @@ namespace Avalonia.Gtk3
if(_context == IntPtr.Zero || _surface == null)
return;
Native.CairoSurfaceMarkDirty(_surface);
Native.CairoScale(_context, 1d / _factor, 1d / _factor);
Native.CairoSetSourceSurface(_context, _surface, 0, 0);
Native.CairoPaint(_context);
_context = IntPtr.Zero;
@ -43,8 +51,15 @@ namespace Avalonia.Gtk3
public int Height { get; }
public int RowBytes { get; }
//TODO: Proper DPI detect
public Size Dpi => new Size(96, 96);
public Size Dpi
{
get
{
return new Size(96, 96) * _factor;
}
}
public PixelFormat Format => PixelFormat.Bgra8888;
}

10
src/Gtk/Avalonia.Gtk3/Interop/DynLoader.cs

@ -13,7 +13,7 @@ namespace Avalonia.Gtk3.Interop
internal interface IDynLoader
{
IntPtr LoadLibrary(string dll);
IntPtr GetProcAddress(IntPtr dll, string proc);
IntPtr GetProcAddress(IntPtr dll, string proc, bool optional);
}
@ -91,10 +91,10 @@ namespace Avalonia.Gtk3.Interop
return handle;
}
public IntPtr GetProcAddress(IntPtr dll, string proc)
public IntPtr GetProcAddress(IntPtr dll, string proc, bool optional)
{
var ptr = DlSym(dll, proc);
if (ptr == IntPtr.Zero)
if (ptr == IntPtr.Zero && !optional)
throw new NativeException(DlErrorString());
return ptr;
}
@ -118,10 +118,10 @@ namespace Avalonia.Gtk3.Interop
throw new NativeException("Error loading " + dll + " error " + err);
}
IntPtr IDynLoader.GetProcAddress(IntPtr dll, string proc)
IntPtr IDynLoader.GetProcAddress(IntPtr dll, string proc, bool optional)
{
var ptr = GetProcAddress(dll, proc);
if (ptr == IntPtr.Zero)
if (ptr == IntPtr.Zero && !optional)
throw new NativeException("Error " + Marshal.GetLastWin32Error());
return ptr;
}

30
src/Gtk/Avalonia.Gtk3/Interop/Native.cs

@ -50,6 +50,10 @@ namespace Avalonia.Gtk3.Interop
[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)]
@ -130,6 +134,9 @@ namespace Avalonia.Gtk3.Interop
[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_scale(IntPtr context, double sx, double sy);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
public delegate void cairo_paint(IntPtr context);
@ -156,6 +163,22 @@ namespace Avalonia.Gtk3.Interop
[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.Gdk)]
public delegate void gdk_window_iconify(IntPtr window);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate void gdk_window_deiconify(IntPtr window);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate void gdk_window_maximize(IntPtr window);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate void gdk_window_unmaximize(IntPtr window);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate void gtk_window_set_geometry_hints(GtkWindow window, IntPtr geometry_widget, ref GdkGeometry geometry, GdkWindowHints geom_mask);
@ -259,6 +282,7 @@ namespace Avalonia.Gtk3.Interop
public static D.gtk_widget_hide GtkWidgetHide;
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;
@ -303,6 +327,11 @@ namespace Avalonia.Gtk3.Interop
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.gdk_window_iconify GdkWindowIconify;
public static D.gdk_window_deiconify GdkWindowDeiconify;
public static D.gdk_window_maximize GdkWindowMaximize;
public static D.gdk_window_unmaximize GdkWindowUnmaximize;
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;
@ -322,6 +351,7 @@ namespace Avalonia.Gtk3.Interop
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_scale CairoScale;
public static D.cairo_paint CairoPaint;
}

10
src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs

@ -128,9 +128,11 @@ namespace Avalonia.Gtk3.Interop
if(import == null)
continue;
IntPtr lib = dlls[import.Dll];
var funcPtr = loader.GetProcAddress(lib, import.Name ?? fieldInfo.FieldType.Name);
fieldInfo.SetValue(null, Marshal.GetDelegateForFunctionPointer(funcPtr, fieldInfo.FieldType));
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" };
@ -139,7 +141,7 @@ namespace Avalonia.Gtk3.Interop
try
{
Native.GetNativeGdkWindowHandle = (Native.D.gdk_get_native_handle)Marshal
.GetDelegateForFunctionPointer(loader.GetProcAddress(dlls[GtkDll.Gdk], name), typeof(Native.D.gdk_get_native_handle));
.GetDelegateForFunctionPointer(loader.GetProcAddress(dlls[GtkDll.Gdk], name, false), typeof(Native.D.gdk_get_native_handle));
break;
}
catch { }

11
src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs

@ -21,6 +21,7 @@ namespace Avalonia.Gtk3
protected readonly List<IDisposable> Disposables = new List<IDisposable>();
private Size _lastSize;
private Point _lastPosition;
private double _lastScaling;
private uint _lastKbdEvent;
private uint _lastSmoothScrollEvent;
@ -63,7 +64,12 @@ namespace Avalonia.Gtk3
PositionChanged?.Invoke(pos);
_lastPosition = pos;
}
var scaling = Scaling;
if (_lastScaling != scaling)
{
ScalingChanged?.Invoke(scaling);
_lastScaling = scaling;
}
return false;
}
@ -228,7 +234,8 @@ namespace Avalonia.Gtk3
}
public double Scaling => 1; //TODO: Implement scaling
public double Scaling => (double) 1 / (Native.GtkWidgetGetScaleFactor?.Invoke(GtkWidget) ?? 1);
public IPlatformHandle Handle => this;
string IPlatformHandle.HandleDescriptor => "HWND";

41
src/Gtk/Avalonia.Gtk3/WindowImpl.cs

@ -7,21 +7,42 @@ namespace Avalonia.Gtk3
{
class WindowImpl : TopLevelImpl, IWindowImpl
{
public WindowState WindowState { get; set; } //STUB
public WindowImpl() : base(Native.GtkWindowNew(GtkWindowType.TopLevel))
{
}
public void SetTitle(string title)
{
using (var t = new Utf8Buffer(title))
Native.GtkWindowSetTitle(GtkWidget, t);
}
class EmptyDisposable : IDisposable
public WindowState WindowState
{
public void Dispose()
get
{
var state = Native.GdkWindowGetState(Native.GtkWidgetGetWindow(GtkWidget));
if (state.HasFlag(GdkWindowState.Iconified))
return WindowState.Minimized;
if (state.HasFlag(GdkWindowState.Maximized))
return WindowState.Maximized;
return WindowState.Normal;
}
set
{
var w = Native.GtkWidgetGetWindow(GtkWidget);
if (value == WindowState.Minimized)
Native.GdkWindowIconify(w);
else if (value == WindowState.Maximized)
Native.GdkWindowMaximize(w);
else
{
Native.GdkWindowUnmaximize(w);
Native.GdkWindowDeiconify(w);
}
}
}
public IDisposable ShowDialog()
{
Native.GtkWindowSetModal(GtkWidget, true);
@ -33,13 +54,17 @@ namespace Avalonia.Gtk3
public void SetIcon(IWindowIconImpl icon) => Native.GtkWindowSetIcon(GtkWidget, (Pixbuf) icon);
public WindowImpl() : base(Native.GtkWindowNew(GtkWindowType.TopLevel))
public void SetCoverTaskbarWhenMaximized(bool enable)
{
//Why do we even have that?
}
public void SetCoverTaskbarWhenMaximized(bool enable)
class EmptyDisposable : IDisposable
{
//Why do we even have that?
public void Dispose()
{
}
}
}
}

Loading…
Cancel
Save