diff --git a/Remotely_Agent/Services/DeviceSocket.cs b/Remotely_Agent/Services/DeviceSocket.cs index b01050f6..f88f5bc9 100644 --- a/Remotely_Agent/Services/DeviceSocket.cs +++ b/Remotely_Agent/Services/DeviceSocket.cs @@ -319,7 +319,7 @@ namespace Remotely_Agent.Services var users = OSUtils.StartProcessWithResults("users", ""); var username = users?.Split()?.FirstOrDefault()?.Trim(); - var casterProc = Process.Start("sudo", $"-u {username} {rcBinaryPath} -mode Unattended -requester {requesterID} -serviceid {serviceID} -hostname {Utilities.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)} & disown"); + var casterProc = Process.Start("sudo", $"-u {username} {rcBinaryPath} -mode Unattended -requester {requesterID} -serviceid {serviceID} -host {Utilities.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)} & disown"); casterProc.WaitForExit(); } } diff --git a/Remotely_Agent/Services/Logger.cs b/Remotely_Agent/Services/Logger.cs index 68927b62..5491ae49 100644 --- a/Remotely_Agent/Services/Logger.cs +++ b/Remotely_Agent/Services/Logger.cs @@ -12,56 +12,27 @@ namespace Remotely_Agent.Services { public static class Logger { + public static object WriteLock { get; } = new object(); public static void Write(string message) { - try + lock (WriteLock) { - var path = Path.Combine(Path.GetTempPath(), "Remotely_Logs.txt"); - if (!File.Exists(path)) + try { - File.Create(path).Close(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + var path = Path.Combine(Path.GetTempPath(), "Remotely_Logs.txt"); + if (!File.Exists(path)) { - Process.Start("sudo", $"chmod 666 {path}").WaitForExit(); + File.Create(path).Close(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Process.Start("sudo", $"chmod 666 {path}").WaitForExit(); + } } - } - var jsoninfo = new - { - Type = "Info", - Timestamp = DateTime.Now.ToString(), - Message = message - }; - if (File.Exists(path)) - { - var fi = new FileInfo(path); - while (fi.Length > 1000000) + var jsoninfo = new { - var content = File.ReadAllLines(path); - File.WriteAllLines(path, content.Skip(10)); - fi = new FileInfo(path); - } - } - File.AppendAllText(path, JsonConvert.SerializeObject(jsoninfo) + Environment.NewLine); - } - catch { } - } - - public static void Write(Exception ex) - { - try - { - var exception = ex; - var path = Path.Combine(Path.GetTempPath(), "Remotely_Logs.txt"); - - while (exception != null) - { - var jsonError = new - { - Type = "Error", + Type = "Info", Timestamp = DateTime.Now.ToString(), - Message = exception?.Message, - Source = exception?.Source, - StackTrace = exception?.StackTrace, + Message = message }; if (File.Exists(path)) { @@ -73,11 +44,47 @@ namespace Remotely_Agent.Services fi = new FileInfo(path); } } - File.AppendAllText(path, JsonConvert.SerializeObject(jsonError) + Environment.NewLine); - exception = exception.InnerException; + File.AppendAllText(path, JsonConvert.SerializeObject(jsoninfo) + Environment.NewLine); } + catch { } + } + } + + public static void Write(Exception ex) + { + lock (WriteLock) + { + try + { + var exception = ex; + var path = Path.Combine(Path.GetTempPath(), "Remotely_Logs.txt"); + + while (exception != null) + { + var jsonError = new + { + Type = "Error", + Timestamp = DateTime.Now.ToString(), + Message = exception?.Message, + Source = exception?.Source, + StackTrace = exception?.StackTrace, + }; + if (File.Exists(path)) + { + var fi = new FileInfo(path); + while (fi.Length > 1000000) + { + var content = File.ReadAllLines(path); + File.WriteAllLines(path, content.Skip(10)); + fi = new FileInfo(path); + } + } + File.AppendAllText(path, JsonConvert.SerializeObject(jsonError) + Environment.NewLine); + exception = exception.InnerException; + } + } + catch { } } - catch { } } } } diff --git a/Remotely_ScreenCast.Core/Utilities/Logger.cs b/Remotely_ScreenCast.Core/Utilities/Logger.cs index a2863d85..a8e5a217 100644 --- a/Remotely_ScreenCast.Core/Utilities/Logger.cs +++ b/Remotely_ScreenCast.Core/Utilities/Logger.cs @@ -12,75 +12,27 @@ namespace Remotely_ScreenCast.Core.Utilities { public static class Logger { + public static object WriteLock { get; } = new object(); public static void Write(string message) { try { - var path = Path.Combine(Path.GetTempPath(), "Remotely_Logs.txt"); - if (!File.Exists(path)) + lock (WriteLock) { - File.Create(path).Close(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + var path = Path.Combine(Path.GetTempPath(), "Remotely_Logs.txt"); + if (!File.Exists(path)) { - Process.Start("sudo", $"chmod 666 {path}").WaitForExit(); + File.Create(path).Close(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Process.Start("sudo", $"chmod 666 {path}").WaitForExit(); + } } - } - var jsoninfo = new - { - Type = "Info", - Timestamp = DateTime.Now.ToString(), - Message = message - }; - if (File.Exists(path)) - { - var fi = new FileInfo(path); - while (fi.Length > 1000000) + var jsoninfo = new { - var content = File.ReadAllLines(path); - File.WriteAllLines(path, content.Skip(10)); - fi = new FileInfo(path); - } - } - try - { - File.AppendAllText(path, JsonConvert.SerializeObject(jsoninfo) + Environment.NewLine); - } - catch - { - Task.Delay(1000).ContinueWith((Task task) => - { - Write(message); - }); - } - } - catch { } - } - - public static void Write(Exception ex) - { - try - { - var exception = ex; - var path = Path.Combine(Path.GetTempPath(), "Remotely_Logs.txt"); - - if (!File.Exists(path)) - { - File.Create(path).Close(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - Process.Start("sudo", $"chmod 666 {path}").WaitForExit(); - } - } - - while (exception != null) - { - var jsonError = new - { - Type = "Error", + Type = "Info", Timestamp = DateTime.Now.ToString(), - Message = exception?.Message, - Source = exception?.Source, - StackTrace = exception?.StackTrace, + Message = message }; if (File.Exists(path)) { @@ -92,11 +44,56 @@ namespace Remotely_ScreenCast.Core.Utilities fi = new FileInfo(path); } } - File.AppendAllText(path, JsonConvert.SerializeObject(jsonError) + Environment.NewLine); - exception = exception.InnerException; + File.AppendAllText(path, JsonConvert.SerializeObject(jsoninfo) + Environment.NewLine); } } catch { } } + + public static void Write(Exception ex) + { + lock (WriteLock) + { + try + { + var exception = ex; + var path = Path.Combine(Path.GetTempPath(), "Remotely_Logs.txt"); + + if (!File.Exists(path)) + { + File.Create(path).Close(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Process.Start("sudo", $"chmod 666 {path}").WaitForExit(); + } + } + + while (exception != null) + { + var jsonError = new + { + Type = "Error", + Timestamp = DateTime.Now.ToString(), + Message = exception?.Message, + Source = exception?.Source, + StackTrace = exception?.StackTrace, + }; + if (File.Exists(path)) + { + var fi = new FileInfo(path); + while (fi.Length > 1000000) + { + var content = File.ReadAllLines(path); + File.WriteAllLines(path, content.Skip(10)); + fi = new FileInfo(path); + } + } + File.AppendAllText(path, JsonConvert.SerializeObject(jsonError) + Environment.NewLine); + exception = exception.InnerException; + } + } + catch { } + } + } } } diff --git a/Remotely_ScreenCast.Linux/Capture/X11Capture.cs b/Remotely_ScreenCast.Linux/Capture/X11Capture.cs index 7325138b..5226fee9 100644 --- a/Remotely_ScreenCast.Linux/Capture/X11Capture.cs +++ b/Remotely_ScreenCast.Linux/Capture/X11Capture.cs @@ -24,16 +24,12 @@ namespace Remotely_ScreenCast.Linux.Capture public EventHandler ScreenChanged { get; set; } public int SelectedScreen { get; private set; } = -1; private Graphics Graphic { get; set; } - private object ScreenLock { get; } = new object(); public void Capture() { try { - lock (ScreenLock) - { - PreviousFrame = (Bitmap)CurrentFrame.Clone(); - Graphic.CopyFromScreen(CurrentScreenBounds.Left, CurrentScreenBounds.Top, 0, 0, new Size(CurrentScreenBounds.Width, CurrentScreenBounds.Height)); - } + PreviousFrame = (Bitmap)CurrentFrame.Clone(); + Graphic.CopyFromScreen(CurrentScreenBounds.Left, CurrentScreenBounds.Top, 0, 0, new Size(CurrentScreenBounds.Width, CurrentScreenBounds.Height)); } catch (Exception ex) { @@ -51,7 +47,7 @@ namespace Remotely_ScreenCast.Linux.Capture public int GetScreenCount() { - return Xlib.XScreenCount(Display); + return LibX11.XScreenCount(Display); } public double GetVirtualScreenHeight() @@ -59,7 +55,7 @@ namespace Remotely_ScreenCast.Linux.Capture double height = 0; for (var i = 0; i < GetScreenCount(); i++) { - height += Xlib.XHeightOfScreen(Xlib.XScreenOfDisplay(Display, i)); + height += LibX11.XHeightOfScreen(LibX11.XScreenOfDisplay(Display, i)); } return height; } @@ -69,19 +65,26 @@ namespace Remotely_ScreenCast.Linux.Capture double width = 0; for (var i = 0; i < GetScreenCount(); i++) { - width += Xlib.XWidthOfScreen(Xlib.XScreenOfDisplay(Display, i)); + width += LibX11.XWidthOfScreen(LibX11.XScreenOfDisplay(Display, i)); } return width; } public void Init() { - Display = Xlib.XOpenDisplay(null); - var defaultScreen = Xlib.XDefaultScreen(Display); - SetSelectedScreen(defaultScreen); - CurrentFrame = new Bitmap(CurrentScreenBounds.Width, CurrentScreenBounds.Height, PixelFormat.Format32bppArgb); - PreviousFrame = new Bitmap(CurrentScreenBounds.Width, CurrentScreenBounds.Height, PixelFormat.Format32bppArgb); - Graphic = Graphics.FromImage(CurrentFrame); + try + { + Display = LibX11.XOpenDisplay(null); + var defaultScreen = LibX11.XDefaultScreen(Display); + SetSelectedScreen(defaultScreen); + CurrentFrame = new Bitmap(CurrentScreenBounds.Width, CurrentScreenBounds.Height, PixelFormat.Format32bppArgb); + PreviousFrame = new Bitmap(CurrentScreenBounds.Width, CurrentScreenBounds.Height, PixelFormat.Format32bppArgb); + Graphic = Graphics.FromImage(CurrentFrame); + } + catch (Exception ex) + { + Logger.Write(ex); + } } public void SetSelectedScreen(int screenNumber) @@ -90,7 +93,7 @@ namespace Remotely_ScreenCast.Linux.Capture { return; } - lock (ScreenLock) + try { if (GetScreenCount() >= screenNumber + 1) { @@ -100,12 +103,17 @@ namespace Remotely_ScreenCast.Linux.Capture { SelectedScreen = 0; } - var width = Xlib.XDisplayWidth(Display, SelectedScreen); - var height = Xlib.XDisplayHeight(Display, SelectedScreen); + var width = LibX11.XDisplayWidth(Display, SelectedScreen); + var height = LibX11.XDisplayHeight(Display, SelectedScreen); CurrentScreenBounds = new Rectangle(0, 0, width, height); CaptureFullscreen = true; Init(); ScreenChanged?.Invoke(this, CurrentScreenBounds); + + } + catch (Exception ex) + { + Logger.Write(ex); } } } diff --git a/Remotely_ScreenCast.Linux/Input/X11Input.cs b/Remotely_ScreenCast.Linux/Input/X11Input.cs index 86fe067d..8e19da8a 100644 --- a/Remotely_ScreenCast.Linux/Input/X11Input.cs +++ b/Remotely_ScreenCast.Linux/Input/X11Input.cs @@ -1,34 +1,117 @@ using Remotely_ScreenCast.Core.Input; +using Remotely_ScreenCast.Core.Utilities; +using Remotely_ScreenCast.Linux.X11Interop; +using Remotely_ScreenCast.Core; using System; using System.Collections.Generic; using System.Text; +using System.Linq; +using Remotely_ScreenCast.Linux.Capture; namespace Remotely_ScreenCast.Linux.Input { public class X11Input : IKeyboardMouseInput { + public void SendKeyDown(string key) { - + try + { + var display = LibX11.XOpenDisplay(null); + var keySim = LibX11.XStringToKeysym(key); + if (keySim == null) + { + Logger.Write($"Key not mapped: {key}"); + return; + } + + var keyCode = LibX11.XKeysymToKeycode(display, keySim); + LibX11.XTestFakeKeyEvent(display, keyCode, true, 1); + LibX11.XSync(display, false); + //LibX11.XCloseDisplay(display); + } + catch (Exception ex) + { + Logger.Write(ex); + } } public void SendKeyUp(string key) { - + try + { + var display = LibX11.XOpenDisplay(null); + var keySim = LibX11.XStringToKeysym(key); + if (keySim == null) + { + Logger.Write($"Key not mapped: {key}"); + return; + } + + var keyCode = LibX11.XKeysymToKeycode(display, keySim); + LibX11.XTestFakeKeyEvent(display, keyCode, false, 1); + LibX11.XSync(display, false); + //LibX11.XCloseDisplay(display); + } + catch (Exception ex) + { + Logger.Write(ex); + } + } public uint SendLeftMouseDown(double percentX, double percentY) { - return 0; + try + { + var display = LibX11.XOpenDisplay(null); + SendMouseMove(percentX, percentY); + LibX11.XTestFakeButtonEvent(display, 1, true, 1); + LibX11.XSync(display, false); + //LibX11.XCloseDisplay(display); + return 0; + } + catch (Exception ex) + { + Logger.Write(ex); + return 1; + } } public uint SendLeftMouseUp(double percentX, double percentY) { - return 0; + try + { + var display = LibX11.XOpenDisplay(null); + SendMouseMove(percentX, percentY); + LibX11.XTestFakeButtonEvent(display, 1, false, 1); + LibX11.XSync(display, false); + //LibX11.XCloseDisplay(display); + return 0; + } + catch (Exception ex) + { + Logger.Write(ex); + return 1; + } } public uint SendMouseMove(double percentX, double percentY) { + try + { + var display = LibX11.XOpenDisplay(null); + var capturer = new X11Capture(); + var width = capturer.GetVirtualScreenWidth(); + var height = capturer.GetVirtualScreenHeight(); + LibX11.XTestFakeMotionEvent(display, 0, (int)(width * percentX), (int)(height * percentY), 1); + LibX11.XSync(display, false); + //LibX11.XCloseDisplay(display); + } + catch (Exception ex) + { + Logger.Write(ex); + } return 0; } @@ -39,12 +122,38 @@ namespace Remotely_ScreenCast.Linux.Input public uint SendRightMouseDown(double percentX, double percentY) { - return 0; + try + { + var display = LibX11.XOpenDisplay(null); + SendMouseMove(percentX, percentY); + LibX11.XTestFakeButtonEvent(display, 3, true, 1); + LibX11.XSync(display, false); + //LibX11.XCloseDisplay(display); + return 0; + } + catch (Exception ex) + { + Logger.Write(ex); + return 1; + } } public uint SendRightMouseUp(double percentX, double percentY) { - return 0; + try + { + var display = LibX11.XOpenDisplay(null); + SendMouseMove(percentX, percentY); + LibX11.XTestFakeButtonEvent(display, 3, false, 1); + LibX11.XSync(display, false); + //LibX11.XCloseDisplay(display); + return 0; + } + catch (Exception ex) + { + Logger.Write(ex); + return 1; + } } } } diff --git a/Remotely_ScreenCast.Linux/Program.cs b/Remotely_ScreenCast.Linux/Program.cs index d2549ab0..c4ed6329 100644 --- a/Remotely_ScreenCast.Linux/Program.cs +++ b/Remotely_ScreenCast.Linux/Program.cs @@ -6,6 +6,7 @@ using Remotely_ScreenCast.Linux.Input; using Remotely_ScreenCast.Linux.X11Interop; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Threading.Tasks; namespace Remotely_ScreenCast.Linux @@ -14,7 +15,6 @@ namespace Remotely_ScreenCast.Linux { public static Conductor Conductor { get; private set; } //public static CursorIconWatcher CursorIconWatcher { get; private set; } - public static void Main(string[] args) { try @@ -32,7 +32,7 @@ namespace Remotely_ScreenCast.Linux Conductor.StartWaitForViewerTimer(); while (true) { - System.Threading.Thread.Sleep(100); + System.Threading.Thread.Sleep(1000); } } catch (Exception ex) @@ -44,10 +44,9 @@ namespace Remotely_ScreenCast.Linux private static void ScreenCastInitiated(object sender, Tuple viewerAndRequester) { - ICapturer capturer; try { - capturer = new X11Capture(); + var capturer = new X11Capture(); //await Conductor.OutgoingMessages.SendCursorChange(CursorIconWatcher.GetCurrentCursor(), new List() { viewerAndRequester.Item1 }); ScreenCaster.BeginScreenCasting(viewerAndRequester.Item1, viewerAndRequester.Item2, capturer, Conductor); } diff --git a/Remotely_ScreenCast.Linux/X11Interop/LibX11.cs b/Remotely_ScreenCast.Linux/X11Interop/LibX11.cs new file mode 100644 index 00000000..cd53fb95 --- /dev/null +++ b/Remotely_ScreenCast.Linux/X11Interop/LibX11.cs @@ -0,0 +1,327 @@ +/* + +Copyright 1985, 1986, 1987, 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.Permissions; +using System.Text; + +namespace Remotely_ScreenCast.Linux.X11Interop +{ + public static unsafe class LibX11 + { + + #region Structs + + //public struct XAnyEvent + //{ + // public int type; + // public ulong serial; /* # of last request processed by server */ + // public bool send_event; /* true if this came from a SendEvent request */ + // public IntPtr display; /* Display the event was read from */ + // public IntPtr window; + //}; + + //public struct XButtonEvent + //{ + // public int type; /* ButtonPress or ButtonRelease */ + // public ulong serial; /* # of last request processed by server */ + // public bool send_event; /* true if this came from a SendEvent request */ + // public IntPtr display; /* Display the event was read from */ + // public IntPtr window; /* “event” window it is reported relative to */ + // public IntPtr root; /* root window that the event occurred on */ + // public IntPtr subwindow; /* child window */ + // public int time; /* milliseconds */ + // public int x; + // public int y; /* pointer x, y coordinates in event window */ + // public int x_root; + // public int y_root; /* coordinates relative to root */ + // public uint state; /* key or button mask */ + // public uint button; /* detail */ + // public bool same_screen; /* same screen flag */ + //} + //public struct XKeyEvent + //{ + // public int type; /* KeyPress or KeyRelease */ + // public ulong serial; /* # of last request processed by server */ + // public bool send_event; /* true if this came from a SendEvent request */ + // public IntPtr display; /* Display the event was read from */ + // public IntPtr window; /* “event” window it is reported relative to */ + // public IntPtr root; /* root window that the event occurred on */ + // public IntPtr subwindow; /* child window */ + // public int time; /* milliseconds */ + // public int x; + // public int y; /* pointer x, y coordinates in event window */ + // public int x_root; + // public int y_root; /* coordinates relative to root */ + // public uint state; /* key or button mask */ + // public uint keycode; /* detail */ + // public bool same_screen; /* same screen flag */ + //} + //public struct XMotionEvent + //{ + // public int type; /* MotionNotify */ + // public ulong serial; /* # of last request processed by server */ + // public bool send_event; /* true if this came from a SendEvent request */ + // public IntPtr display; /* Display the event was read from */ + // public IntPtr window; /* “event” window reported relative to */ + // public IntPtr root; /* root window that the event occurred on */ + // public IntPtr subwindow; /* child window */ + // public int time; /* milliseconds */ + // public int x; + // public int y; /* pointer x, y coordinates in event window */ + // public int x_root; + // public int y_root; /* coordinates relative to root */ + // public uint state; /* key or button mask */ + // public char is_hint; /* detail */ + // public bool same_screen; /* same screen flag */ + //} + + //[StructLayout(LayoutKind.Explicit)] + //public struct XEvent + //{ + // [FieldOffset(0)] + // public int type; /* KeyPress or KeyRelease */ + // [FieldOffset(1)] + // public ulong serial; /* # of last request processed by server */ + // [FieldOffset(2)] + // public bool send_event; /* true if this came from a SendEvent request */ + // [FieldOffset(3)] + // public IntPtr display; /* Display the event was read from */ + // [FieldOffset(4)] + // public IntPtr window; /* “event” window it is reported relative to */ + // [FieldOffset(5)] + // public IntPtr root; /* root window that the event occurred on */ + // [FieldOffset(6)] + // public IntPtr subwindow; /* child window */ + // [FieldOffset(7)] + // public int time; /* milliseconds */ + // [FieldOffset(8)] + // public int x; + // [FieldOffset(9)] + // public int y; /* pointer x, y coordinates in event window */ + // [FieldOffset(10)] + // public int x_root; + // [FieldOffset(11)] + // public int y_root; /* coordinates relative to root */ + // [FieldOffset(12)] + // public uint state; /* key or button mask */ + // [FieldOffset(13)] + // public uint keycode; /* detail */ + // [FieldOffset(13)] + // public char is_hint; + // [FieldOffset(13)] + // public uint button; + // [FieldOffset(14)] + // public bool same_screen; /* same screen flag */ + //} + //public struct XImage + //{ + // public int width; + // public int height; /* size of image */ + // public int xoffset; /* number of pixels offset in X direction */ + // public int format; /* XYBitmap, XYPixmap, ZPixmap */ + // public char* data; /* pointer to image data */ + // public int byte_order; /* data byte order, LSBFirst, MSBFirst */ + // public int bitmap_unit; /* quant. of scanline 8, 16, 32 */ + // public int bitmap_bit_order; /* LSBFirst, MSBFirst */ + // public int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */ + // public int depth; /* depth of image */ + // public int bytes_per_line; /* accelerator to next scanline */ + // public int bits_per_pixel; /* bits per pixel (ZPixmap) */ + // public ulong red_mask; /* bits in z arrangement */ + // public ulong green_mask; + // public ulong blue_mask; + // public IntPtr obdata; /* hook for the object routines to hang on */ + + // public XImage create_image() + // { + // return new XImage(); + // } + + // public int destroy_image() + // { + // return 0; + // } + + // public ulong get_pixel() + // { + // return 0; + // } + // public XImage sub_image() + // { + // return new XImage(); + // } + + // public int add_pixel() + // { + // return 0; + // } + //} + //public struct Screen + //{ + + // public IntPtr ext_data; /* hook for extension to hang data */ + // public IntPtr* display;/* back pointer to display structure */ // TODO: XDisplay struct? + // public IntPtr root; /* Root window id. */ + // public int width; + // public int height; /* width and height of screen */ + // public int mwidth; + // public int mheight; /* width and height of in millimeters */ + // public int ndepths; /* number of depths possible */ + // public uint depths; /* list of allowable depths on the screen */ //TODO: Depth[] + // public int root_depth; /* bits per pixel */ + // public IntPtr root_visual; /* root visual */ + // public IntPtr default_gc; /* GC for the root root visual */ + // public IntPtr cmap; /* default color map */ // TODO: Colormap struct? + // public ulong white_pixel; + // public ulong black_pixel; /* White and Black pixel values */ + // public int max_maps, min_maps; /* max and min color maps */ + // public int backing_store; /* Never, WhenMapped, Always */ + // public bool save_unders; + // public long root_input_mask; /* initial root input mask */ + //} + //public struct Depth + //{ + + // public int depth; /* this depth (Z) of the depth */ + // public int nvisuals; /* number of Visual types at this depth */ + // public Visual[] visuals; /* list of visuals possible at this depth */ + //} + //public struct Visual + //{ + + // public IntPtr ext_data; /* hook for extension to hang data */ + // public int visualid; /* visual id of this visual */ + // public ulong red_mask, green_mask, blue_mask; /* mask values */ + // public int bits_per_rgb; /* log base 2 of distinct color values */ + // public int map_entries; /* color map entries */ + //} + + //public class XExtData + //{ + // public int number; /* number returned by XRegisterExtension */ + // public XExtData next; /* next item on list of data for structure */ + // public IntPtr private_data; /* data private to this extension. */ + //} + #endregion Structs + #region Enums + //public enum EventMasks + //{ + // NoEventMask, + // KeyPressMask, + // KeyReleaseMask, + // ButtonPressMask, + // ButtonReleaseMask, + // EnterWindowMask, + // LeaveWindowMask, + // PointerMotionMask, + // PointerMotionHintMask, + // Button1MotionMask, + // Button2MotionMask, + // Button3MotionMask, + // Button4MotionMask, + // Button5MotionMask, + // ButtonMotionMask, + // KeymapStateMask, + // ExposureMask, + // VisibilityChangeMask, + // StructureNotifyMask, + // ResizeRedirectMask, + // SubstructureNotifyMask, + // SubstructureRedirectMask, + // FocusChangeMask, + // PropertyChangeMask, + // ColormapChangeMask, + // OwnerGrabButtonMask + //} + //public enum RevertState + //{ + // RevertToParent, + // RevertToPointerRoot, + // RevertToNone + //} + #endregion Enums + #region Imports + [DllImport("libX11")] + public static extern IntPtr XGetImage(IntPtr display, IntPtr drawable, int x, int y, uint width, uint height, ulong plane_mask, int format); + [DllImport("libX11")] + public static extern int XScreenCount(IntPtr display); + [DllImport("libX11")] + public static extern int XDefaultScreen(IntPtr display); + [DllImport("libX11")] + public static extern IntPtr XOpenDisplay(string display_name); + [DllImport("libX11")] + public static extern void XCloseDisplay(IntPtr display); + [DllImport("libX11")] + public static extern IntPtr XRootWindow(IntPtr display, int screen_number); + + [DllImport("libX11")] + public static extern IntPtr XGetSubImage(IntPtr display, IntPtr drawable, int x, int y, uint width, uint height, ulong plane_mask, int format, IntPtr dest_image, int dest_x, int dest_y); + [DllImport("libX11")] + public static extern IntPtr XScreenOfDisplay(IntPtr display, int screen_number); + [DllImport("libX11")] + public static extern int XDisplayWidth(IntPtr display, int screen_number); + [DllImport("libX11")] + public static extern int XDisplayHeight(IntPtr display, int screen_number); + [DllImport("libX11")] + public static extern int XWidthOfScreen(IntPtr screen); + [DllImport("libX11")] + public static extern int XHeightOfScreen(IntPtr screen); + [DllImport("libX11")] + public static extern IntPtr XDefaultGC(IntPtr display, int screen_number); + [DllImport("libX11")] + public static extern IntPtr XDefaultRootWindow(IntPtr display); + [DllImport("libX11")] + public static extern uint XSendEvent(IntPtr display, IntPtr window, bool propagate, long event_mask, ref XEvent event_send); + [DllImport("libX11")] + public static extern void XGetInputFocus(IntPtr display, out IntPtr focus_return, out int revert_to_return); + [DllImport("libX11")] + public static extern IntPtr XStringToKeysym(string key); + [DllImport("libX11")] + public static extern uint XKeysymToKeycode(IntPtr display, IntPtr keysym); + + [DllImport("libX11")] + public static extern IntPtr XRootWindowOfScreen(IntPtr screen); + [DllImport("libX11")] + public static extern ulong XNextRequest(IntPtr display); + [DllImport("libX11")] + public static extern void XForceScreenSaver(IntPtr display, int mode); + [DllImport("libXtst")] + public static extern bool XTestQueryExtension(IntPtr display, out int event_base, out int error_base, out int major_version, out int minor_version); + [DllImport("libXtst")] + public static extern void XTestFakeKeyEvent(IntPtr display, uint keycode, bool is_press, ulong delay); + [DllImport("libXtst")] + public static extern void XTestFakeButtonEvent(IntPtr display, uint button, bool is_press, ulong delay); + [DllImport("libXtst")] + public static extern void XTestFakeMotionEvent(IntPtr display, int screen_number, int x, int y, ulong delay); + [DllImport("libXtst")] + public static extern void XSync(IntPtr display, bool discard); + #endregion Imports + } +} diff --git a/Remotely_ScreenCast.Linux/X11Interop/X11Structs.cs b/Remotely_ScreenCast.Linux/X11Interop/X11Structs.cs new file mode 100644 index 00000000..3c14f883 --- /dev/null +++ b/Remotely_ScreenCast.Linux/X11Interop/X11Structs.cs @@ -0,0 +1,1924 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software",, to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2004 Novell, Inc. +// +// Authors: +// Peter Bartok pbartok@novell.com +// + + +// NOT COMPLETE + +using System; +using System.ComponentModel; +using System.Collections; +using System.Drawing; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Timers; + +/// X11 Version +namespace Remotely_ScreenCast.Linux.X11Interop +{ + // + // In the structures below, fields of type long are mapped to IntPtr. + // This will work on all platforms where sizeof(long)==sizeof(void*), which + // is almost all platforms except WIN64. + // + + [StructLayout(LayoutKind.Sequential)] + public struct XAnyEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XKeyEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public IntPtr root; + public IntPtr subwindow; + public IntPtr time; + public int x; + public int y; + public int x_root; + public int y_root; + public int state; + public int keycode; + public bool same_screen; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XButtonEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public IntPtr root; + public IntPtr subwindow; + public IntPtr time; + public int x; + public int y; + public int x_root; + public int y_root; + public int state; + public int button; + public bool same_screen; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XMotionEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public IntPtr root; + public IntPtr subwindow; + public IntPtr time; + public int x; + public int y; + public int x_root; + public int y_root; + public int state; + public byte is_hint; + public bool same_screen; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XCrossingEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public IntPtr root; + public IntPtr subwindow; + public IntPtr time; + public int x; + public int y; + public int x_root; + public int y_root; + public NotifyMode mode; + public NotifyDetail detail; + public bool same_screen; + public bool focus; + public int state; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XFocusChangeEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public int mode; + public NotifyDetail detail; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XKeymapEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public byte key_vector0; + public byte key_vector1; + public byte key_vector2; + public byte key_vector3; + public byte key_vector4; + public byte key_vector5; + public byte key_vector6; + public byte key_vector7; + public byte key_vector8; + public byte key_vector9; + public byte key_vector10; + public byte key_vector11; + public byte key_vector12; + public byte key_vector13; + public byte key_vector14; + public byte key_vector15; + public byte key_vector16; + public byte key_vector17; + public byte key_vector18; + public byte key_vector19; + public byte key_vector20; + public byte key_vector21; + public byte key_vector22; + public byte key_vector23; + public byte key_vector24; + public byte key_vector25; + public byte key_vector26; + public byte key_vector27; + public byte key_vector28; + public byte key_vector29; + public byte key_vector30; + public byte key_vector31; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XExposeEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public int x; + public int y; + public int width; + public int height; + public int count; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XGraphicsExposeEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr drawable; + public int x; + public int y; + public int width; + public int height; + public int count; + public int major_code; + public int minor_code; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XNoExposeEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr drawable; + public int major_code; + public int minor_code; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XVisibilityEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public int state; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XCreateWindowEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr parent; + public IntPtr window; + public int x; + public int y; + public int width; + public int height; + public int border_width; + public bool override_redirect; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XDestroyWindowEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr xevent; + public IntPtr window; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XUnmapEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr xevent; + public IntPtr window; + public bool from_configure; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XMapEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr xevent; + public IntPtr window; + public bool override_redirect; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XMapRequestEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr parent; + public IntPtr window; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XReparentEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr xevent; + public IntPtr window; + public IntPtr parent; + public int x; + public int y; + public bool override_redirect; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XConfigureEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr xevent; + public IntPtr window; + public int x; + public int y; + public int width; + public int height; + public int border_width; + public IntPtr above; + public bool override_redirect; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XGravityEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr xevent; + public IntPtr window; + public int x; + public int y; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XResizeRequestEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public int width; + public int height; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XConfigureRequestEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr parent; + public IntPtr window; + public int x; + public int y; + public int width; + public int height; + public int border_width; + public IntPtr above; + public int detail; + public IntPtr value_mask; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XCirculateEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr xevent; + public IntPtr window; + public int place; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XCirculateRequestEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr parent; + public IntPtr window; + public int place; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XPropertyEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public IntPtr atom; + public IntPtr time; + public int state; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XSelectionClearEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public IntPtr selection; + public IntPtr time; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XSelectionRequestEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr owner; + public IntPtr requestor; + public IntPtr selection; + public IntPtr target; + public IntPtr property; + public IntPtr time; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XSelectionEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr requestor; + public IntPtr selection; + public IntPtr target; + public IntPtr property; + public IntPtr time; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XColormapEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public IntPtr colormap; + public bool c_new; + public int state; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XClientMessageEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public IntPtr message_type; + public int format; + public IntPtr ptr1; + public IntPtr ptr2; + public IntPtr ptr3; + public IntPtr ptr4; + public IntPtr ptr5; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XMappingEvent + { + public XEventName type; + public IntPtr serial; + public bool send_event; + public IntPtr display; + public IntPtr window; + public int request; + public int first_keycode; + public int count; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XErrorEvent + { + public XEventName type; + public IntPtr display; + public IntPtr resourceid; + public IntPtr serial; + public byte error_code; + public XRequest request_code; + public byte minor_code; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XEventPad + { + public IntPtr pad0; + public IntPtr pad1; + public IntPtr pad2; + public IntPtr pad3; + public IntPtr pad4; + public IntPtr pad5; + public IntPtr pad6; + public IntPtr pad7; + public IntPtr pad8; + public IntPtr pad9; + public IntPtr pad10; + public IntPtr pad11; + public IntPtr pad12; + public IntPtr pad13; + public IntPtr pad14; + public IntPtr pad15; + public IntPtr pad16; + public IntPtr pad17; + public IntPtr pad18; + public IntPtr pad19; + public IntPtr pad20; + public IntPtr pad21; + public IntPtr pad22; + public IntPtr pad23; + } + + [StructLayout(LayoutKind.Explicit)] + public struct XEvent + { + [FieldOffset(0)] public XEventName type; + [FieldOffset(0)] public XAnyEvent AnyEvent; + [FieldOffset(0)] public XKeyEvent KeyEvent; + [FieldOffset(0)] public XButtonEvent ButtonEvent; + [FieldOffset(0)] public XMotionEvent MotionEvent; + [FieldOffset(0)] public XCrossingEvent CrossingEvent; + [FieldOffset(0)] public XFocusChangeEvent FocusChangeEvent; + [FieldOffset(0)] public XExposeEvent ExposeEvent; + [FieldOffset(0)] public XGraphicsExposeEvent GraphicsExposeEvent; + [FieldOffset(0)] public XNoExposeEvent NoExposeEvent; + [FieldOffset(0)] public XVisibilityEvent VisibilityEvent; + [FieldOffset(0)] public XCreateWindowEvent CreateWindowEvent; + [FieldOffset(0)] public XDestroyWindowEvent DestroyWindowEvent; + [FieldOffset(0)] public XUnmapEvent UnmapEvent; + [FieldOffset(0)] public XMapEvent MapEvent; + [FieldOffset(0)] public XMapRequestEvent MapRequestEvent; + [FieldOffset(0)] public XReparentEvent ReparentEvent; + [FieldOffset(0)] public XConfigureEvent ConfigureEvent; + [FieldOffset(0)] public XGravityEvent GravityEvent; + [FieldOffset(0)] public XResizeRequestEvent ResizeRequestEvent; + [FieldOffset(0)] public XConfigureRequestEvent ConfigureRequestEvent; + [FieldOffset(0)] public XCirculateEvent CirculateEvent; + [FieldOffset(0)] public XCirculateRequestEvent CirculateRequestEvent; + [FieldOffset(0)] public XPropertyEvent PropertyEvent; + [FieldOffset(0)] public XSelectionClearEvent SelectionClearEvent; + [FieldOffset(0)] public XSelectionRequestEvent SelectionRequestEvent; + [FieldOffset(0)] public XSelectionEvent SelectionEvent; + [FieldOffset(0)] public XColormapEvent ColormapEvent; + [FieldOffset(0)] public XClientMessageEvent ClientMessageEvent; + [FieldOffset(0)] public XMappingEvent MappingEvent; + [FieldOffset(0)] public XErrorEvent ErrorEvent; + [FieldOffset(0)] public XKeymapEvent KeymapEvent; + + //[MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=24)] + //[ FieldOffset(0) ] public int[] pad; + [FieldOffset(0)] public XEventPad Pad; + public override string ToString() + { + switch (type) + { + case XEventName.ButtonPress: + case XEventName.ButtonRelease: + return ToString(ButtonEvent); + case XEventName.CirculateNotify: + case XEventName.CirculateRequest: + return ToString(CirculateEvent); + case XEventName.ClientMessage: + return ToString(ClientMessageEvent); + case XEventName.ColormapNotify: + return ToString(ColormapEvent); + case XEventName.ConfigureNotify: + return ToString(ConfigureEvent); + case XEventName.ConfigureRequest: + return ToString(ConfigureRequestEvent); + case XEventName.CreateNotify: + return ToString(CreateWindowEvent); + case XEventName.DestroyNotify: + return ToString(DestroyWindowEvent); + case XEventName.Expose: + return ToString(ExposeEvent); + case XEventName.FocusIn: + case XEventName.FocusOut: + return ToString(FocusChangeEvent); + case XEventName.GraphicsExpose: + return ToString(GraphicsExposeEvent); + case XEventName.GravityNotify: + return ToString(GravityEvent); + case XEventName.KeymapNotify: + return ToString(KeymapEvent); + case XEventName.MapNotify: + return ToString(MapEvent); + case XEventName.MappingNotify: + return ToString(MappingEvent); + case XEventName.MapRequest: + return ToString(MapRequestEvent); + case XEventName.MotionNotify: + return ToString(MotionEvent); + case XEventName.NoExpose: + return ToString(NoExposeEvent); + case XEventName.PropertyNotify: + return ToString(PropertyEvent); + case XEventName.ReparentNotify: + return ToString(ReparentEvent); + case XEventName.ResizeRequest: + return ToString(ResizeRequestEvent); + case XEventName.SelectionClear: + return ToString(SelectionClearEvent); + case XEventName.SelectionNotify: + return ToString(SelectionEvent); + case XEventName.SelectionRequest: + return ToString(SelectionRequestEvent); + case XEventName.UnmapNotify: + return ToString(UnmapEvent); + case XEventName.VisibilityNotify: + return ToString(VisibilityEvent); + case XEventName.EnterNotify: + case XEventName.LeaveNotify: + return ToString(CrossingEvent); + default: + return type.ToString(); + } + } + + public static string ToString(object ev) + { + string result = string.Empty; + Type type = ev.GetType(); + System.Reflection.FieldInfo[] fields = type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance); + for (int i = 0; i < fields.Length; i++) + { + if (result != string.Empty) + { + result += ", "; + } + object value = fields[i].GetValue(ev); + result += fields[i].Name + "=" + (value == null ? "" : value.ToString()); + } + return type.Name + " (" + result + ")"; + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct XSetWindowAttributes + { + public IntPtr background_pixmap; + public IntPtr background_pixel; + public IntPtr border_pixmap; + public IntPtr border_pixel; + public Gravity bit_gravity; + public Gravity win_gravity; + public int backing_store; + public IntPtr backing_planes; + public IntPtr backing_pixel; + public bool save_under; + public IntPtr event_mask; + public IntPtr do_not_propagate_mask; + public bool override_redirect; + public IntPtr colormap; + public IntPtr cursor; + } + + [StructLayout(LayoutKind.Sequential)] + public struct XWindowAttributes + { + public int x; + public int y; + public int width; + public int height; + public int border_width; + public int depth; + public IntPtr visual; + public IntPtr root; + public int c_class; + public Gravity bit_gravity; + public Gravity win_gravity; + public int backing_store; + public IntPtr backing_planes; + public IntPtr backing_pixel; + public bool save_under; + public IntPtr colormap; + public bool map_installed; + public MapState map_state; + public IntPtr all_event_masks; + public IntPtr your_event_mask; + public IntPtr do_not_propagate_mask; + public bool override_direct; + public IntPtr screen; + + public override string ToString() + { + return XEvent.ToString(this); + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct XTextProperty + { + public string value; + public IntPtr encoding; + public int format; + public IntPtr nitems; + } + + public enum XWindowClass + { + InputOutput = 1, + InputOnly = 2 + } + + public enum XEventName + { + KeyPress = 2, + KeyRelease = 3, + ButtonPress = 4, + ButtonRelease = 5, + MotionNotify = 6, + EnterNotify = 7, + LeaveNotify = 8, + FocusIn = 9, + FocusOut = 10, + KeymapNotify = 11, + Expose = 12, + GraphicsExpose = 13, + NoExpose = 14, + VisibilityNotify = 15, + CreateNotify = 16, + DestroyNotify = 17, + UnmapNotify = 18, + MapNotify = 19, + MapRequest = 20, + ReparentNotify = 21, + ConfigureNotify = 22, + ConfigureRequest = 23, + GravityNotify = 24, + ResizeRequest = 25, + CirculateNotify = 26, + CirculateRequest = 27, + PropertyNotify = 28, + SelectionClear = 29, + SelectionRequest = 30, + SelectionNotify = 31, + ColormapNotify = 32, + ClientMessage = 33, + MappingNotify = 34, + + LASTEvent + } + + [Flags] + public enum SetWindowValuemask + { + Nothing = 0, + BackPixmap = 1, + BackPixel = 2, + BorderPixmap = 4, + BorderPixel = 8, + BitGravity = 16, + WinGravity = 32, + BackingStore = 64, + BackingPlanes = 128, + BackingPixel = 256, + OverrideRedirect = 512, + SaveUnder = 1024, + EventMask = 2048, + DontPropagate = 4096, + ColorMap = 8192, + Cursor = 16384 + } + + public enum SendEventValues + { + PointerWindow = 0, + InputFocus = 1 + } + + public enum CreateWindowArgs + { + CopyFromParent = 0, + ParentRelative = 1, + InputOutput = 1, + InputOnly = 2 + } + + public enum Gravity + { + ForgetGravity = 0, + NorthWestGravity = 1, + NorthGravity = 2, + NorthEastGravity = 3, + WestGravity = 4, + CenterGravity = 5, + EastGravity = 6, + SouthWestGravity = 7, + SouthGravity = 8, + SouthEastGravity = 9, + StaticGravity = 10 + } + + public enum XKeySym : uint + { + XK_BackSpace = 0xFF08, + XK_Tab = 0xFF09, + XK_Clear = 0xFF0B, + XK_Return = 0xFF0D, + XK_Home = 0xFF50, + XK_Left = 0xFF51, + XK_Up = 0xFF52, + XK_Right = 0xFF53, + XK_Down = 0xFF54, + XK_Page_Up = 0xFF55, + XK_Page_Down = 0xFF56, + XK_End = 0xFF57, + XK_Begin = 0xFF58, + XK_Menu = 0xFF67, + XK_Shift_L = 0xFFE1, + XK_Shift_R = 0xFFE2, + XK_Control_L = 0xFFE3, + XK_Control_R = 0xFFE4, + XK_Caps_Lock = 0xFFE5, + XK_Shift_Lock = 0xFFE6, + XK_Meta_L = 0xFFE7, + XK_Meta_R = 0xFFE8, + XK_Alt_L = 0xFFE9, + XK_Alt_R = 0xFFEA, + XK_Super_L = 0xFFEB, + XK_Super_R = 0xFFEC, + XK_Hyper_L = 0xFFED, + XK_Hyper_R = 0xFFEE, + } + + [Flags] + public enum EventMask + { + NoEventMask = 0, + KeyPressMask = 1 << 0, + KeyReleaseMask = 1 << 1, + ButtonPressMask = 1 << 2, + ButtonReleaseMask = 1 << 3, + EnterWindowMask = 1 << 4, + LeaveWindowMask = 1 << 5, + PointerMotionMask = 1 << 6, + PointerMotionHintMask = 1 << 7, + Button1MotionMask = 1 << 8, + Button2MotionMask = 1 << 9, + Button3MotionMask = 1 << 10, + Button4MotionMask = 1 << 11, + Button5MotionMask = 1 << 12, + ButtonMotionMask = 1 << 13, + KeymapStateMask = 1 << 14, + ExposureMask = 1 << 15, + VisibilityChangeMask = 1 << 16, + StructureNotifyMask = 1 << 17, + ResizeRedirectMask = 1 << 18, + SubstructureNotifyMask = 1 << 19, + SubstructureRedirectMask = 1 << 20, + FocusChangeMask = 1 << 21, + PropertyChangeMask = 1 << 22, + ColormapChangeMask = 1 << 23, + OwnerGrabButtonMask = 1 << 24 + } + + public enum GrabMode + { + GrabModeSync = 0, + GrabModeAsync = 1 + } + + [StructLayout(LayoutKind.Sequential)] + public struct XStandardColormap + { + public IntPtr colormap; + public IntPtr red_max; + public IntPtr red_mult; + public IntPtr green_max; + public IntPtr green_mult; + public IntPtr blue_max; + public IntPtr blue_mult; + public IntPtr base_pixel; + public IntPtr visualid; + public IntPtr killid; + } + + [StructLayout(LayoutKind.Sequential, Pack = 2)] + public struct XColor + { + public IntPtr pixel; + public ushort red; + public ushort green; + public ushort blue; + public byte flags; + public byte pad; + } + + public enum Atom + { + AnyPropertyType = 0, + XA_PRIMARY = 1, + XA_SECONDARY = 2, + XA_ARC = 3, + XA_ATOM = 4, + XA_BITMAP = 5, + XA_CARDINAL = 6, + XA_COLORMAP = 7, + XA_CURSOR = 8, + XA_CUT_BUFFER0 = 9, + XA_CUT_BUFFER1 = 10, + XA_CUT_BUFFER2 = 11, + XA_CUT_BUFFER3 = 12, + XA_CUT_BUFFER4 = 13, + XA_CUT_BUFFER5 = 14, + XA_CUT_BUFFER6 = 15, + XA_CUT_BUFFER7 = 16, + XA_DRAWABLE = 17, + XA_FONT = 18, + XA_INTEGER = 19, + XA_PIXMAP = 20, + XA_POINT = 21, + XA_RECTANGLE = 22, + XA_RESOURCE_MANAGER = 23, + XA_RGB_COLOR_MAP = 24, + XA_RGB_BEST_MAP = 25, + XA_RGB_BLUE_MAP = 26, + XA_RGB_DEFAULT_MAP = 27, + XA_RGB_GRAY_MAP = 28, + XA_RGB_GREEN_MAP = 29, + XA_RGB_RED_MAP = 30, + XA_STRING = 31, + XA_VISUALID = 32, + XA_WINDOW = 33, + XA_WM_COMMAND = 34, + XA_WM_HINTS = 35, + XA_WM_CLIENT_MACHINE = 36, + XA_WM_ICON_NAME = 37, + XA_WM_ICON_SIZE = 38, + XA_WM_NAME = 39, + XA_WM_NORMAL_HINTS = 40, + XA_WM_SIZE_HINTS = 41, + XA_WM_ZOOM_HINTS = 42, + XA_MIN_SPACE = 43, + XA_NORM_SPACE = 44, + XA_MAX_SPACE = 45, + XA_END_SPACE = 46, + XA_SUPERSCRIPT_X = 47, + XA_SUPERSCRIPT_Y = 48, + XA_SUBSCRIPT_X = 49, + XA_SUBSCRIPT_Y = 50, + XA_UNDERLINE_POSITION = 51, + XA_UNDERLINE_THICKNESS = 52, + XA_STRIKEOUT_ASCENT = 53, + XA_STRIKEOUT_DESCENT = 54, + XA_ITALIC_ANGLE = 55, + XA_X_HEIGHT = 56, + XA_QUAD_WIDTH = 57, + XA_WEIGHT = 58, + XA_POINT_SIZE = 59, + XA_RESOLUTION = 60, + XA_COPYRIGHT = 61, + XA_NOTICE = 62, + XA_FONT_NAME = 63, + XA_FAMILY_NAME = 64, + XA_FULL_NAME = 65, + XA_CAP_HEIGHT = 66, + XA_WM_CLASS = 67, + XA_WM_TRANSIENT_FOR = 68, + + XA_LAST_PREDEFINED = 68 + } + + [StructLayout(LayoutKind.Sequential)] + public struct XScreen + { + public IntPtr ext_data; + public IntPtr display; + public IntPtr root; + public int width; + public int height; + public int mwidth; + public int mheight; + public int ndepths; + public IntPtr depths; + public int root_depth; + public IntPtr root_visual; + public IntPtr default_gc; + public IntPtr cmap; + public IntPtr white_pixel; + public IntPtr black_pixel; + public int max_maps; + public int min_maps; + public int backing_store; + public bool save_unders; + public IntPtr root_input_mask; + } + + [Flags] + public enum ChangeWindowFlags + { + CWX = 1 << 0, + CWY = 1 << 1, + CWWidth = 1 << 2, + CWHeight = 1 << 3, + CWBorderWidth = 1 << 4, + CWSibling = 1 << 5, + CWStackMode = 1 << 6 + } + + public enum StackMode + { + Above = 0, + Below = 1, + TopIf = 2, + BottomIf = 3, + Opposite = 4 + } + + [StructLayout(LayoutKind.Sequential)] + public struct XWindowChanges + { + public int x; + public int y; + public int width; + public int height; + public int border_width; + public IntPtr sibling; + public StackMode stack_mode; + } + + [Flags] + public enum ColorFlags + { + DoRed = 1 << 0, + DoGreen = 1 << 1, + DoBlue = 1 << 2 + } + + public enum NotifyMode + { + NotifyNormal = 0, + NotifyGrab = 1, + NotifyUngrab = 2 + } + + public enum NotifyDetail + { + NotifyAncestor = 0, + NotifyVirtual = 1, + NotifyInferior = 2, + NotifyNonlinear = 3, + NotifyNonlinearVirtual = 4, + NotifyPointer = 5, + NotifyPointerRoot = 6, + NotifyDetailNone = 7 + } + + [StructLayout(LayoutKind.Sequential)] + public struct MotifWmHints + { + public IntPtr flags; + public IntPtr functions; + public IntPtr decorations; + public IntPtr input_mode; + public IntPtr status; + + public override string ToString() + { + return string.Format("MotifWmHints