From 63a6f50341b6deaa34ee01466220be1a50ccc9da Mon Sep 17 00:00:00 2001 From: "softoille@gmail.com" Date: Thu, 16 Jan 2020 07:05:27 -0600 Subject: [PATCH] Fixed issues where Chromely does not work on some Linux distros - https://github.com/cztomczak/cefpython/issues/393 --- .../Configuration/DefaultConfiguration.cs | 12 +- src/Chromely/Native/LinuxGtk3/GListUtil.cs | 49 ++++ src/Chromely/Native/LinuxGtk3/Library.cs | 17 ++ .../Native/LinuxGtk3/LinuxGtk3Host.cs | 111 ++++---- .../Native/LinuxGtk3/LinuxNativeMethods.cs | 105 +++---- src/Chromely/Native/LinuxGtk3/Utils.cs | 262 ++++++++++++++++++ src/Chromely/Native/MacCocoa/MacCocoaHost.cs | 27 +- 7 files changed, 449 insertions(+), 134 deletions(-) create mode 100644 src/Chromely/Native/LinuxGtk3/GListUtil.cs create mode 100644 src/Chromely/Native/LinuxGtk3/Library.cs create mode 100644 src/Chromely/Native/LinuxGtk3/Utils.cs diff --git a/src/Chromely.Core/Configuration/DefaultConfiguration.cs b/src/Chromely.Core/Configuration/DefaultConfiguration.cs index 33606bc5..31a768b0 100644 --- a/src/Chromely.Core/Configuration/DefaultConfiguration.cs +++ b/src/Chromely.Core/Configuration/DefaultConfiguration.cs @@ -4,6 +4,7 @@ using Chromely.Core.Network; using System; using System.Collections.Generic; +using System.IO; using System.Reflection; namespace Chromely.Core.Configuration @@ -85,7 +86,13 @@ public DefaultConfiguration() }); ControllerAssemblies = new List(); - ControllerAssemblies.RegisterServiceAssembly("Chromely.External.Controllers.dll"); + + var appDirectory = AppDomain.CurrentDomain.BaseDirectory; + var externaControllerFile = Path.Combine(appDirectory, "Chromely.External.Controllers.dll"); + if (File.Exists(externaControllerFile)) + { + ControllerAssemblies.RegisterServiceAssembly("Chromely.External.Controllers.dll"); + } CustomSettings = new Dictionary() { @@ -124,8 +131,7 @@ public static IChromelyConfiguration CreateForPlatform(ChromelyPlatform platform config.CommandLineOptions = new List() { "no-zygote", - "disable-gpu", - "disable-software-rasterizer" + "disable-gpu" }; break; diff --git a/src/Chromely/Native/LinuxGtk3/GListUtil.cs b/src/Chromely/Native/LinuxGtk3/GListUtil.cs new file mode 100644 index 00000000..567fea57 --- /dev/null +++ b/src/Chromely/Native/LinuxGtk3/GListUtil.cs @@ -0,0 +1,49 @@ +using System; +using System.Runtime.InteropServices; + +namespace Chromely.Native +{ + public class GListUtil + { + private readonly IntPtr _list; + public GListUtil(IntPtr list) + { + _list = list; + } + + public int Length + { + get + { + return g_list_length(_list); + } + } + + public void Free() + { + if (_list != IntPtr.Zero) + g_list_free(_list); + } + + public IntPtr GetItem(int nth) + { + if (_list != IntPtr.Zero) + return g_list_nth_data(_list, (uint)nth); + + return IntPtr.Zero; + } + + #region DLLIMPORTS GlibLib + + [DllImport(Library.GlibLib, CallingConvention = CallingConvention.Cdecl)] + static extern int g_list_length(IntPtr l); + + [DllImport(Library.GlibLib, CallingConvention = CallingConvention.Cdecl)] + static extern void g_list_free(IntPtr l); + + [DllImport(Library.GlibLib, CallingConvention = CallingConvention.Cdecl)] + static extern IntPtr g_list_nth_data(IntPtr l, uint n); + + #endregion + } +} diff --git a/src/Chromely/Native/LinuxGtk3/Library.cs b/src/Chromely/Native/LinuxGtk3/Library.cs new file mode 100644 index 00000000..76741fc3 --- /dev/null +++ b/src/Chromely/Native/LinuxGtk3/Library.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Chromely.Native +{ + public static class Library + { + internal const string GtkLib = "libgtk-3.so.0"; + internal const string GObjLib = "libgobject-2.0.so.0"; + internal const string GdkLib = "libgdk-3.so.0"; + internal const string GlibLib = "libglib-2.0.so.0"; + internal const string GioLib = "libgio-2.0.so.0"; + internal const string GdkPixBuf = "libgdk_pixbuf-2.0.so.0"; + internal const string X11Lib = "libX11.so"; + } +} diff --git a/src/Chromely/Native/LinuxGtk3/LinuxGtk3Host.cs b/src/Chromely/Native/LinuxGtk3/LinuxGtk3Host.cs index af3a2c4b..54059c44 100644 --- a/src/Chromely/Native/LinuxGtk3/LinuxGtk3Host.cs +++ b/src/Chromely/Native/LinuxGtk3/LinuxGtk3Host.cs @@ -22,17 +22,40 @@ public class LinuxGtk3Host : IChromelyNativeHost private IWindowOptions _options; private IntPtr _handle; - private IntPtr _gdkHandle; private IntPtr _xid; private bool _isInitialized; private bool _debugging; + private RealizeCallback _onRealizedDelegate; + private SizeAllocateCallback _onSizeAllocateDelegate; + private ResizeCallback _onResizeDelegate; + private DestroyCallback _onDestroyDelegate; + + private IntPtr _onRealizedSignal; + private IntPtr _onSizeAllocateSignal; + private IntPtr _onResizeSignal; + private IntPtr _onDestroySignal; + + private GClosureNotify _onFreeNotify; + + private XHandleXError _onHandleErrorDelegate; + private XHandleXIOError _onHandleIOErrorDelegate; + public LinuxGtk3Host() { _isInitialized = false; _handle = IntPtr.Zero; - _gdkHandle = IntPtr.Zero; _xid = IntPtr.Zero; + + _onRealizedDelegate = new RealizeCallback(OnRealized); + _onSizeAllocateDelegate = new SizeAllocateCallback(OnSizeAllocate); + _onResizeDelegate = new ResizeCallback(OnResize); + _onDestroyDelegate = new DestroyCallback(OnDestroy); + + _onFreeNotify = new GClosureNotify(FreeData); + + _onHandleErrorDelegate = new XHandleXError(HandleError); + _onHandleIOErrorDelegate = new XHandleXIOError(HandleIOError); } public void CreateWindow(IWindowOptions config, bool debugging) @@ -71,10 +94,12 @@ public void CreateWindow(IWindowOptions config, bool debugging) break; } - ConnectRealizeSignal(OnRealized, FreeData); - ConnectSizeAllocateSignal(OnSizeAllocate, FreeData); - ConnectResizeSignal(OnResize, FreeData); - ConnectDestroySignal(OnDestroy, FreeData); + ConnectRealizeSignal(_onRealizedDelegate, _onFreeNotify); + ConnectSizeAllocateSignal(_onSizeAllocateDelegate, _onFreeNotify); + ConnectResizeSignal(_onResizeDelegate, _onFreeNotify); + ConnectDestroySignal(_onDestroyDelegate, _onFreeNotify); + + SetDefaultWindowVisual(_handle); ShowWindow(); } @@ -83,11 +108,11 @@ public IntPtr GetNativeHandle() { try { - _gdkHandle = gtk_widget_get_window(_handle); - Utils.AssertNotNull("GetNativeHandle:gtk_widget_get_window", _gdkHandle); - _xid = gdk_x11_window_get_xid(_gdkHandle); - Utils.AssertNotNull("GetNativeHandle:gdk_x11_window_get_xid", _xid); - return _xid; + IntPtr gdkHandle = gtk_widget_get_window(_handle); + Utils.AssertNotNull("GetNativeHandle:gtk_widget_get_window", gdkHandle); + IntPtr xid = gdk_x11_window_get_xid(gdkHandle); + Utils.AssertNotNull("GetNativeHandle:gdk_x11_window_get_xid", xid); + return xid; } catch (Exception exception) { @@ -198,6 +223,9 @@ public void MessageBox(string message, int type) private delegate bool DestroyCallback(IntPtr window, IntPtr data); private delegate void QuitCallback(); + private delegate short HandleErrorCallback(IntPtr display, ref XErrorEvent errorEven); + private delegate short HandleIOErrorCallback(IntPtr d); + private void Init(int argc, string[] argv) { try @@ -219,8 +247,8 @@ private void InstallX11ErrorHandlers() // Copied from CEF upstream cefclient. // Install xlib error handlers so that the application won't be terminated // on non-fatal errors. Must be done after initializing GTK. - XSetErrorHandler(HandleError); - XSetIOErrorHandler(HandleIOError); + XSetErrorHandler(_onHandleErrorDelegate); + XSetIOErrorHandler(_onHandleIOErrorDelegate); } catch (Exception exception) { @@ -233,17 +261,12 @@ private short HandleError(IntPtr display, ref XErrorEvent errorEvent) { try { - if (this._debugging) + if (this._debugging && errorEvent.request_code > 0 && errorEvent.error_code > 0) { - var builder = new StringBuilder(); - builder.AppendLine("X error received: "); - builder.AppendLine("type " + errorEvent.type); - builder.AppendLine("serial " + errorEvent.serial); - builder.AppendLine("error_code " + errorEvent.error_code); - builder.AppendLine("request_code " + errorEvent.request_code); - builder.AppendLine("minor_code " + errorEvent.minor_code); - - Logger.Instance.Log.Warn(builder.ToString()); + var errorMsgSb = new StringBuilder(160); + XGetErrorText(display, errorEvent.error_code, errorMsgSb, errorMsgSb.Capacity); + var requestType = GetRequestType(errorEvent.request_code); + Logger.Instance.Log.Warn($"Request Code: {errorEvent.request_code}\tRequest Type: {requestType}\tX11 Error: {errorMsgSb.ToString()}"); } return 0; @@ -280,22 +303,6 @@ private IntPtr CreateNewWindow(int windowType) return IntPtr.Zero; } - private IntPtr GetGdkHandle() - { - try - { - _gdkHandle = gtk_widget_get_window(_handle); - Utils.AssertNotNull("GetGdkHandle", _gdkHandle); - return _gdkHandle; - } - catch (Exception exception) - { - Logger.Instance.Log.Error("Error in LinuxGtk3Host::GetGdkHandle"); - Logger.Instance.Log.Error(exception); - } - - return IntPtr.Zero; - } private void SetWindowTitle(string title) { try @@ -438,9 +445,11 @@ private bool OnDestroy(IntPtr window, IntPtr data) private void ConnectRealizeSignal(RealizeCallback callback, GClosureNotify destroyData) { + _onRealizedSignal = Marshal.GetFunctionPointerForDelegate(callback); + RegisterHandler( "realize", - Marshal.GetFunctionPointerForDelegate(callback), + _onRealizedSignal, destroyData, GConnectFlags.GConnectAfter, IntPtr.Zero); @@ -448,9 +457,11 @@ private void ConnectRealizeSignal(RealizeCallback callback, GClosureNotify destr private void ConnectSizeAllocateSignal(SizeAllocateCallback callback, GClosureNotify destroyData) { + _onSizeAllocateSignal = Marshal.GetFunctionPointerForDelegate(callback); + RegisterHandler( "size-allocate", - Marshal.GetFunctionPointerForDelegate(callback), + _onSizeAllocateSignal, destroyData, GConnectFlags.GConnectAfter, IntPtr.Zero); @@ -458,9 +469,11 @@ private void ConnectSizeAllocateSignal(SizeAllocateCallback callback, GClosureNo private void ConnectResizeSignal(ResizeCallback callback, GClosureNotify destroyData) { + _onResizeSignal = Marshal.GetFunctionPointerForDelegate(callback); + RegisterHandler( "configure-event", - Marshal.GetFunctionPointerForDelegate(callback), + _onResizeSignal, destroyData, GConnectFlags.GConnectAfter, IntPtr.Zero); @@ -468,19 +481,11 @@ private void ConnectResizeSignal(ResizeCallback callback, GClosureNotify destroy private void ConnectDestroySignal(DestroyCallback callback, GClosureNotify destroyData) { - RegisterHandler( - "delete-event", - Marshal.GetFunctionPointerForDelegate(callback), - destroyData, - GConnectFlags.GConnectAfter, - IntPtr.Zero); - } + _onDestroySignal = Marshal.GetFunctionPointerForDelegate(callback); - private void ConnectQuitSignal(QuitCallback callback, GClosureNotify destroyData) - { RegisterHandler( - "destroy", - Marshal.GetFunctionPointerForDelegate(callback), + "delete-event", + _onDestroySignal, destroyData, GConnectFlags.GConnectAfter, IntPtr.Zero); diff --git a/src/Chromely/Native/LinuxGtk3/LinuxNativeMethods.cs b/src/Chromely/Native/LinuxGtk3/LinuxNativeMethods.cs index 891abcde..6ddef1c5 100644 --- a/src/Chromely/Native/LinuxGtk3/LinuxNativeMethods.cs +++ b/src/Chromely/Native/LinuxGtk3/LinuxNativeMethods.cs @@ -1,123 +1,98 @@ using System; using System.Runtime.InteropServices; +using System.Text; namespace Chromely.Native { - internal class LinuxNativeMethods + internal partial class LinuxNativeMethods { - internal const string GtkLib = "libgtk-3.so.0"; - internal const string GObjLib = "libgobject-2.0.so.0"; - internal const string GdkLib = "libgdk-3.so.0"; - internal const string GlibLib = "libglib-2.0.so.0"; - internal const string GioLib = "libgio-2.0.so.0"; - internal const string GdkPixBuf = "libgdk_pixbuf-2.0.so.0"; - - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern void gtk_init(int argc, string[] argv); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gtk_window_new(GtkWindowType type); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = false)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = false)] internal static extern void gtk_main(); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gtk_widget_get_window(IntPtr widget); - [DllImport(GdkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] + internal static extern void gtk_widget_set_visual(IntPtr widget, IntPtr visual); + + [DllImport(Library.GdkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gdk_x11_window_get_xid(IntPtr raw); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gtk_widget_get_display(IntPtr window); - [DllImport(GdkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GdkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gdk_x11_display_get_xdisplay(IntPtr gdkDisplay); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern void gtk_widget_show_all(IntPtr window); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern void gtk_window_get_size(IntPtr window, out int width, out int height); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gtk_window_set_title(IntPtr window, string title); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern void gtk_window_set_default_size(IntPtr window, int width, int height); - [DllImport(GdkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GdkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern void gdk_window_resize(IntPtr window, int width, int height); - [DllImport(GdkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GdkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern void gdk_window_move_resize(IntPtr window, int x, int y, int width, int height); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = false)] + [DllImport(Library.GdkLib, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr gdk_x11_visual_get_xvisual(IntPtr handle); + + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = false)] internal static extern bool gtk_window_set_icon_from_file(IntPtr raw, string filename, out IntPtr err); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern bool gtk_window_set_position(IntPtr window, GtkWindowPosition position); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern bool gtk_window_maximize(IntPtr window); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern bool gtk_window_fullscreen(IntPtr window); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern void gtk_main_quit(); + [DllImport(Library.GdkLib, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr gdk_screen_get_default(); + + [DllImport(Library.GdkLib, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr gdk_x11_screen_lookup_visual(IntPtr screen, IntPtr xvisualid); + + [DllImport(Library.GdkLib, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr gdk_screen_list_visuals(IntPtr raw); + // Signals - [DllImport(GObjLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GObjLib, CallingConvention = CallingConvention.Cdecl)] internal static extern uint g_signal_connect_data(IntPtr instance, string detailedSignal, IntPtr handler, IntPtr data, GClosureNotify destroyData, GConnectFlags connectFlags); // MessageBox - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gtk_message_dialog_new(IntPtr parent_window, DialogFlags flags, MessageType type, ButtonsType bt, string msg, IntPtr args); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern int gtk_dialog_run(IntPtr raw); - [DllImport(GtkLib, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GtkLib, CallingConvention = CallingConvention.Cdecl)] internal static extern void gtk_widget_destroy(IntPtr widget); #region Icon work - [DllImport(GdkPixBuf, CallingConvention = CallingConvention.Cdecl)] + [DllImport(Library.GdkPixBuf, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr gdk_pixbuf_new_from_file_utf8(IntPtr filename, out IntPtr error); #endregion - - #region X11 - - internal delegate short XHandleXError(IntPtr display, ref XErrorEvent error_event); - internal delegate short XHandleXIOError(IntPtr display); - - [DllImport("libX11.so")] - internal static extern int XMoveWindow(IntPtr display, IntPtr w, int x, int y); - - [DllImport("libX11.so")] - internal static extern int XResizeWindow(IntPtr display, IntPtr w, int width, int height); - - [DllImport("libX11.so")] - internal static extern int XMoveResizeWindow(IntPtr display, IntPtr w, int x, int y, int width, int height); - - [DllImport("libX11.so")] - internal static extern short XSetErrorHandler(XHandleXError err); - - [DllImport("libX11.so")] - internal static extern short XSetIOErrorHandler(XHandleXIOError err); - - [StructLayout(LayoutKind.Sequential)] - internal struct XErrorEvent - { - internal int type; - internal IntPtr display; - internal int resourceid; - internal int serial; - internal byte error_code; - internal byte request_code; - internal byte minor_code; - } - - #endregion } } diff --git a/src/Chromely/Native/LinuxGtk3/Utils.cs b/src/Chromely/Native/LinuxGtk3/Utils.cs new file mode 100644 index 00000000..46916aaa --- /dev/null +++ b/src/Chromely/Native/LinuxGtk3/Utils.cs @@ -0,0 +1,262 @@ +using Chromely.Core.Logging; +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace Chromely.Native +{ + internal partial class LinuxNativeMethods + { + public static void SetDefaultWindowVisual(IntPtr widget) + { + // *** https://stackoverrun.com/hi/q/11294280 + try + { + // https://github.com/cztomczak/cefcapi/issues/9 + + // GTK+ > 3.15.1 uses an X11 visual optimized for GTK+'s OpenGL stuff + // since revid dae447728d: https://github.com/GNOME/gtk/commit/dae447728d + // However, it breaks CEF: https://github.com/cztomczak/cefcapi/issues/9 + // Let's use the default X11 visual instead the GTK's blessed one. + + var xDisplay = XOpenDisplay(IntPtr.Zero); + var screenNumber = XDefaultScreen(xDisplay); + var xVisual = XDefaultVisual(xDisplay, screenNumber); + var visualId = XVisualIDFromVisual(xVisual); + + var gdkScreen = gdk_screen_get_default(); + var gdkVisualList = gdk_screen_list_visuals(gdkScreen); + + if (gdkVisualList == IntPtr.Zero) + { + Logger.Instance.Log.Warn("Warning in LinuxNativeMethods::SetDefaultWindowVisual: List of visuals is invalid."); + return; + } + + var glistUtil = new GListUtil(gdkVisualList); + int length = glistUtil.Length; + + for (int i = 0; i < length; i++) + { + var currItem = glistUtil.GetItem(i); + if (currItem != IntPtr.Zero) + { + var currVisual = gdk_x11_visual_get_xvisual(currItem); + var currVisualId = XVisualIDFromVisual(currVisual); + if (visualId == currVisualId) + { + var gdkVisual = gdk_x11_screen_lookup_visual(gdkScreen, currVisualId); + gtk_widget_set_visual(widget, gdkVisual); + break; + } + } + } + + glistUtil.Free(); + XCloseDisplay(xDisplay); + } + catch (Exception exception) + { + Logger.Instance.Log.Error("Error in LinuxNativeMethods::SetDefaultWindowVisual"); + Logger.Instance.Log.Error(exception); + } + } + + #region X11 + + [StructLayout(LayoutKind.Sequential)] + internal struct XVisualInfo + { + internal IntPtr visual; + internal IntPtr visualid; + internal int screen; + internal uint depth; + internal int klass; + internal IntPtr red_mask; + internal IntPtr green_mask; + internal IntPtr blue_mask; + internal int colormap_size; + internal int bits_per_rgb; + } + + internal delegate short XHandleXError(IntPtr display, ref XErrorEvent error_event); + internal delegate short XHandleXIOError(IntPtr display); + + [DllImport(Library.X11Lib)] + internal static extern int XMoveWindow(IntPtr display, IntPtr w, int x, int y); + + [DllImport(Library.X11Lib)] + internal static extern int XResizeWindow(IntPtr display, IntPtr w, int width, int height); + + [DllImport(Library.X11Lib)] + internal static extern int XMoveResizeWindow(IntPtr display, IntPtr w, int x, int y, int width, int height); + + [DllImport(Library.X11Lib)] + internal static extern IntPtr XOpenDisplay(IntPtr display); + + [DllImport(Library.X11Lib)] + internal static extern int XCloseDisplay(IntPtr display); + + [DllImport(Library.X11Lib)] + internal static extern int XDefaultScreen(IntPtr display); + + [DllImport(Library.X11Lib)] + internal static extern IntPtr XDefaultVisual(IntPtr display, int screen); + + [DllImport(Library.X11Lib)] + internal static extern IntPtr XVisualIDFromVisual(IntPtr visual); + + [DllImport(Library.X11Lib)] + internal static extern short XSetErrorHandler(XHandleXError err); + + [DllImport(Library.X11Lib)] + internal static extern short XSetIOErrorHandler(XHandleXIOError err); + + [DllImport(Library.X11Lib)] + internal extern static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length); + + [StructLayout(LayoutKind.Sequential)] + internal struct XErrorEvent + { + internal int type; + internal IntPtr display; + internal int resourceid; + internal int serial; + internal byte error_code; + internal byte request_code; + internal byte minor_code; + } + + internal static string GetRequestType(int requestId) + { + switch (requestId) + { + case 1: return "X_CreateWindow"; + case 2: return "X_ChangeWindowAttributes"; + case 3: return "X_GetWindowAttributes"; + case 4: return "X_DestroyWindow"; + case 5: return "X_DestroySubwindows"; + case 6: return "X_ChangeSaveSet"; + case 7: return "X_ReparentWindow"; + case 8: return "X_MapWindow"; + case 9: return "X_MapSubwindows"; + case 10: return "X_UnmapWindow"; + case 11: return "X_UnmapSubwindows"; + case 12: return "X_ConfigureWindow"; + case 13: return "X_CirculateWindow"; + case 14: return "X_GetGeometry"; + case 15: return "X_QueryTree"; + case 16: return "X_InternAtom"; + case 17: return "X_GetAtomName"; + case 18: return "X_ChangeProperty"; + case 19: return "X_DeleteProperty"; + case 20: return "X_GetProperty"; + case 21: return "X_ListProperties"; + case 22: return "X_SetSelectionOwner"; + case 23: return "X_GetSelectionOwner"; + case 24: return "X_ConvertSelection"; + case 25: return "X_SendEvent"; + case 26: return "X_GrabPointer"; + case 27: return "X_UngrabPointer"; + case 28: return "X_GrabButton"; + case 29: return "X_UngrabButton"; + case 30: return "X_ChangeActivePointerGrab"; + case 31: return "X_GrabKeyboard"; + case 32: return "X_UngrabKeyboard"; + case 33: return "X_GrabKey"; + case 34: return "X_UngrabKey"; + case 35: return "X_AllowEvents"; + case 36: return "X_GrabServer"; + case 37: return "X_UngrabServer"; + case 38: return "X_QueryPointer"; + case 39: return "X_GetMotionEvents"; + case 40: return "X_TranslateCoords"; + case 41: return "X_WarpPointer"; + case 42: return "X_SetInputFocus"; + case 43: return "X_GetInputFocus"; + case 44: return "X_QueryKeymap"; + case 45: return "X_OpenFont"; + case 46: return "X_CloseFont"; + case 47: return "X_QueryFont"; + case 48: return "X_QueryTextExtents"; + case 49: return "X_ListFonts"; + case 50: return "X_ListFontsWithInfo"; + case 51: return "X_SetFontPath"; + case 52: return "X_GetFontPath"; + case 53: return "X_CreatePixmap"; + case 54: return "X_FreePixmap"; + case 55: return "X_CreateGC"; + case 56: return "X_ChangeGC"; + case 57: return "X_CopyGC"; + case 58: return "X_SetDashes"; + case 59: return "X_SetClipRectangles"; + case 60: return "X_FreeGC"; + case 61: return "X_ClearArea"; + case 62: return "X_CopyArea"; + case 63: return "X_CopyPlane"; + case 64: return "X_PolyPoint"; + case 65: return "X_PolyLine"; + case 66: return "X_PolySegment"; + case 67: return "X_PolyRectangle"; + case 68: return "X_PolyArc"; + case 69: return "X_FillPoly"; + case 70: return "X_PolyFillRectangle"; + case 71: return "X_PolyFillArc"; + case 72: return "X_PutImage"; + case 73: return "X_GetImage"; + case 74: return "X_PolyText8"; + case 75: return "X_PolyText16"; + case 76: return "X_ImageText8"; + case 77: return "X_ImageText16"; + case 78: return "X_CreateColormap"; + case 79: return "X_FreeColormap"; + case 80: return "X_CopyColormapAndFree"; + case 81: return "X_InstallColormap"; + case 82: return "X_UninstallColormap"; + case 83: return "X_ListInstalledColormaps"; + case 84: return "X_AllocColor"; + case 85: return "X_AllocNamedColor"; + case 86: return "X_AllocColorCells"; + case 87: return "X_AllocColorPlanes"; + case 88: return "X_FreeColors"; + case 89: return "X_StoreColors"; + case 90: return "X_StoreNamedColor"; + case 91: return "X_QueryColors"; + case 92: return "X_LookupColor"; + case 93: return "X_CreateCursor"; + case 94: return "X_CreateGlyphCursor"; + case 95: return "X_FreeCursor"; + case 96: return "X_RecolorCursor"; + case 97: return "X_QueryBestSize"; + case 98: return "X_QueryExtension"; + case 99: return "X_ListExtensions"; + case 100: return "X_ChangeKeyboardMapping"; + case 101: return "X_GetKeyboardMapping"; + case 102: return "X_ChangeKeyboardControl"; + case 103: return "X_GetKeyboardControl"; + case 104: return "X_Bell"; + case 105: return "X_ChangePointerControl"; + case 106: return "X_GetPointerControl"; + case 107: return "X_SetScreenSaver"; + case 108: return "X_GetScreenSaver"; + case 109: return "X_ChangeHosts"; + case 110: return "X_ListHosts"; + case 111: return "X_SetAccessControl"; + case 112: return "X_SetCloseDownMode"; + case 113: return "X_KillClient"; + case 114: return "X_RotateProperties"; + case 115: return "X_ForceScreenSaver"; + case 116: return "X_SetPointerMapping"; + case 117: return "X_GetPointerMapping"; + case 118: return "X_SetModifierMapping"; + case 119: return "X_GetModifierMapping"; + case 127: return "X_NoOperation"; + } + + return "NotFound"; + } + + #endregion + + } +} diff --git a/src/Chromely/Native/MacCocoa/MacCocoaHost.cs b/src/Chromely/Native/MacCocoa/MacCocoaHost.cs index 1f4dc9b5..ae256ae3 100644 --- a/src/Chromely/Native/MacCocoa/MacCocoaHost.cs +++ b/src/Chromely/Native/MacCocoa/MacCocoaHost.cs @@ -24,6 +24,7 @@ public class MacCocoaHost : IChromelyNativeHost private delegate void ResizeCallbackEvent(int width, int height); private delegate void QuitCallbackEvent(); + private ChromelyParam _configParam; private IWindowOptions _options; private IntPtr _appHandle; private IntPtr _poolHandle; @@ -43,7 +44,7 @@ public MacCocoaHost() public void CreateWindow(IWindowOptions options, bool debugging) { _options = options; - ChromelyParam configParam = InitParam(RunCallback, + _configParam = InitParam(RunCallback, ShutdownCallback, InitCallback, CreateCallback, @@ -52,21 +53,21 @@ public void CreateWindow(IWindowOptions options, bool debugging) QuitCallback); - configParam.centerscreen = _options.WindowState == WindowState.Normal && _options.StartCentered ? 1 : 0; - configParam.frameless = _options.WindowFrameless ? 1 : 0; - configParam.fullscreen = _options.WindowState == Core.Host.WindowState.Fullscreen ? 1 : 0; - configParam.noresize = _options.DisableResizing ? 1 : 0; - configParam.nominbutton = _options.DisableMinMaximizeControls ? 1 : 0; - configParam.nomaxbutton = _options.DisableMinMaximizeControls ? 1 : 0; + _configParam.centerscreen = _options.WindowState == WindowState.Normal && _options.StartCentered ? 1 : 0; + _configParam.frameless = _options.WindowFrameless ? 1 : 0; + _configParam.fullscreen = _options.WindowState == Core.Host.WindowState.Fullscreen ? 1 : 0; + _configParam.noresize = _options.DisableResizing ? 1 : 0; + _configParam.nominbutton = _options.DisableMinMaximizeControls ? 1 : 0; + _configParam.nomaxbutton = _options.DisableMinMaximizeControls ? 1 : 0; - configParam.title = _options.Title; + _configParam.title = _options.Title; - configParam.x = _options.Position.X; - configParam.y = _options.Position.Y; - configParam.width = _options.Size.Width; - configParam.height = _options.Size.Height; + _configParam.x = _options.Position.X; + _configParam.y = _options.Position.Y; + _configParam.width = _options.Size.Width; + _configParam.height = _options.Size.Height; - createwindow(ref configParam); + createwindow(ref _configParam); } #region CreateWindow