Skip to content

Instantly share code, notes, and snippets.

@kekekeks
Created November 29, 2016 09:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kekekeks/a25a4f503f9504d5b137446180607ed1 to your computer and use it in GitHub Desktop.
Save kekekeks/a25a4f503f9504d5b137446180607ed1 to your computer and use it in GitHub Desktop.
XPutImage example for GTK#
public static class X11
{
[DllImport ("libX11.so.6")]
static extern IntPtr XOpenDisplay(IntPtr display);
static IntPtr Disp;
[DllImport ("libX11.so.6")]
static extern int XGetGeometry(IntPtr disp, IntPtr hwnd, out IntPtr root, out int x, out int y,
out int width, out int height, out int border, out int depth);
[DllImport ("libX11.so.6")]
static extern IntPtr XInitImage(ref XImage image);
[StructLayout(LayoutKind.Sequential)]
unsafe struct XImage
{
public int width, height;
public int xoffset;
public int format;
public IntPtr data;
public int byte_order;
public int bitmap_unit;
public int bitmap_bit_order;
public int bitmap_pad;
public int depth;
public int bytes_per_line;
public int bits_per_pixel;
public ulong red_mask;
public ulong green_mask;
public ulong blue_mask;
fixed byte fill [128];
}
[DllImport ("libX11.so.6")]
static extern int XPutImage(IntPtr display, IntPtr drawable, IntPtr gc, ref XImage img,
int srcx, int srcy, int destx, int desty, int width, int height);
[DllImport ("libX11.so.6")]
static extern IntPtr XCreateGC(IntPtr display, IntPtr drawable, ulong unused, IntPtr unused2);
[DllImport ("libX11.so.6")]
static extern int XFreeGC(IntPtr display, IntPtr gc);
static void ConvertImage(ref XImage image, IntPtr data, int width, int height, int rowBytes, int bytesPerPixel)
{
int bitsPerPixel = bytesPerPixel * 8;
image.width = width;
image.height = height;
image.format = 2;
image.data = data;
image.byte_order = 0;
image.bitmap_unit = bitsPerPixel;
image.bitmap_bit_order = 0;
image.bitmap_pad = bitsPerPixel;
image.depth = 24;
image.bytes_per_line = rowBytes;// - width * bytesPerPixel;
image.bits_per_pixel = bitsPerPixel;
XInitImage(ref image);
}
static X11()
{
Disp = XOpenDisplay(IntPtr.Zero);
}
public static void GetPlatformWindowSize(IntPtr hwnd, out int w, out int h)
{
int border, x, y, depth;
IntPtr root;
XGetGeometry(Disp, hwnd, out root, out x, out y, out w, out h, out border, out depth);
}
public static void Draw(IntPtr hwnd, IntPtr data, int width, int height, int rowBytes, int bytesPerPixel)
{
XImage img = new XImage();
ConvertImage(ref img, data, width, height, rowBytes, bytesPerPixel);
IntPtr gc = XCreateGC(Disp, hwnd, 0, IntPtr.Zero);
XPutImage(Disp, hwnd, gc, ref img, 0, 0, 0, 0, width, height);
XFreeGC(Disp, gc);
}
}
public partial class MainWindow: Gtk.Window
{
public MainWindow()
: base(Gtk.WindowType.Toplevel)
{
Build();
DoubleBuffered = false;
}
[DllImport("libgtk-x11-2.0.so.0", CallingConvention = CallingConvention.Cdecl)]
extern static IntPtr gdk_x11_drawable_get_xid(IntPtr gdkWindow);
protected override bool OnExposeEvent(Gdk.EventExpose evnt)
{
int w, h;
IntPtr hwnd = gdk_x11_drawable_get_xid(GdkWindow.Handle);
HelloGtk.X11.GetPlatformWindowSize(hwnd, out w, out h);
using(var bmp = new Bitmap(w, h))
using(var g = Graphics.FromImage(bmp))
using(var b = new LinearGradientBrush(new Point(0,0), new Point(w, h), Color.Aqua, Color.GreenYellow))
{
g.FillRectangle(b, new Rectangle(0, 0, w, h));
var data = bmp.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
HelloGtk.X11.Draw(hwnd, data.Scan0, data.Width, data.Height, data.Stride, 4);
bmp.UnlockBits(data);
}
//X11.GetPlatformWindowSize()
return true;
}
protected void OnDeleteEvent(object sender, DeleteEventArgs a)
{
Application.Quit();
a.RetVal = true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment