Hello everyone,
Thanks for welcome saying for me! I am new for here.
I thought SFML is better than SDL2 or Allegro5.
I have made one X11 with SFML with Mono 6.12.x = It works fine like chain. But I can't understand why does it throw BadDrawable in X11
I think VisualInfo is not XDefaultVisual() - It looks like advanced mode with Visual like GLX on X11.
I have made one nice example:
using System;using System.Runtime.InteropServices;using SFML.Graphics;using static X11SFML
.X11;namespace X11SFML
{ static class X11
{ public enum XEventType
{ KeyPress
= 2 } [StructLayout
(LayoutKind
.Explicit)] public struct XEvent
{ [FieldOffset
(0)] public XEventType type
; } public enum XEventMask
: long { KeyPressMask
= 1L
<< 0 } [StructLayout
(LayoutKind
.Sequential)] public struct XSetWindowAttributes
{ public uint background_pixel
; public XEventMask event_mask
; } [Flags
] public enum CWAttributes
: long { CWBackPixel
= 1L
<< 1,
CWEventMask
= 1L
<< 11 } private const string libX11
= "libX11.so.6"; [DllImport
(libX11
)] public extern static IntPtr XOpenDisplay
(string display_name
); [DllImport
(libX11
)] public extern static void XCloseDisplay
(IntPtr x_display
); [DllImport
(libX11
)] public extern static int XDefaultScreen
(IntPtr x_display
); [DllImport
(libX11
)] public extern static int XDefaultDepth
(IntPtr x_display,
int screen_number
); [DllImport
(libX11
)] public extern static IntPtr XDefaultVisual
(IntPtr x_display,
int screen_number
); [DllImport
(libX11
)] public extern static IntPtr XRootWindow
(IntPtr x_display,
int screen_number
); [DllImport
(libX11
)] public extern static uint XBlackPixel
(IntPtr x_display,
int screen_number
); [DllImport
(libX11
)] public extern static IntPtr XCreateWindow
(IntPtr x_display, IntPtr x_window_parent,
int x,
int y,
uint width,
uint height,
uint border_width,
int depth,
uint window_class, IntPtr visual, CWAttributes cws,
ref XSetWindowAttributes attributes
); [DllImport
(libX11
)] public extern static IntPtr XCreateWindow
(IntPtr x_display, IntPtr x_window_parent,
int x,
int y,
uint width,
uint height,
uint border_width,
int depth,
uint window_class, IntPtr visual, CWAttributes cws, IntPtr attributes
); [DllImport
(libX11
)] public extern static void XStoreName
(IntPtr x_display, IntPtr x_window,
string title
); [DllImport
(libX11
)] public extern static void XSync
(IntPtr x_display,
bool discard
); [DllImport
(libX11
)] public extern static void XMapWindow
(IntPtr x_display, IntPtr x_window
); [DllImport
(libX11
)] public extern static void XFlush
(IntPtr x_display
); [DllImport
(libX11
)] public extern static bool XPending
(IntPtr x_display
); [DllImport
(libX11
)] public extern static void XNextEvent
(IntPtr x_display,
out XEvent x_event
); } class MainClass
{ private const int EXIT_SUCCESS
= 0; private const int EXIT_FAILURE
= 1; static int Main
(string[] args
) { Console
.WriteLine("Hello X11 with SFML!"); IntPtr display
= XOpenDisplay
(null); if (display
== IntPtr
.Zero) { return EXIT_FAILURE
; } else { Console
.WriteLine("Display opened - SUCCESS"); } int screen_number
= XDefaultScreen
(display
); int depths
= XDefaultDepth
(display, screen_number
); IntPtr root_window
= XRootWindow
(display, screen_number
); IntPtr visual
= XDefaultVisual
(display, screen_number
); XSetWindowAttributes attributes
= new XSetWindowAttributes
{ background_pixel
= XBlackPixel
(display, screen_number
),
event_mask
= XEventMask
.KeyPressMask }; IntPtr main_window
= XCreateWindow
(display, root_window,
0,
0,
650,
330,
0, depths,
1, visual, CWAttributes
.CWBackPixel | CWAttributes
.CWEventMask,
ref attributes
); if (main_window
== IntPtr
.Zero) { return EXIT_FAILURE
; } else { Console
.WriteLine("Window created - SUCCESS"); } XStoreName
(display, main_window,
"SFML in X11 - Mono 6.12.x"); IntPtr view1
= XCreateWindow
(display, main_window,
10,
10,
310,
310,
0, depths,
1, visual,
0, IntPtr
.Zero); IntPtr view2
= XCreateWindow
(display, main_window,
330,
10,
310,
310,
0, depths,
1, visual,
0, IntPtr
.Zero); XMapWindow
(display, main_window
); XFlush
(display
); RenderWindow forView1
= new RenderWindow
(view1
); RenderWindow forView2
= new RenderWindow
(view2
); forView1
.SetActive(); forView1
.Clear(Color
.Red); forView2
.SetActive(); forView2
.Clear(new Color
(255,
102,
0,
255)); bool running
= true; while (running
) { while (XPending
(display
)) { XNextEvent
(display,
out XEvent evt
); switch (evt
.type) { case XEventType
.KeyPress: running
= false; break; } } CircleShape circle
= new CircleShape
{ FillColor
= Color
.Yellow,
Radius
= 50f,
Position
= new SFML
.System.Vector2f(105,
105) }; forView1
.Draw(circle
); RectangleShape rectangle
= new RectangleShape
{ FillColor
= new Color
(33,
33,
33),
Size
= new SFML
.System.Vector2f(100,
100),
Position
= new SFML
.System.Vector2f(105,
105) }; forView2
.Draw(rectangle
); forView1
.Display(); forView2
.Display(); } XCloseDisplay
(display
); return EXIT_SUCCESS
; } }}
Screenshot:
(https://i.imgur.com/shcfc8g.png)
Enjoy your coding with Mono/Dotnet
Because I try for porting from C++ to C# -
It works fine under GtkSharp 2 / 3 too yay. If I use Events = Gdk.EventMask.AllEventMasks than it will crash. So sad with Gdk.Event :(
using System;using System.Runtime.InteropServices;using SFML.Graphics;using SFML.Window;namespace GtkSharp2SFML
{ public class RenderWidget
: Gtk
.DrawingArea { private const string libgdk_x11
= "libgdk-x11-2.0.so.0"; [DllImport
(libgdk_x11
)] private extern static IntPtr gdk_x11_drawable_get_xid
(IntPtr gdk_window
); private IntPtr GraphicsHandle
{ get { return gdk_x11_drawable_get_xid
(GdkWindow
.Handle); } } public RenderWindow RenderWindow
{ get; private set; } public RenderWidget
() { AppPaintable
= true; DoubleBuffered
= false; CanFocus
= true; // Events = Gdk.EventMask.ButtonPressMask | Gdk.EventMask.ButtonReleaseMask | Gdk.EventMask.KeyPressMask | Gdk.EventMask.KeyReleaseMask; } protected override bool OnExposeEvent
(Gdk
.EventExpose evnt
) { bool ok
= base.OnExposeEvent(evnt
); ContextSettings settings
= new ContextSettings
{ DepthBits
= 24 }; RenderWindow
= new RenderWindow
(GraphicsHandle, settings
); RenderWindow
.DispatchEvents(); RenderWindow
.SetFramerateLimit(60); RenderWindow
.DefaultView.Viewport = new FloatRect
(evnt
.Area.X, evnt
.Area.Y, evnt
.Area.Width, evnt
.Area.Height); Realize
(); OnRender
(); evnt
.Window.Display.Sync(); RenderWindow
.Display(); QueueDraw
(); return ok
; } public event EventHandler Rendered
; protected virtual void OnRender
() { if (Rendered
!= null) Rendered
(this, EventArgs
.Empty); } protected override void OnDestroyed
() { RenderWindow
.Close(); base.OnDestroyed(); } }}
And I try to communicate with Gtk.Button - It works fine!!! Without SFML-Events. I can't expect that SDL2 is really loser and SFML is winner. Congratulations!! I am happy because I have tried since GtkSharp 2 / 3 with SDL2 = Crashed if you add Button. It stopped to run :( So sad. I try to communicate with any controls like you use C# example Windows.Forms, MonoMac or XlibSharp
using System;using System.Runtime.InteropServices;using SFML.Graphics;using SFML.System;using SFML.Window;namespace GtkSharp2SFML
{ class MainClass
{ static RenderWidget render_widget
; // static byte bvalue = 0x00; private static bool color_changed
= true; [STAThread
] static void Main
(string[] args
) { Gtk
.Application.Init(); Gtk
.Window main_window
= new Gtk
.Window(Gtk
.WindowType.Toplevel) { Title
= "SFML in GtkSharp 2",
WindowPosition
= Gtk
.WindowPosition.Center }; main_window
.SetSizeRequest(400,
300); Gtk
.VBox main_area
= new Gtk
.VBox(false,
0); main_window
.Add(main_area
); render_widget
= new RenderWidget
(); main_area
.PackStart(render_widget,
true,
true,
0); color_changed
= false; render_widget
.Rendered += OnRender
; Gtk
.Button changecolor
= new Gtk
.Button { Label
= "Change Color",
}; main_area
.PackStart(changecolor,
false,
false,
0); changecolor
.Clicked += OnChangeColor
; main_window
.Destroyed += delegate { Gtk
.Application.Quit(); }; main_window
.ShowAll(); Gtk
.Application.Run(); } private static void OnChangeColor
(object sender, EventArgs e
) { color_changed
= true; if (color_changed
) { render_widget
.RenderWindow.DispatchEvents(); render_widget
.RenderWindow.Clear(Color
.Blue); render_widget
.RenderWindow.Display(); } } private static void OnRender
(object sender, EventArgs e
) { if (!color_changed
) { render_widget
.RenderWindow.Clear(Color
.Red); color_changed
= false; } } }} Result:
It runs app
(https://i.imgur.com/9fVyMZj.png)
And I clicked button to blue color.
(https://i.imgur.com/G5HioYg.png)
Enjoy and happy coding with GtkSharp 2 and 3 = OK. Please remember and do not use EventMask in code.because EventMask can stop to run Gtk applications.
PS: You know I have found old thread of GraphicsWidget - But it seems like it doesn't work because it has forgotten:
AppPaintable and CanFocus and resizing viewport of SFML.
My own RenderWidget is better than GraphicsWidget.
Resizing = YES
Communicating = for Buttons/Menus = YES, for Text = NOT TESTED, Image into SFML Teexture, NOT TESTED and any...
Closing = YES , It works fine
GraphicsWidget from old thread since I found here.:
Resizing = FAILED NO - HAHAHA
Communicating = DON'T KNOW ???
Closing = FAILED NO - HAHAHA
// EDIT
Great news with Events = Gdk.EventMask.AllEventMasks - no crash because EventMask works fine under ExposeEvent.
It looks like my code and it fixes and it doesn't crash. But I am not sure if it works.
protected override bool OnExposeEvent
(Gdk
.EventExpose evnt
) { bool ok
= base.OnExposeEvent(evnt
); ContextSettings settings
= new ContextSettings
{ DepthBits
= 24,
StencilBits
= 8 }; RenderWindow
= new RenderWindow
(GraphicsHandle, settings
); RenderWindow
.SetVerticalSyncEnabled(true); RenderWindow
.SetFramerateLimit(60); RenderWindow
.DefaultView.Viewport = new FloatRect
(evnt
.Area.X, evnt
.Area.Y, evnt
.Area.Width, evnt
.Area.Height); OnRender
(); evnt
.Window.Display.Sync(); while (ok
&& RenderWindow
.IsOpen) { RenderWindow
.DispatchEvents(); Events
= Gdk
.EventMask.AllEventsMask; } RenderWindow
.Display(); QueueDraw
(); return ok
; }
But it shows like common failure lines under library - I think SFML libraries have thrown failures.
Failed to create input context for window -- TextEntered event won't be able to return unicode
It looks like for my Gtk Application runs fine and doesn't crash. Yay! It works fine. - I know I have found old threads I have readden about "Failure to create input..." That is reason because it calls "code-failure", right or I understand wrongly? Sorry my bad English.
// Update
ColorButton can communicate to SFML's Clear(color) Woohoooo! ColorButton changes color of SFML's Clear() = OK 100 %
(https://i.imgur.com/HKtAUkP.png)
It is easy simple trick
Remember that Gdk.Color's bit is ushort and I calculate to byte
65535 / 257 = 255 -> byte maxvalue in SFML.Color's bit.
// EDIT 2:
Found bug GtkSharp 2 can't show when you maximize Gtk Window and RenderWindow can't change color. That is why I need move to GtkSharp 3.x = OK - Since I tested with Gtk.GLArea()
Sorry for disturbances of edits....